Beispiel #1
0
    def sendmessage(self,to='',subj='',content='',attach=None):
        msg = Message()
        COMMASPACE = ', '
        if not to:
            to=self.to
        to=map(self.addsuff,to)
        print to
        if not subj:
            subj=self.subj
        if not content:
            content=self.subj
        msg = MIMEMultipart()

        msg['From']    = self.emailfrom
        if self.cc:
            msg['CC'] = self.cc

        msg['To']      =COMMASPACE.join(to)

        msg['Subject'] = Header(subj,'utf-8')
        msg['Date']    = email.Utils.formatdate()
        # msg.set_payload(content)
        if not attach:
            msg.set_payload(content)
        else:
            msg.attach(content)
            msg.attach(attach)
        try:

            failed = self.server.sendmail(self.emailfrom,to,msg.as_string())   # may also raise exc
        except Exception ,ex:
            print Exception,ex
            return 'Error - send failed'
Beispiel #2
0
    def notifyModerators(self, moderators, article):
        """
        Send an article to a list of group moderators to be moderated.

        @param moderators: A C{list} of C{str} giving RFC 2821 addresses of
            group moderators to notify.

        @param article: The article requiring moderation.
        @type article: L{Article}

        @return: A L{Deferred} which fires with the result of sending the email.
        """
        # Moderated postings go through as long as they have an Approved
        # header, regardless of what the value is
        group = article.getHeader('Newsgroups')
        subject = article.getHeader('Subject')

        if self._sender is None:
            # This case should really go away.  This isn't a good default.
            sender = 'twisted-news@' + socket.gethostname()
        else:
            sender = self._sender

        msg = Message()
        msg['Message-ID'] = smtp.messageid()
        msg['From'] = sender
        msg['To'] = ', '.join(moderators)
        msg['Subject'] = 'Moderate new %s message: %s' % (group, subject)
        msg['Content-Type'] = 'message/rfc822'

        payload = Message()
        for header, value in article.headers.values():
            payload.add_header(header, value)
        payload.set_payload(article.body)

        msg.attach(payload)

        out = StringIO.StringIO()
        gen = Generator(out, False)
        gen.flatten(msg)
        msg = out.getvalue()

        return self.sendmail(self._mailhost, sender, moderators, msg)
    def notifyModerators(self, moderators, article):
        """
        Send an article to a list of group moderators to be moderated.

        @param moderators: A C{list} of C{str} giving RFC 2821 addresses of
            group moderators to notify.

        @param article: The article requiring moderation.
        @type article: L{Article}

        @return: A L{Deferred} which fires with the result of sending the email.
        """
        # Moderated postings go through as long as they have an Approved
        # header, regardless of what the value is
        group = article.getHeader('Newsgroups')
        subject = article.getHeader('Subject')

        if self._sender is None:
            # This case should really go away.  This isn't a good default.
            sender = 'twisted-news@' + socket.gethostname()
        else:
            sender = self._sender

        msg = Message()
        msg['Message-ID'] = smtp.messageid()
        msg['From'] = sender
        msg['To'] = ', '.join(moderators)
        msg['Subject'] = 'Moderate new %s message: %s' % (group, subject)
        msg['Content-Type'] = 'message/rfc822'

        payload = Message()
        for header, value in article.headers.values():
            payload.add_header(header, value)
        payload.set_payload(article.body)

        msg.attach(payload)

        out = StringIO.StringIO()
        gen = Generator(out, False)
        gen.flatten(msg)
        msg = out.getvalue()

        return self.sendmail(self._mailhost, sender, moderators, msg)
