Files
seoulmate_bot_v1/services/bot/app/handlers/admin.py
Andrey K. Choi 9af84db429
Some checks reported errors
continuous-integration/drone/push Build encountered an error
MVP ready. Fully functional (registration? moderation, profiles vew)
2025-08-12 21:55:56 +09:00

141 lines
5.6 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.

from __future__ import annotations
from telegram import Update
from telegram.ext import ContextTypes
from sqlalchemy import desc
from app.core.db import db_session
from app.repositories.admin_repo import AdminRepository
from app.repositories.candidate_repo import CandidateRepository
from app.models.candidate import Candidate
from app.utils.common import csv_to_list
async def add_admin_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Команда /addadmin <telegram_id> — добавить нового администратора (только для админов)."""
with db_session() as s:
repo = AdminRepository(s)
if not repo.is_admin(update.effective_user.id):
await update.message.reply_text("Недостаточно прав.")
return
args = context.args or []
if not args:
await update.message.reply_text("Формат: /addadmin 123456789")
return
try:
tid = int(args[0])
except ValueError:
await update.message.reply_text("Неверный telegram_id.")
return
from app.models.admin import Admin
if s.query(Admin).filter(Admin.telegram_id == tid).first():
await update.message.reply_text("Этот администратор уже добавлен.")
return
s.add(Admin(telegram_id=tid))
s.commit()
await update.message.reply_text(f"Администратор {tid} добавлен.")
async def list_candidates_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Команда /candidates — показать последние анкеты (только для админов)."""
with db_session() as s:
admin_repo = AdminRepository(s)
if not admin_repo.is_admin(update.effective_user.id):
await update.message.reply_text("Недостаточно прав.")
return
rows = s.query(Candidate).order_by(desc(Candidate.created_at)).limit(30).all()
if not rows:
await update.message.reply_text("Кандидатов пока нет.")
return
out = []
for c in rows:
out.append(
f"#{c.id} {c.full_name or ''} | {c.city or ''} | цель: {c.goal or ''} | @{c.username or ''}"
)
await update.message.reply_text("Последние анкеты:\n" + "\n".join(out))
async def verify_candidate_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Команда /verify <id> — пометить анкету как проверенную (только для админов)."""
with db_session() as s:
admin_repo = AdminRepository(s)
if not admin_repo.is_admin(update.effective_user.id):
await update.message.reply_text("Недостаточно прав.")
return
args = context.args or []
if not args:
await update.message.reply_text("Формат: /verify 12")
return
try:
cid = int(args[0])
except ValueError:
await update.message.reply_text("Укажи числовой id анкеты.")
return
c = s.get(Candidate, cid)
if not c:
await update.message.reply_text("Анкета не найдена.")
return
c.is_verified = True
s.commit()
await update.message.reply_text(f"Анкета #{cid} помечена как проверенная.")
async def view_candidate_handler(update, context):
"""Команда /view <id> — показать карточку анкеты с фото (для админов)."""
with db_session() as s:
admin_repo = AdminRepository(s)
if not admin_repo.is_admin(update.effective_user.id):
await update.message.reply_text("Недостаточно прав.")
return
args = context.args or []
if not args:
await update.message.reply_text("Формат: /view 12")
return
try:
cid = int(args[0])
except ValueError:
await update.message.reply_text("Укажи числовой id анкеты.")
return
c = s.get(Candidate, cid)
if not c:
await update.message.reply_text("Анкета не найдена.")
return
# Текстовая карточка
caption = (
f"#{c.id} {c.full_name or ''} @{c.username or ''}\n"
f"Город: {c.city or ''} | Цель: {c.goal or ''}\n"
f"Статус: {'✅ проверена' if c.is_verified else '⏳ на проверке'} | Активна: {'да' if c.is_active else 'нет'}"
)
chat_id = update.effective_chat.id
# Аватар (если есть)
if c.avatar_file_id:
await context.bot.send_photo(chat_id=chat_id, photo=c.avatar_file_id, caption=caption)
else:
await context.bot.send_message(chat_id=chat_id, text=caption + "\n(аватар отсутствует)")
# Галерея (если есть)
gallery_ids = csv_to_list(c.gallery_file_ids)
if gallery_ids:
# Telegram принимает до 10 media за раз
chunk = []
for fid in gallery_ids:
chunk.append(InputMediaPhoto(media=fid))
if len(chunk) == 10:
await context.bot.send_media_group(chat_id=chat_id, media=chunk)
chunk = []
if chunk:
await context.bot.send_media_group(chat_id=chat_id, media=chunk)