SkillAgentSearch skills...

Tqm

TQM: Torrent Queue Manager, a tool to manage torrents in your clients.

Install / Use

/learn @autobrr/Tqm
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

made-with-golang License: GPL v3 Contributing

tqm

CLI tool to manage your torrent client queues. Primary focus is on removing torrents that meet specific criteria.

This is a fork from l3uddz.

Example Configuration

clients:
  deluge:
    enabled: true
    filter: default
    download_path: /mnt/local/downloads/torrents/deluge
    free_space_path: /mnt/local/downloads/torrents/deluge # Required for Deluge with path that exists on server
    download_path_mapping:
      /downloads/torrents/deluge: /mnt/local/downloads/torrents/deluge
    host: localhost
    login: localclient
    password: password-from-/opt/deluge/auth
    port: 58846
    type: deluge
    v2: true
  qbt:
    download_path: /mnt/local/downloads/torrents/qbittorrent/completed
    # free_space_path is not needed for qBittorrent as it checks globally via API
    download_path_mapping:
      /downloads/torrents/qbittorrent/completed: /mnt/local/downloads/torrents/qbittorrent/completed
    enabled: true
    filter: default
    create_tags_upfront: false # Only sets tags that matches torrents, prevents empty tags
    type: qbittorrent
    url: https://qbittorrent.domain.com/
    user: user
    password: password
    # NEW: If this option is set to true, AutoTmm aka Auto Torrent Managment Mode,
    # will be enabled for torrents after a relabel.
    # This ensures the torrent is also moved in the filesystem to the new category path, and not only changes category in qbit
    # enableAutoTmmAfterRelabel: true
notifications:
  # if detailed is true, TQM will send detailed information about each action it takes
  # if it is false it will only send a summary notification
  detailed: true
  # if skip_empty_run is true, TQM will skip sending a notification if the action didn't change anything
  skip_empty_run: true
  service:
    discord:
      webhook_url: https://discord.com/api/webhooks/yourwebhookid/yourwebhooktoken
      # Both username and avatar_url are optional and only needed if you want to
      # change the name and the picture of the webhook account
      username: yourusername
      avatar_url: youravatarurl
filters:
  default:
    # if true, data will be deleted from disk when removing torrents (default: true)
    #DeleteData: false
    ignore:
      # general
      - IsTrackerDown()
      - Downloaded == false && !IsUnregistered()
      - SeedingHours < 26 && !IsUnregistered()
      # permaseed / un-sorted (unless torrent has been deleted)
      - Label startsWith "permaseed-" && !IsUnregistered()
      # Filter based on qbittorrent tags (only qbit at the moment)
      - '"permaseed" in Tags && !IsUnregistered()'
      # Example: Ignore private torrents unless they are unregistered
      # - IsPrivate == true && !IsUnregistered()
    remove:
      # general
      - IsUnregistered()
      # Example: Remove non-private torrents that meet ratio/seed time criteria
      # - IsPrivate == false && (Ratio > 2.0 || SeedingDays >= 7.0)
      # imported
      - Label in ["sonarr-imported", "radarr-imported", "lidarr-imported"] && (Ratio > 4.0 || SeedingDays >= 15.0)
      # ipt
      - Label in ["autoremove-ipt"] && (Ratio > 3.0 || SeedingDays >= 15.0)
      # hdt
      - Label in ["autoremove-hdt"] && (Ratio > 3.0 || SeedingDays >= 15.0)
      # bhd
      - Label in ["autoremove-bhd"] && (Ratio > 3.0 || SeedingDays >= 15.0)
      # ptp
      - Label in ["autoremove-ptp"] && (Ratio > 3.0 || SeedingDays >= 15.0)
      # btn
      - Label in ["autoremove-btn"] && (Ratio > 3.0 || SeedingDays >= 15.0)
      # hdb
      - Label in ["autoremove-hdb"] && (Ratio > 3.0 || SeedingDays >= 15.0)
      # Qbit tag utilities
      - HasAllTags("480p", "bad-encode") # match if all tags are present
      - HasAnyTag("remove-me", "gross") # match if at least 1 tag is present
    pause: # New section for pausing torrents
      # Pause public torrents
      - IsPrivate == false
      #- IsPublic # same as above, but easier to remember
      # Pause torrents seeding for more than 7 days with a ratio below 0.5
      - Ratio < 0.5 && SeedingDays > 7
      # Pause incomplete torrents older than 2 weeks
      - Downloaded == false && AddedDays > 14
    label:
      # btn 1080p season packs to permaseed (all must evaluate to true)
      - name: permaseed-btn
        update:
          - Label == "sonarr-imported"
          - TrackerName == "landof.tv"
          - Name contains "1080p"
          - len(Files) >= 3

      # cleanup btn season packs to autoremove-btn (all must evaluate to true)
      - name: autoremove-btn
        update:
          - Label == "sonarr-imported"
          - TrackerName == "landof.tv"
          - not (Name contains "1080p")
          - len(Files) >= 3
    # Change qbit tags based on filters
    tag:
      - name: low-seed
        # Mode is optional and defaults to "full" if not specified
        # "mode: full" means tag will be added to
        # torrent if matched and removed from torrent if not
        # use `add` or `remove` to only add/remove respectivly
        # NOTE: Mode does not change the way torrents are flagged,
        # meaning, even with "mode: remove",
        # tags will be removed if the torrent does NOT match the conditions.
        # "mode: remove" simply means that tags will not be added
        # to torrents that do match.
        mode: full
        # uploadKb: 50 # Optional: Apply 50 KiB/s upload limit if conditions match (-1 for unlimited)
        update:
          - Seeds <= 3
      # Example: Limit upload speed for public torrents that have seeded for over 2 days
      # - name: limit-public-seed-time
      #   mode: add # Add tag (optional, could just limit speed without tagging)
      #   uploadKb: 100 # Limit to 100 KiB/s
      #   update:
      #     - IsPrivate == false # Only target public torrents
      #     - SeedingDays > 2.0
      # Example: Tag without mode specification (defaults to "full")
      # - name: completed-torrents
      #   update:
      #     - Downloaded == true
      - name: inactive
        mode: add
        update:
          - LastActivityDays > 30
    # Orphan configuration
    orphan:
      # grace period for recently modified files (default: 10m)
      # valid time units are: ns, us (or µs), ms, s, m, h
      grace_period: 10m
      # paths that will be ignored during the orphaned files check
      ignore_paths:
        - /mnt/local/downloads/torrents/qbittorrent/completed/tv-4k
        - /mnt/local/downloads/torrents/qbittorrent/completed/movie-4k

