mail_import.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. from config import DSN, MAILBOX
  2. from model import StatusMeldung
  3. from datetime import date, time
  4. from email.message import EmailMessage
  5. from sqlalchemy import create_engine
  6. from sqlalchemy.orm import Session
  7. from sqlalchemy.exc import IntegrityError
  8. from imap_tools import MailBox
  9. import json
  10. class MailImport:
  11. def open_mailbox(self) -> MailBox:
  12. return MailBox(MAILBOX["server"]).login(
  13. MAILBOX["user"], MAILBOX["password"], MAILBOX["folder"]
  14. )
  15. def mail_import(self):
  16. with (
  17. Session(create_engine(DSN)) as db_session,
  18. self.open_mailbox() as mb,
  19. ):
  20. messages = mb.fetch(mark_seen=True, limit=500)
  21. imported = []
  22. for msg in messages:
  23. status = self.get_status_message(msg)
  24. if status is None:
  25. continue
  26. db_session.add(status)
  27. try:
  28. db_session.commit()
  29. imported.append(msg.uid)
  30. except IntegrityError as e:
  31. db_session.rollback()
  32. print(e.args[0])
  33. mb.delete(imported)
  34. def get_status_message(self, msg: EmailMessage) -> StatusMeldung:
  35. subject = msg.subject.split(";")
  36. if len(subject) < 5:
  37. print(msg.subject)
  38. return None
  39. attachments = dict(
  40. [(att.filename, att.payload) for att in msg.attachments if att.size > 0]
  41. )
  42. fehlerbericht_json = json.loads(attachments.get("fehlerbericht.json", "[]"))
  43. fehlerbericht_import = json.dumps(fehlerbericht_json)
  44. aufgabe = ""
  45. if len(subject) > 5:
  46. if subject[5][-4:] == ".bat":
  47. aufgabe = subject[5]
  48. elif ":" in subject[5]:
  49. aufgabe = "manuell"
  50. if ":" not in subject[1]:
  51. aufgabe = subject[1]
  52. subject[1] = "00:00"
  53. if aufgabe == "":
  54. files = [f["Name"] for f in fehlerbericht_json if ".bat" in f["Name"]]
  55. if len(files) > 0:
  56. aufgabe = files[0]
  57. return StatusMeldung(
  58. datum=date.fromisoformat(subject[3]),
  59. kunde=subject[0],
  60. aufgabe=aufgabe,
  61. start=time.fromisoformat(subject[1]),
  62. ende=time.fromisoformat(subject[2]),
  63. fehlerbericht_import=fehlerbericht_import,
  64. anzahl=int(subject[4]),
  65. )
  66. def cleanup(self):
  67. pass
  68. if __name__ == "__main__":
  69. mi = MailImport()
  70. mi.mail_import()
  71. mi.cleanup()