Backup automatico script del 2026-07-12 07:00

This commit is contained in:
2026-07-12 07:00:03 +02:00
parent b5a2a814e2
commit 927f0d4184
18 changed files with 2365 additions and 422 deletions
+105 -7
View File
@@ -115,13 +115,19 @@ def setup_logger() -> logging.Logger:
logger.setLevel(logging.DEBUG if DEBUG else logging.INFO)
logger.handlers.clear()
fh = RotatingFileHandler(LOG_FILE, maxBytes=1_000_000, backupCount=5, encoding="utf-8")
fh.setLevel(logging.DEBUG)
fmt = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
fh.setFormatter(fmt)
logger.addHandler(fh)
log_path = os.environ.get("SNOW_RADAR_LOG", LOG_FILE)
try:
fh = RotatingFileHandler(log_path, maxBytes=1_000_000, backupCount=5, encoding="utf-8")
fh.setLevel(logging.DEBUG)
fh.setFormatter(fmt)
logger.addHandler(fh)
except OSError:
sh = logging.StreamHandler()
sh.setFormatter(fmt)
logger.addHandler(sh)
if DEBUG:
if DEBUG and not any(isinstance(h, logging.StreamHandler) for h in logger.handlers):
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
sh.setFormatter(fmt)
@@ -779,14 +785,106 @@ def main(chat_ids: Optional[List[str]] = None, debug_mode: bool = False, chat_id
LOGGER.error("Errore generazione mappe")
def collect_snow_radar_results(session) -> Tuple[List[Dict], List[Dict]]:
"""Analizza tutte le località; ritorna (tutte le analisi, subset per mappe)."""
now = now_local()
center_lat, center_lon = 43.9356, 12.4296
all_rows: List[Dict] = []
map_results: List[Dict] = []
for i, loc in enumerate(LOCATIONS):
distance_km = calculate_distance_km(center_lat, center_lon, loc["lat"], loc["lon"])
data = get_forecast(session, loc["lat"], loc["lon"])
if not data:
continue
snow_analysis = analyze_snowfall_for_location(data, now)
if not snow_analysis:
continue
is_casa = loc["name"] == "Casa (Strada Cà Toro)"
has_snow = (
snow_analysis["snow_past_12h"] >= SNOW_THRESHOLD_CM
or snow_analysis["snow_next_12h"] >= SNOW_THRESHOLD_CM
or snow_analysis["snow_next_24h"] >= SNOW_THRESHOLD_CM
)
row = {
"name": loc["name"],
"lat": loc["lat"],
"lon": loc["lon"],
"distance_km": distance_km,
"has_snow": has_snow,
**snow_analysis,
}
all_rows.append(row)
if is_casa or has_snow:
map_results.append(row)
time.sleep(0.1)
return all_rows, map_results
def build_snow_radar_json(maps_dir: Optional[str] = None) -> Dict:
"""Analisi completa per WebApp (senza Telegram)."""
now = now_local()
center_lat, center_lon = 43.9356, 12.4296
total = len(LOCATIONS)
with requests.Session() as session:
configure_open_meteo_session(session, headers=HTTP_HEADERS)
all_rows, map_results = collect_snow_radar_results(session)
count_past = sum(1 for r in all_rows if r.get("snow_past_12h", 0) >= SNOW_THRESHOLD_CM)
count_future = sum(1 for r in all_rows if r.get("snow_next_24h", 0) >= SNOW_THRESHOLD_CM)
active = count_past > 0 or count_future > 0
payload: Dict = {
"active": active,
"updated_at": now.strftime("%d/%m/%Y %H:%M"),
"total_locations": total,
"count_past_12h": count_past,
"count_next_24h": count_future,
"locations": [
{
"name": r["name"],
"snow_past_12h": round(float(r.get("snow_past_12h", 0)), 1),
"snow_next_24h": round(float(r.get("snow_next_24h", 0)), 1),
"has_snow": bool(r.get("has_snow")),
}
for r in sorted(all_rows, key=lambda x: (-x.get("snow_next_24h", 0), x["name"]))
if r.get("has_snow")
],
"maps": {"past": None, "future": None},
}
if active and maps_dir:
os.makedirs(maps_dir, exist_ok=True)
past_path = os.path.join(maps_dir, "snow_radar_past.png")
future_path = os.path.join(maps_dir, "snow_radar_future.png")
if generate_snow_map(map_results, center_lat, center_lon, past_path,
data_field="snow_past_12h", title_suffix=" - Ultime 12h"):
payload["maps"]["past"] = "past"
if generate_snow_map(map_results, center_lat, center_lon, future_path,
data_field="snow_next_24h", title_suffix=" - Prossime 24h"):
payload["maps"]["future"] = "future"
return payload
if __name__ == "__main__":
arg_parser = argparse.ArgumentParser(description="Snow Radar - Analisi neve in griglia 30km")
arg_parser.add_argument("--debug", action="store_true", help="Invia messaggi solo all'admin (chat ID: %s)" % TELEGRAM_CHAT_IDS[0])
arg_parser.add_argument("--chat_id", type=str, help="Chat ID specifico per invio messaggio (override debug mode)")
arg_parser.add_argument("--json", action="store_true", help="Output JSON per WebApp (no Telegram)")
arg_parser.add_argument("--maps-dir", type=str, default="", help="Directory per salvare mappe PNG (con --json)")
args = arg_parser.parse_args()
if args.json:
maps_dir = args.maps_dir.strip() or None
print(json.dumps(build_snow_radar_json(maps_dir=maps_dir), ensure_ascii=False))
raise SystemExit(0)
# Se --chat_id è specificato, usa quello; altrimenti usa logica debug
chat_id = args.chat_id if args.chat_id else None
chat_ids = None if chat_id else ([TELEGRAM_CHAT_IDS[0]] if args.debug else None)
main(chat_ids=chat_ids, debug_mode=args.debug, chat_id=chat_id)