pounce/backend/app/jobs/tasks.py

73 lines
2.3 KiB
Python

"""Job functions executed by the ARQ worker."""
from __future__ import annotations
from datetime import datetime
from sqlalchemy import select
from app.database import AsyncSessionLocal, init_db
from app.models.auction import DomainAuction
from app.services.auction_scraper import auction_scraper
from app.services.pounce_score import calculate_pounce_score_v2
from app.services.tld_scraper.aggregator import tld_aggregator
async def scrape_auctions(ctx) -> dict: # arq passes ctx
"""Scrape auctions from all platforms and store results."""
await init_db()
async with AsyncSessionLocal() as db:
result = await auction_scraper.scrape_all_platforms(db)
await db.commit()
return {"status": "ok", "result": result, "timestamp": datetime.utcnow().isoformat()}
async def scrape_tld_prices(ctx) -> dict:
"""Scrape TLD prices from all sources and store results."""
await init_db()
async with AsyncSessionLocal() as db:
result = await tld_aggregator.run_scrape(db)
await db.commit()
return {
"status": "ok",
"tlds_scraped": result.tlds_scraped,
"prices_saved": result.prices_saved,
"sources_succeeded": result.sources_succeeded,
"sources_attempted": result.sources_attempted,
"timestamp": datetime.utcnow().isoformat(),
}
async def backfill_auction_scores(ctx, *, limit: int = 5000) -> dict:
"""
Backfill DomainAuction.pounce_score for legacy rows.
Safe to run multiple times; only fills NULL scores.
"""
await init_db()
updated = 0
async with AsyncSessionLocal() as db:
rows = (
await db.execute(
select(DomainAuction)
.where(DomainAuction.pounce_score == None) # noqa: E711
.limit(limit)
)
).scalars().all()
for auction in rows:
auction.pounce_score = calculate_pounce_score_v2(
auction.domain,
auction.tld,
num_bids=auction.num_bids or 0,
age_years=auction.age_years or 0,
is_pounce=False,
)
updated += 1
await db.commit()
return {"status": "ok", "updated": updated, "timestamp": datetime.utcnow().isoformat()}