SACC / course_catcher /config.py
cacode's picture
Deploy updated SCU course catcher
e28c9e4 verified
from __future__ import annotations
import hashlib
import os
from dataclasses import dataclass
from pathlib import Path
def _default_data_dir() -> Path:
persistent_root = Path("/data")
if persistent_root.exists():
return persistent_root / "scu-course-catcher"
return Path("runtime")
@dataclass(frozen=True)
class AppConfig:
admin_username: str
admin_password: str
secret_key: str
data_dir: Path
database_path: Path
chrome_binary: str
chromedriver_binary: str
default_parallelism: int
loop_interval_seconds: float
login_retry_limit: int
request_timeout_seconds: int
debug: bool
def load_config() -> AppConfig:
admin_username = os.getenv("ADMIN", "admin")
admin_password = os.getenv("PASSWORD", "change-me-now")
derived_secret = hashlib.sha256(
f"{admin_username}:{admin_password}:scu-course-catcher".encode("utf-8")
).hexdigest()
secret_key = os.getenv("APP_SECRET", derived_secret)
data_dir = Path(os.getenv("APP_DATA_DIR", str(_default_data_dir()))).resolve()
data_dir.mkdir(parents=True, exist_ok=True)
return AppConfig(
admin_username=admin_username,
admin_password=admin_password,
secret_key=secret_key,
data_dir=data_dir,
database_path=data_dir / "app.db",
chrome_binary=os.getenv("CHROME_BIN", "/usr/bin/chromium"),
chromedriver_binary=os.getenv("CHROMEDRIVER_BIN", "/usr/bin/chromedriver"),
default_parallelism=max(1, int(os.getenv("DEFAULT_PARALLELISM", "1"))),
loop_interval_seconds=max(1.0, float(os.getenv("LOOP_INTERVAL_SECONDS", "3"))),
login_retry_limit=max(1, int(os.getenv("LOGIN_RETRY_LIMIT", "6"))),
request_timeout_seconds=max(15, int(os.getenv("REQUEST_TIMEOUT_SECONDS", "30"))),
debug=os.getenv("DEBUG", "").lower() in {"1", "true", "yes", "on"},
)