224 lines
8.1 KiB
Java
224 lines
8.1 KiB
Java
package com.auction;
|
|
|
|
import org.opencv.core.Core;
|
|
|
|
/**
|
|
* Main entry point for Troostwijk Auction Monitor.
|
|
*
|
|
* ARCHITECTURE:
|
|
* This project focuses on:
|
|
* 1. Image processing and object detection
|
|
* 2. Bid monitoring and notifications
|
|
* 3. Data enrichment
|
|
*
|
|
* Auction/Lot scraping is handled by the external ARCHITECTURE-TROOSTWIJK-SCRAPER process.
|
|
* That process populates the auctions and lots tables in the shared database.
|
|
* This process reads from those tables and enriches them with:
|
|
* - Downloaded images
|
|
* - Object detection labels
|
|
* - Bid monitoring
|
|
* - Notifications
|
|
*/
|
|
public class Main {
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
Console.println("=== Troostwijk Auction Monitor ===\n");
|
|
|
|
// Parse command line arguments
|
|
String mode = args.length > 0 ? args[0] : "workflow";
|
|
|
|
// Configuration - Windows paths
|
|
String databaseFile = System.getenv().getOrDefault("DATABASE_FILE", "C:\\mnt\\okcomputer\\output\\cache.db");
|
|
String notificationConfig = System.getenv().getOrDefault("NOTIFICATION_CONFIG", "desktop");
|
|
|
|
// YOLO model paths (optional - monitor works without object detection)
|
|
String yoloCfg = "models/yolov4.cfg";
|
|
String yoloWeights = "models/yolov4.weights";
|
|
String yoloClasses = "models/coco.names";
|
|
|
|
// Load native OpenCV library (only if models exist)
|
|
try {
|
|
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
|
Console.println("✓ OpenCV loaded");
|
|
} catch (UnsatisfiedLinkError e) {
|
|
Console.println("⚠️ OpenCV not available - image detection disabled");
|
|
}
|
|
|
|
switch (mode.toLowerCase()) {
|
|
case "workflow":
|
|
runWorkflowMode(databaseFile, notificationConfig, yoloCfg, yoloWeights, yoloClasses);
|
|
break;
|
|
|
|
case "once":
|
|
runOnceMode(databaseFile, notificationConfig, yoloCfg, yoloWeights, yoloClasses);
|
|
break;
|
|
|
|
case "legacy":
|
|
runLegacyMode(databaseFile, notificationConfig, yoloCfg, yoloWeights, yoloClasses);
|
|
break;
|
|
|
|
case "status":
|
|
showStatus(databaseFile, notificationConfig, yoloCfg, yoloWeights, yoloClasses);
|
|
break;
|
|
|
|
default:
|
|
showUsage();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* WORKFLOW MODE: Run orchestrated scheduled workflows (default)
|
|
* This is the recommended mode for production use.
|
|
*/
|
|
private static void runWorkflowMode(String dbPath, String notifConfig,
|
|
String yoloCfg, String yoloWeights, String yoloClasses)
|
|
throws Exception {
|
|
|
|
Console.println("🚀 Starting in WORKFLOW MODE (Orchestrated Scheduling)\n");
|
|
|
|
WorkflowOrchestrator orchestrator = new WorkflowOrchestrator(
|
|
dbPath, notifConfig, yoloCfg, yoloWeights, yoloClasses
|
|
);
|
|
|
|
// Show initial status
|
|
orchestrator.printStatus();
|
|
|
|
// Start all scheduled workflows
|
|
orchestrator.startScheduledWorkflows();
|
|
|
|
Console.println("✓ All workflows are running");
|
|
Console.println(" - Scraper import: every 30 min");
|
|
Console.println(" - Image processing: every 1 hour");
|
|
Console.println(" - Bid monitoring: every 15 min");
|
|
Console.println(" - Closing alerts: every 5 min");
|
|
Console.println("\nPress Ctrl+C to stop.\n");
|
|
|
|
// Add shutdown hook
|
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
|
Console.println("\n🛑 Shutdown signal received...");
|
|
orchestrator.shutdown();
|
|
}));
|
|
|
|
// Keep application alive
|
|
try {
|
|
Thread.sleep(Long.MAX_VALUE);
|
|
} catch (InterruptedException e) {
|
|
Thread.currentThread().interrupt();
|
|
orchestrator.shutdown();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* ONCE MODE: Run complete workflow once and exit
|
|
* Useful for cron jobs or scheduled tasks.
|
|
*/
|
|
private static void runOnceMode(String dbPath, String notifConfig,
|
|
String yoloCfg, String yoloWeights, String yoloClasses)
|
|
throws Exception {
|
|
|
|
Console.println("🔄 Starting in ONCE MODE (Single Execution)\n");
|
|
|
|
WorkflowOrchestrator orchestrator = new WorkflowOrchestrator(
|
|
dbPath, notifConfig, yoloCfg, yoloWeights, yoloClasses
|
|
);
|
|
|
|
orchestrator.runCompleteWorkflowOnce();
|
|
|
|
Console.println("✓ Workflow execution completed. Exiting.\n");
|
|
}
|
|
|
|
/**
|
|
* LEGACY MODE: Original monitoring approach
|
|
* Kept for backward compatibility.
|
|
*/
|
|
private static void runLegacyMode(String dbPath, String notifConfig,
|
|
String yoloCfg, String yoloWeights, String yoloClasses)
|
|
throws Exception {
|
|
|
|
Console.println("⚙️ Starting in LEGACY MODE\n");
|
|
|
|
var monitor = new TroostwijkMonitor(dbPath, notifConfig,
|
|
yoloCfg, yoloWeights, yoloClasses);
|
|
|
|
Console.println("\n📊 Current Database State:");
|
|
monitor.printDatabaseStats();
|
|
|
|
Console.println("\n[1/2] Processing images...");
|
|
monitor.processPendingImages();
|
|
|
|
Console.println("\n[2/2] Starting bid monitoring...");
|
|
monitor.scheduleMonitoring();
|
|
|
|
Console.println("\n✓ Monitor is running. Press Ctrl+C to stop.\n");
|
|
Console.println("NOTE: This process expects auction/lot data from the external scraper.");
|
|
Console.println(" Make sure ARCHITECTURE-TROOSTWIJK-SCRAPER is running and populating the database.\n");
|
|
|
|
try {
|
|
Thread.sleep(Long.MAX_VALUE);
|
|
} catch (InterruptedException e) {
|
|
Thread.currentThread().interrupt();
|
|
Console.println("Monitor interrupted, exiting.");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* STATUS MODE: Show current status and exit
|
|
*/
|
|
private static void showStatus(String dbPath, String notifConfig,
|
|
String yoloCfg, String yoloWeights, String yoloClasses)
|
|
throws Exception {
|
|
|
|
Console.println("📊 Checking Status...\n");
|
|
|
|
WorkflowOrchestrator orchestrator = new WorkflowOrchestrator(
|
|
dbPath, notifConfig, yoloCfg, yoloWeights, yoloClasses
|
|
);
|
|
|
|
orchestrator.printStatus();
|
|
}
|
|
|
|
/**
|
|
* Show usage information
|
|
*/
|
|
private static void showUsage() {
|
|
Console.println("Usage: java -jar troostwijk-monitor.jar [mode]\n");
|
|
Console.println("Modes:");
|
|
Console.println(" workflow - Run orchestrated scheduled workflows (default)");
|
|
Console.println(" once - Run complete workflow once and exit (for cron)");
|
|
Console.println(" legacy - Run original monitoring approach");
|
|
Console.println(" status - Show current status and exit");
|
|
Console.println("\nEnvironment Variables:");
|
|
Console.println(" DATABASE_FILE - Path to SQLite database");
|
|
Console.println(" (default: C:\\mnt\\okcomputer\\output\\cache.db)");
|
|
Console.println(" NOTIFICATION_CONFIG - 'desktop' or 'smtp:user:pass:email'");
|
|
Console.println(" (default: desktop)");
|
|
Console.println("\nExamples:");
|
|
Console.println(" java -jar troostwijk-monitor.jar workflow");
|
|
Console.println(" java -jar troostwijk-monitor.jar once");
|
|
Console.println(" java -jar troostwijk-monitor.jar status");
|
|
IO.println();
|
|
}
|
|
|
|
/**
|
|
* Alternative entry point for container environments.
|
|
* Simply keeps the container alive for manual commands.
|
|
*/
|
|
public static void main2(String[] args) {
|
|
if (args.length > 0) {
|
|
Console.println("Command mode - exiting to allow shell commands");
|
|
return;
|
|
}
|
|
|
|
Console.println("Troostwijk Monitor container is running and healthy.");
|
|
Console.println("Use 'docker exec' or 'dokku run' to execute commands.");
|
|
|
|
try {
|
|
Thread.sleep(Long.MAX_VALUE);
|
|
} catch (InterruptedException e) {
|
|
Thread.currentThread().interrupt();
|
|
Console.println("Container interrupted, exiting.");
|
|
}
|
|
}
|
|
}
|