#!/usr/bin/python # -*- coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*- from singleton import Singleton from template import render from functools import partial class WSGITemplate( object ): __metaclass__ = Singleton def __init__( self, basedir='' ): import os self.__basedir = os.path.normpath( os.path.join( os.path.split(__file__)[0], basedir ) ) + '/' self.__fallback_template = \ "
{{ = 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 real_decorator( wsgi_application ):
def wrapper( environ, start_response ):
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
class WSGIMySQL( object ):
__metaclass__ = Singleton
def __init__( self, dsn, *args ):
""" inizializza le connessioni a 1 o più database.
In caso di connessioni a databese multipli,
le connessioni sono identificate tramite ALIAS
o in mancanza di questo tramite DB
ogni singolo dsn deve essere un dizionario con le chiavi:
- DB : nome del database
- HOST : host a cui connettersi
- USER : username da utilizzare per connettersi
- PASSWORD : password da utilizzare per connettersi
- ALIAS : (opzionale) identificativo della connessione
"""
import MySQLdb
#
# aggiungiamo il primo dsn in cima alla lista
#
args = list( args )
args.insert( 0, dsn )
#
# creiamo il nostro dizionario di dizionari
#
self.__dsn = { dsndict.get( 'ALIAS', dsndict['DB'] ):dsndict for dsndict in args }
#
# verifichiamo che non ci siano alias duplicati
#
if len( self.__dsn.keys() ) != len( args ):
raise Exception( "WSGIMySQL :: conflicting alias in dsn list" )
#
# tentiamo di creare la prima connessione verso TUTTI i dsn passati
#
for alias, dsndict in self.__dsn.iteritems():
dsndict['pool'] = [ self.__newconn( alias ) ]
self.__dict_cursor = MySQLdb.cursors.DictCursor
def __newconn( self, alias ):
import MySQLdb
return MySQLdb.connect(
host = self.__dsn[ alias ]["HOST"],
user = self.__dsn[ alias ]["USER"],
passwd = self.__dsn[ alias ]["PASSWORD"],
db = self.__dsn[ alias ]["DB"]
)
def db( self, *args ):
def real_decorator( wsgi_application ):
def wrapper( environ, start_response ):
connections = []
for arg in args:
try:
conn = self.__dsn[ arg ]['pool'].pop( 0 )
except IndexError:
conn = self.__newconn( arg )
connections.append( conn )
cur = conn.cursor( self.__dict_cursor )
environ['mysql.' + arg + '.cur'] = cur
try:
for item in wsgi_application( environ, start_response ):
yield item
finally:
for arg in args:
conn = connections.pop(0)
conn.commit()
self.__dsn[ arg ]['pool'].append( conn )
return wrapper
return real_decorator
def __del__( self ):
#
# chiudiamo tutte le connessioni attualmente aperte
#
for dsndict in self.__dsn.items():
for conn in dsndict['pool']:
conn.close()