Other files
This commit is contained in:
@@ -24,11 +24,15 @@ from config import (
|
||||
NEW_DROP_NOTIFICATIONS,
|
||||
PRICE_CHANGE_NOTIFICATIONS,
|
||||
MAX_PAGES,
|
||||
AUTO_BUY_ENABLED,
|
||||
AUTO_BUY_SITES,
|
||||
AUTO_BUY_DRY_RUN,
|
||||
)
|
||||
from src.browser import get_browser, shutdown_browser
|
||||
from src.product_tracker import ProductTracker
|
||||
from src.discord_notifier import send_stock_alert, send_startup_notification, send_error_notification, send_price_change_alert
|
||||
from src.scraper_state import scraper_state
|
||||
from src.buyers import get_buyer
|
||||
# Note: Pokemon Center uses Chrome Extension (chrome-extension/), not a Python scraper
|
||||
from scrapers import (
|
||||
TargetScraper,
|
||||
@@ -60,6 +64,51 @@ scrapers = {
|
||||
}
|
||||
|
||||
|
||||
def attempt_auto_buy(site: str, products: list):
|
||||
"""
|
||||
Attempt to purchase in-stock products on the given site.
|
||||
Only runs when AUTO_BUY_ENABLED=True and site is in AUTO_BUY_SITES.
|
||||
Logs and notifies on every attempt — never silently buys anything.
|
||||
"""
|
||||
if not AUTO_BUY_ENABLED:
|
||||
return
|
||||
if site not in AUTO_BUY_SITES:
|
||||
return
|
||||
if not products:
|
||||
return
|
||||
|
||||
buyer = get_buyer(site)
|
||||
if not buyer:
|
||||
logger.warning(f"[auto-buy] No buyer implemented for {site}")
|
||||
return
|
||||
|
||||
mode = "DRY RUN" if AUTO_BUY_DRY_RUN else "LIVE"
|
||||
for product in products:
|
||||
if not product.in_stock:
|
||||
continue
|
||||
logger.info(f"[auto-buy] {mode} — {site} — {product.name}")
|
||||
try:
|
||||
result = buyer.buy_product(product)
|
||||
if result.success:
|
||||
logger.info(f"[auto-buy] SUCCESS ({mode}): {product.name} — {result.message}")
|
||||
send_stock_alert(
|
||||
product_name=product.name,
|
||||
product_url=product.url,
|
||||
price=product.price or "See link",
|
||||
site=site,
|
||||
alert_type="auto_buy_success" if not result.dry_run else "auto_buy_dry_run",
|
||||
image_url=product.image_url,
|
||||
)
|
||||
else:
|
||||
logger.warning(f"[auto-buy] FAILED: {product.name} — {result.message}")
|
||||
send_error_notification(
|
||||
f"Auto-buy failed for {product.name} on {site}: {result.message}",
|
||||
site.title(),
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"[auto-buy] Error buying {product.name} on {site}: {e}", exc_info=True)
|
||||
|
||||
|
||||
def check_target():
|
||||
"""Check Target for restocks and new drops"""
|
||||
logger.info("Checking Target...")
|
||||
@@ -129,6 +178,9 @@ def check_target():
|
||||
)
|
||||
logger.info(f"Sent notification for price change: {product.name} ({old_price} -> {new_price})")
|
||||
|
||||
# Auto-buy in-stock new drops and restocks
|
||||
attempt_auto_buy("target", [p for p in new_products if p.in_stock] + restocked_products)
|
||||
|
||||
# Log stats
|
||||
stats = tracker.get_stats()
|
||||
logger.info(
|
||||
@@ -220,6 +272,9 @@ def check_gamestop():
|
||||
)
|
||||
logger.info(f"Sent notification for price change: {product.name} ({old_price} -> {new_price})")
|
||||
|
||||
# Auto-buy in-stock new drops and restocks
|
||||
attempt_auto_buy("gamestop", [p for p in new_products if p.in_stock] + restocked_products)
|
||||
|
||||
# Log stats
|
||||
stats = tracker.get_stats()
|
||||
logger.info(
|
||||
@@ -311,6 +366,9 @@ def check_bestbuy():
|
||||
)
|
||||
logger.info(f"Sent notification for price change: {product.name} ({old_price} -> {new_price})")
|
||||
|
||||
# Auto-buy in-stock new drops and restocks
|
||||
attempt_auto_buy("bestbuy", [p for p in new_products if p.in_stock] + restocked_products)
|
||||
|
||||
# Log stats
|
||||
stats = tracker.get_stats()
|
||||
logger.info(
|
||||
|
||||
Reference in New Issue
Block a user