mailtb.cfg: Added to repository, for the sake of a simple module configuration.
mailtb.py: Added load_config() in order to load a mailtb.cfg file.
Renamed mail_config to config
#!/usr/bin/env python# -*- coding: UTF-8 -*-# Copyright 2009 Pascal Volk# See COPYING for distribution information.__author__='Pascal Volk'__version__='0.1'__date__='2009-11-14'"""Sends information about uncaught exceptions per email."""importsysimportsmtplibimporttracebackfromosimportenvironasenvfromtimeimportctime,gmtime,localtime,strftime,timeconfig={# sender information'from_addr':'','from_name':'',# smtp auth information (if necessary, else leave blank)'auth_user':'','auth_pass':'',# recipient information'rcpt_addr':'','rcpt_name':'',# smtp server information'smtp_host':'localhost','smtp_port':25,# 25 smtp, 587 submission, 465 ssmtp (obsolete)'smtp_tls':False,# True or False (use starttls on port 25/587)# subject of the email'subject':'Exception Notification',# make sure that the web server can write to this file'error_log':'/tmp/mailtb_error.log'}http_status={200:'OK',500:'Internal Server Error'}deflog_mail_error(error,timestamp):try:prefix=strftime('%b %d %H:%M:%S',localtime(timestamp))line=error.messageiflen(error.message)elseerror.argslogfile=open(config['error_log'],'a')logfile.write('%s%s: %s\n'%(prefix,error.__class__.__name__,line))logfile.close()except:passdefload_config(filename):fromConfigParserimportConfigParsercp=ConfigParser()iflen(cp.read(filename)):globalconfigget=cp.getforkin('auth_pass','auth_user','error_log','from_addr','from_name','rcpt_addr','rcpt_name','smtp_host','subject'):config[k]=get('mailtb',k)config['smtp_port']=cp.getint('mailtb','smtp_port')config['smtp_tls']=cp.getboolean('mailtb','smtp_tls')del(cp)defsend_header(status=500,xhtml=False):s=statusifstatusinhttp_statuselse500write=sys.stdout.writeifnotxhtml:write('Content-Type: text/html; charset=utf-8\r\n')else:write('Content-Type: application/xhtml+xml; charset=utf-8\r\n')write('Status: %d%s\r\n\r\n'%(s,http_status[s]))sys.stdout.flush()defsend_error_page():send_header(500,True)print"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de"> <head> <title>Internal Server Error</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <h1>Internal Server Error</h1> <p>So wie es aussieht, ging bei der Bearbeitung Ihrer Anfrage etwas schief.</p> <p>Sofern Sie den Fehler verursacht haben, dürfen Sie jetzt ein schlechtes Gewissen haben.<br /> Die Administration wird sich bei nächster Gelegenheit um das Problem kümmern. Bitte haben Sie dafür etwas Verständnis.</p> <h2>Error 500</h2> <p>Sorry</p> </body></html>"""defsend_mail(info):globalconfigconfig['now']=time()config['host']=info['host']ifinfo['host']!='n/a'else'localhost'config['date']=strftime('%a, %d %b %Y %H:%M:%S +0000',gmtime(config['now']))body="""Hi,an uncaught exception has occurred. The details are as follows: Type: %(extype)s Message: %(message)sTraceback (most recent call last):%(traceback)sAdditional information: Date: %(date)s Request: %(method)s%(uri)s%(protocol)s Referrer: %(referer)s Client: %(addr)s/%(port)s U-Agent: %(agent)s"""%infoheader="""Date: %(date)sFrom: "%(from_name)s" <%(from_addr)s>To: "%(rcpt_name)s" <%(rcpt_addr)s>Subject: %(subject)sMessage-ID: <%(now)f.%(now)X@mailtb.%(host)s>Auto-Submitted: auto-generatedMIME-Version: 1.0Content-Type: text/plain; charset=utf-8Content-Transfer-Encoding: 8bit"""%configtry:ifconfig['smtp_port']!=465:smtp=smtplib.SMTP(config['smtp_host'],config['smtp_port'])ifconfig['smtp_tls']:smtp.starttls()else:smtp=smtplib.SMTP_SSL(config['smtp_host'],config['smtp_port'])iflen(config['auth_user'])andlen(config['auth_pass']):smtp.login(config['auth_user'],config['auth_pass'])smtp.sendmail(config['from_addr'],config['rcpt_addr'],'\n'.join((header,body)))exceptException,e:# try to log it (fire and forget)log_mail_error(e,config['now'])finally:smtp.quit()defmailtbhook(extype,exval,extb):info={}iftype(extype)istype:info['extype']=extype.__name__else:info['extype']=str(extype).split("'")[1]ifhasattr(exval,'message'):info['message']=exval.messageiflen(exval.message)else'n/a'else:info['message']=str(exval)info['traceback']=''.join(['%s\n'%lforlintraceback.format_tb(extb)])info['date']=ctime()forkin('HTTP_HOST','HTTP_REFERER','HTTP_USER_AGENT','REMOTE_ADDR','REMOTE_PORT','REQUEST_METHOD','REQUEST_URI','SERVER_PROTOCOL'):info[k.split('_')[-1].lower()]=env[k]ifenv.has_key(k)else'n/a'send_mail(info)send_error_page()defenable(filename=None):iffilenameisnotNone:load_config(filename)sys.excepthook=mailtbhook