diff --git a/vigilancia/asus_api_control.py b/vigilancia/asus_api_control.py index 5da1624..ee4eddd 100644 --- a/vigilancia/asus_api_control.py +++ b/vigilancia/asus_api_control.py @@ -132,6 +132,60 @@ def _mac_en_vivo(pistas): return None +def _leer_reglas(): + """Lee las reglas parentales del router como dict mac -> campos.""" + from router_control import _run + + def get(var): + out = _run(f"nvram get {var}") + if out.startswith("Error"): + raise RuntimeError(out) + return out + + macs = [x for x in get("MULTIFILTER_MAC").split(">") if x] + names = get("MULTIFILTER_DEVICENAME").split(">") + maps = get("MULTIFILTER_MACFILTER_DAYTIME_V2").split(">") + types = get("MULTIFILTER_ENABLE").split(">") + reglas = {} + for i, mac in enumerate(macs): + reglas[mac.upper()] = { + "name": names[i] if i < len(names) else "", + "timemap": maps[i] if i < len(maps) else TIMEMAP_24_7, + "type": types[i] if i < len(types) else "2", + } + return reglas + + +def fijar_bloqueos(cambios): + """Aplica varios (mac, name, blocked) con una sola lectura-modificacion- + escritura: varios bloqueos seguidos no se pisan entre si.""" + from router_control import _run + import shlex + reglas = _leer_reglas() + for mac, name, blocked in cambios: + mac = (mac or "").upper() + if not mac: + continue + if blocked: + reglas[mac] = {"name": name or "", "timemap": TIMEMAP_24_7, + "type": "2"} + else: + reglas.pop(mac, None) + orden = list(reglas) + cmds = [ + f"nvram set MULTIFILTER_MAC={shlex.quote('>'.join(orden))}", + "nvram set MULTIFILTER_DEVICENAME=" + shlex.quote( + ">".join(reglas[m]["name"] for m in orden)), + "nvram set MULTIFILTER_MACFILTER_DAYTIME_V2=" + shlex.quote( + ">".join(reglas[m]["timemap"] for m in orden)), + f"nvram set MULTIFILTER_ENABLE={shlex.quote('>'.join(reglas[m]['type'] for m in orden))}", + "nvram commit", + "service restart_firewall", + ] + _run("; ".join(cmds)) + return _leer_reglas() + + def cambiar_bloqueo(nombre, blocked): device = resolver_dispositivo(nombre) if not device: @@ -143,8 +197,14 @@ def cambiar_bloqueo(nombre, blocked): if vivo and vivo[1].upper() != mac.upper(): mac = vivo[1] etiqueta = f"{etiqueta} [{vivo[2]} {vivo[0]}]" - asyncio.run(_set_block(mac, device["name"], blocked)) - base = f"{'Bloqueado' if blocked else 'Activado'}: {etiqueta} ({mac})" + try: + reglas = fijar_bloqueos([(mac, device["name"], blocked)]) + except Exception as e: + return f"❌ No se pudo aplicar la regla: {e}" + dentro = mac.upper() in reglas if blocked else mac.upper() not in reglas + marca = "✅" if dentro else "❌" + base = (f"{'Bloqueado' if blocked else 'Activado'}: {etiqueta} " + f"({mac}) {marca}") try: from router_control import bloqueo_red return f"{base}\n{bloqueo_red(nombre, mac, blocked)}"