Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. """Methods for reporting bugs."""
  5.  
  6. import subprocess, sys, os
  7.  
  8. __all__ = ['ReportFailure', 'BugReport', 'getReporters']
  9.  
  10. #
  11.  
  12. class ReportFailure(Exception):
  13.     """Generic exception for failures in bug reporting."""
  14.     def __init__(self, value):        
  15.         self.value = value
  16.  
  17. # Collect information about a bug.
  18.  
  19. class BugReport(object):
  20.     def __init__(self, title, description, files):
  21.         self.title = title
  22.         self.description = description
  23.         self.files = files
  24.  
  25. # Reporter interfaces.
  26.  
  27. import os
  28.  
  29. import email, mimetypes, smtplib
  30. from email import encoders
  31. from email.message import Message
  32. from email.mime.base import MIMEBase
  33. from email.mime.multipart import MIMEMultipart
  34. from email.mime.text import MIMEText
  35.  
  36. #===------------------------------------------------------------------------===#
  37. # ReporterParameter
  38. #===------------------------------------------------------------------------===#
  39.  
  40. class ReporterParameter(object):
  41.   def __init__(self, n):
  42.     self.name = n
  43.   def getName(self):
  44.     return self.name
  45.   def getValue(self,r,bugtype,getConfigOption):
  46.      return getConfigOption(r.getName(),self.getName())
  47.   def saveConfigValue(self):
  48.     return True
  49.  
  50. class TextParameter (ReporterParameter):
  51.   def getHTML(self,r,bugtype,getConfigOption):
  52.     return """\
  53. <tr>
  54. <td class="form_clabel">%s:</td>
  55. <td class="form_value"><input type="text" name="%s_%s" value="%s"></td>
  56. </tr>"""%(self.getName(),r.getName(),self.getName(),self.getValue(r,bugtype,getConfigOption))
  57.  
  58. class SelectionParameter (ReporterParameter):
  59.   def __init__(self, n, values):
  60.     ReporterParameter.__init__(self,n)
  61.     self.values = values
  62.    
  63.   def getHTML(self,r,bugtype,getConfigOption):
  64.     default = self.getValue(r,bugtype,getConfigOption)
  65.     return """\
  66. <tr>
  67. <td class="form_clabel">%s:</td><td class="form_value"><select name="%s_%s">
  68. %s
  69. </select></td>"""%(self.getName(),r.getName(),self.getName(),'\n'.join(["""\
  70. <option value="%s"%s>%s</option>"""%(o[0],
  71.                                      o[0] == default and ' selected="selected"' or '',
  72.                                      o[1]) for o in self.values]))
  73.  
  74. #===------------------------------------------------------------------------===#
  75. # Reporters
  76. #===------------------------------------------------------------------------===#
  77.  
  78. class EmailReporter(object):
  79.     def getName(self):
  80.         return 'Email'
  81.  
  82.     def getParameters(self):
  83.         return [TextParameter(x) for x in ['To', 'From', 'SMTP Server', 'SMTP Port']]
  84.  
  85.     # Lifted from python email module examples.
  86.     def attachFile(self, outer, path):
  87.         # Guess the content type based on the file's extension.  Encoding
  88.         # will be ignored, although we should check for simple things like
  89.         # gzip'd or compressed files.
  90.         ctype, encoding = mimetypes.guess_type(path)
  91.         if ctype is None or encoding is not None:
  92.             # No guess could be made, or the file is encoded (compressed), so
  93.             # use a generic bag-of-bits type.
  94.             ctype = 'application/octet-stream'
  95.         maintype, subtype = ctype.split('/', 1)
  96.         if maintype == 'text':
  97.             fp = open(path)
  98.             # Note: we should handle calculating the charset
  99.             msg = MIMEText(fp.read(), _subtype=subtype)
  100.             fp.close()
  101.         else:
  102.             fp = open(path, 'rb')
  103.             msg = MIMEBase(maintype, subtype)
  104.             msg.set_payload(fp.read())
  105.             fp.close()
  106.             # Encode the payload using Base64
  107.             encoders.encode_base64(msg)
  108.         # Set the filename parameter
  109.         msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(path))
  110.         outer.attach(msg)
  111.  
  112.     def fileReport(self, report, parameters):
  113.         mainMsg = """\
  114. BUG REPORT
  115. ---
  116. Title: %s
  117. Description: %s
  118. """%(report.title, report.description)
  119.  
  120.         if not parameters.get('To'):
  121.             raise ReportFailure('No "To" address specified.')
  122.         if not parameters.get('From'):
  123.             raise ReportFailure('No "From" address specified.')
  124.  
  125.         msg = MIMEMultipart()
  126.         msg['Subject'] = 'BUG REPORT: %s'%(report.title)
  127.         # FIXME: Get config parameters
  128.         msg['To'] = parameters.get('To')
  129.         msg['From'] = parameters.get('From')
  130.         msg.preamble = mainMsg
  131.  
  132.         msg.attach(MIMEText(mainMsg, _subtype='text/plain'))
  133.         for file in report.files:
  134.             self.attachFile(msg, file)
  135.  
  136.         try:
  137.             s = smtplib.SMTP(host=parameters.get('SMTP Server'),
  138.                              port=parameters.get('SMTP Port'))
  139.             s.sendmail(msg['From'], msg['To'], msg.as_string())
  140.             s.close()
  141.         except:
  142.             raise ReportFailure('Unable to send message via SMTP.')
  143.  
  144.         return "Message sent!"
  145.  
  146. class BugzillaReporter(object):
  147.     def getName(self):
  148.         return 'Bugzilla'
  149.    
  150.     def getParameters(self):
  151.         return [TextParameter(x) for x in ['URL','Product']]
  152.  
  153.     def fileReport(self, report, parameters):
  154.         raise NotImplementedError
  155.  
  156.  
  157. class RadarClassificationParameter(SelectionParameter):
  158.   def __init__(self):
  159.     SelectionParameter.__init__(self,"Classification",
  160.             [['1', 'Security'], ['2', 'Crash/Hang/Data Loss'],
  161.              ['3', 'Performance'], ['4', 'UI/Usability'],
  162.              ['6', 'Serious Bug'], ['7', 'Other']])
  163.  
  164.   def saveConfigValue(self):
  165.     return False
  166.    
  167.   def getValue(self,r,bugtype,getConfigOption):
  168.     if bugtype.find("leak") != -1:
  169.       return '3'
  170.     elif bugtype.find("dereference") != -1:
  171.       return '2'
  172.     elif bugtype.find("missing ivar release") != -1:
  173.       return '3'
  174.     else:
  175.       return '7'
  176.  
  177. ###
  178.  
  179. def getReporters():
  180.     reporters = []
  181.     reporters.append(EmailReporter())
  182.     return reporters
  183.  
  184.