Bläddra i källkod

Rewritten using the asyncio lib and new async telegram bot.

marton levente 3 månader sedan
förälder
incheckning
7235738bf9
2 ändrade filer med 183 tillägg och 179 borttagningar
  1. 148 147
      mail_alert.py
  2. 35 32
      start_mail_alert.py

+ 148 - 147
mail_alert.py

@@ -4,6 +4,7 @@ import configparser
 import sys
 import traceback
 import ssl
+import asyncio
 from time import sleep
 from collections import deque
 from threading import Event
@@ -24,14 +25,6 @@ config.read('bot')
 bot = telegram.Bot(token=config['AUTH']['token'])
 bot2 = telegram.Bot(token=config['AUTH']['bank'])
 
-# mailbox = MailBox(host=config['email']['host'], ssl_context=context)
-# mailbox2 = MailBox(host=config['email']['host'], ssl_context=context)
-# mailbox3 = MailBox(host=config['email']['host'], ssl_context=context)
-
-# mailbox.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='Inbox')
-# mailbox2.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='bank_events')
-# mailbox3.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='API')
-
 
 def pretty_exc():
     exc_type, _exc_obj, exc_tb = sys.exc_info()
@@ -52,167 +45,175 @@ def mask2(msg, to_):
                 to_ in msg.bcc,
                 to_ in msg.subject])
 
-
-def mail_alert(event=None):
+def clean_html(text) -> str:
+    soup = BeautifulSoup(text, 'html.parser')
+    stripped_text = soup.get_text()
+    lines = (line.strip() for line in stripped_text.splitlines())
+    # break multi-headlines into a line each
+    chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
+    # drop blank lines
+    text = '\n'.join(chunk for chunk in chunks if chunk)
+    return text
+
+async def mail_alert(container) -> str | None:
     '''mail alert Inbox'''
-    container = deque(maxlen=500)
-    while not event.is_set():
-        try:
-            mailbox = MailBox(host=config['email']['host'], ssl_context=context)
-            mailbox.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='Inbox')
-            sleep(15)
-            msgs = [msgs for msgs in mailbox.fetch(AND(seen=False), mark_seen=False)]
-            for msg in msgs:
-                chk = mask(msg, 'levente.marton@mzk.ro')
-                if chk:
-                    msg_text = msg.text
-                    if 'end of day extras/intraday' in msg.subject:
-                        msg_text = msg.text.replace('<br>', '\n')
-                    if msg.uid not in container:
+    # container: deque = deque(maxlen=500)
+    # while True:
+    try:
+        mailbox = MailBox(host=config['email']['host'], ssl_context=context)
+        mailbox.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='Inbox') # noqa E:mypy
+        sleep(15)
+        msgs = [msgs for msgs in mailbox.fetch(AND(seen=False), mark_seen=False)]
+        for msg in msgs:
+            chk = mask(msg, 'levente.marton@mzk.ro')
+            if chk:
+                msg_text = msg.text
+                if 'end of day extras/intraday' in msg.subject:
+                    msg_text = msg.text.replace('<br>', '\n')
+                if msg.uid not in container:
+                    try:
+                        if len(msg.text) != 0:
+                            await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text}')
+                        else:
+                            await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html}')
+                        container.appendleft(msg.uid)
+                        print('message appended', len(container))
+                    except BadRequest:
                         try:
                             if len(msg.text) != 0:
