from pathlib import Path import tomllib from common.project_paths import ROOT_DIR CONFIG_DIR = ROOT_DIR / "config" CONFIG_FILE = CONFIG_DIR / "config.toml" SECRETS_FILE = CONFIG_DIR / "secrets.toml" DEFAULT_EVENT_FILE = CONFIG_DIR / "event.toml" DEFAULT_GUEST_FILE = CONFIG_DIR / "guests.txt" def loadTomlFile(path): if not path.exists(): return {} return tomllib.loads(path.read_text(encoding="utf-8")) def resolveConfigPath(value, default_path): if not value: return default_path candidate = Path(value) if candidate.is_absolute(): return candidate return (ROOT_DIR / candidate).resolve() def loadNameListFile(path): if not path.exists(): return [] names = [] for line in path.read_text(encoding="utf-8-sig", errors="replace").splitlines(): name = line.strip() if not name or name.startswith("#"): continue names.append(name) return names def loadSecretConfig(): return loadTomlFile(SECRETS_FILE) def getSecretValue(section_name, key, default=""): secrets = loadSecretConfig() section = secrets.get(section_name, {}) return str(section.get(key, default)).strip() def loadOcrConfig(): config = loadTomlFile(CONFIG_FILE) ocr = config.get("ocr", {}) crop = ocr.get("crop", {}) return { "crop_left": float(crop.get("left", 0.05)), "crop_top": float(crop.get("top", 0.35)), "crop_right": float(crop.get("right", 0.95)), "crop_bottom": float(crop.get("bottom", 0.95)), "preprocess": bool(ocr.get("preprocess", True)), "scale": float(ocr.get("scale", 1.5)), "use_angle_cls": bool(ocr.get("use_angle_cls", False)), } def loadVrcLogConfig(): config = loadTomlFile(CONFIG_FILE) vrc_log = config.get("vrc_log", {}) self_section = config.get("self", {}) event_file_value = ( vrc_log.get("event_toml") or vrc_log.get("event_file") or config.get("event_toml") or config.get("event_file") ) event_file = resolveConfigPath(event_file_value, DEFAULT_EVENT_FILE) event_config = loadTomlFile(event_file) if not event_config: event_config = vrc_log or config guest_section = event_config.get("guest", {}) guest_names = guest_section.get("names", []) guest_file_value = ( guest_section.get("file") or event_config.get("guest_file") or config.get("guest_file") ) guest_file = resolveConfigPath(guest_file_value, DEFAULT_GUEST_FILE) if not guest_names: guest_names = loadNameListFile(guest_file) staff_names = event_config.get("staff", {}).get("names", []) if not guest_names and isinstance(event_config.get("guest_names"), list): guest_names = event_config.get("guest_names", []) if not staff_names and isinstance(event_config.get("staff_names"), list): staff_names = event_config.get("staff_names", []) notice_section = event_config.get("notice", {}) missing_count = notice_section.get("missing_count", 0) if not missing_count: missing_count = event_config.get("missing_count", 0) self_name = ( self_section.get("name") or config.get("self_name") or vrc_log.get("self_name") or event_config.get("self", {}).get("name") or "" ) return { "config_file": CONFIG_FILE, "event_file": event_file, "guest_file": guest_file, "guest_names": [str(name).strip() for name in guest_names if str(name).strip()], "staff_names": [str(name).strip() for name in staff_names if str(name).strip()], "missing_count": int(missing_count), "self_name": str(self_name).strip(), }