diff --git a/.github/workflows/update-supported-versions.yml b/.github/workflows/update-supported-versions.yml
index 99318079..af54058a 100644
--- a/.github/workflows/update-supported-versions.yml
+++ b/.github/workflows/update-supported-versions.yml
@@ -42,7 +42,7 @@ jobs:
- name: Create Pull Request
id: cpr
- uses: peter-evans/create-pull-request@v6
+ uses: peter-evans/create-pull-request@v7
with:
commit-message: Update SUPPORTED_VERSIONS.json
title: "Update SUPPORTED_VERSIONS.json for ${{ github.event.inputs.targetBranch || github.ref_name }}"
diff --git a/CHANGELOG b/CHANGELOG
index 1fa7ad71..c2bdb4a6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,16 +1,16 @@
+# Requirements Updated
+- qbittorrent-api==2024.8.65
+- croniter==3.0.3
+- humanize==4.10.0
+
# New Updates
-- BHD config options are now deprecated due to qbm no longer needing to use the api to detect unregistered torrents (Closes #595)
-- Updates mover script to add logging and default to completed torrents only with new optional argument (`--status-filter`)
+- Adds `force_auto_tmm_ignore_tags` feature to ignore tags when force_auto_tmm is enabled (#634)
# Bug Fixes
-- Adds new ignore message for unregistered torrents (Closes #592)
-- Allow `max_seeding_time` to be unlimited (-1) if min_seeding_time is set (Closes #596)
-- Fixes checking tracker status for udp/wss (Closes #586)
-- Fixes Logging header not getting logged in every run (Closes #591)
-- Fixes min_seeding_time tag removal when max_seeding_time is -1 (#Closes 598)
-- Fixes Remove orphaned without moving to orphaned_dir (Closes #590)
-- Fixes bug in printing schedule mode when run is set to True
-- Modifies noHL threshold to 0.1 to address false positives
+- Fixes Print the schedule and delay before starting the sleep (Closes [#605](https://github.com/StuffAnThings/qbit_manage/issues/605))
+- Fixes noHL counting symlinks as part of its logic (Closes [#608](https://github.com/StuffAnThings/qbit_manage/issues/608))
+- Fix typos in documentation (#627)
+- Extended logging to explain why torrent files were not deleted (#625)
-Special thanks to @bakerboy448, @ineednewpajamas, @lflare, @convexshiba for their contributions!
-**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.1.6...v4.1.7
+Special thanks to @ineednewpajamas, @glicholas, @Minituff, @Dark3clipse, @TJZine for their contributions!
+**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.1.7...v4.1.8
diff --git a/Dockerfile b/Dockerfile
index 8a0ec774..d22953d2 100755
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,8 +1,8 @@
FROM python:3.11-alpine
ARG BRANCH_NAME=master
-ENV BRANCH_NAME ${BRANCH_NAME}
-ENV TINI_VERSION v0.19.0
-ENV QBM_DOCKER True
+ENV BRANCH_NAME=${BRANCH_NAME}
+ENV TINI_VERSION=v0.19.0
+ENV QBM_DOCKER=True
COPY requirements.txt /
diff --git a/README.md b/README.md
index 81da3f4f..d1cf7192 100755
--- a/README.md
+++ b/README.md
@@ -46,7 +46,7 @@ Generally expect new releases of Qbittorrent to not immediately be supported. Su
Check out the [wiki](https://github.com/StuffAnThings/qbit_manage/wiki) for installation help
-1. Install qbit_manage either by installing Python 3.8.1+ on the localhost and following the [Local Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Local-Installations) Guide or by installing Docker and following the [Docker Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Docker-Installation) Guide or the [unRAID Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Unraid-Installation) Guide.
+1. Install qbit_manage either by installing Python 3.9.0+ on the localhost and following the [Local Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Local-Installations) Guide or by installing Docker and following the [Docker Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Docker-Installation) Guide or the [unRAID Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Unraid-Installation) Guide.
1. Once installed, you have to [set up your Configuration](https://github.com/StuffAnThings/qbit_manage/wiki/Config-Setup) by create a [Configuration File](https://github.com/StuffAnThings/qbit_manage/blob/master/config/config.yml.sample) filled with all your values to connect to your qBittorrent instance.
1. Please refer to the list of [Commands](https://github.com/StuffAnThings/qbit_manage/wiki/Commands) that can be used with this tool.
diff --git a/SUPPORTED_VERSIONS.json b/SUPPORTED_VERSIONS.json
index 6dc59e4c..3f7e699c 100644
--- a/SUPPORTED_VERSIONS.json
+++ b/SUPPORTED_VERSIONS.json
@@ -1,10 +1,10 @@
{
"master": {
- "qbit": "v4.6.5",
- "qbitapi": "2024.5.63"
+ "qbit": "v4.6.6",
+ "qbitapi": "2024.8.65"
},
"develop": {
- "qbit": "v4.6.5",
- "qbitapi": "2024.5.63"
+ "qbit": "v4.6.6",
+ "qbitapi": "2024.8.65"
}
}
diff --git a/VERSION b/VERSION
index 9edf2a44..a7c00da3 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.1.7
+4.1.8
diff --git a/config/config.yml.sample b/config/config.yml.sample
index 70d6ac5c..c7b6f57c 100755
--- a/config/config.yml.sample
+++ b/config/config.yml.sample
@@ -26,6 +26,9 @@ qbt:
settings:
force_auto_tmm: False # Will force qBittorrent to enable Automatic Torrent Management for each torrent.
+ force_auto_tmm_ignore_tags: #Torrents with these tags will be ignored when force_auto_tmm is enabled.
+ - cross-seed
+ - Upload
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
@@ -36,7 +39,7 @@ settings:
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
+ cat_update_all: True # Checks and updates all torrent categories if set to True when running cat_update command, otherwise only update torrents that are uncategorized
directory:
# Do not remove these
diff --git a/docs/Config-Setup.md b/docs/Config-Setup.md
index 708f3947..2aa5ced4 100644
--- a/docs/Config-Setup.md
+++ b/docs/Config-Setup.md
@@ -46,6 +46,7 @@ This section defines any settings defined in the configuration.
| Variable | Definition | Default Values | Required |
| :-------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------| :----------------- | :----------------- |
| `force_auto_tmm` | Will force qBittorrent to enable Automatic Torrent Management for each torrent. | False |
❌ |
+| `force_auto_tmm_ignore_tags` | Torrents with these tags will be ignored when force_auto_tmm is enabled. | | ❌ |
| `tracker_error_tag` | Define the tag of any torrents that do not have a working tracker. (Used in `--rem-unregistered` and `--tag-tracker-error`) | issue | ❌ |
| `nohardlinks_tag` | Define the tag of any torrents that don't have hardlinks (Used in `--tag-nohardlinks`) | noHL | ❌ |
| `share_limits_tag` | Will add this tag when applying share limits to provide an easy way to filter torrents by share limit group/priority for each torrent. For example, if you have a share-limit group `cross-seed` with a priority of 2 and the default share_limits_tag `~share_limits` would add the tag `~share_limit_2.cross-seed` (Used in `--share-limits`) | ~share_limit | ❌ |
diff --git a/docs/Home.md b/docs/Home.md
index a0329fe2..c4f058a2 100644
--- a/docs/Home.md
+++ b/docs/Home.md
@@ -4,9 +4,9 @@ This wiki should tell you everything you need to know about the script to get it
## Getting Started
-1. Install qbit_manage either by installing Python3.8.1+ on the localhost and following the [Local Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Local-Installations) Guide or by installing Docker and following the [Docker Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Docker-Installation) Guide or the [unRAID Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Unraid-Installation) Guide.
-2. Once installed, you have to [set up your Configuration](https://github.com/StuffAnThings/qbit_manage/wiki/Config-Setup) by create a [Configuration File](https://github.com/StuffAnThings/qbit_manage/blob/master/config/config.yml.sample) filled with all your values to connect to your qBittorrent instance.
-3. Please refer to the list of [Commands](https://github.com/StuffAnThings/qbit_manage/wiki/Commands) that can be used with this tool.
+1. Install qbit_manage either by installing Python3.9.0+ on the localhost and following the [Local Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Local-Installations) Guide or by installing Docker and following the [Docker Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Docker-Installation) Guide or the [unRAID Installation](https://github.com/StuffAnThings/qbit_manage/wiki/Unraid-Installation) Guide.
+1. Once installed, you have to [set up your Configuration](https://github.com/StuffAnThings/qbit_manage/wiki/Config-Setup) by create a [Configuration File](https://github.com/StuffAnThings/qbit_manage/blob/master/config/config.yml.sample) filled with all your values to connect to your qBittorrent instance.
+1. Please refer to the list of [Commands](https://github.com/StuffAnThings/qbit_manage/wiki/Commands) that can be used with this tool.
## Support
diff --git a/docs/Local-Installations.md b/docs/Local-Installations.md
index 14090d11..58679876 100644
--- a/docs/Local-Installations.md
+++ b/docs/Local-Installations.md
@@ -1,6 +1,6 @@
# Local Installations
-* Requires `python 3.8.1`. Dependencies must be installed by running:
+* Requires `python 3.9.0`. Dependencies must be installed by running:
Navigate to the directory you'd liked to clone the repo into
diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md
index 0af94854..06180c84 100644
--- a/docs/_Sidebar.md
+++ b/docs/_Sidebar.md
@@ -13,7 +13,7 @@
- [settings](Config-Setup#settings)
- [directory](Config-Setup#directory)
- [cat](Config-Setup#cat)
- - [cat_changes](Config-Setup#cat_changes)
+ - [cat_change](Config-Setup#cat_change)
- [tracker](Config-Setup#tracker)
- [nohardlinks](Config-Setup#nohardlinks)
- [share_limits](Config-Setup#share_limits)
diff --git a/modules/config.py b/modules/config.py
index f5453655..209b5a7e 100755
--- a/modules/config.py
+++ b/modules/config.py
@@ -229,6 +229,9 @@ def hooks(attr):
"cat_update_all": self.util.check_for_attribute(
self.data, "cat_update_all", parent="settings", var_type="bool", default=True
),
+ "force_auto_tmm_ignore_tags": self.util.check_for_attribute(
+ self.data, "force_auto_tmm_ignore_tags", parent="settings", var_type="list", default=[]
+ ),
}
self.tracker_error_tag = self.settings["tracker_error_tag"]
diff --git a/modules/core/share_limits.py b/modules/core/share_limits.py
index 23920364..7a37a268 100644
--- a/modules/core/share_limits.py
+++ b/modules/core/share_limits.py
@@ -112,7 +112,7 @@ def cleanup_torrents_for_group(self, group_name, priority):
if not self.config.dry_run:
self.qbt.tor_delete_recycle(torrent, attr)
body += logger.print_line(
- logger.insert_space("Deleted .torrent but NOT content files.", 8),
+ logger.insert_space("Deleted .torrent but NOT content files. Reason: is cross-seed", 8),
self.config.loglevel,
)
else:
@@ -131,7 +131,13 @@ def cleanup_torrents_for_group(self, group_name, priority):
if not self.config.dry_run:
self.qbt.tor_delete_recycle(torrent, attr)
body += logger.print_line(
- logger.insert_space("Deleted .torrent but NOT content files.", 8), self.config.loglevel
+ logger.insert_space(
+ "Deleted .torrent but NOT content files. Reason: path does not exist [path="
+ + torrent["content_path"].replace(self.root_dir, self.remote_dir)
+ + "].",
+ 8,
+ ),
+ self.config.loglevel,
)
attr["body"] = "\n".join(body)
if not group_notifications:
diff --git a/modules/qbittorrent.py b/modules/qbittorrent.py
index d99c7fce..4211df4d 100755
--- a/modules/qbittorrent.py
+++ b/modules/qbittorrent.py
@@ -125,7 +125,9 @@ def get_torrent_info(self):
logger.separator("Checking Settings", space=False, border=False)
if settings["force_auto_tmm"]:
logger.print_line(
- "force_auto_tmm set to True. Will force Auto Torrent Management for all torrents.", self.config.loglevel
+ "force_auto_tmm set to True. Will force Auto Torrent Management "
+ "for all torrents without matching force_auto_tmm_ignore_tags.",
+ self.config.loglevel,
)
logger.separator("Gathering Torrent Information", space=True, border=True)
for torrent in self.torrent_list:
@@ -134,7 +136,14 @@ def get_torrent_info(self):
status = None
working_tracker = None
issue = {"potential": False}
- if torrent.auto_tmm is False and settings["force_auto_tmm"] and torrent.category != "" and not self.config.dry_run:
+ if (
+ torrent.auto_tmm is False
+ and settings["force_auto_tmm"]
+ and torrent.category != ""
+ and not self.config.dry_run
+ # check whether the torrent has a matching tag to ignore force_auto_tmm.
+ and not any(tag in torrent.tags for tag in self.config.settings.get("force_auto_tmm_ignore_tags", []))
+ ):
torrent.set_auto_management(True)
try:
torrent_name = torrent.name
diff --git a/modules/util.py b/modules/util.py
index 689c8038..c4684686 100755
--- a/modules/util.py
+++ b/modules/util.py
@@ -536,22 +536,26 @@ def __init__(self, root_dir, remote_dir):
def get_inode_count(self):
self.inode_count = {}
for file in self.root_files:
- try:
- inode_no = os.stat(file.replace(self.root_dir, self.remote_dir)).st_ino
- except PermissionError as perm:
- logger.warning(f"{perm} : file {file} has permission issues. Skipping...")
- continue
- except FileNotFoundError as file_not_found_error:
- logger.warning(f"{file_not_found_error} : File {file} not found. Skipping...")
- continue
- except Exception as ex:
- logger.stacktrace()
- logger.error(ex)
+ # Only check hardlinks for files that are symlinks
+ if os.path.isfile(file) and os.path.islink(file):
continue
- if inode_no in self.inode_count:
- self.inode_count[inode_no] += 1
else:
- self.inode_count[inode_no] = 1
+ try:
+ inode_no = os.stat(file.replace(self.root_dir, self.remote_dir)).st_ino
+ except PermissionError as perm:
+ logger.warning(f"{perm} : file {file} has permission issues. Skipping...")
+ continue
+ except FileNotFoundError as file_not_found_error:
+ logger.warning(f"{file_not_found_error} : File {file} not found. Skipping...")
+ continue
+ except Exception as ex:
+ logger.stacktrace()
+ logger.error(ex)
+ continue
+ if inode_no in self.inode_count:
+ self.inode_count[inode_no] += 1
+ else:
+ self.inode_count[inode_no] = 1
def nohardlink(self, file, notify, ignore_root_dir):
"""
diff --git a/qbit_manage.py b/qbit_manage.py
index e149bd90..43cf1460 100755
--- a/qbit_manage.py
+++ b/qbit_manage.py
@@ -671,8 +671,10 @@ def print_logo(logger):
next_run_time = schedule_every_x_minutes(sch)
if startupDelay:
run_mode_message += f"\n Startup Delay: Initial Run will start after {startupDelay} seconds"
+ logger.info(run_mode_message)
time.sleep(startupDelay)
- logger.info(run_mode_message)
+ else:
+ logger.info(run_mode_message)
start_loop(True)
while not killer.kill_now:
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 175e64ab..325e4be0 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,2 +1,2 @@
-flake8==7.1.0
-pre-commit==3.7.1
+flake8==7.1.1
+pre-commit==3.8.0
diff --git a/requirements.txt b/requirements.txt
index 508bad69..3affde0e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
bencodepy==0.9.5
-croniter==2.0.5
+croniter==3.0.3
GitPython==3.1.43
-humanize==4.9.0
+humanize==4.10.0
pytimeparse2==1.7.1
qbittorrent-api==2024.8.65
requests==2.32.3
diff --git a/tox.ini b/tox.ini
index 135a0aa2..aa931434 100755
--- a/tox.ini
+++ b/tox.ini
@@ -8,7 +8,7 @@ tox_pip_extensions_ext_venv_update = true
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/requirements-dev.txt
-passenv = HOME SSH_AUTH_SOCK USER
+passenv = HOME,SSH_AUTH_SOCK,USER
[testenv:venv]
envdir = venv