-                                bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text}')
+                                await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text[:len(msg_text) // 5]}')
                             else:
-                                bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html}')
+                                await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html[:len(msg.html) // 5]}')
                             container.appendleft(msg.uid)
                             print('message appended', len(container))
                         except BadRequest:
-                            try:
-                                if len(msg.text) != 0:
-                                    bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text[:len(msg_text) // 5]}')
-                                else:
-                                    bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html[:len(msg.html) // 5]}')
-                                container.appendleft(msg.uid)
-                                print('message appended', len(container))
-                            except BadRequest:
-                                bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\nMessage is too long')
-                                container.appendleft(msg.uid)
-                                print('message appended', len(container), '!! last message was to long !!')
-                        except Exception:
-                            try:
-                                mailbox.logout()
-                                pretty_exc()
-                            except IMAP4.abort:
-                                pass
-                            # break
+                            await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\nMessage is too long')
+                            container.appendleft(msg.uid)
+                            print('message appended', len(container), '!! last message was to long !!')
+                    except Exception:
+                        try:
+                            mailbox.logout()
+                            pretty_exc()
+                        except IMAP4.abort:
+                            pass
+                        # break
+        mailbox.logout()
+        return msg.uid
+    except Exception:
+        try:
             mailbox.logout()
-        except Exception:
-            try:
-                mailbox.logout()
-            except IMAP4.abort:
-                pass
-            # break
-        # finally:
-        #     mailbox.logout()
+        except IMAP4.abort:
+            pass
+        return 'empty box'
 
-def mail_alert2(event=None):
-    container = deque(maxlen=500)
-    while not event.is_set():
-        try:
-            mailbox2 = MailBox(host=config['email']['host'], ssl_context=context)
-            mailbox2.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='bank_events')
-            sleep(15)
-            msgs = [msgs for msgs in mailbox2.fetch(AND(seen=False), mark_seen=True)]
-            for msg in msgs:
-                chk = mask2(msg, 'account')
-                if chk:
-                    if msg.uid not in container:
-                        soup = BeautifulSoup(msg.html, 'html.parser')
-                        msg_text = soup.prettify().replace('<br/>', '').replace('<html>', '').replace('<head>', '').replace('</head>', '').replace('<body>', '').replace('<div>', '').replace('</div>', '').replace('</body>', '').replace('</html>', '')
-                        msg_text = msg_text[:msg_text.find('Intraday transactions')]
+async def mail_alert2(container) -> str | None:
+    # container: deque = deque(maxlen=500)
+    # while True:
+    try:
+        mailbox2 = MailBox(host=config['email']['host'], ssl_context=context)
+        mailbox2.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='bank_events') # noqa E:mypy
+        sleep(15)
+        msgs = [msgs for msgs in mailbox2.fetch(AND(seen=False), mark_seen=True)]
+        for msg in msgs:
+            chk = mask2(msg, 'account')
+            if chk:
+                if msg.uid not in container:
+                    soup = BeautifulSoup(msg.html, 'html.parser')
+                    msg_text = soup.prettify().replace('<br/>', '').replace('<html>', '').replace('<head>', '').replace('</head>', '').replace('<body>', '').replace('<div>', '').replace('</div>', '').replace('</body>', '').replace('</html>', '')
+                    msg_text = msg_text[:msg_text.find('Intraday transactions')]
+                    msg_text = clean_html(msg_text)
+                    try:
+                        if len(msg.text) or len(msg.html) != 0:
+                            await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text)
+                        else:
+                            await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text)
+                        container.appendleft(msg.uid)
+                        print('message appended', len(container))
+                    except BadRequest:
                         try:
                             if len(msg.text) or len(msg.html) != 0:
-                                bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text)
+                                await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text // 5) # noqa E:mypy
                             else:
-                                bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text)
+                                await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text // 5) # noqa E:mypy
                             container.appendleft(msg.uid)
                             print('message appended', len(container))
                         except BadRequest:
-                            try:
-                                if len(msg.text) or len(msg.html) != 0:
-                                    bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text // 5)
-                                else:
-                                    bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text // 5)
-                                container.appendleft(msg.uid)
-                                print('message appended', len(container))
-                            except BadRequest:
-                                bot2.send_message(chat_id=config['AUTH']['chatid'], text=f'Message is too long')
-                                container.appendleft(msg.uid)
-                                print('message appended', len(container), '!! last message was to long !!')
-                        except Exception:
-                            try:
-                                mailbox2.logout()
-                                pretty_exc()
-                            except IMAP4.abort:
-                                pass
-                            # break
+                            await bot2.send_message(chat_id=config['AUTH']['chatid'], text=f'Message is too long')
+                            container.appendleft(msg.uid)
+                            print('message appended', len(container), '!! last message was to long !!')
+                    except Exception:
+                        try:
+                            mailbox2.logout()
+                            pretty_exc()
+                        except IMAP4.abort:
+                            pass
+                        # break
+        mailbox2.logout()
+        return msg.uid
+    except Exception:
+        # pretty_exc()
+        try:
             mailbox2.logout()
-        except Exception:
-            # pretty_exc()
-            try:
-                mailbox2.logout()
-            except IMAP4.abort:
-                pass
-            # break
-        # finally:
-        #     mailbox2.logout()
+        except IMAP4.abort:
+            pass
+        return 'empty box'
 
-def mail_alert3(event=None):
+async def mail_alert3(container) -> str | None:
     '''mail alert Inbox'''
-    container = deque(maxlen=500)
-    while not event.is_set():
-        try:
-            mailbox3 = MailBox(host=config['email']['host'], ssl_context=context)
-            mailbox3.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='API')
-            sleep(15)
-            msgs = [msgs for msgs in mailbox3.fetch(AND(seen=False), mark_seen=True)]
-            for msg in msgs:
-                chk = mask(msg, 'Ciel_notifier@mzk.ro')
-                if chk:
-                    msg_text = msg.text
-                    # if 'end of day extras/intraday' in msg.subject:
-                    #     msg_text = msg.text.replace('<br>', '\n')
-                    if msg.uid not in container:
+    # container: deque = deque(maxlen=500)
+    # while True:
+    try:
+        mailbox3 = MailBox(host=config['email']['host'], ssl_context=context)
+        mailbox3.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='API') # noqa E:mypy
+        sleep(15)
+        msgs = [msgs for msgs in mailbox3.fetch(AND(seen=False), mark_seen=True)]
+        for msg in msgs:
+            chk = mask(msg, 'Ciel_notifier@mzk.ro')
+            if chk:
+                msg_text = msg.text
+                # if 'end of day extras/intraday' in msg.subject:
+                #     msg_text = msg.text.replace('<br>', '\n')
+                if msg.uid not in container:
+                    try:
+                        if len(msg.text) != 0:
+                            await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text}')
+                        else:
+                            await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html}')
+                        container.appendleft(msg.uid)
+                        print('message appended', len(container))
+                    except BadRequest:
                         try:
                             if len(msg.text) != 0:
