Skip to content

Triggers

Stephen Cox edited this page Dec 10, 2025 · 3 revisions

Triggers determine when and how rules execute.

Overview

Trigger Use Case Execution Method Torrent Scope Best For
manual Testing, one-off operations CLI command All torrents Development, troubleshooting
scheduled Periodic maintenance Cron job All torrents Cleanup, ratio enforcement
on_added React to new torrents qBittorrent webhook Single torrent Content filtering, auto-categorization
on_completed React to finished downloads qBittorrent webhook Single torrent Post-download actions, seeding rules

Manual Trigger

Description: Direct execution from command line. Ideal for testing rules, debugging issues, and performing one-off operations.

Script: triggers/manual.py

Usage:

# Run all rules against all torrents
python3 triggers/manual.py

# Dry-run mode (show what would happen, make no changes)
python3 triggers/manual.py --dry-run

# Custom config directory
python3 triggers/manual.py --config-dir /path/to/config

# Override log level
python3 triggers/manual.py --log-level DEBUG

# Enable trace mode (detailed logging with module/function/line)
python3 triggers/manual.py --trace

# Validate rules syntax without execution
python3 triggers/manual.py --validate

# List all enabled rules
python3 triggers/manual.py --list-rules

# Show version
python3 triggers/manual.py --version

# Combine flags
python3 triggers/manual.py --dry-run --log-level DEBUG --trace

When to Use:

  • Testing new rules before scheduling them
  • Debugging issues with verbose logging
  • Manual cleanup operations (e.g., after bulk adding torrents)
  • Validating configuration changes
  • Learning how rules work with --dry-run

Example Output:

2024-12-10 12:00:00 | INFO     | Successfully authenticated with qBittorrent at http://localhost:8080
2024-12-10 12:00:00 | INFO     | ============================================================
2024-12-10 12:00:00 | INFO     | Starting qBittorrent automation engine
2024-12-10 12:00:00 | INFO     | Trigger: manual
2024-12-10 12:00:00 | INFO     | Dry run mode: True
2024-12-10 12:00:00 | INFO     | ============================================================
2024-12-10 12:00:00 | INFO     | Fetched 253 torrent(s)
2024-12-10 12:00:00 | INFO     | Loaded 5 rules (execute in file order)
2024-12-10 12:00:00 | INFO     | Processing rule: Auto-categorize HD movies
2024-12-10 12:00:00 | INFO     | Would set_category Movie.2160p.BluRay to movies-hd
2024-12-10 12:00:00 | INFO     | Rule 'Auto-categorize HD movies' matched 1 torrent(s)
2024-12-10 12:00:00 | INFO     | ============================================================
2024-12-10 12:00:00 | INFO     | Execution complete - Summary:
2024-12-10 12:00:00 | INFO     |   Total torrents: 253
2024-12-10 12:00:00 | INFO     |   Processed: 0
2024-12-10 12:00:00 | INFO     |   Rules matched: 1
2024-12-10 12:00:00 | INFO     |   Actions executed: 2
2024-12-10 12:00:00 | INFO     |   Actions skipped (idempotent): 0
2024-12-10 12:00:00 | INFO     | ============================================================

Scheduled Trigger

Description: Automated execution via cron for periodic maintenance tasks.

Script: triggers/scheduled.py

Setup:

# Edit crontab
crontab -e

# Run every 15 minutes
*/15 * * * * cd /app && python3 /app/triggers/scheduled.py >> /var/log/qbt-automation.log 2>&1

# Run every hour
0 * * * * cd /app && python3 /app/triggers/scheduled.py

# Run daily at 3 AM
0 3 * * * cd /app && python3 /app/triggers/scheduled.py

# Run every 6 hours
0 */6 * * * cd /app && python3 /app/triggers/scheduled.py

Docker Setup:

Add to docker-compose.yml:

