on se lance dans les middleware
[restcoda.git] / rest.wsgi
CommitLineData
1795efcd
TN
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4import sys, traceback
5
a6627284
TN
6# configuration (codes d'accès à la base MS-SQL)
7sys.path.append('/home/thomas/public_html/')
8import rest_config
9
10# pour savoir quel objet interroger : Routes et analyse de query_string
1795efcd 11from routes import Mapper
a6627284 12from routes.middleware import RoutesMiddleware
1795efcd
TN
13from cgi import parse_qs
14
a6627284 15# pour chercher les données sur MS-SQL
1795efcd 16from pymssql import connect
a6627284
TN
17
18# pour afficher le résultat : jinja
1795efcd
TN
19from jinja import Environment, FileSystemLoader
20from jinja.filters import stringfilter
21
a6627284
TN
22# systeme de cache : beaker
23from beaker.middleware import CacheMiddleware
1795efcd 24
a6627284 25# formats de sortie autorisés, et content-type correspondant
1795efcd
TN
26formats = { 'xml': 'application/xml', 'html': 'text/html', 'txt': 'text/plain', 'json': 'application/json', 'rss': 'application/rss+xml' }
27
a6627284 28# les routes
1795efcd
TN
29mapper = Mapper()
30mapper.connect(':controller/')
31mapper.connect(':controller/:id', action='get')
32mapper.connect(':controller/:action/:id')
33mapper.create_regs(['document','demlog','comlog'])
34
a6627284 35# 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
TN
36class objetsql(object):
37 def __init__(self, environ):
a6627284 38 self.bd = connect(host=rest_config.host,user=rest_config.user,password=rest_config.password,database=rest_config.database)
1795efcd
TN
39 self.cursor = self.bd.cursor()
40 self.jinja = Environment(loader=FileSystemLoader('/home/thomas/public_html/'))
1795efcd
TN
41 self.environ = environ
42 if (self.environ['org.auf.filters'].has_key('format')):
43 self.outputformat=self.environ['org.auf.filters']['format'][0]
44 else:
45 self.outputformat='xml'
a6627284 46
1795efcd
TN
47class document(objetsql):
48 def __init__(self, environ, code_document='%', basename_template='document'):
49 super(document, self).__init__(environ)
50 self.code_document = code_document
51 self.basename_template = basename_template
52
53 def index(self):
54 self.cursor.execute("select top 30 * from auf_v_acces_demcom where code like '%s' order by date_modif desc" % (self.code_document))
55 documents={}
56 documents['code'] = self.code_document
57 documents_liste=[]
58 while 1:
59 document = dict_fetchone(self.cursor)
60 if document == None: break
61 document['code_rest'] = coda2rest(document['code'])
62 documents_liste.append(document)
63 documents['documents'] = documents_liste
64 template = self.jinja.get_template('%s-index.%s' % (self.basename_template, self.outputformat))
65 output = template.render(documents)
66 return self.outputformat, output
67
68 def get(self):
a6627284 69 id = int(self.environ['wsgiorg.routing_args'][1]['id'])
1795efcd
TN
70 self.cursor.execute("select top 1 * from auf_v_acces_demcom where code like '%s' and numero = %d" % (self.code_document, id))
71 document = dict_fetchone(self.cursor)
72 if document == None:
73 raise "document inexistant"
74 document['code_rest'] = coda2rest(document['code'])
75 details = []
76 self.cursor.execute("select * from auf_v_acces_dtls_demcom where code like '%s' and numero = %d" % (self.code_document, id))
77 while 1:
78 detail = dict_fetchone(self.cursor)
79 if detail == None: break
80 details.append(detail)
81 document['details']=details
82 template = self.jinja.get_template('%s.%s' % (self.basename_template, self.outputformat))
83 output = template.render(document)
84 return self.outputformat, output
85
86class demlog(document):
87 def __init__(self, environ):
88 super(demlog, self).__init__(environ, code_document = 'DEM-LOG-AUF')
89
90class comlog(document):
91 def __init__(self, environ):
92 super(comlog, self).__init__(environ, code_document = 'COM-LOG-AUF')
93
a6627284 94def dispatcher(environ, start_response):
1795efcd 95 """sera lancée par mod_wsgi"""
a6627284
TN
96 if environ.has_key('QUERY_STRING'):
97 environ['org.auf.filters'] = parse_qs(environ['QUERY_STRING'])
98 else:
99 environ['org.auf.filters'] = {}
100 results = environ['wsgiorg.routing_args'][1]
1795efcd
TN
101 try:
102 target_class = globals()[results['controller']]
103 method_name = results['action']
104 if environ['REQUEST_METHOD'] != 'GET':
105 method_name = environ['REQUEST_METHOD'] + '_' + method_name
106 method = getattr(target_class,method_name)
107 type, output = method(target_class(environ))
108 start_response("200 OK", [('Content-type', formats[type])])
109 return output.encode('utf-8')
110 except:
111 start_response("404 NOT FOUND", [('Content-type', 'text/plain')])
112 return 'erreur lors du traitement\n%s: %s\n%s' % ( sys.exc_info()[0] , sys.exc_info()[1] , traceback.format_exc())
113
a6627284 114application = RoutesMiddleware( dispatcher, mapper)
1795efcd
TN
115
116# utilitaires
117def dict_fetchone(cursor):
118 """Renvoie le resultat d'un fetchone dans un dictionnaire"""
119 result = cursor.fetchone()
120 if result == None: return None
121 result_dict = {}
122 for i in range(len(result)):
123 if isinstance( result[i], str ):
124 result_dict[cursor.description[i][0]] = result[i].decode('iso-8859-1')
125 else:
126 result_dict[cursor.description[i][0]] = result[i]
127 return result_dict
128
a6627284
TN
129import re
130p = re.compile('(dem|com)-(...)-auf',re.IGNORECASE)
131def coda2rest(value):
132 """Traduit un nom CODA en l'objet correspodant, par exemple DEM-LOG-AUF en demlog"""
133 m = p.search(value)
134 if m == None: return value
135 return m.group(1).lower() + m.group(2).lower()
136