wcs-dynexport: on renomme aussi le fichier joint indiqué dans le dossier
[progfou.git] / wcs / wcs-extract
index 41ef813..2aef970 100755 (executable)
@@ -14,41 +14,34 @@ import os
 import os.path
 import shutil
 import logging
-from time import gmtime, strftime
+from time import gmtime, strftime, struct_time
 import simplejson as json
 import magic
 import mimetypes
+import unicodedata
 
 from wcs import publisher
 from wcs.formdef import FormDef
 from wcs.fields import TitleField, CommentField, TextField, \
-                       StringField, ItemField, EmailField, \
-                       DateField, FileField, BoolField
+                       StringField, ItemField, ItemsField, EmailField, \
+                       DateField, FileField, BoolField, TableField
 
 
 def reduce_to_alnum(s, replacement_char='-'):
     """réduction d'une chaîne de caractères à de l'alpha-numérique"""
 
-    avec_accent = u'çÇáàâÁÀÂéèêëÉÈÊËíìîïÍÌÎÏóòôöÓÒÔÖúùûüÚÙÛÜýỳyÿÝỲYŸ'
-    sans_accent = u'cCaaaAAAeeeeEEEEiiiiIIIIooooOOOOuuuuUUUUyyyyYYYY'
     if type(s) is not unicode:
         s = unicode(s, 'utf-8')
-        u  = False
+    s = unicodedata.normalize('NFKD', s).encode('ASCII', 'ignore')
     r = ''
     for c in s:
-        index = avec_accent.find(c)
-        if index >= 0:
-            r += sans_accent[index]
-        elif ('a' <= c.lower() <= 'z') or ('0' <= c <= '9'):
+        if ('a' <= c.lower() <= 'z') or ('0' <= c <= '9'):
             r += c
         elif len(r) > 0 and r[-1] != replacement_char:
             r += replacement_char
         else: # r == '' or r[-1] == replacement_char
             pass
-    r = r.strip(replacement_char)
-    if not u:
-        r = r.encode('utf-8')
-    return r
+    return r.strip(replacement_char)
 
 
 def extract_fields(formdef, output_directory):
@@ -65,7 +58,10 @@ def extract_fields(formdef, output_directory):
     for field in formdef.fields:
         if isinstance(field, TitleField) or isinstance(field, CommentField):
             continue
-        name = reduce_to_alnum(field.label,'_').lower()
+        if field.varname:
+            name = field.varname
+        else:
+            name = reduce_to_alnum(field.label,'_').lower()
         if name in field_names.values(): # duplicat
             field_names_duplicates[name] = field_names_duplicates.get(name, 1) + 1
             name = '%s_%d' % (name, field_names_duplicates[name])
@@ -74,12 +70,8 @@ def extract_fields(formdef, output_directory):
 
     f.close()
 
-    try:
-        field_names = dict([(int(k),v) for k,v in field_names.items()])
-    except:
-        pass
     f = open(os.path.join(output_directory, 'field-names.json'), 'wb')
-    f.write(json.dumps(field_names, ensure_ascii=False, sort_keys=True))
+    f.write(json.dumps(field_names, ensure_ascii=False))
     f.close()
 
 
@@ -105,7 +97,8 @@ def extract_data(formdef, output_directory):
         result = {
             'num_dossier': object.id,
             'wcs_status': object.status,
-            'wcs_workflow_status': object.get_workflow_status().name,
+            'wcs_workflow_status': (object.status.startswith('wf-') and \
+                                object.get_workflow_status().name or None),
             'wcs_user_email': object.user.email,
             'wcs_user_display_name': object.user.display_name,
            #'wcs_last_modified': strftime('%Y-%m-%d %H:%M:%S', gmtime(object.last_modified())),
@@ -129,13 +122,22 @@ def extract_data(formdef, output_directory):
                 continue
             field_name = field_names[field_id]
             data = object.data.get(field_id)
+            if data is None:
+                result[field_name] = None
+                continue
             if isinstance(field, StringField) or isinstance(field, TextField) \
             or isinstance(field, EmailField) or isinstance(field, ItemField):
                 result[field_name] = data
+            elif isinstance(field, ItemsField) or isinstance(field, TableField):
+                result[field_name] = data # liste => peux-être joindre sur ';'
             elif isinstance(field, BoolField):
                 result[field_name] = (data == 'True')
             elif isinstance(field, DateField):
-                result[field_name] = strftime('%Y-%m-%d', data)
+                if isinstance(data, struct_time):
+                    result[field_name] = '%04d-%02d-%02d' % (data.tm_year,
+                                                    data.tm_mon, data.tm_mday)
+                else:
+                    result[field_name] = data
             elif isinstance(field, FileField):
                 if '.' in data.orig_filename:
                     extension = data.orig_filename.rpartition('.')[2].lower()
@@ -155,14 +157,13 @@ def extract_data(formdef, output_directory):
                 result[field_name] = "%s.%s" % (field_name, extension)
                 qfiles[field_name] = data.qfilename
             else:
-                logging.error("Type de champ inconnu '%s' pour '%s'.",
-                                    field.__class__.__name__, field.label)
-                raise RuntimeError
+                logging.warning("Type de champ inconnu '%s' pour '%s' (%s).",
+                            field.__class__.__name__, field_name, field.label)
 
         num_dossier = result['num_dossier']
-        nom = reduce_to_alnum(result['nom']).upper()
-        prenom = reduce_to_alnum(result['prenom']).upper()
-        adel = result['adresse_electronique'].replace('@','-').lower()
+        nom = reduce_to_alnum(result.get('nom','sans-nom')).upper()
+        prenom = reduce_to_alnum(result.get('prenom','sans-prenom')).upper()
+        adel = result.get('adresse_electronique','sans-adel').replace('@','-').lower()
 
         filename = "%04d-%s-%s-%s" % (num_dossier, nom, prenom, adel)
         liste_dossiers.append(filename + '.json')
@@ -179,7 +180,7 @@ def extract_data(formdef, output_directory):
         # génération du fichier JSON
         jsonname = os.path.join(output_directory, 'data', filename + '.json')
         f = open(jsonname, 'wb')
-        f.write(json.dumps(result, ensure_ascii=False, sort_keys=True))
+        f.write(json.dumps(result, ensure_ascii=False).encode('utf-8'))
         f.close()
 
         logging.info("Dossier '%s' : %s.",
@@ -221,7 +222,10 @@ if __name__ == '__main__':
 
     extract_fields(formdef, OUTPUT_DIRECTORY)
 
-    extract_data(formdef, OUTPUT_DIRECTORY)
+    try:
+        extract_data(formdef, OUTPUT_DIRECTORY)
+    except:
+        logging.exception("Interruption du traitement pour cause d'erreur !")
 
     logging.info('Fin.')