Example #1
0
 def OldGetEmailPackageObject(self, strip_mime_headers=True):
     import email
     text = self._GetMessageText()
     try:
         try:
             msg = email.message_from_string(text)
         except email.Errors.BoundaryError:
             try:
                 msg = email.message_from_string(text + "\n\n")
             except email.Errors.BoundaryError:
                 msg = None
         except email.Errors.HeaderParseError:
             msg = None
         if msg is None:
             butcher_pos = text.lower().find("\ncontent-type: ")
             if butcher_pos < 0:
                 raise RuntimeError(
                     "email package croaked with a MIME related error, but "
                     "there appears to be no 'Content-Type' header")
             butchered = text[:butcher_pos] + "\nSpamBayes-" + \
                         text[butcher_pos+1:] + "\n\n"
             msg = email.message_from_string(butchered)
     except:
         print "FAILED to create email.message from: ", `text`
         raise
     if strip_mime_headers:
         if msg.has_key('content-type'):
             del msg['content-type']
         if msg.has_key('content-transfer-encoding'):
             del msg['content-transfer-encoding']
     return msg
def find_existing_object(uid, type, user_rec, lock=False):
    """
        Search user's private folders for the given object (by UID+type)
    """
    global imap

    lock_key = None

    if lock:
        lock_key = get_lock_key(user_rec, uid)
        set_write_lock(lock_key)

    event = None
    for folder in list_user_folders(user_rec, type):
        log.debug(_("Searching folder %r for %s %r") % (folder, type, uid), level=8)
        imap.imap.m.select(imap.folder_utf7(folder))

        typ, data = imap.imap.m.search(None, '(UNDELETED HEADER SUBJECT "%s")' % (uid))
        for num in reversed(data[0].split()):
            typ, data = imap.imap.m.fetch(num, '(RFC822)')

            try:
                if type == 'task':
                    event = todo_from_message(message_from_string(data[0][1]))
                else:
                    event = event_from_message(message_from_string(data[0][1]))

                setattr(event, '_imap_folder', folder)
                setattr(event, '_lock_key', lock_key)
            except Exception, e:
                log.error(_("Failed to parse %s from message %s/%s: %s") % (type, folder, num, traceback.format_exc()))
                continue

            if event and event.uid == uid:
                return event
Example #3
0
def parse_headers(fp, _class=Message):
    """Parses only RFC2822 headers from a file pointer.

    This code is taken directly from the Python 3 stdlib, adapted for
    2to3. Returns a dictionary of unicode strings mapping to unicode
    strings.
    """
    headers = []
    while True:
        line = fp.readline()
        headers.append(line)
        if line in HEADER_NEWLINES:
            break

    hbytes = ''.encode('ascii').join(headers)

    # It turns out that in Python 3, email.Parser requires Unicode.
    # Unfortunately,in Python 2, email.Parser refuses to handle
    # Unicode and returns an empty object. We have to make sure that
    # parse_headers returns Unicode in both Python 2 and Python 3. The
    # easiest way is to throw away the email.message.Message interface
    # and just return a dict instead, which lets us massage the bytes
    # into Unicode.

    # iso-8559-1 encoding taken from http/client.py, where this
    # function was stolen from.
    E = 'iso-8859-1'

    if sys.version_info[0] < 3:
        items = list(email.message_from_string(hbytes).items())
        return dict((k.decode(E), v.decode(E)) for k, v in items)

    hstring = hbytes.decode(E)
    return dict(email.message_from_string(hstring))
Example #4
0
 def getMessage(self, mailID, fullname):        
     typ, header = self.IMAP.fetch(mailID, "(UID BODY.PEEK[HEADER])")
     typ, body = self.IMAP.fetch(mailID, "(UID BODY.PEEK[])")
     for x in range(0, len(header), 2):
         firstPart = header[x][0]
         uidStart = firstPart.find("UID ") + 4
         uidEnd = firstPart.find(" ", uidStart)
         uid = int(firstPart[uidStart:uidEnd])
         if uid > self.lastUIDs[fullname]: self.lastUIDs[fullname] = uid
         print "UID %s in %s" % (uid, fullname)
         #info = data[x][0]
         msgFD = open("%s/%s/%s" % (self.username, fullname, uid), "w")
         mssg = email.message_from_string(body[x][1])
         hdrmsg = email.message_from_string(header[x][1])
         jsonHeader = {};
         for key in hdrmsg.keys():
             jsonHeader[key] = hdrmsg[key]
         message = {"headers":jsonHeader, "body":{"parts":{}}}
         for part in mssg.walk():
             maintype = part.get_content_maintype();
             mtype = part.get_content_type();
             # multipart are just containers, so we skip them
             if maintype == 'multipart':
                 continue
             if maintype == 'text':
                 message["body"]["parts"][mtype] = {"payload":part.get_payload()};
             else: #TODO: handle attachments
                 print mtype
         try:
             json.dump(message, msgFD)
         except:
             message["body"] = {"error":"Message download failed!!!"};
             json.dump(message, msgFD)
Example #5
0
    def test_bounce_message(self):
        eq = self.assertEqual
        unless = self.failUnless
        msg = email.message_from_string("""\
To: [email protected]
From: [email protected]
Subject: and another thing

yadda yadda yadda
""", Message.Message)
        self._mlist.BounceMessage(msg, {})
        qmsg = email.message_from_string(self._readmsg())
        unless(qmsg.is_multipart())
        eq(len(qmsg.get_payload()), 2)
        # The first payload is the details of the bounce action, and the
        # second message is the message/rfc822 attachment of the original
        # message.
        msg1 = qmsg.get_payload(0)
        eq(msg1.get_content_type(), 'text/plain')
        eq(msg1.get_payload(), '[No bounce details are available]')
        msg2 = qmsg.get_payload(1)
        eq(msg2.get_content_type(), 'message/rfc822')
        unless(msg2.is_multipart())
        msg3 = msg2.get_payload(0)
        eq(msg3.get_payload(), 'yadda yadda yadda\n')
Example #6
0
    def testSMTPMailFromHeaderSetup(self):
        msg = message_from_string("""\
From: =?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <*****@*****.**>
To: =?utf-8?q?Ferran_Adri=C3=A0?= <*****@*****.**>
Subject: =?utf-8?q?=C2=BFEsferificaci=C3=B3n=3F?=
Date: Sun, 27 Aug 2006 17:00:00 +0200
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64
MIME-Version: 1.1

wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
""")
        mailhost = self._makeOne('MailHost')
        mailhost.send(msg, mfrom='Foo Bar <*****@*****.**>')
        out = message_from_string(mailhost.sent)

        # We need to check if the 'From' header in message that we passed
        # haven't changed.
        self.failUnlessEqual(out['From'], msg['From'])

        # We need to make sure that proper 'SMTP MAIL FROM' header was send.
        self.failUnlessEqual(mailhost.mfrom, 'Foo Bar <*****@*****.**>')

        # If 'From' header is missing in the message
        # it should be added with 'MAIL FROM' SMTP Envelope header value.
        del msg['From']
        mailhost.send(msg, mfrom='Foo Bar <*****@*****.**>')
        out = message_from_string(mailhost.sent)
        self.failUnlessEqual(out['From'], 'Foo Bar <*****@*****.**>')
Example #7
0
def cb_msg(md, type, tid, params, sbd):
	"Message received callback"

	msncb.cb_msg(md, type, tid, params, sbd)

	email = tid.split(" ")[0]
	if email not in usrs:
		usrs[email] = users.RealUser(md, email, conf)
	else:
		usrs[email].updatemd(md)

	msg = email_lib.message_from_string(params)
	routine = msg.get_payload()

	if re.search("text/plain", msg["Content-Type"]):
		usrs[email].execcmd(routine)
	elif re.search("text/x-msmsgsinvite", msg["Content-Type"]):
		msg = email_lib.message_from_string(routine)

		if msg["Invitation-Command"] == "INVITE" and msg["Application-GUID"] == "{5D3E02AB-6190-11d3-BBBB-00C04F795683}":
			# it's incoming file transfer
			fn = msg["Application-File"]
			ft = users.FileTransfer(md, usrs[email], fn, buildpath((os.getcwd(), "received_files", email, fn)), msg["Application-FileSize"], msg["Invitation-Cookie"], 'receive')
			ft.accept(msg["Connectivity"] == "N")
		elif msg["Invitation-Command"] == "ACCEPT":
			# some file transfer was accepted
			users.FileTransfer.dispatchMsg(msg)
	elif re.search("text/x-msmsgsprofile", msg["Content-Type"]):
		conf.myip = msg["ClientIP"]
Example #8
0
    def test_send_email(self):
        """Test sending mail."""

        self.mailhost.reset()

        portal.send_email(
            recipient="*****@*****.**",
            sender="*****@*****.**",
            subject="Trappist",
            body=u"One for you Bob!",
        )

        self.assertEqual(len(self.mailhost.messages), 1)
        msg = message_from_string(self.mailhost.messages[0])
        self.assertEqual(msg['To'], '*****@*****.**')
        self.assertEqual(msg['From'], '*****@*****.**')
        self.assertEqual(msg['Subject'], '=?utf-8?q?Trappist?=')
        self.assertEqual(msg.get_payload(), u'One for you Bob!')
        self.mailhost.reset()

        # When no sender is set, we take the portal properties.
        portal.send_email(
            recipient="*****@*****.**",
            subject="Trappist",
            body=u"One for you Bob!",
        )

        self.assertEqual(len(self.mailhost.messages), 1)
        msg = message_from_string(self.mailhost.messages[0])
        self.assertEqual(msg['From'], 'Portal Owner <*****@*****.**>')
Example #9
0
    def check(self, label='INBOX', senders=None):
        """
        Arguments:
            label
            senders
        """
        logging.debug('GMAIL: Checking %s for %s' % (label, senders))

        _, count = self.imap.select(label)
        _, stats = self.imap.status(label, "(UNSEEN)")

        unread = int(stats[0].split()[2].strip(').,]'))
        if not unread:
            logging.debug('GMAIL: No new messages.')
            return []

        messages = []
        if not senders:
            senders = ['(UNSEEN)']
        else:
            senders = ['(FROM "%s" UNSEEN)' % s for s in senders]
        for sender in senders:
            _, ids = self.imap.search(None, sender)
            ids = ids[0].split(' ')
            for email_id in ids:
                _, data = self.imap.fetch(email_id, '(UID RFC822)')
                msg = email.message_from_string(data[0][1])
                messages.append(email.message_from_string(data[0][1]))

        logging.debug('GMAIL: Received %d messages.' % len(messages))
        return messages
 def testGetSize(self):
     msg = email.message_from_string(spam1, _class=IMAPMessage)
     correct_msg = email.message_from_string(spam1)
     # Our messages are designed for transmittal, so have
     # \r\n rather than \n as end-of-line.
     self.assertEqual(msg.getSize(),
                      len(correct_msg.as_string().replace('\n', '\r\n')))
