first commit

This commit is contained in:
2026-07-14 13:38:43 +07:00
commit 8b0e1ffffa
19 changed files with 836 additions and 0 deletions

94
main.py Normal file
View File

@@ -0,0 +1,94 @@
from __future__ import annotations
import asyncio
import logging
from aiogram import Bot, Dispatcher, Router
from aiogram.types import CallbackQuery
from aiogram.client.session.aiohttp import AiohttpSession
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from app.config import load_settings
from app.service import OfferProcessingService
from app.sources import KworkSource
from app.state import SentOffersStore
from app.telegram import TelegramPublisher
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
)
logger = logging.getLogger(__name__)
def build_dispatcher() -> Dispatcher:
router = Router()
@router.callback_query(lambda callback: callback.data == "delete_post")
async def delete_post_callback(callback: CallbackQuery) -> None:
if callback.message is None:
await callback.answer()
return
try:
await callback.message.delete()
logger.info(
"Deleted Telegram message chat_id=%s message_id=%s by user_id=%s",
callback.message.chat.id,
callback.message.message_id,
callback.from_user.id,
)
await callback.answer("Пост удален")
except Exception:
logger.exception(
"Failed to delete Telegram message chat_id=%s message_id=%s",
callback.message.chat.id,
callback.message.message_id,
)
await callback.answer("Не удалось удалить пост", show_alert=True)
dispatcher = Dispatcher()
dispatcher.include_router(router)
return dispatcher
async def main() -> None:
settings = load_settings()
dispatcher = build_dispatcher()
session = AiohttpSession(proxy=settings.telegram_proxy_url) if settings.telegram_proxy_url else None
bot = Bot(token=settings.telegram_bot_token, session=session)
publisher = TelegramPublisher(bot=bot, channel_id=settings.telegram_channel_id)
store = SentOffersStore(settings.state_file)
service = OfferProcessingService(
sources=[
KworkSource(
category_ids=settings.kwork_category_ids,
timeout_seconds=settings.requests_timeout_seconds,
)
],
publisher=publisher,
sent_offers_store=store,
include_keywords=settings.keywords_include,
exclude_keywords=settings.keywords_exclude,
min_price_amount=settings.min_price_amount,
)
scheduler = AsyncIOScheduler()
scheduler.add_job(service.run_once, "interval", minutes=settings.scheduler_interval_minutes)
scheduler.start()
await service.run_once()
try:
await dispatcher.start_polling(bot)
finally:
scheduler.shutdown()
await bot.session.close()
if __name__ == "__main__":
asyncio.run(main())