Пример #1
0
def main():
	messages = []
	for url in RSS_URLS:
		messages += download_nzbs(url)
	#if len(messages) > 0:
	#	from xmlrpclib import ServerProxy
	#	server = ServerProxy('http://caliburn.csh.rit.edu:9611/')
	#	for msg in messages:
	#		server.message('hella: %s' %msg)

	if MAIL_ENABLED and len(messages) > 0:
		from email.Message import Message
		#print 'Sending email to %s' % EMAIL_TO
		email = Message()
		email.set_unixfrom(MAIL_FROM)
		email.add_header('Subject', '[hella] Queued %s files' % len(messages))
		content = ''
		for msg in messages:
			content += '%s\r\n' % msg
		email.set_payload(content)
		email = email.as_string()

		server = SMTP(MAIL_SERVER)
		server.sendmail(MAIL_FROM, MAIL_TO, email)
		server.quit()
def handler(doc):
    # If all the addresses aren't email addresses, we pass...
    check = [doc['from']] + doc['to'] + doc.get('cc', []) + doc.get('bcc', [])
    for c in check:
        if c[0] != 'email':
            logger.info('skipping %(_id)r - not all email addresses', doc)
            return
    # all addresses are emails - so off we go...
    smtp_items = {}
    m = Message()
    (_, addr) = doc['from']
    smtp_items['smtp_from'] = addr
    m.add_header('From', formataddr((doc['from_display'], doc['from'][1])))

    smtp_to = smtp_items['smtp_to'] = []
    for (_, addr), name in zip(doc.get('to', []), doc.get('to_display', [])):
        m.add_header('To', formataddr((name, addr)))
        smtp_to.append(addr)
    for (_, addr), name in zip(doc.get('cc', []), doc.get('cc_display', [])):
        m.add_header('CC', formataddr((name, addr)))
        smtp_to.append(addr)
    for (_, addr), name in zip(doc.get('bcc', []), doc.get('bcc_display', [])):
        m.add_header('BCC', formataddr((name, addr)))
        smtp_to.append(addr)

    m.add_header("Subject", doc['subject'])
    # for now body is plain-text as-is.
    m.set_payload(doc['body'], 'utf-8')
    attach_info = {'smtp_body': {'data': m.as_string()}}
    emit_schema('rd.msg.outgoing.smtp', smtp_items, attachments=attach_info)
Пример #3
0
def create_msg(v, rcptlist=None, origmsg=None, template=None):
    """Create a DSN message from a template.  Template must be '\n' separated.
     v - an object whose attributes are used for substitutions.  Must
       have sender and receiver attributes at a minimum.
     rcptlist - used to set v.rcpt if given
     origmsg - used to set v.subject and v.spf_result if given
     template - a '\n' separated string with python '%(name)s' substitutions.
  """
    if not template:
        return None
    if hasattr(v, 'perm_error'):
        # likely to be an spf.query, try translating for backward compatibility
        q = v
        v = Vars()
        try:
            v.heloname = q.h
            v.sender = q.s
            v.connectip = q.i
            v.receiver = q.r
            v.sender_domain = q.o
            v.result = q.result
            v.perm_error = q.perm_error
        except:
            v = q
    if rcptlist:
        v.rcpt = '\n\t'.join(rcptlist)
    if origmsg:
        try:
            v.subject = origmsg['Subject']
        except:
            v.subject = '(none)'
        try:
            v.spf_result = origmsg['Received-SPF']
        except:
            v.spf_result = None

    msg = Message()

    msg.add_header('X-Mailer', 'PyMilter-' + Milter.__version__)
    msg.set_type('text/plain')

    hdrs, body = template.split('\n\n', 1)
    for ln in hdrs.splitlines():
        name, val = ln.split(':', 1)
        msg.add_header(name, (val % v.__dict__).strip())
    msg.set_payload(body % v.__dict__)
    # add headers if missing from old template
    if 'to' not in msg:
        msg.add_header('To', v.sender)
    if 'from' not in msg:
        msg.add_header('From', 'postmaster@%s' % v.receiver)
    if 'auto-submitted' not in msg:
        msg.add_header('Auto-Submitted', 'auto-generated')
    return msg
