PageRenderTime 30ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/core/promogest/Environment.py

http://promogest.googlecode.com/
Python | 643 lines | 614 code | 12 blank | 17 comment | 3 complexity | a98b0bac7ef1006d02f6857614025959 MD5 | raw file
Possible License(s): GPL-2.0
  1. # -*- coding: utf-8 -*-
  2. # Copyright (C) 2005, 2006, 2007 2008, 2009, 2010 by Promotux
  3. # di Francesco Meloni snc - http://www.promotux.it/
  4. # Author: Francesco Meloni <francesco@promotux.it>
  5. # This file is part of Promogest.
  6. # Promogest is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 2 of the License, or
  9. # (at your option) any later version.
  10. # Promogest is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. # You should have received a copy of the GNU General Public License
  15. # along with Promogest. If not, see <http://www.gnu.org/licenses/>.
  16. from promogest import pg3_check
  17. pg3 = pg3_check.pg3_cla
  18. aziendaforce = pg3_check.aziendaforce
  19. tipodbforce = pg3_check.tipodbforce
  20. import locale
  21. from config import Config
  22. if pg3:
  23. from gi.repository import Gtk as gtk
  24. else:
  25. import gtk
  26. try:
  27. settings = gtk.settings_get_default()
  28. gtk.Settings.set_long_property(settings, "gtk-button-images", 1, "main")
  29. except:
  30. print "Aggiunta icone non ha funzionato"
  31. import os
  32. import shutil
  33. import glob
  34. import getopt, sys
  35. import sqlalchemy
  36. SAVER = sqlalchemy.__version__
  37. from sqlalchemy import *
  38. from sqlalchemy.orm import *
  39. from sqlalchemy.interfaces import PoolListener
  40. #from sqlalchemy import event
  41. #from sqlalchemy.pool import NullPool
  42. from sqlalchemy.interfaces import ConnectionProxy
  43. from sqlalchemy.exc import *
  44. import logging
  45. import logging.handlers
  46. import smtplib
  47. import string
  48. from email.MIMEBase import MIMEBase
  49. from email.MIMEMultipart import MIMEMultipart
  50. from email.MIMEBase import MIMEBase
  51. from email.MIMEText import MIMEText
  52. from email.Utils import COMMASPACE, formatdate
  53. from email.mime.image import MIMEImage
  54. from email.Header import Header
  55. from email import Encoders
  56. import datetime
  57. PRODOTTO = "PromoTux"
  58. VERSIONE = "PromoGest 2.7.0.1"
  59. debugFilter = False
  60. debugDao = False
  61. debugSQL = False
  62. reportTemplatesDir = None
  63. imagesDir = None
  64. labelTemplatesDir = None
  65. templatesDir = None
  66. documentsDir = None
  67. conf = None
  68. promogestDir = None
  69. exceptionHandler = None
  70. connection = None
  71. feed = None
  72. emailcompose = None
  73. loc = None
  74. subject= None
  75. body = None
  76. rivenditoreUrl = None
  77. smtpServer = None
  78. emailmittente = None
  79. cliente_predefinito = None
  80. tipo_documento_predefinito = None
  81. multilinelimit = None
  82. mltext = None
  83. bordoDestro = None
  84. bordoSinistro = None
  85. feedCache = ""
  86. feedAll = ""
  87. scontisave = {}
  88. tagliacoloretempdata = (False,None)
  89. lastCode = None
  90. modules_folders = []
  91. righeDocumentoDict = {}
  92. totaliDict = {}
  93. percentualeIvaRiga = None
  94. aliquotaIvaRiga = None
  95. modulesList = []
  96. listinoFissato = None
  97. new_print_enjine=True
  98. shop = False
  99. rev_locale = None
  100. rev_remota = None
  101. magazzino_pos = None
  102. windowGroup = []
  103. view = "month"
  104. puntoA = None
  105. puntoB = None
  106. puntoP = None
  107. eta = 0
  108. tipo_pg = None
  109. cartella_moduli = 'promogest/modules'
  110. totale_pn_con_riporto = 0
  111. da_data_inizio_primanota = None
  112. a_data_inizio_primanota = None
  113. hapag = ["Fattura accompagnatoria","Fattura acquisto","Fattura differita acquisto",
  114. "Fattura differita vendita","Fattura vendita","Ricevuta Fiscale","Vendita dettaglio",
  115. "Nota di credito a cliente","Nota di credito da fornitore"]
  116. fromHtmlLits = ["Promemoria", "TestataPrimaNota","Articolo", "Cliente",
  117. "Contatto", "Fornitore", "Fornitura", "Contatto", "Vettore",
  118. "AliquotaIva", "TestataCommessa"]
  119. package = ["ONE BASIC", "ONE FULL", "ONE STANDARD", "PRO BASIC", "PRO STANDARD",
  120. "PRO FULL","ONE PROMOWEAR", "ONE PROMOSHOP", "PRO PROMOWEAR", "PRO PROMOSHOP"]
  121. loc = locale.setlocale(locale.LC_ALL, '')
  122. mm = {'3996679c06ebc369feefc92063644d83':'e4da3b7fbbce2345d7772b0674a318d5', #Contatto = 5
  123. 'cfe6753e5e82f522119e09df7b726e4a':'eccbc87e4b5ce2fe28308fd9f2a7baf3'} #Promemoria = 3
  124. confList=[]
  125. configDir= None
  126. def getConfigureDir(company='__default__'):
  127. """ Tests if another configuration folder was indicated """
  128. default='promogest2'
  129. if company != '__default__' and company is not None:
  130. default = os.path.join('promogest2',company)
  131. try:
  132. opts, args = getopt.getopt(sys.argv[1:], "c:", ["config-dir="])
  133. for opt, arg in opts:
  134. if opt in ("-c", "--config-dir"):
  135. return arg
  136. else:
  137. return default
  138. except getopt.GetoptError:
  139. return default
  140. def startdir():
  141. startDir = getConfigureDir()
  142. promogestStartDir = os.path.expanduser('~') + os.sep + startDir + os.sep
  143. return promogestStartDir
  144. def messageInfoEnv(msg="Messaggio generico", transient=None):
  145. """generic msg dialog """
  146. dialoggg = gtk.MessageDialog(transient,
  147. gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
  148. gtk.MESSAGE_INFO,
  149. gtk.BUTTONS_OK,
  150. msg)
  151. try:
  152. pg2log.info(msg)
  153. except:
  154. pass
  155. dialoggg.run()
  156. dialoggg.destroy()
  157. class MyProxy(ConnectionProxy):
  158. def cursor_execute(self, execute, cursor, statement, parameters, context, executemany):
  159. try:
  160. return execute(cursor, statement, parameters, context)
  161. except OperationalError as e:
  162. # Handle this exception
  163. # print("ATTENZIONE:OperationalError",e)
  164. messageInfoEnv(msg="UN ERRORE Č STATO INTERCETTATO E SEGNALATO: "+e.message)
  165. # pass
  166. except IntegrityError as e:
  167. # Handle this exception
  168. # print("ATTENZIONE:IntegrityError",e)
  169. messageInfoEnv(msg="IntegrityError UN ERRORE Č STATO INTERCETTATO E SEGNALATO: "+e.message)
  170. session.rollback()
  171. except ProgrammingError as e:
  172. # Handle this exception
  173. # print("ATTENZIONE:ProgrammingError",e)
  174. messageInfoEnv(msg="UN ERRORE Č STATO INTERCETTATO E SEGNALATO: "+e.message)
  175. session.rollback()
  176. except InvalidRequestError as e:
  177. # Handle this exception
  178. # print("ATTENZIONE:InvalidRequestError",e)
  179. messageInfoEnv(msg="UN ERRORE Č STATO INTERCETTATO E SEGNALATO: "+e.message)
  180. session.rollback()
  181. except AssertionError as e:
  182. # Handle this exception
  183. # print("ATTENZIONE:AssertionError",e)
  184. messageInfoEnv(msg="UN ERRORE Č STATO INTERCETTATO E SEGNALATO\n Possibile tentativo di cancellazione di un dato\n collegato ad altri dati fondamentali: "+e.message)
  185. session.rollback()
  186. except ValueError as e:
  187. # Handle this exception
  188. # print("ATTENZIONE:ValueError",e)
  189. messageInfoEnv(msg="Risulta inserito un Valore non corretto. Ricontrolla: "+e.message)
  190. session.rollback()
  191. def _pg8000():
  192. try:
  193. engine = create_engine('postgresql+pg8000:'+'//'
  194. +user+':'
  195. + password+ '@'
  196. + host + ':'
  197. + port + '/'
  198. + database,
  199. encoding='utf-8',pool_size=30,
  200. convert_unicode=True,proxy=MyProxy() )
  201. # pg2log.info("PG8000")
  202. return engine
  203. except:
  204. # pg2log.info("PG8000 NON PRESENTE")
  205. return None
  206. def _py_postgresql():
  207. try:
  208. engine = create_engine('postgresql+pypostgresql:'+'//'
  209. +user+':'
  210. + password+ '@'
  211. + host + ':'
  212. + port + '/'
  213. + database,
  214. encoding='utf-8',pool_size=30,
  215. convert_unicode=True,proxy=MyProxy())
  216. # pg2log.info("PY-POSTGRESQL")
  217. return engine
  218. except:
  219. # pg2log.info("PY-POSTGRESQL NON PRESENTE")
  220. return None
  221. def connect():
  222. import psycopg2
  223. a=None
  224. try:
  225. a = psycopg2.connect(user=user, host=host, port=port,
  226. password=password, database=database)
  227. except Exception, e:
  228. a= "CONNESSIONE AL DATABASE PRO NON RIUSCITA.\n DETTAGLIO ERRORE: [%s]" % ( e,)
  229. messageInfoEnv(msg=a)
  230. exit( )
  231. if a:
  232. return a
  233. def _psycopg2new():
  234. try:
  235. engine = create_engine('postgresql://', creator=connect,
  236. convert_unicode=True,
  237. encoding='utf-8',
  238. proxy=MyProxy())
  239. # engine = create_engine('postgresql:'+'//'
  240. # +user+':'
  241. # + password+ '@'
  242. # + host + ':'
  243. # + port + '/'
  244. # + database,
  245. # encoding='utf-8',pool_size=30,
  246. # convert_unicode=True,proxy=MyProxy() )
  247. return engine
  248. except:
  249. return None
  250. def _psycopg2old():
  251. try:
  252. engine = create_engine('postgres:'+'//'
  253. +user+':'
  254. + password+ '@'
  255. + host + ':'
  256. + port + '/'
  257. + database,
  258. encoding='utf-8',pool_size=30,
  259. convert_unicode=True,proxy=MyProxy())
  260. # print "PSYCOPG2 OLD"
  261. # pg2log.info("PSYCOPG2 OLD")
  262. return engine
  263. except:
  264. # pg2log.info("PSYCOPG2 OLD NON PRESENTE")
  265. return None
  266. try:
  267. promogestStartDir = startdir()
  268. if not (os.path.exists(promogestStartDir)):
  269. os.mkdir(promogestStartDir)
  270. configFile = promogestStartDir + 'configure'
  271. conf = Config(configFile)
  272. conf.guiDir = '.' + os.sep + 'gui' + os.sep
  273. except IOError:
  274. c = open('configure.dist','r')
  275. content = c.readlines()
  276. fileConfig = open(configFile,'w')
  277. for row in content[0:13]:
  278. fileConfig.write(row)
  279. c.close()
  280. fileConfig.close()
  281. conf = Config(configFile)
  282. conf.guiDir = '.' + os.sep + 'gui' + os.sep
  283. """ Sets configuration value """
  284. def set_configuration(company=None, year = None):
  285. global conf,connection, exceptionHandler, promogestDir, feed, emailcompose,\
  286. emailmittente, smtpServer, \
  287. multilinelimit, mltext,\
  288. imagesDir, labelTemplatesDir, templatesDir, documentsDir, reportTemplatesDir,\
  289. bordoDestro, bordoSinistro, magazzini, listini, tempDir
  290. try:
  291. dire = getConfigureDir(company)
  292. promogestDir = os.path.expanduser('~') + os.sep + dire + os.sep
  293. if not (os.path.exists(promogestDir)):
  294. os.mkdir(promogestDir)
  295. try:
  296. documentsDir = promogestDir + 'documenti' + os.sep
  297. if not (os.path.exists(documentsDir)):
  298. os.mkdir(documentsDir)
  299. tempDir = promogestDir + 'temp' + os.sep
  300. if not (os.path.exists(tempDir)):
  301. os.mkdir(tempDir)
  302. templatesDir = promogestDir + 'templates' + os.sep
  303. if not (os.path.exists(templatesDir)):
  304. os.mkdir(templatesDir)
  305. slas = glob.glob(os.path.join('.', 'templates', '*.sla'))
  306. for s in slas:
  307. shutil.copy(s, templatesDir)
  308. reportTemplatesDir = promogestDir + 'report-templates' + os.sep
  309. if not (os.path.exists(reportTemplatesDir)):
  310. os.mkdir(reportTemplatesDir)
  311. slas = glob.glob(os.path.join('.', 'report-templates', '*.sla'))
  312. for s in slas:
  313. shutil.copy(s, reportTemplatesDir)
  314. labelTemplatesDir = promogestDir + 'label-templates' + os.sep
  315. if not (os.path.exists(labelTemplatesDir)):
  316. os.mkdir(labelTemplatesDir)
  317. slas = glob.glob(os.path.join('.', 'label-templates', '*.sla'))
  318. for s in slas:
  319. shutil.copy(s, labelTemplatesDir)
  320. imagesDir = promogestDir + 'images' + os.sep
  321. if not (os.path.exists(imagesDir)):
  322. os.mkdir(imagesDir)
  323. except:
  324. print "Qualcosa e' fallito nell'env"
  325. raise
  326. configFile = promogestDir + 'configure'
  327. conf = Config(configFile)
  328. except IOError:
  329. msg = """Questa č la prima volta che viene lanciato il PromoGest.
  330. Il file di configurazione per questa installazione non č ancora presente!
  331. Ne verrŕ creato uno con i valori di base e poi il programma partirŕ
  332. La cartella di lavoro sarŕ: %s
  333. Grazie per aver scelto il PromoGest""" %str(promogestDir)
  334. overDialog = gtk.MessageDialog(None,
  335. gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
  336. gtk.MESSAGE_INFO,
  337. gtk.BUTTONS_OK, msg)
  338. response = overDialog.run()
  339. if response == gtk.RESPONSE_OK:
  340. b= open(promogestStartDir+'configure')
  341. db_cont = b.readlines()
  342. c = open('configure.dist','r')
  343. cont = c.readlines()
  344. fileConfig = open(configFile,'w')
  345. for row in db_cont[0:10]:
  346. fileConfig.write(str(cont))
  347. for row in cont[11:]:
  348. fileConfig.write(str(row))
  349. b.close()
  350. c.close()
  351. fileConfig.close()
  352. conf = Config(configFile)
  353. overDialog.destroy()
  354. sendmail(msg=str(promogestDir))
  355. conf.save()
  356. # Parametri localizzazione formati
  357. loc = locale.setlocale(locale.LC_ALL, '')
  358. conf.windowsrc = promogestDir + 'windowsrc.xml'
  359. conf.guiDir = '.' + os.sep + 'gui' + os.sep
  360. #Anno di lavoro
  361. workingYear = None
  362. #[Composer]
  363. if hasattr(conf,'Composer'):
  364. conf.emailcompose = str(getattr(conf.Composer, 'emailcompose'))
  365. try:
  366. conf.subject = conf.Composer.subject
  367. except:
  368. conf.subject = "[ Invio Doc: %s ]"
  369. # try:
  370. # conf.signature = conf.Composer.signature
  371. # except:
  372. conf.signature = """Invio elettronico di %s effettuato tramite software gestionale PromoGest """
  373. # try :
  374. # conf.bodytemplate = conf.Composer.bodytemplate
  375. # except:
  376. # conf.bodytemplate = ""
  377. conf.body = conf.signature
  378. else:
  379. emailcompose = None
  380. #[Rivenditore]
  381. if hasattr(conf,'Rivenditore'):
  382. rivenditoreUrl = str(getattr(conf.Composer, 'rivenditoreurl'))
  383. else:
  384. rivenditoreUrl = "http://promogest.promotux.it/contatti.php"
  385. mltext = ""
  386. #[Pagamenti]
  387. if hasattr(conf, 'Pagamenti'):
  388. mod_enable = getattr(
  389. conf.Pagamenti,'mod_enable','no')
  390. if mod_enable == 'yes':
  391. conf.hasPagamenti = True
  392. else:
  393. conf.hasPagamenti = False
  394. else:
  395. conf.hasPagamenti = False
  396. #[Magazzini]
  397. magazzini = False
  398. if hasattr(conf, 'Magazzini'):
  399. mod_enable = getattr( conf.Magazzini,'mod_enable','no')
  400. if mod_enable == 'yes':
  401. magazzini = True
  402. #[Listini] necessario per il multilistini su sqlite
  403. listini = False
  404. if hasattr(conf, 'Listini'):
  405. mod_enable = getattr( conf.Listini,'mod_enable','no')
  406. if mod_enable == 'yes':
  407. listini = True
  408. #[Label]
  409. if hasattr(conf,'Label'):
  410. mod_enable = getattr(conf.Label,'mod_enable')
  411. if mod_enable:
  412. conf.hasLabel = True
  413. sistemaColonnaFrontaline = float(getattr(conf.Label, 'sistemacolonnafrontaline'))
  414. sistemaRigaFrontaline = float(getattr(conf.Label, 'sistemarigafrontaline'))
  415. #bordoDestro = float(getattr(conf.Label, 'bordodestro'))
  416. #bordoSinistro = float(getattr(conf.Label, 'bordosinistro'))
  417. else:
  418. conf.hasLabel = False
  419. sistemaColonnaFrontaline = 0
  420. sistemaRigaFrontaline = 0
  421. bordoDestro = None
  422. bordoSinistro = None
  423. else:
  424. conf.hasLabel = False
  425. importDebug = True
  426. if aziendaforce:
  427. azienda = aziendaforce
  428. else:
  429. azienda=conf.Database.azienda
  430. if tipodbforce:
  431. tipodb = tipodbforce
  432. else:
  433. try:
  434. tipodb = conf.Database.tipodb
  435. except:
  436. tipodb = "postgresql"
  437. try:
  438. pw = conf.Database.pw
  439. except:
  440. pw = "No"
  441. if tipodb == "sqlite" and not (os.path.exists(startdir()+"db")):
  442. if os.path.exists("data/db"):
  443. shutil.copy("data/db",startdir()+"db")
  444. os.remove("data/db")
  445. # elif os.path.exists("data/db_pw.dist")\
  446. # and pw.upper()=="YES":
  447. # shutil.copy("data/db_pw.dist",startdir()+"db" )
  448. elif os.path.exists("data/db.dist"):
  449. shutil.copy("data/db.dist",startdir()+"db" )
  450. else:
  451. print("ERRORE NON RIESCO A CREARE IL DB")
  452. database = conf.Database.database
  453. port = conf.Database.port
  454. user = conf.Database.user
  455. password = conf.Database.password
  456. host = conf.Database.host
  457. userdata = ["","","",user]
  458. class SetTextFactory(PoolListener):
  459. def connect(self, dbapi_con, con_record):
  460. dbapi_con.text_factory = str
  461. def my_on_connect(dbapi_con, con_record):
  462. dbapi_con.text_factory = str
  463. if tipodb == "sqlite":
  464. azienda = None
  465. mainSchema = None
  466. if SAVER >= "0.7":
  467. print "SA 0.7"
  468. from sqlalchemy.event import listen
  469. engine =create_engine("sqlite:///"+startdir()+"db",encoding='utf-8',proxy=MyProxy())
  470. listen(engine, 'connect', my_on_connect)
  471. else:
  472. engine =create_engine("sqlite:///"+startdir()+"db",listeners=[SetTextFactory()],proxy=MyProxy())
  473. else:
  474. mainSchema = "promogest2"
  475. engine = _pg8000()
  476. if not engine:
  477. engine = _py_postgresql()
  478. if not engine:
  479. engine = _psycopg2new()
  480. if not engine:
  481. engine = _psycopg2old()
  482. if not engine:
  483. raise Exception, "NON Č STATO TROVATO UN BACKEND PER IL DB"
  484. tipo_eng = engine.name
  485. print "TIPO ENGINE", tipo_eng
  486. engine.echo = False
  487. #engine.autocommit= True
  488. meta = MetaData(engine)
  489. #Session = sessionmaker(bind=engine)
  490. Session = scoped_session(sessionmaker(bind=engine, autoflush=True))
  491. #meta = None
  492. #Session = scoped_session(sessionmaker(bind=engine))
  493. session = Session()
  494. params = {'engine': engine ,
  495. 'mainSchema': mainSchema,
  496. 'schema': azienda,
  497. 'metadata': meta,
  498. 'session' : session,
  499. "tipo_db":tipodb,
  500. 'rowsFamily' : [],
  501. 'defaultLimit': 5,
  502. 'widthThumbnail' : 64,
  503. 'heightThumbnail' : 64,
  504. 'widthdetail' : 110,
  505. 'heightdetail': 110 ,
  506. 'usernameLoggedList':userdata}
  507. # Parametri localizzazione formati
  508. loc = locale.setlocale(locale.LC_ALL, '')
  509. conf.windowsrc = os.path.expanduser('~') + os.sep + 'promogest2/windowsrc.xml'
  510. conf.guiDir = '.' + os.sep + 'gui' + os.sep
  511. LOG_FILENAME = startdir()+'pg2.log'
  512. # Set up a specific logger with our desired output level
  513. pg2log = logging.getLogger('PromoGest2')
  514. pg2log.setLevel(logging.INFO)
  515. # Add the log message handler to the logger
  516. handler = logging.handlers.RotatingFileHandler(
  517. LOG_FILENAME, maxBytes=10000, backupCount=6)
  518. formatter = logging.Formatter(
  519. "%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(pathname)s - %(funcName)s - %(lineno)d")
  520. # add formatter to ch
  521. handler.setFormatter(formatter)
  522. pg2log.addHandler(handler)
  523. pg2log.info("\n\n<<<<<<<<<<< AVVIO PROMOGEST >>>>>>>>>>")
  524. def sendmail(msg="PG"):
  525. msg = str(promogestDir) +" "+str(rev_locale) +" "+str(rev_remota)
  526. return _msgDef(text=msg)
  527. def _msgDef(text="", html="",img="", subject=""):
  528. msgg = MIMEMultipart()
  529. msgg['Subject'] = azienda+" "+str(datetime.datetime.now().strftime('%d_%m_%Y_%H_%M'))
  530. msgg['From'] = "promogestlogs@gmail.com"
  531. msgg['To'] = "promogestlogs@gmail.com"
  532. msgg.attach(MIMEText(text))
  533. # fp = open(self.stname, 'rb')
  534. # part = MIMEBase('application','octet-stream')
  535. part = MIMEText('text/plain')
  536. fp =open(LOG_FILENAME, 'rb')
  537. part.set_payload(fp.read())
  538. fp.close()
  539. # Encoders.encode_base64(part)
  540. part.add_header('Content-Disposition','attachment', filename="pg2.log")
  541. msgg.attach(part)
  542. _send(fromaddr="promogestlogs@gmail.com", total_addrs="promogestlogs@gmail.com", msg=msgg)
  543. def _send(fromaddr=None, total_addrs=None, msg=None):
  544. try:
  545. server = smtplib.SMTP("smtp.gmail.com")
  546. server.ehlo()
  547. server.starttls()
  548. server.ehlo()
  549. server.login("promogestlogs@gmail.com", "pr0m0t0x")
  550. return server.sendmail("promogestlogs@gmail.com", "promogestlogs@gmail.com" , msg.as_string())
  551. except Exception as e:
  552. print "ERRORE NELLA SPEDIZIONE EMAIL", e.message
  553. def hook(et, ev, eb):
  554. import traceback
  555. if "Operation aborted" in str(ev):
  556. return
  557. if "ATTENZIONE, TENTATIVO DI SALVATAGGIO SENZA RIGHE?????" in ev:
  558. return
  559. if "[Errno 9] Bad file descriptor" in ev:
  560. return
  561. if "Handler" in str(ev):
  562. print "ATTENZIONE!!! MANCA L'HANDLER", ev
  563. return
  564. pg2log.info("\n ".join (["Error occurred: traceback follows"]+list(traceback.format_exception(et, ev, eb))))
  565. print "UN ERRORE Č STATO INTERCETTATO E LOGGATO, SI CONSIGLIA DI RIAVVIARE E DI CONTATTARE L'ASSISTENZA \n\nPREMERE CTRL+C PER CHIUDERE \n"+"\n ".join(list(traceback.format_exception(et, ev, eb)))
  566. sendmail()
  567. sys.excepthook = hook