mirror of
https://github.com/wahyd4/links.git
synced 2026-08-09 05:06:16 +10:00
68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
import logging
|
|
|
|
from apscheduler.triggers.interval import IntervalTrigger
|
|
from django.utils.timezone import now
|
|
|
|
from core.scheduler import scheduler
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def check_watcher(watcher_pk: int) -> None:
|
|
from pricemon.models import PriceWatcher, PriceSnapshot, PriceAlert
|
|
from pricemon.scraper import fetch_price
|
|
from pricemon.notifications import notify_telegram
|
|
|
|
try:
|
|
watcher = PriceWatcher.objects.get(pk=watcher_pk)
|
|
except PriceWatcher.DoesNotExist:
|
|
logger.warning(f'PriceWatcher {watcher_pk} no longer exists, skipping')
|
|
return
|
|
|
|
price, raw_text, error = fetch_price(watcher)
|
|
|
|
PriceSnapshot.objects.create(
|
|
watcher=watcher,
|
|
price=price,
|
|
raw_text=raw_text or '',
|
|
error=error or '',
|
|
)
|
|
|
|
if price is not None and watcher.last_price is not None and price < watcher.last_price:
|
|
drop_pct = (watcher.last_price - price) / watcher.last_price * 100
|
|
if drop_pct >= watcher.alert_threshold_pct:
|
|
alert = PriceAlert.objects.create(
|
|
watcher=watcher,
|
|
old_price=watcher.last_price,
|
|
new_price=price,
|
|
drop_pct=drop_pct,
|
|
)
|
|
notify_telegram(watcher, alert)
|
|
|
|
update_fields = ['last_checked_at']
|
|
if price is not None:
|
|
watcher.last_price = price
|
|
update_fields.append('last_price')
|
|
watcher.last_checked_at = now()
|
|
watcher.save(update_fields=update_fields)
|
|
logger.info(f'Checked watcher {watcher_pk} ({watcher.name}): price={price}')
|
|
|
|
|
|
def schedule_watcher(watcher) -> None:
|
|
job_id = f'pricemon_watcher_{watcher.pk}'
|
|
scheduler.add_job(
|
|
check_watcher,
|
|
trigger=IntervalTrigger(hours=watcher.check_interval_hours),
|
|
id=job_id,
|
|
args=[watcher.pk],
|
|
replace_existing=True,
|
|
)
|
|
logger.info(f'Scheduled pricemon job {job_id} every {watcher.check_interval_hours}h')
|
|
|
|
|
|
def unschedule_watcher(watcher) -> None:
|
|
job_id = f'pricemon_watcher_{watcher.pk}'
|
|
if scheduler.get_job(job_id):
|
|
scheduler.remove_job(job_id)
|
|
logger.info(f'Removed pricemon job {job_id}')
|