Пример #4
0
def create_msg(v,rcptlist=None,origmsg=None,template=None):
  """Create a DSN message from a template.  Template must be '\n' separated.
     v - an object whose attributes are used for substitutions.  Must
       have sender and receiver attributes at a minimum.
     rcptlist - used to set v.rcpt if given
     origmsg - used to set v.subject and v.spf_result if given
     template - a '\n' separated string with python '%(name)s' substitutions.
  """
  if not template:
    return None
  if hasattr(v,'perm_error'):
    # likely to be an spf.query, try translating for backward compatibility
    q = v
    v = Vars()
    try:
      v.heloname = q.h
      v.sender = q.s
      v.connectip = q.i
      v.receiver = q.r
      v.sender_domain = q.o
      v.result = q.result
      v.perm_error = q.perm_error
    except: v = q
  if rcptlist:
    v.rcpt = '\n\t'.join(rcptlist)
  if origmsg:
    try: v.subject = origmsg['Subject']
    except: v.subject = '(none)'
    try:
      v.spf_result = origmsg['Received-SPF']
    except: v.spf_result = None

  msg = Message()

  msg.add_header('X-Mailer','PyMilter-'+Milter.__version__)
  msg.set_type('text/plain')

  hdrs,body = template.split('\n\n',1)
  for ln in hdrs.splitlines():
    name,val = ln.split(':',1)
    msg.add_header(name,(val % v.__dict__).strip())
  msg.set_payload(body % v.__dict__)
  # add headers if missing from old template
  if 'to' not in msg:
    msg.add_header('To',v.sender)
  if 'from' not in msg:
    msg.add_header('From','postmaster@%s'%v.receiver)
  if 'auto-submitted' not in msg:
    msg.add_header('Auto-Submitted','auto-generated')
  return msg
    def _convert_to_mbox_msg(self, msg):
        file_ids = list(msg.objectIds('File'))
        encoding = "utf-8"

        # true only if we have attachments
        if file_ids:
            enc_msg = MIMEMultipart()
            txt = MIMEText(msg.body.encode(encoding))
            enc_msg.attach(txt)
        else:
            enc_msg = Message()
            enc_msg.set_payload(msg.body.encode(encoding))

        enc_msg['From'] = encode_header(msg.from_addr, encoding)
        enc_msg['To'] = encode_header(self.context.mailto, encoding)
        enc_msg['Subject'] = encode_header(msg.subject, encoding).replace("\n", " ").strip()
        enc_msg['Date'] = encode_header(str(msg.date), encoding)
        enc_msg['Message-id'] = encode_header(msg.message_id, encoding)
        if msg.references:
            enc_msg['References'] = encode_header(" ".join(msg.references), encoding)
        if msg.in_reply_to:
            enc_msg['In-reply-to'] = encode_header(msg.in_reply_to, encoding)
                                    
        ctime = str(msg.date)
        enc_msg.set_unixfrom("From %s %s" % (parseaddr(msg.from_addr)[1], ctime))

        for file_id in file_ids:
            file = msg._getOb(file_id)
            data = file.data
            if not isinstance(data, basestring):
                data = str(data)
            content_type = file.getContentType()
            if content_type == 'message/rfc822':
                attachment = message_from_string(data)
            else:
                attachment = Message()
                attachment.add_header('Content-Disposition', 'attachment', filename=file.title)
                attachment.add_header('Content-Type', content_type)
                attachment.set_payload(data)
            enc_msg.attach(attachment)

        try:
            retval = enc_msg.as_string(unixfrom=True)
        except TypeError, e:
            raise
Пример #6
0
 def addAttachment(self, content, content_type='application/octet-stream',
                   inline=False, filename=None, charset=None):
     attachment = Message()
     if charset and isinstance(content, unicode):
         content = content.encode(charset)
     attachment.add_header('Content-Type', content_type)
     if inline:
         disposition = 'inline'
     else:
         disposition = 'attachment'
     disposition_kwargs = {}
     if filename is not None:
         disposition_kwargs['filename'] = filename
     attachment.add_header(
         'Content-Disposition', disposition, **disposition_kwargs)
     attachment.set_payload(content, charset)
     self.encodeOptimally(attachment)
     self.attachments.append(attachment)
Пример #7
0
    def test_sendmail_with_email_header(self):
        """Check the timeline is ok even if there is an email.Header.

        See https://bugs.launchpad.net/launchpad/+bug/885972
        """
        fake_mailer = RecordingMailer()
        self.useFixture(ZopeUtilityFixture(fake_mailer, IMailDelivery, 'Mail'))
        subject_str = self.getUniqueString('subject')
        subject_header = email.header.Header(subject_str)
        message = Message()
        message.add_header('From', '*****@*****.**')
        message['Subject'] = subject_header
        message.add_header('To', '*****@*****.**')
        with CaptureTimeline() as ctl:
            sendmail.sendmail(message)
        self.assertEquals(fake_mailer.from_addr, '*****@*****.**')
        self.assertEquals(fake_mailer.to_addr, ['*****@*****.**'])
        self.checkTimelineHasOneMailAction(ctl.timeline, subject=subject_str)