Example #11
0
    def test_get_mail_addresses(self):

        to_message_object = email.message_from_string("To: John Doe <*****@*****.**>")
        self.assertEqual([{'email': '*****@*****.**', 'name': u'John Doe'}], get_mail_addresses(to_message_object, 'to'))

        from_message_object = email.message_from_string("From: John Smith <*****@*****.**>")
        self.assertEqual([{'email': '*****@*****.**', 'name': u'John Smith'}], get_mail_addresses(from_message_object, 'from'))
Example #12
0
 def setUp(self):
     # setup some test mails
     self.msg_empty = MIMEText('')
     here = os.path.dirname(__file__)
     msg_txt = open(os.path.join(here, 'mails', 'ascii_7bit.txt'), 'r').read()
     self.msg_ascii = email.message_from_string(msg_txt)
     msg_txt = open(os.path.join(here, 'mails', 'latin1.txt'), 'r').read()
     self.msg_latin1 = email.message_from_string(msg_txt)
     msg_txt = open(os.path.join(here, 'mails', 'utf8.txt'), 'r').read()
     self.msg_utf8 = email.message_from_string(msg_txt)
     msg_txt = open(os.path.join(here, 'mails', 'attachment.txt'), 'r').read()
     self.msg_attachment = email.message_from_string(msg_txt)
     msg_txt = open(os.path.join(here, 'mails', 'fwd_attachment.txt'), 'r').read()
     self.msg_fwd_attachment = email.message_from_string(msg_txt)
     msg_txt = open(os.path.join(here, 'mails', 'nested_attachments.txt'), 'r').read()
     self.msg_nested_attachments = email.message_from_string(msg_txt)
     msg_txt = open(os.path.join(here, 'mails', 'nested_referenced_image_attachment.txt'),
                    'r').read()
     self.nested_referenced_image_attachment = email.message_from_string(msg_txt)
     msg_txt = open(os.path.join(here, 'mails', 'multiple_html_parts.txt'), 'r').read()
     self.msg_multiple_html_parts = email.message_from_string(msg_txt)
     msg_txt = open(os.path.join(here, 'mails', 'from_header_with_quotes.txt'), 'r').read()
     self.from_header_with_quotes = email.message_from_string(msg_txt)
     msg_txt = open(os.path.join(here, 'mails', 'encoded_word_without_lwsp.txt'), 'r').read()
     self.encoded_word_without_lwsp = email.message_from_string(msg_txt)
Example #13
0
 def load(self):
     '''Read the Message substance from the file'''
     if self.loaded:
         return
     assert self.file_name is not None, \
            "Must set filename before using FileMessage instances."
     if options["globals", "verbose"]:
         print('loading', self.file_name)
     pn = self.pathname()
     fp = gzip.open(pn, 'rb')
     try:
         self._msg = email.message_from_string(\
             fp.read(), _class = self.message_class)
     except IOError as e:
         if str(e) == 'Not a gzipped file' or \
            str(e) == 'Unknown compression method':
             fp.close()
             fp = open(self.pathname(), 'rb')
             self._msg = email.message_from_string(\
                 fp.read(), _class = self.message_class)
             fp.close()
         else:
             raise
     else:
         fp.close()
     self.loaded = True
Example #14
0
def parseEmail(data):
    msg = email.message_from_string(data[0][1])
    t = time.strptime(msg['Date'], '%a, %d %b %Y %H:%M:%S +0000')
    msg_date = "%s-%s-%s" % (str(t.tm_year), str(t.tm_mon).zfill(2), str(t.tm_mday).zfill(2))
    msg = email.message_from_string(data[0][1])
    msg_from_name, msg_from_addr = email.utils.parseaddr(msg['From'])
    return msg_from_addr, msg_date
Example #15
0
    def test_top(self):
        """
        `top(which, howmuch)'
             Retrieves the message header plus HOWMUCH lines of the message
             after the header of message number WHICH. Result is in form
             `(RESPONSE, ['line', ...], OCTETS)'.

             The POP3 TOP command this method uses, unlike the RETR command,
             doesn't set the message's seen flag; unfortunately, TOP is poorly
             specified in the RFCs and is frequently broken in off-brand
             servers.  Test this method by hand against the POP3 servers you
             will use before trusting it.
        """
        list = self.o.list()
        id, size = [x for x in [
            (int(x[0]), int(x[1])) for x in [
                x.split(' ') for x in list[1]]] if x[1] > 1000][0]

        result = self.o.top(id, 10)
        self.assertEquals(result[0], '+OK 10 lines of message %d' % id)
        result = self.o.top(id, 0)
        msg = message_from_string('\r\n'.join(result[1]))
        self.assertEquals(msg.get_payload(), "")

        result = self.o.top(id, 2)
        msg = message_from_string('\r\n'.join(result[1]))
        self.assertEquals(len(msg.get_payload().split('\r\n')), 3)
Example #16
0
    def testSendMessageObject(self):
        # send will accept an email.Message.Message object directly
        msg = message_from_string("""\
From: =?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <*****@*****.**>
To: =?utf-8?q?Ferran_Adri=C3=A0?= <*****@*****.**>
Subject: =?utf-8?q?=C2=BFEsferificaci=C3=B3n=3F?=
Date: Sun, 27 Aug 2006 17:00:00 +0200
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: base64
MIME-Version: 1.1

wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
""")
        mailhost = self._makeOne('MailHost')
        mailhost.send(msg)
        out = message_from_string(mailhost.sent)
        self.failUnlessEqual(out.as_string(), msg.as_string())

        # we can even alter a from and subject headers without affecting the
        # original object
        mailhost.send(msg,
                      mfrom='Foo Bar <*****@*****.**>', subject='Changed!')
        out = message_from_string(mailhost.sent)

        # We need to make sure we didn't mutate the message we were passed
        self.failIfEqual(out.as_string(), msg.as_string())
        self.failUnlessEqual(out['From'], 'Foo Bar <*****@*****.**>')
        self.failUnlessEqual(msg['From'],
            '=?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <*****@*****.**>')
        # The subject is encoded with the body encoding since no
        # explicit encoding was specified
        self.failUnlessEqual(out['Subject'], '=?utf-8?q?Changed!?=')
        self.failUnlessEqual(msg['Subject'],
                             '=?utf-8?q?=C2=BFEsferificaci=C3=B3n=3F?=')
Example #17
0
    def test_processReply(self):
        # Make sure an unknown token in an older email is deleted
        msg = email.message_from_string(self.dataFile('good_reply_past'))
        result = (yield self.receiver.processReply(msg))
        self.assertEquals(result, MailReceiver.UNKNOWN_TOKEN_OLD)

        # Make sure an unknown token is not processed
        msg = email.message_from_string(self.dataFile('good_reply_future'))
        result = (yield self.receiver.processReply(msg))
        self.assertEquals(result, MailReceiver.UNKNOWN_TOKEN)

        # Make sure a known token *is* processed
        txn = self.store.newTransaction()
        yield txn.imipCreateToken(
            "urn:x-uid:5A985493-EE2C-4665-94CF-4DFEA3A89500",
            "mailto:[email protected]",
            "1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C",
            token="d7cdf68d-8b73-4df1-ad3b-f08002fb285f"
        )
        yield txn.commit()

        result = (yield self.receiver.processReply(msg))
        self.assertEquals(result, MailReceiver.INJECTION_SUBMITTED)

        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)
Example #18
0
 def test_email(self):
     """Check that the registration email has been recieved and is in good shape."""
     messages = ''
     testPass = False
     time.sleep(10)
     m = imaplib.IMAP4_SSL(settings.EMAIL_IMAP_HOST)
     m.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD)
     sel_rv, data = m.select(settings.EMAIL_IMAP_INBOX)
     try:
         if sel_rv == 'OK':
             search_rv, data = m.search(
                 None, 'FROM', settings.DEFAULT_FROM_EMAIL, 'SUBJECT', '{0}'.format(self.emailHeader))
             if search_rv == 'OK':
                 if len(data[0].split()) > 0:
                     for num in data[0].split():
                         fetch_rv, msgData = m.fetch(num, '(RFC822)')
                         if fetch_rv == 'OK':
                             # This check should do something to make sure
                             # that the email is unique
                             if self.emailCheck(str(email.message_from_string(msgData[0][1]))):
                                 m.store(num, '+FLAGS', '\\DELETED')
                                 m.expunge()
                         else:
                             messages += str(
                                 email.message_from_string(msgData[0][1]))
                 else:
                     raise RuntimeError('Message not found in inbox')
             else:
                 raise RuntimeError('Message Searching failed')
         else:
             raise RuntimeError(
                 'Inbox selection failed. Perhaps a different inbox is needed for settings.EMAIL_IMAP_INBOX in settings.py.')
     finally:
         m.close()
         m.logout()
def visit_listing(p, listing):
    number, size = listing.decode('ascii').split()
    print('Message', number, '(size is', size, 'bytes):')
    print()
    response, lines, octets = p.top(number, 0)
    document = '\n'.join( line.decode('ascii') for line in lines )
    message = email.message_from_string(document)
    for header in 'From', 'To', 'Subject', 'Date':
        if header in message:
            print(header + ':', message[header])
    print()
    print('Read this message [ny]?')
    answer = input()
    if answer.lower().startswith('y'):
        response, lines, octets = p.retr(number)
        document = '\n'.join( line.decode('ascii') for line in lines )
        message = email.message_from_string(document)
        print('-' * 72)
        for part in message.walk():
            if part.get_content_type() == 'text/plain':
                print(part.get_payload())
                print('-' * 72)
    print()
    print('Delete this message [ny]?')
    answer = input()
    if answer.lower().startswith('y'):
        p.dele(number)
        print('Deleted.')
 def deserialize(self, graph, content, mimetype):
     if type(content) == str or type(content) == unicode:
         msg = email.message_from_string("Content-Type:" + mimetype + "\n" + content)
     else:
         msg = email.message_from_string("Content-Type:" + mimetype + "\n" + content.read())
     named_parts = {}
     unnamed_parts = []
     for part in msg.walk():
         if part.is_multipart():
             continue
         filename = part.get_filename(None)
         if filename:
             named_parts[filename] = part
         else:
             unnamed_parts.append(part)
     rdf = [part for part in unnamed_parts if part.get_content_type() in self.serializers]
     if len(rdf) == 0:
         raise Exception("SADI With Attachments requires one unnamed RDF part.")
     print "\n".join([str(x) for x in rdf])
     print "\n".join([str(x) for x in named_parts.values()])
     rdf_content = rdf[0].get_payload()
     print "using this RDF content:"
     print rdf_content
     ser = self.serializers[rdf[0].get_content_type()]
     ser.deserialize(graph, unicode(rdf_content), rdf[0].get_content_type())
     graph.attachments.update(named_parts)
     return frir.RDFGraphDigest