Beispiel #4
0
    def sendAggregateMail(self, cachedResults):
        # cachedResults is a list of dicts: {'name':name, 'build':build, 'results':results}
        projectName = self.status.getProjectName()

        # build will be the same for all messages, so just use the first one
        build = cachedResults[0]['build']

        source = build.getSourceStamp().revision

        # Delimiting wht "," causes email subject line to contain a TAB character for some reason
        blamelist = "|".join(build.getResponsibleUsers())
        p = re.compile(
            " <[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?>"
        )
        blamelist = p.sub("", blamelist)

        slaves = []
        results = []
        for result in cachedResults:
            slaves.append(result['name'])
            results.append(result['results'])

        text = ''
        text += "Blame:  %s\n" % blamelist
        text += "Slave(s):  %s\n" % ', '.join(slaves)
        text += "Branch:    %s\n" % self.branch
        text += "        %s\n" % self.status.getBuildbotURL()
        text += "Change: %s\n" % source
        # TODO - handle results other than FAILURE
        text += "Status: fail"
        text += "\n"

        if FAILURE in results:
            text += "Log(s) of failed build steps:\n"
            for result in cachedResults:
                if result['results'] == FAILURE:
                    build = result['build']
                    text += "  Slave: %s\n" % result['name']
                    for step in build.getSteps():
                        if step.getResults()[0] == FAILURE:
                            text += "        %s\n" % ''.join(
                                step.getResults()[1])
                            buildurl = "%sbuilders/%s/builds/%d" % (
                                self.status.getBuildbotURL(), result['name'],
                                build.getNumber())
                            text += "        %s/steps/%s/logs/stdio\n" % (
                                buildurl, ''.join(step.getResults()[1]))
                            text += "\n"
                    failSteps, buildinfo = self.getBuildsStatusFileinfo(
                        build, blamelist, source)
                    # add previous failures to email
                    if failSteps:
                        text += '  Buildsteps that were failing before this build:\n'
                        for step in failSteps:
                            text += '    %s Revision: %s Blamelist: %s\n' % (
                                step, buildinfo[step]['revision'],
                                buildinfo[step]['blamelist'])
                        text += "\n"

        m = Message()
        m.set_payload(text)

        m['Date'] = formatdate(localtime=True)
        m['Subject'] = self.subject % {
            'result': 'fail',
            'blamelist': blamelist,
            'branch': self.branch,
            'src': source,
        }

        m['From'] = self.fromaddr
        # m['To'] is added later

        if self.addLogs:
            for result in cachedResults:
                build = result['build']
                for log in build.getLogs():
                    name = "%s.%s" % (log.getStep().getName(), log.getName())
                    a = MIMEText(log.getText())
                    a.add_header('Content-Disposition',
                                 "attachment",
                                 filename=name)
                    m.attach(a)

        # now, who is this message going to?
        dl = []
        recipients = self.extraRecipients[:]
        if self.sendToInterestedUsers and self.lookup:
            for u in build.getInterestedUsers():
                d = defer.maybeDeferred(self.lookup.getAddress, u)
                d.addCallback(recipients.append)
                dl.append(d)
        d = defer.DeferredList(dl)
        d.addCallback(self._gotRecipients, recipients, m)
        return d