Пример #8
0
    def test_sendmail_with_email_header(self):
        """Check the timeline is ok even if there is an email.Header.

        See https://bugs.launchpad.net/launchpad/+bug/885972
        """
        fake_mailer = RecordingMailer()
        self.useFixture(ZopeUtilityFixture(
            fake_mailer, IMailDelivery, 'Mail'))
        subject_str = self.getUniqueString('subject')
        subject_header = email.header.Header(subject_str)
        message = Message()
        message.add_header('From', '*****@*****.**')
        message['Subject'] = subject_header
        message.add_header('To', '*****@*****.**')
        with CaptureTimeline() as ctl:
            sendmail.sendmail(message)
        self.assertEquals(fake_mailer.from_addr, '*****@*****.**')
        self.assertEquals(fake_mailer.to_addr, ['*****@*****.**'])
        self.checkTimelineHasOneMailAction(ctl.timeline, subject=subject_str)
Пример #9
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)
Пример #11
0
 def test_epilogue(self):
     fp = openfile('msg_21.txt')
     try:
         text = fp.read()
     finally:
         fp.close()
     msg = Message()
     msg['From'] = '*****@*****.**'
     msg['To'] = '*****@*****.**'
     msg['Subject'] = 'Test'
     msg.preamble = 'MIME message\n'
     msg.epilogue = 'End of MIME message\n'
     msg1 = MIMEText('One')
     msg2 = MIMEText('Two')
     msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY')
     msg.add_payload(msg1)
     msg.add_payload(msg2)
     sfp = StringIO()
     g = Generator(sfp)
     g(msg)
     self.assertEqual(sfp.getvalue(), text)
Пример #12
0
 def test_epilogue(self):
     fp = openfile('msg_21.txt')
     try:
         text = fp.read()
     finally:
         fp.close()
     msg = Message()
     msg['From'] = '*****@*****.**'
     msg['To'] = '*****@*****.**'
     msg['Subject'] = 'Test'
     msg.preamble = 'MIME message\n'
     msg.epilogue = 'End of MIME message\n'
     msg1 = MIMEText('One')
     msg2 = MIMEText('Two')
     msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY')
     msg.add_payload(msg1)
     msg.add_payload(msg2)
     sfp = StringIO()
     g = Generator(sfp)
     g(msg)
     self.assertEqual(sfp.getvalue(), text)
Пример #13
0
 def addAttachment(self,
                   content,
                   content_type='application/octet-stream',
                   inline=False,
                   filename=None,
                   charset=None):
     attachment = Message()
     if charset and isinstance(content, unicode):
         content = content.encode(charset)
     attachment.add_header('Content-Type', content_type)
     if inline:
         disposition = 'inline'
     else:
         disposition = 'attachment'
     disposition_kwargs = {}
     if filename is not None:
         disposition_kwargs['filename'] = filename
     attachment.add_header('Content-Disposition', disposition,
                           **disposition_kwargs)
     attachment.set_payload(content, charset)
     self.encodeOptimally(attachment)
     self.attachments.append(attachment)
Пример #14
0
def send_email(fromAddress, toAddress, subject, message, smtp_server=SMTP_SERVER):
    '''Send an email if there's an error.
    
    This will be replaced by sending messages to a log later.
    '''
    msg = Message()
    msg.add_header('To', toAddress)
    msg.add_header('From', fromAddress)
    msg.add_header('Subject', subject)
    msg.set_payload(message)
    smtp = smtplib.SMTP(smtp_server)
    smtp.sendmail(fromAddress, [toAddress], msg.as_string())
    smtp.quit()
Пример #15
0
def send_email(fromAddress, toAddress, subject, message, smtp_server=SMTP_SERVER):
    """Send an email if there's an error.
    
    This will be replaced by sending messages to a log later.
    """
    msg = Message()
    msg.add_header("To", toAddress)
    msg.add_header("From", fromAddress)
    msg.add_header("Subject", subject)
    msg.set_payload(message)
    smtp = smtplib.SMTP(smtp_server)
    smtp.sendmail(fromAddress, [toAddress], msg.as_string())
    smtp.quit()
