|
- #!/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 = \
- "<h1> NO TEMPLATE DEFINED </h1>\n" \
- "{{ from pprint import pformat }}" \
- "<pre>{{ = pformat( { k:v for k,v in locals().iteritems() if k not in ('NOESCAPE','__builtins__','pformat','response') }, width=132 ) }}</pre>\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()
|