Beispiel #5
0
class GPGEmail(SimpleEmail):
    """Třída pro vytvoření a odeslaní jednoduchého kryptovaného mailu."""

    ERR_GPG_MODULE = _(u"Could not import Python GnuPG module")
    ERR_GPG_INSTANCE = _(u"Could not create GPG instance")
    ERR_GPG_KEYRING = _(u"Could not create a temporary GPG keyring")
    ERR_GPG_OUTPUT = _(u"GPG process did not return string.")

    def __init__(self,
                 to,
                 from_,
                 subject,
                 content,
                 key,
                 html=False,
                 smtp='localhost',
                 charset='iso-8859-2'):
        """Inicializuj instanci.
        
          to -- adresa příjemce (zatím podporujeme jen jednoho příjemce)
          from_ -- adresa odesílatele
          subject -- předmět zprávy (může obsahovat buď řetězec nebo unicode
          content -- vlastní obsah zprávy
          key -- veřejný klíč, kterým má být zpráva zakryptována
          html -- příznak, zda obsah je html
          smtp -- adresa odesílacího serveru
          charset -- v případě, že content není v unicode, je zde uveden charset pro content
        """
        super(GPGEmail, self).__init__(to,
                                       from_,
                                       subject,
                                       content,
                                       html=html,
                                       smtp=smtp,
                                       charset=charset)
        self.key = key

    def _create_message(self):
        """Return basic instance of Message."""
        self.msg = Message()

    def _setup_gpg(self):
        "Setup GPG process. Returns initialized gpg instance."
        try:
            import tempfile
            import GnuPGInterface
        except:
            self._error_msg = self.ERR_GPG_MODULE
            return None
        try:
            gpg = GnuPGInterface.GnuPG()
        except:
            self._error_msg = self.ERR_GPG_INSTANCE
            return None
        try:
            keyring = tempfile.mkstemp()[1]
        except:
            self._error_msg = self.ERR_GPG_KEYRING
            return None
        gpg.options.armor = 1
        gpg.options.meta_interactive = 0
        gpg.options.extra_args.append('--no-secmem-warning')
        for o in ('--always-trust', '--no-default-keyring',
                  '--keyring=%s' % keyring):
            gpg.options.extra_args.append(o)
        proc = gpg.run(['--import'], create_fhs=['stdin', 'stderr'])
        proc.handles['stdin'].write(self.key)
        proc.handles['stdin'].close()
        proc.handles['stderr'].read()
        proc.handles['stderr'].close()
        proc.wait()
        return gpg

    def _gpg_encrypt_content(self):
        "Encrypt the content."
        gpg = self._setup_gpg()
        if not gpg:
            raise pytis.util.ProgramError(self._error_msg)
        if isinstance(self.to, basestring):
            to = (self.to, )
        elif isinstance(self.to, unicode):
            # Unicode arguments are problem for GPG process, so we will convert them to UTF-8
            to = []
            for t in self.to:
                to.append(t.encode('UTF-8'))
        else:
            to = self.to
        content = self.get_content_text(self.content,
                                        html=self.html,
                                        charset=self.charset)
        gpg.options.recipients = to  # a list or tuple!
        proc = gpg.run(['--encrypt'], create_fhs=['stdin', 'stdout'])
        proc.handles['stdin'].write(content.as_string())
        proc.handles['stdin'].close()
        output = proc.handles['stdout'].read()
        proc.handles['stdout'].close()
        proc.wait()
        success = True
        if not isinstance(output, basestring):
            success = False
        # BUG: There is no `keyring' defined here so the following
        # statement is effectively void:
        try:
            os.remove(keyring)
        except:
            pass
        if not success:
            raise pytis.util.ProgramError(self.ERR_GPG_OUTPUT)
        else:
            return output

    def create_headers(self):
        super(GPGEmail, self).create_headers()
        self.msg["Mime-version"] = "1.0"
        self.msg["Content-type"] = "Multipart/encrypted"
        self.msg["Content-transfer-encoding"] = "8bit"
        self.msg.preamble = "This is an OpenPGP/MIME encrypted message (RFC 2440 and 3156)"

    def create_content(self):
        # Part 1
        firstSubMsg = email.Message.Message()
        firstSubMsg["Content-Type"] = "application/pgp-encrypted"
        firstSubMsg["Content-Description"] = "PGP/MIME version identification"
        firstSubMsg.set_payload("Version: 1\n")
        # Part 2
        if self.html:
            filename = 'content.html.pgp'
        else:
            filename = 'content.txt.pgp'
        encrypted = self._gpg_encrypt_content()
        secondSubMsg = email.Message.Message()
        secondSubMsg.add_header("Content-Type",
                                "application/octet-stream",
                                name=filename)
        secondSubMsg.add_header("Content-Description",
                                "OpenPGP encrypted message")
        secondSubMsg.add_header("Content-Disposition",
                                "inline",
                                filename=filename)
        secondSubMsg.set_payload(encrypted)
        # Přidání částí do main
        self.msg.attach(firstSubMsg)
        self.msg.attach(secondSubMsg)
Beispiel #6
0
    def sendAggregateMail(self, cachedResults):
        # cachedResults is a list of dicts: {'name':name, 'build':build, 'results':results}
        projectName = self.status.getProjectName()
        
        # build will be the same for all messages, so just use the first one
        build = cachedResults[0]['build']
        
        source = build.getSourceStamp().revision
        
        # Delimiting wht "," causes email subject line to contain a TAB character for some reason
        blamelist = "|".join(build.getResponsibleUsers())
        p = re.compile(" <[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?>")
        blamelist = p.sub("", blamelist)
        
        slaves = []
        results = []
        for result in cachedResults:
            slaves.append(result['name'])
            results.append(result['results'])

        text = ''
        text += "Blame:  %s\n" % blamelist
        text += "Slave(s):  %s\n" % ', '.join(slaves)
        text += "Branch:    %s\n" % self.branch
        text += "        %s\n" % self.status.getBuildbotURL()
        text += "Change: %s\n" % source
        # TODO - handle results other than FAILURE
        text += "Status: fail"
        text += "\n"
        
        if FAILURE in results:
            text += "Log(s) of failed build steps:\n"
            for result in cachedResults:
                if result['results'] == FAILURE:
                    build = result['build']
                    text += "  Slave: %s\n" % result['name']
                    for step in build.getSteps():
                        if step.getResults()[0] == FAILURE:
                            text += "        %s\n" % ''.join(step.getResults()[1])
                            buildurl = "%sbuilders/%s/builds/%d" % (self.status.getBuildbotURL(),result['name'],build.getNumber())
                            text += "        %s/steps/%s/logs/stdio\n" % (buildurl,''.join(step.getResults()[1]))
                            text += "\n"
                    failSteps, buildinfo = self.getBuildsStatusFileinfo(build, blamelist, source)
                    # add previous failures to email
                    if failSteps:
                        text += '  Buildsteps that were failing before this build:\n'
                        for step in failSteps:
                            text += '    %s Revision: %s Blamelist: %s\n' %  (step, buildinfo[step]['revision'], buildinfo[step]['blamelist'])
                        text += "\n"
        
        m = Message()
        m.set_payload(text)
        
        m['Date'] = formatdate(localtime=True)
        m['Subject'] = self.subject % { 'result': 'fail',
                                        'blamelist': blamelist,
                                        'branch': self.branch,
                                        'src': source,
                                        }

        m['From'] = self.fromaddr
        # m['To'] is added later

        if self.addLogs:
            for result in cachedResults:
                build = result['build']
                for log in build.getLogs():
                    name = "%s.%s" % (log.getStep().getName(),
                                      log.getName())
                    a = MIMEText(log.getText())
                    a.add_header('Content-Disposition', "attachment",
                                 filename=name)
                    m.attach(a)

        # now, who is this message going to?
        dl = []
        recipients = self.extraRecipients[:]
        if self.sendToInterestedUsers and self.lookup:
            for u in build.getInterestedUsers():
                d = defer.maybeDeferred(self.lookup.getAddress, u)
                d.addCallback(recipients.append)
                dl.append(d)
        d = defer.DeferredList(dl)
        d.addCallback(self._gotRecipients, recipients, m)
        return d