Example #21
0
	def __init__(self, content):
		"""Parses headers, content, attachments from given raw message.

		:param content: Raw message."""
		if six.PY2:
			self.mail = email.message_from_string(safe_encode(content))
		else:
			if isinstance(content, bytes):
				self.mail = email.message_from_bytes(content)
			else:
				self.mail = email.message_from_string(content)

		self.text_content = ''
		self.html_content = ''
		self.attachments = []
		self.cid_map = {}
		self.parse()
		self.set_content_and_type()
		self.set_subject()
		self.set_from()
		self.message_id = (self.mail.get('Message-ID') or "").strip(" <>")

		if self.mail["Date"]:
			try:
				utc = email.utils.mktime_tz(email.utils.parsedate_tz(self.mail["Date"]))
				utc_dt = datetime.datetime.utcfromtimestamp(utc)
				self.date = convert_utc_to_user_timezone(utc_dt).strftime('%Y-%m-%d %H:%M:%S')
			except:
				self.date = now()
		else:
			self.date = now()
		if self.date > now():
			self.date = now()
 def testExecuteMultiRecipients(self):
     dummyMailHost = self._setup_mockmail()
     e = MailAction()
     e.source = '*****@*****.**'
     e.recipients = '[email protected],[email protected]'
     e.message = 'Document created !'
     ex = getMultiAdapter((self.folder, e, DummyEvent(self.folder.d1)),
                          IExecutable)
     ex()
     self.assertEqual(len(dummyMailHost.messages), 2)
     # in py3 the order of mails is non-determininistic
     # because sending iterates over a set of recipients
     for msg in dummyMailHost.messages:
         if '*****@*****.**' in msg:
             mailSent1 = message_from_string(msg)
         else:
             mailSent2 = message_from_string(msg)
     self.assertEqual('text/plain; charset="utf-8"',
                      mailSent1.get('Content-Type'))
     self.assertEqual('*****@*****.**', mailSent1.get('To'))
     self.assertEqual('*****@*****.**', mailSent1.get('From'))
     self.assertEqual('Document created !',
                      mailSent1.get_payload())
     self.assertEqual('text/plain; charset="utf-8"',
                      mailSent2.get('Content-Type'))
     self.assertEqual('*****@*****.**', mailSent2.get('To'))
     self.assertEqual('*****@*****.**', mailSent2.get('From'))
     self.assertEqual('Document created !',
                      mailSent2.get_payload())
     self._teardown_mockmail()
    def _retrieve_mails(self, callback, get_msgs_type='(UNSEEN)', delete=False):
        """
        Calls a callback function for new (unseen) mails from account

        :param callback: Callback function for processing incoming emails
        :param get_msgs_type: Expression for emails to get '(UNSEEN)' by default to get new emails
        :param delete: Delete obtained emails in account (default False)
        """

        # get all unread messages
        status, response = self.connection.search(None, get_msgs_type)
        unread_msg_nums = response[0].split()
        mails = []
        for e_id in unread_msg_nums:
            _, response = self.connection.fetch(e_id, '(RFC822)')
            if sys.version_info >= (3, 0):
                email_message = email.message_from_string(response[0][1].decode('utf-8'))
            else:
                email_message = email.message_from_string(response[0][1])

            mails.append(email_message)
        # Post Process
        for e_id in unread_msg_nums:
            self.connection.store(e_id, '+FLAGS', '\Seen')
            if delete:
                self.connection.store(e_id, '+FLAGS', '\\Deleted')
        if delete:
            self.connection.expunge()

        callback(mails)
Example #24
0
     def test_filter_train(self):

        self.h.open('c')

        self.h.h.bayes.learn(tokenize(good1), False)

        self.h.h.bayes.learn(tokenize(spam1), True)

        self.h.h.store()

        result = email.message_from_string(self.h.filter_train(spam1))

        self.assert_(result[options["Headers",
                                    "classification_header_name"]].\
                     startswith(options["Headers", "header_spam_string"]))

        self.assertEqual(self.h.h.bayes.nspam, 2)

        result = email.message_from_string(self.h.filter_train(good1))

        self.assert_(result[options["Headers",
                                    "classification_header_name"]].\
                     startswith(options["Headers", "header_ham_string"]))

        self.assertEqual(self.h.h.bayes.nham, 2)
Example #25
0
    def lostphotosfound(self):
        """The actual program, which fetchs the mails and all its parts attachments"""

        messages = self._filter_messages()

        for msg in messages:
            try:
                idfetched = self._server.fetch([msg], ['X-GM-MSGID'])
            except:
                raise Exception('Could not fetch the message ID, server did not respond')

            msgid = str(idfetched[idfetched.keys()[0]]['X-GM-MSGID'])

            # mail has been processed in the past, skip it
            if self._use_index and msgid in self._index.keys():
                print 'Skipping X-GM-MSDID %s' % (msgid)
                continue

            # if it hasn't, fetch it and iterate through its parts
            msgdata = self._server.fetch([msg], ['RFC822'])

            for data in msgdata:
                try:
                    mail = message_from_string(msgdata[data]['RFC822'].encode('utf-8'))
                except UnicodeDecodeError:
                    print("Warning: can't encode message data to UTF-8")
                    mail = message_from_string(msgdata[data]['RFC822'])

                if mail.get_content_maintype() != 'multipart':
                    continue

                # logging
                header_from = _charset_decoder(mail['From'])
                header_subject = _charset_decoder(mail['Subject'])
                print '[%s]: %s' % (header_from, header_subject)

		# use raw header, header_from sometimes excludes the email address
		sender = email.utils.parseaddr(mail['From'])[1]
		if not sender:
			sender = 'unknown_sender'

                for part in mail.walk():
                    # if it's only plain text, i.e. no images
                    if part.get_content_maintype() == 'multipart':
                        continue
                    # if no explicit attachments unless they're inline
                    if part.get('Content-Disposition') is None:
                        pass
                    # if non-graphic inline data
                    if 'image/' not in part.get_content_type():
                        continue

                    # only then we can save this mail part
                    self._save_part(part, mail, sender)

                # all parts of mail processed, add it to the index
                self._index[msgid] = msgid

        self._cleanup()
 def testGetBodyFile(self):
     msg = email.message_from_string(spam1, _class=IMAPMessage)
     correct_msg = email.message_from_string(spam1)
     body = msg.getBodyFile()
     # Our messages are designed for transmittal, so have
     # \r\n rather than \n as end-of-line.
     self.assertEqual(body.read().replace('\r\n', '\n'),
                      correct_msg.get_payload())
Example #27
0
 def testGetSize(self):

        msg = email.message_from_string(spam1, _class=IMAPMessage)

        correct_msg = email.message_from_string(spam1)

        self.assertEqual(msg.getSize(),
                         len(correct_msg.as_string().replace('\n', '\r\n')))
Example #28
0
    def test_missing_date(self):
        msg = message_from_string('SUBject: nothing')
        info = models.get_email_info(msg)
        self.assertNotIn('date', info)

        msg = message_from_string('Whatever: Sat, 11 Jan 2014 00:41:13 +08000 (CST)')
        info = models.get_email_info(msg)
        self.assertNotIn('date', info)
Example #29
0
def message_from_string(string):
    if six.PY3:
        if isinstance(string, six.binary_type):
            return email.message_from_bytes(string, policy=_compat32_crlf)

        return email.message_from_string(string, policy=_compat32_crlf)

    return email.message_from_string(string)
 def get_body_html(self, body_data):
     try:
         parsed_body = email.message_from_string(body_data).get_payload(1)
         return parsed_body
     except TypeError:
         parsed_body = email.message_from_string(body_data).get_payload()
         return parsed_body
     except:
         print "No Body exists"
Example #31
0
    def examine(self, suspect):
        # check if someone wants to skip sa checks
        if suspect.get_tag('SAPlugin.skip') is True:
            self.logger.debug(
                '%s Skipping SA Plugin (requested by previous plugin)' %
                suspect.id)
            suspect.set_tag('SAPlugin.skipreason',
                            'requested by previous plugin')
            return DUNNO

        runtimeconfig = DBConfig(self.config, suspect)

        spamsize = suspect.size
        maxsize = self.config.getint(self.section, 'maxsize')
        spamheadername = self.config.get(self.section, 'spamheader')

        if spamsize > maxsize:
            self.logger.info('%s Size Skip, %s > %s' %
                             (suspect.id, spamsize, maxsize))
            suspect.debug('Too big for spamchecks. %s > %s' %
                          (spamsize, maxsize))
            prependheader = self.config.get('main', 'prependaddedheaders')
            suspect.addheader(
                "%sSA-SKIP" % prependheader,
                'Too big for spamchecks. %s > %s' % (spamsize, maxsize))
            suspect.set_tag('SAPlugin.skipreason', 'size skip')
            return self.check_sql_blacklist(suspect)

        forwardoriginal = self.config.getboolean(self.section,
                                                 'forwardoriginal')

        if self.config.getboolean(self.section, 'scanoriginal'):
            spam = suspect.get_original_source()
        else:
            spam = suspect.get_source()

        # prepend temporary headers set by other plugins
        tempheader = suspect.get_tag('SAPlugin.tempheader')
        if tempheader is not None:
            if type(tempheader) == list:
                tempheader = "\r\n".join(tempheader)
            tempheader = tempheader.strip()
            if tempheader != '':
                spam = tempheader + '\r\n' + spam

        if forwardoriginal:
            ret = self.safilter_report(spam, suspect.to_address)
            if ret is None:
                suspect.debug('SA report Scan failed - please check error log')
                self.logger.error('%s SA report scan FAILED' % suspect.id)
                suspect.addheader(
                    '%sSA-SKIP' %
                    self.config.get('main', 'prependaddedheaders'),
                    'SA scan failed')
                suspect.set_tag('SAPlugin.skipreason', 'scan failed')
                return self._problemcode()
            isspam, spamscore, report = ret
            suspect.tags['SAPlugin.report'] = report

        else:
            filtered = self.safilter(spam, suspect.to_address)
            if filtered is None:
                suspect.debug('SA Scan failed - please check error log')
                self.logger.error('%s SA scan FAILED' % suspect.id)
                suspect.addheader(
                    '%sSA-SKIP' %
                    self.config.get('main', 'prependaddedheaders'),
                    'SA scan failed')
                suspect.set_tag('SAPlugin.skipreason', 'scan failed')
                return self._problemcode()
            else:
                content = filtered

            newmsgrep = email.message_from_string(content)
            suspect.set_source(content)
            isspam, spamscore = self._extract_spamstatus(
                newmsgrep, spamheadername, suspect)

        action = DUNNO
        message = None

        if isspam:
            self.logger.debug('%s Message is spam' % suspect.id)
            suspect.debug('Message is spam')

            configaction = string_to_actioncode(
                runtimeconfig.get(self.section, 'lowspamaction'), self.config)
            if configaction is not None:
                action = configaction
            values = dict(spamscore=spamscore)
            message = apply_template(
                self.config.get(self.section, 'rejectmessage'), suspect,
                values)
        else:
            self.logger.debug('%s Message is not spam' % suspect.id)
            suspect.debug('Message is not spam')

        suspect.tags['spam']['SpamAssassin'] = isspam
        suspect.tags['highspam']['SpamAssassin'] = False
        if spamscore is not None:
            suspect.tags['SAPlugin.spamscore'] = spamscore
            highspamlevel = runtimeconfig.getfloat(self.section,
                                                   'highspamlevel')
            if spamscore >= highspamlevel:
                suspect.tags['highspam']['SpamAssassin'] = True
                configaction = string_to_actioncode(
                    runtimeconfig.get(self.section, 'highspamaction'),
                    self.config)
                if configaction is not None:
                    action = configaction
        return action, message
