Files
DosVault/src/libs/config.py
th3r00t 7e4c194c1f Added new rom import system utilizing WAL to avoid locking the database and freezing the frontend
Also added new logging setup to hopefully stream the scrape process
2025-09-07 12:50:05 -04:00

123 lines
5.1 KiB
Python

from pathlib import Path
from dataclasses import dataclass
from typing import Optional, Dict
import json
import os
# Check for environment variable override (used in Docker)
if os.getenv("DOSFRONTEND_CONFIG_DIR"):
DOSFRONTEND_CONFIG_DIR: Path = Path(os.getenv("DOSFRONTEND_CONFIG_DIR"))
else:
# Default to XDG config directory for regular installations
XDG_CONFIG_HOME: Path = Path(Path.home()).joinpath(".config")
DOSFRONTEND_CONFIG_DIR: Path = XDG_CONFIG_HOME.joinpath("dosfrontend")
DOSFRONTEND_CONFIG_FILE: Path = DOSFRONTEND_CONFIG_DIR.joinpath("config.json")
@dataclass
class Config:
path: Path = DOSFRONTEND_CONFIG_FILE
rom_path: Path = DOSFRONTEND_CONFIG_DIR.joinpath("roms")
metadata_path: Path = DOSFRONTEND_CONFIG_DIR.joinpath("metadata")
database_path: Path = DOSFRONTEND_CONFIG_DIR.joinpath("roms.db")
images_path: Path = DOSFRONTEND_CONFIG_DIR.joinpath("images")
host: str = "localhost"
port: int = 8080
websocket_port: int = 8081
igdb_api_key: str = ""
igdb_client_id: str = ""
def __init__(self, path: Optional[Path] = None):
if path:
self.path = path
self.load()
def load_env_secrets(self) -> Dict[str, str] | None:
secrets: Dict[str, str] = {}
igdb_api_key = os.getenv("IGDB_SECRET_KEY")
igdb_client_id = os.getenv("IGDB_CLIENT_ID")
if not igdb_api_key or not igdb_client_id:
file_path: Path = Path(__file__)
env_path: Path = file_path.parent.parent.parent.joinpath(".env")
if not env_path.exists():
return
else:
with env_path.open('r') as f:
for line in f:
if line.startswith("#") or "=" not in line:
continue
key, value = line.strip().split("=", 1)
key, value = key.strip(), value.strip('"').strip("'")
secrets[key] = value
f.close()
if secrets.get("IGDB_SECRET_KEY") and secrets.get("IGDB_CLIENT_ID"):
return secrets
else: return None
else:
secrets = {
"IGDB_SECRET_KEY": igdb_api_key,
"IGDB_CLIENT_ID": igdb_client_id,
}
return secrets
def to_dict(self) -> dict:
return {
"rom_path": str(self.rom_path),
"metadata_path": str(self.metadata_path),
"database_path": str(self.database_path),
"images_path": str(self.images_path),
"host": self.host,
"port": self.port,
"websocket_port": self.websocket_port,
"igdb_api_key": self.igdb_api_key,
"igdb_client_id": self.igdb_client_id,
}
def save(self):
# Ensure config directory exists
if not self.path.parent.exists():
self.path.parent.mkdir(parents=True, exist_ok=True)
# Create directories if they don't exist
if not self.rom_path.exists():
self.rom_path.mkdir(parents=True, exist_ok=True)
if not self.metadata_path.exists():
self.metadata_path.mkdir(parents=True, exist_ok=True)
if not self.images_path.exists():
self.images_path.mkdir(parents=True, exist_ok=True)
# Write configuration to file
with open(self.path, 'w') as f:
json.dump(self.to_dict(), f, indent=4)
def load(self) -> "Config":
if self.path.exists():
with open(self.path, 'r') as f:
data = json.load(f)
self.rom_path = Path(data.get("rom_path", str(self.rom_path)))
self.metadata_path = Path(data.get("metadata_path", str(self.metadata_path)))
self.database_path = Path(data.get("database_path", str(self.database_path)))
self.images_path = Path(data.get("images_path", str(self.images_path)))
self.host = data.get("host", self.host)
self.port = data.get("port", self.port)
self.websocket_port = data.get("websocket_port", self.websocket_port)
self.igdb_api_key = data.get("igdb_api_key", self.igdb_api_key)
self.igdb_client_id = data.get("igdb_client_id", self.igdb_client_id)
# Load environment secrets if API keys are still empty
if self.igdb_api_key == "" or self.igdb_client_id == "":
secrets = self.load_env_secrets()
if secrets:
self.igdb_api_key = secrets.get("IGDB_SECRET_KEY", self.igdb_api_key)
self.igdb_client_id = secrets.get("IGDB_CLIENT_ID", self.igdb_client_id)
else:
# Config file doesn't exist, create it with defaults
# Load environment secrets for initial setup
secrets = self.load_env_secrets()
if secrets:
self.igdb_api_key = secrets.get("IGDB_SECRET_KEY", self.igdb_api_key)
self.igdb_client_id = secrets.get("IGDB_CLIENT_ID", self.igdb_client_id)
self.save()
return self