Files
duty-teller/duty_teller/handlers/commands.py
Nikolay Tatarinov 28973489a5 Refactor project structure and enhance Docker configuration
- Updated `.dockerignore` to exclude test and development artifacts, optimizing the Docker image size.
- Refactored `main.py` to delegate execution to `duty_teller.run.main()`, simplifying the entry point.
- Introduced a new `duty_teller` package to encapsulate core functionality, improving modularity and organization.
- Enhanced `pyproject.toml` to define a script for running the application, streamlining the execution process.
- Updated README documentation to reflect changes in project structure and usage instructions.
- Improved Alembic environment configuration to utilize the new package structure for database migrations.
2026-02-18 13:03:14 +03:00

95 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Command handlers: /start, /help; /start registers user."""
import asyncio
import duty_teller.config as config
from telegram import Update
from telegram.ext import CommandHandler, ContextTypes
from duty_teller.db.session import session_scope
from duty_teller.db.repository import get_or_create_user, set_user_phone
from duty_teller.utils.user import build_full_name
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not update.message:
return
user = update.effective_user
if not user:
return
full_name = build_full_name(user.first_name, user.last_name)
telegram_user_id = user.id
username = user.username
first_name = user.first_name
last_name = user.last_name
def do_get_or_create() -> None:
with session_scope(config.DATABASE_URL) as session:
get_or_create_user(
session,
telegram_user_id=telegram_user_id,
full_name=full_name,
username=username,
first_name=first_name,
last_name=last_name,
)
await asyncio.get_running_loop().run_in_executor(None, do_get_or_create)
text = "Привет! Я бот календаря дежурств. Используй /help для списка команд."
await update.message.reply_text(text)
async def set_phone(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not update.message or not update.effective_user:
return
if update.effective_chat and update.effective_chat.type != "private":
await update.message.reply_text("Команда /set_phone доступна только в личке.")
return
args = context.args or []
phone = " ".join(args).strip() if args else None
telegram_user_id = update.effective_user.id
def do_set_phone() -> str:
with session_scope(config.DATABASE_URL) as session:
full_name = build_full_name(
update.effective_user.first_name, update.effective_user.last_name
)
get_or_create_user(
session,
telegram_user_id=telegram_user_id,
full_name=full_name,
username=update.effective_user.username,
first_name=update.effective_user.first_name,
last_name=update.effective_user.last_name,
)
user = set_user_phone(session, telegram_user_id, phone or None)
if user is None:
return "Ошибка сохранения."
if phone:
return f"Телефон сохранён: {phone}"
return "Телефон очищен."
result = await asyncio.get_running_loop().run_in_executor(None, do_set_phone)
await update.message.reply_text(result)
async def help_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not update.message or not update.effective_user:
return
lines = [
"Доступные команды:",
"/start — Начать",
"/help — Показать эту справку",
"/set_phone — Указать или очистить телефон для отображения в дежурстве",
"/pin_duty — В группе: закрепить сообщение о дежурстве (нужны права админа у бота)",
]
if config.is_admin(update.effective_user.username or ""):
lines.append("/import_duty_schedule — Импорт расписания дежурств (JSON)")
await update.message.reply_text("\n".join(lines))
start_handler = CommandHandler("start", start)
help_handler = CommandHandler("help", help_cmd)
set_phone_handler = CommandHandler("set_phone", set_phone)