06-sep: [parental] Bloquear dispositivo: inventario vivo con toggle por numero + alias TV/Xbox

This commit is contained in:
juanjo
2026-09-06 15:06:20 +02:00
parent 2801d2a412
commit df1f7f0d93
2 changed files with 142 additions and 0 deletions

View File

@@ -35,8 +35,20 @@ DEVICE_ALIASES = {
"carolina": {"name": "Caroline-tablet", "mac": "3A:99:2B:ED:D3:5E"},
"caroline": {"name": "Caroline-tablet", "mac": "3A:99:2B:ED:D3:5E"},
"caroline tablet": {"name": "Caroline-tablet", "mac": "3A:99:2B:ED:D3:5E"},
"tele": {"name": "Tele", "mac": "14:EA:63:1D:1B:25"},
"television": {"name": "Tele", "mac": "14:EA:63:1D:1B:25"},
"tv salon": {"name": "Tele", "mac": "14:EA:63:1D:1B:25"},
"xbox": {"name": "XBOX", "mac": "A8:8C:3E:7C:F3:C7"},
}
TIPOS = (
("📺", ("tele", "tv", "samsung", "lg", "androidtv", "bravia", "philips")),
("🎮", ("xbox", "playstation", "ps4", "ps5", "nintendo", "switch")),
("📱", ("iphone", "android", "galaxy", "xiaomi", "redmi", "pixel")),
("💻", ("pc", "laptop", "minguez", "juanjer", "nahid")),
("🏠", ("tapo", "dreame", "vacuum", "echo", "alexa", "google", "nest")),
)
def _env(name, default=""):
return os.getenv(name, FILE_ENV.get(name, default)).strip()
@@ -186,6 +198,79 @@ def fijar_bloqueos(cambios):
return _leer_reglas()
def _icono(nombre):
n = normalizar_nombre(nombre)
for icono, claves in TIPOS:
if any(c in n for c in claves):
return icono
return "🔌"
def listar_dispositivos(limite=14):
"""Inventario vivo: leases DHCP + alias conocidos + estado de bloqueo.
Devuelve lista de dicts (nombre, mac, ip, tipo, bloqueado)."""
try:
from router_control import _inventario, _nombre_por_mac
except Exception:
return []
try:
devices, _by_mac = _inventario()
except Exception:
devices = []
try:
reglas = _leer_reglas()
except Exception:
reglas = {}
vistos, salida = set(), []
for ip, mac, nombre in devices:
if mac in vistos:
continue
vistos.add(mac)
bonito = nombre
try:
bonito = _nombre_por_mac(mac)
except Exception:
pass
if bonito in ("pendiente-identificar", "*"):
bonito = nombre
salida.append({
"nombre": bonito, "mac": mac, "ip": ip,
"tipo": _icono(f"{bonito} {nombre}"),
"bloqueado": mac in reglas,
})
for alias, info in DEVICE_ALIASES.items():
if info["mac"] in vistos:
continue
vistos.add(info["mac"])
salida.append({
"nombre": f"{info['name']} (alias)", "mac": info["mac"],
"ip": "", "tipo": _icono(info["name"]),
"bloqueado": info["mac"] in reglas,
})
orden = {"📺": 0, "🎮": 1, "📱": 2, "💻": 3, "🏠": 4, "🔌": 5}
salida.sort(key=lambda d: (orden.get(d["tipo"], 9),
d["bloqueado"], d["nombre"].lower()))
return salida[:limite]
def bloquear_mac(mac, blocked, nombre=""):
"""Bloquea/desbloquea por MAC directa (regla 24/7 + iptables + verif)."""
from router_control import bloqueo_red
mac = (mac or "").upper()
if not mac:
raise ValueError("MAC vacia")
fijar_bloqueos([(mac, nombre or mac, blocked)])
reglas = _leer_reglas()
dentro = mac in reglas if blocked else mac not in reglas
marca = "✅" if dentro else "❌"
base = (f"{'Bloqueado' if blocked else 'Activado'}: "
f"{nombre or mac} ({mac}) {marca}")
try:
return f"{base}\n{bloqueo_red(nombre or mac, mac, blocked)}"
except Exception as e:
return f"{base}\n⚠️ Sin verificacion de red: {e}"
def cambiar_bloqueo(nombre, blocked):
device = resolver_dispositivo(nombre)
if not device: