mail_alert.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. '''Created Sep 28, 2021 Levi'''
  2. import configparser
  3. import sys
  4. import traceback
  5. import ssl
  6. from time import sleep
  7. from imaplib import IMAP4
  8. import telegram
  9. import keyring
  10. from bs4 import BeautifulSoup
  11. from telegram.error import BadRequest
  12. from imap_tools import MailBox, AND
  13. # -> for python >=3.10, the dh key too small problem
  14. context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
  15. context.set_ciphers('DEFAULT@SECLEVEL=1')
  16. config = configparser.ConfigParser()
  17. config.read('bot')
  18. bot = telegram.Bot(token=config['AUTH']['token'])
  19. bot2 = telegram.Bot(token=config['AUTH']['bank'])
  20. def pretty_exc():
  21. exc_type, _exc_obj, exc_tb = sys.exc_info()
  22. # fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
  23. for tb in list(traceback.format_exception(exc_type, _exc_obj, exc_tb)):
  24. print(tb)
  25. def mask(msg, to_):
  26. return any([to_ == msg.from_,
  27. to_ in msg.to,
  28. to_ in msg.cc,
  29. to_ in msg.bcc])
  30. def mask2(msg, to_):
  31. return any([to_ == msg.from_,
  32. to_ in msg.to,
  33. to_ in msg.cc,
  34. to_ in msg.bcc,
  35. to_ in msg.subject])
  36. def clean_html(text) -> str:
  37. soup = BeautifulSoup(text, 'html.parser')
  38. stripped_text = soup.get_text()
  39. lines = (line.strip() for line in stripped_text.splitlines())
  40. # break multi-headlines into a line each
  41. chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
  42. # drop blank lines
  43. text = '\n'.join(chunk for chunk in chunks if chunk)
  44. return text
  45. async def mail_alert(container) -> str | None:
  46. '''mail alert Inbox'''
  47. # container: deque = deque(maxlen=500)
  48. # while True:
  49. try:
  50. mailbox = MailBox(host=config['email']['host'], ssl_context=context)
  51. mailbox.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='Inbox') # noqa E:mypy
  52. sleep(15)
  53. msgs = [msgs for msgs in mailbox.fetch(AND(seen=False), mark_seen=False)]
  54. for msg in msgs:
  55. chk = mask(msg, 'levente.marton@mzk.ro')
  56. if chk:
  57. msg_text = msg.text
  58. if 'end of day extras/intraday' in msg.subject:
  59. msg_text = msg.text.replace('<br>', '\n')
  60. if msg.uid not in container:
  61. try:
  62. if len(msg.text) != 0:
  63. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text}')
  64. else:
  65. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html}')
  66. container.appendleft(msg.uid)
  67. print('message appended', len(container))
  68. except BadRequest:
  69. try:
  70. if len(msg.text) != 0:
  71. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text[:len(msg_text) // 5]}')
  72. else:
  73. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html[:len(msg.html) // 5]}')
  74. container.appendleft(msg.uid)
  75. print('message appended', len(container))
  76. except BadRequest:
  77. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\nMessage is too long')
  78. container.appendleft(msg.uid)
  79. print('message appended', len(container), '!! last message was to long !!')
  80. except Exception:
  81. try:
  82. mailbox.logout()
  83. pretty_exc()
  84. except IMAP4.abort:
  85. pass
  86. # break
  87. mailbox.logout()
  88. return msg.uid
  89. except Exception:
  90. try:
  91. mailbox.logout()
  92. except IMAP4.abort:
  93. pass
  94. return 'empty box'
  95. async def mail_alert2(container) -> str | None:
  96. # container: deque = deque(maxlen=500)
  97. # while True:
  98. try:
  99. mailbox2 = MailBox(host=config['email']['host'], ssl_context=context)
  100. mailbox2.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='bank_events') # noqa E:mypy
  101. sleep(15)
  102. msgs = [msgs for msgs in mailbox2.fetch(AND(seen=False), mark_seen=True)]
  103. for msg in msgs:
  104. chk = mask2(msg, 'account')
  105. if chk:
  106. if msg.uid not in container:
  107. soup = BeautifulSoup(msg.html, 'html.parser')
  108. msg_text = soup.prettify().replace('<br/>', '').replace('<html>', '').replace('<head>', '').replace('</head>', '').replace('<body>', '').replace('<div>', '').replace('</div>', '').replace('</body>', '').replace('</html>', '')
  109. msg_text = msg_text[:msg_text.find('Intraday transactions')]
  110. msg_text = clean_html(msg_text)
  111. try:
  112. if len(msg.text) or len(msg.html) != 0:
  113. await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text)
  114. else:
  115. await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text)
  116. container.appendleft(msg.uid)
  117. print('message appended', len(container))
  118. except BadRequest:
  119. try:
  120. if len(msg.text) or len(msg.html) != 0:
  121. await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text // 5) # noqa E:mypy
  122. else:
  123. await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text // 5) # noqa E:mypy
  124. container.appendleft(msg.uid)
  125. print('message appended', len(container))
  126. except BadRequest:
  127. await bot2.send_message(chat_id=config['AUTH']['chatid'], text=f'Message is too long')
  128. container.appendleft(msg.uid)
  129. print('message appended', len(container), '!! last message was to long !!')
  130. except Exception:
  131. try:
  132. mailbox2.logout()
  133. pretty_exc()
  134. except IMAP4.abort:
  135. pass
  136. # break
  137. mailbox2.logout()
  138. return msg.uid
  139. except Exception:
  140. # pretty_exc()
  141. try:
  142. mailbox2.logout()
  143. except IMAP4.abort:
  144. pass
  145. return 'empty box'
  146. async def mail_alert3(container) -> str | None:
  147. '''mail alert Inbox'''
  148. # container: deque = deque(maxlen=500)
  149. # while True:
  150. try:
  151. mailbox3 = MailBox(host=config['email']['host'], ssl_context=context)
  152. mailbox3.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='API') # noqa E:mypy
  153. sleep(15)
  154. msgs = [msgs for msgs in mailbox3.fetch(AND(seen=False), mark_seen=True)]
  155. for msg in msgs:
  156. chk = mask(msg, 'Ciel_notifier@mzk.ro')
  157. if chk:
  158. msg_text = msg.text
  159. # if 'end of day extras/intraday' in msg.subject:
  160. # msg_text = msg.text.replace('<br>', '\n')
  161. if msg.uid not in container:
  162. try:
  163. if len(msg.text) != 0:
  164. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text}')
  165. else:
  166. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html}')
  167. container.appendleft(msg.uid)
  168. print('message appended', len(container))
  169. except BadRequest:
  170. try:
  171. if len(msg.text) != 0:
  172. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text[:len(msg_text) // 5]}')
  173. else:
  174. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html[:len(msg.html) // 5]}')
  175. container.appendleft(msg.uid)
  176. print('message appended', len(container))
  177. except BadRequest:
  178. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\nMessage is too long')
  179. container.appendleft(msg.uid)
  180. print('message appended', len(container), '!! last message was to long !!')
  181. except Exception:
  182. try:
  183. mailbox3.logout()
  184. pretty_exc()
  185. except IMAP4.abort:
  186. pass
  187. # break
  188. mailbox3.logout()
  189. return msg.uid
  190. except Exception:
  191. try:
  192. mailbox3.logout()
  193. except IMAP4.abort:
  194. pass
  195. return 'empty box'
  196. # if __name__ == '__main__':
  197. # try:
  198. # # event = Event()
  199. # asyncio.run(mail_alert())
  200. # except KeyboardInterrupt:
  201. # loop = asyncio.get_event_loop()
  202. # loop.stop()