#!/usr/bin/python # -*- coding: utf-8 -*- import sys, traceback # configuration (codes d'accès à la base MS-SQL) sys.path.append('/home/thomas/public_html/') import rest_config # pour savoir quel objet interroger : Routes from routes import Mapper from routes.middleware import RoutesMiddleware # et analyse des paramètres (POST et query_string) pour filtrage from paste.request import parse_formvars # pour chercher les données sur MS-SQL from pymssql import connect # pour afficher le résultat : jinja from jinja import Environment, FileSystemLoader from jinja.filters import stringfilter # TODO systeme de cache : beaker # from beaker.middleware import CacheMiddleware # formats de sortie autorisés, et content-type correspondant # formats = { 'xml': 'application/xml', 'html': 'text/html', 'txt': 'text/plain', 'json': 'application/json', 'rss': 'application/rss+xml' } formats = { 'xml': 'application/xml', 'html': 'text/html', 'txt': 'text/plain', 'json': 'text/plain', 'rss': 'application/rss+xml' } # les routes RESTful (cf http://routes.groovie.org/manual.html#restful-services) mapper = Mapper() mapper.resource('demlog','demlog') mapper.resource('comlog','comlog') mapper.resource('demdep','demdep') mapper.resource('comdep','comdep') mapper.resource('dempub','dempub') mapper.resource('compub','compub') mapper.resource('comare','comare') # pour les comarexxx où xxx est un code d'implantation mapper.resource('comarei','comare:(impl)',controller='comare') mapper.resource('comsra','comsre') mapper.resource('comsrai','comsre:(impl)',controller='comsre') mapper.resource('dem','dem') mapper.resource('com','com') class objetsql(object): """objet de base : dispose d'un accès à MS-SQL (lire les données) et d'un accès à jinja (rendu des données)""" def __init__(self, environ): self.bd = connect(host=rest_config.host,user=rest_config.user,password=rest_config.password,database=rest_config.database) self.cursor = self.bd.cursor() self.jinja = Environment(loader=FileSystemLoader('/home/thomas/public_html/')) self.environ = environ self.outputformat = environ['wsgiorg.routing_args'][1].get('format','xml') class document(objetsql): """objet document CODA (demlog, comlog, demdep... ils ont tous le même format)""" def __init__(self, environ, code_document='%', basename_template='document'): super(document, self).__init__(environ) self.code_document = code_document self.basename_template = basename_template def index(self): self.cursor.execute("select top 30 * from auf_v_acces_demcom where code like '%s' order by date_modif desc" % (self.code_document)) documents={} documents['code'] = self.code_document documents_liste=[] while 1: document = dict_fetchone(self.cursor) if document == None: break document['code_rest'] = coda2rest(document['code']) documents_liste.append(document) documents['documents'] = documents_liste template = self.jinja.get_template('%s-index.%s' % (self.basename_template, self.outputformat)) output = template.render(documents) return self.outputformat, output def show_debug(self): return 'txt', '%s' % self.environ def show(self): id = int(self.environ['wsgiorg.routing_args'][1]['id']) self.cursor.execute("select top 1 * from auf_v_acces_demcom where code like '%s' and numero = %d" % (self.code_document, id)) document = dict_fetchone(self.cursor) if document == None: raise "document inexistant" document['code_rest'] = coda2rest(document['code']) details = [] self.cursor.execute("select * from auf_v_acces_dtls_demcom where code like '%s' and numero = %d" % (self.code_document, id)) while 1: detail = dict_fetchone(self.cursor) if detail == None: break details.append(detail) document['details']=details template = self.jinja.get_template('%s.%s' % (self.basename_template, self.outputformat)) output = template.render(document) return self.outputformat, output class dem(document): def __init__(self, environ): super(dem, self).__init__(environ, code_document = 'DEM-%') class com(document): def __init__(self, environ): super(com, self).__init__(environ, code_document = 'COM-%') class demlog(document): def __init__(self, environ): super(demlog, self).__init__(environ, code_document = 'DEM-LOG-AUF') class comlog(document): def __init__(self, environ): super(comlog, self).__init__(environ, code_document = 'COM-LOG-AUF') class demdep(document): def __init__(self, environ): super(demdep, self).__init__(environ, code_document = 'DEM-DEP-AUF') class comdep(document): def __init__(self, environ): super(comdep, self).__init__(environ, code_document = 'COM-DEP-AUF') class dempub(document): def __init__(self, environ): super(dempub, self).__init__(environ, code_document = 'DEM-PUB-AUF') class compub(document): def __init__(self, environ): super(compub, self).__init__(environ, code_document = 'COM-PUB-AUF') class comsre(document): def __init__(self, environ): # est-ce un appel de comsre ou comsrexxx (avec xxx = implantation) impl = environ['wsgiorg.routing_args'][1].get('impl','%') super(comsre, self).__init__(environ, code_document = 'COM-SRE-%s' % impl) class comare(document): def __init__(self, environ): impl = environ['wsgiorg.routing_args'][1].get('impl','%') super(comare, self).__init__(environ, code_document = 'COM-ARE-%s' % impl) def dispatcher(environ, start_response): """dispatch vers la bonne methode du bon objet, et retour WSGI""" parse_formvars(environ) results = environ['wsgiorg.routing_args'][1] try: target_class = globals()[results['controller']] method_name = results['action'] method = getattr(target_class,method_name) type, output = method(target_class(environ)) start_response("200 OK", [('Content-type', formats[type])]) return output.encode('utf-8') except: start_response("404 NOT FOUND", [('Content-type', 'text/plain')]) return 'erreur lors du traitement\n%s: %s\n%s' % ( sys.exc_info()[0] , sys.exc_info()[1] , traceback.format_exc()) # application qui sera lancée par mod_wsgi : on route et on dispatche application = RoutesMiddleware( dispatcher, mapper) # TODO : ajouter un middleware de cache (beaker) # # petits utilitaires # def dict_fetchone(cursor): """Renvoie le resultat d'un fetchone dans un dictionnaire""" result = cursor.fetchone() if result == None: return None result_dict = {} for i in range(len(result)): if isinstance( result[i], str ): result_dict[cursor.description[i][0]] = result[i].decode('iso-8859-1') else: result_dict[cursor.description[i][0]] = result[i] return result_dict import re p = re.compile('(dem|com)-(...)-(...)',re.IGNORECASE) def coda2rest(value): """Traduit un nom CODA vers la base REST correspodante, par exemple DEM-LOG-AUF en demlog ou COM-ARE-VN3 en comarevn3""" m = p.search(value) if m == None: return value if m.group(3).lower() == 'auf': return m.group(1).lower() + m.group(2).lower() else: return m.group(1).lower() + m.group(2).lower() + m.group(3).lower()