vigilancia: panorama con autoborrado en Telegram a los 10min (proceso separado) - PANORAMA_DELETE_AFTER

This commit is contained in:
minguezsanzjuanjose
2026-08-03 00:31:02 +02:00
parent 668d4337bf
commit 9c97a6474f
2 changed files with 112 additions and 0 deletions

110
vigilancia/panorama.py Normal file
View File

@@ -0,0 +1,110 @@
#!/usr/bin/env python3
import json
import os
import subprocess
import sys
from datetime import datetime
import requests
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import config
# Segundos tras los que se borran las fotos del panorama en Telegram (default 10 min)
DELETE_AFTER = int(os.getenv("PANORAMA_DELETE_AFTER", "600"))
if not config.CAMARAS:
print("No hay cámaras configuradas")
sys.exit(1)
def programar_borrado(message_ids):
"""Borra los mensajes (fotos del panorama) tras DELETE_AFTER segundos.
Se lanza en un proceso separado para que sobreviva al cierre de este script."""
codigo = (
"import time, requests\n"
f"time.sleep({DELETE_AFTER})\n"
f"chat={config.TELEGRAM_CHAT_ID!r}\n"
f"ids={list(message_ids)!r}\n"
f"tok={config.TELEGRAM_TOKEN!r}\n"
"for mid in ids:\n"
" try:\n"
" requests.post('https://api.telegram.org/bot'+tok+'/deleteMessage',"
" data={'chat_id': chat, 'message_id': mid}, timeout=10)\n"
" print('borrado', mid)\n"
" except Exception as e:\n"
" print('err', mid, e)\n"
)
subprocess.Popen(["python3", "-c", codigo],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
start_new_session=True,
creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0))
def capturar_snapshot():
os.makedirs(config.SNAPSHOT_DIR, exist_ok=True)
resultados = []
for cam in config.CAMARAS:
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
ruta = os.path.join(config.SNAPSHOT_DIR, f"panorama_{cam['nombre']}_{ts}.jpg")
cmd = ["ffmpeg", "-i", cam["rtsp"], "-frames:v", "1", "-q:v", "2",
"-y", "-hide_banner", "-loglevel", "error", ruta]
try:
subprocess.run(cmd, timeout=15, check=True)
print(f"[{cam['nombre']}] Snapshot: {ruta}")
resultados.append((cam["nombre"], ruta))
except Exception as e:
print(f"[{cam['nombre']}] Error: {e}")
return resultados
def enviar_album(fotos):
if not fotos:
print("No hay fotos para enviar")
return
if len(fotos) == 1:
nombre, ruta = fotos[0]
url = f"https://api.telegram.org/bot{config.TELEGRAM_TOKEN}/sendPhoto"
try:
with open(ruta, "rb") as f:
r = requests.post(url,
data={"chat_id": config.TELEGRAM_CHAT_ID,
"caption": f"📷 {nombre}{datetime.now().strftime('%H:%M:%S')}"},
files={"photo": f}, timeout=30)
print(f"Foto enviada: HTTP {r.status_code}")
if r.status_code == 200:
programar_borrado([r.json()["result"]["message_id"]])
except Exception as e:
print(f"Error: {e}")
else:
url = f"https://api.telegram.org/bot{config.TELEGRAM_TOKEN}/sendMediaGroup"
media = []
files_dict = {}
for i, (nombre, ruta) in enumerate(fotos):
media.append({
"type": "photo",
"media": f"attach://{i}",
"caption": f"📷 {nombre}{datetime.now().strftime('%H:%M:%S')}"
})
files_dict[str(i)] = open(ruta, "rb")
try:
r = requests.post(url, data={"chat_id": config.TELEGRAM_CHAT_ID,
"media": json.dumps(media)}, files=files_dict, timeout=30)
print(f"Album enviado: HTTP {r.status_code}")
if r.status_code == 200:
ids = [m["message_id"] for m in r.json()["result"]]
print(f"Borrado programado dentro de {DELETE_AFTER}s para {len(ids)} foto(s)")
programar_borrado(ids)
else:
print(f"Error: {r.text[:300]}")
except Exception as e:
print(f"Error: {e}")
finally:
for f in files_dict.values():
f.close()
if __name__ == "__main__":
print("Capturando snapshots...")
fotos = capturar_snapshot()
if fotos:
print(f"Enviando {len(fotos)} foto(s) a IDD...")
enviar_album(fotos)
else:
print("No se capturaron fotos")