summaryrefslogtreecommitdiff
path: root/paste/exceptions/reporter.py
diff options
context:
space:
mode:
Diffstat (limited to 'paste/exceptions/reporter.py')
-rw-r--r--paste/exceptions/reporter.py141
1 files changed, 141 insertions, 0 deletions
diff --git a/paste/exceptions/reporter.py b/paste/exceptions/reporter.py
new file mode 100644
index 0000000..7c0c266
--- /dev/null
+++ b/paste/exceptions/reporter.py
@@ -0,0 +1,141 @@
+# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
+# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
+
+from email.mime.text import MIMEText
+from email.mime.multipart import MIMEMultipart
+import smtplib
+import time
+try:
+ from socket import sslerror
+except ImportError:
+ sslerror = None
+from paste.exceptions import formatter
+
+class Reporter(object):
+
+ def __init__(self, **conf):
+ for name, value in conf.items():
+ if not hasattr(self, name):
+ raise TypeError(
+ "The keyword argument %s was not expected"
+ % name)
+ setattr(self, name, value)
+ self.check_params()
+
+ def check_params(self):
+ pass
+
+ def format_date(self, exc_data):
+ return time.strftime('%c', exc_data.date)
+
+ def format_html(self, exc_data, **kw):
+ return formatter.format_html(exc_data, **kw)
+
+ def format_text(self, exc_data, **kw):
+ return formatter.format_text(exc_data, **kw)
+
+class EmailReporter(Reporter):
+
+ to_addresses = None
+ from_address = None
+ smtp_server = 'localhost'
+ smtp_username = None
+ smtp_password = None
+ smtp_use_tls = False
+ subject_prefix = ''
+
+ def report(self, exc_data):
+ msg = self.assemble_email(exc_data)
+ server = smtplib.SMTP(self.smtp_server)
+ if self.smtp_use_tls:
+ server.ehlo()
+ server.starttls()
+ server.ehlo()
+ if self.smtp_username and self.smtp_password:
+ server.login(self.smtp_username, self.smtp_password)
+ server.sendmail(self.from_address,
+ self.to_addresses, msg.as_string())
+ try:
+ server.quit()
+ except sslerror:
+ # sslerror is raised in tls connections on closing sometimes
+ pass
+
+ def check_params(self):
+ if not self.to_addresses:
+ raise ValueError("You must set to_addresses")
+ if not self.from_address:
+ raise ValueError("You must set from_address")
+ if isinstance(self.to_addresses, (str, unicode)):
+ self.to_addresses = [self.to_addresses]
+
+ def assemble_email(self, exc_data):
+ short_html_version = self.format_html(
+ exc_data, show_hidden_frames=False)
+ long_html_version = self.format_html(
+ exc_data, show_hidden_frames=True)
+ text_version = self.format_text(
+ exc_data, show_hidden_frames=False)
+ msg = MIMEMultipart()
+ msg.set_type('multipart/alternative')
+ msg.preamble = msg.epilogue = ''
+ text_msg = MIMEText(text_version)
+ text_msg.set_type('text/plain')
+ text_msg.set_param('charset', 'ASCII')
+ msg.attach(text_msg)
+ html_msg = MIMEText(short_html_version)
+ html_msg.set_type('text/html')
+ # @@: Correct character set?
+ html_msg.set_param('charset', 'UTF-8')
+ html_long = MIMEText(long_html_version)
+ html_long.set_type('text/html')
+ html_long.set_param('charset', 'UTF-8')
+ msg.attach(html_msg)
+ msg.attach(html_long)
+ subject = '%s: %s' % (exc_data.exception_type,
+ formatter.truncate(str(exc_data.exception_value)))
+ msg['Subject'] = self.subject_prefix + subject
+ msg['From'] = self.from_address
+ msg['To'] = ', '.join(self.to_addresses)
+ return msg
+
+class LogReporter(Reporter):
+
+ filename = None
+ show_hidden_frames = True
+
+ def check_params(self):
+ assert self.filename is not None, (
+ "You must give a filename")
+
+ def report(self, exc_data):
+ text = self.format_text(
+ exc_data, show_hidden_frames=self.show_hidden_frames)
+ f = open(self.filename, 'a')
+ try:
+ f.write(text + '\n' + '-'*60 + '\n')
+ finally:
+ f.close()
+
+class FileReporter(Reporter):
+
+ file = None
+ show_hidden_frames = True
+
+ def check_params(self):
+ assert self.file is not None, (
+ "You must give a file object")
+
+ def report(self, exc_data):
+ text = self.format_text(
+ exc_data, show_hidden_frames=self.show_hidden_frames)
+ self.file.write(text + '\n' + '-'*60 + '\n')
+
+class WSGIAppReporter(Reporter):
+
+ def __init__(self, exc_data):
+ self.exc_data = exc_data
+
+ def __call__(self, environ, start_response):
+ start_response('500 Server Error', [('Content-type', 'text/html')])
+ return [formatter.format_html(self.exc_data)]