models.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. # -*- coding: utf-8 -*-
  2. """
  3. Datenmodelle fuer das Calendar-Plugin.
  4. Definiert CalendarEvent, CalendarInfo, NotificationRecord und EventStatus.
  5. """
  6. from dataclasses import dataclass, field
  7. from datetime import datetime
  8. from enum import Enum
  9. class EventStatus(Enum):
  10. """Status eines Kalender-Events."""
  11. CONFIRMED = "confirmed"
  12. TENTATIVE = "tentative"
  13. CANCELLED = "cancelled"
  14. @dataclass
  15. class CalendarEvent:
  16. """
  17. Ein Kalender-Termin.
  18. Attributes:
  19. event_id: Eindeutige ID vom Provider
  20. calendar_id: Zugehoeriger Kalender-Key
  21. provider_name: Provider-Schluessel (outlook_firma, google_firma, etc.)
  22. title: Titel des Termins
  23. start: Startzeitpunkt
  24. end: Endzeitpunkt
  25. all_day: Ganztaegiger Termin
  26. location: Ort
  27. description: Beschreibung
  28. attendees: Teilnehmer (Namen/Emails)
  29. organizer: Organisator
  30. status: Terminstatus
  31. reminder_minutes: Erinnerung in Minuten vor Start
  32. raw_data: Original-Daten vom Provider
  33. """
  34. event_id: str
  35. calendar_id: str
  36. provider_name: str
  37. title: str
  38. start: datetime
  39. end: datetime
  40. all_day: bool = False
  41. location: str = ""
  42. description: str = ""
  43. attendees: list[str] = field(default_factory=list)
  44. organizer: str = ""
  45. status: EventStatus = EventStatus.CONFIRMED
  46. reminder_minutes: int = 15
  47. raw_data: dict = field(default_factory=dict)
  48. @property
  49. def duration(self) -> int:
  50. """Dauer in Minuten."""
  51. delta = self.end - self.start
  52. return int(delta.total_seconds() / 60)
  53. @property
  54. def is_upcoming(self) -> bool:
  55. """Liegt der Termin in der Zukunft?"""
  56. return self.start > datetime.now()
  57. @property
  58. def is_ongoing(self) -> bool:
  59. """Findet der Termin gerade statt?"""
  60. now = datetime.now()
  61. return self.start <= now <= self.end
  62. @dataclass
  63. class CalendarInfo:
  64. """
  65. Informationen ueber einen einzelnen Kalender.
  66. Attributes:
  67. calendar_id: ID beim Provider
  68. provider_name: Provider-Schluessel aus Config
  69. display_name: Anzeigename
  70. readonly: Nur lesbar
  71. is_global: Gilt fuer alle Satellites
  72. """
  73. calendar_id: str
  74. provider_name: str
  75. display_name: str
  76. readonly: bool = True
  77. is_global: bool = False
  78. @dataclass
  79. class NotificationRecord:
  80. """
  81. Aufzeichnung einer gesendeten Benachrichtigung.
  82. Attributes:
  83. event_id: Event-ID
  84. notification_type: "reminder" oder "start"
  85. sent_at: Zeitpunkt der Benachrichtigung
  86. satellite_ids: Betroffene Satellites
  87. """
  88. event_id: str
  89. notification_type: str
  90. sent_at: datetime
  91. satellite_ids: list[str] = field(default_factory=list)