parse output screen ok but cant get desired output new file!

Larry Bates lbates at swamisoft.com
Wed Jun 23 16:16:43 CEST 2004


I wrote something a couple of weeks ago that might help.
It works with POP3 mailboxes and it handles messages with
body text and/or attachments, but you could easily change
it.

Hope it helps.
Larry Bates
Syscon, Inc.

import poplib
import email
import email.Parser
import os
import sys

class email_attachment:
    def __init__(self, messagenum, attachmentnum, filename, contents):
        '''
        arguments:

        messagenum - message number of this message in the Inbox
        attachmentnum - attachment number for this attachment
        filename - filename for this attachment
        contents - attachment's contents
        '''
        self.messagenum=messagenum
        self.attachmentnum=attachmentnum
        self.filename=filename
        self.contents=contents
        return

    def save(self, savepath, savefilename=None):
        '''
        Method to save the contents of an attachment to a file
        arguments:

        savepath - path where file is to be saved
        safefilename - optional name (if None will use filename of
attachment
        '''

        savefilename=savefilename or self.filename
        f=open(os.path.join(savepath, savefilename),"wb")
        f.write(self.contents)
        f.close()
        return

class email_msg:
    def __init__(self, messagenum, contents):
        self.messagenum=messagenum
        self.contents=contents
        self.attachments_index=0  # Index of attachments for next method
        self.ATTACHMENTS=[]       # List of attachment objects

        self.msglines='\n'.join(contents[1])
        #
        # See if I can parse the message lines with email.Parser
        #
        self.msg=email.Parser.Parser().parsestr(self.msglines)
        if self.msg.is_multipart():
            attachmentnum=0
            for part in self.msg.walk():
                # multipart/* are just containers
                mptype=part.get_content_maintype()
                filename = part.get_filename()
                if mptype == "multipart": continue
                if filename: # Attached object with filename
                    attachmentnum+=1
                    self.ATTACHMENTS.append(email_attachment(messagenum,
attachmentnum,
                                                             filename,
part.get_payload(decode=1)))
                    print "Attachment filename=%s" % filename

                else: # Must be body portion of multipart
                    self.body=part.get_payload()

        else: # Not multipart, only body portion exists
            self.body=self.msg.get_payload()

        return


    def get(self, key):
        try: return self.msg.get(key)
        except:
            emsg="email_msg-Unable to get email key=%s information" % key
            print emsg
            sys.exit(emsg)

    def has_attachments(self):
        return (len(self.ATTACHMENTS) > 0)

    def __iter__(self):
        return self

    def next(self):
        #
        # Try to get the next attachment
        #
        try: ATTACHMENT=self.ATTACHMENTS[self.attachments_index]
        except:
            self.attachments_index=0
            raise StopIteration
        #
        # Increment the index pointer for the next call
        #
        self.attachments_index+=1
        return ATTACHMENT

class pop3_inbox:
    def __init__(self, server, userid, password):
        self._trace=0
        if self._trace: print "pop3_inbox.__init__-Entering"
        self.result=0             # Result of server communication
        self.MESSAGES=[]          # List for storing message objects
        self.messages_index=0     # Index of message for next method
        #
        # See if I can connect using information provided
        #
        try:
            if self._trace: print "pop3_inbox.__init__-Calling
poplib.POP3(server)"
            self.connection=poplib.POP3(server)
            if self._trace: print "pop3_inbox.__init__-Calling
connection.user(userid)"
            self.connection.user(userid)
            if self._trace: print "pop3_inbox.__init__-Calling
connection.pass_(password)"
            self.connection.pass_(password)

        except:
            if self._trace: print "pop3_inbox.__init__-Login failure,
closing connection"
            self.result=1
            self.connection.quit()

        #
        # Get count of messages and size of mailbox
        #
        if self._trace: print "pop3_inbox.__init__-Calling
connection.stat()"
        self.msgcount, self.size=self.connection.stat()
        #
        # Loop over all the messages processing each one in turn
        #
        for msgnum in range(1, self.msgcount+1):
            self.MESSAGES.append(email_msg(msgnum,
self.connection.retr(msgnum)))

        if self._trace: print "pop3_inbox.__init__-Leaving"
        return

    def close(self):
        self.connection.quit()
        return

    def remove(self, msgnumorlist):
        if isinstance(msgnumorlist, int): self.connection.dele(msgnumorlist)
        elif isinstance(msgnumorlist, (list, tuple)):