Example #32
0
 def parse_headers(self, data):
     if "\r\n" not in data:
         return {}
     raw_headers = data.split("\r\n", 1)[1]
     headers = email.message_from_string(raw_headers)
     return dict((k.lower(), v) for k, v in six.iteritems(dict(headers)))
Example #33
0
def main():

    while (True):
        print datetime.datetime.now().time()
        detach = "."
        if 'attachments' not in os.listdir("."):
            print "Could not find attachments folder, so i made it."
            os.mkdir('attachments')

        try:
            imapSession = imaplib.IMAP4_SSL('imap.gmail.com')
            typ, account = imapSession.login('username', 'password')
            imapSession.list()
            if typ != "OK":
                print "Error: Could not sign in, check creds"
            else:
                print "Logged in, checking labelname Emails"
                imapSession.select("label to check")

                (typ, data) = imapSession.search(None, '(UNSEEN)')
                if (data[0] == ""):
                    print "No new mail"
                else:
                    print "There is new mail"

                    for msgs in str(data[0]).split():
                        typ, msgInfo = imapSession.fetch(msgs, '(RFC822)')
                        if typ != "OK":
                            print "error fetching mail"
                        else:
                            msgBody = msgInfo[0][1]
                            mail = email.message_from_string(msgBody)
                            for part in mail.walk():
                                fileName = part.get_filename()

                                if bool(fileName):
                                    filePath = os.path.join(
                                        detach, 'attachments', fileName)
                                    print "Downloading", fileName
                                    if not os.path.isfile(filePath):
                                        print fileName, "from", str(
                                            mail['From'])
                                        fp = open(filePath, 'wb')
                                        fp.write(part.get_payload(decode=True))
                                        fp.close()
                                    print "Downloaded", fileName
                                    print "Now printing", filePath
                                    os.startfile(filePath, "print")
                                    time.sleep(15)
                                    os.system(
                                        'cmd.exe /c taskkill /f /im AcroRd32.exe'
                                    )
                                    print "Deleting file"
                                    os.remove(filePath)
            imapSession.close()
            print "checking again..."
            time.sleep(60)

    #imapSession.logout()

        except:
            print sys.exc_info()[0:]
            break
def ProcessEmail():
    import imaplib
    import email
    import urllib.request
    from os import getcwd
    from os.path import join
    from bs4 import BeautifulSoup as bs
    import io
    import os
    #import credentials

    mail = imaplib.IMAP4_SSL('imap.gmail.com')
    # imaplib module implements connection based on IMAPv4 protocol
    senderEmail = os.environ['SenderEmail']
    senderPassword = os.environ['SenderPassword']
    receiverEmail = os.environ['ReceiverEmail']
    fromMail = os.environ['FromMail']
    mail.login(senderEmail, senderPassword)

    # In[19]:

    mail.list()  # Lists all labels in GMail
    mail.select('inbox')  # Connected to inbox.

    # In[20]:

    result, data = mail.uid('search',
                            "From " + fromMail + ' Subject "Fly Morning News"',
                            "ALL")
    i = len(data[0].split())
    latest_email_uid = data[0].split()[i - 1]
    result, email_data = mail.uid('fetch', latest_email_uid, '(RFC822)')
    raw_email = email_data[0][1]
    raw_email_string = raw_email.decode('utf-8')
    email_message = email.message_from_string(raw_email_string)
    for part in email_message.walk():
        if part.get_content_type() == "text/html":  # ignore attachments/html
            body = part.get_payload(decode=True)
            text = body.decode("utf-8")
    soup = bs(text, 'html.parser')

    # In[21]:

    import pandas as pd
    l = []
    for tick in soup.select('a[href*="/news.php?symbol"]'):
        titles = tick.parent.parent.parent.select(
            'a[href^="https://thefly.com/permalinks/entry.php"] span')
        if (tick.text.find(",") == -1 and len(titles) > 0):
            dict1 = {}
            dict1["Tick"] = tick.text
            dict1["News"] = titles[0].text
            l.append(dict1)
    flydf = pd.DataFrame(l)
    flydf

    # In[22]:

    group_ticker = flydf.groupby("Tick").count()
    group_ticker = group_ticker.reset_index()
    group_ticker.head()

    # In[23]:

    sort_ticker = group_ticker.sort_values("News", ascending=False)
    sort_ticker.head()

    # In[24]:

    merged_df = pd.merge(flydf, sort_ticker, on=["Tick"])
    merged_df.head()

    # In[25]:

    final_tickerdf = merged_df.rename(columns={
        "News_x": "TickerNews",
        "News_y": "Count"
    })
    final_tickerdf
    final_tickerdf = final_tickerdf.sort_values(["Count", "Tick"],
                                                ascending=False)
    final_tickerdf.head()
    final_tickerdf.to_csv("today_flymorningnews.csv", index=False)

    # In[26]:

    final_tickerdf.head()

    # In[27]:

    targetraised_df = final_tickerdf[final_tickerdf["TickerNews"].str.contains(
        "target raised")]
    targetraised_df
    targetraised_df.to_csv("tagetraised.csv", index=False)
    targetlowered_df = final_tickerdf[
        final_tickerdf["TickerNews"].str.contains("target lowered")]
    targetlowered_df.to_csv("tagetlowered.csv", index=False)
    targetupgraded_df = final_tickerdf[
        final_tickerdf["TickerNews"].str.contains("upgraded")]
    targetupgraded_df.to_csv("tagetupgraded.csv", index=False)
    targetdowngraded_df = final_tickerdf[
        final_tickerdf["TickerNews"].str.contains("downgraded")]
    targetdowngraded_df.to_csv("tagetdowngraded.csv", index=False)

    # In[28]:

    targetupgraded_df.head()

    # In[29]:

    b = final_tickerdf[final_tickerdf["Count"] >= 3]
    final_ticker_more_3_df = b.sort_values(["Count", "Tick"], ascending=False)
    final_ticker_more_3_df.head()
    final_ticker_more_3_df.to_csv("3_or_more_ticks.csv", index=False)

    # In[30]:

    final_ticker_more_3_df.head()

    # In[31]:

    c = final_ticker_more_3_df["Tick"].unique()
    ticksdf = pd.DataFrame(c)
    ticksdf
    # ticksdf.to_csv("allticks.csv",index=False)

    # In[32]:

    targetraised_df_ticker = final_ticker_more_3_df[
        final_ticker_more_3_df["TickerNews"].str.contains("target raised")]
    targetraised_df_ticker_3more = targetraised_df_ticker[
        targetraised_df_ticker["Count"] >= 3]
    targetraised_df_ticker_3more
    a = targetraised_df_ticker_3more["Tick"].unique()

    df4 = pd.DataFrame(a)
    df4.to_csv("tagetraised_3ormore.txt", index=False)
    # a.to_csv("tagetraised_3ormore.txt",index=False)
    df4

    # In[33]:

    targetraised_df_ticker = final_tickerdf[
        final_tickerdf["TickerNews"].str.contains("upgraded")]
    targetraised_df_ticker_3more = targetraised_df_ticker[
        targetraised_df_ticker["Count"] >= 3]
    c = targetraised_df_ticker_3more["Tick"].unique()
    df5 = pd.DataFrame(c)
    df5.to_csv("tagetupgraded_3ormore.txt", index=False)

    # In[34]:

    df5

    # In[ ]:

    import smtplib
    from email.message import EmailMessage
    import csv
    import os

    # In[ ]:

    contacts = [receiverEmail]
    msg = EmailMessage()
    msg['Subject'] = "Fly Morning News"
    msg['From'] = senderEmail
    msg['To'] = ','.join(contacts)
    msg.set_content(
        "Please find the files attached. Review and get back to me if any questions. -Naga"
    )
    files = [
        "tagetraised_3ormore.txt", "tagetupgraded_3ormore.txt",
        "today_flymorningnews.csv"
    ]
    for file in files:
        with open(file, "rb") as f:
            filedata = f.read()
            filename = f.name
        msg.add_attachment(filedata,
                           maintype="text/csv",
                           subtype="octet-stream",
                           filename=filename)
    with smtplib.SMTP_SSL("smtp.gmail.com", 465) as smtp:
        smtp.login(senderEmail, senderPassword)
        smtp.send_message(msg)
Example #35
0
 def __init__(self, email_text):
     self.email = message_from_string(email_text)
     self.reply_text = EmailReplyParser.read(self.email.get_payload()).reply
Example #36
0
# oldest = inbox_item_list[0]
# result2, email_data = mail.uid('fetch', oldest, 'RFC822')
# raw_email = email_data[0][1].decode('utf-8')
# email_message = email.message_from_string(raw_email)
# print(dir(email_message))
# print('')
# print(email_message['To'])
# payload = email_message.get_payload()
# print(payload)

# ~ WAY TO FIND ALL ELEMENTS ~
print("")
for element in inbox_item_list:
    result2, email_data = mail.uid('fetch', element, '(RFC822)')
    raw_email = email_data[0][1].decode('utf-8')
    email_message = email.message_from_string(raw_email)
    to_ = email_message['To']
    from_ = email_message['From']
    subject_ = email_message['Subject']
    date_ = email_message['date']
    counter = 1
    for part in email_message.walk():
        if part.get_content_maintype() == "multipart":
            continue
        filename = part.get_filename()
        content_type = part.get_content_type()
        if not filename:
            ext = mimetypes.guess_extension(content_type)
            if not ext:
                ext = '.bin'
            if 'text' in content_type:
swith = ['BEAMS', 'CABLES']

try:
    os.mkdir(detach_dir)
except FileExistsError:
    pass

#CURRENTLY IT DOWNLOADS ALL FILES STARTING WITH THE KEYWORD
#I CAN CHANGE IT TO DOWNLOAD ATTACHMENTS TILL A SPECIFIED DATE TOO

count = 1
for emailid in reversed(items):
    if count < 3:
        typ, data = m.fetch(emailid, "(RFC822)")
        email_body = data[0][1].decode('utf-8')
        mail = email.message_from_string(email_body)
        print(emailid)
        print("[" + mail["From"] + "] :" + mail["Subject"])

        for part in mail.walk():
            if part.get_content_maintype() == 'multipart':
                #print("maintype is multipart")
                continue
            if part.get('Content-Disposition') is None:
                #print("content disposition is None")
                continue

            filename = part.get_filename()
            #print('x ',filename)

            if not filename:
Example #38
0
 def _get_email_object(self, name):
     copy = self._get_email_as_text(name)
     if six.PY3:
         return email.message_from_bytes(copy)
     else:
         return email.message_from_string(copy)
