Exemplo n.º 1
0
    def onMime(self, who, data):
        ''' Handles incoming MIME messages, such as those sent by
        NotesBuddy containing embedded image data '''

        from email.Parser import Parser
        from StringIO import StringIO

        print '<mime>%s' % who[0]
        msg = Parser().parsestr(data)

        html = StringIO()  # combined text segments
        images = {}  # map of Content-ID:binary image

        for part in msg.walk():
            mt = part.get_content_maintype()
            if mt == 'text':
                html.write(part.get_payload(decode=True))
            elif mt == 'image':
                cid = part.get('Content-ID')
                images[cid] = part.get_payload(decode=True)

        print ' <text/html>:', html.getvalue()
        html.close()

        print ' <images>:', [k[1:-1] for k in images.keys()]
Exemplo n.º 2
0
            f = open("tmp.mime", 'w')

        except Exception, e:
            print >> sys.stderr, e

        else:
            f.write(data)
            f.close()

        # second, parse and display
        msg = Parser().parsestr(data)

        html = StringIO()  # combined text segments
        images = {}  # map of Content-ID:binary image

        for part in msg.walk():
            mt = part.get_content_maintype()
            if mt == 'text':
                html.write(part.get_payload(decode=True))
            elif mt == 'image':
                cid = part.get('Content-ID')
                images[cid] = part.get_payload(decode=True)

        print ' <text/html>:', html.getvalue()
        html.close()

        print ' <images>:', [k[1:-1] for k in images.keys()]

    def onSubject(self, who, subj):
        print '<subject>%s: "%s"' % (who[0], subj)
Exemplo n.º 3
0
def fetch(folder, username, password, server='imap.gmail.com', archive=True,
          archive_folder=None, accept_only=None):
    """
    Connects over IMAP to a mailbox and extracts attachments from all emails

    folder
        The IMAP folder name to parse for emails
    server
        The IMAP server URL
    username
        The username to connect to IMAP with
    password
        The username to connect to IMAP with
    archive
        Optionally move completed emails to a different folder (default: True)
    archive_folder:
        The folder to move completed mails to
        (default: folder + "_archive")
    accept_only (list):
        One or more file type suffixes to extract from emails, from this list:
            csv
            excel
            zip
            gz
        (Default: any from that list)
    """
    mime_types = []

    if accept_only is None:
        accept_only = ('csv', 'excel', 'zip', 'gz')

    if 'csv' in accept_only:
        mime_types.extend(['text/csv', 'application/csv'])

    if 'zip' in accept_only:
        mime_types.extend([
            'application/zip', 'multipart/x-zip',
            'application/x-zip-compressed', 'application/octet-stream',
        ])

    if 'gz' in accept_only:
        mime_types.extend(['application/x-gzip', 'multipart/x-gzip'])

    if 'excel' in accept_only:
        mime_types.extend([
            'vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'application/vnd.ms-excel', 'application/octet-stream',
        ])

    # default the IMAP archive folder for completed emails
    if archive and archive_folder is None:
        archive_folder = "{0}_archive".format(folder)

    try:
        # login to IMAP
        M = imaplib.IMAP4_SSL(server)
        M.login(username, password)
    except socket.gaierror:
        raise Exception("Bad credentials for IMAP server {0}".format(server))

    files = []
    to_archive = []

    try:
        # look at all mail in this IMAP folder
        result, data = M.select(folder)
        result, data = M.search(None, "ALL")
        id_list = data[0].split()

        for id in id_list:
            result, data = M.fetch(id, "(RFC822)")
            content = data[0][1]
            if sys.version < '3':
                msg = Parser().parsestr(content)
            else:
                msg = Parser().parsestr(content.decode('utf-8'))

            # only look at if has attachment.
            if msg.is_multipart():
                for part in msg.walk():
                    if part.get_content_type() in mime_types:
                        # download attachment into temp file
                        tmpfile = tempfile.mkstemp(part.get_filename())
                        tmp_fhandle, tmp_fname = tmpfile
                        if sys.version < '3':
                            with os.fdopen(tmp_fhandle, "w") as f:
                                f.write(part.get_payload(decode=True))
                        else:
                            with os.fdopen(tmp_fhandle, "wb") as f:
                                f.write(part.get_payload(decode=True))

                        # decompress zip/gz into contained files
                        if _is_compressed(tmp_fname):
                            files.extend(_extract_csvs_from_zip(tmp_fname))
                        else:
                            files.append(tmp_fname)

            # mark this email for archival
            if archive is True:
                to_archive.append(str(id))

        # move mails from mailbox to archive_mbox
        if len(to_archive) > 0:
            message_set = ",".join(to_archive)
            M.copy(message_set, archive_folder)
            M.store(message_set, "+FLAGS", r"(\Deleted)")
            M.expunge()

    finally:
        # close the mailbox and disconnect the IMAP connection
        M.close()
        M.logout()

    return files