diff --git a/decorators.py b/decorators.py index 1a1e280..866934c 100644 --- a/decorators.py +++ b/decorators.py @@ -9,16 +9,74 @@ from functools import partial class WSGITemplate( object ): __metaclass__ = Singleton - def __init__( self, basedir=None ): + def __init__( self, basedir='' ): import os self.__basedir = os.path.normpath( os.path.join( os.path.split(__file__)[0], basedir ) ) + '/' + self.__fallback_template = \ + "

NO TEMPLATE DEFINED

\n" \ + "{{ from pprint import pformat }}" \ + "
{{ = pformat( { k:v for k,v in locals().iteritems() if k not in ('NOESCAPE','__builtins__','pformat','response') }, width=132 ) }}
\n\n" - def template(self, filename=None ): + def template( self, filename=None ): def real_decorator( wsgi_application ): def wrapper( environ, start_response ): - environ[ 'template' ] = partial( render, filename= self.__basedir + filename ) - environ[ 'basedir' ] = self.__basedir + if filename: + environ[ 'template' ] = partial( render, filename=self.__basedir + filename ) + else: + environ[ 'template' ] = partial( render, content=self.__fallback_template ) return wsgi_application( environ, start_response ) + return wrapper - return real_decorator \ No newline at end of file + + return real_decorator + + +class WSGIMySQL( object ): + __metaclass__ = Singleton + + def __init__( self, dsn, *args ): + import MySQLdb + + self.__dsn = dsn + self.__pool = [ self.__newconn() ] + self.__dict_cursor = MySQLdb.cursors.DictCursor + + + def __newconn( self ): + import MySQLdb + + return MySQLdb.connect( + host = self.__dsn["HOST"], + user = self.__dsn["USER"], + passwd = self.__dsn["PASSWORD"], + db = self.__dsn["DB"] + ) + + def db( self, *args ): + def real_decorator( wsgi_application ): + def wrapper( environ, start_response ): + try: + conn = self.__pool.pop( 0 ) + except IndexError: + conn = self.__newconn() + + cur = conn.cursor( self.__dict_cursor ) + + environ['mysql.cur'] = cur + + try: + for item in wsgi_application( environ, start_response ): + yield item + finally: + conn.commit() + self.__pool.append( conn ) + + return wrapper + + return real_decorator + + + def __del__( self ): + for conn in self.__pool: + conn.close() diff --git a/dispatch_wsgi.py b/dispatch_wsgi.py index 5a3fb7a..fee191b 100755 --- a/dispatch_wsgi.py +++ b/dispatch_wsgi.py @@ -17,7 +17,21 @@ from decorators import WSGITemplate WSGITemplate( basedir='views' ) # -# importazione handler +# inizializzazione connessione al db ( mysql ) +# +from decorators import WSGIMySQL +WSGIMySQL( + dsn = dict( + DB = "mywiki", + HOST = "localhost", + USER = "corso", + PASSWORD = "pwdcorso" + ) +) + + +# +# importazione handler definiti esternamente # from router import WSGIRouter, WSGISmartRouter @@ -50,12 +64,12 @@ def fallback( environ, start_response ): # # definiamo gli handler per le url che vogliamo servire # -from test_mysql import simple_mysql +################################################################################ from test_mysql import simple_mysql handlers = ( ( r'/', index ), ( r'/hello', hello ), - ( r'/mysql', simple_mysql ), + ############################################################################ ( r'/mysql', simple_mysql ), ) diff --git a/nanowsgi.wpu b/nanowsgi.wpu index fc827d9..8a3f2d5 100644 --- a/nanowsgi.wpu +++ b/nanowsgi.wpu @@ -4,7 +4,7 @@ # Wing IDE project file : User-specific branch # ################################################################## [user attributes] -console.id-seed = 2 +console.id-seed = 6 console.toolbox = [{'autosave': False, 'ctype': ('cmd', 'tail -f /var/log/apache2/error.log'), @@ -60,10 +60,13 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window', 'tree-states': {'deep': {'column-widths': None, 'expanded-nodes': [(0,), (1,), + (1, + 0), (2,), (3,)], - 'selected-nodes': [(3, - 3)], + 'selected-nodes': [(1, + 0, + 1)], 'top-node': (0,)}}, 'tree-style': 'deep'}}), ('refactoring', @@ -100,7 +103,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window', 'primary_view_state': {'area': 'wide', 'constraint': None, 'current_pages': [6], - 'notebook_display': 'normal', + 'notebook_display': 'tabs only', 'notebook_percent': 0.39739413680781754, 'override_title': None, 'pagelist': [('bookmarks', @@ -429,223 +432,300 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window', 'expanded-nodes': [(0,)], 'selected-nodes': [], 'top-node': (0,)}})], - 'primary_view_state': {'editor_states': {'bookmarks': ([[loc('../corso_python/www/wsgi/wsgi_test.py'), - {'attrib-starts': [], + 'primary_view_state': {'editor_states': {'bookmarks': ([(loc('controllers/demo.py'), + {'attrib-starts': [('get', + 14)], 'first-line': 0, 'folded-linenos': [], - 'sel-line': 0, - 'sel-line-start': 0, - 'selection_end': 148, - 'selection_start': 0}, - 1352922666.5966339], - [loc('../corso_python/www/wsgi/sqlpooler.py'), + 'sel-line': 19, + 'sel-line-start': 511, + 'selection_end': 535, + 'selection_start': 535}, + 1353075633.076438), + (loc('../corso_python/www/wsgi/sqlpooler.py'), {'attrib-starts': [('WSGISqlPoolMySQL', - 4)], - 'first-line': 0, - 'folded-linenos': [21, - 34, - 67, - 80], - 'sel-line': 7, - 'sel-line-start': 268, - 'selection_end': 275, - 'selection_start': 275}, - 1352922666.8889589], - [loc('../corso_python/www/static/index.html'), - {'attrib-starts': [], + 4), + ('WSGISqlPoolMySQL.__call__', + 34)], 'first-line': 0, 'folded-linenos': [], - 'sel-line': 4, - 'sel-line-start': 68, - 'selection_end': 78, - 'selection_start': 78}, - 1352922667.347193], - [loc('../corso_python/www/static/dispatch_wsgi.py'), + 'sel-line': 54, + 'sel-line-start': 1723, + 'selection_end': 1739, + 'selection_start': 1739}, + 1353075665.5788369), + (loc('../corso_python/www/static/dispatch_wsgi.py'), {'attrib-starts': [], - 'first-line': 37, + 'first-line': 39, 'folded-linenos': [], - 'sel-line': 51, - 'sel-line-start': 1203, - 'selection_end': 1249, - 'selection_start': 1217}, - 1352922667.6854961], - [loc('../corso_python/www/static/dispatch_fcgi.py'), - {'attrib-starts': [], - 'first-line': 25, + 'sel-line': 45, + 'sel-line-start': 1075, + 'selection_end': 1196, + 'selection_start': 1075}, + 1353075682.988924), + (loc('decorators.py'), + {'attrib-starts': [('WSGITemplate', + 8), + ('WSGITemplate.__init__', + 11)], + 'first-line': 22, 'folded-linenos': [], - 'sel-line': 41, - 'sel-line-start': 913, - 'selection_end': 945, - 'selection_start': 913}, - 1352922668.0699551], - [loc('../corso_python/www/static/.htaccess'), + 'sel-line': 15, + 'sel-line-start': 430, + 'selection_end': 461, + 'selection_start': 461}, + 1353075698.5145061), + (loc('dispatch_wsgi.py'), {'attrib-starts': [], - 'first-line': 34, + 'first-line': 14, 'folded-linenos': [], - 'sel-line': 54, - 'sel-line-start': 1157, - 'selection_end': 1157, - 'selection_start': 1157}, - 1352922668.490283], - [loc('../corso_python/www/protected/info_handler.py'), - {'attrib-starts': [('info', - 22)], - 'first-line': 0, - 'folded-linenos': [], - 'sel-line': 34, - 'sel-line-start': 1127, - 'selection_end': 1151, - 'selection_start': 1127}, - 1352922668.901685], - [loc('../corso_python/www/protected/hello_handler.py'), - {'attrib-starts': [('hello', - 18)], - 'first-line': 0, - 'folded-linenos': [], - 'sel-line': 46, - 'sel-line-start': 1148, - 'selection_end': 1213, - 'selection_start': 1153}, - 1352922669.3464761], - [loc('../corso_python/www/protected/fallback_handler.py'), + 'sel-line': 29, + 'sel-line-start': 601, + 'selection_end': 601, + 'selection_start': 601}, + 1353075701.1062429), + [loc('sql.py'), {'attrib-starts': [], 'first-line': 0, 'folded-linenos': [], 'sel-line': 3, 'sel-line-start': 81, - 'selection_end': 108, + 'selection_end': 164, 'selection_start': 81}, - 1352922669.920784], - [loc('../corso_python/www/cgi/dispatch_cgi.py'), + 1353075751.1481929], + (loc('../corso_python/www/static/dispatch_wsgi.py'), {'attrib-starts': [], + 'first-line': 39, + 'folded-linenos': [], + 'sel-line': 45, + 'sel-line-start': 1075, + 'selection_end': 1196, + 'selection_start': 1075}, + 1353075829.8857551), + (loc('../corso_python/www/wsgi/sqlpooler.py'), + {'attrib-starts': [('WSGISqlPoolMySQL', + 4), + ('WSGISqlPoolMySQL.__call__', + 34)], 'first-line': 0, 'folded-linenos': [], - 'sel-line': 5, - 'sel-line-start': 162, - 'selection_end': 164, - 'selection_start': 164}, - 1352922670.2010989], - [loc('../corso_python/www/apache_config.txt'), + 'sel-line': 54, + 'sel-line-start': 1723, + 'selection_end': 1739, + 'selection_start': 1739}, + 1353075837.216579), + (loc('dispatch_wsgi.py'), {'attrib-starts': [], - 'first-line': 6, + 'first-line': 59, + 'folded-linenos': [], + 'sel-line': 29, + 'sel-line-start': 601, + 'selection_end': 601, + 'selection_start': 601}, + 1353075862.859385), + (loc('test_mysql.py'), + {'attrib-starts': [('simple_mysql', + 3)], + 'first-line': 15, 'folded-linenos': [], 'sel-line': 16, - 'sel-line-start': 467, - 'selection_end': 499, - 'selection_start': 499}, - 1352922670.649184], - (loc('controllers/demo.py'), - {'attrib-starts': [('get', - 14)], - 'first-line': 17, + 'sel-line-start': 415, + 'selection_end': 727, + 'selection_start': 415}, + 1353075879.6448979), + (loc('controllers/demo/sql.py'), + {'attrib-starts': [('application', + 11)], + 'first-line': 9, 'folded-linenos': [], - 'sel-line': 27, - 'sel-line-start': 805, - 'selection_end': 811, - 'selection_start': 811}, - 1352970566.1362541), - (loc('static/index.html'), - {'attrib-starts': [], - 'first-line': 0, + 'sel-line': 26, + 'sel-line-start': 547, + 'selection_end': 547, + 'selection_start': 547}, + 1353075896.5156269), + (loc('decorators.py'), + {'attrib-starts': [('WSGIMySQL', + 34), + ('WSGIMySQL.db', + 51), + ('WSGIMySQL.db.real_decorator', + 52), + ('WSGIMySQL.db.real_decorator.wrapper', + 53)], + 'first-line': 42, 'folded-linenos': [], - 'sel-line': 11, - 'sel-line-start': 315, - 'selection_end': 315, - 'selection_start': 315}, - 1352970992.829721), - (loc('controllers/demo.py'), - {'attrib-starts': [('get', - 14)], - 'first-line': 17, + 'sel-line': 59, + 'sel-line-start': 1904, + 'selection_end': 1954, + 'selection_start': 1954}, + 1353075950.644135), + (loc('controllers/demo/sql.py'), + {'attrib-starts': [('application', + 11)], + 'first-line': 9, 'folded-linenos': [], - 'sel-line': 27, - 'sel-line-start': 805, - 'selection_end': 811, - 'selection_start': 811}, - 1352971019.481142), - (loc('dispatch_wsgi.py'), - {'attrib-starts': [], - 'first-line': 31, + 'sel-line': 14, + 'sel-line-start': 304, + 'selection_end': 304, + 'selection_start': 304}, + 1353076011.1992331), + (loc('decorators.py'), + {'attrib-starts': [('WSGIMySQL', + 34), + ('WSGIMySQL.db', + 55), + ('WSGIMySQL.db.real_decorator', + 56), + ('WSGIMySQL.db.real_decorator.wrapper', + 57)], + 'first-line': 30, 'folded-linenos': [], - 'sel-line': 0, - 'sel-line-start': 0, - 'selection_end': 0, - 'selection_start': 0}, - 1352971025.356674), - (loc('static/index.html'), - {'attrib-starts': [], - 'first-line': 0, + 'sel-line': 63, + 'sel-line-start': 1985, + 'selection_end': 2038, + 'selection_start': 2038}, + 1353076048.7585621), + (loc('controllers/demo/sql.py'), + {'attrib-starts': [('application', + 11)], + 'first-line': 9, 'folded-linenos': [], - 'sel-line': 10, - 'sel-line-start': 268, - 'selection_end': 318, - 'selection_start': 318}, - 1352971029.3790801), - (loc('dispatch_wsgi.py'), + 'sel-line': 29, + 'sel-line-start': 597, + 'selection_end': 633, + 'selection_start': 633}, + 1353076170.14289), + (loc('test_mysql.py'), {'attrib-starts': [], - 'first-line': 31, + 'first-line': 0, 'folded-linenos': [], 'sel-line': 0, 'sel-line-start': 0, 'selection_end': 0, 'selection_start': 0}, - 1352971052.15623), - (loc('static/index.html'), + 1353076484.6436961), + (loc('dispatch_wsgi.py'), + {'attrib-starts': [('fallback', + 54)], + 'first-line': 39, + 'folded-linenos': [], + 'sel-line': 61, + 'sel-line-start': 1549, + 'selection_end': 1554, + 'selection_start': 1554}, + 1353076572.715292), + (loc('controllers/demo/sql.py'), {'attrib-starts': [], 'first-line': 0, 'folded-linenos': [], - 'sel-line': 9, - 'sel-line-start': 209, - 'selection_end': 240, - 'selection_start': 235}, - 1352971058.338448), + 'sel-line': 10, + 'sel-line-start': 205, + 'selection_end': 228, + 'selection_start': 228}, + 1353078077.1347899), (loc('dispatch_wsgi.py'), - {'attrib-starts': [], - 'first-line': 31, + {'attrib-starts': [('fallback', + 54)], + 'first-line': 0, 'folded-linenos': [], - 'sel-line': 0, - 'sel-line-start': 0, - 'selection_end': 0, - 'selection_start': 0}, - 1352971071.333266), - [loc('static/index.html'), + 'sel-line': 61, + 'sel-line-start': 1549, + 'selection_end': 1554, + 'selection_start': 1554}, + 1353078144.7990141), + [loc('controllers/demo/sql.py'), {'attrib-starts': [], 'first-line': 0, 'folded-linenos': [], - 'sel-line': 9, - 'sel-line-start': 209, - 'selection_end': 240, - 'selection_start': 235}, - 1352971072.960921]], + 'sel-line': 10, + 'sel-line-start': 205, + 'selection_end': 228, + 'selection_start': 228}, + 1353078225.3298531]], 19), - 'current-loc': loc('static/index.html'), - 'editor-states': {loc('controllers/demo.py'): {'attrib-starts': [('g'\ + 'current-loc': loc('controllers/demo/sql.py'), + 'editor-states': {loc('../corso_python/www/static/dispatch_wsgi.py'): {''\ + 'attrib-starts': [], + 'first-line': 39, + 'folded-linenos': [], + 'sel-line': 45, + 'sel-line-start': 1075, + 'selection_end': 1196, + 'selection_start': 1075}, + loc('../corso_python/www/wsgi/sqlpooler.py'): {'at'\ + 'trib-starts': [('WSGISqlPoolMySQL', + 4), + ('WSGISqlPoolMySQL.__call__', + 34)], + 'first-line': 0, + 'folded-linenos': [], + 'sel-line': 54, + 'sel-line-start': 1723, + 'selection_end': 1739, + 'selection_start': 1739}, + loc('controllers/demo.py'): {'attrib-starts': [('g'\ 'et', 14)], - 'first-line': 17, + 'first-line': 0, 'folded-linenos': [], - 'sel-line': 27, - 'sel-line-start': 805, - 'selection_end': 811, - 'selection_start': 811}, - loc('dispatch_wsgi.py'): {'attrib-starts': [], - 'first-line': 31, + 'sel-line': 19, + 'sel-line-start': 511, + 'selection_end': 535, + 'selection_start': 535}, + loc('controllers/demo/due.py'): {'attrib-starts': [], + 'first-line': 0, 'folded-linenos': [], 'sel-line': 0, 'sel-line-start': 0, - 'selection_end': 0, + 'selection_end': 598, 'selection_start': 0}, + loc('controllers/demo/sql.py'): {'attrib-starts': [], + 'first-line': 9, + 'folded-linenos': [], + 'sel-line': 10, + 'sel-line-start': 205, + 'selection_end': 228, + 'selection_start': 228}, + loc('decorators.py'): {'attrib-starts': [('WSGIMyS'\ + 'QL', + 34), + ('WSGIMySQL.db', + 55), + ('WSGIMySQL.db.real_decorator', + 56), + ('WSGIMySQL.db.real_decorator.wrapper', + 57)], + 'first-line': 30, + 'folded-linenos': [], + 'sel-line': 63, + 'sel-line-start': 1985, + 'selection_end': 2038, + 'selection_start': 2038}, + loc('dispatch_wsgi.py'): {'attrib-starts': [('fall'\ + 'back', + 54)], + 'first-line': 0, + 'folded-linenos': [], + 'sel-line': 61, + 'sel-line-start': 1549, + 'selection_end': 1554, + 'selection_start': 1554}, loc('static/index.html'): {'attrib-starts': [], 'first-line': 0, 'folded-linenos': [], - 'sel-line': 11, - 'sel-line-start': 335, - 'selection_end': 394, - 'selection_start': 394}}, + 'sel-line': 14, + 'sel-line-start': 539, + 'selection_end': 590, + 'selection_start': 590}}, 'has-focus': True}, - 'open_files': [u'controllers/demo.py', + 'open_files': [u'../corso_python/www/static/dispatch_wsgi.py', + u'../corso_python/www/wsgi/sqlpooler.py', + u'controllers/demo.py', + u'controllers/demo/due.py', + u'decorators.py', u'dispatch_wsgi.py', - u'static/index.html']}, + u'static/index.html', + u'controllers/demo/sql.py']}, 'saved_notebook_display': None, 'split_percents': {0: 0.33189122373300373}, 'splits': 1, @@ -656,10 +736,15 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window', 'splits': 2, 'tab_location': 'left', 'user_data': {}}, - 'window-alloc': (38, - 40, - 1322, - 964)}]} -guimgr.recent-documents = [loc('static/index.html'), + 'window-alloc': (10, + 33, + 1639, + 965)}]} +guimgr.recent-documents = [loc('controllers/demo/sql.py'), + loc('static/index.html'), loc('dispatch_wsgi.py'), - loc('controllers/demo.py')] + loc('decorators.py'), + loc('../corso_python/www/wsgi/sqlpooler.py'), + loc('../corso_python/www/static/dispatch_wsgi.py'), + loc('controllers/demo.py'), + loc('controllers/demo/due.py')] diff --git a/static/index.html b/static/index.html index 9efadfd..2f4306b 100644 --- a/static/index.html +++ b/static/index.html @@ -12,6 +12,7 @@
  • test MYSQL access
  • test autorouting
  • test autorouting (longest path possible)
  • +
  • test sql access
  • diff --git a/test_mysql.py b/test_mysql.py deleted file mode 100644 index 3f76254..0000000 --- a/test_mysql.py +++ /dev/null @@ -1,36 +0,0 @@ -import MySQLdb -from config import config - -def simple_mysql( environ, start_response ): - # - # collegamento al mysql - # - # for more options see: - # http://mysql-python.sourceforge.net/MySQLdb.html#introduction - conn = MySQLdb.connect( - host = config['MYSQL_HOST'], - user = config['MYSQL_USER'], - passwd = config['MYSQL_PASSWORD'], - db = config['MYSQL_DB'] - ) - - # - # esecuzione query - # - cur = conn.cursor( MySQLdb.cursors.DictCursor ) - cur.execute( 'SHOW tables;' ) - - # - # recupero record e generazione html - # - - start_response( '200 OK', [('Content-Type', 'text/plain')] ) - - for record in cur.fetchall(): - yield "\n" + str( record ) - - # - # chiusura connessione al mysql - # - conn.close() -