It's version 0.5

This commit is contained in:
Niken
2025-10-29 21:46:06 +03:00
parent a71a7fbd0c
commit e56401bf1d
19 changed files with 582 additions and 7 deletions
+99
View File
@@ -0,0 +1,99 @@
import asyncio
import aiosqlite
from datetime import datetime
from logging import getLogger
from aiogram import Dispatcher, Bot
from config import Config
from models.state import BotState
from utils.antispam import save_message
logger = getLogger(__name__)
def register_handlers(dp: Dispatcher, state: BotState, bot: Bot) -> int:
async def init_db():
async with aiosqlite.connect(Config.DAYS_TO_DB_PATH) as db:
await db.execute("""
CREATE TABLE IF NOT EXISTS days_to_new_year (
user_id INTEGER PRIMARY KEY,
days INTEGER NOT NULL,
timestamp TEXT NOT NULL
)
""")
await db.commit()
logger.info("База данных инициализирована")
async def save_days_to_db(user_id: int, days: int):
logger.debug(f"Сохраняем user_id={user_id}, days={days}")
async with aiosqlite.connect(Config.DAYS_TO_DB_PATH) as db:
await db.execute("""
INSERT OR REPLACE INTO days_to_new_year (user_id, days, timestamp)
VALUES (?, ?, ?)
""", (int(user_id), int(days), datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
await db.commit()
logger.info(f"Запись сохранена: user_id={user_id}, days={days}")
async def get_last_days(user_id: int) -> int | None:
async with aiosqlite.connect(Config.DAYS_TO_DB_PATH) as db:
async with db.execute(
"SELECT days FROM days_to_new_year WHERE user_id = ?", (int(user_id),)
) as cursor:
row = await cursor.fetchone()
return row[0] if row else None
async def days_to_new_years() -> int:
now = datetime.now()
new_year = datetime(now.year + 1, 1, 1)
delta = (new_year - now).days
logger.debug(f"До Нового года осталось {delta} дней")
return delta
async def days_to_summer() -> int:
"""Считает дни до 1 июня текущего года (или следующего, если уже лето прошло)."""
now = datetime.now()
summer = datetime(now.year, 6, 1)
if now >= summer:
summer = datetime(now.year + 1, 6, 1)
delta = (summer - now).days
logger.debug(f"До лета осталось {delta} дней")
return delta
async def send_days_to_new_years(user_id: int):
days_ny = await days_to_new_years()
days_summer = await days_to_summer()
last_days = await get_last_days(user_id)
if last_days == days_ny:
logger.info(f"user_id={user_id}: запись уже есть ({days_ny} дней), пропускаем")
return
await save_days_to_db(user_id, days_ny)
message_text = (
f"🌞 До лета осталось {days_summer} дней!\n"
f"🎄 До Нового Года осталось {days_ny} дней!"
)
for chat_id in Config.CHAT_IDS:
try:
logger.info(f"Отправляем сообщение в чат {chat_id} для user_id={user_id}")
await bot.send_message(chat_id, message_text)
except Exception as e:
logger.error(f"Ошибка при отправке в чат {chat_id}: {e}")
async def periodic_task():
await init_db()
while True:
logger.info("Запуск цикла periodic_task")
for uid in Config.CHAT_IDS:
try:
msg = await send_days_to_new_years(int(uid))
if msg:
save_message(msg.chat.id, msg.message_id)
except Exception as e:
logger.exception(f"Ошибка при обработке uid={uid}: {e}")
logger.info("Завершён цикл periodic_task, спим 6 часов")
await asyncio.sleep(21600) # каждые 6 часов
asyncio.create_task(periodic_task())
return 0