Files
duty-teller/handlers/commands.py
Nikolay Tatarinov 5331fac334 Add configuration rules, refactor settings management, and enhance import functionality
- Introduced a new configuration file `.cursorrules` to define coding standards, error handling, testing requirements, and project-specific guidelines.
- Refactored `config.py` to implement a `Settings` dataclass for better management of environment variables, improving testability and maintainability.
- Updated the import duty schedule handler to utilize session management with `session_scope`, ensuring proper database session handling.
- Enhanced the import service to streamline the duty schedule import process, improving code organization and readability.
- Added new service layer functions to encapsulate business logic related to group duty pinning and duty schedule imports.
- Updated README documentation to reflect the new configuration structure and improved import functionality.
2026-02-18 12:35:11 +03:00

97 lines
3.8 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 config
from telegram import Update
from telegram.ext import CommandHandler, ContextTypes
from db.session import session_scope
from db.repository import get_or_create_user, set_user_phone
from 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:
"""Set or clear phone for the current user (private chat only)."""
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
# Optional: restrict to allowed usernames; plan says "or without restrictions"
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)