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