From c289d9c54e8798f07cdf1302f751af671eeff6e0 Mon Sep 17 00:00:00 2001 From: Arity-T Date: Mon, 2 Feb 2026 20:42:12 +0300 Subject: [PATCH] feat: add project infrastructure - Add src/ structure with config and logger modules - Add .env.example with required environment variables - Add python-dotenv dependency - Add TASK.md with implementation roadmap --- .env.example | 6 ++++++ .gitignore | 2 ++ README.md | 2 -- main.py | 18 ++++++++++++++++-- pyproject.toml | 1 + src/__init__.py | 0 src/config.py | 25 +++++++++++++++++++++++++ src/logger.py | 25 +++++++++++++++++++++++++ uv.lock | 15 ++++++++++++++- 9 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 .env.example create mode 100644 src/__init__.py create mode 100644 src/config.py create mode 100644 src/logger.py diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..89726a1 --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +# Telegram Bot +BOT_TOKEN=your_bot_token_here +ADMIN_LOGIN=your_telegram_username + +# Logging (DEBUG, INFO, WARNING, ERROR) +LOG_LEVEL=INFO diff --git a/.gitignore b/.gitignore index 505a3b1..9989825 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ wheels/ # Virtual environments .venv + +TASK.md \ No newline at end of file diff --git a/README.md b/README.md index 103ad3d..7e98759 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,6 @@ В `data` попадают только полностью озвученные дорожки. Под дорожкой подразумевается набор всех реплик одного диктора в рамках сценария. Дорожки, озвученные частично, хранятся в `data_partial//_.wav`. Они автоматически переносятся в `data` после завершения озвучивания. -Тихие участки в начале и конце аудиофайла автоматически удаляются. - ### База данных Служебные данные, такие как состояния пользовательских сессий, соответствие `dataset_speaker_id` и `telegram_user_id` и т. п., сохраняются в базе данных SQLite. После перезагрузки бота его состояние полностью восстанавливается из базы данных. diff --git a/main.py b/main.py index cbcfa8a..4a0c460 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,19 @@ -def main(): - print("Hello from dataset-tg-bot!") +from telegram.ext import ApplicationBuilder + +from src.config import BOT_TOKEN +from src.logger import logger + + +def main() -> None: + """Точка входа приложения.""" + logger.info("Запуск бота...") + + app = ApplicationBuilder().token(BOT_TOKEN).build() + + # TODO: добавить обработчики + + logger.info("Бот запущен") + app.run_polling() if __name__ == "__main__": diff --git a/pyproject.toml b/pyproject.toml index 0139b00..564e2a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,5 +5,6 @@ description = "Add your description here" readme = "README.md" requires-python = ">=3.12" dependencies = [ + "python-dotenv>=1.2.1", "python-telegram-bot>=22.6", ] diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/config.py b/src/config.py new file mode 100644 index 0000000..4b911f9 --- /dev/null +++ b/src/config.py @@ -0,0 +1,25 @@ +import os +from pathlib import Path + +from dotenv import load_dotenv + +load_dotenv() + + +def _get_env(key: str) -> str: + """Получает переменную окружения или выбрасывает ошибку.""" + value = os.getenv(key) + if value is None: + raise RuntimeError(f"Переменная окружения {key} не задана") + return value + + +BOT_TOKEN: str = _get_env("BOT_TOKEN") +ADMIN_LOGIN: str = _get_env("ADMIN_LOGIN") +LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO") + +BASE_DIR: Path = Path(__file__).parent.parent +DATA_DIR: Path = BASE_DIR / "data" +DATA_PARTIAL_DIR: Path = BASE_DIR / "data_partial" +SCENARIOS_DIR: Path = BASE_DIR / "scenarios" +DB_PATH: Path = BASE_DIR / "bot.db" diff --git a/src/logger.py b/src/logger.py new file mode 100644 index 0000000..99ee96b --- /dev/null +++ b/src/logger.py @@ -0,0 +1,25 @@ +import logging +import sys + +from src.config import LOG_LEVEL + + +def setup_logger() -> logging.Logger: + """Настраивает и возвращает логгер приложения.""" + logger = logging.getLogger("bot") + logger.setLevel(LOG_LEVEL) + + if not logger.handlers: + handler = logging.StreamHandler(sys.stdout) + handler.setLevel(LOG_LEVEL) + formatter = logging.Formatter( + "%(asctime)s | %(levelname)-8s | %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + ) + handler.setFormatter(formatter) + logger.addHandler(handler) + + return logger + + +logger = setup_logger() diff --git a/uv.lock b/uv.lock index b7d5d57..18c85c4 100644 --- a/uv.lock +++ b/uv.lock @@ -33,11 +33,15 @@ name = "dataset-tg-bot" version = "0.1.0" source = { virtual = "." } dependencies = [ + { name = "python-dotenv" }, { name = "python-telegram-bot" }, ] [package.metadata] -requires-dist = [{ name = "python-telegram-bot", specifier = ">=22.6" }] +requires-dist = [ + { name = "python-dotenv", specifier = ">=1.2.1" }, + { name = "python-telegram-bot", specifier = ">=22.6" }, +] [[package]] name = "h11" @@ -85,6 +89,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] +[[package]] +name = "python-dotenv" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, +] + [[package]] name = "python-telegram-bot" version = "22.6"