Download from email over pop3


6 posts
by Davies » Tue May 16, 2017 3:59 pm
hi all, im trying to download from an email with a specific subject field.
the file will usually download the first time but then fail thereafter.
heres the code...
Code: Select all
import poplib
from email import parser

frm = email@address
password = a_password

def mail_connection():
    pop_conn = poplib.POP3_SSL('pop.gmail.com')
    pop_conn.user(frm)
    pop_conn.pass_(password)
    print 'dialled in'
    return pop_conn


def fetch_mail(delete_after=False):
    print 'checking mail'
    pop_conn = mail_connection()
    messages = [pop_conn.retr(i) for i in range(1, len(pop_conn.list()[1]) + 1)]
    messages = ["\n".join(mssg[1]) for mssg in messages]
    messages = [parser.Parser().parsestr(mssg) for mssg in messages]
    if delete_after == True:
        delete_messages = [pop_conn.dele(i) for i in range(1, len(pop_conn.list()[1]) + 1)]
    pop_conn.quit()
    return messages
#allowed_mimetypes = ["application/txt"]


def get_attachments():
    messages = fetch_mail()
    attachments = []
    for message in messages:
        if message['subject'] == 'rpi_download':
            print "download found"
            for part in message.walk():
                name = part.get_filename()
                if name == 'test123.py' or 'testing123.txt':
                    print name
                    data = part.get_payload(decode=True)
                    f = file("/home/pi/" + name, 'wb')
                    f.write(data)
                    f.close()
                    attachments.append(name)
                    return attachments
        else:
            print "subject didnt match"

get_attachments()


in get_attachments, "print name" prints None to terminal, but how can this be when name must be 'test123.py' or 'testing123.txt' to be able to print?
the error i get in terminal is "Cannot concatenate str() and None"
any help would be greatly appreciated
Posts: 110
Joined: Sat Apr 04, 2015 4:24 pm
by Davies » Tue May 16, 2017 4:43 pm
strange... in "get_attachments()" if i remove ' or testing123.txt' from
Code: Select all
if name == 'test123.py' or 'testing123.txt':

the code works without issue, but running with detection of multiple files it fails each time.. can anybody see why? i assumed python would use the "or" clause like any other time...?
Posts: 110
Joined: Sat Apr 04, 2015 4:24 pm
by hippy » Tue May 16, 2017 5:04 pm
Davies wrote:
Code: Select all
if name == 'test123.py' or 'testing123.txt':

I suspect that's doing "( a == b ) or c" and always returning True. You might want to try ...

Code: Select all
if name == 'test123.py' or name == 'testing123.txt':

Possibly ...

Code: Select all
if name in [ 'test123.py', 'testing123.txt' ]:
Posts: 1946
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK
by Davies » Tue May 16, 2017 5:13 pm
hippy, your awesome!.. thank you very much, thats working :)

am i correct in thinking that for example
Code: Select all
if variable == '123' or 'abc'
would be correct usage, or should normal usage actually be
Code: Select all
if variable == '123' or variable == 'abc'
Posts: 110
Joined: Sat Apr 04, 2015 4:24 pm
by elParaguayo » Wed May 17, 2017 8:45 am
The last one is correct. If you want to check whether a string matches a number of alternatives you can do:
Code: Select all
if variable == "123" or variable == "abc":
or
Code: Select all
if variable in ["123", "abc"]:
This last one may be preferable when you're checking a number of alternatives as it saves repeating the "variable ==" part.

Your first example is different. You're checking whether "variable" equals "123" or if "abc" evaluates as True. In python, a non-blank string will always be true so the statement
Code: Select all
if variable == '123' or 'abc'
is always true.
RPi Information Screen: plugin based system for displaying weather, travel information, football scores etc.
User avatar
Posts: 1776
Joined: Wed May 16, 2012 12:46 pm
Location: London, UK
by Davies » Wed May 17, 2017 3:52 pm
thank you for explaining that further. looking back through previous scripts i can see that i have written "or" statements repeating variables multiple times, unsure why i couldnt see the error this time around (though self taught over last few years so still very much a noob) ill be using the "in" statement from now on as it gives a much cleaner read through when using the same variable multiple times.
thank you both for your answers.
Posts: 110
Joined: Sat Apr 04, 2015 4:24 pm