diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 22c0166..52f7759 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: - id: debug-statements - id: requirements-txt-fixer - id: check-added-large-files - - id: check-byte-order-marker + - id: fix-byte-order-marker - id: fix-encoding-pragma args: [--remove] - id: pretty-format-json @@ -45,7 +45,7 @@ repos: hooks: - id: black language_version: python3 - args: [--line-length, '130', --preview] + args: [--line-length, '130'] - repo: https://github.com/PyCQA/flake8 rev: 6.1.0 hooks: diff --git a/CHANGELOG b/CHANGELOG index ddec541..6772aa7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,19 +1,14 @@ # Requirements Updated -- GitPython==3.1.37 -- ruamel.yaml==0.17.35 -- schedule==1.2.1 - -# New Features -- Added a last_active flag for share_limits to resume torrents and avoid cleanup if there was activity in the last X minutes. (Closes #353) -- New cat option in trackers/[tracker] to allow changing category based on tracker URL. (Closes #200) -- Added new script to edit tracker urls (https://github.com/StuffAnThings/qbit_manage/commit/9290d2c958ea733d22cb3c98d30bab7037997f1d) +- GitPython==3.1.40 +- qbittorrent-api==2023.10.54 +- ruamel.yaml==0.18.2 # Bug Fixes -- Fixes [#388](https://github.com/StuffAnThings/qbit_manage/issues/388) -- Fixes handling BHD API announce related issues -- Special mapping to leave torrents uncategorized on cat-update (closes #395) -- fix exit codes when program fails (#411) +- Fixes #419 +- Remove duplicates when cleaning up directories (#422) +- Fixes #426 +- Fixes #429 -**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.0.4...v4.0.5 +**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.0.5...v4.0.6 -Special thanks to @estebanthi, @fabricionaweb for their contributions! +Special thanks to @garypiner for their contributions! diff --git a/VERSION b/VERSION index 7636e75..d13e837 100755 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.0.5 +4.0.6 diff --git a/modules/apprise.py b/modules/apprise.py index 697d557..5ae9c0e 100755 --- a/modules/apprise.py +++ b/modules/apprise.py @@ -1,5 +1,4 @@ """Apprise notification class""" - import time from modules import util diff --git a/modules/bhd.py b/modules/bhd.py index 9bd2109..19d517d 100755 --- a/modules/bhd.py +++ b/modules/bhd.py @@ -1,5 +1,4 @@ """Module for BeyondHD (BHD) tracker.""" - from json import JSONDecodeError from modules import util diff --git a/modules/config.py b/modules/config.py index 2f77bfc..149c43d 100755 --- a/modules/config.py +++ b/modules/config.py @@ -1,5 +1,4 @@ """Config class for qBittorrent-Manage""" - import os import re import stat @@ -650,6 +649,7 @@ class Config: for path, subdirs, files in os.walk(r_path) for name in files ] + location_files = list(set(location_files)) # remove duplicates location_files = sorted(location_files) logger.trace(f"location_files: {location_files}") if location_files: diff --git a/modules/core/share_limits.py b/modules/core/share_limits.py index eb86f3e..f7ef28d 100644 --- a/modules/core/share_limits.py +++ b/modules/core/share_limits.py @@ -379,7 +379,7 @@ class ShareLimits: return [] if is_tag_in_torrent(LAST_ACTIVE_TAG, torrent.tags): return [] - torrent.set_share_limits(max_ratio, max_seeding_time) + torrent.set_share_limits(ratio_limit=max_ratio, seeding_time_limit=max_seeding_time, inactive_seeding_time_limit=-2) return body def has_reached_seed_limit( @@ -413,7 +413,7 @@ class ShareLimits: ) if not self.config.dry_run: torrent.add_tags(MIN_SEEDING_TIME_TAG) - torrent.set_share_limits(-1, -1) + torrent.set_share_limits(ratio_limit=-1, seeding_time_limit=-1, inactive_seeding_time_limit=-1) if resume_torrent: torrent.resume() return False @@ -443,7 +443,7 @@ class ShareLimits: ) if not self.config.dry_run: torrent.add_tags(MIN_NUM_SEEDS_TAG) - torrent.set_share_limits(-1, -1) + torrent.set_share_limits(ratio_limit=-1, seeding_time_limit=-1, inactive_seeding_time_limit=-1) if resume_torrent: torrent.resume() return True @@ -452,7 +452,7 @@ class ShareLimits: print_log = [] now = int(time()) inactive_time_minutes = round((now - torrent.last_activity) / 60) - if inactive_time_minutes >= last_active * 60: + if inactive_time_minutes >= last_active: if is_tag_in_torrent(LAST_ACTIVE_TAG, torrent.tags): if not self.config.dry_run: torrent.remove_tags(tags=LAST_ACTIVE_TAG) @@ -463,7 +463,7 @@ class ShareLimits: print_log += logger.print_line(logger.insert_space(f"Tracker: {tracker}", 8), self.config.loglevel) print_log += logger.print_line( logger.insert_space( - f"Min inactive time not met: {timedelta(seconds=inactive_time_minutes)} <=" + f"Min inactive time not met: {timedelta(minutes=inactive_time_minutes)} <=" f" {timedelta(minutes=last_active)}. Removing Share Limits so qBittorrent can continue" " seeding.", 8, @@ -473,7 +473,7 @@ class ShareLimits: print_log += logger.print_line(logger.insert_space(f"Adding Tag: {LAST_ACTIVE_TAG}", 8), self.config.loglevel) if not self.config.dry_run: torrent.add_tags(LAST_ACTIVE_TAG) - torrent.set_share_limits(-1, -1) + torrent.set_share_limits(ratio_limit=-1, seeding_time_limit=-1, inactive_seeding_time_limit=-1) if resume_torrent: torrent.resume() return False @@ -485,8 +485,8 @@ class ShareLimits: return False if max_seeding_time >= 0: seeding_time_limit = max_seeding_time - elif max_seeding_time == -2 and self.global_max_seeding_time_enabled: - seeding_time_limit = self.global_max_seeding_time + elif max_seeding_time == -2 and self.qbt.global_max_seeding_time_enabled: + seeding_time_limit = self.qbt.global_max_seeding_time else: return False if seeding_time_limit: @@ -510,10 +510,10 @@ class ShareLimits: if torrent.ratio >= max_ratio and _has_reached_min_seeding_time_limit(): body += logger.insert_space(f"Ratio vs Max Ratio: {torrent.ratio:.2f} >= {max_ratio:.2f}", 8) return body - elif max_ratio == -2 and self.global_max_ratio_enabled and _has_reached_min_seeding_time_limit(): - if torrent.ratio >= self.global_max_ratio: + elif max_ratio == -2 and self.qbt.global_max_ratio_enabled and _has_reached_min_seeding_time_limit(): + if torrent.ratio >= self.qbt.global_max_ratio: body += logger.insert_space( - f"Ratio vs Global Max Ratio: {torrent.ratio:.2f} >= {self.global_max_ratio:.2f}", 8 + f"Ratio vs Global Max Ratio: {torrent.ratio:.2f} >= {self.qbt.global_max_ratio:.2f}", 8 ) return body if _has_reached_seeding_time_limit(): diff --git a/modules/logs.py b/modules/logs.py index c41a72e..d634c2e 100755 --- a/modules/logs.py +++ b/modules/logs.py @@ -1,5 +1,4 @@ """Logging module""" - import io import logging import os diff --git a/modules/qbittorrent.py b/modules/qbittorrent.py index 9db88f4..101094e 100755 --- a/modules/qbittorrent.py +++ b/modules/qbittorrent.py @@ -1,5 +1,4 @@ """Qbittorrent Module""" - import os import sys diff --git a/modules/util.py b/modules/util.py index ca2eaf5..f1421ce 100755 --- a/modules/util.py +++ b/modules/util.py @@ -1,5 +1,4 @@ """ Utility functions for qBit Manage. """ - import json import logging import os diff --git a/modules/webhooks.py b/modules/webhooks.py index bda738a..41afd54 100755 --- a/modules/webhooks.py +++ b/modules/webhooks.py @@ -1,5 +1,4 @@ """Class to handle webhooks.""" - import time from json import JSONDecodeError diff --git a/qbit_manage.py b/qbit_manage.py index 7b5569b..0cf24da 100755 --- a/qbit_manage.py +++ b/qbit_manage.py @@ -432,9 +432,7 @@ def start(): next_run = nxt_run["next_run"] body = logger.separator( f"Finished Run\n{os.linesep.join(stats_summary) if len(stats_summary)>0 else ''}" - f"\nRun Time: {run_time}\n{next_run_str if len(next_run_str)>0 else ''}".replace( - "\n\n", "\n" - ).rstrip() + f"\nRun Time: {run_time}\n{next_run_str if len(next_run_str)>0 else ''}".replace("\n\n", "\n").rstrip() )[0] return next_run, body diff --git a/requirements-dev.txt b/requirements-dev.txt index 9ad64f9..f1730c9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,2 +1,2 @@ flake8==6.1.0 -pre-commit==3.4.0 +pre-commit==3.5.0 diff --git a/requirements.txt b/requirements.txt index 626c9fe..712cffc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ bencodepy==0.9.5 -GitPython==3.1.37 -qbittorrent-api==2023.9.53 +GitPython==3.1.40 +qbittorrent-api==2023.10.54 requests==2.31.0 retrying==1.3.4 -ruamel.yaml==0.17.35 +ruamel.yaml==0.18.2 schedule==1.2.1 diff --git a/scripts/delete_torrents_on_low_disk_space.py b/scripts/delete_torrents_on_low_disk_space.py index fb1a35c..463cae7 100755 --- a/scripts/delete_torrents_on_low_disk_space.py +++ b/scripts/delete_torrents_on_low_disk_space.py @@ -4,7 +4,6 @@ You can also allow incomplete torrents to be deleted. Torrents will be deleted starting with the ones with the most seeds, only torrents with a single hardlink will be deleted. Only torrents on configured drive path will be deleted. To monitor multiple drives, use multiple copies of this script. """ - import os import shutil import time diff --git a/scripts/edit_tracker.py b/scripts/edit_tracker.py index 048d179..064f7b0 100644 --- a/scripts/edit_tracker.py +++ b/scripts/edit_tracker.py @@ -36,5 +36,5 @@ if __name__ == "__main__": if OLD_TRACKER in x.url: newurl = x.url.replace(OLD_TRACKER, NEW_TRACKER) print(f"torrent name: {torrent.name}, original url: {x.url}, modified url: {newurl}\n") - torrent.remove_trackers(hash=(torrent.hash), urls=(x.url)) - torrent.add_trackers(hash=(torrent.hash), urls=(newurl)) + torrent.remove_trackers(urls=x.url) + torrent.add_trackers(urls=newurl)