Example #39
0
def fetch_email_body(num):
    global email
    text_list = []

    #https://docs.python.org/2/library/email.message.html
    # non multipart .get_payload return string multipart,  get_payload return list of message

    rv, data = M.fetch(num, '(RFC822)')
    #rv, data = M.uid('fetch', num, '(RFC822)')

    if rv != 'OK':
        print "ERROR getting message body", num
        return (False, [])

    raw_email = data[0][1]
    if not raw_email:  # ceinture et bretelles
        return []
    #raw_email_string = raw_email.decode('utf-8')    will decode payload as utf-8 anyway
    msg = email.message_from_string(raw_email)

    for part in msg.walk():  # recursive

        print "==========  getting parts for message: ", num
        content_type = part.get_content_type()

        main_type = part.get_content_maintype()
        print "main type: %s , content_type: %s, is_multipart: %r" % (
            main_type, content_type, part.is_multipart())
        # ismultipart can be true for non "multipart" main type
        charset = part.get_content_charset()
        if charset is None:
            print "unknown charset"
        else:
            print "charset: ", charset

#Optional decode is a flag indicating whether the payload should be decoded or not, according to the
#Content-Transfer-Encoding header. When True and the message is not a multipart, the payload will be decoded
#if this header value is quoted-printable or base64. If some other encoding is used,
#or Content-Transfer-Encoding header is missing, or if the payload has bogus base64 data, the payload
#is returned as-is (undecoded). If the message is a multipart and the decode flag is True, then None is returned.
#The default for decode is False.

#https://stackoverflow.com/questions/43824650/encoding-issue-decode-quoted-printable-string-in-python
# quotable printable string: unicode coded as ascii eg =AC=E9  .

        if content_type == 'text/plain':
            print "=======>>>> got a text plain payload "
            # return Return the current payload, which will be a list of messages or a string is_multipart
            payload = part.get_payload(
                decode=True
            )  # string or list of messages. true toi decode quotable printable string. otherwize shouw up in  text
            print chardet.detect(payload)
            if isinstance(payload, str):
                print "payload str"
            else:
                print "payload not str"
            # print type(payload) ERROR TypeError: 'str' object is not callable

# let ^^  0xe2 80 90  U+2019 rigth single quote

            if payload.find(' ') == -1:  # check if base 64
                print("base64 ignored")
                text_list.append(u"ignored binary")  # space otherwise says dot
            else:
                try:
                    text = payload.decode('utf-8')
                    print "text decoded as utf "
                except Exception as e:
                    print "Exception decoding payload as uft8: ", str(e)
                #soup= BeautifulSoup(payload)
                #text = soup.get_text()
                #html = markdown(payload)
                #html = payload # to not use markdown. also normally not needed. this is not html
                #soup = BeautifulSoup(html,"html.parser")
                #text = ''.join(soup.findAll(text=True))
                text_list.append(text)
        else:
            type = re.sub(r'/', " ", content_type)
            text_list.append(u"ignored %s" % (type.split(' ')[1]))
    return (True, text_list)  # list of text/ascii payloads.
Example #40
0
    def parse_message(self, message, save_original=False):
        """Parses a string or email.message.Message representing an
           RFC-2822 email, and returns a generic dict holding the
           message details.

           :param message: the message to parse
           :type message: email.message.Message | string | unicode
           :param bool save_original: whether the returned dict
               should include an ``original`` entry with the base64
               encoded source of the message.
           :rtype: dict
           :return: A dict with the following structure, where each
                    field may not be present if missing in original
                    message::

                    { 'message-id': msg_id,
                      'subject': subject,
                      'from': from,
                      'to': to,
                      'cc': cc,
                      'headers' : { 'X-Mailer': mailer,
                                    #.. all X- headers...
                                  },
                      'subtype': msg_mime_subtype,
                      'body_text': plaintext_body
                      'body_html': html_body,
                      'attachments': [('file1', 'bytes'),
                                       ('file2', 'bytes') }
                       # ...
                       'original': source_of_email,
                    }
        """
        msg_txt = message
        if isinstance(message, str):
            msg_txt = email.message_from_string(message)

        # Warning: message_from_string doesn't always work correctly on unicode,
        # we must use utf-8 strings here :-(
        if isinstance(message, unicode):
            message = message.encode('utf-8')
            msg_txt = email.message_from_string(message)

        message_id = msg_txt.get('message-id', False)
        msg = {}

        if save_original:
            # save original, we need to be able to read the original email sometimes
            msg['original'] = message.as_string() if isinstance(message, Message) \
                                                  else message
            msg['original'] = base64.b64encode(
                msg['original'])  # binary fields are b64

        if not message_id:
            # Very unusual situation, be we should be fault-tolerant here
            message_id = time.time()
            msg_txt['message-id'] = message_id
            _logger.info(
                'Parsing Message without message-id, generating a random one: %s',
                message_id)

        fields = msg_txt.keys()
        msg['id'] = message_id
        msg['message-id'] = message_id

        if 'Subject' in fields:
            msg['subject'] = decode(msg_txt.get('Subject'))

        if 'Content-Type' in fields:
            msg['content-type'] = msg_txt.get('Content-Type')

        if 'From' in fields:
            msg['from'] = decode(msg_txt.get('From') or msg_txt.get_unixfrom())

        if 'To' in fields:
            msg['to'] = decode(msg_txt.get('To'))

        if 'Delivered-To' in fields:
            msg['to'] = decode(msg_txt.get('Delivered-To'))

        if 'CC' in fields:
            msg['cc'] = decode(msg_txt.get('CC'))

        if 'Cc' in fields:
            msg['cc'] = decode(msg_txt.get('Cc'))

        if 'Reply-To' in fields:
            msg['reply'] = decode(msg_txt.get('Reply-To'))

        if 'Date' in fields:
            try:
                date_hdr = decode(msg_txt.get('Date'))
                parsed_date = dateutil.parser.parse(date_hdr, fuzzy=True)
                if parsed_date.utcoffset() is None:
                    # naive datetime, so we arbitrarily decide to make it
                    # UTC, there's no better choice. Should not happen,
                    # as RFC2822 requires timezone offset in Date headers.
                    stored_date = parsed_date.replace(tzinfo=pytz.utc)
                else:
                    stored_date = parsed_date.astimezone(pytz.utc)
            except Exception:
                _logger.warning(
                    'Failed to parse Date header %r in incoming mail '
                    'with message-id %r, assuming current date/time.',
                    msg_txt.get('Date'), message_id)
                stored_date = datetime.datetime.now()

            msg['date'] = stored_date.strftime("%Y-%m-%d %H:%M:%S")

        if 'Content-Transfer-Encoding' in fields:
            msg['encoding'] = msg_txt.get('Content-Transfer-Encoding')

        if 'References' in fields:
            msg['references'] = msg_txt.get('References')

        if 'In-Reply-To' in fields:
            msg['in-reply-to'] = msg_txt.get('In-Reply-To')

        msg['headers'] = {}
        msg['subtype'] = 'plain'
        for item in msg_txt.items():
            if item[0].startswith('X-'):
                msg['headers'].update({item[0]: item[1]})
        if not msg_txt.is_multipart() or 'text/plain' in msg.get(
                'content-type', ''):
            encoding = msg_txt.get_content_charset()
            body = tools.ustr(msg_txt.get_payload(decode=True),
                              encoding,
                              errors='replace')
            if 'text/html' in msg.get('content-type', ''):
                msg['body_html'] = body
                msg['subtype'] = 'html'
                body = tools.html2plaintext(body)
            msg['body_text'] = tools.ustr(body, encoding, errors='replace')

        attachments = []
        if msg_txt.is_multipart() or 'multipart/alternative' in msg.get(
                'content-type', ''):
            body = ""
            if 'multipart/alternative' in msg.get('content-type', ''):
                msg['subtype'] = 'alternative'
            else:
                msg['subtype'] = 'mixed'
            for part in msg_txt.walk():
                if part.get_content_maintype() == 'multipart':
                    continue

                encoding = part.get_content_charset()
                filename = part.get_filename()
                if part.get_content_maintype() == 'text':
                    content = part.get_payload(decode=True)
                    if filename:
                        attachments.append((filename, content))
                    content = tools.ustr(content, encoding, errors='replace')
                    if part.get_content_subtype() == 'html':
                        msg['body_html'] = content
                        msg['subtype'] = 'html'  # html version prevails
                        body = tools.ustr(tools.html2plaintext(content))
                        body = body.replace('&#13;', '')
                    elif part.get_content_subtype() == 'plain':
                        body = content
                elif part.get_content_maintype() in ('application', 'image'):
                    if filename:
                        attachments.append(
                            (filename, part.get_payload(decode=True)))
                    else:
                        res = part.get_payload(decode=True)
                        body += tools.ustr(res, encoding, errors='replace')

            msg['body_text'] = body
        msg['attachments'] = attachments

        # for backwards compatibility:
        msg['body'] = msg['body_text']
        msg['sub_type'] = msg['subtype'] or 'plain'
        return msg
Example #41
0
    def post(self, user, data):
        try:
            # msg分解
            msg = email.message_from_string(data)

            # Subject取得
            try:
                # content-type指定でdecode
                (subject_str,
                 subject_type) = email.Header.decode_header(msg['Subject'])[0]
                subject = subject_str.decode(subject_type)
            except BaseException:
                # 存在しない場合はそのまま使用
                subject = msg['Subject']

            from ctirs.models import Feed
            # Feed作成
            feed = Feed()
            # Title は Subject
            feed.title = subject
            # TLP は UserのデフォルトTLP
            feed.tlp = user.tlp
            # Use
            feed.user = user

            # 本文/Attachement取得
            attachements = []
            payloads = msg.get_payload()
            # 添付がある場合は list, ない場合はstr
            if isinstance(payloads, str):
                content_type = self.get_char_set_from_content_type(
                    msg['Content-Type'])
                content_type = content_type.split(':')[0]
                if content_type is not None:
                    body = payloads.decode(content_type)
                else:
                    body = payloads
            elif isinstance(payloads, list):
                # bodyは payloads[0]
                body_payload = payloads[0]
                body = self.get_unicode_content(body_payload)
                # それ以降はattachement
                for index in range(1, len(payloads)):
                    payload = payloads[index]
                    attachements.append(payload)

            # Sharing Rangeはall
            feed.sharing_range_type = SHARING_RANGE_TYPE_KEY_ALL
            # 一旦Feedを保存しSTIXを作成する
            feed.save()

            # 添付ファイル処理
            from feeds.views import save_post, save_attach_file
            for payload in attachements:
                file_name = self.get_file_name(payload)
                content = self.get_content(payload)
                # content を file stream にする
                import io
                o = io.BytesIO(content)
                attach_file = save_attach_file(file_name, o, feed.id)
                feed.files.add(attach_file)
            feed.save()

            # POSTする
            save_post(None, feed, body)

        except BaseException:
            import traceback
            traceback.print_exc()
        return
Example #42
0
def parse_message():
    return email.message_from_string(sys.stdin.read())
Example #43
0
def handling_incoming_email(context):
    mailbox = Mailbox.objects.create(
        name='Temporary Mailbox'
    )
    email_message = email.message_from_string(context.text)
    mailbox.process_incoming_message(email_message)
