| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- """Methods for reporting bugs."""
- import subprocess, sys, os
- __all__ = ['ReportFailure', 'BugReport', 'getReporters']
- #
- class ReportFailure(Exception):
- """Generic exception for failures in bug reporting."""
- def __init__(self, value):
- self.value = value
- # Collect information about a bug.
- class BugReport(object):
- def __init__(self, title, description, files):
- self.title = title
- self.description = description
- self.files = files
- # Reporter interfaces.
- import os
- import email, mimetypes, smtplib
- from email import encoders
- from email.message import Message
- from email.mime.base import MIMEBase
- from email.mime.multipart import MIMEMultipart
- from email.mime.text import MIMEText
- #===------------------------------------------------------------------------===#
- # ReporterParameter
- #===------------------------------------------------------------------------===#
- class ReporterParameter(object):
- def __init__(self, n):
- self.name = n
- def getName(self):
- return self.name
- def getValue(self,r,bugtype,getConfigOption):
- return getConfigOption(r.getName(),self.getName())
- def saveConfigValue(self):
- return True
- class TextParameter (ReporterParameter):
- def getHTML(self,r,bugtype,getConfigOption):
- return """\
- <tr>
- <td class="form_clabel">%s:</td>
- <td class="form_value"><input type="text" name="%s_%s" value="%s"></td>
- </tr>"""%(self.getName(),r.getName(),self.getName(),self.getValue(r,bugtype,getConfigOption))
- class SelectionParameter (ReporterParameter):
- def __init__(self, n, values):
- ReporterParameter.__init__(self,n)
- self.values = values
-
- def getHTML(self,r,bugtype,getConfigOption):
- default = self.getValue(r,bugtype,getConfigOption)
- return """\
- <tr>
- <td class="form_clabel">%s:</td><td class="form_value"><select name="%s_%s">
- %s
- </select></td>"""%(self.getName(),r.getName(),self.getName(),'\n'.join(["""\
- <option value="%s"%s>%s</option>"""%(o[0],
- o[0] == default and ' selected="selected"' or '',
- o[1]) for o in self.values]))
- #===------------------------------------------------------------------------===#
- # Reporters
- #===------------------------------------------------------------------------===#
- class EmailReporter(object):
- def getName(self):
- return 'Email'
- def getParameters(self):
- return [TextParameter(x) for x in ['To', 'From', 'SMTP Server', 'SMTP Port']]
- # Lifted from python email module examples.
- def attachFile(self, outer, path):
- # Guess the content type based on the file's extension. Encoding
- # will be ignored, although we should check for simple things like
- # gzip'd or compressed files.
- ctype, encoding = mimetypes.guess_type(path)
- if ctype is None or encoding is not None:
- # No guess could be made, or the file is encoded (compressed), so
- # use a generic bag-of-bits type.
- ctype = 'application/octet-stream'
- maintype, subtype = ctype.split('/', 1)
- if maintype == 'text':
- fp = open(path)
- # Note: we should handle calculating the charset
- msg = MIMEText(fp.read(), _subtype=subtype)
- fp.close()
- else:
- fp = open(path, 'rb')
- msg = MIMEBase(maintype, subtype)
- msg.set_payload(fp.read())
- fp.close()
- # Encode the payload using Base64
- encoders.encode_base64(msg)
- # Set the filename parameter
- msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(path))
- outer.attach(msg)
- def fileReport(self, report, parameters):
- mainMsg = """\
- BUG REPORT
- ---
- Title: %s
- Description: %s
- """%(report.title, report.description)
- if not parameters.get('To'):
- raise ReportFailure('No "To" address specified.')
- if not parameters.get('From'):
- raise ReportFailure('No "From" address specified.')
- msg = MIMEMultipart()
- msg['Subject'] = 'BUG REPORT: %s'%(report.title)
- # FIXME: Get config parameters
- msg['To'] = parameters.get('To')
- msg['From'] = parameters.get('From')
- msg.preamble = mainMsg
- msg.attach(MIMEText(mainMsg, _subtype='text/plain'))
- for file in report.files:
- self.attachFile(msg, file)
- try:
- s = smtplib.SMTP(host=parameters.get('SMTP Server'),
- port=parameters.get('SMTP Port'))
- s.sendmail(msg['From'], msg['To'], msg.as_string())
- s.close()
- except:
- raise ReportFailure('Unable to send message via SMTP.')
- return "Message sent!"
- class BugzillaReporter(object):
- def getName(self):
- return 'Bugzilla'
-
- def getParameters(self):
- return [TextParameter(x) for x in ['URL','Product']]
- def fileReport(self, report, parameters):
- raise NotImplementedError
-
- class RadarClassificationParameter(SelectionParameter):
- def __init__(self):
- SelectionParameter.__init__(self,"Classification",
- [['1', 'Security'], ['2', 'Crash/Hang/Data Loss'],
- ['3', 'Performance'], ['4', 'UI/Usability'],
- ['6', 'Serious Bug'], ['7', 'Other']])
- def saveConfigValue(self):
- return False
-
- def getValue(self,r,bugtype,getConfigOption):
- if bugtype.find("leak") != -1:
- return '3'
- elif bugtype.find("dereference") != -1:
- return '2'
- elif bugtype.find("missing ivar release") != -1:
- return '3'
- else:
- return '7'
- ###
- def getReporters():
- reporters = []
- reporters.append(EmailReporter())
- return reporters
|