675 lines
24 KiB
Python
675 lines
24 KiB
Python
"""
|
|
Timer-Manager für Countdown-Zähler mit Force-Quit-Funktionalität
|
|
|
|
Dieses Modul verwaltet System-Timer für verschiedene Anwendungsfälle:
|
|
- Kiosk-Timer für automatische Session-Beendigung
|
|
- Job-Timer für Druckaufträge mit Timeout
|
|
- Session-Timer für Benutzerinaktivität
|
|
- Wartungs-Timer für geplante System-Shutdowns
|
|
|
|
Autor: System
|
|
Erstellt: 2025
|
|
"""
|
|
|
|
import threading
|
|
import time
|
|
import json
|
|
import logging
|
|
from datetime import datetime, timedelta
|
|
from typing import Dict, List, Optional, Callable, Any
|
|
from enum import Enum
|
|
from contextlib import contextmanager
|
|
|
|
from models import SystemTimer, get_db_session, get_cached_session
|
|
from utils.logging_config import get_logger
|
|
|
|
logger = get_logger("timer_manager")
|
|
|
|
class TimerType(Enum):
|
|
"""Verfügbare Timer-Typen"""
|
|
KIOSK = "kiosk"
|
|
SESSION = "session"
|
|
JOB = "job"
|
|
SYSTEM = "system"
|
|
MAINTENANCE = "maintenance"
|
|
|
|
class ForceQuitAction(Enum):
|
|
"""Verfügbare Force-Quit-Aktionen"""
|
|
LOGOUT = "logout"
|
|
RESTART = "restart"
|
|
SHUTDOWN = "shutdown"
|
|
CUSTOM = "custom"
|
|
|
|
class TimerStatus(Enum):
|
|
"""Timer-Status-Werte"""
|
|
STOPPED = "stopped"
|
|
RUNNING = "running"
|
|
PAUSED = "paused"
|
|
EXPIRED = "expired"
|
|
FORCE_QUIT = "force_quit"
|
|
|
|
class TimerManager:
|
|
"""
|
|
Zentraler Timer-Manager für alle System-Timer.
|
|
Verwaltet Timer-Instanzen und führt automatische Cleanup-Operationen durch.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self._timers: Dict[str, SystemTimer] = {}
|
|
self._timer_callbacks: Dict[str, List[Callable]] = {}
|
|
self._force_quit_handlers: Dict[str, Callable] = {}
|
|
self._background_thread: Optional[threading.Thread] = None
|
|
self._shutdown_flag = threading.Event()
|
|
self._update_interval = 1.0 # Sekunden zwischen Updates
|
|
|
|
# Standard Force-Quit-Handler registrieren
|
|
self._register_default_handlers()
|
|
|
|
# Background-Thread für Timer-Updates starten
|
|
self._start_background_thread()
|
|
|
|
logger.info("Timer-Manager initialisiert")
|
|
|
|
def _register_default_handlers(self):
|
|
"""Registriert Standard-Handler für Force-Quit-Aktionen"""
|
|
|
|
def logout_handler(timer: SystemTimer) -> bool:
|
|
"""Standard-Handler für Logout-Aktion"""
|
|
try:
|
|
logger.info(f"Logout-Handler für Timer '{timer.name}' ausgeführt")
|
|
# Hier würde der tatsächliche Logout implementiert werden
|
|
# Das wird in app.py über die API-Endpunkte gemacht
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Fehler im Logout-Handler: {str(e)}")
|
|
return False
|
|
|
|
def restart_handler(timer: SystemTimer) -> bool:
|
|
"""Standard-Handler für System-Restart"""
|
|
try:
|
|
logger.warning(f"System-Restart durch Timer '{timer.name}' ausgelöst")
|
|
# Implementierung würde über System-API erfolgen
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Fehler im Restart-Handler: {str(e)}")
|
|
return False
|
|
|
|
def shutdown_handler(timer: SystemTimer) -> bool:
|
|
"""Standard-Handler für System-Shutdown"""
|
|
try:
|
|
logger.warning(f"System-Shutdown durch Timer '{timer.name}' ausgelöst")
|
|
# Implementierung würde über System-API erfolgen
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Fehler im Shutdown-Handler: {str(e)}")
|
|
return False
|
|
|
|
# Handler registrieren
|
|
self._force_quit_handlers[ForceQuitAction.LOGOUT.value] = logout_handler
|
|
self._force_quit_handlers[ForceQuitAction.RESTART.value] = restart_handler
|
|
self._force_quit_handlers[ForceQuitAction.SHUTDOWN.value] = shutdown_handler
|
|
|
|
def _start_background_thread(self):
|
|
"""Startet den Background-Thread für Timer-Updates"""
|
|
if self._background_thread is None or not self._background_thread.is_alive():
|
|
self._background_thread = threading.Thread(
|
|
target=self._background_worker,
|
|
name="TimerManager-Background",
|
|
daemon=True
|
|
)
|
|
self._background_thread.start()
|
|
logger.debug("Background-Thread für Timer-Updates gestartet")
|
|
|
|
def _background_worker(self):
|
|
"""Background-Worker für kontinuierliche Timer-Updates"""
|
|
logger.debug("Timer-Manager Background-Worker gestartet")
|
|
|
|
while not self._shutdown_flag.is_set():
|
|
try:
|
|
self._update_all_timers()
|
|
self._process_expired_timers()
|
|
|
|
# Warte bis zum nächsten Update
|
|
self._shutdown_flag.wait(self._update_interval)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler im Timer-Background-Worker: {str(e)}")
|
|
time.sleep(5) # Kurze Pause bei Fehlern
|
|
|
|
logger.debug("Timer-Manager Background-Worker beendet")
|
|
|
|
def _update_all_timers(self):
|
|
"""Aktualisiert alle Timer aus der Datenbank"""
|
|
try:
|
|
with get_cached_session() as session:
|
|
# Lade alle aktiven Timer aus der Datenbank
|
|
db_timers = session.query(SystemTimer).filter(
|
|
SystemTimer.status.in_([TimerStatus.RUNNING.value, TimerStatus.PAUSED.value])
|
|
).all()
|
|
|
|
# Update lokale Timer-Cache
|
|
current_timer_names = set(self._timers.keys())
|
|
db_timer_names = {timer.name for timer in db_timers}
|
|
|
|
# Entferne Timer die nicht mehr in der DB sind
|
|
for name in current_timer_names - db_timer_names:
|
|
if name in self._timers:
|
|
del self._timers[name]
|
|
logger.debug(f"Timer '{name}' aus lokalem Cache entfernt")
|
|
|
|
# Aktualisiere/füge Timer hinzu
|
|
for timer in db_timers:
|
|
self._timers[timer.name] = timer
|
|
|
|
# Callback-Funktionen aufrufen wenn verfügbar
|
|
if timer.name in self._timer_callbacks:
|
|
for callback in self._timer_callbacks[timer.name]:
|
|
try:
|
|
callback(timer)
|
|
except Exception as e:
|
|
logger.error(f"Fehler in Timer-Callback für '{timer.name}': {str(e)}")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Update der Timer: {str(e)}")
|
|
|
|
def _process_expired_timers(self):
|
|
"""Verarbeitet abgelaufene Timer und führt Force-Quit-Aktionen aus"""
|
|
try:
|
|
expired_timers = SystemTimer.get_expired_timers()
|
|
|
|
for timer in expired_timers:
|
|
try:
|
|
logger.warning(f"Timer '{timer.name}' ist abgelaufen - führe Force-Quit aus")
|
|
|
|
# Force-Quit-Aktion ausführen
|
|
success = self._execute_force_quit(timer)
|
|
|
|
if success:
|
|
# Timer als abgelaufen markieren
|
|
with get_cached_session() as session:
|
|
db_timer = session.query(SystemTimer).filter(
|
|
SystemTimer.id == timer.id
|
|
).first()
|
|
|
|
if db_timer:
|
|
db_timer.status = TimerStatus.EXPIRED.value
|
|
db_timer.updated_at = datetime.now()
|
|
session.commit()
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Verarbeiten des abgelaufenen Timers '{timer.name}': {str(e)}")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Verarbeiten abgelaufener Timer: {str(e)}")
|
|
|
|
def _execute_force_quit(self, timer: SystemTimer) -> bool:
|
|
"""Führt die Force-Quit-Aktion für einen Timer aus"""
|
|
try:
|
|
action = timer.force_quit_action
|
|
|
|
# Custom-Endpoint prüfen
|
|
if action == ForceQuitAction.CUSTOM.value and timer.custom_action_endpoint:
|
|
return self._execute_custom_action(timer)
|
|
|
|
# Standard-Handler verwenden
|
|
if action in self._force_quit_handlers:
|
|
handler = self._force_quit_handlers[action]
|
|
return handler(timer)
|
|
|
|
logger.warning(f"Unbekannte Force-Quit-Aktion: {action}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Ausführen der Force-Quit-Aktion für Timer '{timer.name}': {str(e)}")
|
|
return False
|
|
|
|
def _execute_custom_action(self, timer: SystemTimer) -> bool:
|
|
"""Führt eine benutzerdefinierte Force-Quit-Aktion aus"""
|
|
try:
|
|
# Hier würde ein HTTP-Request an den Custom-Endpoint gemacht werden
|
|
# Das wird über die Flask-App-Routen implementiert
|
|
logger.info(f"Custom-Action für Timer '{timer.name}': {timer.custom_action_endpoint}")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Fehler bei Custom-Action für Timer '{timer.name}': {str(e)}")
|
|
return False
|
|
|
|
def create_timer(self, name: str, timer_type: TimerType, duration_seconds: int,
|
|
force_quit_action: ForceQuitAction = ForceQuitAction.LOGOUT,
|
|
auto_start: bool = False, **kwargs) -> Optional[SystemTimer]:
|
|
"""
|
|
Erstellt einen neuen Timer.
|
|
|
|
Args:
|
|
name: Eindeutiger Name des Timers
|
|
timer_type: Typ des Timers
|
|
duration_seconds: Dauer in Sekunden
|
|
force_quit_action: Aktion bei Force-Quit
|
|
auto_start: Automatisch starten
|
|
**kwargs: Zusätzliche Timer-Konfiguration
|
|
|
|
Returns:
|
|
SystemTimer-Instanz oder None bei Fehler
|
|
"""
|
|
try:
|
|
with get_cached_session() as session:
|
|
# Prüfe ob Timer bereits existiert
|
|
existing = session.query(SystemTimer).filter(
|
|
SystemTimer.name == name
|
|
).first()
|
|
|
|
if existing:
|
|
logger.warning(f"Timer '{name}' existiert bereits")
|
|
return existing
|
|
|
|
# Neuen Timer erstellen
|
|
timer = SystemTimer(
|
|
name=name,
|
|
timer_type=timer_type.value,
|
|
duration_seconds=duration_seconds,
|
|
remaining_seconds=duration_seconds,
|
|
target_timestamp=datetime.now() + timedelta(seconds=duration_seconds),
|
|
force_quit_action=force_quit_action.value,
|
|
auto_start=auto_start,
|
|
**kwargs
|
|
)
|
|
|
|
session.add(timer)
|
|
session.commit()
|
|
|
|
# Zu lokalem Cache hinzufügen
|
|
self._timers[name] = timer
|
|
|
|
if auto_start:
|
|
timer.start_timer()
|
|
|
|
logger.info(f"Timer '{name}' erstellt - Typ: {timer_type.value}, Dauer: {duration_seconds}s")
|
|
return timer
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Erstellen des Timers '{name}': {str(e)}")
|
|
return None
|
|
|
|
def get_timer(self, name: str) -> Optional[SystemTimer]:
|
|
"""
|
|
Holt einen Timer anhand des Namens.
|
|
|
|
Args:
|
|
name: Name des Timers
|
|
|
|
Returns:
|
|
SystemTimer-Instanz oder None
|
|
"""
|
|
try:
|
|
# Erst aus lokalem Cache prüfen
|
|
if name in self._timers:
|
|
return self._timers[name]
|
|
|
|
# Aus Datenbank laden
|
|
timer = SystemTimer.get_by_name(name)
|
|
if timer:
|
|
self._timers[name] = timer
|
|
|
|
return timer
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Laden des Timers '{name}': {str(e)}")
|
|
return None
|
|
|
|
def start_timer(self, name: str) -> bool:
|
|
"""Startet einen Timer"""
|
|
try:
|
|
timer = self.get_timer(name)
|
|
if not timer:
|
|
logger.error(f"Timer '{name}' nicht gefunden")
|
|
return False
|
|
|
|
success = timer.start_timer()
|
|
|
|
if success:
|
|
with get_cached_session() as session:
|
|
# Timer in Datenbank aktualisieren
|
|
db_timer = session.merge(timer)
|
|
session.commit()
|
|
|
|
logger.info(f"Timer '{name}' gestartet")
|
|
|
|
return success
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Starten des Timers '{name}': {str(e)}")
|
|
return False
|
|
|
|
def pause_timer(self, name: str) -> bool:
|
|
"""Pausiert einen Timer"""
|
|
try:
|
|
timer = self.get_timer(name)
|
|
if not timer:
|
|
logger.error(f"Timer '{name}' nicht gefunden")
|
|
return False
|
|
|
|
success = timer.pause_timer()
|
|
|
|
if success:
|
|
with get_cached_session() as session:
|
|
db_timer = session.merge(timer)
|
|
session.commit()
|
|
|
|
logger.info(f"Timer '{name}' pausiert")
|
|
|
|
return success
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Pausieren des Timers '{name}': {str(e)}")
|
|
return False
|
|
|
|
def stop_timer(self, name: str) -> bool:
|
|
"""Stoppt einen Timer"""
|
|
try:
|
|
timer = self.get_timer(name)
|
|
if not timer:
|
|
logger.error(f"Timer '{name}' nicht gefunden")
|
|
return False
|
|
|
|
success = timer.stop_timer()
|
|
|
|
if success:
|
|
with get_cached_session() as session:
|
|
db_timer = session.merge(timer)
|
|
session.commit()
|
|
|
|
logger.info(f"Timer '{name}' gestoppt")
|
|
|
|
return success
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Stoppen des Timers '{name}': {str(e)}")
|
|
return False
|
|
|
|
def reset_timer(self, name: str) -> bool:
|
|
"""Setzt einen Timer zurück"""
|
|
try:
|
|
timer = self.get_timer(name)
|
|
if not timer:
|
|
logger.error(f"Timer '{name}' nicht gefunden")
|
|
return False
|
|
|
|
success = timer.reset_timer()
|
|
|
|
if success:
|
|
with get_cached_session() as session:
|
|
db_timer = session.merge(timer)
|
|
session.commit()
|
|
|
|
logger.info(f"Timer '{name}' zurückgesetzt")
|
|
|
|
return success
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Zurücksetzen des Timers '{name}': {str(e)}")
|
|
return False
|
|
|
|
def extend_timer(self, name: str, additional_seconds: int) -> bool:
|
|
"""Verlängert einen Timer"""
|
|
try:
|
|
timer = self.get_timer(name)
|
|
if not timer:
|
|
logger.error(f"Timer '{name}' nicht gefunden")
|
|
return False
|
|
|
|
success = timer.extend_timer(additional_seconds)
|
|
|
|
if success:
|
|
with get_cached_session() as session:
|
|
db_timer = session.merge(timer)
|
|
session.commit()
|
|
|
|
logger.info(f"Timer '{name}' um {additional_seconds} Sekunden verlängert")
|
|
|
|
return success
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Verlängern des Timers '{name}': {str(e)}")
|
|
return False
|
|
|
|
def delete_timer(self, name: str) -> bool:
|
|
"""Löscht einen Timer"""
|
|
try:
|
|
with get_cached_session() as session:
|
|
timer = session.query(SystemTimer).filter(
|
|
SystemTimer.name == name
|
|
).first()
|
|
|
|
if not timer:
|
|
logger.error(f"Timer '{name}' nicht gefunden")
|
|
return False
|
|
|
|
session.delete(timer)
|
|
session.commit()
|
|
|
|
# Aus lokalem Cache entfernen
|
|
if name in self._timers:
|
|
del self._timers[name]
|
|
|
|
# Callbacks entfernen
|
|
if name in self._timer_callbacks:
|
|
del self._timer_callbacks[name]
|
|
|
|
logger.info(f"Timer '{name}' gelöscht")
|
|
return True
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Löschen des Timers '{name}': {str(e)}")
|
|
return False
|
|
|
|
def register_callback(self, timer_name: str, callback: Callable[[SystemTimer], None]):
|
|
"""
|
|
Registriert eine Callback-Funktion für Timer-Updates.
|
|
|
|
Args:
|
|
timer_name: Name des Timers
|
|
callback: Callback-Funktion die bei Updates aufgerufen wird
|
|
"""
|
|
if timer_name not in self._timer_callbacks:
|
|
self._timer_callbacks[timer_name] = []
|
|
|
|
self._timer_callbacks[timer_name].append(callback)
|
|
logger.debug(f"Callback für Timer '{timer_name}' registriert")
|
|
|
|
def register_force_quit_handler(self, action: str, handler: Callable[[SystemTimer], bool]):
|
|
"""
|
|
Registriert einen benutzerdefinierten Force-Quit-Handler.
|
|
|
|
Args:
|
|
action: Name der Aktion
|
|
handler: Handler-Funktion
|
|
"""
|
|
self._force_quit_handlers[action] = handler
|
|
logger.debug(f"Force-Quit-Handler für Aktion '{action}' registriert")
|
|
|
|
def get_all_timers(self) -> List[SystemTimer]:
|
|
"""Gibt alle Timer zurück"""
|
|
try:
|
|
with get_cached_session() as session:
|
|
timers = session.query(SystemTimer).all()
|
|
return timers
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Laden aller Timer: {str(e)}")
|
|
return []
|
|
|
|
def get_timers_by_type(self, timer_type: TimerType) -> List[SystemTimer]:
|
|
"""Gibt alle Timer eines bestimmten Typs zurück"""
|
|
try:
|
|
return SystemTimer.get_by_type(timer_type.value)
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Laden der Timer vom Typ '{timer_type.value}': {str(e)}")
|
|
return []
|
|
|
|
def get_running_timers(self) -> List[SystemTimer]:
|
|
"""Gibt alle laufenden Timer zurück"""
|
|
try:
|
|
return SystemTimer.get_running_timers()
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Laden der laufenden Timer: {str(e)}")
|
|
return []
|
|
|
|
def create_kiosk_timer(self, duration_minutes: int = 30, auto_start: bool = True) -> Optional[SystemTimer]:
|
|
"""
|
|
Erstellt einen Standard-Kiosk-Timer.
|
|
|
|
Args:
|
|
duration_minutes: Timer-Dauer in Minuten
|
|
auto_start: Automatisch starten
|
|
|
|
Returns:
|
|
SystemTimer-Instanz oder None
|
|
"""
|
|
return self.create_timer(
|
|
name="kiosk_session",
|
|
timer_type=TimerType.KIOSK,
|
|
duration_seconds=duration_minutes * 60,
|
|
force_quit_action=ForceQuitAction.LOGOUT,
|
|
auto_start=auto_start,
|
|
force_quit_warning_seconds=30,
|
|
show_warning=True,
|
|
warning_message="Kiosk-Session läuft ab. Bitte speichern Sie Ihre Arbeit."
|
|
)
|
|
|
|
def create_session_timer(self, user_id: int, duration_minutes: int = 120,
|
|
auto_start: bool = True) -> Optional[SystemTimer]:
|
|
"""
|
|
Erstellt einen Session-Timer für einen Benutzer.
|
|
|
|
Args:
|
|
user_id: Benutzer-ID
|
|
duration_minutes: Timer-Dauer in Minuten
|
|
auto_start: Automatisch starten
|
|
|
|
Returns:
|
|
SystemTimer-Instanz oder None
|
|
"""
|
|
return self.create_timer(
|
|
name=f"session_{user_id}",
|
|
timer_type=TimerType.SESSION,
|
|
duration_seconds=duration_minutes * 60,
|
|
force_quit_action=ForceQuitAction.LOGOUT,
|
|
auto_start=auto_start,
|
|
context_id=user_id,
|
|
force_quit_warning_seconds=60,
|
|
show_warning=True,
|
|
warning_message="Ihre Session läuft ab. Aktivität erforderlich."
|
|
)
|
|
|
|
def update_session_activity(self, user_id: int) -> bool:
|
|
"""
|
|
Aktualisiert die Aktivität eines Session-Timers.
|
|
|
|
Args:
|
|
user_id: Benutzer-ID
|
|
|
|
Returns:
|
|
True wenn erfolgreich
|
|
"""
|
|
try:
|
|
timer = self.get_timer(f"session_{user_id}")
|
|
if timer and timer.timer_type == TimerType.SESSION.value:
|
|
success = timer.update_activity()
|
|
|
|
if success:
|
|
with get_cached_session() as session:
|
|
db_timer = session.merge(timer)
|
|
session.commit()
|
|
|
|
return success
|
|
|
|
return False
|
|
|
|
except Exception as e:
|
|
logger.error(f"Fehler beim Aktualisieren der Session-Aktivität für User {user_id}: {str(e)}")
|
|
return False
|
|
|
|
def shutdown(self):
|
|
"""Beendet den Timer-Manager sauber"""
|
|
logger.info("Timer-Manager wird heruntergefahren...")
|
|
|
|
self._shutdown_flag.set()
|
|
|
|
if self._background_thread and self._background_thread.is_alive():
|
|
self._background_thread.join(timeout=5)
|
|
|
|
self._timers.clear()
|
|
self._timer_callbacks.clear()
|
|
|
|
logger.info("Timer-Manager heruntergefahren")
|
|
|
|
|
|
# Globale Timer-Manager-Instanz
|
|
_timer_manager: Optional[TimerManager] = None
|
|
|
|
def get_timer_manager() -> TimerManager:
|
|
"""
|
|
Gibt die globale Timer-Manager-Instanz zurück.
|
|
Thread-sicher mit Lazy Loading.
|
|
"""
|
|
global _timer_manager
|
|
|
|
if _timer_manager is None:
|
|
_timer_manager = TimerManager()
|
|
|
|
return _timer_manager
|
|
|
|
def init_timer_manager() -> TimerManager:
|
|
"""
|
|
Initialisiert den Timer-Manager explizit.
|
|
Sollte beim App-Start aufgerufen werden.
|
|
"""
|
|
return get_timer_manager()
|
|
|
|
def shutdown_timer_manager():
|
|
"""
|
|
Beendet den Timer-Manager sauber.
|
|
Sollte beim App-Shutdown aufgerufen werden.
|
|
"""
|
|
global _timer_manager
|
|
|
|
if _timer_manager:
|
|
_timer_manager.shutdown()
|
|
_timer_manager = None
|
|
|
|
# Convenience-Funktionen für häufige Timer-Operationen
|
|
def create_kiosk_timer(duration_minutes: int = 30, auto_start: bool = True) -> Optional[SystemTimer]:
|
|
"""Erstellt einen Kiosk-Timer"""
|
|
return get_timer_manager().create_kiosk_timer(duration_minutes, auto_start)
|
|
|
|
def create_session_timer(user_id: int, duration_minutes: int = 120) -> Optional[SystemTimer]:
|
|
"""Erstellt einen Session-Timer"""
|
|
return get_timer_manager().create_session_timer(user_id, duration_minutes)
|
|
|
|
def start_timer(name: str) -> bool:
|
|
"""Startet einen Timer"""
|
|
return get_timer_manager().start_timer(name)
|
|
|
|
def pause_timer(name: str) -> bool:
|
|
"""Pausiert einen Timer"""
|
|
return get_timer_manager().pause_timer(name)
|
|
|
|
def stop_timer(name: str) -> bool:
|
|
"""Stoppt einen Timer"""
|
|
return get_timer_manager().stop_timer(name)
|
|
|
|
def reset_timer(name: str) -> bool:
|
|
"""Setzt einen Timer zurück"""
|
|
return get_timer_manager().reset_timer(name)
|
|
|
|
def extend_timer(name: str, additional_seconds: int) -> bool:
|
|
"""Verlängert einen Timer"""
|
|
return get_timer_manager().extend_timer(name, additional_seconds)
|
|
|
|
def get_timer_status(name: str) -> Optional[Dict[str, Any]]:
|
|
"""Gibt den Status eines Timers zurück"""
|
|
timer = get_timer_manager().get_timer(name)
|
|
return timer.to_dict() if timer else None
|
|
|
|
def update_session_activity(user_id: int) -> bool:
|
|
"""Aktualisiert Session-Aktivität"""
|
|
return get_timer_manager().update_session_activity(user_id) |