map(self.connection.dele, msgnumorlist)
        else:
            emsg="pop3_inbox.remove-msgnumorlist must be type int, list, or
tuple, not %s" % type(msgnumorlist)
            print emsg
            sys.exit(emsg)

        self.msgcount-=1
        return

    def __len__(self):
        return self.msgcount

    def __iter__(self):
        return self

    def next(self):
        #
        # Try to get the next attachment
        #
        try: MESSAGE=self.MESSAGES[self.messages_index]
        except:
            self.messages_index=0
            raise StopIteration
        #
        # Increment the index pointer for the next call
        #
        self.messages_index+=1
        return MESSAGE

if __name__=="__main__":
    server="www.domain.com"   # set server here
    userid="userid"   # set userid here
    password="password" # set password here
    inbox=pop3_inbox(server, userid, password)
    if inbox.result:
        emsg="Failure connecting to pop3_inbox"
        print emsg
        sys.exit(emsg)

    print "Message count=%i, Inbox size=%i" % (inbox.msgcount, inbox.size)

    counter=0
    for m in inbox:
        counter+=1
        print "Subject: %s" % m.get('subject')
        print "-------------Message (%i) body lines---------------" %
counter
        print m.body
        print "-------------End message (%i) body lines-----------" %
counter
        if m.has_attachments():
            acounter=0
            for a in m:
                acounter+=1
                print "-------------Message (%i) attachments-------------" %
counter
                print "%i: %s" % (acounter, a.filename)
                print "-------------End message (%i) attachments---------" %
counter
                a.save(r"C:\temp")

        else: print "-------------Message has no attachments----------"

    #
    # See if I can delete all messages
    #
    #if inbox.msgcount: inbox.remove(range(1, inbox.msgcount+1))
    inbox.close()


"chuck amadi" <chuck.amadi at ntlworld.com> wrote in message
news:mailman.32.1087971963.27577.python-list at python.org...
> By the way list is there a better way than using the readlines() to
> > > >parse the mail data into a file , because Im using
> > > >email.message_from_file it returns
> > > >all the data i.e reads one entire line from the file , headers as
> well
> > > >as just the desired body messages .
> > > >
> > > >fp = file("/home/chuck/pythonScript/testbox")
> > > >mb = mailbox.UnixMailbox(fp,
> > > >email.message_from_file)
> > > >
> > > >
> > > >mailout = file("/home/chuck/pythonScript/SurveyResults.txt","w")
> > > >for mail in fp.readlines():
> > > >    mailout.write(mail)
> > > >
> > > >Something like this>
> > > >
> > > >for mail in mb:
> > > >        body = mail.get_payload()
> > > >   mailout.write(body) # write only the body messages to
> SurveyResults.txt
> > > >
> > > >Cheers if the is a better way I can't get my head round how I can
> print
> > > >mail (
> > > >only the body messages) to screen and the entire mail headers and
> body
> > > >to the new file.
> > > >
> > > >Hi have any one got any suggstions to my script I can parse the
> email
> > > >body messages to screen but I want the same desired effect to save
> to a
> > > >new file.I have tried a few things to no effect.
> > >                     .
> > >                     .
> > >                     .
> > > There's a lot going on in your message.  I *think* what you want
> > > is the suggestion to replace
> > >   for mail in fp.readlines():
> > >       mailout.write(mail)
> > > with
> > >   mailout.write(fp.read())
> > > -- 
> > >
> > >
>
> > Hi again where I print mail.get_payload()
> > I want to write this to the file. Bu uisng readlinds() function I
> > obviously get the entire contents including the headers thus I want to
> > do something like this
>
> > for bdymsg in mb:
> > bdymsg = mail.get_payload()
> > print mail.get_payload()# prints body msg's to screen
> > mailout.write(bdymsg)
> > # mailout.write(mail.get_payload()) # Something along these lines.
> > mailout.close()
>
>
>
>
>
>





More information about the Python-list mailing list