def send_email(fromAddress, toAddress, subject, message):
    '''Send an email if there's an error.
    
    This will be replaced by sending messages to a log later.
    '''
    msg = Message()
    msg.add_header('To', toAddress)
    msg.add_header('From', fromAddress)
    msg.add_header('Subject', subject)
    msg.set_payload(message)
    smtp = smtplib.SMTP('bastion')
    smtp.sendmail(fromAddress, [toAddress], msg.as_string())
    smtp.quit()
Пример #17
0
        def __call__(self, sender, recipient, subject, body):
            
            msg = Message()
            msg.add_header("Subject", subject)
            msg.add_header("To", str(recipient))
            msg.add_header("From", str(sender))
            msg.set_payload(body)

            command = [ self.SENDMAIL_PATH, '-i', '-f', sender.address, recipient.address ] 
            command = Command(command)
            command.tochild.write(msg.as_string())
            command.tochild.close()
            command.wait()

            if command.exitcode != 0:
                raise Error("sendmail failed (%d): %s" % (command.exitcode,
                                                          command.output))
Пример #18
0
        def __call__(self, sender, recipient, subject, body):

            msg = Message()
            msg.add_header("Subject", subject)
            msg.add_header("To", str(recipient))
            msg.add_header("From", str(sender))
            msg.set_payload(body)

            command = [
                self.SENDMAIL_PATH, '-i', '-f', sender.address,
                recipient.address
            ]
            command = Command(command)
            command.tochild.write(msg.as_string())
            command.tochild.close()
            command.wait()

            if command.exitcode != 0:
                raise Error("sendmail failed (%d): %s" %
                            (command.exitcode, command.output))
Пример #19
0
class Out(object):
    def get():
        global theOutput
        if theOutput is None:
            raise Error, "No output object has been installed."
        return theOutput

    get = staticmethod(get)

    def __init__(self):
        global theOutput
        if theOutput is not None:
            raise Error, "An output object has already been installed."

            # Hook standard output
        self.real_stdout = sys.stdout
        self.buffer = cStringIO.StringIO()
        sys.stdout = self.buffer

        # Default content type
        self.contenttype = "text/html"

        # No headers
        self.headers = Message()
        self.sendEntityHeaders = True
        self.redirecting = False

        self.cookies = Cookie.SimpleCookie()

        # Detect compression
        self.acceptsGzip = 0
        if os.environ.get("HTTP_ACCEPT_ENCODING", "").find("gzip") != -1:
            self.acceptsGzip = 1

            # Trap exiting a script to force output to close
        self.ran = False
        theOutput = self
        sys.exitfunc = Close

    def getResponseBody(self, body):
        if self.acceptsGzip:
            # gzip writes the time into its header
            # this kills cacheability, so we hack the time to be 0
            real_time = time.time
            time.time = lambda a=None: 0
            zbuf = cStringIO.StringIO()
            zfile = gzip.GzipFile(mode="wb", fileobj=zbuf)
            zfile.write(body)
            zfile.close()
            self.headers["Content-Encoding"] = "gzip"
            output = zbuf.getvalue()
            time.time = real_time
            return output
        else:
            return body

    def close(self):
        if self.ran:
            return

        # Restore stdout so we can pipe our data out
        sys.stdout = self.real_stdout

        body = self.buffer.getvalue()
        headers = ""
        self.buffer.close()

        # Look for any headers already written
        if re.search("location:", body, re.I):
            self.redirecting = True
            self.sendEntityHeaders = False
            msg = HeaderParser().parsestr(body, True)

            # Add written headers to our header list
            for name, value in msg.items():
                self.headers.add_header(name, value)

        elif re.search("content-type:", body, re.I):
            try:
                endOfHeaders = body.index("\n\n")
                headers = body[:endOfHeaders]
                body = body[endOfHeaders + 2 :]

                msg = HeaderParser().parsestr(headers, True)

                # Add written headers to our header list
                for name, value in msg.items():
                    self.headers.add_header(name, value)

            except ValueError:
                raise error, "Headers detected, sort of"

                # Get the response body, possibly compressed
        if self.sendEntityHeaders:
            body = self.getResponseBody(body)

        del self.headers["Content-Length"]
        self.headers["Content-Length"] = str(len(body))

        if not self.redirecting and (not "content-type" in self.headers):
            self.headers["Content-Type"] = self.contenttype

        etag = base64.encodestring(md5.new(body).digest())[:-1]
        self.headers["ETag"] = '"' + etag + '"'
        if "HTTP_IF_NONE_MATCH" in os.environ:
            if etag in ETags(os.environ["HTTP_IF_NONE_MATCH"]):
                print "Status: 304 Not Modified"
                self.sendEntityHeaders = False

        self._send_headers()

        if self.sendEntityHeaders:
            sys.stdout.write(body)

        self.ran = True

    def _send_headers(self):
        for header in self.headers.keys():
            if (not self.sendEntityHeaders) and (header.lower() in entity_headers):
                continue
            print header + ": " + str(self.headers[header])

        if len(self.cookies) > 0:
            print self.cookies.output()

        print
