Suggestions on programming in Python an email simple client
MRAB
python at mrabarnett.plus.com
Tue Feb 13 18:35:15 EST 2018
On 2018-02-13 22:54, Maroso Marco wrote:
> Il giorno martedì 13 febbraio 2018 21:18:37 UTC+1, Chris Angelico ha scritto:
>> On Wed, Feb 14, 2018 at 7:05 AM, Maroso Marco <androidmaroso at gmail.com> wrote:
>> > Hi,
>> >
>> > what i'm trying to do is develop my own email client, but a simple one.
>> >
>> > I just want it to connect to a specific email account and read the subject line of messages coming from a certain email address.
>> >
>> > I then want it to be able to execute the command i wrote on the subject.
>>
>> Be aware that "from" addresses can easily be forged. I suggest
>> whitelisting a set of valid commands and executing only those. If you
>> want a REAL way to manage your home system remotely, I would recommend
>> SSH instead.
>>
>> > It would be nice if i could specify two parameters on the subject line
>> >
>> > first : password;
>> > second : command;
>> >
>> > The first parameter is the password and the second is the command to be executed in the local pc where this program is running.
>>
>> That's an improvement, but since the password is being transmitted in
>> clear text, it won't prevent attacks. It does mean you won't try to
>> execute the subject lines of random spam, though, so accidents will be
>> reduced (or eliminated).
>>
>> > The program will have to show only email coming from a specific account
>> > and if the mail is unread then it should read the subject line and find parameters.
>> > The first parameter must match my hardcoded password, and the second parameter must be executed on the local pc (example ... c:\windows\notepad.exe)
>> >
>> > It must check for new emails at a given timing (example ...every 30 seconds )
>> > (the timing can be hardcoded or specified in a separate file)
>> >
>> > This is it.
>> >
>> > Any suggestions?
>>
>> Seems perfectly possible.
>>
>> > I have started doing this (but i never programmed in python before):
>> >
>> >
>> > import imaplib
>> > import os
>> > import email
>> > import email.header
>> >
>> > plusmail = "emailaddresstobechecked at gmail.com"
>> > googlepass = "mypassword"
>> > owner = "validsender at gmail.com"
>> >
>> > M = imaplib.IMAP4_SSL('imap.gmail.com')
>> > M.login(plusmail, googlepass)
>> > M.select()
>> >
>> > status, response = M.search(None, '(UNSEEN)')
>> > unread_msg_nums = response[0].split()
>> >
>> > # Print the count of all unread messages
>> > print (len(unread_msg_nums))
>> >
>> > # Print all unread messages from a certain sender of interest
>> > status, response = M.search(None, '(UNSEEN)', '(FROM "%s")' % (owner))
>> > unread_msg_nums = response[0].split()
>> > da = []
>> > for e_id in unread_msg_nums:
>> > _, response = imap.fetch(e_id, '(BODY.PEEK[HEADER.FIELDS (From Subject)] RFC822.SIZE)')
>> > da.append(response[0][1])
>> > # print (da)
>> >
>> > # Mark them as seen
>> > for e_id in unread_msg_nums:
>> > imap.store(e_id, '+FLAGS', '\Seen')
>> >
>> >
>> >
>> > typ, data = M.search(None, 'From',(owner))
>> > for num in data[0].split():
>> > typ, data = M.fetch(num, '(RFC822)')
>> > print ('Message %s\n%s\n' % (num, data[0][1]))
>> > M.close()
>> > M.logout()
>> >
>> > I know there are duplicates but i need to figure out how to build this correctly
>>
>> Seems like a reasonable start. So what's the code doing wrong, or
>> failing to do? Is it failing with an exception? Is it running
>> successfully, but not doing something you want it to do?
>>
>> ChrisA
>
> Hi Chris and thanks for replying.
>
> I came up with the following code (thanks for the security suggestions-i'm just testing) :
>
> My code actually works fine allthough i have a couple of problems :
>
> 1 - once parced the messages and executed the command in the subject line, it keeps looping even if i told to only execute on unread messages
> 2 - it loops continuosly instead of waiting the correct wait time
> 3 - i had to add a delete statement so that the program stops looping at least on processing the commands.
>
> Can you help me sort out the issue? Maybe it's an indent problem!
>
>
> Here is the code :
>
> import imaplib
> import os
> import email
> import email.header
> import time
>
> def mailcontroller():
>
> # Set user, pass and allowed mail for giving commands
> plusmail = "emailaddresstobechecked at gmail.com"
> googlepass = "thesecretpassword"
> captain = "theallowedemailaddress at gmail.com"
>
> # Set vars for IMAP access
> M = imaplib.IMAP4_SSL('imap.gmail.com')
> M.login(plusmail, googlepass)
> M.select()
>
> # Set search on UNSEEN messages
> status, response = M.search(None, '(UNSEEN)')
> unread_msg_nums = response[0].split()
>
>
> # Mark as read
> for e_id in unread_msg_nums:
> M.store(e_id, '+FLAGS', '\Seen')
>
Here you iterate through all of the messages:
> # cycle messages sent from autorized email address
> typ, data = M.search(None, 'From',(captain))
> for num in data[0].split():
> typ, data = M.fetch(num, '(RFC822)')
> msg = email.message_from_string(data[0][1])
> decode = email.header.decode_header(msg['Subject'])[0]
> subject = unicode(decode[0])
> comando = subject
>
These lines are indented the same as the 'for' loop above, so they'll
executed only the last message. If there are no messages, 'subject'
won't be defined.
> if googlepass in subject:
> print 'Message %s: %s' % (num, subject)
>
> # Split subject line
> googlepass,comando = subject.split(";")
> # Print command
> print comando
> # Execute command
> os.system(comando)
>
> M.store(num, '+FLAGS', '\\Deleted')
There's no need to use 'expunge' here because those messages that are
marked for deletion will be expunged anyway when the mailbox is closed:
> M.expunge()
>
Why not just "else:" here?
> elif googlepass not in subject:
> print "Nope"
>
> M.close()
> M.logout()
>
Actually, the sequence should be more like:
login
for each message:
execute if necessary
close and logout
>
> time.sleep(10)
>
> while True:
> mailcontroller()
>
It should really be sleeping between calls.
> THanks in advance :-)
>
More information about the Python-list
mailing list