Backup automatico script del 2026-07-12 07:00
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user