brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · 21874b3 Raw
227 lines · python
1#!/usr/bin/env python2# -*- coding: utf-8 -*-3 4"""Methods for reporting bugs."""5 6import subprocess, sys, os7 8__all__ = ["ReportFailure", "BugReport", "getReporters"]9 10#11 12 13class ReportFailure(Exception):14    """Generic exception for failures in bug reporting."""15 16    def __init__(self, value):17        self.value = value18 19 20# Collect information about a bug.21 22 23class BugReport(object):24    def __init__(self, title, description, files):25        self.title = title26        self.description = description27        self.files = files28 29 30# Reporter interfaces.31 32import os33 34import email, mimetypes, smtplib35from email import encoders36from email.message import Message37from email.mime.base import MIMEBase38from email.mime.multipart import MIMEMultipart39from email.mime.text import MIMEText40 41# ===------------------------------------------------------------------------===#42# ReporterParameter43# ===------------------------------------------------------------------------===#44 45 46class ReporterParameter(object):47    def __init__(self, n):48        self.name = n49 50    def getName(self):51        return self.name52 53    def getValue(self, r, bugtype, getConfigOption):54        return getConfigOption(r.getName(), self.getName())55 56    def saveConfigValue(self):57        return True58 59 60class TextParameter(ReporterParameter):61    def getHTML(self, r, bugtype, getConfigOption):62        return """\63<tr>64<td class="form_clabel">%s:</td>65<td class="form_value"><input type="text" name="%s_%s" value="%s"></td>66</tr>""" % (67            self.getName(),68            r.getName(),69            self.getName(),70            self.getValue(r, bugtype, getConfigOption),71        )72 73 74class SelectionParameter(ReporterParameter):75    def __init__(self, n, values):76        ReporterParameter.__init__(self, n)77        self.values = values78 79    def getHTML(self, r, bugtype, getConfigOption):80        default = self.getValue(r, bugtype, getConfigOption)81        return """\82<tr>83<td class="form_clabel">%s:</td><td class="form_value"><select name="%s_%s">84%s85</select></td>""" % (86            self.getName(),87            r.getName(),88            self.getName(),89            "\n".join(90                [91                    """\92<option value="%s"%s>%s</option>"""93                    % (o[0], o[0] == default and ' selected="selected"' or "", o[1])94                    for o in self.values95                ]96            ),97        )98 99 100# ===------------------------------------------------------------------------===#101# Reporters102# ===------------------------------------------------------------------------===#103 104 105class EmailReporter(object):106    def getName(self):107        return "Email"108 109    def getParameters(self):110        return [TextParameter(x) for x in ["To", "From", "SMTP Server", "SMTP Port"]]111 112    # Lifted from python email module examples.113    def attachFile(self, outer, path):114        # Guess the content type based on the file's extension.  Encoding115        # will be ignored, although we should check for simple things like116        # gzip'd or compressed files.117        ctype, encoding = mimetypes.guess_type(path)118        if ctype is None or encoding is not None:119            # No guess could be made, or the file is encoded (compressed), so120            # use a generic bag-of-bits type.121            ctype = "application/octet-stream"122        maintype, subtype = ctype.split("/", 1)123        if maintype == "text":124            fp = open(path)125            # Note: we should handle calculating the charset126            msg = MIMEText(fp.read(), _subtype=subtype)127            fp.close()128        else:129            fp = open(path, "rb")130            msg = MIMEBase(maintype, subtype)131            msg.set_payload(fp.read())132            fp.close()133            # Encode the payload using Base64134            encoders.encode_base64(msg)135        # Set the filename parameter136        msg.add_header(137            "Content-Disposition", "attachment", filename=os.path.basename(path)138        )139        outer.attach(msg)140 141    def fileReport(self, report, parameters):142        mainMsg = """\143BUG REPORT144---145Title: %s146Description: %s147""" % (148            report.title,149            report.description,150        )151 152        if not parameters.get("To"):153            raise ReportFailure('No "To" address specified.')154        if not parameters.get("From"):155            raise ReportFailure('No "From" address specified.')156 157        msg = MIMEMultipart()158        msg["Subject"] = "BUG REPORT: %s" % (report.title)159        # FIXME: Get config parameters160        msg["To"] = parameters.get("To")161        msg["From"] = parameters.get("From")162        msg.preamble = mainMsg163 164        msg.attach(MIMEText(mainMsg, _subtype="text/plain"))165        for file in report.files:166            self.attachFile(msg, file)167 168        try:169            s = smtplib.SMTP(170                host=parameters.get("SMTP Server"), port=parameters.get("SMTP Port")171            )172            s.sendmail(msg["From"], msg["To"], msg.as_string())173            s.close()174        except:175            raise ReportFailure("Unable to send message via SMTP.")176 177        return "Message sent!"178 179 180class BugzillaReporter(object):181    def getName(self):182        return "Bugzilla"183 184    def getParameters(self):185        return [TextParameter(x) for x in ["URL", "Product"]]186 187    def fileReport(self, report, parameters):188        raise NotImplementedError189 190 191class RadarClassificationParameter(SelectionParameter):192    def __init__(self):193        SelectionParameter.__init__(194            self,195            "Classification",196            [197                ["1", "Security"],198                ["2", "Crash/Hang/Data Loss"],199                ["3", "Performance"],200                ["4", "UI/Usability"],201                ["6", "Serious Bug"],202                ["7", "Other"],203            ],204        )205 206    def saveConfigValue(self):207        return False208 209    def getValue(self, r, bugtype, getConfigOption):210        if bugtype.find("leak") != -1:211            return "3"212        elif bugtype.find("dereference") != -1:213            return "2"214        elif bugtype.find("missing ivar release") != -1:215            return "3"216        else:217            return "7"218 219 220###221 222 223def getReporters():224    reporters = []225    reporters.append(EmailReporter())226    return reporters227