Beispiel #7
0
    def sendAggregateMail(self, cachedResults):
        # cachedResults is a list of dicts: {'name':name, 'build':build, 'results':results}
        projectName = self.status.getProjectName()
        
        # build will be the same for all messages, so just use the first one
        build = cachedResults[0]['build']
        
        sourcestamp = build.getSourceStamp()
        source = sourcestamp.revision
        
        # Delimiting wht "," causes email subject line to contain a TAB character for some reason
        blamelist = "|".join(build.getResponsibleUsers())
        p = re.compile(" <[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?>")
        blamelist = p.sub("", blamelist)
        
        slaves = []
        results = []
        for result in cachedResults:
            slaves.append(result['name'])
            results.append(result['results'])

        # If _any_ build failed, then we do not send this email (failure emails are dealt with separately)
        if FAILURE in results:
            return

        text = ''
        text += 'Congratulations, your %s build has passed all acceptance tests!\n' % self.branch
        
        text += '\n'
        text += self.getChangesText(sourcestamp.changes)
        
        m = Message()
        m.set_payload(text)
        
        m['Date'] = formatdate(localtime=True)
        m['Subject'] = self.subject % { 'result': 'pass',
                                        'blamelist': blamelist,
                                        'branch': self.branch,
                                        'src': source,
                                        }

        m['From'] = self.fromaddr
        # m['To'] is added later

        if self.addLogs:
            for result in cachedResults:
                build = result['build']
                for log in build.getLogs():
                    name = "%s.%s" % (log.getStep().getName(),
                                      log.getName())
                    a = MIMEText(log.getText())
                    a.add_header('Content-Disposition', "attachment",
                                 filename=name)
                    m.attach(a)

        # now, who is this message going to?
        dl = []
        recipients = self.extraRecipients[:]
        if self.sendToInterestedUsers and self.lookup:
            for u in build.getInterestedUsers():
                d = defer.maybeDeferred(self.lookup.getAddress, u)
                d.addCallback(recipients.append)
                dl.append(d)
        d = defer.DeferredList(dl)
        d.addCallback(self._gotRecipients, recipients, m)
        return d
