mail_alert.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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) -> list | str:
  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. ids: list = []
  55. for msg in msgs:
  56. chk = mask(msg, 'levente.marton@mzk.ro')
  57. if chk:
  58. msg_text = msg.text
  59. if 'end of day extras/intraday' in msg.subject:
  60. msg_text = msg.text.replace('<br>', '\n')
  61. if msg.uid not in container:
  62. try:
  63. if len(msg.text) != 0:
  64. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text}')
  65. else:
  66. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html}')
  67. # container.appendleft(msg.uid)
  68. print('message appended', len(container))
  69. except BadRequest:
  70. try:
  71. if len(msg.text) != 0:
  72. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text[:len(msg_text) // 5]}')
  73. else:
  74. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html[:len(msg.html) // 5]}')
  75. # container.appendleft(msg.uid)
  76. print('message appended', len(container))
  77. except BadRequest:
  78. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\nMessage is too long')
  79. # container.appendleft(msg.uid)
  80. print('message appended', len(container), '!! last message was to long !!')
  81. except Exception:
  82. try:
  83. mailbox.logout()
  84. pretty_exc()
  85. except IMAP4.abort:
  86. pass
  87. # break
  88. ids.append(msg.uid)
  89. mailbox.logout()
  90. # return msg.uid
  91. return ids
  92. except Exception:
  93. try:
  94. mailbox.logout()
  95. except IMAP4.abort:
  96. pass
  97. return 'empty box'
  98. async def mail_alert2(container) -> list | str:
  99. # container: deque = deque(maxlen=500)
  100. # while True:
  101. try:
  102. mailbox2 = MailBox(host=config['email']['host'], ssl_context=context)
  103. mailbox2.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='bank_events') # noqa E:mypy
  104. sleep(15)
  105. msgs = [msgs for msgs in mailbox2.fetch(AND(seen=False), mark_seen=True)]
  106. ids: list = []
  107. for msg in msgs:
  108. chk = mask2(msg, 'account')
  109. if chk:
  110. if msg.uid not in container:
  111. soup = BeautifulSoup(msg.html, 'html.parser')
  112. msg_text = soup.prettify().replace('<br/>', '').replace('<html>', '').replace('<head>', '').replace('</head>', '').replace('<body>', '').replace('<div>', '').replace('</div>', '').replace('</body>', '').replace('</html>', '')
  113. msg_text = msg_text[:msg_text.find('Intraday transactions')]
  114. msg_text = clean_html(msg_text)
  115. try:
  116. if len(msg.text) or len(msg.html) != 0:
  117. await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text)
  118. else:
  119. await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text)
  120. # container.appendleft(msg.uid)
  121. print('message appended', len(container))
  122. except BadRequest:
  123. try:
  124. if len(msg.text) or len(msg.html) != 0:
  125. await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text // 5) # noqa E:mypy
  126. else:
  127. await bot2.send_message(chat_id=config['AUTH']['chatid'], text=msg_text // 5) # noqa E:mypy
  128. # container.appendleft(msg.uid)
  129. print('message appended', len(container))
  130. except BadRequest:
  131. await bot2.send_message(chat_id=config['AUTH']['chatid'], text=f'Message is too long')
  132. # container.appendleft(msg.uid)
  133. print('message appended', len(container), '!! last message was to long !!')
  134. except Exception:
  135. try:
  136. mailbox2.logout()
  137. pretty_exc()
  138. except IMAP4.abort:
  139. pass
  140. # break
  141. ids.append(msg.uid)
  142. mailbox2.logout()
  143. # return msg.uid
  144. return ids
  145. except Exception:
  146. # pretty_exc()
  147. try:
  148. mailbox2.logout()
  149. except IMAP4.abort:
  150. pass
  151. return 'empty box'
  152. async def mail_alert3(container) -> list | str:
  153. '''mail alert Inbox'''
  154. # container: deque = deque(maxlen=500)
  155. # while True:
  156. try:
  157. mailbox3 = MailBox(host=config['email']['host'], ssl_context=context)
  158. mailbox3.login(config['email']['user'], keyring.get_password('yagmail', 'levente.marton@mzk.ro'), initial_folder='API') # noqa E:mypy
  159. sleep(15)
  160. msgs = [msgs for msgs in mailbox3.fetch(AND(seen=False), mark_seen=True)]
  161. ids: list = []
  162. for msg in msgs:
  163. chk = mask(msg, 'Ciel_notifier@mzk.ro')
  164. if chk:
  165. msg_text = msg.text
  166. # if 'end of day extras/intraday' in msg.subject:
  167. # msg_text = msg.text.replace('<br>', '\n')
  168. if msg.uid not in container:
  169. try:
  170. if len(msg.text) != 0:
  171. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text}')
  172. else:
  173. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html}')
  174. # container.appendleft(msg.uid)
  175. print('message appended', len(container))
  176. except BadRequest:
  177. try:
  178. if len(msg.text) != 0:
  179. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg_text[:len(msg_text) // 5]}')
  180. else:
  181. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\n{msg.html[:len(msg.html) // 5]}')
  182. # container.appendleft(msg.uid)
  183. print('message appended', len(container))
  184. except BadRequest:
  185. await bot.send_message(chat_id=config['AUTH']['chatid'], text=f'{msg.from_}\nsubj: {msg.subject}\n\nMessage is too long')
  186. # container.appendleft(msg.uid)
  187. print('message appended', len(container), '!! last message was to long !!')
  188. except Exception:
  189. try:
  190. mailbox3.logout()
  191. pretty_exc()
  192. except IMAP4.abort:
  193. pass
  194. # break
  195. ids.append(msg.uid)
  196. mailbox3.logout()
  197. # return msg.uid
  198. return ids
  199. except Exception:
  200. try:
  201. mailbox3.logout()
  202. except IMAP4.abort:
  203. pass
  204. return 'empty box'
  205. # if __name__ == '__main__':
  206. # try:
  207. # # event = Event()
  208. # asyncio.run(mail_alert())
  209. # except KeyboardInterrupt:
  210. # loop = asyncio.get_event_loop()
  211. # loop.stop()