Skip to content

Commit

Permalink
feat(qbittorrent): add qbit_manage
Browse files Browse the repository at this point in the history
  • Loading branch information
Maksim Shakavin committed Jul 29, 2024
1 parent 3807385 commit 4ebc75d
Show file tree
Hide file tree
Showing 5 changed files with 371 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ spec:
namespace: default
values:
controllers:
tagging:
main:
type: cronjob
cronjob:
schedule: "@hourly"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./emonoda
- ./qbit_manage
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
---
# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/external-secrets.io/externalsecret_v1beta1.json
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: qbit-manage
spec:
secretStoreRef:
kind: ClusterSecretStore
name: onepassword-connect
target:
name: qbit-manage-secret
template:
engineVersion: v2
data:
config.yaml: |
# This is an example configuration file that documents all the options.
# It will need to be modified for your specific use case.
# Please refer to the link below for more details on how to set up the configuration file
# https://github.com/StuffAnThings/qbit_manage/wiki/Config-Setup
commands:
# The commands defined below will IGNORE any commands used in command line and docker env variables.
dry_run: True
cross_seed: False
recheck: True # Recheck paused torrents sorted by lowest size. Resume if Completed.
cat_update: False
tag_update: True
rem_unregistered: True
tag_tracker_error: True
rem_orphaned: True
tag_nohardlinks: True
share_limits: False
skip_qb_version_check: True
skip_cleanup: True
qbt:
# qBittorrent parameters
host: "qbittorrent.default.svc.cluster.local:8080"
user: {{ .qbittorrent_username }}
pass: {{ .qbittorrent_password }}
settings:
force_auto_tmm: False # Will force qBittorrent to enable Automatic Torrent Management for each torrent.
tracker_error_tag: issue # Will set the tag of any torrents that do not have a working tracker.
nohardlinks_tag: noHL # Will set the tag of any torrents with no hardlinks.
share_limits_tag: ~share_limit # Will add this tag when applying share limits to provide an easy way to filter torrents by share limit group/priority for each torrent
share_limits_min_seeding_time_tag: MinSeedTimeNotReached # Tag to be added to torrents that have not yet reached the minimum seeding time
share_limits_min_num_seeds_tag: MinSeedsNotMet # Tag to be added to torrents that have not yet reached the minimum number of seeds
share_limits_last_active_tag: LastActiveLimitNotReached # Tag to be added to torrents that have not yet reached the last active limit
cross_seed_tag: cross-seed # Will set the tag of any torrents that are added by cross-seed command
cat_filter_completed: True # Filters for completed torrents only when running cat_update command
share_limits_filter_completed: True # Filters for completed torrents only when running share_limits command
tag_nohardlinks_filter_completed: True # Filters for completed torrents only when running tag_nohardlinks command
cat_update_all: True # Checks and udpates all torrent categories if set to True when running cat_update command, otherwise only update torrents that are uncategorized
directory:
# Do not remove these
# Cross-seed var: </your/path/here/> # Output directory of cross-seed
# root_dir var: </your/path/here/> # Root downloads directory used to check for orphaned files, noHL, and RecycleBin.
# <OPTIONAL> remote_dir var: </your/path/here/> # Path of docker host mapping of root_dir.
# remote_dir must be set if you're running qbit_manage locally and qBittorrent/cross_seed is in a docker
# remote_dir should not be set if qbit_manage is running in a container
# <OPTIONAL> recycle_bin var: </your/path/here/> # Path of the RecycleBin folder. Default location is set to remote_dir/.RecycleBin
# <OPTIONAL> torrents_dir var: </your/path/here/> # Path of the your qbittorrent torrents directory. Required for `save_torrents` attribute in recyclebin
# <OPTIONAL> orphaned_dir var: </your/path/here/> # Path of the the Orphaned Data folder. This is similar to RecycleBin, but only for orphaned data.
cross_seed: "/your/path/here/"
root_dir: "/data/torrents/"
remote_dir: /data/torrents/
recycle_bin: "/mnt/user/data/torrents/.RecycleBin"
torrents_dir: "/qbittorrent/data/BT_backup"
orphaned_dir: "/data/torrents/orphaned_data"
cat:
# Category & Path Parameters
# <Category Name> : <save_path> # Path of your save directory.
movies: "/data/torrents/movies"
tv: "/data/torrents/tv"
cat_change:
# This moves all the torrents from one category to another category. This executes on --cat-update
# WARNING: if the paths are different and Default Torrent Management Mode is set to automatic the files could be moved !!!
# <Old Category Name> : <New Category>
Radarr-HD.cross-seed: movies-hd
Radarr-UHD.cross-seed: movies-uhd
movies-hd.cross-seed: movies-hd
movies-uhd.cross-seed: movies-uhd
tracker:
# Mandatory
# Tag Parameters
# <Tracker URL Keyword>: # <MANDATORY> This is the keyword in the tracker url. You can define multiple tracker urls by splitting with `|` delimiter
# <MANDATORY> Set tag name. Can be a list of tags or a single tag
# tag: <Tag Name>
# <OPTIONAL> Set the category based on tracker URL. This category option takes priority over the category defined by save directory
# cat: <Category Name>
# <OPTIONAL> Set this to the notifiarr react name. This is used to add indexer reactions to the notifications sent by Notifiarr
# notifiarr: <notifiarr indexer>
bt.t-ru|bt2.t-ru|bt3.t-ru|bt4.t-ru:
tag: rutracker
notifiarr: rutracker
# The "other" key is a special keyword and if defined will tag any other trackers that don't match the above trackers into this tag
other:
tag: other
nohardlinks:
# Tag Movies/Series that are not hard linked outside the root directory
# Mandatory to fill out directory parameter above to use this function (root_dir/remote_dir)
# This variable should be set to your category name of your completed movies/completed series in qbit. Acceptable variable can be any category you would like to tag if there are no hardlinks found
movies:
tv:
share_limits:
# Control how torrent share limits are set depending on the priority of your grouping
# Each torrent will be matched with the share limit group with the highest priority that meets the group filter criteria.
# Each torrent can only be matched with one share limit group
# This variable is mandatory and is a text defining the name of your grouping. This can be any string you want
noHL:
# <MANDATORY> priority: <int/float> # This is the priority of your grouping. The lower the number the higher the priority
priority: 1
# <OPTIONAL> include_all_tags: <list> # Filter the group based on one or more tags. Multiple include_all_tags are checked with an AND condition
# All tags defined here must be present in the torrent for it to be included in this group
include_all_tags:
- noHL
# <OPTIONAL> include_any_tags: <list> # Filter the group based on one or more tags. Multiple include_any_tags are checked with an OR condition
# Any tags defined here must be present in the torrent for it to be included in this group
include_any_tags:
- noHL
# <OPTIONAL> exclude_all_tags: <list> # Filter by excluding one or more tags. Multiple exclude_all_tags are checked with an AND condition
# This is useful to combine with the category filter to exclude one or more tags from an entire category
# All tags defined here must be present in the torrent for it to be excluded in this group
exclude_all_tags:
- Beyond-HD
# <OPTIONAL> exclude_any_tags: <list> # Filter by excluding one or more tags. Multiple exclude_any_tags are checked with an OR condition
# This is useful to combine with the category filter to exclude one or more tags from an entire category
# Any tags defined here must be present in the torrent for it to be excluded in this group
exclude_any_tags:
- Beyond-HD
# <OPTIONAL> categories: <list> # Filter by including one or more categories. Multiple categories are checked with an OR condition
# Since one torrent can only be associated with a single category, multiple categories are checked with an OR condition
categories:
- RadarrComplete
- SonarrComplete
# <OPTIONAL> max_ratio <float>: Will set the torrent Maximum share ratio until torrent is stopped from seeding/uploading and may be cleaned up / removed if the minimums have been met.
# Will default to -1 (no limit) if not specified for the group.
max_ratio: 5.0
# <OPTIONAL> max_seeding_time <str>: Will set the torrent Maximum seeding time until torrent is stopped from seeding/uploading and may be cleaned up / removed if the minimums have been met.
# See Some examples of valid time expressions (https://github.com/onegreyonewhite/pytimeparse2)
# 32m, 2h32m, 3d2h32m, 1w3d2h32m
# Will default to -1 (no limit) if not specified for the group. (Max value of 1 year (525600 minutes))
max_seeding_time: 90d
# <OPTIONAL> min_seeding_time <str>: Will prevent torrent deletion by cleanup variable if torrent has not yet minimum seeding time (minutes).
# This should only be set if you are using this in conjunction with max_seeding_time and max_ratio. If you are not setting a max_ratio, then use max_seeding_time instead.
# If the torrent has not yet reached this minimum seeding time, it will change the share limits back to no limits and resume the torrent to continue seeding.
# See Some examples of valid time expressions (https://github.com/onegreyonewhite/pytimeparse2)
# 32m, 2h32m, 3d2h32m, 1w3d2h32m
# Will default to 0 if not specified for the group.
min_seeding_time: 30d
# <OPTIONAL> last_active <str>: Will prevent torrent deletion by cleanup variable if torrent has been active within the last x minutes.
# If the torrent has been active within the last x minutes, it will change the share limits back to no limits and resume the torrent to continue seeding.
# See Some examples of valid time expressions (https://github.com/onegreyonewhite/pytimeparse2)
# 32m, 2h32m, 3d2h32m, 1w3d2h32m
# Will default to 0 if not specified for the group.
last_active: 30d
# <OPTIONAL> Limit Upload Speed <int>: Will limit the upload speed KiB/s (KiloBytes/second) (`-1` : No Limit)
limit_upload_speed: 0
# <OPTIONAL> Enable Group Upload Speed <bool>: Upload speed limits are applied at the group level. This will take limit_upload_speed defined and divide it equally among the number of torrents in the group.
enable_group_upload_speed: false
# <OPTIONAL> cleanup <bool>: WARNING!! Setting this as true Will remove and delete contents of any torrents that satisfies the share limits (max time OR max ratio)
cleanup: false
# <OPTIONAL> resume_torrent_after_change <bool>: This variable will resume your torrent after changing share limits. Default is true
resume_torrent_after_change: true
# <OPTIONAL> add_group_to_tag <bool>: This adds your grouping as a tag with a prefix defined in settings . Default is true
# Example: A grouping defined as noHL will have a tag set to ~share_limit.noHL (if using the default prefix)
add_group_to_tag: true
# <OPTIONAL> min_num_seeds <int>: Will prevent torrent deletion by cleanup variable if the number of seeds is less than the value set here.
# If the torrent has less number of seeds than the min_num_seeds, the share limits will be changed back to no limits and resume the torrent to continue seeding.
# Will default to 0 if not specified for the group.
min_num_seeds: 0
# <OPTIONAL> custom_tag <str>: Apply a custom tag name for this particular group. **WARNING (This tag MUST be unique as it will be used to determine share limits. Please ensure it does not overlap with any other tags in qbt)**
custom_tag: sharelimits_noHL
cross-seed:
priority: 2
include_all_tags:
- cross-seed
max_seeding_time: 7d
cleanup: false
PTP:
priority: 3
include_all_tags:
- PassThePopcorn
max_ratio: 2.0
max_seeding_time: 90d
cleanup: false
default:
priority: 999
max_ratio: -1
max_seeding_time: -1
cleanup: false
recyclebin:
# Recycle Bin method of deletion will move files into the recycle bin (Located in /root_dir/.RecycleBin) instead of directly deleting them in qbit
# By default the Recycle Bin will be emptied on every run of the qbit_manage script if empty_after_x_days is defined.
enabled: false
# <OPTIONAL> empty_after_x_days var:
# Will automatically remove all files and folders in recycle bin after x days. (Checks every script run)
# If this variable is not defined it, the RecycleBin will never be emptied.
# WARNING: Setting this variable to 0 will delete all files immediately upon script run!
empty_after_x_days: 60
# <OPTIONAL> save_torrents var:
# If this option is set to true you MUST fill out the torrents_dir in the directory attribute.
# This will save a copy of your .torrent and .fastresume file in the recycle bin before deleting it from qbittorrent
save_torrents: true
# <OPTIONAL> split_by_category var:
# This will split the recycle bin folder by the save path defined in the `cat` attribute
# and add the base folder name of the recycle bin that was defined in the `recycle_bin` sub-attribute under directory.
split_by_category: false
orphaned:
# Orphaned files are those in the root_dir download directory that are not referenced by any active torrents.
# Will automatically remove all files and folders in orphaned data after x days. (Checks every script run)
# If this variable is not defined it, the orphaned data will never be emptied.
# WARNING: Setting this variable to 0 will delete all files immediately upon script run!
empty_after_x_days: 0
# File patterns that will not be considered orphaned files. Handy for generated files that aren't part of the torrent but belong with the torrent's files
exclude_patterns:
- "**/.DS_Store"
- "**/Thumbs.db"
- "**/@eaDir"
- "/data/torrents/.torrents/**"
- "/data/torrents/temp/**"
- "**/*.!qB"
- "**/*_unpackerred"
apprise:
# Apprise integration with webhooks
# Leave Empty/Blank to disable
# Mandatory to fill out the url of your apprise API endpoint
# api_url: http://apprise-api:8000
# Mandatory to fill out the notification url/urls based on the notification services provided by apprise. https://github.com/caronc/apprise/wiki
# notify_url:
notifiarr:
# Notifiarr integration with webhooks
# Leave Empty/Blank to disable
# Mandatory to fill out API Key
apikey: {{ .notifiarr_qbit_api_key }}
# <OPTIONAL> Set to a unique value (could be your username on notifiarr for example)
instance:
webhooks:
# Webhook notifications:
# Possible values:
# Set value to notifiarr if using notifiarr integration
# Set value to apprise if using apprise integration
# Set value to a valid webhook URL
# Set value to nothing (leave Empty/Blank) to disable
error: notifiarr
run_start: notifiarr
run_end: notifiarr
function:
cross_seed: notifiarr
recheck: notifiarr
cat_update: notifiarr
tag_update: notifiarr
rem_unregistered: notifiarr
tag_tracker_error: notifiarr
rem_orphaned: notifiarr
tag_nohardlinks: notifiarr
share_limits: notifiarr
cleanup_dirs: notifiarr
dataFrom:
- extract:
key: qbittorrent
rewrite:
- regexp:
source: "(.*)"
target: "qbittorrent_$1"
- extract:
key: notifiarr
rewrite:
- regexp:
source: "(.*)"
target: "notifiarr_$1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/helm.toolkit.fluxcd.io/helmrelease_v2.json
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: qbit-manage
spec:
interval: 30m
chart:
spec:
chart: app-template
version: 3.2.1
sourceRef:
kind: HelmRepository
name: bjw-s
namespace: flux-system
install:
remediation:
retries: 3
upgrade:
cleanupOnFail: true
remediation:
strategy: rollback
retries: 3
dependsOn:
- name: qbittorrent
namespace: default
values:
controllers:
main:
type: cronjob
cronjob:
schedule: "@hourly"
timeZone: "${TIMEZONE}"
concurrencyPolicy: Forbid
successfulJobsHistory: 1
failedJobsHistory: 1
containers:
main:
image:
repository: ghcr.io/stuffanthings/qbit_manage
tag: latest@sha256:576a71fe73bb83367090313cff9d1ca654836f2a7a0b18d0193025609e9eba7f
env:
QBT_RUN: "true"
QBT_CONFIG: "/config/config.yaml"
args:
- --config
- /app/config.yaml
resources:
requests:
cpu: 25m
limits:
memory: 256M
pod:
restartPolicy: OnFailure
defaultPodOptions:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
persistence:
logs:
type: emptyDir
globalMounts:
- path: /config/logs
config-file:
type: secret
name: qbit-manage-secret
globalMounts:
- path: /config/config.yaml
subPath: config.yaml
downloads:
type: nfs
server: "${NAS_URL}"
path: "${NAS_PATH}"
globalMounts:
- path: /data
Loading

0 comments on commit 4ebc75d

Please sign in to comment.