services:
  qbittorrent-automation:
    image: qbittorrent-automation:latest
    volumes:
      - ./config:/config
    environment:
      - QBITTORRENT_HOST=http://qbittorrent:8080
      - QBITTORRENT_USER=admin
      - QBITTORRENT_PASS=password
    command: |
      sh -c 'while true; do
        python3 /app/triggers/scheduled.py
        sleep 900
      done'

Or use system cron with Docker exec:

# Run inside container every 15 minutes
*/15 * * * * docker exec qbittorrent-automation python3 /app/triggers/scheduled.py

Best Practices:

  • Interval: 15-60 minutes for most use cases
  • Monitoring: Direct output to log file for troubleshooting
  • Testing: Run manually first to verify behavior
  • Dry-run: Test with cron using --dry-run initially

When to Use:

  • Removing old/completed torrents automatically
  • Enforcing ratio requirements periodically
  • Bandwidth limit adjustments based on time/conditions
  • Periodic reannounce operations
  • Tagging torrents based on age or status

Example Rules for Scheduled:

rules:
  - name: "Remove old completed torrents"
    enabled: true
    conditions:
      trigger: [scheduled, manual]  # Run on schedule, allow manual testing
      all:
        - field: info.completion_on
          operator: older_than
          value: 30 days
        - field: info.ratio
          operator: ">="
          value: 1.0
    actions:
      - type: delete_torrent
        params:
          keep_files: false

On Added Trigger (Webhook)

Description: Triggered immediately when qBittorrent adds a new torrent. Executes for a single torrent identified by hash.

Script: triggers/on_added.py

qBittorrent Configuration:

  1. Open qBittorrent → ToolsOptionsDownloads
  2. Scroll to "Run external program on torrent added"
  3. Check the box to enable
  4. Set command:

Bare Metal:

python3 /path/to/qbittorrent-automation/triggers/on_added.py "%I"

Docker:

docker exec qbittorrent-automation python3 /app/triggers/on_added.py "%I"

Or if automation runs inside qBittorrent container:

python3 /config/scripts/triggers/on_added.py "%I"

Important: %I is qBittorrent's placeholder for torrent info hash (required)

Usage in Rules:

To make a rule execute only on the on_added trigger:

conditions:
  trigger: on_added
  any:
    - field: info.name
      operator: contains
      value: "unwanted"

Best Practices:

  • Keep processing lightweight - Only single torrent, but triggered frequently
  • Avoid expensive API calls - Don't use files.* or trackers.* unless necessary
  • Use for immediate actions - Categorization, tagging, filtering
  • Fast decisions - Block unwanted content before download starts

When to Use:

  • Content filtering - Block/stop unwanted torrents immediately
  • Auto-categorization - Assign category based on name/tracker
  • Initial tagging - Tag by tracker, content type, or name pattern
  • Download priority - Set force_start for important torrents

Example Rules for On Added:

# Block unwanted file types immediately
- name: "Block archive files on add"
  enabled: true
  stop_on_match: true
  conditions:
    trigger: on_added
    any:
      - field: files.name
        operator: matches
        value: '(?i)\.(rar|zip|7z)$'
  actions:
    - type: stop
    - type: add_tag
      params:
        tags:
          - blocked-archive
# Auto-categorize by name pattern
- name: "Auto-categorize new movies"
  enabled: true
  conditions:
    trigger: on_added
    all:
      - field: info.name
        operator: matches
        value: '(?i).*(1080p|2160p).*'
  actions:
    - type: set_category
      params:
        category: movies-hd

Troubleshooting:

  • Not triggering? Check qBittorrent logs for errors
  • Wrong path? Ensure script path is absolute and accessible
  • Permission denied? Make script executable: chmod +x triggers/on_added.py
  • Test manually: python3 triggers/on_added.py <torrent_hash>

On Completed Trigger (Webhook)

Description: Triggered when a torrent finishes downloading. Executes for a single torrent identified by hash.

Script: triggers/on_completed.py

qBittorrent Configuration:

  1. Open qBittorrent → ToolsOptionsDownloads
  2. Scroll to "Run external program on torrent completion"
  3. Check the box to enable
  4. Set command:

