Backup automatico script del 2026-01-25 07:00

This commit is contained in:
2026-01-25 07:00:03 +01:00
parent 9dbe0cfa93
commit f0c5672607
16 changed files with 241 additions and 61 deletions

View File

@@ -1,5 +1,6 @@
import argparse
import requests
from open_meteo_client import open_meteo_get
import datetime
import os
import sys
@@ -77,31 +78,68 @@ def get_bot_token():
sys.exit(1)
def save_current_state(state):
def save_current_state(state, report_meta=None):
try:
# Aggiungi timestamp corrente per tracciare quando è stato salvato lo stato
if report_meta is None:
report_meta = {}
state_with_meta = {
"points": state,
"last_update": datetime.datetime.now().isoformat()
"last_update": datetime.datetime.now().isoformat(),
"report_meta": report_meta,
}
with open(STATE_FILE, 'w') as f:
json.dump(state_with_meta, f)
except Exception as e:
print(f"Errore salvataggio stato: {e}")
def load_previous_state():
def load_state_with_meta():
if not os.path.exists(STATE_FILE):
return {}
return {}, {}
try:
with open(STATE_FILE, 'r') as f:
data = json.load(f)
# Supporta sia il formato vecchio (solo dict di punti) che nuovo (con metadata)
if isinstance(data, dict) and "points" in data:
return data["points"]
return data.get("points", {}), data.get("report_meta", {})
else:
return data
return data, {}
except Exception:
return {}
return {}, {}
def normalize_report_meta(report_meta: dict) -> dict:
today = datetime.date.today().isoformat()
date_str = report_meta.get("date")
count = report_meta.get("count", 0)
if date_str != today:
return {"date": today, "count": 0}
try:
count = int(count)
except Exception:
count = 0
return {"date": today, "count": max(0, count)}
def is_important_update(new_level: int, old_level: int, message: str) -> bool:
# Importante se rischio alto (gelicidio) o neve su strada (livello 4).
if max(new_level, old_level) >= 3:
return True
lowered = (message or "").lower()
return "gelicidio" in lowered or "neve" in lowered
def append_report(target_list: list, message: str, important: bool, report_meta: dict, debug_mode: bool) -> None:
DAILY_LIMIT = 3
if important:
target_list.append(message)
return
if report_meta.get("count", 0) >= DAILY_LIMIT:
if debug_mode:
print(" ⏸️ Report non importante saltato: limite giornaliero raggiunto")
return
target_list.append(message)
report_meta["count"] = report_meta.get("count", 0) + 1
def is_improvement_report_allowed() -> bool:
"""
@@ -151,7 +189,7 @@ def get_weather_data(lat, lon, model_slug, include_past_days=1):
params["minutely_15"] = "temperature_2m,precipitation,rain,snowfall"
try:
response = requests.get(url, params=params, timeout=15)
response = open_meteo_get(url, params=params, timeout=(5, 15))
response.raise_for_status()
return response.json()
except Exception as e:
@@ -1121,7 +1159,7 @@ def get_coordinates_from_city(city_name: str) -> Optional[Tuple[float, float, st
url = "https://geocoding-api.open-meteo.com/v1/search"
try:
resp = requests.get(url, params={"name": city_name, "count": 1, "language": "it", "format": "json"}, timeout=5)
resp = open_meteo_get(url, params={"name": city_name, "count": 1, "language": "it", "format": "json"}, timeout=(5, 10))
res = resp.json().get("results", [])
if res:
res = res[0]
@@ -1926,7 +1964,8 @@ def main():
DEBUG_MODE = args.debug
token = get_bot_token()
previous_state = load_previous_state()
previous_state, report_meta = load_state_with_meta()
report_meta = normalize_report_meta(report_meta)
current_state = {}
new_alerts = []
@@ -2074,7 +2113,8 @@ def main():
for detail in past_24h_details:
final_msg += f"{detail}\n"
new_alerts.append(final_msg)
important = is_important_update(max_risk_level, old_level, final_msg)
append_report(new_alerts, final_msg, important, report_meta, DEBUG_MODE)
# 3. Rischio Cessato (Tutti i modelli danno verde)
# IMPORTANTE: Non inviare "allerta rientrata" se ci sono ancora condizioni che mantengono il ghiaccio
@@ -2129,7 +2169,8 @@ def main():
# Non aggiungere a solved_alerts - il ghiaccio potrebbe ancora essere presente
# Ma potremmo inviare un messaggio informativo se in debug mode
if DEBUG_MODE:
new_alerts.append(persist_msg)
important = is_important_update(max_risk_level, old_level, persist_msg)
append_report(new_alerts, persist_msg, important, report_meta, DEBUG_MODE)
else:
# Condizioni completamente risolte: neve sciolta e temperature sopra lo zero
if DEBUG_MODE:
@@ -2153,7 +2194,8 @@ def main():
solved_msg += f" (Scioglimento confermato: {', '.join(melting_info)})"
else:
solved_msg += " (Tutti i modelli)"
solved_alerts.append(solved_msg)
important = is_important_update(max_risk_level, old_level, solved_msg)
append_report(solved_alerts, solved_msg, important, report_meta, DEBUG_MODE)
# 4. Rischio Diminuito (es. Da Ghiaccio a Brina, o da Brina a nessun rischio ma non ancora 0)
elif max_risk_level < old_level and max_risk_level > 0:
@@ -2191,7 +2233,8 @@ def main():
for detail in past_24h_details:
improvement_msg += f"{detail}\n"
new_alerts.append(improvement_msg)
important = is_important_update(max_risk_level, old_level, improvement_msg)
append_report(new_alerts, improvement_msg, important, report_meta, DEBUG_MODE)
# Genera e invia mappa solo quando ci sono aggiornamenti
if new_alerts or solved_alerts:
@@ -2231,7 +2274,7 @@ def main():
print("Nessuna variazione.")
if not DEBUG_MODE:
save_current_state(current_state)
save_current_state(current_state, report_meta=report_meta)
if __name__ == "__main__":
main()