Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

128 rindas
4.0 KiB

  1. #!/usr/bin/python
  2. # -*- coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*-
  3. from singleton import Singleton
  4. from template import render
  5. from functools import partial
  6. class WSGITemplate( object ):
  7. __metaclass__ = Singleton
  8. def __init__( self, basedir='' ):
  9. import os
  10. self.__basedir = os.path.normpath( os.path.join( os.path.split(__file__)[0], basedir ) ) + '/'
  11. self.__fallback_template = \
  12. "<h1> NO TEMPLATE DEFINED </h1>\n" \
  13. "{{ from pprint import pformat }}" \
  14. "<pre>{{ = pformat( { k:v for k,v in locals().iteritems() if k not in ('NOESCAPE','__builtins__','pformat','response') }, width=132 ) }}</pre>\n\n"
  15. def template( self, filename=None ):
  16. def real_decorator( wsgi_application ):
  17. def wrapper( environ, start_response ):
  18. if filename:
  19. environ[ 'template' ] = partial( render, filename=self.__basedir + filename )
  20. else:
  21. environ[ 'template' ] = partial( render, content=self.__fallback_template )
  22. return wsgi_application( environ, start_response )
  23. return wrapper
  24. return real_decorator
  25. class WSGIMySQL( object ):
  26. __metaclass__ = Singleton
  27. def __init__( self, dsn, *args ):
  28. """ inizializza le connessioni a 1 o più database.
  29. In caso di connessioni a databese multipli,
  30. le connessioni sono identificate tramite ALIAS
  31. o in mancanza di questo tramite DB
  32. ogni singolo dsn deve essere un dizionario con le chiavi:
  33. - DB : nome del database
  34. - HOST : host a cui connettersi
  35. - USER : username da utilizzare per connettersi
  36. - PASSWORD : password da utilizzare per connettersi
  37. - ALIAS : (opzionale) identificativo della connessione
  38. """
  39. import MySQLdb
  40. #
  41. # aggiungiamo il primo dsn in cima alla lista
  42. #
  43. args = list( args )
  44. args.insert( 0, dsn )
  45. #
  46. # creiamo il nostro dizionario di dizionari
  47. #
  48. self.__dsn = { dsndict.get( 'ALIAS', dsndict['DB'] ):dsndict for dsndict in args }
  49. #
  50. # verifichiamo che non ci siano alias duplicati
  51. #
  52. if len( self.__dsn.keys() ) != len( args ):
  53. raise Exception( "WSGIMySQL :: conflicting alias in dsn list" )
  54. #
  55. # tentiamo di creare la prima connessione verso TUTTI i dsn passati
  56. #
  57. for alias, dsndict in self.__dsn.iteritems():
  58. dsndict['pool'] = [ self.__newconn( alias ) ]
  59. self.__dict_cursor = MySQLdb.cursors.DictCursor
  60. def __newconn( self, alias ):
  61. import MySQLdb
  62. return MySQLdb.connect(
  63. host = self.__dsn[ alias ]["HOST"],
  64. user = self.__dsn[ alias ]["USER"],
  65. passwd = self.__dsn[ alias ]["PASSWORD"],
  66. db = self.__dsn[ alias ]["DB"]
  67. )
  68. def db( self, *args ):
  69. def real_decorator( wsgi_application ):
  70. def wrapper( environ, start_response ):
  71. connections = []
  72. for arg in args:
  73. try:
  74. conn = self.__dsn[ arg ]['pool'].pop( 0 )
  75. except IndexError:
  76. conn = self.__newconn( arg )
  77. connections.append( conn )
  78. cur = conn.cursor( self.__dict_cursor )
  79. environ['mysql.' + arg + '.cur'] = cur
  80. try:
  81. for item in wsgi_application( environ, start_response ):
  82. yield item
  83. finally:
  84. for arg in args:
  85. conn = connections.pop(0)
  86. conn.commit()
  87. self.__dsn[ arg ]['pool'].append( conn )
  88. return wrapper
  89. return real_decorator
  90. def __del__( self ):
  91. #
  92. # chiudiamo tutte le connessioni attualmente aperte
  93. #
  94. for dsndict in self.__dsn.items():
  95. for conn in dsndict['pool']:
  96. conn.close()