trackbert/classes/tracker.py

92 lines
3.4 KiB
Python
Raw Normal View History

import logging
import subprocess
import time
from pathlib import Path
from typing import Optional, Tuple, Never
from .database import Database
from pykeydelivery import KeyDelivery
class Tracker:
def __init__(self):
logging.basicConfig(
format="%(asctime)s %(levelname)s: %(message)s",
level=logging.DEBUG,
datefmt="%Y-%m-%d %H:%M:%S",
)
def notify(self, title: str, message: str, urgency: str = "normal", timeout: Optional[int] = 5000) -> None:
logging.debug(f"Sending notification: {title} - {message}")
command = [
"notify-send",
"-a", "trackbert",
"-u", urgency,
"-i", str(Path(__file__).parent / "assets" / "parcel-delivery-icon.webp"),
]
if timeout:
command += ["-t", str(timeout)]
command = command + [title, message]
try:
subprocess.run(command)
except FileNotFoundError:
logging.warning("notify-send not found, not sending notification")
def start_loop(self) -> Never:
logging.debug("Starting loop")
while True:
for shipment in self.db.get_shipments():
shipment_id = shipment.id
tracking_number = shipment.tracking_number
carrier = shipment.carrier
description = shipment.description
logging.debug(f"Checking shipment {tracking_number} with carrier {carrier}")
latest_known_event = self.db.get_latest_event(shipment_id)
all_events = self.api.realtime(carrier, tracking_number)
try:
logging.debug(f"Got events for {tracking_number}: {len(all_events['data']['items'])}")
except KeyError:
print(f"Error getting events for {tracking_number}: {all_events}")
continue
events = sorted(all_events["data"]["items"], key=lambda x: x["time"], reverse=True)
if latest_known_event:
logging.debug(f"Latest known event for {tracking_number}: {latest_known_event.event_description} - {latest_known_event.event_time}")
else:
logging.debug(f"No known events for {tracking_number}")
logging.debug(f"Latest upstream event for {tracking_number}: {events[0]['context']} - {events[0]['time']}")
latest = True
for event in events:
if latest_known_event is None or event["time"] > latest_known_event.event_time:
self.db.create_event(
shipment_id,
event["time"],
event["context"],
event,
)
logging.info(f"New event for {tracking_number}: {event['context']} - {event['time']}")
self.notify(f"New event for {description or tracking_number}", event["context"] + " - " + event["time"], urgency="critical" if latest else "normal")
latest = False
time.sleep(300)
def start(self):
self.db = Database('sqlite:///trackbert.db')
self.api = KeyDelivery.from_config("config.ini")
self.notify("Trackbert", "Starting up")
self.start_loop()