Bare Metal:

python3 /path/to/qbittorrent-automation/triggers/on_completed.py "%I"

Docker:

docker exec qbittorrent-automation python3 /app/triggers/on_completed.py "%I"

Or if automation runs inside qBittorrent container:

python3 /config/scripts/triggers/on_completed.py "%I"

Important: %I is qBittorrent's placeholder for torrent info hash (required)

Usage in Rules:

conditions:
  trigger: on_completed
  all:
    - field: info.size
      operator: ">"
      value: 1073741824  # > 1GB

Best Practices:

  • Post-download processing - Trigger notifications, move files, update tags
  • Seeding strategy - Apply upload limits, set ratio goals
  • Category migration - Move from "downloading" to "completed" categories
  • Tracking - Tag completed torrents for organization

When to Use:

  • Notifications - Trigger external notification systems
  • Seeding rules - Apply limits or force_start for ratio requirements
  • Category changes - Move to "completed" or "seeding" categories
  • Upload limiting - Throttle completed torrents to prioritize active downloads
  • Tagging - Mark as completed for tracking

Example Rules for On Completed:

# Tag large completed downloads
- name: "Tag large completed downloads"
  enabled: true
  conditions:
    trigger: on_completed
    all:
      - field: info.size
        operator: ">"
        value: 10737418240  # > 10GB
  actions:
    - type: add_tag
      params:
        tags:
          - completed-large
          - needs-seeding
# Move to seeding category
- name: "Move completed to seeding"
  enabled: true
  conditions:
    trigger: on_completed
  actions:
    - type: set_category
      params:
        category: seeding
# Limit upload speed for private tracker torrents
- name: "Limit upload on completion for private"
  enabled: true
  conditions:
    trigger: on_completed
    all:
      - field: trackers.url
        operator: contains
        value: ".private"
  actions:
    - type: set_upload_limit
      params:
        limit: 1048576  # 1 MB/s

Troubleshooting:

  • Not triggering? Check qBittorrent logs
  • Fires multiple times? qBittorrent may trigger on re-check or resume
  • Test manually: python3 triggers/on_completed.py <torrent_hash>

Trigger Filtering in Rules

You can filter rules to execute only on specific trigger types using the trigger field in conditions.

Single Trigger:

conditions:
  trigger: on_added
  # This rule ONLY runs when on_added.py is executed

Multiple Triggers:

conditions:
  trigger: [scheduled, manual]
  # This rule runs when scheduled.py OR manual.py is executed
  # Does NOT run for on_added or on_completed

All Triggers (Default):

conditions:
  # No trigger field = runs on ALL trigger types
  all:
    - field: info.ratio
      operator: ">"
      value: 2.0

Available Trigger Values:

  • manual - Manual CLI execution
  • scheduled - Cron/scheduled execution
  • on_added - Torrent added webhook
  • on_completed - Torrent completed webhook

Use Cases:

# Cleanup rules: Only run on schedule (not on every webhook)
- name: "Remove old torrents"
  conditions:
    trigger: [scheduled, manual]
    # ...

# Real-time filtering: Only on torrent added
- name: "Block unwanted content"
  conditions:
    trigger: on_added
    # ...

# Seeding rules: Only on completion
- name: "Set upload limits on completion"
  conditions:
    trigger: on_completed
    # ...

# Universal rules: No trigger filter (runs always)
- name: "Tag private tracker torrents"
  conditions:
    # Runs on ALL triggers
    all:
      - field: trackers.url
        operator: contains
        value: ".private"

🎯 qbt-rules

v0.3.0 | GitHub


📚 Getting Started

📖 Core Concepts

🔧 Configuration

🆘 Help & Support

🤝 Contributing


🆕 What's New (v0.3.0)

  • ✅ Unified CLI (qbt-rules)
  • ✅ Custom triggers
  • ✅ Trigger-agnostic mode
  • ✅ Size operators (50GB)

🔗 Quick Links

Clone this wiki locally