Пример #20
0
def construct_message(imap, msg_format, msg_to, msg_from, msg_date, msg_subject, msg_body):
	msg = Message()
	msg.add_header('Date', formatdate(time.mktime(msg_date.timetuple())))
	msg.add_header('Message-Id', create_id(msg_date, msg_from))
	msg.add_header('To', msg_to)
	msg.add_header('From', msg_from)
	msg.add_header('MIME-Version', '1.0')
	msg.add_header('Subject', msg_subject)
	payload = Message()
	payload.add_header('Content-Type', msg_format)
	if msg_format in ('text/html', 'text/plain'):
		payload.add_header('Content-Transfer-Encoding', '8bit')
		payload.set_payload(''.join(msg_body))
	else:
		payload.add_header('Content-Transfer-Encoding', 'base64')
		payload.add_header('Content-Disposition', 'attachment; filename="%s"' % msg_subject)
		payload.set_payload(encodestring(''.join(msg_body)).decode())
	for item in payload.items():
		msg.add_header(item[0], item[1])
		msg.set_payload(payload.get_payload())
	try:
		msg.as_string()
	except Exception, e:
		print e
Пример #21
0
# Copyright (C) 2001 Python Software Foundation
Пример #22
0
    def repost(self,cancelid):
        self.__cancelid = cancelid

        self._getCancelMsg()
        self._getOriginalMsg()

        text1 = self.__origMsg.get_payload()
        text2 = self.__cancelMsg.as_string() 
         
        newmsg = Message()
        newmsg['Sender'] = self.__reposter
        
        newmsg['Newsgroups'] = self.__origMsg['Newsgroups']
        newmsg['From'] = self.__origMsg['From']
        newmsg['Subject'] = '[REPOST] ' + self.__origMsg['Subject'] 
        
        if self.__origMsg.has_key('References'):
            newmsg['References'] =  self.__origMsg['References']
        
        newmsg['Supersedes'] = self.__origMsg['Message-ID']
        
        if self.__origMsg.has_key('Followup-To'):    
            newmsg['Followup-To'] = self.__origMsg['Followup-To']
        
        if self.__origMsg.has_key('Reply-To'):    
            newmsg['Reply-To'] = self.__origMsg['Reply-To']
            
        if self.__origMsg.has_key('Organization'):    
            newmsg['Organization'] = self.__origMsg['Organization']
        
        newmsg['X-Original-Path'] = self.__origMsg['Path']

    
        from datetime import datetime
        now = datetime.now()
        
        s1 = now.strftime("%y%j%H%M%S.")
        
        s2 = self.__origMsg['Message-ID']
        s2 = s2[1:-1]

        newmsg['Message-ID'] = '<REPOST.' + s1 + s2 + ">"
        newmsg['X-Original-Message-ID'] = self.__origMsg['Message-ID']
                        
        if self.__origMsg.has_key('NNTP-Posting-Host'):    
            newmsg['X-Original-NNTP-Posting-Host'] = self.__origMsg['NNTP-Posting-Host']

        if self.__origMsg.has_key('NNTP-Posting-Date'):    
            newmsg['X-Original-NNTP-Posting-Date'] = self.__origMsg['NNTP-Posting-Date']
        
        newmsg['X-Original-Date'] = self.__origMsg['Date']

        newmsg['X-Comment'] = 'Reposted by NNTPRepost ' + self.__reposter
        newmsg.add_header('X-Comment', 'The following Usenet article was cancelled') 
        newmsg.add_header('X-Comment', 'more than likely by someone other than the original poster.')  
        newmsg.add_header('X-Comment', 'Please see the end of this posting for a copy of the cancel.')
        newmsg.add_header('X-Comment', self.__reposter)
                 
        newmsg['X-Reposted-By'] = newmsg['Sender']
        newmsg['Path'] = '!NNTPRepost'
        
        newmsg['X-No-Archive'] = 'yes'

        if self.__origMsg.has_key('MIME-Version'):    
            newmsg['MIME-Version'] = self.__origMsg['MIME-Version']

        if self.__origMsg.has_key('Content-Type'):    
            newmsg['Content-Type'] = self.__origMsg['Content-Type']

        if self.__origMsg.has_key('Content-Transfer-Encoding'):    
            newmsg['Content-Transfer-Encoding'] = self.__origMsg['Content-Transfer-Encoding']
        
        text = text1 + "\n========= WAS CANCELLED BY =======:\n" + text2
        text = text1 + "\n-- \n========= WAS CANCELLED BY =======:\n" + text2

        newmsg.set_payload(text)

        self.__nntpc.post(newmsg)
