Outils de création et mise à jour d'annuaire AuF.
[progfou.git] / wcs / wcs-extract
CommitLineData
0f48356a
P
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import os
5import os.path
a9de62a1
P
6import shutil
7import logging
0f48356a
P
8from time import gmtime, strftime
9import simplejson as json
10
0cd61ae9
P
11from wcs import publisher
12from wcs.formdef import FormDef
13from wcs.fields import TitleField, CommentField, TextField, \
14 StringField, ItemField, EmailField, \
15 DateField, FileField, BoolField
0f48356a 16
0f48356a 17
0cd61ae9
P
18def reduce_to_alnum(s, replacement_char='-'):
19 """réduction d'une chaîne de caractères à de l'alpha-numérique"""
20
0f48356a
P
21 avec_accent = u'çÇáàâÁÀÂéèêëÉÈÊËíìîïÍÌÎÏóòôöÓÒÔÖúùûüÚÙÛÜýỳyÿÝỲYŸ'
22 sans_accent = u'cCaaaAAAeeeeEEEEiiiiIIIIooooOOOOuuuuUUUUyyyyYYYY'
23 if type(s) is not unicode:
24 s = unicode(s, 'utf-8')
25 u = False
26 r = ''
27 for c in s:
28 index = avec_accent.find(c)
29 if index >= 0:
30 r += sans_accent[index]
31 elif ('a' <= c.lower() <= 'z') or ('0' <= c <= '9'):
32 r += c
33 elif len(r) > 0 and r[-1] != replacement_char:
34 r += replacement_char
35 else: # r == '' or r[-1] == replacement_char
36 pass
37 r = r.strip(replacement_char)
38 if not u:
39 r = r.encode('utf-8')
40 return r
41
0f48356a 42
0cd61ae9
P
43def extract_fields(formdef, output_directory):
44 """nommage des champs de façon unique"""
45 # TODO: devrait retourner un résultat, qui serait alors sauvé en dehors
46
36319452
P
47 # XXX: hack temporaire… :-/
48 global field_names
49
0cd61ae9
P
50 f = open(os.path.join(output_directory, 'field-names.txt'), 'w')
51
52 field_names = {}
53 field_names_duplicates = {}
0f48356a 54 for field in formdef.fields:
0f48356a
P
55 if isinstance(field, TitleField) or isinstance(field, CommentField):
56 continue
0cd61ae9
P
57 name = reduce_to_alnum(field.label,'_').lower()
58 if name in field_names.values(): # duplicat
59 field_names_duplicates[name] = field_names_duplicates.get(name, 1) + 1
60 name = '%s_%d' % (name, field_names_duplicates[name])
61 field_names.update({field.id: name})
62 print >>f, "%s:%s:%s" % (field.id, field_names[field.id], field.label)
63
0f48356a
P
64 f.close()
65
0cd61ae9
P
66 f = open(os.path.join(output_directory, 'field-names.json'), 'wb')
67 f.write(json.dumps(field_names, ensure_ascii=False))
68 f.close()
69
70
71def extract_data(formdef, output_directory):
72 """extraction des données du formulaire"""
73 # TODO: devrait retourner un résultat, qui serait alors sauvé en dehors
74
e80345a7
P
75 # XXX: hack temporaire… :-/
76 global pub
77
2e14236b 78 liste_dossiers = []
0cd61ae9
P
79 for object in formdef.data_class().select():
80 result = {
81 'num_dossier': object.id,
82 'wcs_status': object.status,
83 'wcs_workflow_status': object.get_workflow_status().name,
84 'wcs_user_email': object.user.email,
85 'wcs_user_display_name': object.user.display_name,
86 #'wcs_last_modified': strftime('%Y-%m-%d %H:%M:%S', gmtime(object.last_modified())),
e80345a7 87 'wcs_comments': [],
0cd61ae9 88 }
e80345a7
P
89
90 if object.evolution is not None:
91 for e in object.evolution:
92 if e.comment is not None:
93 who = pub.user_class.get(e.who).display_name
94 time = strftime('%Y-%m-%d %H:%M:%S', e.time)
95 comment = '%s -- %s %s' % (e.comment, who, time)
96 result['wcs_comments'].append(comment)
97
0cd61ae9
P
98 qfiles = { }
99 for field in formdef.fields:
100 field_id = str(field.id)
101 if not field_id in object.data:
102 continue
103 if isinstance(field, TitleField) or isinstance(field, CommentField):
104 continue
105 field_name = field_names[field_id]
106 data = object.data.get(field_id)
107 if isinstance(field, StringField) or isinstance(field, TextField) \
108 or isinstance(field, EmailField) or isinstance(field, ItemField):
109 result[field_name] = data
110 elif isinstance(field, BoolField):
111 result[field_name] = (data == 'True')
112 elif isinstance(field, DateField):
113 result[field_name] = strftime('%Y-%m-%d', data)
114 elif isinstance(field, FileField):
115 extension = data.orig_filename.rpartition('.')[2].lower()
116 result[field_name] = "%s.%s" % (field_name, extension)
117 qfiles[field_name] = data.qfilename
118 else:
a9de62a1
P
119 logging.error("Type de champ inconnu '%s' pour '%s'.",
120 field.__class__.__name__, field.label)
0cd61ae9
P
121 raise RuntimeError
122
123 num_dossier = result['num_dossier']
124 nom = reduce_to_alnum(result['nom']).upper()
125 prenom = reduce_to_alnum(result['prenom']).upper()
126 adel = result['adresse_electronique'].replace('@','-').lower()
127
128 filename = "%04d-%s-%s-%s" % (num_dossier, nom, prenom, adel)
2e14236b 129 liste_dossiers.append(filename + '.json')
0cd61ae9 130
0cd61ae9
P
131 # copie des fichiers joints
132 for f in qfiles:
133 result[f] = filename + '_' + result[f]
134 src = os.path.join(pub.app_dir, 'uploads', qfiles[f])
a9de62a1 135 dst = os.path.join(output_directory, 'data', result[f])
0cd61ae9 136 if not os.path.exists(dst) or os.path.getmtime(src) > os.path.getmtime(dst):
a9de62a1 137 shutil.copy2(src, dst)
0cd61ae9
P
138 os.chmod(dst, 0644)
139
140 # génération du fichier JSON
a9de62a1
P
141 jsonname = os.path.join(output_directory, 'data', filename + '.json')
142 f = open(jsonname, 'wb')
0cd61ae9
P
143 f.write(json.dumps(result, ensure_ascii=False))
144 f.close()
145
a9de62a1
P
146 logging.info("Dossier '%s' : %s.",
147 filename, result['wcs_workflow_status'])
0cd61ae9 148
2e14236b
P
149 f = open(os.path.join(output_directory, 'liste-dossiers.json'), 'wb')
150 f.write(json.dumps(liste_dossiers, ensure_ascii=False))
151 f.close()
152
0cd61ae9
P
153
154if __name__ == '__main__':
155 import sys
156
157 if len(sys.argv) != 4:
158 print >>sys.stderr, "Usage : %s <dossier-destination> <site> <formulaire>" % sys.argv[0]
159 sys.exit(1)
160
161 VHOST = sys.argv[2]
162 FORM_NAME = sys.argv[3]
163 OUTPUT_DIRECTORY = os.path.join(sys.argv[1], VHOST, FORM_NAME)
164
165 os.umask(0022)
166 # création du dossier d'extraction, au besoin
167 if not os.path.isdir(OUTPUT_DIRECTORY):
168 os.makedirs(OUTPUT_DIRECTORY, 0755)
169
a9de62a1
P
170 logging.basicConfig(level=logging.DEBUG,
171 format='%(asctime)s %(levelname)s %(message)s',
172 filename=os.path.join(OUTPUT_DIRECTORY, 'last-run.log'),
173 filemode='w')
174
175 logging.info('Début.')
176
0cd61ae9
P
177 pub = publisher.WcsPublisher.create_publisher()
178 pub.app_dir = os.path.join(pub.app_dir, VHOST)
179
180 formdef = FormDef.get_by_urlname(FORM_NAME)
181
182 extract_fields(formdef, OUTPUT_DIRECTORY)
183
184 extract_data(formdef, OUTPUT_DIRECTORY)
185
a9de62a1 186 logging.info('Fin.')
0f48356a 187