Skip to content

Latest commit

 

History

History
736 lines (592 loc) · 26.5 KB

File metadata and controls

736 lines (592 loc) · 26.5 KB

qBittorrent Handler

An automated torrent management system that integrates with qBittorrent's Web API to organize and process torrents based on their origin (Empornium, OneJav) and content type. The system handles categorization, file organization, cleanup of non-media files, and provides reliable monitoring alternatives to qBittorrent's external program feature.

Overview

This handler automatically manages torrents throughout their lifecycle:

  1. Torrent Addition: Identifies torrent origin from metadata/comments and assigns appropriate categories via qBittorrent API
  2. Download Completion: Processes finished downloads by moving video files to organized destinations, removing non-video content, and cleaning up source directories
  3. Reliable Monitoring: Uses periodic polling and systemd service to ensure no torrents are missed due to qBittorrent's unreliable external program execution

The system supports two operational modes:

  • Traditional Mode: Direct integration with qBittorrent's external program feature (less reliable in recent versions)
  • Monitor Mode: Recommended approach using continuous monitoring with periodic polling (production-ready)

Key Features

Torrent Origin Detection

  • Metadata Analysis: Parses torrent comments for "empornium" or "onejav" keywords (case-insensitive)
  • Tracker URL Fallback: Uses tracker patterns when metadata is unavailable
  • Category Inheritance: Uses qBittorrent category parameter to avoid race conditions
  • Default Handling: Graceful fallback for unknown sources

File Processing & Organization

  • Single-File Torrents: Direct rename/copy to destination with cross-filesystem support
  • Multi-File Torrents:
    • Removes non-video files (images, text files, metadata, etc.)
    • Creates subdirectories for torrents with 10+ video files
    • Preserves original filenames
  • Cross-Filesystem Moves: Automatic detection and fallback from rename to copy+remove
  • Protected Directories: Prevents accidental deletion of important folders
  • qBittorrent Auto-Move Detection: Skips redundant file operations when qBittorrent has already moved files

Video File Support

  • Supported Formats: MP4, MKV, AVI, MOV, WMV, FLV, WebM, M4V, MPG, MPEG, M2V, M2TS, TS, VOB, DIVX, 3GP, OGV, MTS, ASF
  • Image File Detection: JPG, JPEG, PNG, GIF, BMP, WebP, TIFF, TIF, SVG, RAW, HEIC, HEIF, ICO, PSD, AI, EPS, JFIF, AVIF (removed during cleanup)
  • Size Limits: Configurable maximum file size (default: 10GB)

Monitoring & Reliability

  • Polling Mode: Uses periodic polling of the qBittorrent API for reliable detection of completed torrents (trigger file support removed)
  • Fallback Polling: Checks for completed torrents every 5 minutes
  • Systemd Integration: Automatic startup, restart on failure, and log management
  • Duplicate Prevention: Tracks processed torrent hashes to avoid re-processing
  • Resource Limits: Memory (512MB) and CPU (50%) limits for stable operation

Error Handling & Logging

  • Comprehensive Logging: Detailed operation logs with timestamps
  • Error Tracking: Separate error log for troubleshooting
  • Retry Logic: Configurable API retries with exponential backoff
  • Graceful Degradation: Continues processing even if individual operations fail
  • Race Condition Protection: Uses category inheritance to avoid API timing issues

System Architecture

Traditional Mode (External Programs)

qBittorrent Event → torrentProcessor.js → handleAddedTorrent.js / handleFinishedTorrent.js → qBittorrent API

Pros: Direct, simple integration Cons: Unreliable execution in qBittorrent v5.1.2+, race conditions, limited error recovery

Monitor Mode (Recommended)

qBittorrent Event → monitor-torrents.js (polling) → handle* functions → qBittorrent API

Pros: Reliable, immediate response, continuous operation, comprehensive error handling Cons: Requires systemd service setup, additional file I/O

Components

Core Processing

  • torrentProcessor.js: Main entry point for traditional mode, parses qBittorrent arguments and routes to appropriate handlers
  • handleAddedTorrent.js: Categorizes newly added torrents based on origin detection
  • handleFinishedTorrent.js: Main processing logic for completed downloads including file movement, cleanup, and torrent removal
  • sharedFunctions.js:
    • getTorrentOrigin(): Determines torrent source from metadata/tracker
    • logMessage(): Unified logging system
    • execPromise(): Secure shell command execution with increased buffer limits
    • getConfig(): Lazy-loaded configuration management