Beispiel #8
0
    def buildMessage(self, name, build, results):
        
        projectName = self.status.getProjectName()
        sourcestamp = build.getSourceStamp()
        source = sourcestamp.revision
        buildurl = "%sbuilders/%s/builds/%d" % (self.status.getBuildbotURL(),name,build.getNumber())
        
        # Delimiting wht "," causes email subject line to contain a TAB character for some reason
        blamelist = "|".join(build.getResponsibleUsers())
        p = re.compile(" <[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?>")
        blamelist = p.sub("", blamelist)
        
        res = "pass"
        if results == FAILURE:
            res = "fail"
        
        text = ''
        text += 'Slave:  %s\n' % name
        text += 'Branch:    %s\n' % self.branch
        
        text += self.getChangesText(sourcestamp.changes)
        
        if results == FAILURE:
            text += "Log(s) of failed build steps:\n"
            for step in build.getSteps():
                if step.getResults()[0] == FAILURE:
                    text += "        %s\n" % ''.join(step.getResults()[1])
                    text += "        %s/steps/%s/logs/stdio\n" % (buildurl,''.join(step.getResults()[1]))
                    text += "\n"
        
        failSteps, buildinfo = self.getBuildsStatusFileinfo(build, blamelist, source)
        
        # add previous failures to email
        if failSteps:
            text += 'Buildsteps that were failing before this build:\n'
            for step in failSteps:
                text += '    %s Revision: %s Blamelist: %s\n' %  (step, buildinfo[step]['revision'], buildinfo[step]['blamelist'])
            text += "\n"
        
        m = Message()
        m.set_payload(text)
        
        m['Date'] = formatdate(localtime=True)
        m['Subject'] = self.subject % { 'result': res,
                                        'blamelist': blamelist,
                                        'branch': self.branch,
                                        'src': source,
                                        }

        m['From'] = self.fromaddr
        # m['To'] is added later

        if self.addLogs:
            for log in build.getLogs():
                name = "%s.%s" % (log.getStep().getName(),
                                  log.getName())
                a = MIMEText(log.getText())
                a.add_header('Content-Disposition', "attachment",
                             filename=name)
                m.attach(a)

        # now, who is this message going to?
        dl = []
        recipients = self.extraRecipients[:]
        if self.sendToInterestedUsers and self.lookup:
            for u in build.getInterestedUsers():
                d = defer.maybeDeferred(self.lookup.getAddress, u)
                d.addCallback(recipients.append)
                dl.append(d)
        d = defer.DeferredList(dl)
        d.addCallback(self._gotRecipients, recipients, m)
        return d
Beispiel #9
0
    def sendAggregateMail(self, cachedResults):
        # cachedResults is a list of dicts: {'name':name, 'build':build, 'results':results}
        projectName = self.status.getProjectName()

        # build will be the same for all messages, so just use the first one
        build = cachedResults[0]['build']

        sourcestamp = build.getSourceStamp()
        source = sourcestamp.revision

        # Delimiting wht "," causes email subject line to contain a TAB character for some reason
        blamelist = "|".join(build.getResponsibleUsers())
        p = re.compile(
            " <[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?>"
        )
        blamelist = p.sub("", blamelist)

        slaves = []
        results = []
        for result in cachedResults:
            slaves.append(result['name'])
            results.append(result['results'])

        # If _any_ build failed, then we do not send this email (failure emails are dealt with separately)
        if FAILURE in results:
            return

        text = ''
        text += 'Congratulations, your %s build has passed all acceptance tests!\n' % self.branch

        text += '\n'
        text += self.getChangesText(sourcestamp.changes)

        m = Message()
        m.set_payload(text)

        m['Date'] = formatdate(localtime=True)
        m['Subject'] = self.subject % {
            'result': 'pass',
            'blamelist': blamelist,
            'branch': self.branch,
            'src': source,
        }

        m['From'] = self.fromaddr
        # m['To'] is added later

        if self.addLogs:
            for result in cachedResults:
                build = result['build']
                for log in build.getLogs():
                    name = "%s.%s" % (log.getStep().getName(), log.getName())
                    a = MIMEText(log.getText())
                    a.add_header('Content-Disposition',
                                 "attachment",
                                 filename=name)
                    m.attach(a)

        # now, who is this message going to?
        dl = []
        recipients = self.extraRecipients[:]
        if self.sendToInterestedUsers and self.lookup:
            for u in build.getInterestedUsers():
                d = defer.maybeDeferred(self.lookup.getAddress, u)
                d.addCallback(recipients.append)
                dl.append(d)
        d = defer.DeferredList(dl)
        d.addCallback(self._gotRecipients, recipients, m)
        return d
