optimisations et meilleure gestion des erreurs
authorThomas NOEL <thomas@new-dev.(none)>
Thu, 3 Jul 2008 17:15:51 +0000 (13:15 -0400)
committerThomas NOEL <thomas.noel@auf.org>
Thu, 3 Jul 2008 17:15:51 +0000 (13:15 -0400)
rest.wsgi

index 09e55de..a61ba8d 100644 (file)
--- a/rest.wsgi
+++ b/rest.wsgi
@@ -19,6 +19,7 @@ from pymssql import connect
 # pour afficher le résultat : jinja
 from jinja import Environment, FileSystemLoader
 from jinja.filters import stringfilter
+import jinja.exceptions
 
 # TODO systeme de cache : beaker
 # from beaker.middleware import CacheMiddleware
@@ -46,11 +47,15 @@ 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')
+    def template(self,template):
+       self.jinja = Environment(loader=FileSystemLoader('/home/thomas/public_html/'))
+        self.outputformat = self.environ['wsgiorg.routing_args'][1].get('format','xml')
+       return self.jinja.get_template('%s.%s' % (template,self.outputformat))
+    def cursor(self):
+        if not hasattr(self,'bd'):
+            self.bd = connect(host=rest_config.host,user=rest_config.user,password=rest_config.password,database=rest_config.database)
+       return self.bd.cursor()
 
 class document(objetsql):
     """objet document CODA (demlog, comlog, demdep... ils ont tous le même format)"""
@@ -59,40 +64,62 @@ class document(objetsql):
         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=[]
+    def _get_index(self, code):
+        """renvoie une liste de documents"""
+       # connexion a la base de données
+       cursor = self.cursor()
+       # extraction des données
+       cursor.execute("select top 15 * from auf_v_acces_demcom where code like '%s' order by date_modif desc" % code)
+       index = {}
+       index['code'] = code
+       items = []
        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'])
+           item = dict_fetchone( cursor )
+           if item == None: break
+           item['code_rest'] = coda2rest(item['code'])
+           items.append(item)
+       index['documents'] = items
+       return index
+
+    def _get_details(self,code,id):
+         """renvoie la liste des détails pour un document"""
         details = []
-        self.cursor.execute("select * from auf_v_acces_dtls_demcom where code like '%s' and numero = %d" % (self.code_document, id))
+       cursor = self.cursor()
+        cursor.execute("select * from auf_v_acces_dtls_demcom where code like '%s' and numero = %d" % (code, id))
         while 1:
-            detail = dict_fetchone(self.cursor)
+            detail = dict_fetchone(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 details
+
+    def _get_document(self,code,id):
+         """renvoie un document"""
+       cursor = self.cursor()
+        cursor.execute("select top 1 * from auf_v_acces_demcom where code like '%s' and numero = %d" % (code, id))
+        document = dict_fetchone(cursor)
+       if document == None:
+           raise "document inexistant"
+       document['code_rest'] = coda2rest( document['code'] )
+        document['details'] = self._get_details( code,id )
+       return document
+
+    def index(self):
+        """renvoie une liste de documents formatée"""
+       # preparation du modèle
+        template = self.template('%s-index' % self.basename_template)
+       # recherche des documents concernés
+       index = self._get_index( self.code_document )
+       # envoi des données au template
+       output = template.render( index )
+       return self.outputformat, output
+
+    def show(self):
+        """renvoie un document formaté"""
+        # return 'txt', '%s' % self.environ # pour debug
+        id = int(self.environ['wsgiorg.routing_args'][1]['id'])
+        template = self.template( self.basename_template )
+        document = self._get_document( self.code_document, id )
+        output = template.render( document )
        return self.outputformat, output
 
 class dem(document):
@@ -138,24 +165,34 @@ class comare(document):
         impl = environ['wsgiorg.routing_args'][1].get('impl','%')
         super(comare, self).__init__(environ, code_document = 'COM-ARE-%s' % impl)
 
+#
+# fin des objets accessibles
+#
+
 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)
+        method = getattr(target_class,results['action'])
+    except:
+        start_response("404 Not Found", [('Content-type', 'text/html')])
+       return '<html><body><h2>404 objet ou action invalide</h2><pre>%s: %s\n%s</pre></body></html>' % ( sys.exc_info()[0] , sys.exc_info()[1] , traceback.format_exc())
+    try:
         type, output = method(target_class(environ))
        start_response("200 OK", [('Content-type', formats[type])])
         return output.encode('utf-8')
+    except jinja.exceptions.TemplateNotFound, template:
+        start_response("415 Unsupported Media Type", [('Content-type', 'text/html')])
+       return '<html><body><h2>415 format non supporté (%s inexistant)</h2></body></html>' % template
     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())
+        start_response("500 INTERNAL ERROR", [('Content-type', 'text/html')])
+        return '<html><body><h2>500 erreur lors du traitement</h2><pre>%s: %s\n%s</pre></body></html>' % ( 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)
+# TODO : ajouter un middleware de cache (beaker, basé sur REQUEST_URI quand la methode est GET)
 
 
 #