Fixes #359 using save_files

This commit is contained in:
bobokun 2024-02-15 19:39:56 -05:00
parent c1ace03502
commit 1e3a45df86
No known key found for this signature in database
GPG key ID: B73932169607D927
5 changed files with 81 additions and 20 deletions

View file

@ -1 +1 @@
4.0.9-develop11 4.0.9-develop12

View file

@ -76,7 +76,6 @@ class CrossSeed:
self.client.torrents.add( self.client.torrents.add(
torrent_files=src, save_path=dest, category=category, tags=self.cross_seed_tag, is_paused=True torrent_files=src, save_path=dest, category=category, tags=self.cross_seed_tag, is_paused=True
) )
self.qbt.torrentinfo[t_name]["count"] += 1
try: try:
torrent_hash_generator = TorrentHashGenerator(src) torrent_hash_generator = TorrentHashGenerator(src)
torrent_hash = torrent_hash_generator.generate_torrent_hash() torrent_hash = torrent_hash_generator.generate_torrent_hash()
@ -90,6 +89,7 @@ class CrossSeed:
logger.warning(f"Unable to find hash {torrent_hash} in qbt: {e}") logger.warning(f"Unable to find hash {torrent_hash} in qbt: {e}")
if torrent_info: if torrent_info:
torrent = torrent_info[0] torrent = torrent_info[0]
self.qbt.add_torrent_files(torrent.hash, torrent.files)
self.qbt.torrentvalid.append(torrent) self.qbt.torrentvalid.append(torrent)
self.qbt.torrentinfo[t_name]["torrents"].append(torrent) self.qbt.torrentinfo[t_name]["torrents"].append(torrent)
self.qbt.torrent_list.append(torrent) self.qbt.torrent_list.append(torrent)
@ -114,8 +114,7 @@ class CrossSeed:
t_cat = torrent.category t_cat = torrent.category
if ( if (
not util.is_tag_in_torrent(self.cross_seed_tag, torrent.tags) not util.is_tag_in_torrent(self.cross_seed_tag, torrent.tags)
and self.qbt.torrentinfo[t_name]["count"] > 1 and self.qbt.is_cross_seed(torrent)
and self.qbt.torrentinfo[t_name]["first_hash"] != torrent.hash
and torrent.downloaded == 0 and torrent.downloaded == 0
and torrent.seeding_time > 0 and torrent.seeding_time > 0
): ):

View file

@ -209,7 +209,7 @@ class RemoveUnregistered:
"torrent_tracker": tracker["url"], "torrent_tracker": tracker["url"],
"notifiarr_indexer": tracker["notifiarr"], "notifiarr_indexer": tracker["notifiarr"],
} }
if self.qbt.torrentinfo[self.t_name]["count"] > 1: if self.qbt.has_cross_seed(torrent):
# Checks if any of the original torrents are working # Checks if any of the original torrents are working
if "" in self.t_msg or 2 in self.t_status: if "" in self.t_msg or 2 in self.t_status:
attr["torrents_deleted_and_contents"] = False attr["torrents_deleted_and_contents"] = False
@ -232,4 +232,3 @@ class RemoveUnregistered:
attr["body"] = "\n".join(body) attr["body"] = "\n".join(body)
self.torrents_updated_unreg.append(self.t_name) self.torrents_updated_unreg.append(self.t_name)
self.notify_attr_unreg.append(attr) self.notify_attr_unreg.append(attr)
self.qbt.torrentinfo[self.t_name]["count"] -= 1

View file

