Files

85 lines
4.1 KiB
Python
Executable File

"""
config.py — Centralised configuration for RepoRadar.
Loads environment variables and defines git-server endpoints, the colour
palette, cache TTLs and other tunables. Import `settings` everywhere instead of
reading os.environ directly so configuration stays in one place.
"""
from __future__ import annotations
import os
from dataclasses import dataclass
from pathlib import Path
from dotenv import load_dotenv
# Load .env from the project root (the directory this file lives in).
PROJECT_ROOT = Path(__file__).resolve().parent
load_dotenv(PROJECT_ROOT / ".env")
def _get_int(name: str) -> int | None:
"""Parse an optional integer env var, returning None when unset/blank."""
raw = os.getenv(name, "").strip()
if not raw:
return None
try:
return int(raw)
except ValueError:
return None
@dataclass(frozen=True)
class Settings:
"""Immutable runtime settings sourced from environment + defaults."""
# ── Discord ──────────────────────────────────────────────
discord_token: str = os.getenv("DISCORD_TOKEN", "").strip()
# Restrict slash-command sync to one guild for instant updates (recommended).
guild_id: int | None = _get_int("GUILD_ID")
# ── Git server ───────────────────────────────────────────
# Provider: "auto" (probe), "gitea" (also Forgejo), "gitlab", or "github".
git_provider: str = os.getenv("GIT_PROVIDER", "auto").strip().lower()
# Base URL of the git server, e.g. https://git.example.com / https://gitlab.com
# For GitHub leave blank (defaults to api.github.com) and set GIT_PROVIDER=github.
git_base_url: str = os.getenv("GIT_BASE_URL", "").strip().rstrip("/")
# Personal access token (read-only is enough). Optional for public servers.
git_token: str = os.getenv("GIT_TOKEN", "").strip()
# Default channel for new-project drops (also settable per-guild via modal).
git_drop_channel_id: int | None = _get_int("GIT_DROP_CHANNEL_ID")
# Channel for highlighted/featured drops (keyword/star matches).
git_highlight_channel_id: int | None = _get_int("GIT_HIGHLIGHT_CHANNEL_ID")
# Role to ping on a highlighted drop.
git_highlight_role_id: int | None = _get_int("GIT_HIGHLIGHT_ROLE_ID")
# How often (seconds) the monitor polls the git server for new projects.
git_poll_interval: int = _get_int("GIT_POLL_INTERVAL") or 300
# Max new projects to drop per scan cycle (avoids flooding on bursts).
git_max_drops_per_cycle: int = _get_int("GIT_MAX_DROPS_PER_CYCLE") or 10
# ── Paths ────────────────────────────────────────────────
data_dir: Path = PROJECT_ROOT / "data"
db_path: Path = PROJECT_ROOT / "data" / "reporadar.db"
# ── Behaviour ────────────────────────────────────────────
log_level: str = os.getenv("LOG_LEVEL", "INFO").strip().upper()
http_timeout: int = 30 # seconds per request
request_retries: int = 3 # transient retry attempts
user_agent: str = "RepoRadar/1.0 (+https://github.com/your-org/reporadar)"
# ── Cyberpunk / hacker colour palette (hex → int) ─────────
color_drop: int = 0x8A63FF # neon violet (new project drops)
color_highlight: int = 0xE0115F # ruby (featured / highlighted)
color_success: int = 0x00FF9C # matrix green
color_error: int = 0xFF003C # neon red
color_medium: int = 0xFFB300 # amber (unconfigured / neutral)
color_info: int = 0x0A84FF # electric blue
def ensure_dirs(self) -> None:
"""Create the data directory if it does not yet exist."""
self.data_dir.mkdir(parents=True, exist_ok=True)
settings = Settings()