# Troostwijk Auction Scraper A Java-based web scraper for Dutch auctions on Troostwijk Auctions with **100% free** desktop/email notifications, SQLite persistence, and AI-powered object detection. ## Features - **Auction Discovery**: Automatically discovers active Dutch auctions - **Data Scraping**: Fetches detailed lot information via Troostwijk's JSON API - **SQLite Storage**: Persists auction data, lots, images, and detected objects - **Image Processing**: Downloads and analyzes lot images using OpenCV YOLO object detection - **Free Notifications**: Real-time notifications when: - Bids change on monitored lots - Auctions are closing soon (within 5 minutes) - Via desktop notifications (Windows/macOS/Linux system tray) βœ… - Optionally via email (Gmail SMTP - free) βœ… ## Dependencies All dependencies are managed via Maven (see `pom.xml`): - **jsoup 1.17.2** - HTML parsing and HTTP client - **Jackson 2.17.0** - JSON processing - **SQLite JDBC 3.45.1.0** - Database operations - **JavaMail 1.6.2** - Email notifications (free) - **OpenCV 4.9.0** - Image processing and object detection ## Setup ### 1.. Notification Options (Choose One) #### Option A: Desktop Notifications Only ⭐ (Recommended - Zero Setup) Desktop notifications work out of the box on: - **Windows**: System tray notifications - **macOS**: Notification Center - **Linux**: Desktop environment notifications (GNOME, KDE, etc.) **No configuration required!** Just run with default settings: ```bash export NOTIFICATION_CONFIG="desktop" # Or simply don't set it - desktop is the default ``` #### Option B: Desktop + Email Notifications πŸ“§ (Free Gmail) 1. Enable 2-Factor Authentication in your Google Account 2. Go to: **Google Account β†’ Security β†’ 2-Step Verification β†’ App passwords** 3. Generate an app password for "Mail" 4. Set environment variable: ```bash export NOTIFICATION_CONFIG="smtp:your.email@gmail.com:your_app_password:recipient@example.com" ``` **Format**: `smtp:username:app_password:recipient_email` **Example**: ```bash export NOTIFICATION_CONFIG="smtp:john.doe@gmail.com:abcd1234efgh5678:john.doe@gmail.com" ``` **Note**: This is completely free using Gmail's SMTP server. No paid services required! ### 2. OpenCV Native Libraries Download and install OpenCV native libraries for your platform: **Windows:** ```bash # Download from https://opencv.org/releases/ # Extract and add to PATH or use: java -Djava.library.path="C:\opencv\build\java\x64" -jar scraper.jar ``` **Linux:** ```bash sudo apt-get install libopencv-dev ``` **macOS:** ```bash brew install opencv ``` ### 3. YOLO Model Files Download YOLO model files for object detection: ```bash mkdir models cd models # Download YOLOv4 config wget https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov4.cfg # Download YOLOv4 weights (245 MB) wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights # Download COCO class names wget https://raw.githubusercontent.com/AlexeyAB/darknet/master/data/coco.names ``` ## Building ```bash mvn clean package ``` This creates: - `target/troostwijk-scraper-1.0-SNAPSHOT.jar` - Regular JAR - `target/troostwijk-scraper-1.0-SNAPSHOT-jar-with-dependencies.jar` - Executable JAR with all dependencies ## Running ### Quick Start (Desktop Notifications Only) ```bash java -Djava.library.path="/path/to/opencv/lib" \ -jar target/troostwijk-scraper-1.0-SNAPSHOT-jar-with-dependencies.jar ``` ### With Email Notifications ```bash export NOTIFICATION_CONFIG="smtp:your@gmail.com:app_password:your@gmail.com" java -Djava.library.path="/path/to/opencv/lib" \ -jar target/troostwijk-scraper-1.0-SNAPSHOT-jar-with-dependencies.jar ``` ### Using Maven ```bash mvn exec:java -Dexec.mainClass="com.auction.scraper.TroostwijkScraper" ``` ## System Architecture & Integration Flow ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ COMPLETE SYSTEM INTEGRATION DIAGRAM β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PHASE 1: EXTERNAL SCRAPER (Python/Playwright) - ARCHITECTURE-TROOSTWIJK β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β–Ό β–Ό β–Ό [Listing Pages] [Auction Pages] [Lot Pages] /auctions?page=N /a/auction-id /l/lot-id β”‚ β”‚ β”‚ β”‚ Extract URLs β”‚ Parse __NEXT_DATA__ β”‚ Parse __NEXT_DATA__ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”‚ JSON β”‚ JSON β”‚ β”‚ β”‚ β”‚ β–Ό β–Ό β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ INSERT auctionsβ”‚ β”‚ INSERT lots β”‚ β”‚ β”‚ to SQLite β”‚ β”‚ INSERT images β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ (URLs only) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ SQLITE DATABASE β”‚ β”‚ troostwijk.db β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β–Ό β–Ό β–Ό [auctions table] [lots table] [images table] - auction_id - lot_id - id - title - auction_id - lot_id - location - title - url - lots_count - current_bid - local_path - closing_time - bid_count - downloaded=0 - closing_time β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PHASE 2: MONITORING & PROCESSING (Java) - THIS PROJECT β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β–Ό β–Ό β–Ό [TroostwijkMonitor] [DatabaseService] [ScraperDataAdapter] β”‚ β”‚ β”‚ β”‚ Read lots β”‚ Query lots β”‚ Transform data β”‚ every hour β”‚ Import images β”‚ TEXT β†’ INTEGER β”‚ β”‚ β”‚ "€123" β†’ 123.0 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β–Ό β–Ό β–Ό [Bid Monitoring] [Image Processing] [Closing Alerts] Check API every 1h Download images Check < 5 min β”‚ β”‚ β”‚ β”‚ New bid? β”‚ Process via β”‚ Time critical? β”œβ”€[YES]──────────┐ β”‚ ObjectDetection β”œβ”€[YES]────┐ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β–Ό β”‚ β”‚ [Update current_bid] β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ in database β”‚ β”‚ YOLO Detection β”‚ β”‚ β”‚ β”‚ β”‚ OpenCV DNN β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Detect objects β”‚ β”‚ β”‚ β”œβ”€[vehicle] β”‚ β”‚ β”‚ β”œβ”€[furniture] β”‚ β”‚ β”‚ β”œβ”€[machinery] β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”‚ [Save labels to DB] β”‚ β”‚ β”‚ [Estimate value] β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PHASE 3: NOTIFICATION SYSTEM - USER INTERACTION TRIGGERS β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β–Ό β–Ό [NotificationService] [User Decision Points] β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β–Ό β–Ό β–Ό β”‚ [Desktop Notify] [Email Notify] [Priority Level] β”‚ Windows/macOS/ Gmail SMTP 0=Normal β”‚ Linux system (FREE) 1=High β”‚ tray β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ USER INTERACTION β”‚ β”‚ TRIGGER EVENTS: β”‚ β”‚ NOTIFICATIONS β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β–Ό β–Ό β–Ό β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ 1. BID CHANGE β”‚ β”‚ 2. OBJECT β”‚ β”‚ 3. CLOSING β”‚ β”‚ β”‚ β”‚ β”‚ DETECTED β”‚ β”‚ ALERT β”‚ β”‚ β”‚ "Nieuw bod op β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ kavel 12345: β”‚ β”‚ "Lot contains: β”‚ β”‚ "Kavel 12345 β”‚ β”‚ β”‚ €150 (was €125)"β”‚ β”‚ - Vehicle β”‚ β”‚ sluit binnen β”‚ β”‚ β”‚ β”‚ β”‚ - Machinery β”‚ β”‚ 5 min." β”‚ β”‚ β”‚ Priority: NORMAL β”‚ β”‚ Est: €5000" β”‚ β”‚ Priority: HIGH β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Action needed: β”‚ β”‚ Action needed: β”‚ β”‚ Action needed: β”‚ β”‚ β”‚ β–Έ Place bid? β”‚ β”‚ β–Έ Review item? β”‚ β”‚ β–Έ Place final β”‚ β”‚ β”‚ β–Έ Monitor? β”‚ β”‚ β–Έ Confirm value? β”‚ β”‚ bid? β”‚ β”‚ β”‚ β–Έ Ignore? β”‚ β”‚ β–Έ Add to watch? β”‚ β”‚ β–Έ Let expire? β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ USER ACTIONS & EXCEPTIONS β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Additional interaction points: β”‚ β”‚ β”‚ β”‚ 4. VIEWING DAY QUESTIONS β”‚ β”‚ "Bezichtiging op [date] - kunt u aanwezig zijn?" β”‚ β”‚ Action: β–Έ Confirm attendance β–Έ Request alternative β–Έ Decline β”‚ β”‚ β”‚ β”‚ 5. ITEM RECOGNITION CONFIRMATION β”‚ β”‚ "Detected: [object] - Is deze correcte identificatie?" β”‚ β”‚ Action: β–Έ Confirm β–Έ Correct label β–Έ Add notes β”‚ β”‚ β”‚ β”‚ 6. VALUE ESTIMATE APPROVAL β”‚ β”‚ "Geschatte waarde: €X - Akkoord?" β”‚ β”‚ Action: β–Έ Accept β–Έ Adjust β–Έ Request manual review β”‚ β”‚ β”‚ β”‚ 7. EXCEPTION HANDLING β”‚ β”‚ "Afwijkende sluitingstijd / locatiewijziging / special terms" β”‚ β”‚ Action: β–Έ Acknowledge β–Έ Update preferences β–Έ Withdraw interest β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ OBJECT DETECTION & VALUE ESTIMATION PIPELINE β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ [Downloaded Image] β†’ [ImageProcessingService] β”‚ β”‚ β”‚ β–Ό β”‚ [ObjectDetectionService] β”‚ β”‚ β”‚ β”œβ”€ Load YOLO model β”‚ β”œβ”€ Run inference (416x416) β”‚ β”œβ”€ Post-process detections β”‚ β”‚ (confidence > 0.5) β”‚ β”‚ β”‚ β–Ό β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ Detected Objects: β”‚ β”‚ β”‚ - person β”‚ β”‚ β”‚ - car β”‚ β”‚ β”‚ - truck β”‚ β”‚ β”‚ - furniture β”‚ β”‚ β”‚ - machinery β”‚ β”‚ β”‚ - electronics β”‚ β”‚ β”‚ (80 COCO classes) β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β–Ό β”‚ [Value Estimation Logic] β”‚ (Future enhancement) β”‚ β”‚ β”‚ β”œβ”€ Match objects to auction categories β”‚ β”œβ”€ Historical price analysis β”‚ β”œβ”€ Condition assessment β”‚ β”œβ”€ Market trends β”‚ β”‚ β”‚ β–Ό β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ Estimated Value: β”‚ β”‚ β”‚ €X - €Y range β”‚ β”‚ β”‚ Confidence: 75% β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ └──────────────────────┴─ [Save to DB] β”‚ β–Ό [Trigger notification if value > threshold] ``` ## Integration Hooks & Timing | Event | Frequency | Trigger | Notification Type | User Action Required | |-------|-----------|---------|-------------------|---------------------| | **New auction discovered** | On scrape | Scraper finds new auction | Desktop + Email (optional) | Review auction | | **Bid change detected** | Every 1 hour | Monitor detects higher bid | Desktop + Email | Place counter-bid? | | **Closing soon (< 30 min)** | When detected | Time-based check | Desktop + Email | Review lot | | **Closing imminent (< 5 min)** | When detected | Time-based check | Desktop + Email (HIGH) | Final bid decision | | **Object detected** | On image process | YOLO finds objects | Desktop + Email | Confirm identification | | **Value estimated** | After detection | Estimation complete | Desktop + Email | Approve estimate | | **Viewing day scheduled** | From lot metadata | Scraper extracts date | Desktop + Email | Confirm attendance | | **Exception/Change** | On update | Scraper detects change | Desktop + Email (HIGH) | Acknowledge | ## Project Structure ``` src/main/java/com/auction/ β”œβ”€β”€ Main.java # Entry point β”œβ”€β”€ TroostwijkMonitor.java # Monitoring & orchestration β”œβ”€β”€ DatabaseService.java # SQLite operations β”œβ”€β”€ ScraperDataAdapter.java # Schema translation (TEXTβ†’INT, €→float) β”œβ”€β”€ ImageProcessingService.java # Downloads & processes images β”œβ”€β”€ ObjectDetectionService.java # OpenCV YOLO detection β”œβ”€β”€ NotificationService.java # Desktop + Email notifications (FREE) β”œβ”€β”€ Lot.java # Domain model for auction lots β”œβ”€β”€ AuctionInfo.java # Domain model for auctions └── Console.java # Logging utility ``` ## Configuration Edit `TroostwijkScraper.main()` to customize: - **Database file**: `troostwijk.db` (SQLite database location) - **YOLO paths**: Model configuration and weights files - **Monitoring frequency**: Default is every 1 hour - **Closing alerts**: Default is 5 minutes before closing ## Database Schema The scraper creates three tables: **sales** - `sale_id` (PRIMARY KEY) - `title`, `location`, `closing_time` **lots** - `lot_id` (PRIMARY KEY) - `sale_id`, `title`, `description`, `manufacturer`, `type`, `year` - `category`, `current_bid`, `currency`, `url` - `closing_time`, `closing_notified` **images** - `id` (PRIMARY KEY) - `lot_id`, `url`, `file_path`, `labels` (detected objects) ## Notification Examples ### Desktop Notification ![System Tray Notification] ``` πŸ”” Kavel bieding update Nieuw bod op kavel 12345: €150.00 (was €125.00) ``` ### Email Notification ``` From: your.email@gmail.com To: your.email@gmail.com Subject: [Troostwijk] Kavel bieding update Nieuw bod op kavel 12345: €150.00 (was €125.00) ``` **High Priority Alerts** (closing soon): ``` ⚠️ Lot nearing closure Kavel 12345 sluit binnen 5 min. ``` ## Why This Approach? βœ… **100% Free** - No paid services (Twilio, Pushover, etc.) βœ… **No External Dependencies** - Desktop notifications built into Java βœ… **Works Offline** - Desktop notifications don't need internet βœ… **Privacy First** - Your data stays on your machine βœ… **Cross-Platform** - Windows, macOS, Linux supported βœ… **Optional Email** - Add Gmail notifications if you want ## Troubleshooting ### Desktop Notifications Not Showing - **Windows**: Check if Java has notification permissions - **Linux**: Ensure you have a desktop environment running (not headless) - **macOS**: Check System Preferences β†’ Notifications ### Email Not Sending 1. Verify 2FA is enabled in Google Account 2. Confirm you're using an **App Password** (not your regular Gmail password) 3. Check that "Less secure app access" is NOT needed (app passwords work with 2FA) 4. Verify the SMTP format: `smtp:username:app_password:recipient` ## Notes - Desktop notifications require a graphical environment (not headless servers) - For headless servers, use email-only notifications - Gmail SMTP is free and has generous limits (500 emails/day) - OpenCV native libraries must match your platform architecture - YOLO weights file is ~245 MB ## License This is example code for educational purposes.