/
Shtirlitc
/
TickBot
Обзор
Документация
Войти
/
Shtirlitc
/
TickBot
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
config.py
168 строк
5 KB
Shtirlyts
Initial commit: TickBot attendance bot with stale-status fixes
31 июл 2026, 23:40
31 июл 2026, 23:40
30e955c
Код
Авторство
О чём код?
from asyncio.log import logger import os import json import base64 from pathlib import Path from dotenv import load_dotenv from pydantic_settings import BaseSettings from typing import Dict, List, Optional # Загружаем .env load_dotenv() class Settings(BaseSettings): """Настройки бота через Pydantic""" # Telegram bot_token: str = os.getenv("BOT_TOKEN", "") admin_id: int = int(os.getenv("ADMIN_ID", "0")) # Proxy proxy_url: Optional[str] = os.getenv("PROXY_URL", "") proxy_login: Optional[str] = os.getenv("PROXY_LOGIN", "") proxy_password: Optional[str] = os.getenv("PROXY_PASSWORD", "") # Google Sheets google_credentials_json: Optional[str] = os.getenv("GOOGLE_CREDENTIALS_JSON", None) # Groups groups_raw: str = os.getenv("GROUPS", "") # Payments payment_provider_token: str = os.getenv("PAYMENT_PROVIDER_TOKEN", "").strip() # Database database_path: str = os.getenv("DATABASE_PATH", "./data/bot.db") # Logging log_level: str = os.getenv("LOG_LEVEL", "INFO") log_file_path: str = os.getenv("LOG_FILE_PATH", "./logs/bot.log") remote_logger_url: str = os.getenv("REMOTE_LOGGER_URL", "http://redleg30607.fvds.ru/logger.php") log_server_token: str = os.getenv("LOG_SERVER_TOKEN", "default_token") class Config: env_file = ".env" case_sensitive = False extra = "ignore" # Глобальный экземпляр настроек settings = Settings() # ========================================== # ЭКСПОРТ ДЛЯ СОВМЕСТИМОСТИ (как в старом config.py) # ========================================== BOT_TOKEN = settings.bot_token ADMIN_ID = settings.admin_id PAYMENT_PROVIDER_TOKEN = settings.payment_provider_token REMOTE_LOGGER_URL = settings.remote_logger_url EMOJI_MAP = { 'present': '✅', 'absent': '❌', 'noclass': '⚙️' } # ========================================== # PARSE GROUPS # ========================================== def parse_groups() -> Dict[str, dict]: """Парсинг строки GROUPS из .env""" groups = {} groups_str = os.getenv("GROUPS", "") if not groups_str: return groups for part in groups_str.split(','): part = part.strip() if not part: continue tokens = part.split(':') if len(tokens) < 2: print(f"⚠️ Неверный формат группы: {part}") continue name = tokens[0].strip() warden_ids = [] last_token = tokens[-1].strip() if any(char.isdigit() for char in last_token): for s_id in last_token.split(';'): s_id = s_id.strip() if s_id.isdigit(): warden_ids.append(int(s_id)) url = ':'.join(tokens[1:-1]).strip() else: url = ':'.join(tokens[1:]).strip() if url.endswith(':'): url = url[:-1] groups[name] = { "spreadsheet_url": url, "warden_ids": warden_ids } return groups GROUPS = parse_groups() # ========================================== # GOOGLE CREDENTIALS # ========================================== def get_google_credentials() -> Optional[dict]: """Загружает credentials из переменной окружения (base64)""" if settings.google_credentials_json: try: creds_json = base64.b64decode(settings.google_credentials_json).decode() return json.loads(creds_json) except Exception as e: print(f"❌ Ошибка декодирования credentials: {e}") return None return None # ========================================== # PROXY CONFIG # ========================================== def get_proxy_url() -> Optional[str]: """Возвращает URL прокси: внешний из .env ИЛИ локальный TeleProxy""" # 1. Если внешний прокси ЗАДАН в .env if settings.proxy_url and settings.proxy_url.strip(): if settings.proxy_login and settings.proxy_password: from urllib.parse import urlparse, urlunparse parsed = urlparse(settings.proxy_url) netloc = f"{settings.proxy_login}:{settings.proxy_password}@{parsed.hostname}" if parsed.port: netloc += f":{parsed.port}" return urlunparse(parsed._replace(netloc=netloc)) return settings.proxy_url # 2. Если внешний НЕ задан — используем наш локальный TeleProxy # Проверяем, установлена ли зависимость aiohttp-socks try: import aiohttp_socks return "socks5://127.0.0.1:1443" except ImportError: logger.warning("Для использования SOCKS5 прокси установите: pip install aiohttp-socks") return None # ========================================== # PATHS # ========================================== BASE_DIR = Path(__file__).parent DATA_DIR = BASE_DIR / "data" LOGS_DIR = BASE_DIR / "logs" # Создаём директории если не существуют DATA_DIR.mkdir(exist_ok=True) LOGS_DIR.mkdir(exist_ok=True)