Beispiel #10
0
    def buildMessage(self, name, build, results):

        projectName = self.status.getProjectName()
        sourcestamp = build.getSourceStamp()
        source = sourcestamp.revision
        buildurl = "%sbuilders/%s/builds/%d" % (self.status.getBuildbotURL(),
                                                name, build.getNumber())

        # Delimiting wht "," causes email subject line to contain a TAB character for some reason
        blamelist = "|".join(build.getResponsibleUsers())
        p = re.compile(
            " <[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?>"
        )
        blamelist = p.sub("", blamelist)

        res = "pass"
        if results == FAILURE:
            res = "fail"

        text = ''
        text += 'Slave:  %s\n' % name
        text += 'Branch:    %s\n' % self.branch

        text += self.getChangesText(sourcestamp.changes)

        if results == FAILURE:
            text += "Log(s) of failed build steps:\n"
            for step in build.getSteps():
                if step.getResults()[0] == FAILURE:
                    text += "        %s\n" % ''.join(step.getResults()[1])
                    text += "        %s/steps/%s/logs/stdio\n" % (
                        buildurl, ''.join(step.getResults()[1]))
                    text += "\n"

        failSteps, buildinfo = self.getBuildsStatusFileinfo(
            build, blamelist, source)

        # add previous failures to email
        if failSteps:
            text += 'Buildsteps that were failing before this build:\n'
            for step in failSteps:
                text += '    %s Revision: %s Blamelist: %s\n' % (
                    step, buildinfo[step]['revision'],
                    buildinfo[step]['blamelist'])
            text += "\n"

        m = Message()
        m.set_payload(text)

        m['Date'] = formatdate(localtime=True)
        m['Subject'] = self.subject % {
            'result': res,
            'blamelist': blamelist,
            'branch': self.branch,
            'src': source,
        }

        m['From'] = self.fromaddr
        # m['To'] is added later

        if self.addLogs:
            for log in build.getLogs():
                name = "%s.%s" % (log.getStep().getName(), log.getName())
                a = MIMEText(log.getText())
                a.add_header('Content-Disposition',
                             "attachment",
                             filename=name)
                m.attach(a)

        # now, who is this message going to?
        dl = []
        recipients = self.extraRecipients[:]
        if self.sendToInterestedUsers and self.lookup:
            for u in build.getInterestedUsers():
                d = defer.maybeDeferred(self.lookup.getAddress, u)
                d.addCallback(recipients.append)
                dl.append(d)
        d = defer.DeferredList(dl)
        d.addCallback(self._gotRecipients, recipients, m)
        return d
Beispiel #11
0
class GPGEmail(SimpleEmail):
    """Třída pro vytvoření a odeslaní jednoduchého kryptovaného mailu."""

    ERR_GPG_MODULE = _(u"Could not import Python GnuPG module")
    ERR_GPG_INSTANCE = _(u"Could not create GPG instance")
    ERR_GPG_KEYRING = _(u"Could not create a temporary GPG keyring")
    ERR_GPG_OUTPUT = _(u"GPG process did not return string.")
    
    def __init__(self, to, from_, subject, content, key, html=False,
                 smtp='localhost', charset='iso-8859-2'):
        """Inicializuj instanci.
        
          to -- adresa příjemce (zatím podporujeme jen jednoho příjemce)
          from_ -- adresa odesílatele
          subject -- předmět zprávy (může obsahovat buď řetězec nebo unicode
          content -- vlastní obsah zprávy
          key -- veřejný klíč, kterým má být zpráva zakryptována
          html -- příznak, zda obsah je html
          smtp -- adresa odesílacího serveru
          charset -- v případě, že content není v unicode, je zde uveden charset pro content
        """
        super(GPGEmail, self).__init__(to, from_, subject, content, html=html,
                                       smtp=smtp, charset=charset)
        self.key = key

    def _create_message(self):
        """Return basic instance of Message."""
        self.msg = Message()
        
    def _setup_gpg(self):
        "Setup GPG process. Returns initialized gpg instance."
        try:
            import tempfile
            import GnuPGInterface
        except:
            self._error_msg = self.ERR_GPG_MODULE
            return None
        try:
            gpg = GnuPGInterface.GnuPG()
        except:
            self._error_msg = self.ERR_GPG_INSTANCE
            return None
        try:
            keyring = tempfile.mkstemp()[1]
        except:
            self._error_msg = self.ERR_GPG_KEYRING
            return None
        gpg.options.armor = 1
        gpg.options.meta_interactive = 0
        gpg.options.extra_args.append('--no-secmem-warning')
        for o in ('--always-trust', '--no-default-keyring', '--keyring=%s' % keyring):
            gpg.options.extra_args.append(o)
        proc = gpg.run(['--import'], create_fhs=['stdin', 'stderr'])
        proc.handles['stdin'].write(self.key)
        proc.handles['stdin'].close()
        proc.handles['stderr'].read()
        proc.handles['stderr'].close()
        proc.wait()
        return gpg
    
    def _gpg_encrypt_content(self):
        "Encrypt the content."
        gpg = self._setup_gpg()
        if not gpg:
            raise pytis.util.ProgramError(self._error_msg)
        if isinstance(self.to, basestring):
            to = (self.to,)
        elif isinstance(self.to, unicode):
            # Unicode arguments are problem for GPG process, so we will convert them to UTF-8
            to = []
            for t in self.to:
                to.append(t.encode('UTF-8'))
        else:
            to = self.to
        content = self.get_content_text(self.content, html=self.html, charset=self.charset)
        gpg.options.recipients = to   # a list or tuple!
        proc = gpg.run(['--encrypt'], create_fhs=['stdin', 'stdout'])
        proc.handles['stdin'].write(content.as_string())
        proc.handles['stdin'].close()
        output = proc.handles['stdout'].read()
        proc.handles['stdout'].close()
        proc.wait()
        success = True
        if not isinstance(output, basestring):
            success = False
        # BUG: There is no `keyring' defined here so the following
        # statement is effectively void:
        try:
            os.remove(keyring)
        except:
            pass
        if not success:
            raise pytis.util.ProgramError(self.ERR_GPG_OUTPUT)
        else:
            return output

    def create_headers(self):
        super(GPGEmail, self).create_headers()
        self.msg["Mime-version"] = "1.0"
        self.msg["Content-type"] = "Multipart/encrypted"
        self.msg["Content-transfer-encoding"] = "8bit"
        self.msg.preamble = "This is an OpenPGP/MIME encrypted message (RFC 2440 and 3156)"
       
    def create_content(self):
        # Part 1
        firstSubMsg = email.Message.Message()
        firstSubMsg["Content-Type"] = "application/pgp-encrypted"
        firstSubMsg["Content-Description"] = "PGP/MIME version identification"
        firstSubMsg.set_payload("Version: 1\n")
        # Part 2
        if self.html:
            filename = 'content.html.pgp'
        else:
            filename = 'content.txt.pgp'
        encrypted = self._gpg_encrypt_content()
        secondSubMsg = email.Message.Message()
        secondSubMsg.add_header("Content-Type", "application/octet-stream",
                                name=filename)
        secondSubMsg.add_header("Content-Description",
                                "OpenPGP encrypted message")
        secondSubMsg.add_header("Content-Disposition", "inline",
                                filename=filename)
        secondSubMsg.set_payload(encrypted)
        # Přidání částí do main
        self.msg.attach(firstSubMsg)
        self.msg.attach(secondSubMsg)