Monitor System

-- monitor-torrents.js: Continuous monitoring service using periodic polling

  • Polls qBittorrent API for completed torrents every 5 minutes
  • Fallback polling for completed torrents every 5 minutes
  • Duplicate torrent hash tracking
  • Systemd/journald logging integration -- trigger-monitor.js (removed): Lightweight trigger script that was used to create JSON trigger files — no longer required by the monitor
  • qbittorrent-monitor.service: Systemd service file for automatic service management
    • Automatic startup on boot
    • Restart on failure (10s delay)
    • Resource limits (512MB memory, 50% CPU)
    • Secure paths and permissions

Configuration & Utilities

  • config.js: Centralized configuration with environment variable support and validation
    • qBittorrent API settings (host, port, auth)
    • File paths (destinations, temporary directories)
    • Processing options (retries, timeouts, file limits)
    • Logging configuration (files, levels, rotation)
    • OneJav fetcher settings
  • validate-config.js: Comprehensive setup validation tool
    • Tests qBittorrent API connectivity
    • Validates file paths and permissions
    • Tests module imports and logging
    • Provides configuration summary

Configuration

Environment Variables

All configuration is managed through environment variables with sensible defaults:

qBittorrent API

QB_HOST=localhost              # qBittorrent host
QB_PORT=12389                  # Web UI port (your setup)
QB_PROTOCOL=http               # HTTP/HTTPS
QB_USERNAME=admin              # Web UI username (if auth enabled)
QB_PASSWORD=yourpassword       # Web UI password

File Paths

EMPORNIUM_FINISHED_PATH="/mnt/ST26/Torrents/Fertig/Porn/EmporniumFinished/"
ONEJAV_FINISHED_PATH="/mnt/ST26/Torrents/Fertig/Porn/OnejavFinished/"
TEMP_DOWNLOAD_PATH="/mnt/Torrent/Torrents/Fertig"

Processing Settings

MAX_RETRIES=3                  # API retry attempts
API_TIMEOUT=30000              # API timeout in milliseconds
MAX_FILE_SIZE=10737418240      # Maximum file size (10GB)
CONCURRENT_OPS=5               # Maximum concurrent operations

Logging

LOG_FILE="./log.log"           # Main log file
ERROR_LOG_FILE="./error.log"   # Error log file
LOG_LEVEL="info"               # debug, info, warn, error
MAX_LOG_SIZE=1048576           # 1MB max log size

Protected Paths (Auto-configured)

The system automatically protects these directories from cleanup:

  • /mnt/Torrent/Torrents/Fertig/Porn/EmporniumFinished/
  • /mnt/Torrent/Torrents/Fertig/Porn/OnejavFinished/
  • /mnt/Torrent/Torrents/Fertig/Porn/

Default Configuration Paths

  • Empornium Destination: /mnt/ST26/Torrents/Fertig/Porn/EmporniumFinished/
  • OneJav Destination: /mnt/ST26/Torrents/Fertig/Porn/OnejavFinished/
  • Temporary Downloads: /mnt/Torrent/Torrents/Fertig
  • Logs: ./log.log and ./error.log
  • Trigger Files: Removed — the monitor does not use trigger files anymore; it relies on periodic polling

Installation & Setup

