PageRenderTime 40ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/upgrades/archive/to_v5.2/weberror/reporter.py

https://bitbucket.org/iwuyan/stemformatics
Python | 147 lines | 136 code | 9 blank | 2 comment | 2 complexity | faf47f7479b16750651e0d0a12431269 MD5 | raw file
  1. # (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
  2. # Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
  3. from email.MIMEText import MIMEText
  4. from email.MIMEMultipart import MIMEMultipart
  5. import smtplib
  6. import time
  7. from weberror import formatter
  8. class Reporter(object):
  9. def __init__(self, **conf):
  10. for name, value in conf.items():
  11. if not hasattr(self, name):
  12. raise TypeError(
  13. "The keyword argument %s was not expected"
  14. % name)
  15. setattr(self, name, value)
  16. self.check_params()
  17. def check_params(self):
  18. pass
  19. def format_date(self, exc_data):
  20. return time.strftime('%c', exc_data.date)
  21. def format_html(self, exc_data, **kw):
  22. return formatter.format_html(exc_data, **kw)
  23. def format_text(self, exc_data, **kw):
  24. return formatter.format_text(exc_data, **kw)
  25. class EmailReporter(Reporter):
  26. to_addresses = None
  27. from_address = None
  28. smtp_server = 'localhost'
  29. smtp_username = None
  30. smtp_password = None
  31. smtp_port = 25
  32. smtp_use_tls = False
  33. subject_prefix = ''
  34. def report(self, exc_data):
  35. msg = self.assemble_email(exc_data)
  36. server = smtplib.SMTP(self.smtp_server,self.smtp_port)
  37. if self.smtp_use_tls:
  38. server.ehlo()
  39. server.starttls()
  40. server.ehlo()
  41. if self.smtp_username and self.smtp_password:
  42. server.login(self.smtp_username, self.smtp_password)
  43. ## FIXME: this should check the return value from this function:
  44. result = server.sendmail(self.from_address,
  45. self.to_addresses, msg.as_string())
  46. try:
  47. server.quit()
  48. except sslerror:
  49. # sslerror is raised in tls connections on closing sometimes
  50. pass
  51. def check_params(self):
  52. if not self.to_addresses:
  53. raise ValueError("You must set to_addresses")
  54. if not self.from_address:
  55. raise ValueError("You must set from_address")
  56. if isinstance(self.to_addresses, (str, unicode)):
  57. self.to_addresses = [self.to_addresses]
  58. def assemble_email(self, exc_data):
  59. short_html_version, short_extra = self.format_html(
  60. exc_data, show_hidden_frames=False, show_extra_data=True)
  61. long_html_version, long_extra = self.format_html(
  62. exc_data, show_hidden_frames=True, show_extra_data=True)
  63. text_version = self.format_text(
  64. exc_data, show_hidden_frames=True, show_extra_data=True)[0]
  65. msg = MIMEMultipart()
  66. msg.set_type('multipart/alternative')
  67. msg.preamble = msg.epilogue = ''
  68. text_msg = MIMEText(as_str(text_version))
  69. text_msg.set_type('text/plain')
  70. text_msg.set_param('charset', 'UTF-8')
  71. msg.attach(text_msg)
  72. html_msg = MIMEText(as_str(short_html_version) + as_str(''.join(short_extra)))
  73. html_msg.set_type('text/html')
  74. html_msg.set_param('charset', 'UTF-8')
  75. html_long = MIMEText(as_str(long_html_version) + as_str(''.join(long_extra)))
  76. html_long.set_type('text/html')
  77. html_long.set_param('charset', 'UTF-8')
  78. msg.attach(html_msg)
  79. msg.attach(html_long)
  80. subject = as_str('%s: %s' % (exc_data.exception_type,
  81. formatter.truncate(str(exc_data.exception_value))))
  82. msg['Subject'] = as_str(self.subject_prefix) + subject
  83. msg['From'] = as_str(self.from_address)
  84. msg['To'] = as_str(', '.join(self.to_addresses))
  85. return msg
  86. class LogReporter(Reporter):
  87. filename = None
  88. show_hidden_frames = True
  89. def check_params(self):
  90. assert self.filename is not None, (
  91. "You must give a filename")
  92. def report(self, exc_data):
  93. text, head_text = self.format_text(
  94. exc_data, show_hidden_frames=self.show_hidden_frames)
  95. f = open(self.filename, 'a')
  96. try:
  97. f.write(text + '\n' + '-'*60 + '\n')
  98. finally:
  99. f.close()
  100. class FileReporter(Reporter):
  101. file = None
  102. show_hidden_frames = True
  103. def check_params(self):
  104. assert self.file is not None, (
  105. "You must give a file object")
  106. def report(self, exc_data):
  107. text = self.format_text(
  108. exc_data, show_hidden_frames=self.show_hidden_frames)
  109. self.file.write(text + '\n' + '-'*60 + '\n')
  110. class WSGIAppReporter(Reporter):
  111. def __init__(self, exc_data):
  112. self.exc_data = exc_data
  113. def __call__(self, environ, start_response):
  114. start_response('500 Server Error', [('Content-type', 'text/html')])
  115. return [formatter.format_html(self.exc_data)]
  116. def as_str(v):
  117. if isinstance(v, str):
  118. return v
  119. if not isinstance(v, unicode):
  120. v = unicode(v)
  121. if isinstance(v, unicode):
  122. v = v.encode('utf8')
  123. return v