Beispiel #12
0
def constructMessage(context, fields, charset='utf-8'):
    msg = Message()
    
    primary = []
    
    # First get all headers, storing primary fields for later
    for name, field in fields:
        
        if IPrimaryField.providedBy(field):
            primary.append((name, field,))
            break
        
#         marshaler = queryMultiAdapter((context, field,), IFieldMarshaler)
#         if marshaler is None:
#             LOG.debug("No marshaler found for field %s of %s" % (name, repr(context)))
#             continue
#          
#         try:
#             value = marshaler.marshal(charset, primary=False)
#         except ValueError, e:
#             LOG.debug("Marshaling of %s for %s failed: %s" % (name, repr(context), str(e)))
#             continue
#          
#         if value is None:
#             value = ''
#         elif not isinstance(value, str):
#             raise ValueError("Marshaler for field %s did not return a string" % name)
#          
#         if marshaler.ascii and '\n' not in value:
#             msg[name] = value
#         else:
#             msg[name] = Header(value, charset)
    
    # Then deal with the primary field
    
    # If there's a single primary field, we have a non-multipart message with
    # a string payload

    if len(primary) == 1:
        name, field = primary[0]
        
        marshaler = queryMultiAdapter((context, field,), IFieldMarshaler)
#         import pdb
#         pdb.set_trace()
        if marshaler is not None:
            contentType = marshaler.getContentType()
            payloadCharset = marshaler.getCharset(charset)
            
#             if contentType is not None:
#                 msg.set_type(contentType)
#             
#             if payloadCharset is not None:
#                 # using set_charset() would also add transfer encoding,
#                 # which we don't want to do always
#                 msg.set_param('charset', payloadCharset)
                
            value = marshaler.marshal(charset, primary=True)
#             import pdb
#             pdb.set_trace()
            if value is not None:
                msg.set_payload(value)
            
#             marshaler.postProcessMessage(msg)
    
    # Otherwise, we return a multipart message
    
    elif len(primary) > 1:
        msg.set_type('multipart/mixed')
        
        for name, field in primary:
            
            marshaler = queryMultiAdapter((context, field,), IFieldMarshaler)
            if marshaler is None:
                continue
            
            payload = Message()
            attach = False
            
            contentType = marshaler.getContentType()
            payloadCharset = marshaler.getCharset(charset)
            
            if contentType is not None:
                payload.set_type(contentType)
                attach = True
            if payloadCharset is not None:
                # using set_charset() would also add transfer encoding,
                # which we don't want to do always
                payload.set_param('charset', payloadCharset)
                attach = True
            
            value = marshaler.marshal(charset, primary=True)
            
            if value is not None:
                payload.set_payload(value)
                attach = True
            
            if attach:
                marshaler.postProcessMessage(payload)
                msg.attach(payload)

    return msg