## Optional - Tracker Configuration

trackers:
  bhd:
    api_key: your-api-key
  btn:
    api_key: your-api-key
  ptp:
    api_user: your-api-user
    api_key: your-api-key
  hdb:
    username: your-username
    passkey: your-passkey
  red:
    api_key: your-api-key
  ops:
    api_key: your-api-key
  unit3d:
    aither:
      api_key: your_api_key
      domain: aither.cc
    blutopia:
      api_key: your_api_key
      domain: blutopia.cc

Allows tqm to validate if a torrent was removed from the tracker using the tracker's own API.

Currently implements:

  • Beyond-HD
  • BTN
  • HDB
  • OPS
  • PTP
  • RED
  • UNIT3D trackers

Note for BTN users: When first using the BTN API, you may need to authorize your IP address. Check your BTN notices/messages for the authorization request.

Filtering Language Definition

The language definition used in the configuration filters is available here

Filterable Fields

The following torrent fields (along with their types) can be used in the configuration when filtering torrents:

type Torrent struct {
 Hash                 string
 Name                 string
 Path                 string
 TotalBytes           int64
 DownloadedBytes      int64
 State                string
 Files                []string
 Tags                 []string
 Downloaded           bool
 Seeding              bool
 Ratio                float32
 AddedSeconds         int64
 AddedHours           float32
 AddedDays            float32
 SeedingSeconds       int64
 SeedingHours         float32
 SeedingDays          float32
 LastActivitySeconds  int64
 LastActivityHours    float32
 LastActivityDays     float32
 Label                string
 Seeds                int64
 Peers                int64
 IsPrivate            bool
 IsPublic             bool

 FreeSpaceGB  func() float64
 FreeSpaceSet bool

 TrackerName   string
 TrackerStatus string
}

Number fields of types int64, float32 and float64 support arithmetic and comparison operators.

Fields of type string support string operators.

Fields of type []string (lists) such as the Tags and Files fields support membership checks and various built in functions.

All of this and more can be noted in the language definition mentioned above.

Helper Filter

Related Skills

View on GitHub
GitHub Stars79
CategoryDevelopment
Updated23d ago
Forks7

Languages

Go

Security Score

100/100

Audited on Mar 5, 2026

No findings