Example #44
0
def discussion_notify(comment_on_object, variables={}):
    portal = comment_on_object.portal_url.getPortalObject()

    send_from_address = portal.portal_properties.email_from_address
    send_from_name = portal.portal_properties.email_from_name
    host = portal.plone_utils.getMailHost()
    encoding = portal.plone_utils.getSiteEncoding()
    envelope_from = send_from_address

    mt = portal.portal_membership
    if IDiscussionResponse.providedBy(comment_on_object):
        owner = comment_on_object.Creator()
        if owner:
            member = mt.getMemberById(owner)
            if member:
                send_to_address = member.getProperty('email')

                if send_to_address:
                    message_body = portal.discussion_reply_notify_template(
                        portal,
                        comment_on_object=comment_on_object,
                        send_from_address=send_from_address,
                        send_from_name=send_from_name,
                        send_to_address=send_to_address,
                        **variables)
                    subject = "New comment on " + comment_on_object.title_or_id(
                    )
                    message = message_from_string(
                        message_body.encode(encoding))
                    message.set_charset(encoding)
                    message['From'] = Header(envelope_from)

                    if PLONE4:
                        host.send(message,
                                  send_to_address,
                                  envelope_from,
                                  subject=subject,
                                  charset=encoding,
                                  msg_type='text/plain')
                    else:
                        host.secureSend(message_body,
                                        send_to_address,
                                        envelope_from,
                                        subject=subject,
                                        subtype='plain',
                                        charset=encoding,
                                        debug=False,
                                        From=envelope_from)

        parents = comment_on_object.parentsInThread()
        if not parents:
            return
        comment_on_object = parents[0]

    owner = comment_on_object.Creator()
    if owner:
        member = mt.getMemberById(owner)
        if member:
            send_to_address = member.getProperty('email')

            if send_to_address:

                message_body = portal.discussion_notify_template(
                    portal,
                    comment_on_object=comment_on_object,
                    send_from_address=send_from_address,
                    send_from_name=send_from_name,
                    send_to_address=send_to_address,
                    **variables)
                subject = "New comment on " + comment_on_object.title_or_id()

                message = message_from_string(message_body.encode(encoding))
                message.set_charset(encoding)
                message['From'] = Header(envelope_from)

                if PLONE4:
                    host.send(message,
                              send_to_address,
                              envelope_from,
                              subject=subject,
                              charset=encoding,
                              msg_type='text/plain')
                else:
                    host.secureSend(message_body,
                                    send_to_address,
                                    envelope_from,
                                    subject=subject,
                                    subtype='plain',
                                    charset=encoding,
                                    debug=False,
                                    From=envelope_from)
Example #45
0
def view_html_message():
    with open('/Users/rpetrello/.mail/temporary/cur-message', 'rb') as data:
        msgid = data.read()

    subprocess.check_call(['notmuch', 'new'])
    fnames = subprocess.check_output(
        ['notmuch', 'search', '--output=files', '%s' % msgid]
    )
    msg = None
    for line in fnames.splitlines():
        try:
            with open(line, 'rb') as data:
                msg = email.message_from_string(data.read())
                if msg:
                    break
        except IOError:
            continue

    html_parts = []
    subfiles = []
    for part in msg.walk():
        if part.is_multipart() or part.get_content_type() == 'message/rfc822':
            continue

        if part.get_content_subtype() == 'html':
            html_parts.append(part)

        # Save it to a file in the temp dir.
        mime = part.get_content_type()

        for k in part.keys():
            if k.lower() == 'content-id':
                content_id = part[k]
                if content_id.startswith('<') and content_id.endswith('>'):
                    content_id = content_id[1:-1]

                subfiles.append(
                    (content_id, mime, part.get_payload(decode=True))
                )
                break

    buff = StringIO()
    for part in html_parts:
        payload = part.get_payload(decode=True)

        # Substitute all the filenames for CIDs:
        for content_id, mime, attachment in subfiles:
            payload = payload.replace(
                'cid:%s' % content_id,
                'data:%s;base64,%s' % (mime, base64.b64encode(attachment))
            )
        buff.write(payload)

    with tempfile.NamedTemporaryFile(suffix='.html') as f:
        filename = f.name

    with codecs.open(filename, 'w', encoding='utf-8') as f:
        f.write('<html><head><meta charset="utf-8"/></head><body>')
        f.write(buff.getvalue().decode('utf8', 'ignore'))
        f.write('</body></html>')
        f.flush()
        subprocess.check_call(['open', '-a', '/Applications/Firefox.app/', f.name])
        time.sleep(3)
    def mailPassword(self, login, REQUEST, immediate=False):
        """ Wrapper around mailPassword """
        membership = getToolByName(self, 'portal_membership')
        if not membership.checkPermission('Mail forgotten password', self):
            raise Unauthorized(
                _(u"Mailing forgotten passwords has been disabled."))

        utils = getToolByName(self, 'plone_utils')
        member = get_member_by_login_name(self, login, raise_exceptions=False)

        if member is None:
            raise ValueError(
                _(u'The username you entered could not be found.'))

        # assert that we can actually get an email address, otherwise
        # the template will be made with a blank To:, this is bad
        email = member.getProperty('email')
        if not email:
            raise ValueError(_(u'That user does not have an email address.'))
        else:
            # add the single email address
            if not utils.validateSingleEmailAddress(email):
                raise ValueError(_(u'The email address did not validate.'))
        check, msg = _checkEmail(email)
        if not check:
            raise ValueError(msg)

        # Rather than have the template try to use the mailhost, we will
        # render the message ourselves and send it from here (where we
        # don't need to worry about 'UseMailHost' permissions).
        reset_tool = getToolByName(self, 'portal_password_reset')
        reset = reset_tool.requestReset(member.getId())

        encoding = getUtility(ISiteRoot).getProperty('email_charset', 'utf-8')
        mail_text = self.mail_password_template(self,
                                                REQUEST,
                                                member=member,
                                                reset=reset,
                                                password=member.getPassword(),
                                                charset=encoding)
        # The mail headers are not properly encoded we need to extract
        # them and let MailHost manage the encoding.
        if isinstance(mail_text, unicode):
            mail_text = mail_text.encode(encoding)
        message_obj = message_from_string(mail_text.strip())
        subject = message_obj['Subject']
        m_to = message_obj['To']
        m_from = message_obj['From']
        host = getToolByName(self, 'MailHost')
        try:
            host.send(mail_text,
                      m_to,
                      m_from,
                      subject=subject,
                      charset=encoding,
                      immediate=immediate)
        except SMTPRecipientsRefused:
            # Don't disclose email address on failure
            raise SMTPRecipientsRefused(
                _(u'Recipient address rejected by server.'))
        except SMTPException as e:
            raise (e)
        # return the rendered template "mail_password_response.pt"
        # (in Products.PasswordResetTool)
        return self.mail_password_response(self, REQUEST)
Example #47
0
def process_response(response):
    logger.debug("Processing Request Response...")

    if response.status_code == 200:
        try:
            data = bytes("Content-Type: ", 'utf-8') + bytes(
                response.headers['content-type'], 'utf-8') + bytes(
                    '\r\n\r\n', 'utf-8') + response.content
            msg = email.message_from_bytes(data)  # pylint: disable=no-member
        except AttributeError:
            data = "Content-Type: " + response.headers[
                'content-type'] + '\r\n\r\n' + response.content
            msg = email.message_from_string(data)

        for payload in msg.get_payload():
            if payload.get_content_type() == "application/json":
                j = json.loads(payload.get_payload())
                logger.debug("JSON String Returned: %s", json.dumps(j,
                                                                    indent=2))
            elif payload.get_content_type() == "audio/mpeg":
                filename = tmp_path + payload.get('Content-ID').strip(
                    "<>") + ".mp3"
                with open(filename, 'wb') as f:
                    f.write(payload.get_payload(decode=True))
            else:
                logger.debug("NEW CONTENT TYPE RETURNED: %s",
                             payload.get_content_type())

        # Now process the response
        if 'directives' in j['messageBody']:
            if not j['messageBody']['directives']:
                logger.debug("0 Directives received")

            for directive in j['messageBody']['directives']:
                if directive['namespace'] == 'SpeechSynthesizer':
                    if directive['name'] == 'speak':
                        player.play_speech(
                            mrl_fix("file://" + tmp_path + directive['payload']
                                    ['audioContent'].lstrip("cid:") + ".mp3"))

                elif directive['namespace'] == 'SpeechRecognizer':
                    if directive['name'] == 'listen':
                        logger.debug(
                            "Further Input Expected, timeout in: %sms",
                            directive['payload']['timeoutIntervalInMillis'])

                        player.play_speech(resources_path + 'beep.wav')
                        timeout = directive['payload'][
                            'timeoutIntervalInMillis'] / 116
                        audio_stream = capture.silence_listener(timeout)

                        # now process the response
                        alexa_speech_recognizer(audio_stream)

                elif directive['namespace'] == 'AudioPlayer':
                    if directive['name'] == 'play':
                        player.play_playlist(directive['payload'])

                elif directive['namespace'] == "Speaker":
                    # speaker control such as volume
                    if directive['name'] == 'SetVolume':
                        vol_token = directive['payload']['volume']
                        type_token = directive['payload']['adjustmentType']
                        if (type_token == 'relative'):
                            volume = player.get_volume() + int(vol_token)
                        else:
                            volume = int(vol_token)

                        if (volume > MAX_VOLUME):
                            volume = MAX_VOLUME
                        elif (volume < MIN_VOLUME):
                            volume = MIN_VOLUME

                        player.set_volume(volume)

                        logger.debug("new volume = %s", volume)

        # Additional Audio Iten
        elif 'audioItem' in j['messageBody']:
            player.play_playlist(j['messageBody'])

        return

    elif response.status_code == 204:
        logger.debug("Request Response is null (This is OKAY!)")
    else:
        logger.info("(process_response Error) Status Code: %s",
                    response.status_code)
        response.connection.close()

        platform.indicate_failure()
 def _getMessage(self):
     return email.message_from_string(self.getData())
