package com.auction; import org.opencv.core.Core; import java.util.List; public class Main { public static void main2(String[] args) { // If arguments are passed, this is likely a one-off command via dokku run // Just exit immediately to allow the command to run if (args.length > 0) { IO.println("Command mode - exiting to allow shell commands"); return; } IO.println("Starting Troostwijk Auction Scraper..."); IO.println("Container is running and healthy."); // Keep container alive try { Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { Thread.currentThread().interrupt(); IO.println("Container interrupted, exiting."); } } /** * Entry point. Configure database location, notification settings, and * YOLO model paths here before running. Once started the scraper * discovers Dutch auctions, scrapes lots, and begins monitoring. */ public static void main(String[] args) throws Exception { IO.println("=== Troostwijk Auction Scraper ===\n"); // Configuration parameters (replace with your own values) String databaseFile = "troostwijk.db"; // Notification configuration - choose one: // Option 1: Desktop notifications only (free, no setup required) String notificationConfig = System.getenv().getOrDefault("NOTIFICATION_CONFIG", "desktop"); // Option 2: Desktop + Email via Gmail (free, requires Gmail app password) // Format: "smtp:username:appPassword:toEmail" // Example: "smtp:your.email@gmail.com:abcd1234efgh5678:recipient@example.com" // Get app password: Google Account > Security > 2-Step Verification > App passwords // YOLO model paths (optional - scraper works without object detection) String yoloCfg = "models/yolov4.cfg"; String yoloWeights = "models/yolov4.weights"; String yoloClasses = "models/coco.names"; // Load native OpenCV library System.loadLibrary(Core.NATIVE_LIBRARY_NAME); IO.println("Initializing scraper..."); TroostwijkScraper scraper = new TroostwijkScraper(databaseFile, notificationConfig, "", yoloCfg, yoloWeights, yoloClasses); // Step 1: Discover auctions in NL IO.println("\n[1/3] Discovering Dutch auctions..."); List auctions = scraper.discoverDutchAuctions(); IO.println("āœ“ Found " + auctions.size() + " auctions: " + auctions); // Step 2: Fetch lots for each auction IO.println("\n[2/3] Fetching lot details..."); int totalAuctions = auctions.size(); int currentAuction = 0; for (int saleId : auctions) { currentAuction++; IO.println(" [Page " + currentAuction + "] Fetching auctions..."); IO.println(" [" + currentAuction + "/" + totalAuctions + "] Processing sale " + saleId + "..."); scraper.fetchLotsForSale(saleId); } // Show database summary IO.println("\nšŸ“Š Database Summary:"); scraper.printDatabaseStats(); // Step 3: Start monitoring bids and closures IO.println("\n[3/3] Starting monitoring service..."); scraper.scheduleMonitoring(); IO.println("āœ“ Monitoring active. Press Ctrl+C to stop.\n"); } }