Iniital release of DosVault.

This commit is contained in:
2025-09-06 13:53:44 -04:00
commit b3e71456c8
41 changed files with 7391 additions and 0 deletions

113
src/libs/config.py Normal file
View File

@@ -0,0 +1,113 @@
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),
"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):
if not self.path.parent.exists():
self.path.parent.mkdir(parents=True, exist_ok=True)
rom_path = input(f"Enter the path to your ROMs [{self.rom_path}] enter for default: ").strip()
metadata_path = input(f"Enter the path to your metadata [{self.metadata_path}] enter for default: ").strip()
self.rom_path = Path(rom_path) if rom_path else self.rom_path
self.metadata_path = Path(metadata_path) if metadata_path else self.metadata_path
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)
with open(self.path, 'w') as f:
json.dump(self.to_dict(), f, indent=4)
f.close()
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.host = data.get("host", self.host)
self.port = data.get("port", self.port)
self.websocket_port = data.get("websocket_port", self.websocket_port)
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_client_id = secrets.get("IGDB_CLIENT_ID", "")
f.close()
self.save()
return self
f.close()
else:
self.save()
self.load()
return self