mailtb.py: Reworded error_page, more serious and in English-language.
Added global error_page_is_xhtml variable.
#!/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,timeerror_page="""<!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="en"> <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>The server encountered an internal error and was unable to complete your request.</p> <p>The administration team will take care of this problem. We apologize for any inconvenience.</p> <h2>Error 500</h2> <p>Server got itself in trouble</p> </body></html>"""error_page_is_xhtml=Truemsg_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"""msg_header="""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"""config={# 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')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,error_page_is_xhtml)sys.stdout.write(error_page)sys.stdout.flush()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']))try: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((msg_header%config,msg_body%info)))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_error_page()send_mail(info)defenable(filename=None):iffilenameisnotNone:load_config(filename)sys.excepthook=mailtbhook