Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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