Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Der-Henning
GitHub Repository: Der-Henning/tgtg
Path: blob/main/tgtg_scanner/notifiers/base.py
1494 views
1
import logging
2
import threading
3
from abc import ABC, abstractmethod
4
from queue import Queue
5
6
from tgtg_scanner.models import Config, Cron, Favorites, Item, Reservations
7
from tgtg_scanner.models.reservations import Reservation
8
9
log = logging.getLogger("tgtg")
10
11
12
class Notifier(ABC):
13
"""Base Notifier."""
14
15
@abstractmethod
16
def __init__(self, config: Config, reservations: Reservations, favorites: Favorites):
17
self.config = config
18
self.enabled = False
19
self.reservations = reservations
20
self.favorites = favorites
21
self.cron = Cron()
22
self.thread = threading.Thread(target=self._run)
23
self.queue: Queue[Item | Reservation | None] = Queue()
24
25
@property
26
def name(self):
27
"""Get notifier name."""
28
return self.__class__.__name__
29
30
def _run(self) -> None:
31
"""Run notifier."""
32
self.config.set_locale()
33
while True:
34
try:
35
item = self.queue.get()
36
if item is None:
37
break
38
log.debug("Sending %s Notification", self.name)
39
self._send(item)
40
except KeyboardInterrupt:
41
pass
42
except Exception as exc:
43
log.error("Failed sending %s: %s", self.name, exc)
44
45
def start(self) -> None:
46
"""Run notifier in thread."""
47
if self.enabled:
48
log.debug("Starting %s Notifier thread", self.name)
49
self.thread.start()
50
51
def send(self, item: Item | Reservation) -> None:
52
"""Send notification."""
53
if not isinstance(item, (Item, Reservation)):
54
log.error("Invalid item type: %s", type(item))
55
return
56
if self.enabled and self.cron.is_now:
57
self.queue.put(item)
58
if not self.thread.is_alive():
59
log.debug("%s Notifier thread is dead. Restarting", self.name)
60
self.thread = threading.Thread(target=self._run)
61
self.start()
62
63
@abstractmethod
64
def _send(self, item: Item | Reservation) -> None:
65
"""Send Item information."""
66
67
def stop(self) -> None:
68
"""Stop notifier."""
69
if self.thread.is_alive():
70
log.debug("Stopping %s Notifier thread", self.name)
71
self.queue.put(None)
72
self.thread.join()
73
log.debug("%s Notifier thread stopped", self.name)
74
75
@abstractmethod
76
def __repr__(self) -> str:
77
pass
78
79