Commit | Line | Data |
---|---|---|
1795efcd TN |
1 | #!/usr/bin/python |
2 | # -*- coding: utf-8 -*- | |
3 | ||
4 | import sys, traceback | |
5 | ||
a6627284 TN |
6 | # configuration (codes d'accès à la base MS-SQL) |
7 | sys.path.append('/home/thomas/public_html/') | |
8 | import rest_config | |
9 | ||
0a4c31d4 | 10 | # pour savoir quel objet interroger : Routes |
1795efcd | 11 | from routes import Mapper |
a6627284 | 12 | from routes.middleware import RoutesMiddleware |
81b8aba3 TN |
13 | # et analyse des paramètres (POST et query_string) pour filtrage |
14 | from paste.request import parse_formvars | |
1795efcd | 15 | |
a6627284 | 16 | # pour chercher les données sur MS-SQL |
1795efcd | 17 | from pymssql import connect |
a6627284 TN |
18 | |
19 | # pour afficher le résultat : jinja | |
1795efcd TN |
20 | from jinja import Environment, FileSystemLoader |
21 | from jinja.filters import stringfilter | |
22 | ||
0a4c31d4 TN |
23 | # TODO systeme de cache : beaker |
24 | # from beaker.middleware import CacheMiddleware | |
1795efcd | 25 | |
a6627284 | 26 | # formats de sortie autorisés, et content-type correspondant |
d588d902 TN |
27 | # formats = { 'xml': 'application/xml', 'html': 'text/html', 'txt': 'text/plain', 'json': 'application/json', 'rss': 'application/rss+xml' } |
28 | formats = { 'xml': 'application/xml', 'html': 'text/html', 'txt': 'text/plain', 'json': 'text/plain', 'rss': 'application/rss+xml' } | |
1795efcd | 29 | |
0a4c31d4 | 30 | # les routes RESTful (cf http://routes.groovie.org/manual.html#restful-services) |
1795efcd | 31 | mapper = Mapper() |
0a4c31d4 TN |
32 | mapper.resource('demlog','demlog') |
33 | mapper.resource('comlog','comlog') | |
34 | mapper.resource('demdep','demdep') | |
35 | mapper.resource('comdep','comdep') | |
36 | mapper.resource('dempub','dempub') | |
37 | mapper.resource('compub','compub') | |
0a4c31d4 | 38 | mapper.resource('comare','comare') |
db1681c0 TN |
39 | # pour les comarexxx où xxx est un code d'implantation |
40 | mapper.resource('comarei','comare:(impl)',controller='comare') | |
0a4c31d4 | 41 | mapper.resource('comsra','comsre') |
db1681c0 | 42 | mapper.resource('comsrai','comsre:(impl)',controller='comsre') |
f6b772ed TN |
43 | mapper.resource('dem','dem') |
44 | mapper.resource('com','com') | |
1795efcd TN |
45 | |
46 | class objetsql(object): | |
0a4c31d4 | 47 | """objet de base : dispose d'un accès à MS-SQL (lire les données) et d'un accès à jinja (rendu des données)""" |
1795efcd | 48 | def __init__(self, environ): |
a6627284 | 49 | self.bd = connect(host=rest_config.host,user=rest_config.user,password=rest_config.password,database=rest_config.database) |
1795efcd TN |
50 | self.cursor = self.bd.cursor() |
51 | self.jinja = Environment(loader=FileSystemLoader('/home/thomas/public_html/')) | |
1795efcd | 52 | self.environ = environ |
0a4c31d4 | 53 | self.outputformat = environ['wsgiorg.routing_args'][1].get('format','xml') |
a6627284 | 54 | |
1795efcd | 55 | class document(objetsql): |
0a4c31d4 | 56 | """objet document CODA (demlog, comlog, demdep... ils ont tous le même format)""" |
1795efcd TN |
57 | def __init__(self, environ, code_document='%', basename_template='document'): |
58 | super(document, self).__init__(environ) | |
59 | self.code_document = code_document | |
60 | self.basename_template = basename_template | |
61 | ||
62 | def index(self): | |
63 | self.cursor.execute("select top 30 * from auf_v_acces_demcom where code like '%s' order by date_modif desc" % (self.code_document)) | |
64 | documents={} | |
65 | documents['code'] = self.code_document | |
66 | documents_liste=[] | |
67 | while 1: | |
68 | document = dict_fetchone(self.cursor) | |
69 | if document == None: break | |
70 | document['code_rest'] = coda2rest(document['code']) | |
71 | documents_liste.append(document) | |
72 | documents['documents'] = documents_liste | |
73 | template = self.jinja.get_template('%s-index.%s' % (self.basename_template, self.outputformat)) | |
74 | output = template.render(documents) | |
75 | return self.outputformat, output | |
76 | ||
db1681c0 TN |
77 | def show_debug(self): |
78 | return 'txt', '%s' % self.environ | |
79 | ||
0a4c31d4 | 80 | def show(self): |
a6627284 | 81 | id = int(self.environ['wsgiorg.routing_args'][1]['id']) |
1795efcd TN |
82 | self.cursor.execute("select top 1 * from auf_v_acces_demcom where code like '%s' and numero = %d" % (self.code_document, id)) |
83 | document = dict_fetchone(self.cursor) | |
84 | if document == None: | |
85 | raise "document inexistant" | |
86 | document['code_rest'] = coda2rest(document['code']) | |
87 | details = [] | |
88 | self.cursor.execute("select * from auf_v_acces_dtls_demcom where code like '%s' and numero = %d" % (self.code_document, id)) | |
89 | while 1: | |
90 | detail = dict_fetchone(self.cursor) | |
91 | if detail == None: break | |
92 | details.append(detail) | |
93 | document['details']=details | |
94 | template = self.jinja.get_template('%s.%s' % (self.basename_template, self.outputformat)) | |
95 | output = template.render(document) | |
96 | return self.outputformat, output | |
97 | ||
f6b772ed TN |
98 | class dem(document): |
99 | def __init__(self, environ): | |
100 | super(dem, self).__init__(environ, code_document = 'DEM-%') | |
101 | ||
102 | class com(document): | |
103 | def __init__(self, environ): | |
104 | super(com, self).__init__(environ, code_document = 'COM-%') | |
105 | ||
1795efcd TN |
106 | class demlog(document): |
107 | def __init__(self, environ): | |
108 | super(demlog, self).__init__(environ, code_document = 'DEM-LOG-AUF') | |
109 | ||
110 | class comlog(document): | |
111 | def __init__(self, environ): | |
112 | super(comlog, self).__init__(environ, code_document = 'COM-LOG-AUF') | |
113 | ||
0a4c31d4 TN |
114 | class demdep(document): |
115 | def __init__(self, environ): | |
116 | super(demdep, self).__init__(environ, code_document = 'DEM-DEP-AUF') | |
117 | ||
118 | class comdep(document): | |
119 | def __init__(self, environ): | |
120 | super(comdep, self).__init__(environ, code_document = 'COM-DEP-AUF') | |
121 | ||
122 | class dempub(document): | |
123 | def __init__(self, environ): | |
124 | super(dempub, self).__init__(environ, code_document = 'DEM-PUB-AUF') | |
125 | ||
126 | class compub(document): | |
127 | def __init__(self, environ): | |
128 | super(compub, self).__init__(environ, code_document = 'COM-PUB-AUF') | |
129 | ||
0a4c31d4 TN |
130 | class comsre(document): |
131 | def __init__(self, environ): | |
db1681c0 TN |
132 | # est-ce un appel de comsre ou comsrexxx (avec xxx = implantation) |
133 | impl = environ['wsgiorg.routing_args'][1].get('impl','%') | |
134 | super(comsre, self).__init__(environ, code_document = 'COM-SRE-%s' % impl) | |
0a4c31d4 TN |
135 | |
136 | class comare(document): | |
137 | def __init__(self, environ): | |
db1681c0 TN |
138 | impl = environ['wsgiorg.routing_args'][1].get('impl','%') |
139 | super(comare, self).__init__(environ, code_document = 'COM-ARE-%s' % impl) | |
0a4c31d4 | 140 | |
a6627284 | 141 | def dispatcher(environ, start_response): |
81b8aba3 TN |
142 | """dispatch vers la bonne methode du bon objet, et retour WSGI""" |
143 | parse_formvars(environ) | |
a6627284 | 144 | results = environ['wsgiorg.routing_args'][1] |
1795efcd TN |
145 | try: |
146 | target_class = globals()[results['controller']] | |
147 | method_name = results['action'] | |
1795efcd TN |
148 | method = getattr(target_class,method_name) |
149 | type, output = method(target_class(environ)) | |
150 | start_response("200 OK", [('Content-type', formats[type])]) | |
151 | return output.encode('utf-8') | |
152 | except: | |
153 | start_response("404 NOT FOUND", [('Content-type', 'text/plain')]) | |
154 | return 'erreur lors du traitement\n%s: %s\n%s' % ( sys.exc_info()[0] , sys.exc_info()[1] , traceback.format_exc()) | |
155 | ||
81b8aba3 | 156 | # application qui sera lancée par mod_wsgi : on route et on dispatche |
a6627284 | 157 | application = RoutesMiddleware( dispatcher, mapper) |
81b8aba3 | 158 | # TODO : ajouter un middleware de cache (beaker) |
1795efcd | 159 | |
0a4c31d4 TN |
160 | |
161 | # | |
162 | # petits utilitaires | |
163 | # | |
1795efcd TN |
164 | def dict_fetchone(cursor): |
165 | """Renvoie le resultat d'un fetchone dans un dictionnaire""" | |
166 | result = cursor.fetchone() | |
167 | if result == None: return None | |
168 | result_dict = {} | |
169 | for i in range(len(result)): | |
170 | if isinstance( result[i], str ): | |
171 | result_dict[cursor.description[i][0]] = result[i].decode('iso-8859-1') | |
172 | else: | |
173 | result_dict[cursor.description[i][0]] = result[i] | |
174 | return result_dict | |
175 | ||
a6627284 | 176 | import re |
db1681c0 | 177 | p = re.compile('(dem|com)-(...)-(...)',re.IGNORECASE) |
a6627284 | 178 | def coda2rest(value): |
db1681c0 TN |
179 | """Traduit un nom CODA vers la base REST correspodante, |
180 | par exemple DEM-LOG-AUF en demlog ou COM-ARE-VN3 en comarevn3""" | |
a6627284 TN |
181 | m = p.search(value) |
182 | if m == None: return value | |
db1681c0 TN |
183 | if m.group(3).lower() == 'auf': |
184 | return m.group(1).lower() + m.group(2).lower() | |
185 | else: | |
186 | return m.group(1).lower() + m.group(2).lower() + m.group(3).lower() | |
a6627284 | 187 |