vk_chat_bot/tg/tasks.py

91 lines
3 KiB
Python

import datetime
import traceback
from asyncio import sleep
from aiogram import Bot
from aiogram.exceptions import TelegramBadRequest
from aiogram.types import ChatMemberBanned, ChatMemberLeft
from aiogram.utils.formatting import Bold
import tg.tg_database as database
from tg.handlers.user import format_rating
async def cleanup_users(bot: Bot):
for chat in database.DB.get_chats():
if chat['active'] == 0:
continue
chat_id = chat['id']
for user in database.DB.get_top_silent(chat_id=chat_id, threshold_days=14):
user_id = user['user_id']
found = False
try:
info = await bot.get_chat_member(chat_id, user_id)
if not isinstance(info, ChatMemberLeft) and not isinstance(info, ChatMemberBanned):
found = True
except TelegramBadRequest:
pass
if not found:
database.DB.delete_user(chat_id, user_id)
print(f'Из чата (id={chat_id}) удален пользователь (id={user_id})')
async def reset_counters(reset_month: bool, bot: Bot):
database.DB.reset_messages_today()
print('Дневные счетчики сброшены.')
if reset_month:
for chat in database.DB.get_chats():
if chat['active'] == 0:
continue
top_users = database.DB.get_top_messages_month(chat['id'])
if len(top_users) == 0:
continue
message = Bold('Итоговая статистика за прошедший месяц') + '\n'
message += await format_rating(chat['id'], top_users, bot)
await bot.send_message(chat_id=chat['id'], **message.as_kwargs())
database.DB.reset_messages_month()
print('Месячные счетчики сброшены.')
async def wait_until(target_time: datetime.datetime):
now = datetime.datetime.now(target_time.tzinfo)
if now >= target_time:
return
delay_seconds = (target_time - now).total_seconds()
await sleep(delay_seconds)
async def daily_maintenance_task(bot: Bot):
tz = datetime.timezone(datetime.timedelta(hours=3), name="MSK")
target_time = datetime.time(6, 0, 0, tzinfo=tz)
now = datetime.datetime.now(tz)
if now.hour > target_time.hour or now.hour == target_time.hour and now.minute > target_time.minute:
target_date = now.date() + datetime.timedelta(days=1)
else:
target_date = now.date()
target_datetime = datetime.datetime.combine(target_date, target_time)
while True:
await wait_until(target_datetime)
try:
await cleanup_users(bot)
await reset_counters(target_datetime.day == 1, bot)
except Exception:
print(traceback.format_exc())
target_datetime = target_datetime + datetime.timedelta(days=1)
async def startup_task(bot: Bot):
me = await bot.get_me()
print(f"Бот '{me.full_name}' (id={me.id}) запущен.")