-                                bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text}')
+                                await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text[:len(msg_text) // 5]}')
                             else:
-                                bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html}')
+                                await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html[:len(msg.html) // 5]}')
                             container.appendleft(msg.uid)
                             print('message appended', len(container))
                         except BadRequest:
-                            try:
-                                if len(msg.text) != 0:
-                                    bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text[:len(msg_text) // 5]}')
-                                else:
-                                    bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html[:len(msg.html) // 5]}')
-                                container.appendleft(msg.uid)
-                                print('message appended', len(container))
-                            except BadRequest:
-                                bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\nMessage is too long')
-                                container.appendleft(msg.uid)
-                                print('message appended', len(container), '!! last message was to long !!')
-                        except Exception:
-                            try:
-                                mailbox3.logout()
-                                pretty_exc()
-                            except IMAP4.abort:
-                                pass
-                            # break
+                            await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\nMessage is too long')
+                            container.appendleft(msg.uid)
+                            print('message appended', len(container), '!! last message was to long !!')
+                    except Exception:
+                        try:
+                            mailbox3.logout()
+                            pretty_exc()
+                        except IMAP4.abort:
+                            pass
+                        # break
+        mailbox3.logout()
+        return msg.uid
+    except Exception:
+        try:
             mailbox3.logout()
-        except Exception:
-            try:
-                mailbox3.logout()
-            except IMAP4.abort:
-                pass
-            # break
-        # finally:
-        #     mailbox3.logout()
-
-
-if __name__ == '__main__':
-    try:
-        event = Event()
-        mail_alert2(event=event)
-    except KeyboardInterrupt:
-        event.set()
+        except IMAP4.abort:
+            pass
+        return 'empty box'
+
+
+# if __name__ == '__main__':
+#     try:
+#         # event = Event()
+#         asyncio.run(mail_alert())
+#     except KeyboardInterrupt:
+#         loop = asyncio.get_event_loop()
+#         loop.stop()

+ 35 - 32
start_mail_alert.py

@@ -1,45 +1,48 @@
 '''Created 16 Nov 2022 Levi'''
 
+from collections import deque
 from threading import Event
 from threading import Thread
 from time import sleep
+import asyncio
 
 import mail_alert
 
-event1 = Event()
-event2 = Event()
-event3 = Event()
-thread1 = Thread(target=mail_alert.mail_alert, args=(event1,))
-thread2 = Thread(target=mail_alert.mail_alert2, args=(event2,))
-thread3 = Thread(target=mail_alert.mail_alert3, args=(event3,))
+# event1 = Event()
+# event2 = Event()
+# event3 = Event()
+# thread1 = Thread(target=mail_alert.mail_alert, args=(event1,))
+# thread2 = Thread(target=mail_alert.mail_alert2, args=(event2,))
+# thread3 = Thread(target=mail_alert.mail_alert3, args=(event3,))
 # thread4 =
 # thread5 =
 # thread6 =
 
+async def main() -> None:
+    container: deque = deque(maxlen=500)
+    try:
+        while True:
+            # loop = asyncio.get_event_loop()
+            # tasks = map(asyncio.create_task,
+            #             [mail_alert.mail_alert(container)
+            #              # mail_alert.mail_alert2()
+            #              # mail_alert.mail_alert3()
+            #              ])
+            tasks = [mail_alert.mail_alert(container),
+                     mail_alert.mail_alert2(container),
+                     mail_alert.mail_alert3(container)]
+            # result = await asyncio.wait(tasks)
+            results = await asyncio.gather(*tasks)
+            # print(result)
+            for result in results:
+                container.appendleft(result)
+            # await asyncio.sleep(1)
+    except KeyboardInterrupt:
+        print('Cancelling all tasks...')
+        for task in tasks:
+            task.cancel() # noqa
+        await asyncio.gather(*tasks, return_exceptions=True)
+        print('All tasks cancelled.')
+
 if __name__ == '__main__':
-    thread1.start()
-    print(f'started mail alert Inbox')
-    # sleep(0.5)
-    thread2.start()
-    print(f'started mail alert Bank events')
-    # sleep(0.5)
-    thread3.start()
-    print(f'started mail alert API')
-    # sleep(0.5)
-    while True:
-        try:
-            sleep(1)
-        except KeyboardInterrupt:
-            event1.set()
-            event2.set()
-            event3.set()
-            thread1.join()
-            print(f'stopped mail alert Inbox')
-            # sleep(0.5)
-            thread2.join()
-            print(f'stopped mail alert Bank events')
-            # sleep(0.5)
-            thread3.join()
-            print(f'stopped mail alert API')
-            # sleep(0.5)
-            break
+    asyncio.run(main())