Example #49
0
	def get_redirect_url(self, *args, **kwargs):

		pk=self.kwargs.get('pk')
		mail = imaplib.IMAP4_SSL('imap.gmail.com')
		user = self.request.user
		compania = Compania.objects.get(pk=pk)
		print(compania)
		assert compania.correo_intercambio, "No hay correo"
		assert compania.pass_correo_intercambio, "No hay password"
		correo = compania.correo_intercambio.strip()
		passw = compania.pass_correo_intercambio.strip()
		print(correo,passw)
		try:

			mail.login(correo,passw)
		except imaplib.IMAP4.error as e:
			
			messages.error(self.request, str(e))
			return reverse_lazy('intercambios:lista', kwargs={'pk':pk})
		mail.list()
		mail.select("inbox")
		result, data = mail.search(None, "ALL")
		id_list = data[0].split()
		try:
			last_email = Intercambio.objects.latest('codigo_email')
		except Intercambio.DoesNotExist:
			last_email = 0

		last_email_code = int(id_list[-1].decode())
		if last_email == 0:

			local_last_email_code = last_email
		else:

			local_last_email_code = int(last_email.codigo_email)
		if last_email_code > local_last_email_code:

			new_elements = last_email_code - local_last_email_code
		else:
			messages.info(self.request, "No posee nuevos correos")
			return reverse_lazy('intercambios:lista', kwargs={'pk':pk})
		if new_elements == 1:

			latest_emails = [id_list[-1]]
		else:

			latest_emails = id_list[-new_elements:]
		for element in latest_emails:

			result, email_data = mail.fetch(element, "(RFC822)")
			raw_email = email_data[0][1]
			raw_multipart = email.message_from_bytes(raw_email)
			raw_email_string = raw_email.decode('utf-8')
			email_message = email.message_from_string(raw_email_string)
			attachment_count, attachments = self.get_attachment(raw_multipart)
			remisor_name, remisor_email = self.get_remisor(str(email.header.make_header(email.header.decode_header(email_message['From']))))
			Intercambio.objects.create(
				codigo_email = element.decode(),
				receptor = compania,
				remisor = remisor_name,
				email_remisor = remisor_email,
				fecha_de_recepcion = self.get_received_time(str(email.header.make_header(email.header.decode_header(email_message['Received'])))),
				cantidad_dte = attachment_count,
				titulo = str(email.header.make_header(email.header.decode_header(email_message['Subject']))),
				contenido = self.get_body(raw_multipart).decode('latin-1')
			) 

		messages.success(self.request, "Cantidad de correos nuevos: {}".format(new_elements))
		return reverse_lazy('intercambios:lista', kwargs={'pk':pk})
Example #50
0
 def get_email_object(self):
     return email.message_from_string(self.body)
Example #51
0
def fetch_email_headers(num):
    global yahoo_mail
    #print "\nFetching Email header: ", num
    print num

    # id_list[-1] latest
    #https://tools.ietf.org/html/rfc3501#section-6.4.5
    # update global yahoo_mail dict and return value to hook

    # peek does not seen seen ?
    rv, data = M.fetch(num, '(BODY.PEEK[HEADER])')  # header only
    #rv, data = M.uid('fetch', num, '(BODY.PEEK[HEADER])') # header only

    if rv != 'OK':
        print "ERROR getting message header", num
        return (False, " ", " ", " ")

    raw_email = data[0][1]
    # data type list, lot of lines
    #https://docs.python.org/2/library/email.parser.html

    raw_email_string = raw_email.decode('utf-8')

    msg = email.message_from_string(raw_email_string)
    # msg type instance , From, received, .. all headers and bodies all headers, list of tuple
    # print msg.items()

    # decode is a tuple (subject, None or 'utf-8')

    decode = email.header.decode_header(msg['Subject'])[0]
    subject = decode[0]
    # type str
    #print subject, type(subject), decode[1]
    #  P2(P3) str(bytes) unicode(str)
    if isinstance(subject, str):
        #print "str type, decode as utf"
        subject = subject.decode('utf-8')
        #print "decoded" , type(subject)

    decode = email.header.decode_header(msg['From'])[0]
    from_add = decode[0]
    # type str
    #print from_add, type(from_add),  decode[1]
    if isinstance(from_add, str):
        #print "str type, decode as utf"
        from_add = from_add.decode('utf-8')
        #print "decoded"  , type(from_add)

    to_add = msg['To']

    #print 'Raw Date:', msg['Date'] # type str
    # Now convert to local date-time
    date_tuple = email.utils.parsedate_tz(msg['Date'])
    # type tuple (2018, 11, 16, 11, 0, 45, 0, 1, -1, 3600)
    if date_tuple:
        local_date = datetime.datetime.fromtimestamp(
            email.utils.mktime_tz(date_tuple))
        #print "Local Date:", local_date.strftime("%a, %d %b %Y %H:%M:%S")

        # local_date 2018-11-17 16:31:26
        # Local Date: Sat, 17 Nov 2018 16:31:26

    # dict, value is list vs tuple as we want to change it later. add text

    #print "\nFetching Email flag: ", num
    (flag, (dele, seen)) = fetch_email_flag(num)
    if not flag:
        print "error getting flag: ", num
        # default false, false
    #type, data = M.store(num, '+FLAGS', '\\Seen')
    return (True, from_add, to_add, subject, (dele, seen))
Example #52
0
count = 0
print(
    "______________________________________________________________________\n")
print("Empieza la recuperación y comparación de message-id\n")

# Se recorre cada elemento de la lista ID's, no condundir con el 'message-id'
for id in msg_list:
    # Se deodifica de bytes a utf-8
    id_raw = id.decode()
    # Se recupera el encabezado del correo
    # Retorna un mensaje del estado de la petición y la información solicitada
    typ2, msg_data = conn.fetch(id, 'BODY.PEEK[HEADER]')
    # Se decodifica
    raw_email = msg_data[0][1].decode('utf-8')
    # Se convierte en un objeto 'Message'
    email_obj = email.message_from_string(raw_email)
    # Se selecciona el 'message-id' y se le quitan los '<' y '>' del principio y final
    msg_id = email_obj['message-id'].strip('<>')
    # Se compara la expresión regular con el ID recién guardado
    matched = re.fullmatch(regex, msg_id)
    if not matched:
        count = count + 1
        print(
            "______________________________________________________________________________________________________________________"
        )
        print("Un mensaje no cumple con la expresión regular!!!")
        print("Fecha: " + email_obj['date'].strip('<>'))
        print("Message-ID: " + email_obj['message-id'].strip('<>'))
        print(
            "Recuerda revisar si cumple con alguna expresión regular anterior o si la fecha es cercana a la validez de la actual ER!"
        )
Example #53
0
mail = imaplib.IMAP4_SSL(SMTP_SERVER)
mail.login(FROM_EMAIL, FROM_PWD)  # user + password
mail.select('inbox')

type, data = mail.search(None,
                         '(FROM "*****@*****.**" SUBJECT "fileTesting")')

mail_ids = data[0]
id_list = mail_ids.split()
first_email_id = int(id_list[0])
latest_email_id = int(id_list[-1])

typ, data = mail.fetch(id_list[-1], '(RFC822)')
for response_part in data:
    if isinstance(response_part, tuple):
        msg = email.message_from_string(response_part[1])
        email_subject = msg['subject']
        email_from = msg['from']
        for part in msg.walk():
            #find the attachment part
            if part.get_content_maintype() == 'multipart': continue
            if part.get('Content-Disposition') is None: continue

            #save the attachment in the program directory
            filename = part.get_filename()
            fp = open(filename, 'wb')
            fp.write(part.get_payload(decode=True))
            fp.close()
            print '%s saved!' % filename

for i in range(latest_email_id, first_email_id, -1):
    def handle(self, *args, **options):
        ##########
        # 1. Save the email-attachment file to the django model (database)
        ##########
        sticker_email_host = env('STICKER_EMAIL_HOST', '')
        sticker_email_port = env('STICKER_EMAIL_PORT', '')
        sticker_email_username = env('STICKER_EMAIL_USERNAME', '')
        sticker_email_password = env('STICKER_EMAIL_PASSWORD', '')

        if not sticker_email_host or not sticker_email_port or not sticker_email_username or not sticker_email_password:
            raise Exception(
                'Configure email settings at .env to process sticker responses'
            )

        context = ssl.create_default_context()
        imapclient = imaplib.IMAP4_SSL(sticker_email_host,
                                       sticker_email_port,
                                       ssl_context=context)

        # login
        imapclient.login(sticker_email_username, sticker_email_password)
        """
        Retrieve messages
        """
        imapclient.select('INBOX')  # Select mail box
        typ, data = imapclient.search(None, "ALL")  # data = [b"1 2 3 4 ..."]
        datas = data[0].split()
        fetch_num = 5000  # The number of messages to fetch

        if (len(datas) - fetch_num) < 0:
            fetch_num = len(datas)

        # msg_list = []

        for num in datas[len(datas) - fetch_num::]:
            try:
                ##########
                # 2. Save the attached files into the database
                ##########
                typ, data = imapclient.fetch(num, '(RFC822)')
                # typ, data = imapclient.fetch(num, '(BODY[HEADER.FIELDS (MESSAGE-ID)])')
                raw_email = data[0][1]

                # converts byte literal to string removing b''
                raw_email_string = raw_email.decode('utf-8')
                email_message = email.message_from_string(raw_email_string)

                email_message_id = str(
                    make_header(decode_header(email_message["Message-ID"])))
                if StickerPrintingResponseEmail.objects.filter(
                        email_message_id=email_message_id):
                    # This email has been saved in the database already.  Skip this email
                    continue

                email_subject = str(
                    make_header(decode_header(email_message["Subject"])))
                email_from = email_message['From']
                body = get_text(email_message)
                email_body = body.decode()
                email_date = email_message['Date']

                sticker_printing_response_email = StickerPrintingResponseEmail.objects.create(
                    email_subject=email_subject,
                    email_from=email_from,
                    email_body=email_body,
                    email_date=email_date,
                    email_message_id=email_message_id,
                )

                # downloading attachments
                for part in email_message.walk():
                    try:
                        # this part comes from the snipped I don't understand yet...
                        if part.get_content_maintype() == 'multipart':
                            continue
                        if part.get('Content-Disposition') is None:
                            continue
                        fileName = part.get_filename()
                        if bool(fileName) and fileName.lower().endswith(
                                '.xlsx'):
                            now = timezone.localtime(timezone.now())

                            # Create sticker_printing_response object. File is not saved yet
                            sticker_printing_response = StickerPrintingResponse.objects.create(
                                sticker_printing_response_email=
                                sticker_printing_response_email,
                                name=fileName,
                            )

                            # Load attachment file
                            my_bytes = part.get_payload(decode=True)
                            content_file = ContentFile(my_bytes)

                            # Save file
                            sticker_printing_response._file.save(
                                fileName, content_file)
                    except Exception as e:
                        logger.exception(
                            'Exception has been raised when importing .xlsx file'
                        )
                        continue

                # imapclient.store(num, "+FLAGS", "\\Deleted")
                imapclient.copy(num, "Archive")
                imapclient.store(num, "+FLAGS", "\\Deleted")
            except:
                logger.exception(
                    'Exception has been raised when processing emails')
                continue

        imapclient.close()
        imapclient.logout()

        ##########
        # 3. Process xlsx file saved in django model
        ##########
        updates, errors = process_sticker_printing_response()

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # error_count = len(errors) + len(error_filenames)
        error_count = len(errors)
        err_str = '<strong style="color: red;">Errors: {}</strong>'.format(
            error_count
        ) if error_count else '<strong style="color: green;">Errors: 0</strong>'
        msg = '<p>{} completed. {}. IDs updated: {}.</p>'.format(
            cmd_name, err_str, updates)
        logger.info(msg)
        print(
            msg)  # will redirect to cron_tasks.log file, by the parent script
Example #55
0
"""
The init just contain versioning data.
"""

from collections import namedtuple

# get the raw PKG-INFO data
from pkg_resources import get_distribution
pkgInfo = get_distribution('gronk').get_metadata('PKG-INFO')

