from functools import lru_cache from app.core.handles import parse_handles from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict(env_file=".env", extra="ignore") bot_token: str database_url: str = "sqlite+aiosqlite:///./dev.db" gate_channel: str = "@DBUCentral" gate_channels: str = "" # optional override: "@DBUCentral,@DBUcentralforum" hide_empty_courses: bool = True # students only see courses that already have files admin_ids: str = "" # comma separated Telegram user ids default_lang: str = "en" library_channel_id: int = 0 # private backup channel (0 = no backup copy) log_level: str = "INFO" # --- watermark stamped on every PDF the admin uploads --- watermark_enabled: bool = True watermark_text: str = "DBU Freshman Central" watermark_url: str = "" # empty = https://t.me/ watermark_diagonal: bool = True # faint diagonal brand text in the middle of each page @property def gate_list(self) -> list[str]: """EVERY listed channel/group must be joined. Default: the channel + the discussion forum.""" return parse_handles(self.gate_channels) or parse_handles(f"{self.gate_channel},@DBUcentralforum") @property def watermark_link(self) -> str: return self.watermark_url or f"https://t.me/{self.gate_channel.lstrip('@')}" # --- student file contributions --- contributions_enabled: bool = True contribution_xp: int = 20 contribution_bonus_xp: int = 5 # extra when the course is short of material contribution_weekly_cap: int = 5 # rewarded files per student per week contribution_min_days: int = 2 # active days before a student may submit contribution_pending_limit: int = 5 contribution_daily_limit: int = 8 # --- weekly season / prizes (money is OFF until you switch it on) --- prizes_enabled: bool = True prize_top: str = "50,30,20" # birr airtime card for rank 1,2,3 (comma separated) prize_raffle: int = 10 # birr, one weighted draw among other eligible players min_week_xp: int = 40 min_active_days: int = 4 @property def prize_list(self) -> list[int]: return [int(x) for x in self.prize_top.replace(" ", "").split(",") if x.isdigit()] @property def admin_id_set(self) -> set[int]: return {int(x) for x in self.admin_ids.replace(" ", "").split(",") if x.isdigit()} @lru_cache def get_settings() -> Settings: return Settings()