From cd0c2834912858f0d1b40917c6910962dcb33df7 Mon Sep 17 00:00:00 2001 From: michael1986 Date: Wed, 26 Nov 2025 13:05:04 +0100 Subject: [PATCH] start Former-commit-id: 47854d8b39e3a3542024f1d3e5eb977542b2ec53 --- QUICKSTART.md | 191 +++ README.md | 233 ++++ models/coco.names | 80 ++ models/yolov4.cfg | 1158 +++++++++++++++++ models/yolov4.weights.REMOVED.git-id | 1 + .../auction/scraper/TroostwijkScraper.java | 67 +- target/classes/com/auction/scraper/Main.class | Bin 0 -> 635 bytes .../TroostwijkScraper$DatabaseService.class | Bin 0 -> 7932 bytes .../scraper/TroostwijkScraper$Lot.class | Bin 0 -> 1128 bytes ...ostwijkScraper$NotificationService$1.class | Bin 0 -> 1161 bytes ...roostwijkScraper$NotificationService.class | Bin 0 -> 5720 bytes ...stwijkScraper$ObjectDetectionService.class | Bin 0 -> 5821 bytes .../auction/scraper/TroostwijkScraper.class | Bin 0 -> 15371 bytes troostwijk.db | Bin 0 -> 20480 bytes 14 files changed, 1718 insertions(+), 12 deletions(-) create mode 100644 QUICKSTART.md create mode 100644 README.md create mode 100644 models/coco.names create mode 100644 models/yolov4.cfg create mode 100644 models/yolov4.weights.REMOVED.git-id create mode 100644 target/classes/com/auction/scraper/Main.class create mode 100644 target/classes/com/auction/scraper/TroostwijkScraper$DatabaseService.class create mode 100644 target/classes/com/auction/scraper/TroostwijkScraper$Lot.class create mode 100644 target/classes/com/auction/scraper/TroostwijkScraper$NotificationService$1.class create mode 100644 target/classes/com/auction/scraper/TroostwijkScraper$NotificationService.class create mode 100644 target/classes/com/auction/scraper/TroostwijkScraper$ObjectDetectionService.class create mode 100644 target/classes/com/auction/scraper/TroostwijkScraper.class create mode 100644 troostwijk.db diff --git a/QUICKSTART.md b/QUICKSTART.md new file mode 100644 index 0000000..572e887 --- /dev/null +++ b/QUICKSTART.md @@ -0,0 +1,191 @@ +# Quick Start Guide + +Get the scraper running in minutes without downloading YOLO models! + +## Minimal Setup (No Object Detection) + +The scraper works perfectly fine **without** YOLO object detection. You can run it immediately and add object detection later if needed. + +### Step 1: Run the Scraper + +```bash +# Using Maven +mvn clean compile exec:java -Dexec.mainClass="com.auction.scraper.TroostwijkScraper" +``` + +Or in IntelliJ IDEA: +1. Open `TroostwijkScraper.java` +2. Right-click on the `main` method +3. Select "Run 'TroostwijkScraper.main()'" + +### What You'll See + +``` +=== Troostwijk Auction Scraper === + +Initializing scraper... +⚠️ Object detection disabled: YOLO model files not found + Expected files: + - models/yolov4.cfg + - models/yolov4.weights + - models/coco.names + Scraper will continue without image analysis. + +[1/3] Discovering Dutch auctions... +✓ Found 5 auctions: [12345, 12346, 12347, 12348, 12349] + +[2/3] Fetching lot details... + Processing sale 12345... + +[3/3] Starting monitoring service... +✓ Monitoring active. Press Ctrl+C to stop. +``` + +### Step 2: Test Desktop Notifications + +The scraper will automatically send desktop notifications when: +- A new bid is placed on a monitored lot +- An auction is closing within 5 minutes + +**No setup required** - desktop notifications work out of the box! + +--- + +## Optional: Add Email Notifications + +If you want email notifications in addition to desktop notifications: + +```bash +# Set environment variable +export NOTIFICATION_CONFIG="smtp:your.email@gmail.com:app_password:your.email@gmail.com" + +# Then run the scraper +mvn exec:java -Dexec.mainClass="com.auction.scraper.TroostwijkScraper" +``` + +**Get Gmail App Password:** +1. Enable 2FA in Google Account +2. Go to: Google Account → Security → 2-Step Verification → App passwords +3. Generate password for "Mail" +4. Use that password (not your regular Gmail password) + +--- + +## Optional: Add Object Detection Later + +If you want AI-powered image analysis to detect objects in auction photos: + +### 1. Create models directory +```bash +mkdir models +cd models +``` + +### 2. Download YOLO files +```bash +# YOLOv4 config (small) +curl -O https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov4.cfg + +# YOLOv4 weights (245 MB - takes a few minutes) +curl -LO https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights + +# COCO class names +curl -O https://raw.githubusercontent.com/AlexeyAB/darknet/master/data/coco.names +``` + +### 3. Run again +```bash +mvn exec:java -Dexec.mainClass="com.auction.scraper.TroostwijkScraper" +``` + +Now you'll see: +``` +✓ Object detection enabled with YOLO +``` + +The scraper will now analyze auction images and detect objects like: +- Vehicles (cars, trucks, forklifts) +- Equipment (machines, tools) +- Furniture +- Electronics +- And 80+ other object types + +--- + +## Features Without Object Detection + +Even without YOLO, the scraper provides: + +✅ **Full auction scraping** - Discovers all Dutch auctions +✅ **Lot tracking** - Monitors bids and closing times +✅ **Desktop notifications** - Real-time alerts +✅ **SQLite database** - All data persisted locally +✅ **Image downloading** - Saves all lot images +✅ **Scheduled monitoring** - Automatic updates every hour + +Object detection simply adds: +- AI-powered image analysis +- Automatic object labeling +- Searchable image database + +--- + +## Database Location + +The scraper creates `troostwijk.db` in your current directory with: +- All auction data +- Lot details (title, description, bids, etc.) +- Downloaded image paths +- Object labels (if detection enabled) + +View the database with any SQLite browser: +```bash +sqlite3 troostwijk.db +.tables +SELECT * FROM lots LIMIT 5; +``` + +--- + +## Stopping the Scraper + +Press **Ctrl+C** to stop the monitoring service. + +--- + +## Next Steps + +1. ✅ **Run the scraper** without YOLO to test it +2. ✅ **Verify desktop notifications** work +3. ⚙️ **Optional**: Add email notifications +4. ⚙️ **Optional**: Download YOLO models for object detection +5. 🔧 **Customize**: Edit monitoring frequency, closing alerts, etc. + +--- + +## Troubleshooting + +### Desktop notifications not appearing? +- **Windows**: Check if Java has notification permissions +- **Linux**: Ensure desktop environment is running (not headless) +- **macOS**: Check System Preferences → Notifications + +### OpenCV warnings? +These are normal and can be ignored: +``` +WARNING: A restricted method in java.lang.System has been called +WARNING: Use --enable-native-access=ALL-UNNAMED to avoid warning +``` + +The scraper works fine despite these warnings. + +--- + +## Full Documentation + +See [README.md](README.md) for complete documentation including: +- Email setup details +- YOLO installation guide +- Configuration options +- Database schema +- API endpoints diff --git a/README.md b/README.md new file mode 100644 index 0000000..e7f1ffa --- /dev/null +++ b/README.md @@ -0,0 +1,233 @@ +# 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" +``` + +## Project Structure + +``` +src/main/java/com/auction/scraper/ +├── TroostwijkScraper.java # Main scraper class +│ ├── Lot # Domain model for auction lots +│ ├── DatabaseService # SQLite operations +│ ├── NotificationService # Desktop + Email notifications (FREE) +│ └── ObjectDetectionService # OpenCV YOLO object detection +└── Main.java # Entry point +``` + +## 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. diff --git a/models/coco.names b/models/coco.names new file mode 100644 index 0000000..ca76c80 --- /dev/null +++ b/models/coco.names @@ -0,0 +1,80 @@ +person +bicycle +car +motorbike +aeroplane +bus +train +truck +boat +traffic light +fire hydrant +stop sign +parking meter +bench +bird +cat +dog +horse +sheep +cow +elephant +bear +zebra +giraffe +backpack +umbrella +handbag +tie +suitcase +frisbee +skis +snowboard +sports ball +kite +baseball bat +baseball glove +skateboard +surfboard +tennis racket +bottle +wine glass +cup +fork +knife +spoon +bowl +banana +apple +sandwich +orange +broccoli +carrot +hot dog +pizza +donut +cake +chair +sofa +pottedplant +bed +diningtable +toilet +tvmonitor +laptop +mouse +remote +keyboard +cell phone +microwave +oven +toaster +sink +refrigerator +book +clock +vase +scissors +teddy bear +hair drier +toothbrush diff --git a/models/yolov4.cfg b/models/yolov4.cfg new file mode 100644 index 0000000..a7be12b --- /dev/null +++ b/models/yolov4.cfg @@ -0,0 +1,1158 @@ +[net] +batch=64 +subdivisions=8 +# Training +#width=512 +#height=512 +width=608 +height=608 +channels=3 +momentum=0.949 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.0013 +burn_in=1000 +max_batches = 500500 +policy=steps +steps=400000,450000 +scales=.1,.1 + +#cutmix=1 +mosaic=1 + +#:104x104 54:52x52 85:26x26 104:13x13 for 416 + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=mish + +# Downsample + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=2 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -2 + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=32 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -1,-7 + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +# Downsample + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=2 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -2 + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=64 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -1,-10 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +# Downsample + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=2 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -2 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -1,-28 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +# Downsample + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=2 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -2 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -1,-28 + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +# Downsample + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=2 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -2 + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=mish + +[shortcut] +from=-3 +activation=linear + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=mish + +[route] +layers = -1,-16 + +[convolutional] +batch_normalize=1 +filters=1024 +size=1 +stride=1 +pad=1 +activation=mish + +########################## + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +### SPP ### +[maxpool] +stride=1 +size=5 + +[route] +layers=-2 + +[maxpool] +stride=1 +size=9 + +[route] +layers=-4 + +[maxpool] +stride=1 +size=13 + +[route] +layers=-1,-3,-5,-6 +### End SPP ### + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = 85 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -1, -3 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = 54 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[route] +layers = -1, -3 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +########################## + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=256 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=255 +activation=linear + + +[yolo] +mask = 0,1,2 +anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401 +classes=80 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +scale_x_y = 1.2 +iou_thresh=0.213 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +nms_kind=greedynms +beta_nms=0.6 +max_delta=5 + + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +size=3 +stride=2 +pad=1 +filters=256 +activation=leaky + +[route] +layers = -1, -16 + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=512 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=255 +activation=linear + + +[yolo] +mask = 3,4,5 +anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401 +classes=80 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +scale_x_y = 1.1 +iou_thresh=0.213 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +nms_kind=greedynms +beta_nms=0.6 +max_delta=5 + + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +size=3 +stride=2 +pad=1 +filters=512 +activation=leaky + +[route] +layers = -1, -37 + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +size=3 +stride=1 +pad=1 +filters=1024 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=255 +activation=linear + + +[yolo] +mask = 6,7,8 +anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401 +classes=80 +num=9 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +random=1 +scale_x_y = 1.05 +iou_thresh=0.213 +cls_normalizer=1.0 +iou_normalizer=0.07 +iou_loss=ciou +nms_kind=greedynms +beta_nms=0.6 +max_delta=5 + diff --git a/models/yolov4.weights.REMOVED.git-id b/models/yolov4.weights.REMOVED.git-id new file mode 100644 index 0000000..efd58d3 --- /dev/null +++ b/models/yolov4.weights.REMOVED.git-id @@ -0,0 +1 @@ +921f4406ecaa54a53031dd695e7bcd96f5dd9be2 \ No newline at end of file diff --git a/src/main/java/com/auction/scraper/TroostwijkScraper.java b/src/main/java/com/auction/scraper/TroostwijkScraper.java index b5ad33f..6d64fd8 100644 --- a/src/main/java/com/auction/scraper/TroostwijkScraper.java +++ b/src/main/java/com/auction/scraper/TroostwijkScraper.java @@ -354,6 +354,8 @@ public class TroostwijkScraper { * discovers Dutch auctions, scrapes lots, and begins monitoring. */ public static void main(String[] args) throws Exception { + System.out.println("=== Troostwijk Auction Scraper ===\n"); + // Configuration parameters (replace with your own values) String databaseFile = "troostwijk.db"; @@ -366,27 +368,34 @@ public class TroostwijkScraper { // Example: "smtp:your.email@gmail.com:abcd1234efgh5678:recipient@example.com" // Get app password: Google Account > Security > 2-Step Verification > App passwords - String yoloCfg = "models/yolov4.cfg"; // path to YOLO config file - String yoloWeights = "models/yolov4.weights"; // path to YOLO weights file - String yoloClasses = "models/coco.names"; // list of class names + // 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); + System.out.println("Initializing scraper..."); TroostwijkScraper scraper = new TroostwijkScraper(databaseFile, notificationConfig, "", yoloCfg, yoloWeights, yoloClasses); // Step 1: Discover auctions in NL + System.out.println("\n[1/3] Discovering Dutch auctions..."); List auctions = scraper.discoverDutchAuctions(); - System.out.println("Found auctions: " + auctions); + System.out.println("✓ Found " + auctions.size() + " auctions: " + auctions); // Step 2: Fetch lots for each auction + System.out.println("\n[2/3] Fetching lot details..."); for (int saleId : auctions) { + System.out.println(" Processing sale " + saleId + "..."); scraper.fetchLotsForSale(saleId); } // Step 3: Start monitoring bids and closures + System.out.println("\n[3/3] Starting monitoring service..."); scraper.scheduleMonitoring(); + System.out.println("✓ Monitoring active. Press Ctrl+C to stop.\n"); } // ---------------------------------------------------------------------- @@ -710,23 +719,53 @@ public class TroostwijkScraper { } /** - * Service for performing object detection on images using OpenCV’s DNN + * Service for performing object detection on images using OpenCV's DNN * module. The DNN module can load pre‑trained models from several * frameworks (Darknet, TensorFlow, ONNX, etc.)【784097309529506†L209-L233】. Here * we load a YOLO model (Darknet) by specifying the configuration and * weights files. For each image we run a forward pass and return a * list of detected class labels. + * + * If model files are not found, the service operates in disabled mode + * and returns empty lists. */ static class ObjectDetectionService { private final Net net; private final List classNames; + private final boolean enabled; + ObjectDetectionService(String cfgPath, String weightsPath, String classNamesPath) throws IOException { - // Load network - this.net = Dnn.readNetFromDarknet(cfgPath, weightsPath); - this.net.setPreferableBackend(DNN_BACKEND_OPENCV); - this.net.setPreferableTarget(DNN_TARGET_CPU); - // Load class names (one per line) - this.classNames = Files.readAllLines(Paths.get(classNamesPath)); + // Check if model files exist + Path cfgFile = Paths.get(cfgPath); + Path weightsFile = Paths.get(weightsPath); + Path classNamesFile = Paths.get(classNamesPath); + + if (!Files.exists(cfgFile) || !Files.exists(weightsFile) || !Files.exists(classNamesFile)) { + System.out.println("⚠️ Object detection disabled: YOLO model files not found"); + System.out.println(" Expected files:"); + System.out.println(" - " + cfgPath); + System.out.println(" - " + weightsPath); + System.out.println(" - " + classNamesPath); + System.out.println(" Scraper will continue without image analysis."); + this.enabled = false; + this.net = null; + this.classNames = new ArrayList<>(); + return; + } + + try { + // Load network + this.net = Dnn.readNetFromDarknet(cfgPath, weightsPath); + this.net.setPreferableBackend(DNN_BACKEND_OPENCV); + this.net.setPreferableTarget(DNN_TARGET_CPU); + // Load class names (one per line) + this.classNames = Files.readAllLines(classNamesFile); + this.enabled = true; + System.out.println("✓ Object detection enabled with YOLO"); + } catch (Exception e) { + System.err.println("⚠️ Object detection disabled: " + e.getMessage()); + throw new IOException("Failed to initialize object detection", e); + } } /** * Detects objects in the given image file and returns a list of @@ -736,9 +775,13 @@ public class TroostwijkScraper { * post‑processing【784097309529506†L324-L344】. * * @param imagePath absolute path to the image - * @return list of detected class names + * @return list of detected class names (empty if detection disabled) */ List detectObjects(String imagePath) { + if (!enabled) { + return new ArrayList<>(); + } + List labels = new ArrayList<>(); Mat image = Imgcodecs.imread(imagePath); if (image.empty()) return labels; diff --git a/target/classes/com/auction/scraper/Main.class b/target/classes/com/auction/scraper/Main.class new file mode 100644 index 0000000000000000000000000000000000000000..d400324056ade1da88d314be02d6490ffe3f6012 GIT binary patch literal 635 zcmZ{iO>fgc5Qg8)mlI>sCLw7Wpk1JcltX>w5QKy(^^{Vigj_gn+*P{4_Ezh45kCtK zAaURa@S_m3cBFum`Y@yU*yo+y@$WxBe*t)f6CV{+J=6l!(O}qLi#rj6{Mrrv*sq@V!x~omnGAGHIgCFq#{! zGy7SsKk>JDWR*_&EHdI&8Xx=Uc<2V`;Sob`2ZO=8b;LL&k#VU~j7t(KT}@6GO$->q z51Hg!p$(r$vB)xRH8*+6?TzGFDSYN($S{m_5{h!9a8n5{g(9iixxSVRdsCIlcX_gu zW-gX7Wx7)xiFhH5a`7fvvo|WEn@;ZoPKcNk;KBIgu1io|m=!U4JIW0HOy?$&7s`#$ zawDF(x56_V&_3N)0dpHAdq`18o{_J=`~mj0D38dxGEl{1vO(E^CwNLx3r9Gnj5~Z@ pz<|y-c-@EJvFCiB{1((E2+`^1XwVA1e}ElunhJz^PPT#P literal 0 HcmV?d00001 diff --git a/target/classes/com/auction/scraper/TroostwijkScraper$DatabaseService.class b/target/classes/com/auction/scraper/TroostwijkScraper$DatabaseService.class new file mode 100644 index 0000000000000000000000000000000000000000..7069d866f22bb227b8bd796be11da7680122769e GIT binary patch literal 7932 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 literal 0 HcmV?d00001 diff --git a/target/classes/com/auction/scraper/TroostwijkScraper$NotificationService.class b/target/classes/com/auction/scraper/TroostwijkScraper$NotificationService.class new file mode 100644 index 0000000000000000000000000000000000000000..526cd7538504728a06407b9ce1977b87ec2e5a96 GIT binary patch literal 5720 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 literal 0 HcmV?d00001 diff --git a/target/classes/com/auction/scraper/TroostwijkScraper.class b/target/classes/com/auction/scraper/TroostwijkScraper.class new file mode 100644 index 0000000000000000000000000000000000000000..c04fa8f80eb3f545064c12ad0310fc3fd02e880e GIT binary patch literal 15371 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 E18S_!bN~PV literal 0 HcmV?d00001 diff --git a/troostwijk.db b/troostwijk.db new file mode 100644 index 0000000000000000000000000000000000000000..729611b8976b7ffe671eebc822e2db8ae3ce89a7 GIT binary patch literal 20480 zcmeI#O>dhp7zc1@(&dzGmkRafV^GmFDPLeLb1Jlyc9c%b2|3isEb)?pQz^$*yG+`L z=tr%=kcMje0E_-ePVC1oJpP%BufNTNvRcW89-ESM} z-`uPJtJ*U@-2Wb`-u}=x-u-#|efXp*cpv})2tWV=5P$##AOHaf{PzM^{WsRxnK_qi zk?`^^QCF*|Z25CMs06ar<$6G_X!i%wJxeb=6muUMJ%! zLYgUm%h@TJ%4RQ3DP+QRHn+Tt3$d0W&vYPV*=EUNxhZ&|BXYZL25&hl+7~!6lYEsI zTRkY=6a~*@v{0{6=P`41Aa1&MFmaNXB3ngLq|KsjB+I2(3jU)0g-+d@Sx7!Q9kOOK z9kVJ{j@ll(Fb9@pnGX~F`Ba_th@%c$9U|?lc3=C4?d(A%x!UkfsZDyf4ZFIVt4lu~ z2tWV=5P$##AOHafKmY;|fB*yzSOE9`13p}A4FV8=00bZa0SG_<0uX=z1R&4|;Qo(K y0Rj+!00bZa0SG_<0uX=z1R!wu0=WMl{uyJ35P$##AOHafKmY;|fB*y_0D))dFzJi{ literal 0 HcmV?d00001