Prerequisites

  1. Deno: Version 1.40+ (install via curl -fsSL https://deno.land/install.sh | sh)
  2. qBittorrent: Version 5.1.2+ with Web UI enabled (port 12389 in your setup)
  3. System Access: Root access for systemd service installation
  4. File System: Write access to destination paths and log directories

Step-by-Step Setup

1. Clone and Prepare

git clone <repository-url>
cd qbittorrent_downloadhandler
chmod +x *.js  # Make scripts executable

2. Validate Configuration

# Test API connectivity and paths
deno run --allow-net --allow-read --allow-write --allow-env validate-config.js

Expected output:

🔍 Validating configuration...
✅ qBittorrent API connected (http://localhost:12389) - Version: 5.1.2
✅ Path exists: /mnt/ST26/Torrents/Fertig/Porn/EmporniumFinished/
✅ Path exists: /mnt/ST26/Torrents/Fertig/Porn/OnejavFinished/
✅ Path exists: /mnt/Torrent/Torrents/Fertig
✅ 19 video extensions configured
✅ 19 image extensions configured
✅ Configuration validation complete

3. Set Up Monitor System (Recommended)

# Copy systemd service
sudo cp qbittorrent-monitor.service /etc/systemd/system/

# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable qbittorrent-monitor.service
sudo systemctl start qbittorrent-monitor.service

# Verify service is running
sudo systemctl status qbittorrent-monitor.service

Service configuration (qbittorrent-monitor.service):

[Unit]
Description=qBittorrent Torrent Monitor Service
After=network.target

[Service]
Type=simple
User=franz
Group=franz
WorkingDirectory=/mnt/MG09/JD/IT/ownSoftware/qbittorrent_downloadhandler
ExecStart=/home/franz/.deno/bin/deno run --allow-net --allow-read --allow-write --allow-run --allow-env monitor-torrents.js
Restart=always
RestartSec=10
Environment=QB_PORT=12389

# Security
NoNewPrivileges=yes
ProtectHome=read-only
ProtectSystem=strict
ReadWritePaths=/mnt/MG09/JD/IT/ownSoftware/qbittorrent_downloadhandler /mnt/ST26/Torrents/Fertig/Porn /mnt/Torrent/Torrents/Fertig

# Resources
MemoryLimit=512M
CPUQuota=50%

StandardOutput=journal
StandardError=journal
SyslogIdentifier=qbittorrent-monitor

4. Configure qBittorrent External Programs

Monitor Mode (Recommended): No external program configuration is required — monitor-torrents.js runs as a systemd service and polls the qBittorrent API for completed torrents. If you prefer immediate processing on event, continue to use the Traditional Mode with torrentProcessor.js instead.

Traditional Mode (Fallback):

  • On torrent added:
    /home/franz/.deno/bin/deno run --allow-all /mnt/MG09/JD/IT/ownSoftware/qbittorrent_downloadhandler/torrentProcessor.js "%N" "%L" "%G" "%F" "%R" "%D" "%C" "%Z" "%T" "%I" "%J" "%K" added
    
  • On torrent finished:
    /home/franz/.deno/bin/deno run --allow-all /mnt/MG09/JD/IT/ownSoftware/qbittorrent_downloadhandler/torrentProcessor.js "%N" "%L" "%G" "%F" "%R" "%D" "%C" "%Z" "%T" "%I" "%J" "%K" finished
    

5. Test the Setup

# Start monitor service (polling)
sudo systemctl start qbittorrent-monitor.service

# Test traditional processor
deno run --allow-all torrentProcessor.js "TestTorrent" "onejav" "" "/tmp/testpath" "/tmp/root" "/tmp/save" "1" "1048576" "http://onejav.com" "testhash" "" "testid" "added"

# View logs
tail -f log.log

6. Verify Monitor Operation

# Check service logs
sudo journalctl -u qbittorrent-monitor.service -f

# Expected startup output:
# 🎬 Starting qBittorrent torrent monitor...
# 📊 Regular polling every 5 minutes
# ✅ Polling timer active

qBittorrent Integration Details

External Program Parameters

qBittorrent passes these parameters to external programs:

Parameter Variable Description
%N torrentName Name of the torrent
%L category Current torrent category
%G tags Torrent tags
%F contentPath Path to torrent content
%R rootPath Root path of torrent
%D savePath Save path configured in qBittorrent
%C numberOfFiles Number of files in torrent
%Z torrentSize Total size in bytes
%T currentTracker Current tracker URL
%I v1hash Info hash v1
%J v2hash Info hash v2
%K torrentId Internal torrent ID
%S programStatus Event type: added, finished

API Endpoints Used

The handler interacts with qBittorrent's Web API (version 2):

  • Authentication: Automatic login on first API call
  • Version Check: GET /api/v2/app/version
  • Torrent Info: GET /api/v2/torrents/info?hashes={hash}
  • Set Category: POST /api/v2/torrents/setCategory
  • Get Files: GET /api/v2/torrents/files?hash={hash}
  • Delete Torrent: POST /api/v2/torrents/delete?hashes={hash}&deleteFiles={true/false}

Category Management

The system uses these categories:

  • empornium: For torrents from Empornium tracker
  • onejav: For torrents from OneJav/Sukebei trackers
  • uncategorized: Default when origin detection fails

File Processing Workflow

Single-File Torrent

1. Check if file is already in destination
2. If not: rename to target path (or copy+remove if cross-filesystem)
3. Remove empty parent directory (if not protected)
4. Remove torrent from qBittorrent

Multi-File Torrent

1. Count video files via qBittorrent API
2. Remove non-video files from content directory
3. Determine target: flat directory or subdirectory (if ≥10 videos)
4. Move all remaining files to target directory
5. Create subdirectory if needed (sanitized torrent name)
6. Remove empty source directory (if not protected)
7. Remove torrent from qBittorrent

Protected Directory Logic

Directories matching these patterns are never deleted:

  • /mnt/Torrent/Torrents/Fertig/Porn/EmporniumFinished/
  • /mnt/Torrent/Torrents/Fertig/Porn/OnejavFinished/
  • /mnt/Torrent/Torrents/Fertig/Porn/

Before deletion, the system verifies directories are empty to prevent accidental data loss.

Troubleshooting

Common Issues & Solutions

1. Monitor Service Won't Start

Symptoms: systemctl status qbittorrent-monitor.service shows errors Solutions:

# Check service logs
sudo journalctl -u qbittorrent-monitor.service -n 50

# Verify Deno path
which deno
ls -la /home/franz/.deno/bin/deno

# Check working directory permissions
ls -la /mnt/MG09/JD/IT/ownSoftware/qbittorrent_downloadhandler/

# Test manual execution
cd /mnt/MG09/JD/IT/ownSoftware/qbittorrent_downloadhandler
/home/franz/.deno/bin/deno run --allow-net --allow-read --allow-write --allow-run --allow-env monitor-torrents.js

Service File Issues:

  • Update ExecStart with correct Deno path
  • Verify WorkingDirectory exists and is accessible
  • Check ReadWritePaths match your mount points
  • Ensure User/Group exist and have permissions

2. qBittorrent API Connection Failed

Symptoms: Log shows "Failed to get torrent info" or validation fails Solutions:

# Test API connectivity
curl "http://localhost:12389/api/v2/app/version"

# Check qBittorrent Web UI settings
# Tools → Options → Web UI → Enable Web UI (port 12389)

# Verify environment variables
echo $QB_PORT  # Should be 12389
echo $QB_HOST  # Should be localhost

# Test with authentication (if enabled)
curl -u admin:yourpassword "http://localhost:12389/api/v2/auth/login"

3. Files Not Moving to Destination

Symptoms: Torrents complete but files remain in download directory Solutions:

# Check log for specific errors
grep "Error moving files" log.log
grep "cross-device" log.log

# Verify destination paths exist and are writable
ls -la /mnt/ST26/Torrents/Fertig/Porn/EmporniumFinished/
touch /mnt/ST26/Torrents/Fertig/Porn/EmporniumFinished/test.txt
rm /mnt/ST26/Torrents/Fertig/Porn/EmporniumFinished/test.txt

# Test cross-filesystem move manually
ls -la /tmp/testfile
mv /tmp/testfile /mnt/ST26/Torrents/Fertig/Porn/testfile 2>&1

# Check if qBittorrent auto-move is enabled
# Tools → Options → Downloads → Keep incomplete torrents in and move completed to

4. Torrents Not Being Categorized

Symptoms: Torrents show as "uncategorized" or wrong category Solutions:

# Check origin detection logs
grep "Determined origin" log.log

# Test manual categorization
curl -X POST "http://localhost:12389/api/v2/torrents/setCategory" \
  -d "hashes=testid123&category=onejav"

# Verify torrent comments contain expected keywords
curl "http://localhost:12389/api/v2/torrents/info?hashes=testid123" | jq '.[0].comment'

# Check tracker URLs
curl "http://localhost:12389/api/v2/torrents/info?hashes=testid123" | jq '.[0].trackers[] | .url'

5. Non-Video Files Not Being Removed

Symptoms: Images, text files, or metadata remain after processing Solutions:

# Check video extension matching
grep -A 10 "videoExtensions" config.js

# Test file detection manually
deno run --allow-read test-file-detection.js image.jpg  # Should return false for non-videos

# Verify cleanup logs
grep "Removed non-video file" log.log

# Check protected directories
grep "Skipping deletion of protected directory" log.log

6. Duplicate Processing or Missed Torrents

Symptoms: Same torrent processed multiple times or some torrents skipped Solutions:

# Check processed torrent tracking (monitor mode)
grep "Already processed" log.log

# Verify monitor operation
# Check that the monitor performs regular polling and processes torrents as expected
grep "Regular polling check" log.log
grep "Found.*completed torrent" log.log

# Check fallback polling
grep "Regular polling check" log.log

# Monitor service for missed events
sudo journalctl -u qbittorrent-monitor.service | grep "Found.*completed torrent"

Log Analysis Commands

Real-time Monitoring

# Monitor main application log
tail -f log.log

# Monitor service log
sudo journalctl -u qbittorrent-monitor.service -f

# Monitor both simultaneously
multitail log.log -cS qbittorrent '(sudo journalctl -u qbittorrent-monitor.service -f)'

Error Investigation

# Find recent errors
grep "ERROR\|Failed\|Exception" log.log | tail -20

# Cross-reference with service logs
sudo journalctl -u qbittorrent-monitor.service --since "1 hour ago" | grep -i error

# Find specific torrent issues
grep "torrentId: abc123" log.log

Performance Analysis

# Check processing times
grep "Processed torrent" log.log | awk '{print $1, $NF}' | sort | uniq -c

# Monitor API call success rate
grep "curl.*api/v2" log.log | wc -l
grep "Failed to.*API" log.log | wc -l

# File operation statistics
grep "Moved\|Copied\|Removed" log.log | sort | uniq -c

Advanced Debugging

Enable Debug Logging

export LOG_LEVEL=debug
# Restart monitor service
sudo systemctl restart qbittorrent-monitor.service

API Response Debugging

Add to sharedFunctions.js for detailed API responses:

// In execPromise function, before return
if (command.includes('/api/v2/')) {
    console.log(`API Response [${command}]:`, stdout.substring(0, 1000));
}

File System Debugging

Test file operations manually:

# Test single file move
deno run --allow-read --allow-write single-file-test.js /tmp/source.mp4 /mnt/ST26/Torrents/Fertig/Porn/EmporniumFinished/

# Test multi-file cleanup
deno run --allow-read --allow-write multi-file-test.js /tmp/test-torrent/ /mnt/ST26/Torrents/Fertig/Porn/OnejavFinished/

Performance Considerations

Resource Usage

  • Memory: Monitor service limited to 512MB
  • CPU: 50% quota prevents system impact
  • Disk I/O: Minimal during normal operation, spikes during file processing
  • Network: Only qBittorrent API calls (local), no external dependencies during processing

Scaling

  • Concurrent Operations: Limited to 5 simultaneous file operations
  • Large Torrents: Handles torrents up to 10GB by default (configurable)
  • High Volume: Processes multiple torrents sequentially, suitable for 50-100 torrents/day

Optimization Tips

  1. Use SSDs for temporary download paths to speed up file operations
  2. Same Filesystem for source and destination when possible (avoids copy+remove)
  3. Pre-create Directories to avoid permission issues during processing
  4. Monitor Logs Regularly to catch issues early
  5. Regular Backups of log files for troubleshooting

Security & Best Practices

qBittorrent Security

  • Web UI Access: Restrict to localhost only (127.0.0.1:12389)
  • Strong Authentication: Use complex username/password for Web UI
  • API Permissions: Handler only needs read/write torrent operations
  • Network Isolation: No external network access required for core functions

File System Security

  • Path Validation: All paths validated against protected directories
  • Sanitization: Torrent names sanitized for subdirectory creation
  • Permission Checks: Verify write access before file operations
  • Error Handling: Graceful failures prevent system crashes

Service Security

  • Systemd Hardening:
    • NoNewPrivileges=yes: Prevents privilege escalation
    • ProtectHome=read-only: Prevents home directory access
    • ProtectSystem=strict: Prevents system file modification
    • ReadWritePaths: Explicitly limits filesystem access
  • User Isolation: Runs as non-root user (franz)
  • Resource Limits: Prevents resource exhaustion attacks

Log Security

  • Sensitive Data: API responses filtered to remove passwords
  • File Permissions: Logs readable only by service user
  • Rotation: Configurable log rotation prevents disk exhaustion
  • Audit Trail: Comprehensive logging for troubleshooting and compliance

Integration with Other Tools

OneJav Fetcher Integration

The handler works seamlessly with the OneJav Torrent Fetcher:

  1. Automated Fetching: fetchOnejav.js downloads torrents to ./torrents/
  2. Automatic Processing: qBittorrent loads torrents and handler categorizes them
  3. Origin Detection: OneJav torrents automatically detected and organized

Usage workflow:

# 1. Fetch new torrents (cron job)
0 8 * * * cd /path/to/project && deno run --allow-net --allow-write fetchOnejav.js >> fetch.log 2>&1

# 2. qBittorrent loads torrents from watch directory
# 3. Handler automatically processes and organizes

Log Management

Integrate with log rotation tools:

# /etc/logrotate.d/qbittorrent-handler
/mnt/MG09/JD/IT/ownSoftware/qbittorrent_downloadhandler/log.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    create 644 franz franz
    postrotate
        systemctl reload qbittorrent-monitor.service
    endscript
}

Monitoring & Alerts

Add to monitoring systems:

# Check service health
systemctl is-active --quiet qbittorrent-monitor.service && echo "OK" || echo "CRITICAL"

# Check recent processing
[ $(grep "Successfully processed" log.log | wc -l) -gt 0 ] && echo "OK" || echo "WARNING"

# Alert on errors
grep "Failed to process\|CRITICAL" log.log | tail -1 | grep -q . && echo "ALERT: Processing errors detected"

Development & Maintenance

Code Structure

src/
├── config/          # Configuration management
│   └── config.js
├── core/            # Main processing logic
│   ├── handleAddedTorrent.js
│   ├── handleFinishedTorrent.js
│   └── torrentProcessor.js
├── monitor/         # Monitoring system
│   ├── monitor-torrents.js
│   └── (trigger-monitor.js removed)
├── utils/           # Shared utilities
│   └── sharedFunctions.js
└── tools/           # Maintenance tools
    └── validate-config.js

Testing Strategy

  1. Unit Tests: Test individual functions (planned enhancement)
  2. Integration Tests: Validate end-to-end workflows
  3. Configuration Tests: validate-config.js for setup verification
  4. Manual Testing: Use test_args.txt for command-line testing

Planned Enhancements (from todo.md)

  1. Configuration Health Checks: Integrate validation into systemd service
  2. Automatic Log Rotation: Implement file size/date-based rotation
  3. Additional Sources: Extensible origin detection framework
  4. Test Suite: Comprehensive Deno test framework integration
  5. Web Dashboard: Monitoring interface for status and configuration

Version History

  • v1.0: Initial external program implementation
  • v1.1: Cross-filesystem moves, error handling improvements
  • v1.2: Race condition fixes, buffer limit increases
  • v2.0: Monitor system with file watching and systemd integration (current)

Usage Examples

Testing Origin Detection

# Test with Empornium-like comment
echo '{"comment": "Empornium - Movie Title"}' | \
curl -X POST "http://localhost:12389/api/v2/torrents/info?hashes=test123" -d @- | \
jq '.comment'

# Expected: handler detects "empornium" and sets category

Manual File Processing Test

Create test directory:

mkdir -p /tmp/test-torrent/{videos,images}
touch /tmp/test-torrent/videos/movie.mp4
touch /tmp/test-torrent/images/poster.jpg
touch /tmp/test-torrent/info.nfo

# Test processing
deno run --allow-all handleFinishedTorrent.js test123 "Test Movie" "/tmp/test-torrent" "onejav" ""

# Verify: only movie.mp4 moved, others removed
ls /mnt/ST26/Torrents/Fertig/Porn/OnejavFinished/

Monitor Polling Test

# Ensure monitor service is running
sudo systemctl start qbittorrent-monitor.service

# Create a sample torrent using the traditional processor to simulate an event (or use the UI)
deno run --allow-all torrentProcessor.js "TestTrigger" "onejav" "" "/tmp/completed" "/tmp/root" "/tmp/save" "5" "5242880" "udp://tracker.onejav.com" "triggerhash" "" "triggerid" "finished"

# Verify monitor processes it via logs
sudo journalctl -u qbittorrent-monitor.service -f

Support & Community

Getting Help

  1. Check Logs: Start with tail -f log.log and service logs
  2. Validation: Run validate-config.js for setup issues
  3. Documentation: Refer to this file and main README
  4. Issues: Check todo.md for known limitations

Contributing

  1. Bug Reports: Include log excerpts and reproduction steps
  2. Features: Open issues for discussion before implementation
  3. Code: Follow Deno style guidelines, add tests
  4. Documentation: Keep docs updated with code changes

Known Limitations

  • qBittorrent v5.1.2: External program feature unreliable (use monitor mode)
  • Cross-Filesystem: Copy+remove slower than rename (inherent limitation)
  • Large Torrents: API responses limited to 10MB (configurable)
  • Single Origin: Currently supports only Empornium/OneJav (extensible)

Current Status: Production-ready with monitor system. Handles 100+ torrents daily reliably.

Next Steps: See todo.md for planned enhancements including log rotation, additional sources, and comprehensive testing.

Created: October 2025
Updated: Based on current codebase analysis