From 603fb76328208f60d76b6cd6d69bc9cd2bd254cc Mon Sep 17 00:00:00 2001 From: bobokun Date: Sat, 22 Apr 2023 15:40:02 -0400 Subject: [PATCH 1/8] 3.6.2 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 9575d51b..b7276283 100755 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.6.1 +3.6.2 From c64ec410dac49305c064b81fabd9e1aebf94498f Mon Sep 17 00:00:00 2001 From: bobokun Date: Sat, 22 Apr 2023 15:40:49 -0400 Subject: [PATCH 2/8] Fixes #270 --- CHANGELOG | 7 +++---- modules/core/cross_seed.py | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4633b88a..8f2b26a0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,8 +1,7 @@ # Requirements Updated -- Updates qbitorrent api to 2023.4.47 + # Bug Fixes -- Fixes bug in not removing empty directories (Thanks to @buthed010203 #266) -- Speed up remove_orphan by using multiprocessing (Thanks to @buthed010203 #266) +- Fixes bug in cross_seed (Fixes #270) -**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v3.6.0...v3.6.1 +**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v3.6.1...v3.6.2 diff --git a/modules/core/cross_seed.py b/modules/core/cross_seed.py index 3c5c2559..80e79244 100644 --- a/modules/core/cross_seed.py +++ b/modules/core/cross_seed.py @@ -39,7 +39,7 @@ def cross_seed(self): dest = os.path.join(self.qbt.torrentinfo[t_name]["save_path"], "") src = os.path.join(dir_cs, file) dir_cs_out = os.path.join(dir_cs, "qbit_manage_added", file) - category = self.qbt.global_max_ratioget_category(dest) + category = self.qbt.get_category(dest) # Only add cross-seed torrent if original torrent is complete if self.qbt.torrentinfo[t_name]["is_complete"]: categories.append(category) From 538dd61f8965894185861c9d642979d6aab19369 Mon Sep 17 00:00:00 2001 From: bobokun Date: Sat, 22 Apr 2023 15:57:56 -0400 Subject: [PATCH 3/8] removes old deprecated tags config --- modules/config.py | 2 - modules/qbittorrent.py | 142 +++++++++++++++++++---------------------- 2 files changed, 66 insertions(+), 78 deletions(-) diff --git a/modules/config.py b/modules/config.py index 8092b999..25929f64 100755 --- a/modules/config.py +++ b/modules/config.py @@ -96,8 +96,6 @@ def __init__(self, default_dir, args): self.data["cat_change"] = self.data.pop("cat_change") if "tracker" in self.data: self.data["tracker"] = self.data.pop("tracker") - elif "tags" in self.data: - self.data["tracker"] = self.data.pop("tags") else: self.data["tracker"] = {} if "nohardlinks" in self.data: diff --git a/modules/qbittorrent.py b/modules/qbittorrent.py index 1ca73fa4..99b99035 100755 --- a/modules/qbittorrent.py +++ b/modules/qbittorrent.py @@ -364,102 +364,92 @@ def get_tags(self, trackers): except IndexError as e: logger.debug(f"Tracker Url:{url}") logger.debug(e) - # Tracker Format 1 deprecated. - if isinstance(tag_details, str): - e = ( - "Config Error: Tracker format invalid. Please see config.yml.sample for correct format and fix " - f"`{tag_details}` in the Tracker section of the config." - ) - self.config.notify(e, "Config") - raise Failed(e) - # Using new Format - else: - tracker["tag"] = self.config.util.check_for_attribute( - self.config.data, "tag", parent="tracker", subparent=tag_url, default=tag_url, var_type="list" - ) - if tracker["tag"] == [tag_url]: - self.config.data["tracker"][tag_url]["tag"] = [tag_url] - if isinstance(tracker["tag"], str): - tracker["tag"] = [tracker["tag"]] - is_max_ratio_defined = self.config.data["tracker"].get("max_ratio") - is_max_seeding_time_defined = self.config.data["tracker"].get("max_seeding_time") - if is_max_ratio_defined or is_max_seeding_time_defined: - tracker["max_ratio"] = self.config.util.check_for_attribute( - self.config.data, - "max_ratio", - parent="tracker", - subparent=tag_url, - var_type="float", - min_int=-2, - do_print=False, - default=-1, - save=False, - ) - tracker["max_seeding_time"] = self.config.util.check_for_attribute( - self.config.data, - "max_seeding_time", - parent="tracker", - subparent=tag_url, - var_type="int", - min_int=-2, - do_print=False, - default=-1, - save=False, - ) - else: - tracker["max_ratio"] = self.config.util.check_for_attribute( - self.config.data, - "max_ratio", - parent="tracker", - subparent=tag_url, - var_type="float", - min_int=-2, - do_print=False, - default_is_none=True, - save=False, - ) - tracker["max_seeding_time"] = self.config.util.check_for_attribute( - self.config.data, - "max_seeding_time", - parent="tracker", - subparent=tag_url, - var_type="int", - min_int=-2, - do_print=False, - default_is_none=True, - save=False, - ) - tracker["min_seeding_time"] = self.config.util.check_for_attribute( + tracker["tag"] = self.config.util.check_for_attribute( + self.config.data, "tag", parent="tracker", subparent=tag_url, default=tag_url, var_type="list" + ) + if tracker["tag"] == [tag_url]: + self.config.data["tracker"][tag_url]["tag"] = [tag_url] + if isinstance(tracker["tag"], str): + tracker["tag"] = [tracker["tag"]] + is_max_ratio_defined = self.config.data["tracker"].get("max_ratio") + is_max_seeding_time_defined = self.config.data["tracker"].get("max_seeding_time") + if is_max_ratio_defined or is_max_seeding_time_defined: + tracker["max_ratio"] = self.config.util.check_for_attribute( self.config.data, - "min_seeding_time", + "max_ratio", parent="tracker", subparent=tag_url, - var_type="int", - min_int=0, + var_type="float", + min_int=-2, do_print=False, - default=0, + default=-1, save=False, ) - tracker["limit_upload_speed"] = self.config.util.check_for_attribute( + tracker["max_seeding_time"] = self.config.util.check_for_attribute( self.config.data, - "limit_upload_speed", + "max_seeding_time", parent="tracker", subparent=tag_url, var_type="int", - min_int=-1, + min_int=-2, do_print=False, - default=0, + default=-1, save=False, ) - tracker["notifiarr"] = self.config.util.check_for_attribute( + else: + tracker["max_ratio"] = self.config.util.check_for_attribute( self.config.data, - "notifiarr", + "max_ratio", parent="tracker", subparent=tag_url, + var_type="float", + min_int=-2, + do_print=False, default_is_none=True, + save=False, + ) + tracker["max_seeding_time"] = self.config.util.check_for_attribute( + self.config.data, + "max_seeding_time", + parent="tracker", + subparent=tag_url, + var_type="int", + min_int=-2, do_print=False, + default_is_none=True, save=False, ) + tracker["min_seeding_time"] = self.config.util.check_for_attribute( + self.config.data, + "min_seeding_time", + parent="tracker", + subparent=tag_url, + var_type="int", + min_int=0, + do_print=False, + default=0, + save=False, + ) + tracker["limit_upload_speed"] = self.config.util.check_for_attribute( + self.config.data, + "limit_upload_speed", + parent="tracker", + subparent=tag_url, + var_type="int", + min_int=-1, + do_print=False, + default=0, + save=False, + ) + tracker["notifiarr"] = self.config.util.check_for_attribute( + self.config.data, + "notifiarr", + parent="tracker", + subparent=tag_url, + default_is_none=True, + do_print=False, + save=False, + ) return tracker if tracker_other_tag: tracker["tag"] = tracker_other_tag From 706821f916fa4b5944d26dc07044bc6eba6cfa00 Mon Sep 17 00:00:00 2001 From: bobokun Date: Sat, 22 Apr 2023 17:06:07 -0400 Subject: [PATCH 4/8] better logging for #271 --- modules/util.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/util.py b/modules/util.py index 9999c822..3af9311d 100755 --- a/modules/util.py +++ b/modules/util.py @@ -197,11 +197,13 @@ def check_for_attribute( return data[attribute] else: message = f"{text}: {data[attribute]} is an invalid input" - if var_type == "path" and default and os.path.exists(os.path.abspath(default)): - return os.path.join(default, "") - elif var_type == "path" and default and make_dirs: - os.makedirs(default, exist_ok=True) - return os.path.join(default, "") + if var_type == "path" and default: + default_path = os.path.abspath(default) + if make_dirs and not os.path.exists(default_path): + os.makedirs(default, exist_ok=True) + if os.path.exists(default_path): + default = os.path.join(default, "") + message = message + f", using {default} as default" elif var_type == "path" and default: if data and attribute in data and data[attribute]: message = f"neither {data[attribute]} or the default path {default} could be found" From 9e954c943b08b3fdd77d45eae8835a33153a0b47 Mon Sep 17 00:00:00 2001 From: bobokun Date: Sun, 23 Apr 2023 13:06:14 -0400 Subject: [PATCH 5/8] additional trace logging and error checking to fix #272 --- modules/config.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/modules/config.py b/modules/config.py index 25929f64..f884dc62 100755 --- a/modules/config.py +++ b/modules/config.py @@ -519,6 +519,7 @@ def cleanup_dirs(self, location): for name in files ] location_files = sorted(location_files) + logger.trace(f"location_files: {location_files}") if location_files: body = [] logger.separator(f"Emptying {location} (Files > {empty_after_x_days} days)", space=True, border=True) @@ -527,9 +528,16 @@ def cleanup_dirs(self, location): folder = re.search(f".*{os.path.basename(location_path.rstrip(os.sep))}", file).group(0) if folder != prevfolder: body += logger.separator(f"Searching: {folder}", space=False, border=False) - fileStats = os.stat(file) - filename = os.path.basename(file) - last_modified = fileStats[stat.ST_MTIME] # in seconds (last modified time) + try: + fileStats = os.stat(file) + filename = os.path.basename(file) + last_modified = fileStats[stat.ST_MTIME] # in seconds (last modified time) + except FileNotFoundError: + ex = logger.print_line( + f"{location} Warning - FileNotFound: No such file or directory: {file} ", "WARNING" + ) + self.config.notify(ex, "Cleanup Dirs", False) + continue now = time.time() # in seconds days = (now - last_modified) / (60 * 60 * 24) if empty_after_x_days <= days: From 79cc4fd133d29ac91e50312ecdf17c856d861411 Mon Sep 17 00:00:00 2001 From: bobokun Date: Sun, 23 Apr 2023 13:27:40 -0400 Subject: [PATCH 6/8] Fixes #271 --- modules/util.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/util.py b/modules/util.py index 3af9311d..46dfe235 100755 --- a/modules/util.py +++ b/modules/util.py @@ -182,7 +182,14 @@ def check_for_attribute( if os.path.exists(os.path.abspath(data[attribute])): return os.path.join(data[attribute], "") else: - message = f"Path {os.path.abspath(data[attribute])} does not exist" + if make_dirs: + try: + os.makedirs(data[attribute], exist_ok=True) + return os.path.join(data[attribute], "") + except OSError: + message = f"Path {os.path.abspath(data[attribute])} does not exist and can't be created" + else: + message = f"Path {os.path.abspath(data[attribute])} does not exist" elif var_type == "list": return get_list(data[attribute], split=False) elif var_type == "list_path": From 9beda595f7e0ec015f60ff257ad6856b1ed1a906 Mon Sep 17 00:00:00 2001 From: bobokun Date: Sun, 23 Apr 2023 13:29:03 -0400 Subject: [PATCH 7/8] update changelog --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 8f2b26a0..1c7c7e6b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,5 +3,6 @@ # Bug Fixes - Fixes bug in cross_seed (Fixes #270) +- Bug causing RecycleBin not to be created when full path is defined. (Fixes #271) **Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v3.6.1...v3.6.2 From 8684066e403e0399a0b6c68ae109cd8e1e461dca Mon Sep 17 00:00:00 2001 From: bobokun Date: Mon, 24 Apr 2023 20:17:27 -0400 Subject: [PATCH 8/8] updates changelog --- CHANGELOG | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1c7c7e6b..d09f187f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,8 +1,6 @@ -# Requirements Updated - - # Bug Fixes - Fixes bug in cross_seed (Fixes #270) - Bug causing RecycleBin not to be created when full path is defined. (Fixes #271) +- Fixes Uncaught exception while emptying recycle bin (Fixes #272) **Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v3.6.1...v3.6.2