#!/usr/bin/env python3 """Migrate old config.cfg to SQLite database.""" import re import sys from configparser import ConfigParser from database import init_db, get_db, set_setting def parse_color(value): """Parse 'R=255&G=0&B=0' or '/win&A=255&R=200&G=200&B=200' into (r, g, b, effect).""" effect = "" # Extract effect prefix (e.g., /win&A=255) if value.startswith("/"): parts = value.split("&R=") if len(parts) == 2: effect = parts[0] value = "R=" + parts[1] r = g = b = 0 for part in value.replace("&", " ").split(): if part.startswith("R="): r = int(part[2:]) elif part.startswith("G="): g = int(part[2:]) elif part.startswith("B="): b = int(part[2:]) return r, g, b, effect def migrate(config_path="config.cfg"): """Import old config.cfg into the SQLite database.""" config = ConfigParser() config.read(config_path, encoding="utf-8") init_db() conn = get_db() # Azure settings if config.has_section("azure"): az = config["azure"] set_setting("azure_client_id", az.get("clientid", "")) set_setting("azure_client_secret", az.get("clientsecret", "")) set_setting("azure_tenant_id", az.get("tenantid", "")) set_setting("azure_auth_tenant", az.get("authtenant", "common")) set_setting("azure_scopes", az.get("graphuserscopes", "")) # Auth record if config.has_option("cred", "value"): set_setting("azure_auth_record", config["cred"]["value"]) # Config settings if config.has_section("config"): cfg = config["config"] set_setting("poll_interval", cfg.get("intervall", "15")) set_setting("aida_csv_path", cfg.get("anwesenheit_csv", "")) set_setting("aida_status_anwesend", cfg.get("anwesenheit_anwesend", "~~1~~")) set_setting("aida_status_abwesend", cfg.get("anwesenheit_abwesend", "~~0~~")) set_setting("aida_status_homeoffice", cfg.get("anwesenheit_homeoffice", "~~2~~")) # WLED color rules if config.has_section("wled"): for status, value in config["wled"].items(): r, g, b, effect = parse_color(value) conn.execute( """INSERT OR REPLACE INTO color_rules (status, r, g, b, effect) VALUES (?, ?, ?, ?, ?)""", (status, r, g, b, effect), ) # Users and WLED devices devices = {} # hostname -> device_id if config.has_section("user"): for azure_id, entry in config["user"].items(): parts = entry.split(" - ", 1) hostname = parts[0].strip() display_name = parts[1].strip() if len(parts) > 1 else "" # Get personal number from anwesenheit section personal_nr = "" if config.has_option("anwesenheit", azure_id): anw_val = config["anwesenheit"][azure_id].split()[0] personal_nr = anw_val # Determine if user is active (has a known hostname) is_active = 0 if hostname == "unbekannt" else 1 conn.execute( """INSERT OR REPLACE INTO users (azure_id, display_name, personal_nr, active) VALUES (?, ?, ?, ?)""", (azure_id, display_name, personal_nr, is_active), ) # Create WLED device if hostname is known if hostname != "unbekannt" and hostname not in devices: conn.execute( "INSERT OR IGNORE INTO wled_devices (hostname, name, segment_count) VALUES (?, ?, 2)", (hostname, hostname), ) row = conn.execute( "SELECT id FROM wled_devices WHERE hostname = ?", (hostname,) ).fetchone() if row: devices[hostname] = row["id"] # Segment assignments if config.has_section("segment"): for azure_id, entry in config["segment"].items(): parts = entry.split() seg_str = parts[0] if parts else "-" if seg_str == "-": continue try: segment = int(seg_str) except ValueError: continue # Find the user's hostname if config.has_option("user", azure_id): user_entry = config["user"][azure_id] hostname = user_entry.split(" - ", 1)[0].strip() if hostname in devices: device_id = devices[hostname] conn.execute( """INSERT OR REPLACE INTO assignments (user_azure_id, wled_device_id, segment) VALUES (?, ?, ?)""", (azure_id, device_id, segment), ) conn.commit() conn.close() print(f"Migration abgeschlossen.") print(f" - {len(devices)} WLED-Geraete importiert") conn = get_db() user_count = conn.execute("SELECT COUNT(*) as c FROM users").fetchone()["c"] active_count = conn.execute("SELECT COUNT(*) as c FROM users WHERE active=1").fetchone()["c"] assign_count = conn.execute("SELECT COUNT(*) as c FROM assignments").fetchone()["c"] conn.close() print(f" - {user_count} User importiert ({active_count} aktiv)") print(f" - {assign_count} Segment-Zuordnungen importiert") if __name__ == "__main__": path = sys.argv[1] if len(sys.argv) > 1 else "config.cfg" migrate(path)