Beispiel #13
0
class SmartMessage:
    """Uproszczony interfejs dla bibliotek Pythona, który potrafi tworzyæ
    wiadomoœci tekstowe i z za³¹cznikami MIME."""
    def __init__(self, fromAddr, toAddrs, subject, body, enc='iso-8859-2'):
        """Zacznij od za³o¿enia, i¿ bêdzie to prosta wiadomoœæ tekstowa
        zgodna z RFC 2822 i bez MIME."""
        self.msg = Message()
        self.msg.set_payload(body)
        self['Subject'] = subject
        self.setFrom(fromAddr)
        self.setTo(toAddrs)
        self.hasAttachments = False
        self.enc = enc

    def setFrom(self, fromAddr):
        "Ustawia adres nadawcy wiadomoœci."
        if not fromAddr or not type(fromAddr) == type(''):
            raise Exception, 'Wiadomoœæ musi mieæ jednego i tylko jednego nadawcê.'
        self['From'] = fromAddr

    def setTo(self, to):
        "Ustawia adresy osób, które maj¹ otrzymaæ wiadomoœæ."
        if not to:
            raise Exception, 'Wiadomoœæ musi mieæ co najmniej jednego odbiorcê.'
        self._addresses(to, 'To')

        #Dodatkowo przechowuj adresy jako listê. Byæ mo¿e
        #skorzysta z niej kod, który zajmie siê wysy³aniem wiadomoœci.
        self.to = to

    def setCc(self, cc):
        """Ustawia adresy osób, które maj¹ otrzymaæ kopiê wiadomoœc. choæ
        nie jest ona adresowana do nich w sposób bezpoœredni."""
        self._addresses(cc, 'Cc')

    def addAttachment(self, attachment, filename, mimetype=None):
        "Do³¹cza do wiadomoœci wskazany plik."

        #Odgadnij g³ówny i dodatkowy typ MIME na podstawie nazwy pliku.
        if not mimetype:
            mimetype = mimetypes.guess_type(filename)[0]
        if not mimetype:
            raise Exception, "Nie uda³o siê okreœliæ typu MIME dla", filename
        if '/' in mimetype:
            major, minor = mimetype.split('/')
        else:
            major = mimetype
            minor = None

        #Wiadomoœæ by³a konstruowana z za³o¿eniem, i¿ bêdzie zawieraæ
        #tylko i wy³¹cznie tekst. Poniewa¿ wiem, ¿e bêdzie zawieraæ
        #co najmniej jeden za³¹cznik, musimy zmieniæ j¹ na wiadomoœæ
        #wieloczêœciow¹ i wkleiæ tekst jako pierwsz¹ czêœæ.
        if not self.hasAttachments:
            body = self.msg.get_payload()
            newMsg = MIMEMultipart()
            newMsg.attach(MIMEText(body, 'plain', self.enc))
            #Skopiuj stare nag³ówki do nowego obiektu.
            for header, value in self.msg.items():
                newMsg[header] = value
            self.msg = newMsg
            self.hasAttachments = True
        subMessage = MIMENonMultipart(major, minor, name=filename)
        subMessage.set_payload(attachment)

        #Zakoduj teksty jako quoted printable natomiast wszystkie
        #inne typy jako base64.
        if major == 'text':
            encoder = Encoders.encode_quopri
        else:
            encoder = Encoders.encode_base64
        encoder(subMessage)

        #Powi¹¿ fragment MIME z g³ówn¹ wiadomoœci¹.
        self.msg.attach(subMessage)

    def _addresses(self, addresses, key):
        """Ustawia zawartoœæ nag³ówka na podstawie listy przekazanych adresów."""
        if hasattr(addresses, '__iter__'):
            addresses = ', '.join(addresses)
        self[key] = addresses

    #Kilka metod dodatkowych umo¿liwiaj¹cych traktowanie klasy w podobny
    #sposób, jak klasy Message lub MultipartMessage, stosuj¹c odpowiedni¹
    #delegacjê poleceñ do tych klas.
    def __getitem__(self, key):
        "Zwróæ nag³ówek o podanym kluczu."
        return self.msg[key]

    def __setitem__(self, key, value):
        "Ustaw nag³ówek o wskazanej nazwie."
        self.msg[key] = value

    def __getattr__(self, key):
        return getattr(self.msg, key)

    def __str__(self):
        "Zwróæ tekstow¹ reprezentacjê wiadomoœci."
        return self.msg.as_string()