Tqm
TQM: Torrent Queue Manager, a tool to manage torrents in your clients.
Install / Use
/learn @autobrr/TqmREADME
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
node-connect
339.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.9kCommit, push, and open a PR
