123 lines
5.1 KiB
Python
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
|