# parse it using email.Parser
from email import message_from_string
msg = message_from_string(pkgInfo)
inftuple = namedtuple('gronkinfo','author version year')
info = inftuple(msg['Author'],msg['Version'],'2018')
Example #56
0
	def process_mailbox(self, M, search_email, curr_dir):

		rv, data = M.search(None, '(OR (TO %s) (FROM %s))' % (search_email, search_email))
		if rv != 'OK':
			print "No messages found!"
			return

		for num in data[0].split():
			rv, data = M.fetch(num, '(RFC822)')
			if rv != 'OK':
				print "ERROR getting message", num
				return

			localinfo = []

			print '-----'
			msg = email.message_from_string(data[0][1])
			decode = email.header.decode_header(msg['Subject'])[0]
			subject = unicode(decode[0])
			print 'Message %s : %s' % (num, subject)
			self.ui.listWidget.addItem(QListWidgetItem('Message %s : %s' % (num, subject)))
			localinfo.append(num)
			localinfo.append(subject)

			sender = msg['from'].split()[-1]
			sender = sender[1:]
			sender = sender[:-1]

			print 'Sender : ', sender
			localinfo.append(sender)
			#print 'Raw Date:', msg['Date']

			for part in msg.walk():
				if part.get_content_type() == 'text/plain':
					print part.get_payload()
					localinfo.append(part.get_payload())
			
			# Kepping up to local time
			date_tuple = email.utils.parsedate_tz(msg['Date'])
			if date_tuple:
				local_date = datetime.datetime.fromtimestamp(
					email.utils.mktime_tz(date_tuple))
				print "Dated : ", \
					local_date.strftime("%a, %d %b %Y %H:%M:%S")


			fcount = 0
			for part in msg.walk():
		   
				if(part.get('Content-Disposition' ) is not None ) :
					filename = part.get_filename()
					print filename

		  

					final_path= os.path.join(curr_dir + filename)

					if not os.path.isfile(final_path) :
			  
					   fp = open(curr_dir+"/"+(filename), 'wb')
					   fp.write(part.get_payload(decode=True))
					   fcount += 1
					   fp.close()

			localinfo.append(fcount)

			global mailinfo
			mailinfo.append(localinfo)

			print '%d attachment(s) fetched' %fcount
			print '-----\n\n'

		mailinfo = [item for sublist in mailinfo for item in sublist]
		print mailinfo
Example #57
0
def parse_email(raw_email):
    if isinstance(raw_email, binary_type):
        raw_email = str_encode(raw_email, 'utf-8')
    try:
        email_message = email.message_from_string(raw_email)
    except UnicodeEncodeError:
        email_message = email.message_from_string(raw_email.encode('utf-8'))
    maintype = email_message.get_content_maintype()
    parsed_email = {}

    parsed_email['raw_email'] = raw_email

    body = {"plain": [], "html": []}
    attachments = []

    if maintype in ('multipart', 'image'):
        logger.debug("Multipart message. Will process parts.")
        for part in email_message.walk():
            content_type = part.get_content_type()
            part_maintype = part.get_content_maintype()
            content_disposition = part.get('Content-Disposition', None)
            if content_disposition or not part_maintype == "text":
                content = part.get_payload(decode=True)
            else:
                content = decode_content(part)

            is_inline = content_disposition is None \
                or content_disposition == "inline"
            if content_type == "text/plain" and is_inline:
                body['plain'].append(content)
            elif content_type == "text/html" and is_inline:
                body['html'].append(content)
            elif content_disposition:
                attachment = parse_attachment(part)
                if attachment:
                    attachments.append(attachment)

    elif maintype == 'text':
        payload = decode_content(email_message)
        body['plain'].append(payload)

    parsed_email['attachments'] = attachments

    parsed_email['body'] = body
    email_dict = dict(email_message.items())

    parsed_email['sent_from'] = get_mail_addresses(email_message, 'from')
    parsed_email['sent_to'] = get_mail_addresses(email_message, 'to')
    parsed_email['cc'] = get_mail_addresses(email_message, 'cc')
    parsed_email['bcc'] = get_mail_addresses(email_message, 'bcc')

    value_headers_keys = ['subject', 'date', 'message-id']
    key_value_header_keys = [
        'received-spf', 'mime-version', 'x-spam-status', 'x-spam-score',
        'content-type'
    ]

    parsed_email['headers'] = []
    for key, value in email_dict.items():

        if key.lower() in value_headers_keys:
            valid_key_name = key.lower().replace('-', '_')
            parsed_email[valid_key_name] = decode_mail_header(value)

        if key.lower() in key_value_header_keys:
            parsed_email['headers'].append({'Name': key, 'Value': value})

    if parsed_email.get('date'):
        timetuple = email.utils.parsedate(parsed_email['date'])
        parsed_date = datetime.fromtimestamp(time.mktime(timetuple)) \
            if timetuple else None
        parsed_email['parsed_date'] = parsed_date

    logger.info("Downloaded and parsed mail '{}' with {} attachments".format(
        parsed_email.get('subject'), len(parsed_email.get('attachments'))))
    return Struct(**parsed_email)
Example #58
0
def _handle_encrypted(original, message, session_keys=None):
    """Handle encrypted messages helper.

    RFC 3156 is quite strict:
    * exactly two messages
    * the first is of type 'application/pgp-encrypted'
    * the first contains 'Version: 1'
    * the second is of type 'application/octet-stream'
    * the second contains the encrypted and possibly signed data

    :param original: The original top-level mail. This is required to attache
        special headers to
    :type original: :class:`email.message.Message`
    :param message: The multipart/signed payload to verify
    :type message: :class:`email.message.Message`
    :param session_keys: a list OpenPGP session keys
    :type session_keys: [str]
    """
    malformed = False

    ct = message.get_payload(0).get_content_type()
    if ct != _APP_PGP_ENC:
        malformed = 'expected Content-Type: {0}, got: {1}'.format(
            _APP_PGP_ENC, ct)

    want = 'application/octet-stream'
    ct = message.get_payload(1).get_content_type()
    if ct != want:
        malformed = 'expected Content-Type: {0}, got: {1}'.format(want, ct)

    if not malformed:
        # This should be safe because PGP uses US-ASCII characters only
        payload = message.get_payload(1).get_payload().encode('ascii')
        try:
            sigs, d = crypto.decrypt_verify(payload, session_keys)
        except GPGProblem as e:
            # signature verification failures end up here too if the combined
            # method is used, currently this prevents the interpretation of the
            # recovered plain text mail. maybe that's a feature.
            malformed = str(e)
        else:
            n = decrypted_message_from_bytes(d, session_keys)

            # add the decrypted message to message. note that n contains all
            # the attachments, no need to walk over n here.
            original.attach(n)

            original.defects.extend(n.defects)

            # there are two methods for both signed and encrypted data, one is
            # called 'RFC 1847 Encapsulation' by RFC 3156, and one is the
            # 'Combined method'.
            if not sigs:
                # 'RFC 1847 Encapsulation', the signature is a detached
                # signature found in the recovered mime message of type
                # multipart/signed.
                if X_SIGNATURE_VALID_HEADER in n:
                    for k in (X_SIGNATURE_VALID_HEADER,
                              X_SIGNATURE_MESSAGE_HEADER):
                        original[k] = n[k]
            else:
                # 'Combined method', the signatures are returned by the
                # decrypt_verify function.

                # note that if we reached this point, we know the signatures
                # are valid. if they were not valid, the else block of the
                # current try would not have been executed
                add_signature_headers(original, sigs, '')

    if malformed:
        msg = 'Malformed OpenPGP message: {0}'.format(malformed)
        content = email.message_from_string(msg,
                                            _class=email.message.EmailMessage,
                                            policy=email.policy.SMTP)
        content.set_charset('utf-8')
        original.attach(content)
Example #59
0
def main(args=sys.argv):
    parser = option_parser()
    opts, args = parser.parse_args(args)

    if len(args) > 1:
        if len(args) < 4:
            print('You must specify the from address, to address and body text'
                  ' on the command line')
            return 1
        msg = compose_mail(args[1],
                           args[2],
                           args[3],
                           subject=opts.subject,
                           attachment=opts.attachment)
        from_, to = args[1:3]
        eto = [extract_email_address(x.strip()) for x in to.split(',')]
        efrom = extract_email_address(from_)
    else:
        msg = sys.stdin.read()
        from email import message_from_string
        from email.utils import getaddresses
        eml = message_from_string(msg)
        tos = eml.get_all('to', [])
        ccs = eml.get_all('cc', []) + eml.get_all('bcc', [])
        eto = [x[1] for x in getaddresses(tos + ccs) if x[1]]
        if not eto:
            raise ValueError(
                'Email from STDIN does not specify any recipients')
        efrom = getaddresses(eml.get_all('from', []))
        if not efrom:
            raise ValueError('Email from STDIN does not specify a sender')
        efrom = efrom[0][1]

    outbox = None
    if opts.outbox is not None:
        outbox = os.path.abspath(os.path.expanduser(opts.outbox))
        from mailbox import Maildir
        outbox = Maildir(opts.outbox, factory=None)
    if opts.fork:
        if os.fork() != 0:
            return 0

    if isinstance(msg, str):
        msg = msg.encode('utf-8')
    try:
        sendmail(msg,
                 efrom,
                 eto,
                 localhost=opts.localhost,
                 verbose=opts.verbose,
                 timeout=opts.timeout,
                 relay=opts.relay,
                 username=opts.username,
                 password=opts.password,
                 port=opts.port,
                 encryption=opts.encryption_method,
                 verify_server_cert=not opts.dont_verify_server_certificate,
                 cafile=opts.cafile)
    except:
        if outbox is not None:
            outbox.add(msg)
            outbox.close()
            print('Delivery failed. Message saved to', opts.outbox)
        raise
    return 0
Example #60
0
    """
    Take in text and replace all proofpoint url defense urls.
    with the original url
    """
    pp_url_pattern = re.compile(
        r'(https://urldefense\.(?:proofpoint\.)?com/v\d.*?(&e=$|\$))')
    for match in pp_url_pattern.finditer(c):
        unescaped_url = match.group(0)
        url = unescape(unescaped_url)
        decoded_url = decode_proofpoint(url)
        c = c.replace(unescaped_url, decoded_url)
    return c


# Get the message from stdin
message = email.message_from_string(sys.stdin.read())

# # this should deal with either single messages or flat multipart messages.
# # A more thorough approach would be needed for complex mime trees
# # ref. http://blog.magiksys.net/parsing-email-using-python-content
#
if message.is_multipart():
    for part in message.walk():
        content_transfer = part.__getitem__('Content-Transfer-Encoding')
        charset = part.get_content_charset()
        content_type = part.get_content_type()
        if content_type in ['text/html', 'text/plain']:
            _content = part.get_payload(decode=True).decode('iso-8859-1')
            _payload = revert_ppurls(_content)
            if content_transfer and content_transfer.lower() == 'base64':
                part.set_payload(base64.encodebytes(_payload.encode('utf=8')))