From 41f2eac415ddaf3b93565225317f0579e9ae8cc4 Mon Sep 17 00:00:00 2001 From: VG Date: Thu, 19 May 2016 21:00:26 +0200 Subject: Move processing mail code to a dedicated function Also move KeyboardIntr handling to a better place --- climl/__init__.py | 10 +++++++- climl/imap.py | 72 +++++++++++++++++++++++++++---------------------------- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/climl/__init__.py b/climl/__init__.py index d577ace..bc8ca94 100644 --- a/climl/__init__.py +++ b/climl/__init__.py @@ -1,7 +1,15 @@ from . import imap +from . import interface def on_email(content): print('on_email:', content) + print('now, raising exception') + raise interface.HookAbortError() def main(): - imap.main(on_email) + print('starting imap.main loop') + try: + imap.main(on_email) + except KeyboardInterrupt: + pass + print('end of main imap loop') diff --git a/climl/imap.py b/climl/imap.py index 034c77a..a0a3871 100644 --- a/climl/imap.py +++ b/climl/imap.py @@ -56,7 +56,12 @@ def connect_to_imap(conf, password): # never try to shutdown socket or send a logout since the goal of climl is # to stay connected, if this fails it is an error and thus no need to try # to be nice with a logout to a dead connection. - yield connection + print('connection...') + try: + yield connection + except: + print('end of connection') + raise def imap_waiter(connection): @@ -110,6 +115,34 @@ def imap_waiter(connection): return events +def process_emails(connection, callback=None, maxsize=None): + assert connection + assert callback + assert maxsize + idlist = connection.search(['UNANSWERED']) + print('found unprocessed idlist: ', idlist) + for oneid in idlist: + print('new mail:', oneid) + print('checking size of mail...') + response = connection.fetch([oneid], ['RFC822.SIZE']) + size = int(response[oneid][b'RFC822.SIZE']) + print('message size: {} bytes'.format(size)) + if size > maxsize: + print('message is too big, skip and mark it') + connection.add_flags([oneid], ['\Answered']) + continue + print('getting mail...') + response = connection.fetch([oneid], ['RFC822']) + data = response[oneid][b'RFC822'] + print('calling callback...') + try: + callback('mail: ' + str(oneid) + ': ' + str(data)) + connection.add_flags([oneid], ['\Answered']) + except interface.HookAbortError: + pass + data = None + + def main(callback=None): assert callback confpath = os.path.expanduser('~/.config/climl/climl.cfg') @@ -123,49 +156,16 @@ def main(callback=None): maxsize = conf.get('mail.maxsize', 100*1024) # 100k default maxsize = int(maxsize) while True: - print('connection...') try: with connect_to_imap(conf, password) as connection: print('selecting folder', conf.get('imap.mailbox')) connection.select_folder(conf.get('imap.mailbox')) - # at start, select all mails - idlist = connection.search(['UNSEEN']) - print('initial idlist: ', idlist) - for oneid in idlist: - print('new mail:', oneid) - print('checking size of mail...') - response = connection.fetch([oneid], ['RFC822.SIZE']) - size = int(response[oneid][b'RFC822.SIZE']) - print('message size: {} bytes'.format(size)) - if size > maxsize: - print('message is too big, skip and mark it seen') - connection.add_flags([oneid], ['\Seen']) - continue - print('getting mail...') - response = connection.fetch([oneid], ['RFC822']) - data = response[oneid][b'RFC822'] - print('calling callback...') - try: - callback('mail: ' + str(oneid) + ': ' + str(data)) - connection.add_flags([oneid], ['\Seen']) - except interface.HookAbortError: - pass - data = None while True: + process_emails(connection, callback, maxsize) imap_waiter(connection) - idlist = connection.search(['UNSEEN']) - for oneid in idlist: - print('calling callback...') - callback('mail: ' + str(oneid)) except (socket.error, socket.timeout, ssl.SSLError, ssl.CertificateError): print('socket/ssl error, retrying in 10s...') - try: - time.sleep(10) # wait between retries - except KeyboardInterrupt: - break - except KeyboardInterrupt: - break - print('end of connection') + time.sleep(10) # wait between retries -- cgit v1.2.3