05/23 Add Pick 5, Millionair Balls, etc
This commit is contained in:
+103
-1
@@ -12,6 +12,7 @@ import logging
|
||||
import threading
|
||||
|
||||
import requests
|
||||
from datetime import datetime
|
||||
|
||||
from db.models import get_game_by_name, insert_draw, insert_fetch_log
|
||||
|
||||
@@ -26,6 +27,10 @@ MEGAMILLIONS_TX_URL = (
|
||||
"Mega_Millions/Winning_Numbers/download.html"
|
||||
)
|
||||
|
||||
VA_CASH5_URL = "https://www.valottery.com/api/v1/downloadall?gameId=1030"
|
||||
VA_MILLIONAIREFORLIFE_URL = "https://www.valottery.com/api/v1/downloadall?gameId=1075"
|
||||
VA_BANKAMILLION_URL = "https://www.valottery.com/api/v1/downloadall?gameId=1070"
|
||||
|
||||
_fetch_lock = threading.Lock()
|
||||
|
||||
|
||||
@@ -231,6 +236,96 @@ def fetch_megamillions_tx():
|
||||
return _error_result(source, added, skipped, f"Network error: {e}")
|
||||
|
||||
|
||||
# ── Virginia Lottery (shared parser) ─────────────────────────────────────────
|
||||
|
||||
def _parse_va_date(raw: str) -> str | None:
|
||||
"""'5/22/2026' or '05/22/2026' → '2026-05-22'."""
|
||||
parts = raw.strip().split("/")
|
||||
if len(parts) != 3:
|
||||
return None
|
||||
try:
|
||||
return f"{parts[2]}-{parts[0].zfill(2)}-{parts[1].zfill(2)}"
|
||||
except (IndexError, ValueError):
|
||||
return None
|
||||
|
||||
|
||||
def _fetch_va_lottery(game_name: str, source: str, url: str) -> dict:
|
||||
"""
|
||||
Fetch VA Lottery draw data from the valottery.com download API.
|
||||
Format per line: 'M/D/YYYY; N1,N2,...[; Label: bonus]'
|
||||
First line may be a 'Results for ...' header — skipped automatically.
|
||||
"""
|
||||
game = get_game_by_name(game_name)
|
||||
if not game:
|
||||
return _error_result(source, 0, 0, f"{game_name} game not found in DB")
|
||||
|
||||
game_id = game["id"]
|
||||
added = skipped = 0
|
||||
|
||||
try:
|
||||
resp = requests.get(url, timeout=30)
|
||||
resp.raise_for_status()
|
||||
|
||||
for line in resp.text.splitlines():
|
||||
line = line.strip()
|
||||
if not line or line.lower().startswith("results for"):
|
||||
continue
|
||||
|
||||
parts = [p.strip() for p in line.split(";")]
|
||||
if len(parts) < 2:
|
||||
continue
|
||||
|
||||
draw_date = _parse_va_date(parts[0])
|
||||
if draw_date is None:
|
||||
continue
|
||||
|
||||
try:
|
||||
numbers = [int(n.strip()) for n in parts[1].split(",") if n.strip()]
|
||||
except ValueError as e:
|
||||
logger.warning("[FETCH] VA %s parse error %r: %s", source, line, e)
|
||||
continue
|
||||
|
||||
bonus = None
|
||||
if len(parts) >= 3:
|
||||
colon = parts[2].rfind(":")
|
||||
if colon >= 0:
|
||||
try:
|
||||
bonus = int(parts[2][colon + 1:].strip())
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
result = insert_draw(game_id, draw_date, numbers, bonus=bonus, source=source)
|
||||
if result == "inserted":
|
||||
added += 1
|
||||
else:
|
||||
skipped += 1
|
||||
|
||||
logger.info("[FETCH] %s done — added=%d skipped=%d", source, added, skipped)
|
||||
insert_fetch_log(source, added, skipped, "success")
|
||||
return {"source": source, "added": added, "skipped": skipped,
|
||||
"status": "success", "message": None}
|
||||
|
||||
except requests.RequestException as e:
|
||||
logger.error("[FETCH] %s error: %s", source, e)
|
||||
return _error_result(source, added, skipped, f"Network error: {e}")
|
||||
|
||||
|
||||
def fetch_cash5_va():
|
||||
"""Fetch Cash 5 draws from VA Lottery download API."""
|
||||
return _fetch_va_lottery("Cash 5", "cash5_va", VA_CASH5_URL)
|
||||
|
||||
|
||||
def fetch_millionaireforlife_va():
|
||||
"""Fetch Millionaire for Life draws from VA Lottery download API."""
|
||||
return _fetch_va_lottery("Millionaire for Life", "millionaireforlife_va",
|
||||
VA_MILLIONAIREFORLIFE_URL)
|
||||
|
||||
|
||||
def fetch_bankamillion_va():
|
||||
"""Fetch Bank a Million draws from VA Lottery download API."""
|
||||
return _fetch_va_lottery("Bank a Million", "bankamillion_va", VA_BANKAMILLION_URL)
|
||||
|
||||
|
||||
# ── fetch_all ─────────────────────────────────────────────────────────────────
|
||||
|
||||
def fetch_all():
|
||||
@@ -241,7 +336,14 @@ def fetch_all():
|
||||
"""
|
||||
logger.info("[FETCH] fetch_all() starting")
|
||||
results = []
|
||||
for fn in (fetch_powerball_ny, fetch_megamillions_ny, fetch_megamillions_tx):
|
||||
for fn in (
|
||||
fetch_powerball_ny,
|
||||
fetch_megamillions_ny,
|
||||
fetch_megamillions_tx,
|
||||
fetch_cash5_va,
|
||||
fetch_millionaireforlife_va,
|
||||
fetch_bankamillion_va,
|
||||
):
|
||||
try:
|
||||
results.append(fn())
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user