wcs-extract : gestion des exceptions sur la détection du type de fichier
[progfou.git] / wcs / wcs-extract
index 72b8e37..ec414a9 100755 (executable)
@@ -1,12 +1,23 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+"""
+Outil d'export de données w.c.s.
 
+Copyright : Agence universitaire de la Francophonie — www.auf.org
+Licence : GNU General Public Licence, version 2
+Auteur : Jean Christophe André
+Date de création : 15 octobre 2009
+
+Depends: wcs, python-simplejson, python-magic
+"""
 import os
 import os.path
 import shutil
 import logging
 from time import gmtime, strftime
 import simplejson as json
+import magic
+import mimetypes
 
 from wcs import publisher
 from wcs.formdef import FormDef
@@ -64,7 +75,7 @@ def extract_fields(formdef, output_directory):
     f.close()
 
     f = open(os.path.join(output_directory, 'field-names.json'), 'wb')
-    f.write(json.dumps(field_names, ensure_ascii=False))
+    f.write(json.dumps(field_names, ensure_ascii=False, sort_keys=True))
     f.close()
 
 
@@ -75,8 +86,17 @@ def extract_data(formdef, output_directory):
     # XXX: hack temporaire… :-/
     global pub
 
+    # on charge la base des types MIME une fois pour toutes
+    #magicmime = magic.Magic(mime=True) => ce sera pour plus tard…
+    magicmime = magic.open(magic.MAGIC_MIME)
+
     liste_dossiers = []
     for object in formdef.data_class().select():
+        if object.user is None:
+            logging.warning("Dossier '%s' sans utilisateur associé ?!?"\
+                            " On ignore...", object.id)
+            continue
+
         result = {
             'num_dossier': object.id,
             'wcs_status': object.status,
@@ -112,7 +132,21 @@ def extract_data(formdef, output_directory):
             elif isinstance(field, DateField):
                 result[field_name] = strftime('%Y-%m-%d', data)
             elif isinstance(field, FileField):
-                extension = data.orig_filename.rpartition('.')[2].lower()
+                if '.' in data.orig_filename:
+                    extension = data.orig_filename.rpartition('.')[2].lower()
+                else: # il n'y a pas d'extension dans le nom de fichier
+                    p = os.path.join(pub.app_dir, 'uploads', data.qfilename)
+                    try:
+                        #m = magicmime.from_file(p) => ce sera pour plus tard…
+                        m = magicmime.file(p).split()[0].strip(';')
+                        extension = mimetypes.guess_extension(m)
+                    except:
+                        logging.warning("Type de fichier inconnu pour '%s'.", p)
+                        extension = None
+                    if extension is not None:
+                        extension = extension[1:]
+                    else:
+                        extension = 'unknown'
                 result[field_name] = "%s.%s" % (field_name, extension)
                 qfiles[field_name] = data.qfilename
             else:
@@ -140,14 +174,14 @@ 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))
+        f.write(json.dumps(result, ensure_ascii=False, sort_keys=True))
         f.close()
 
         logging.info("Dossier '%s' : %s.",
                                     filename, result['wcs_workflow_status'])
 
     f = open(os.path.join(output_directory, 'liste-dossiers.json'), 'wb')
-    f.write(json.dumps(liste_dossiers, ensure_ascii=False))
+    f.write(json.dumps(liste_dossiers, ensure_ascii=False, sort_keys=True))
     f.close()
 
 
@@ -164,8 +198,8 @@ if __name__ == '__main__':
 
     os.umask(0022)
     # création du dossier d'extraction, au besoin
-    if not os.path.isdir(OUTPUT_DIRECTORY):
-        os.makedirs(OUTPUT_DIRECTORY, 0755)
+    if not os.path.isdir(os.path.join(OUTPUT_DIRECTORY, 'data')):
+        os.makedirs(os.path.join(OUTPUT_DIRECTORY, 'data'), 0755)
 
     logging.basicConfig(level=logging.DEBUG,
         format='%(asctime)s %(levelname)s %(message)s',