91 lines
3.1 KiB
Python
91 lines
3.1 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from app.filters import get_offer_skip_reason
|
|
from app.state import SentOffersStore
|
|
from app.telegram import TelegramPublisher
|
|
from app.sources.base import OfferSource
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class OfferProcessingService:
|
|
def __init__(
|
|
self,
|
|
sources: list[OfferSource],
|
|
publisher: TelegramPublisher,
|
|
sent_offers_store: SentOffersStore,
|
|
include_keywords: list[str],
|
|
exclude_keywords: list[str],
|
|
min_price_amount: int | None,
|
|
) -> None:
|
|
self._sources = sources
|
|
self._publisher = publisher
|
|
self._sent_offers_store = sent_offers_store
|
|
self._include_keywords = include_keywords
|
|
self._exclude_keywords = exclude_keywords
|
|
self._min_price_amount = min_price_amount
|
|
|
|
async def run_once(self) -> None:
|
|
for source in self._sources:
|
|
try:
|
|
logger.info("Fetching offers from source=%s", source.source_name)
|
|
offers = source.fetch_offers()
|
|
logger.info("Fetched %s offers from source=%s", len(offers), source.source_name)
|
|
except Exception:
|
|
logger.exception("Failed to fetch offers from source %s", source.source_name)
|
|
continue
|
|
|
|
skipped_duplicates = 0
|
|
skipped_exclude_keyword = 0
|
|
skipped_include_keyword = 0
|
|
skipped_min_price_amount = 0
|
|
published_count = 0
|
|
|
|
for offer in offers:
|
|
if self._sent_offers_store.has(offer.dedup_key):
|
|
skipped_duplicates += 1
|
|
continue
|
|
|
|
skip_reason = get_offer_skip_reason(
|
|
offer,
|
|
self._include_keywords,
|
|
self._exclude_keywords,
|
|
self._min_price_amount,
|
|
)
|
|
if skip_reason == "exclude_keyword":
|
|
skipped_exclude_keyword += 1
|
|
continue
|
|
if skip_reason == "include_keyword":
|
|
skipped_include_keyword += 1
|
|
continue
|
|
if skip_reason == "min_price_amount":
|
|
skipped_min_price_amount += 1
|
|
continue
|
|
|
|
try:
|
|
await self._publisher.publish_offer(offer)
|
|
except Exception:
|
|
logger.exception("Failed to publish offer %s", offer.dedup_key)
|
|
continue
|
|
|
|
self._sent_offers_store.add(offer.dedup_key)
|
|
published_count += 1
|
|
logger.info("Published offer %s", offer.dedup_key)
|
|
|
|
logger.info(
|
|
(
|
|
"Source %s summary: fetched=%s published=%s skipped_duplicates=%s "
|
|
"skipped_exclude_keyword=%s skipped_include_keyword=%s skipped_min_price_amount=%s"
|
|
),
|
|
source.source_name,
|
|
len(offers),
|
|
published_count,
|
|
skipped_duplicates,
|
|
skipped_exclude_keyword,
|
|
skipped_include_keyword,
|
|
skipped_min_price_amount,
|
|
)
|