From d0421f2b7d6ab40cd3b4f6c838cb5cc11c192865 Mon Sep 17 00:00:00 2001 From: bobokun Date: Sun, 11 Jun 2023 15:33:09 -0400 Subject: [PATCH] fixes #329 (updates missing share_limits tag when share_limits are satisfied) Modifies logic for share_limits_suffix_tag to become share_limits_tag. This change adds share_limits_tag to become prefix rather than suffix and adds additional priority information --- CHANGELOG | 16 ++++++++++++++-- VERSION | 2 +- config/config.yml.sample | 2 +- modules/config.py | 11 ++++++++--- modules/core/share_limits.py | 35 +++++++++++++++++++++++++++-------- modules/core/tags.py | 4 ++-- modules/util.py | 7 +++++++ 7 files changed, 60 insertions(+), 17 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 09739e4..f7cf940 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,11 +1,23 @@ # Requirements Updated -# Breaking Changes - # New Features - cross-seed will move torrent to an error folder if it fails to inject torrent # Bug Fixes +- Fixes #329 (Updates missing share_limits tag even when share_limits are satisfied) +# Enhancements +- Logic for `share_limits_suffix_tag` changed to become a prefix tag instead along with adding the priority of the group. The reason for this change is so it's easier to see the share limit groups togethered in qbitorrent ordered by priority. + - `share_limits_suffix_tag` key is now `share_limits_tag` + - No config changes are required as the qbm will automatically change the previous `share_limits_suffix_tag` key to `share_limits_tag` + +Example based on config.sample: + +| old tag (v4.0.0) | new tag (v4.0.1) | +| ----------- | ----------- | +| noHL.share_limits | share_limits_1.noHL | +| cross-seed.share_limits | share_limits_2.cross-seed | +| PTP.share_limits | share_limits_3.PTP | +| default.share_limits | share_limits_999.default | **Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.0.0...v4.0.1 diff --git a/VERSION b/VERSION index 4db799f..0379052 100755 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.0.1-develop1 +4.0.1-develop2 diff --git a/config/config.yml.sample b/config/config.yml.sample index 40b8e5d..76c6a2a 100755 --- a/config/config.yml.sample +++ b/config/config.yml.sample @@ -28,7 +28,7 @@ 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_suffix_tag: share_limit # Will add this suffix to the grouping separated by '.' to the tag of any torrents with share limits. + 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 ignoreTags_OnUpdate: # When running tag-update function, it will update torrent tags for a given torrent even if the torrent has at least one or more of the tags defined here. Otherwise torrents will not be tagged if tags exist. - noHL - issue diff --git a/modules/config.py b/modules/config.py index ecad953..4e6dfa1 100755 --- a/modules/config.py +++ b/modules/config.py @@ -146,6 +146,8 @@ class Config: self.loglevel = "DRYRUN" if self.dry_run else "INFO" self.session = requests.Session() + share_limits_tag = self.data["settings"].get("share_limits_suffix_tag", "share_limits") + self.settings = { "force_auto_tmm": self.util.check_for_attribute( self.data, "force_auto_tmm", parent="settings", var_type="bool", default=False @@ -154,19 +156,22 @@ class Config: self.data, "tracker_error_tag", parent="settings", default="issue" ), "nohardlinks_tag": self.util.check_for_attribute(self.data, "nohardlinks_tag", parent="settings", default="noHL"), - "share_limits_suffix_tag": self.util.check_for_attribute( - self.data, "share_limits_suffix_tag", parent="settings", default="share_limit" + "share_limits_tag": self.util.check_for_attribute( + self.data, "share_limits_tag", parent="settings", default=share_limits_tag ), } self.tracker_error_tag = self.settings["tracker_error_tag"] self.nohardlinks_tag = self.settings["nohardlinks_tag"] - self.share_limits_suffix_tag = "." + self.settings["share_limits_suffix_tag"] + self.share_limits_tag = self.settings["share_limits_tag"] default_ignore_tags = [self.nohardlinks_tag, self.tracker_error_tag, "cross-seed"] self.settings["ignoreTags_OnUpdate"] = self.util.check_for_attribute( self.data, "ignoreTags_OnUpdate", parent="settings", default=default_ignore_tags, var_type="list" ) + "Migrate settings from v4.0.0 to v4.0.1 and beyond. Convert 'share_limits_suffix_tag' to 'share_limits_tag'" + if "share_limits_suffix_tag" in self.data["settings"]: + self.util.overwrite_attributes(self.settings, "settings") default_function = { "cross_seed": None, diff --git a/modules/core/share_limits.py b/modules/core/share_limits.py index 2e5b615..9fb092a 100644 --- a/modules/core/share_limits.py +++ b/modules/core/share_limits.py @@ -24,10 +24,11 @@ class ShareLimits: self.share_limits_config = qbit_manager.config.share_limits # configuration of share limits self.torrents_updated = [] # list of torrents that have been updated self.torrent_hash_checked = [] # list of torrent hashes that have been checked for share limits - self.share_limits_suffix_tag = qbit_manager.config.share_limits_suffix_tag # suffix tag for share limits + self.share_limits_tag = qbit_manager.config.share_limits_tag # tag for share limits self.group_tag = None # tag for the share limit group self.update_share_limits() + self.delete_share_limits_suffix_tag() def update_share_limits(self): """Updates share limits for torrents based on grouping""" @@ -166,6 +167,9 @@ class ShareLimits: for torrent in torrents: t_name = torrent.name t_hash = torrent.hash + self.group_tag = ( + f"{self.share_limits_tag}_{group_config['priority']}.{group_name}" if group_config["add_group_to_tag"] else None + ) tracker = self.qbt.get_tags(torrent.trackers) check_max_ratio = group_config["max_ratio"] != torrent.max_ratio check_max_seeding_time = group_config["max_seeding_time"] != torrent.max_seeding_time @@ -175,6 +179,7 @@ class ShareLimits: group_config["limit_upload_speed"] = -1 check_limit_upload_speed = group_config["limit_upload_speed"] != torrent_upload_limit hash_not_prev_checked = t_hash not in self.torrent_hash_checked + share_limits_not_yet_tagged = True if self.group_tag and self.group_tag not in torrent.tags else False logger.trace(f"Torrent: {t_name} [Hash: {t_hash}]") logger.trace(f"Torrent Category: {torrent.category}") logger.trace(f"Torrent Tags: {torrent.tags}") @@ -192,9 +197,11 @@ class ShareLimits: ) logger.trace(f"check_limit_upload_speed: {check_limit_upload_speed}") logger.trace(f"hash_not_prev_checked: {hash_not_prev_checked}") - if (check_max_ratio or check_max_seeding_time or check_limit_upload_speed) and hash_not_prev_checked: + logger.trace(f"share_limits_not_yet_tagged: {share_limits_not_yet_tagged}") + if ( + check_max_ratio or check_max_seeding_time or check_limit_upload_speed or share_limits_not_yet_tagged + ) and hash_not_prev_checked: if "MinSeedTimeNotReached" not in torrent.tags: - self.group_tag = f"{group_name}{self.share_limits_suffix_tag}" if group_config["add_group_to_tag"] else None logger.print_line(logger.insert_space(f"Torrent Name: {t_name}", 3), self.config.loglevel) logger.print_line(logger.insert_space(f'Tracker: {tracker["url"]}', 8), self.config.loglevel) if self.group_tag: @@ -226,7 +233,7 @@ class ShareLimits: # Remove previous share_limits tag tags = util.get_list(torrent.tags) for tag in tags: - if self.share_limits_suffix_tag in tag: + if self.share_limits_tag in tag: torrent.remove_tags(tag) # Will tag the torrent with the group name if add_group_to_tag is True and set the share limits @@ -371,8 +378,11 @@ 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 seed time not met: {timedelta(seconds=torrent.seeding_time)} <= " - f"{timedelta(minutes=min_seeding_time)}. Removing Share Limits so qBittorrent can continue seeding.", + ( + f"Min seed time not met: {timedelta(seconds=torrent.seeding_time)} <=" + f" {timedelta(minutes=min_seeding_time)}. Removing Share Limits so qBittorrent can continue" + " seeding." + ), 8, ), self.config.loglevel, @@ -401,8 +411,10 @@ class ShareLimits: if seeding_time_limit: if (torrent.seeding_time >= seeding_time_limit * 60) and _has_reached_min_seeding_time_limit(): body += logger.insert_space( - f"Seeding Time vs Max Seed Time: {timedelta(seconds=torrent.seeding_time)} >= " - f"{timedelta(minutes=seeding_time_limit)}", + ( + f"Seeding Time vs Max Seed Time: {timedelta(seconds=torrent.seeding_time)} >= " + f"{timedelta(minutes=seeding_time_limit)}" + ), 8, ) return True @@ -422,3 +434,10 @@ class ShareLimits: if _has_reached_seeding_time_limit(): return body return False + + def delete_share_limits_suffix_tag(self): + """ "Delete Share Limits Suffix Tag from version 4.0.0""" + tags = self.client.torrent_tags.tags + for tag in tags: + if tag.endswith(f".{self.share_limits_tag}"): + self.client.torrent_tags.delete_tags(tag) diff --git a/modules/core/tags.py b/modules/core/tags.py index 540571f..7eaf243 100644 --- a/modules/core/tags.py +++ b/modules/core/tags.py @@ -9,7 +9,7 @@ class Tags: self.config = qbit_manager.config self.client = qbit_manager.client self.stats = 0 - self.share_limits_suffix_tag = qbit_manager.config.share_limits_suffix_tag # suffix tag for share limits + self.share_limits_tag = qbit_manager.config.share_limits_tag # suffix tag for share limits self.torrents_updated = [] # List of torrents updated self.notify_attr = [] # List of single torrent attributes to send to notifiarr @@ -21,7 +21,7 @@ class Tags: ignore_tags = self.config.settings["ignoreTags_OnUpdate"] logger.separator("Updating Tags", space=False, border=False) for torrent in self.qbt.torrent_list: - check_tags = [tag for tag in util.get_list(torrent.tags) if self.share_limits_suffix_tag not in tag] + check_tags = [tag for tag in util.get_list(torrent.tags) if self.share_limits_tag not in tag] if torrent.tags == "" or (len([trk for trk in check_tags if trk not in ignore_tags]) == 0): tracker = self.qbt.get_tags(torrent.trackers) diff --git a/modules/util.py b/modules/util.py index 97a4796..109e619 100755 --- a/modules/util.py +++ b/modules/util.py @@ -136,6 +136,13 @@ class check: def __init__(self, config): self.config = config + def overwrite_attributes(self, data, attribute): + """Overwrite attributes in config.""" + yaml = YAML(self.config.config_path) + if data is not None and attribute in yaml.data: + yaml.data[attribute] = data + yaml.save() + def check_for_attribute( self, data,