mirror of
https://github.com/EDeev/chatping_abobot.git
synced 2026-10-07 20:49:45 +03:00
База — PostgreSQL (asyncpg) вместо четырёх файлов SQLite с таблицей на каждый чат: chats, users, members, chat_stats и member_stats с полем «период» — месяцы хранятся, а не обнуляются; счётчики растут одним запросом без блокировки бота. scripts/migrate_sqlite.py переносит старые базы со сверкой сумм (проверено на копии рабочих баз: 20 694 пользователя, 45 чатов, 3 142 038 сообщений — совпадает). Учёт бота в чатах: статус и права бота (событие my_chat_member и сверка с Telegram при запуске и раз в 6 часов), история изменений в bot_status_history; из чатов, где бота исключили, данные не удаляются — меняется только статус. Большие чаты (больше 100 участников): /all — только для админов, раз в 5 минут и только писавшие за 30 дней; упоминание одного человека по имени — не чаще раза в минуту. В любом чате /all делится на сообщения до 4096 символов (раньше в чате на 14 тысяч падал). Новое: /settings (упоминания, имена в голосовых, ивенты, удаление служебных сообщений — меняют админы), /top, /month (итоги месяца по команде). /stop_bot раньше ничего не выключал — флаг не проверялся; теперь работает. Участник, вышедший из чата, больше не упоминается, но его статистика сохраняется. Ошибки — в технический чат DEBUG_CHAT_ID. Код: handlers.py разбит на роутеры, Markdown заменён на HTML (экранирование через html.escape), тесты на PostgreSQL (18), CI на Python 3.10 и 3.12.
44 lines
1.4 KiB
Python
44 lines
1.4 KiB
Python
"""Общее для обработчиков: учёт статистики, права, размер чата"""
|
|
import time
|
|
|
|
from aiogram import Bot
|
|
from aiogram.types import Message
|
|
|
|
import config
|
|
import db
|
|
from nlp import clean_name
|
|
|
|
_size_cache = {}
|
|
|
|
|
|
def in_group(message: Message):
|
|
return message.chat.id < 0
|
|
|
|
|
|
async def count(message: Message, *var_ids):
|
|
"""Учёт события в группе от автора сообщения"""
|
|
if in_group(message) and message.from_user and not message.from_user.is_bot:
|
|
await db.count(message.chat.id, message.from_user.id, var_ids, clean_name(message.from_user.first_name),
|
|
message.chat.title)
|
|
|
|
|
|
async def is_admin(bot: Bot, chat_id, user_id):
|
|
member = await bot.get_chat_member(chat_id, user_id)
|
|
return member.status in ("creator", "administrator")
|
|
|
|
|
|
async def chat_size(bot: Bot, chat_id):
|
|
"""Число участников чата по Telegram (кэш на 10 минут)"""
|
|
cached = _size_cache.get(chat_id)
|
|
if cached and time.monotonic() - cached[1] < 600:
|
|
return cached[0]
|
|
try:
|
|
size = await bot.get_chat_member_count(chat_id)
|
|
except Exception:
|
|
size = await db.member_count(chat_id)
|
|
_size_cache[chat_id] = (size, time.monotonic())
|
|
return size
|
|
|
|
|
|
async def is_big(bot: Bot, chat_id):
|
|
return await chat_size(bot, chat_id) > config.BIG_CHAT
|