diff --git a/adguard_scheduler.py b/adguard_scheduler.py index b08234b..e9a49a3 100644 --- a/adguard_scheduler.py +++ b/adguard_scheduler.py @@ -6,6 +6,7 @@ from requests.auth import HTTPBasicAuth import subprocess from glob import glob from datetime import datetime +import re # Dodane dla walidacji regexów REQUIRED_SERVER_KEYS = {"url", "username", "password"} REQUIRED_CLIENT_KEYS = {"ip", "services", "schedule"} @@ -69,6 +70,32 @@ def validate_config(config): if section.startswith("client:") and not REQUIRED_CLIENT_KEYS.issubset(keys): raise ValueError(f"Błędna konfiguracja w {section}: wymagane {REQUIRED_CLIENT_KEYS}") +def is_valid_regex(pattern): + """Walidacja regexów (opcjonalne)""" + try: + re.compile(pattern) + return True + except re.error: + return False + +def expand_aliases(config): + aliases = {} + for section in config.sections(): + if section.startswith("alias:"): + alias_name = section.split(":")[1] + domains = [] + for d in config.get(section, "domains").split(","): + d = d.strip() + if d: + # Opcjonalna walidacja regexów (tylko dla /.../) + if d.startswith("/") and d.endswith("/"): + if not is_valid_regex(d[1:-1]): + print(f"⚠️ Nieprawidłowy regex w aliasie {alias_name}: {d}") + continue + domains.append(d) + aliases[alias_name] = domains + return aliases + def load_configs(files): merged = configparser.ConfigParser() for file in files: @@ -89,6 +116,7 @@ def test_server_connection(url, auth): def main(config_paths, silent=False): config = load_configs(config_paths) + aliases = expand_aliases(config) servers = { section: { @@ -99,14 +127,22 @@ def main(config_paths, silent=False): for section in config.sections() if section.startswith("server") } - clients = { - section: { - "ip": config.get(section, "ip"), - "services": [s.strip() for s in config.get(section, "services").split(",")], - "schedule": config.get(section, "schedule"), - } - for section in config.sections() if section.startswith("client:") - } + clients = {} + for section in config.sections(): + if section.startswith("client:"): + raw_services = [s.strip() for s in config.get(section, "services").split(",")] + expanded_services = [] + for service in raw_services: + if service in aliases: + expanded_services.extend(aliases[service]) + else: + expanded_services.append(service) + + clients[section] = { + "ip": config.get(section, "ip"), + "services": expanded_services, + "schedule": config.get(section, "schedule"), + } for srv_name, srv in servers.items(): if not silent: @@ -123,7 +159,11 @@ def main(config_paths, silent=False): for cdata in clients.values(): if should_block(cdata["schedule"]): for service in cdata["services"]: - rule = f"||{service}^$client={cdata['ip']}" + # Zachowaj oryginalną składnię (regex, wyjątki, itp.) + if service.startswith(("||", "@@", "/", "!", "#", "127.0.0.1")): + rule = f"{service}$client={cdata['ip']}" + else: + rule = f"||{service}^$client={cdata['ip']}" # Domyślna reguła rules_set.add(rule) if not silent: show_block_details(cdata["ip"], service, cdata["schedule"]) @@ -131,7 +171,7 @@ def main(config_paths, silent=False): payload = {"rules": sorted(rules_set)} endpoint = f"{srv['url']}/control/filtering/set_rules" response = requests.post(endpoint, json=payload, auth=auth, - headers={"Content-Type": "application/json"}) + headers={"Content-Type": "application/json"}) if not silent: if response.status_code in [200, 204]: diff --git a/config.example.ini b/config.example.ini index dd1f7b6..26b7610 100644 --- a/config.example.ini +++ b/config.example.ini @@ -3,11 +3,27 @@ url = http://192.168.1.1:3000 username = admin password = mypass -[server:office] +[server:office-dns1] url = http://10.0.0.1:3000 username = admin password = secret123 +[server:office-dns2] +url = http://10.0.0.1:3000 +username = admin +password = secret123 + +[alias:tiktok] +domains = tiktok.com, www.tiktok.com, m.tiktok.com, vm.tiktok.com, vt.tiktok.com, + api.tiktok.com, log.tiktok.com, tiktokcdn.com, tiktokv.com, + musical.ly, bytedance.com + +[alias:social] +domains = /(facebook|twitter|instagram)\.com/,@@||linkedin.com^ # Regex + wyjątek + +[alias:custom] +domains = 127.0.0.1 malware.com, ! Komentarz, /^ads?\./ + [client:tv] ip = 192.168.1.101 services = youtube.com, netflix.com @@ -25,7 +41,7 @@ schedule = custom:8-20 [client:guest] ip = 192.168.1.200 -services = tiktok.com +services = tiktok # alias schedule = custom:0-0 ; zero godzin = nie blokuj [client:office-laptop]