Пример #23
0
 def forum_post_as_email(self, forum, post):
     '''Convert a post to email'''
     topic = post.topic
     sre, subject = re.match(r'(Re: )?(.*)',
                             post.subject).groups()
     if subject == '':
         if post.pid != topic.firstpost:
             sre = 'Re: '
         subject = topic.title or 'topic %s' % topic.tid
     subject = (sre or '') + forum.subjectPrefix + subject
     if post.datetime is not None:
         pass
     zauthor,n = re.subn(r'[^-A-Za-z0-9]+','_', post.author)
     fromm = _subst(self.fromPattern, u=zauthor)
     msgid = _subst(self.messageIdPattern, p=post.pid)
     hbody = '<html><body>%s</body></html>' % post.body.encode('utf-8')
     try:
         from email.Message import Message 
         from email.Header import Header
         from email.Utils import formatdate
         # Force quoted-printable for utf-8 instead of base64 (for Thunderbird "View source")
         import email.Charset as cs
         cs.add_charset('utf-8', cs.SHORTEST, cs.QP, 'utf-8')
     except ImportError:
         from email.message import Message
         from email.header import Header
         from email.utils import formatdate
     msg = Message()
     msg.add_header('From', fromm)
     msg.add_header('To', forum.recipient)
     hsubj = Header(subject)
     msg.add_header('Subject', str(hsubj))
     msg.add_header('Message-ID', '<%s>' % msgid)
     if topic.firstpost:
         firstid = _subst(self.messageIdPattern, p=topic.firstpost)
         msg.add_header('In-Reply-To', '<%s>' % firstid)
         msg.add_header('References', '<%s>' % firstid)
     if post.datetime is not None:
         date = formatdate(post.datetime)
         msg.add_header('Date', date)
     msg.set_payload(hbody)
     msg.set_type('text/html')
     msg.set_charset('utf-8')
     return msg.as_string()