@ -80,7 +80,6 @@ class ShareLimits:
for torrent_hash, torrent_dict in self.tdel_dict.items(): for torrent_hash, torrent_dict in self.tdel_dict.items():
torrent = torrent_dict["torrent"] torrent = torrent_dict["torrent"]
t_name = torrent.name t_name = torrent.name
t_count = self.qbt.torrentinfo[t_name]["count"]
t_msg = self.qbt.torrentinfo[t_name]["msg"] t_msg = self.qbt.torrentinfo[t_name]["msg"]
t_status = self.qbt.torrentinfo[t_name]["status"] t_status = self.qbt.torrentinfo[t_name]["status"]
# Double check that the content path is the same before we delete anything # Double check that the content path is the same before we delete anything
@ -106,7 +105,7 @@ class ShareLimits:
} }
if os.path.exists(torrent["content_path"].replace(self.root_dir, self.remote_dir)): if os.path.exists(torrent["content_path"].replace(self.root_dir, self.remote_dir)):
# Checks if any of the original torrents are working # Checks if any of the original torrents are working
if t_count > 1 and ("" in t_msg or 2 in t_status): if self.qbt.has_cross_seed(torrent) and ("" in t_msg or 2 in t_status):
self.stats_deleted += 1 self.stats_deleted += 1
attr["torrents_deleted_and_contents"] = False attr["torrents_deleted_and_contents"] = False
t_deleted.add(t_name) t_deleted.add(t_name)
@ -137,7 +136,6 @@ class ShareLimits:
attr["body"] = "\n".join(body) attr["body"] = "\n".join(body)
if not group_notifications: if not group_notifications:
self.config.send_notifications(attr) self.config.send_notifications(attr)
self.qbt.torrentinfo[t_name]["count"] -= 1
if group_notifications: if group_notifications:
if t_deleted: if t_deleted:
attr = { attr = {

View file

@ -80,6 +80,7 @@ class Qbt:
raise Failed(exc) raise Failed(exc)
logger.separator("Getting Torrent List", space=False, border=False) logger.separator("Getting Torrent List", space=False, border=False)
self.torrent_list = self.get_torrents({"sort": "added_on"}) self.torrent_list = self.get_torrents({"sort": "added_on"})
self.torrentfiles = {} # a map of torrent files to track cross-seeds
self.global_max_ratio_enabled = self.client.app.preferences.max_ratio_enabled self.global_max_ratio_enabled = self.client.app.preferences.max_ratio_enabled
self.global_max_ratio = self.client.app.preferences.max_ratio self.global_max_ratio = self.client.app.preferences.max_ratio
@ -97,12 +98,11 @@ class Qbt:
def get_torrent_info(self): def get_torrent_info(self):
""" """
Will create a 2D Dictionary with the torrent name as the key Will create a 2D Dictionary with the torrent name as the key
self.torrentinfo = {'TorrentName1' : {'Category':'TV', 'save_path':'/data/torrents/TV', 'count':1, 'msg':'[]'...}, self.torrentinfo = {'TorrentName1' : {'Category':'TV', 'save_path':'/data/torrents/TV', 'msg':'[]'...},
'TorrentName2' : {'Category':'Movies', 'save_path':'/data/torrents/Movies'}, 'count':2, 'msg':'[]'...} 'TorrentName2' : {'Category':'Movies', 'save_path':'/data/torrents/Movies'}, 'msg':'[]'...}
List of dictionary key definitions List of dictionary key definitions
Category = Returns category of the torrent (str) Category = Returns category of the torrent (str)
save_path = Returns the save path of the torrent (str) save_path = Returns the save path of the torrent (str)
count = Returns a count of the total number of torrents with the same name (int)
msg = Returns a list of torrent messages by name (list of str) msg = Returns a list of torrent messages by name (list of str)
status = Returns the list of status numbers of the torrent by name status = Returns the list of status numbers of the torrent by name
(0: Tracker is disabled (used for DHT, PeX, and LSD), (0: Tracker is disabled (used for DHT, PeX, and LSD),
@ -112,8 +112,6 @@ class Qbt:
4: Tracker has been contacted, but it is not working (or doesn't send proper replies) 4: Tracker has been contacted, but it is not working (or doesn't send proper replies)
is_complete = Returns the state of torrent is_complete = Returns the state of torrent
(Returns True if at least one of the torrent with the State is categorized as Complete.) (Returns True if at least one of the torrent with the State is categorized as Complete.)
first_hash = Returns the hash number of the original torrent (Assuming the torrent list is sorted by date added (Asc))
Takes in a number n, returns the square of n
""" """
self.torrentinfo = {} self.torrentinfo = {}
self.torrentissue = [] # list of unregistered torrent objects self.torrentissue = [] # list of unregistered torrent objects
@ -141,23 +139,20 @@ class Qbt:
save_path = torrent.save_path save_path = torrent.save_path
category = torrent.category category = torrent.category
torrent_trackers = torrent.trackers torrent_trackers = torrent.trackers
self.add_torrent_files(torrent_hash, torrent.files)
except Exception as ex: except Exception as ex:
self.config.notify(ex, "Get Torrent Info", False) self.config.notify(ex, "Get Torrent Info", False)
logger.warning(ex) logger.warning(ex)
if torrent_name in self.torrentinfo: if torrent_name in self.torrentinfo:
t_obj_list.append(torrent) t_obj_list.append(torrent)
t_count = self.torrentinfo[torrent_name]["count"] + 1
msg_list = self.torrentinfo[torrent_name]["msg"] msg_list = self.torrentinfo[torrent_name]["msg"]
status_list = self.torrentinfo[torrent_name]["status"] status_list = self.torrentinfo[torrent_name]["status"]
is_complete = True if self.torrentinfo[torrent_name]["is_complete"] is True else torrent_is_complete is_complete = True if self.torrentinfo[torrent_name]["is_complete"] is True else torrent_is_complete
first_hash = self.torrentinfo[torrent_name]["first_hash"]
else: else:
t_obj_list = [torrent] t_obj_list = [torrent]
t_count = 1
msg_list = [] msg_list = []
status_list = [] status_list = []
is_complete = torrent_is_complete is_complete = torrent_is_complete
first_hash = torrent_hash
for trk in torrent_trackers: for trk in torrent_trackers:
if trk.url.startswith("http"): if trk.url.startswith("http"):
status = trk.status status = trk.status
@ -188,14 +183,80 @@ class Qbt:
"torrents": t_obj_list, "torrents": t_obj_list,
"Category": category, "Category": category,
"save_path": save_path, "save_path": save_path,
"count": t_count,
"msg": msg_list, "msg": msg_list,
"status": status_list, "status": status_list,
"is_complete": is_complete, "is_complete": is_complete,
"first_hash": first_hash,
} }
self.torrentinfo[torrent_name] = torrentattr self.torrentinfo[torrent_name] = torrentattr
def add_torrent_files(self, torrent_hash, torrent_files):
"""Process torrent files by adding the hash to the appropriate torrent_files list.
Example structure:
torrent_files = {
"folder1/file1.txt": {"original": torrent_hash1, "cross_seed": ["torrent_hash2", "torrent_hash3"]},
"folder1/file2.txt": {"original": torrent_hash1, "cross_seed": ["torrent_hash2"]},
"folder2/file1.txt": {"original": torrent_hash2, "cross_seed": []},
}
"""
for file in torrent_files:
file_name = file.name
if file_name not in self.torrentfiles:
self.torrentfiles[file_name] = {"original": torrent_hash, "cross_seed": []}
else:
self.torrentfiles[file_name]["cross_seed"].append(torrent_hash)
def is_cross_seed(self, torrent):
"""Check if the torrent is a cross seed if it has one or more files that are cross seeded."""
t_hash = torrent.hash
t_name = torrent.name
if torrent.downloaded != 0:
logger.trace(f"Torrent: {t_name} [Hash: {t_hash}] is not a cross seeded torrent. Download is > 0.")
return False
cross_seed = True
for file in torrent.files:
file_name = file.name
if self.torrentfiles[file_name]["original"] == t_hash or t_hash not in self.torrentfiles[file_name]["cross_seed"]:
logger.trace(f"File: [{file_name}] is found in Torrent: {t_name} [Hash: {t_hash}] as the original torrent")
cross_seed = False
break
elif self.torrentfiles[file_name]["original"] is None:
cross_seed = False
break
logger.trace(f"Torrent: {t_name} [Hash: {t_hash}] {'is' if cross_seed else 'is not'} a cross seed torrent.")
return cross_seed
def has_cross_seed(self, torrent):
"""Check if the torrent has a cross seed"""
cross_seed = False
t_hash = torrent.hash
t_name = torrent.name
for file in torrent.files:
file_name = file.name
if len(self.torrentfiles[file_name]["cross_seed"]) > 0:
logger.trace(f"{file_name} has cross seeds: {self.torrentfiles[file_name]['cross_seed']}")
cross_seed = True
break
logger.trace(f"Torrent: {t_name} [Hash: {t_hash}] {'has' if cross_seed else 'has no'} cross seeds.")
return cross_seed
def remove_torrent_files(self, torrent):
"""Update the torrent_files list after a torrent is deleted"""
torrent_hash = torrent.hash
for file in torrent.files:
file_name = file.name
if self.torrentfiles[file_name]["original"] == torrent_hash:
if len(self.torrentfiles[file_name]["cross_seed"]) > 0:
self.torrentfiles[file_name]["original"] = self.torrentfiles[file_name]["cross_seed"].pop(0)
logger.trace(f"Updated {file_name} original to {self.torrentfiles[file_name]['original']}")
else:
self.torrentfiles[file_name]["original"] = None
else:
if torrent_hash in self.torrentfiles[file_name]["cross_seed"]:
self.torrentfiles[file_name]["cross_seed"].remove(torrent_hash)
logger.trace(f"Removed {torrent_hash} from {file_name} cross seeds")
logger.trace(f"{file_name} original: {self.torrentfiles[file_name]['original']}")
logger.trace(f"{file_name} cross seeds: {self.torrentfiles[file_name]['cross_seed']}")
def get_torrents(self, params): def get_torrents(self, params):
"""Get torrents from qBittorrent""" """Get torrents from qBittorrent"""
return self.client.torrents.info(**params) return self.client.torrents.info(**params)
@ -424,3 +485,7 @@ class Qbt:
self.torrent_list.remove(torrent) self.torrent_list.remove(torrent)
except ValueError: except ValueError:
logger.debug(f"Torrent {torrent.name} has already been deleted from torrent list.") logger.debug(f"Torrent {torrent.name} has already been deleted from torrent list.")
try:
self.remove_torrent_files(torrent)
except ValueError:
logger.debug(f"Torrent {torrent.name} has already been removed from torrent files.")