Backup automatico script del 2026-01-11 07:00
This commit is contained in:
120
services/telegram-bot/scheduler_viaggi.py
Normal file
120
services/telegram-bot/scheduler_viaggi.py
Normal file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Scheduler dinamico per viaggi attivi
|
||||
- Lancia meteo.py alle 8:00 AM local time per ogni viaggio attivo
|
||||
- Lancia previsione7.py alle 7:30 AM local time per ogni viaggio attivo
|
||||
- Gestisce fusi orari diversi per ogni località
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
import datetime
|
||||
from zoneinfo import ZoneInfo
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
# PERCORSI SCRIPT
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
METEO_SCRIPT = os.path.join(SCRIPT_DIR, "meteo.py")
|
||||
METEO7_SCRIPT = os.path.join(SCRIPT_DIR, "previsione7.py")
|
||||
VIAGGI_STATE_FILE = os.path.join(SCRIPT_DIR, "viaggi_attivi.json")
|
||||
|
||||
def load_viaggi_state() -> Dict:
|
||||
"""Carica lo stato dei viaggi attivi da file JSON"""
|
||||
if os.path.exists(VIAGGI_STATE_FILE):
|
||||
try:
|
||||
with open(VIAGGI_STATE_FILE, "r", encoding="utf-8") as f:
|
||||
return json.load(f) or {}
|
||||
except Exception as e:
|
||||
print(f"Errore lettura viaggi state: {e}")
|
||||
return {}
|
||||
return {}
|
||||
|
||||
def get_next_scheduled_time(target_hour: int, target_minute: int, timezone_str: str) -> Tuple[datetime.datetime, bool]:
|
||||
"""
|
||||
Calcola il prossimo orario schedulato in UTC per un target locale.
|
||||
|
||||
Args:
|
||||
target_hour: Ora target (0-23)
|
||||
target_minute: Minuto target (0-59)
|
||||
timezone_str: Timezone IANA (es: "Europe/Rome")
|
||||
|
||||
Returns:
|
||||
(datetime UTC, should_run_now): True se dovrebbe essere eseguito ora
|
||||
"""
|
||||
try:
|
||||
tz = ZoneInfo(timezone_str)
|
||||
now_utc = datetime.datetime.now(datetime.timezone.utc)
|
||||
now_local = now_utc.astimezone(tz)
|
||||
|
||||
# Crea datetime target per oggi
|
||||
target_local = now_local.replace(hour=target_hour, minute=target_minute, second=0, microsecond=0)
|
||||
|
||||
# Se l'orario è già passato oggi, programma per domani
|
||||
if now_local >= target_local:
|
||||
target_local += datetime.timedelta(days=1)
|
||||
|
||||
# Converti in UTC
|
||||
target_utc = target_local.astimezone(datetime.timezone.utc)
|
||||
|
||||
# Verifica se dovrebbe essere eseguito ora (entro 5 minuti)
|
||||
time_diff = (target_utc - now_utc).total_seconds()
|
||||
should_run_now = 0 <= time_diff <= 300 # Entro 5 minuti
|
||||
|
||||
return target_utc, should_run_now
|
||||
except Exception as e:
|
||||
print(f"Errore calcolo orario per {timezone_str}: {e}")
|
||||
return None, False
|
||||
|
||||
def launch_meteo_viaggio(chat_id: str, viaggio: Dict, script_type: str = "meteo") -> None:
|
||||
"""Lancia meteo.py o previsione7.py per un viaggio attivo"""
|
||||
lat = viaggio.get("lat")
|
||||
lon = viaggio.get("lon")
|
||||
location = viaggio.get("location")
|
||||
name = viaggio.get("name")
|
||||
timezone = viaggio.get("timezone", "Europe/Rome")
|
||||
|
||||
if script_type == "meteo":
|
||||
script = METEO_SCRIPT
|
||||
args = ["--query", location, "--chat_id", chat_id, "--timezone", timezone]
|
||||
elif script_type == "meteo7":
|
||||
script = METEO7_SCRIPT
|
||||
args = [location, "--chat_id", chat_id, "--timezone", timezone]
|
||||
else:
|
||||
return
|
||||
|
||||
try:
|
||||
subprocess.Popen(["python3", script] + args)
|
||||
print(f"✅ Lanciato {script_type} per chat_id={chat_id}, località={name}, timezone={timezone}")
|
||||
except Exception as e:
|
||||
print(f"❌ Errore lancio {script_type} per chat_id={chat_id}: {e}")
|
||||
|
||||
def check_and_launch_scheduled() -> None:
|
||||
"""Controlla e lancia gli script schedulati per tutti i viaggi attivi"""
|
||||
viaggi = load_viaggi_state()
|
||||
if not viaggi:
|
||||
return
|
||||
|
||||
now_utc = datetime.datetime.now(datetime.timezone.utc)
|
||||
|
||||
for chat_id, viaggio in viaggi.items():
|
||||
timezone = viaggio.get("timezone", "Europe/Rome")
|
||||
name = viaggio.get("name", "Unknown")
|
||||
|
||||
# Controlla meteo.py (8:00 AM local time)
|
||||
target_utc_meteo, should_run_meteo = get_next_scheduled_time(8, 0, timezone)
|
||||
if should_run_meteo:
|
||||
print(f"🕐 Eseguendo meteo.py per {name} (chat_id={chat_id}) alle 8:00 {timezone}")
|
||||
launch_meteo_viaggio(chat_id, viaggio, "meteo")
|
||||
|
||||
# Controlla previsione7.py (7:30 AM local time)
|
||||
target_utc_meteo7, should_run_meteo7 = get_next_scheduled_time(7, 30, timezone)
|
||||
if should_run_meteo7:
|
||||
print(f"🕐 Eseguendo previsione7.py per {name} (chat_id={chat_id}) alle 7:30 {timezone}")
|
||||
launch_meteo_viaggio(chat_id, viaggio, "meteo7")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Questo script dovrebbe essere eseguito periodicamente (es. ogni 5 minuti) da Portainer
|
||||
# Controlla se ci sono viaggi attivi che devono essere eseguiti ora
|
||||
check_and_launch_scheduled()
|
||||
Reference in New Issue
Block a user