Пример #24
0
    which bugzilla is telling us is not an account in bugzilla.  If you could
    please set up an account in bugzilla with this address or change your email
    address on your Fedora Account to match an existing bugzilla account this would
    let us go forward.

    Note: this message is being generated by an automated script.  You'll continue
    getting this message until the problem is resolved.  Sorry for the
    inconvenience.

    Thank you,
    The Fedora Account System
    %(admin_email)s
    ''' % {'name': person.person.human_name, 'email': person.email,
            'admin_email': ADMINEMAIL}

            msg.add_header('To', person.email)
            msg.add_header('From', ADMINEMAIL)
            msg.add_header('Subject', 'Fedora Account System and Bugzilla Mismatch')
            msg.set_payload(message)
            smtp = smtplib.SMTP(MAILSERVER)
            smtp.sendmail(ADMINEMAIL, [person.email], msg.as_string())
            smtp.quit()
    recipients = [e for e in NOTIFYEMAIL if e != '$USER']
    if recipients and no_bz_account:
        smtplib.SMTP(MAILSERVER)
        msg = Message()
        people = []
        for person in no_bz_account:
            if person.person.status == 'Active':
                people.append('  %(user)s  --  %(name)s  --  %(email)s' %
                    {'name': person.person.human_name, 'email': person.email,
Пример #25
0
def verpdeliver(mlist, msg, msgdata, envsender, failures, conn):
    for recip in msgdata['recips']:
        # We now need to stitch together the message with its header and
        # footer.  If we're VERPIng, we have to calculate the envelope sender
        # for each recipient.  Note that the list of recipients must be of
        # length 1.
        #
        # BAW: ezmlm includes the message number in the envelope, used when
        # sending a notification to the user telling her how many messages
        # they missed due to bouncing.  Neat idea.
        msgdata['recips'] = [recip]
        # Make a copy of the message and decorate + delivery that
        msgcopy = copy.deepcopy(msg)
        Decorate.process(mlist, msgcopy, msgdata)
        # Calculate the envelope sender, which we may be VERPing
        if msgdata.get('verp'):
            bmailbox, bdomain = Utils.ParseEmail(envsender)
            rmailbox, rdomain = Utils.ParseEmail(recip)
            if rdomain is None:
                # The recipient address is not fully-qualified.  We can't
                # deliver it to this person, nor can we craft a valid verp
                # header.  I don't think there's much we can do except ignore
                # this recipient.
                syslog('smtp', 'Skipping VERP delivery to unqual recip: %s',
                       recip)
                continue
            d = {'bounces': bmailbox,
                 'mailbox': rmailbox,
                 'host'   : DOT.join(rdomain),
                 }
            envsender = '%s@%s' % ((mm_cfg.VERP_FORMAT % d), DOT.join(bdomain))
        if mlist.personalize == 2:
            # When fully personalizing, we want the To address to point to the
            # recipient, not to the mailing list
            del msgcopy['to']
            name = None
            if mlist.isMember(recip):
                name = mlist.getMemberName(recip)
            if name:
                # Convert the name to an email-safe representation.  If the
                # name is a byte string, convert it first to Unicode, given
                # the character set of the member's language, replacing bad
                # characters for which we can do nothing about.  Once we have
                # the name as Unicode, we can create a Header instance for it
                # so that it's properly encoded for email transport.
                charset = Utils.GetCharSet(mlist.getMemberLanguage(recip))
                if charset == 'us-ascii':
                    # Since Header already tries both us-ascii and utf-8,
                    # let's add something a bit more useful.
                    charset = 'iso-8859-1'
                charset = Charset(charset)
                codec = charset.input_codec or 'ascii'
                if not isinstance(name, UnicodeType):
                    name = unicode(name, codec, 'replace')
                name = Header(name, charset).encode()
                msgcopy['To'] = formataddr((name, recip))
            else:
                msgcopy['To'] = recip
        # We can flag the mail as a duplicate for each member, if they've
        # already received this message, as calculated by Message-ID.  See
        # AvoidDuplicates.py for details.
        del msgcopy['x-mailman-copy']
        if msgdata.get('add-dup-header', {}).has_key(recip):
            msgcopy['X-Mailman-Copy'] = 'yes'
        # GPG encryption
        if 'encrypted_gpg' in msgdata and msgdata['encrypted_gpg'] and mlist.encrypt_policy!=0:
            # Encryption is not forbidden in config
            try:
                keyids=mlist.getGPGKeyIDs(recip)
            except:
                keyids=None
            if enforceEncryptPolicy(mlist,msg,msgdata) and keyids==None:
                syslog('gpg','Encryption mandatory, but no keys found for %s: '\
                        'Discarding message',recip)
                failures[recip]=(550,'Encryption mandatory, but no keys found')
                return
            gh = GPGUtils.GPGHelper(mlist)
            # Extract / generate plaintext
            gpg_use_inlineformat = False # TODO: Create config setting
            if not msgcopy.is_multipart() and gpg_use_inlineformat:
                plaintext=msgcopy.get_payload()
            else:
                if not msgcopy.is_multipart():
                    plaintext = 'Content-Type: %s\n' \
                        'Content-Disposition: inline\n' \
                        % msgcopy.get('Content-Type')
                    if not msgcopy.get('Content-Transfer-Encoding') is None:
                        plaintext += 'Content-Transfer-Encoding: %s\n' \
                                % msgcopy.get('Content-Transfer-Encoding')
                    plaintext += '\n%s' % msgcopy.get_payload()
                else:
                    hp = HeaderParser()
                    tmp = msgcopy.as_string()
                    tmpmsg = hp.parsestr(tmp)
                    plaintext = 'Content-Type: %s\n' \
                        'Content-Disposition: inline\n\n%s' \
                        % (msgcopy.get('Content-Type'),tmpmsg.get_payload())
            # Do encryption, report errors
            ciphertext = None
            if not keyids is None:
                # Can encrypt.
                # No signing policy, or voluntary and original wasn't signed: just encrypt
                if mlist.sign_policy == 0 or \
                    (mlist.sign_policy==1 and not msgdata['signed_gpg']):
                    ciphertext = gh.encryptMessage(plaintext,keyids)
                else:
                    ciphertext = gh.encryptSignMessage(plaintext,keyids)
                if ciphertext==None:
                    # Must always encrypt, since if we arrived here encrypt_policy
                    # is either Mantatory or (Voluntary and incoming msg was encrypted).
                    syslog('gpg',"Can't encrypt message to %s: " \
                            "Discarding message",keyids)
                    failures[recip]=(550,'Unable to encrypt message')
                    return
            # Compile encrypted message
            if not ciphertext is None:
                if msgcopy.has_key('Content-Transfer-Encoding'):
                    msgcopy.replace_header('Content-Transfer-Encoding','7bit')
                else:
                    msgcopy.add_header('Content-Transfer-Encoding','7bit')
                if not msgcopy.is_multipart() and gpg_use_inlineformat:
                    msgcopy.set_payload(ciphertext)
                    msgcopy.set_param('x-action','pgp-encrypted')
                else:
                    msgcopy.replace_header('Content-Type','multipart/encrypted')
                    msgcopy.set_param('protocol','application/pgp-encrypted')
                    msgcopy.set_payload(None)
                    submsg = Message()
                    submsg.add_header('Content-Type','application/pgp-encrypted')
                    submsg.set_payload('Version: 1\n')
                    msgcopy.attach(submsg)
                    submsg = Message()
                    submsg.add_header('Content-Type','application/octet-stream; name="encrypted.asc"')
                    submsg.add_header('Content-Disposition','inline; filename="encrypted.asc"')
                    submsg.set_payload(ciphertext)
                    msgcopy.attach(submsg)
                syslog('gpg','Sending encrypted message to %s',recip)
            else:
                syslog('gpg','Sending unencrypted message to %s',recip)

        if 'encrypted_smime' in msgdata and msgdata['encrypted_smime'] and mlist.encrypt_policy != 0:
            # FIXME: this is as crude as can be
            sm = SMIMEUtils.SMIMEHelper(mlist)
            recipfile = sm.getSMIMEMemberCertFile(recip)

            if not recipfile:
                failures[recip]=(550,'No S/MIME key found')
                return
            else:
                plaintext=msgcopy.get_payload()
                if not msgcopy.is_multipart():
                    plaintext = msgcopy.get_payload()
                    syslog('gpg', "About to S/MIME encrypt plaintext from singlepart")
                else:
                    # message contains e.g. signature?
                    # FIXME we fetch only the first attachment.  We search for
                    # attachments only 2 levels deep.  That's suboptimal...
                    # perhaps the PGP way (invoking
                    # hp = HeaderParser()
                    # ) is better.
                    submsgs = msgcopy.get_payload()
                    submsg = submsgs[0]
                    if not submsg.is_multipart():
                        plaintext = submsg.get_payload()
                    else:
                        subsubmsgs = submsg.get_payload()
                        subsubmsg = subsubmsgs[0]
                        plaintext = subsubmsg.get_payload()

                    syslog('gpg', "About to S/MIME encrypt plaintext from multipart")

                if mlist.sign_policy == 0 or \
                    (mlist.sign_policy==1 and not msgdata['signed_smime']):
                    ciphertext = sm.encryptMessage(plaintext,recipfile)
                else:
                    ciphertext = sm.encryptSignMessage(plaintext,recipfile)

                # deal with both header and body-part of ciphertext
                (header, body) = ciphertext.split("\n\n", 1)
                for l in header.split("\n"):
                    (k, v) = l.split(": ", 1)

                    # behave sane with borken openssl like 0.9.7e (e.g. Debian's 0.9.7e-3sarge1)
                    # openssl 0.9.8a-4a0.sarge.1 is known to work OK.
                    # A borken openssl (and therefore sm.encryptMessage) returns
                    #  Content-Type: application/x-pkcs7-mime; name="smime.p7m"
                    # while we need a
                    #  Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"
                    if v == 'application/x-pkcs7-mime; name="smime.p7m"':
                        v = 'application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"'

                    try:
                        msgcopy.replace_header(k, v)
                    except KeyError:
                        msgcopy.add_header(k, v)

                msgcopy.set_payload(body)

        # For the final delivery stage, we can just bulk deliver to a party of
        # one. ;)
        bulkdeliver(mlist, msgcopy, msgdata, envsender, failures, conn)