yejunzhou / typhoonae

Automatically exported from code.google.com/p/typhoonae
0 stars 0 forks source link

Incoming Mail Service #73

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Google App Engine provides an Incoming Mail Service. See 
http://code.google.com/appengine/docs/python/mail/receivingmail.html for 
further information.

It would be a great enhancement for TyphoonAE to have a similar service.

Original issue reported on code.google.com by tobias.r...@gmail.com on 10 Oct 2010 at 11:59

GoogleCodeExporter commented 9 years ago
We could use the IMAPClient http://imapclient.freshfoo.com/ library for 
connecting to an IMAP server. The credentials should be configured with apptool 
and in etc/typhoonae.cfg.

Original comment by tobias.r...@gmail.com on 10 Oct 2010 at 12:03

GoogleCodeExporter commented 9 years ago
I've implemented Incoming Mail Service for TyphoonAE in friday's clone of trunk 
and would like to contribute my code. 
What would be the best way to do that?

Original comment by ivovnenko on 24 Oct 2010 at 9:23

GoogleCodeExporter commented 9 years ago
Hi ivovnenko - Great to hear that!

It might be the best, if you create a clone here 
http://code.google.com/p/typhoonae/source/clones and push your changes there. 
In that way diffing, testing and eventually pulling the changes into the trunk 
would be much easier.

Thanks a lot for contributing! I'm eager to see your implementation.

Original comment by tobias.r...@gmail.com on 25 Oct 2010 at 9:01

GoogleCodeExporter commented 9 years ago
Guys, pushed to https://ivovnenko-mail-typhoonae.googlecode.com/hg

Original comment by ivovnenko on 25 Oct 2010 at 2:25

GoogleCodeExporter commented 9 years ago
Awesome ivovnenko!

A few comments on the code itself, you listen to the imap server in a loop on a 
thread. For the first hour, your program is interruptible with Ctrl-C. After 
this first hour the program is no longer interruptible and will keep running 
until it's killed.

Given that this will run in its own process (I assume), I don't really see the 
need for running this code in a thread, I think it will be simpler to have your 
_loop function with a few modifications (remove checks to stop_event, remove 
except handler for Exception).

The process will die when you send it SIGTERM or CTRL-C not just in its first 
hour, but all during its life, and you will not need the stop_event because it 
will just be an uncatched exception that will propagate out of _loop.

On a side node, as Tobias and I discussed in private a while ago, this solves 
the problem of accepting incoming emails when you have only 1 (or a small set) 
of users accounts that can receive emails, but it doesn't solve the problem of 
receiving emails to unknown, dynamic addresses (think 
foo-<SECURITY_TOKEN>@example.com). This is however more robust than having our 
own SMTP daemon, so I guess that we will have some option in the future to 
choose between listening to an existing IMAP server, and be our own SMTP server 
(less robust, but more flexible).

Cheers,

Original comment by e98cu...@gmail.com on 25 Oct 2010 at 4:36

GoogleCodeExporter commented 9 years ago
Great work, ivovnenko! - Your IMAP/HTTP dispatcher works like a charm.

I'm planning to merge your changes into the trunk during this week. Although, I 
believe, e98cuenc might be right that using a thread for the listener isn't 
entirely necessary. Can you elaborate a bit on your design decision?

The GAE docs say that incoming mails are received at 
string@appid.appspotmail.com which basically means that we need our own SMTP 
daemon (string@appid.example.com), as e98cuenc proposed, if we want to be fully 
compatible to GAE.

However, I believe your implementation is a huge benefit and a great option for 
numerous use-cases.

@e98cuenc: From looking into the code, I don't see why the program shouldn't be 
interruptible after the first hour. But maybe I missed something. Did you mean 
the following code?

while True:
    try:
        time.sleep(3600)
    except KeyboardInterrupt:
        listener.stop()
        listener.join()
        break

http://code.google.com/r/ivovnenko-mail-typhoonae/source/browse/src/typhoonae/ma
il/imap_http_dispatch.py#268

Anyway, thanks a lot for contributing!

Original comment by tobias.r...@gmail.com on 25 Oct 2010 at 7:32

GoogleCodeExporter commented 9 years ago
Thanks for you feedback. 

If you give this code a second look

  while True:
        try:
            time.sleep(3600)
        except KeyboardInterrupt:
            listener.stop()
            listener.join()
            break

you will see it will exit on KeyboardInterrupt properly even after 1 hour sleep.

However you have the point regarding the simplification, just pushed the 
changes to https://ivovnenko-mail-typhoonae.googlecode.com/hg

Agreed on the side note.

Original comment by ivovnenko on 25 Oct 2010 at 7:47

GoogleCodeExporter commented 9 years ago
Sorry, somehow I missed the loop. My only remaining comment will be that I 
don't think you need to catch KeyboardException, specially when this code will 
be managed by supervisord.

Great work!

Original comment by e98cu...@gmail.com on 26 Oct 2010 at 8:09

GoogleCodeExporter commented 9 years ago
Thanks. 
@e98cuenc sure, i can remove except KeyboardException, but wont we have stack 
trace in logs on every impa_http_dispatcher shutdown?

Original comment by ivovnenko on 26 Oct 2010 at 5:06

GoogleCodeExporter commented 9 years ago
This is going to be in the next release. Thanks again for contributing!

- Tobias

Original comment by tobias.r...@gmail.com on 2 Dec 2010 at 11:19

GoogleCodeExporter commented 9 years ago
Available in the 0.2.0 release.

Original comment by tobias.r...@gmail.com on 12 Dec 2010 at 11:33