Spaces:
Paused
Paused
Download app/config.py from Mega-Evolutions/ButtonBot: direct link, hf CLI and curl.
- Browser
- Download file 5.06 kB
-
https://huggingface.co/spaces/Mega-Evolutions/ButtonBot/resolve/main/app/config.py
- Command line
-
hf download hf://spaces/Mega-Evolutions/ButtonBot/app/config.py
-
curl -L -o config.py https://huggingface.co/spaces/Mega-Evolutions/ButtonBot/resolve/main/app/config.py
5.06 kB
| """Settings, read from environment variables (or a .env file).""" | |
| from __future__ import annotations | |
| import math | |
| import os | |
| import tempfile | |
| from dataclasses import dataclass | |
| from typing import Optional | |
| try: # python-dotenv is optional; real env vars always win | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| except Exception: # pragma: no cover | |
| pass | |
| def _ints(name: str) -> frozenset: | |
| raw = os.getenv(name, "") or "" | |
| out = set() | |
| for part in raw.replace(";", ",").replace(" ", ",").split(","): | |
| part = part.strip() | |
| if part.lstrip("-").isdigit(): | |
| out.add(int(part)) | |
| return frozenset(out) | |
| def _bool(name: str, default: bool) -> bool: | |
| raw = os.getenv(name) | |
| if raw is None or raw.strip() == "": | |
| return default | |
| return raw.strip().lower() in {"1", "true", "yes", "on"} | |
| DEFAULT_ERROR_LOG_CHAT_ID = -1002525172451 | |
| _OFF = {"0", "off", "none", "false", "no", "disabled", "disable"} | |
| def _chat_id(name: str, default: Optional[int]) -> Optional[int]: | |
| """A chat id from the environment: unset or empty -> default, "0" / "off" -> None (switched off).""" | |
| raw = (os.getenv(name) or "").strip() | |
| if raw == "": | |
| return default | |
| if raw.lower() in _OFF: | |
| return None | |
| try: | |
| return int(raw) | |
| except ValueError: | |
| raise SystemExit(f"{name} must be a chat id such as -1001234567890 (or 0 / off to switch it off), not {raw!r}") | |
| def _float(name: str, default: float) -> float: | |
| try: | |
| return float(os.getenv(name, "") or default) | |
| except ValueError: | |
| return default | |
| def _whole(name: str, default: int) -> int: | |
| """A whole number from the environment; anything that is not a finite number gives the default.""" | |
| value = _float(name, float(default)) | |
| return int(value) if math.isfinite(value) else default | |
| class Config: | |
| api_id: int | |
| api_hash: str | |
| bot_token: str | |
| owners: frozenset | |
| admins: frozenset | |
| database_url: str | |
| db_pool: str | |
| session_path: str | |
| session_string: str | |
| edit_delay: float | |
| replace_typed_links: bool | |
| port: int | |
| log_level: str | |
| error_log_chat_id: Optional[int] = None # errors are sent to this chat; None = off | |
| userbot_session: str = "" # session text of the helper account that deletes old posts | |
| userbot_keep_admin: bool = False # keep the userbot an admin after a clean-up (default: take the right away) | |
| delete_service_messages: bool = True # remove "channel name changed", "pinned a message", video chat ... notices | |
| sync_interval_minutes: int = 60 # how often every channel is compared with My posts (0 = never on its own) | |
| import_old_posts: bool = True # read the posts that were in a channel before the bot was added into My posts | |
| markup_input: bool = True # text typed as HTML or Markdown (and sent without Telegram formatting) becomes real formatting | |
| def is_owner(self, uid) -> bool: | |
| return uid in self.owners | |
| def is_allowed(self, uid) -> bool: | |
| return uid in self.owners or uid in self.admins | |
| def default_session_path() -> str: | |
| """Outside the app folder on purpose: a host that publishes that folder (python -m http.server) must not | |
| publish the login session. A bot can always log in again with its token, so losing it is harmless.""" | |
| return os.path.join(tempfile.gettempdir(), "channel-post-bot", "bot") | |
| def load_config() -> Config: | |
| missing = [k for k in ("API_ID", "API_HASH", "BOT_TOKEN") if not os.getenv(k)] | |
| owners = _ints("OWNER_IDS") | |
| if not owners: | |
| missing.append("OWNER_IDS") | |
| if missing: | |
| raise SystemExit("Missing required settings: " + ", ".join(missing) + " (see .env.example)") | |
| try: | |
| api_id = int(os.environ["API_ID"]) | |
| except ValueError: | |
| raise SystemExit("API_ID must be a number") | |
| return Config( | |
| api_id=api_id, | |
| api_hash=os.environ["API_HASH"].strip(), | |
| bot_token=os.environ["BOT_TOKEN"].strip(), | |
| owners=owners, | |
| admins=frozenset(), | |
| database_url=(os.getenv("DATABASE_URL") or "sqlite+aiosqlite:///data/bot.db").strip(), | |
| db_pool=(os.getenv("DB_POOL") or "null").strip().lower(), | |
| session_path=(os.getenv("SESSION_PATH") or default_session_path()).strip(), | |
| session_string=(os.getenv("SESSION_STRING") or "").strip(), | |
| edit_delay=max(0.3, _float("EDIT_DELAY", 1.2)), | |
| replace_typed_links=_bool("REPLACE_TYPED_LINKS", True), | |
| port=int(os.getenv("PORT") or 0), | |
| log_level=(os.getenv("LOG_LEVEL") or "INFO").upper(), | |
| error_log_chat_id=_chat_id("ERROR_LOG_CHAT_ID", DEFAULT_ERROR_LOG_CHAT_ID), | |
| userbot_session=(os.getenv("USERBOT_SESSION") or "").strip(), | |
| userbot_keep_admin=_bool("USERBOT_KEEP_ADMIN", False), | |
| delete_service_messages=_bool("DELETE_SERVICE_MESSAGES", True), | |
| sync_interval_minutes=max(0, _whole("SYNC_INTERVAL_MINUTES", 60)), | |
| import_old_posts=_bool("IMPORT_OLD_POSTS", True), | |
| markup_input=_bool("MARKUP_INPUT", True), | |
| ) | |