mail_import.py 3.0 KB

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