paste.request.parse_formvars pour analyse des arguments cgi
[restcoda.git] / rest.wsgi
index 1c12508..09e55de 100644 (file)
--- a/rest.wsgi
+++ b/rest.wsgi
@@ -7,10 +7,11 @@ import sys, traceback
 sys.path.append('/home/thomas/public_html/')
 import rest_config
 
-# pour savoir quel objet interroger : Routes et analyse de query_string
+# pour savoir quel objet interroger : Routes
 from routes import Mapper
 from routes.middleware import RoutesMiddleware
-from cgi import parse_qs
+# 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
@@ -19,32 +20,40 @@ from pymssql import connect
 from jinja import Environment, FileSystemLoader
 from jinja.filters import stringfilter
 
-# systeme de cache : beaker
-from beaker.middleware import CacheMiddleware
+# 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': '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
+# les routes RESTful (cf http://routes.groovie.org/manual.html#restful-services)
 mapper = Mapper()
-mapper.connect(':controller/')
-mapper.connect(':controller/:id', action='get')
-mapper.connect(':controller/:action/:id')
-mapper.create_regs(['document','demlog','comlog'])
+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')
 
-# objet de base : dispose d'un accès à MS-SQL (lire les données) et d'un accès à jinja (rendu des données)
 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
-        if (self.environ['org.auf.filters'].has_key('format')):
-           self.outputformat=self.environ['org.auf.filters']['format'][0]
-       else:
-           self.outputformat='xml'
+        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
@@ -65,7 +74,10 @@ class document(objetsql):
        output = template.render(documents)
        return self.outputformat, output
 
-    def get(self):
+    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)
@@ -83,6 +95,14 @@ class document(objetsql):
         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')
@@ -91,18 +111,40 @@ 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):
-    """sera lancée par mod_wsgi"""
-    if environ.has_key('QUERY_STRING'):
-        environ['org.auf.filters'] = parse_qs(environ['QUERY_STRING'])
-    else:
-        environ['org.auf.filters'] = {}
+    """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']
-       if environ['REQUEST_METHOD'] != 'GET':
-            method_name = environ['REQUEST_METHOD'] + '_' + method_name
         method = getattr(target_class,method_name)
         type, output = method(target_class(environ))
        start_response("200 OK", [('Content-type', formats[type])])
@@ -111,9 +153,14 @@ def dispatcher(environ, start_response):
         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)
 
-# utilitaires
+
+#
+# petits utilitaires
+#
 def dict_fetchone(cursor):
     """Renvoie le resultat d'un fetchone dans un dictionnaire"""
     result = cursor.fetchone()
@@ -127,10 +174,14 @@ def dict_fetchone(cursor):
     return result_dict
 
 import re 
-p = re.compile('(dem|com)-(...)-auf',re.IGNORECASE)
+p = re.compile('(dem|com)-(...)-(...)',re.IGNORECASE)
 def coda2rest(value):
-    """Traduit un nom CODA en l'objet correspodant, par exemple DEM-LOG-AUF en demlog"""
+    """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
-    return m.group(1).lower() + m.group(2).lower()
+    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()