Merge branch 'develop' into pre-commit-ci-update-config

This commit is contained in:
bobokun 2025-11-28 11:26:18 -05:00 committed by GitHub
commit 8ebf9fa378
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 168 additions and 147 deletions

View file

@ -1 +1 @@
4.6.5-develop6
4.6.5-develop9

View file

@ -259,6 +259,76 @@ class ShareLimits:
share_limits_not_yet_tagged = False
check_multiple_share_limits_tag = False
self._log_torrent_details(
t_name,
t_hash,
torrent,
group_name,
group_config,
check_max_ratio,
check_max_seeding_time,
check_limit_upload_speed,
torrent_upload_limit,
hash_not_prev_checked,
share_limits_not_yet_tagged,
)
tor_reached_seed_limit = self.has_reached_seed_limit(
torrent=torrent,
max_ratio=group_config["max_ratio"],
max_seeding_time=group_config["max_seeding_time"],
max_last_active=group_config["max_last_active"],
min_seeding_time=group_config["min_seeding_time"],
min_num_seeds=group_config["min_num_seeds"],
min_last_active=group_config["min_last_active"],
resume_torrent=group_config["resume_torrent_after_change"],
tracker=tracker["url"],
reset_upload_speed_on_unmet_minimums=group_config["reset_upload_speed_on_unmet_minimums"],
)
logger.trace(f"tor_reached_seed_limit: {tor_reached_seed_limit}")
# Update share limits tag if needed
tags_changed = self.update_share_limits_tag_for_torrent(torrent)
# Get updated torrent after checking if the torrent has reached seed limits
if tags_changed:
torrent = self.qbt.get_torrents({"torrent_hashes": t_hash})[0]
if self._should_update_torrent(
check_max_ratio,
check_max_seeding_time,
check_limit_upload_speed,
share_limits_not_yet_tagged,
check_multiple_share_limits_tag,
tor_reached_seed_limit,
group_config,
hash_not_prev_checked,
torrent,
):
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:
logger.print_line(logger.insert_space(f"Added Tag: {self.group_tag}", 8), self.config.loglevel)
self.process_share_limits_for_torrent(torrent, group_config, tor_reached_seed_limit, torrent_upload_limit)
self.stats_tagged += 1
self.torrents_updated.append(t_name)
self.torrent_hash_checked.append(t_hash)
def _log_torrent_details(
self,
t_name,
t_hash,
torrent,
group_name,
group_config,
check_max_ratio,
check_max_seeding_time,
check_limit_upload_speed,
torrent_upload_limit,
hash_not_prev_checked,
share_limits_not_yet_tagged,
):
"""Log detailed trace information for a torrent"""
logger.trace(f"Torrent: {t_name} [Hash: {t_hash}]")
logger.trace(f"Torrent Category: {torrent.category}")
logger.trace(f"Torrent Tags: {torrent.tags}")
@ -289,71 +359,70 @@ class ShareLimits:
logger.trace(f"upload_speed_on_limit_reached: {group_config['upload_speed_on_limit_reached']}")
logger.trace(f"hash_not_prev_checked: {hash_not_prev_checked}")
logger.trace(f"share_limits_not_yet_tagged: {share_limits_not_yet_tagged}")
logger.trace(
f"check_multiple_share_limits_tag: {is_tag_in_torrent(self.share_limits_tag, torrent.tags, exact=False)}"
)
logger.trace(f"check_multiple_share_limits_tag: {is_tag_in_torrent(self.share_limits_tag, torrent.tags, exact=False)}")
tor_reached_seed_limit = self.has_reached_seed_limit(
torrent=torrent,
max_ratio=group_config["max_ratio"],
max_seeding_time=group_config["max_seeding_time"],
max_last_active=group_config["max_last_active"],
min_seeding_time=group_config["min_seeding_time"],
min_num_seeds=group_config["min_num_seeds"],
min_last_active=group_config["min_last_active"],
resume_torrent=group_config["resume_torrent_after_change"],
tracker=tracker["url"],
reset_upload_speed_on_unmet_minimums=group_config["reset_upload_speed_on_unmet_minimums"],
)
logger.trace(f"tor_reached_seed_limit: {tor_reached_seed_limit}")
# Update share limits tag if needed
self.update_share_limits_tag_for_torrent(torrent)
def _should_update_torrent(
self,
check_max_ratio,
check_max_seeding_time,
check_limit_upload_speed,
share_limits_not_yet_tagged,
check_multiple_share_limits_tag,
tor_reached_seed_limit,
group_config,
hash_not_prev_checked,
torrent,
):
"""Determine if a torrent needs to be updated"""
if not hash_not_prev_checked:
return False
# Get updated torrent after checking if the torrent has reached seed limits
torrent = self.qbt.get_torrents({"torrent_hashes": t_hash})[0]
if (
needs_update = (
check_max_ratio
or check_max_seeding_time
or check_limit_upload_speed
or share_limits_not_yet_tagged
or check_multiple_share_limits_tag
or tor_reached_seed_limit
) and hash_not_prev_checked:
if (
(
or (tor_reached_seed_limit and (group_config["cleanup"] or group_config["upload_speed_on_limit_reached"] != 0))
)
if not needs_update:
return False
# Check for exclusion tags
has_exclusion_tags = (
not is_tag_in_torrent(self.min_seeding_time_tag, torrent.tags)
and not is_tag_in_torrent(self.min_num_seeds_tag, torrent.tags)
and not is_tag_in_torrent(self.last_active_tag, torrent.tags)
)
return (
has_exclusion_tags
or share_limits_not_yet_tagged
or check_multiple_share_limits_tag
or tor_reached_seed_limit
):
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:
logger.print_line(logger.insert_space(f"Added Tag: {self.group_tag}", 8), self.config.loglevel)
self.process_share_limits_for_torrent(torrent, group_config, tor_reached_seed_limit, torrent_upload_limit)
self.stats_tagged += 1
self.torrents_updated.append(t_name)
self.torrent_hash_checked.append(t_hash)
or (tor_reached_seed_limit and (group_config["cleanup"] or group_config["upload_speed_on_limit_reached"] != 0))
)
def update_share_limits_tag_for_torrent(self, torrent):
"""Updates share limits tag for a torrent if needed"""
"""Updates share limits tag for a torrent if needed. Returns True if tags were changed."""
tags_changed = False
# Check if the share limits tag needs to be updated
if not self.config.dry_run:
# Remove previous share_limits tag
tag = is_tag_in_torrent(self.share_limits_tag, torrent.tags, exact=False)
if tag:
torrent.remove_tags(tag)
tags_changed = True
# Check if any of the previous share limits custom tags are there
for custom_tag in self.share_limits_custom_tags:
if is_tag_in_torrent(custom_tag, torrent.tags):
torrent.remove_tags(custom_tag)
tags_changed = True
# Will tag the torrent with the group name if add_group_to_tag is True
if self.group_tag:
torrent.add_tags(self.group_tag)
tags_changed = True
return tags_changed
def process_share_limits_for_torrent(self, torrent, group_config, tor_reached_seed_limit, torrent_upload_limit):
"""Updates share limits for a torrent"""
@ -595,112 +664,64 @@ class ShareLimits:
body = ""
torrent_tags = torrent.tags
def _remove_min_seeding_time_tag():
def _remove_tag(tag):
nonlocal torrent_tags
if is_tag_in_torrent(self.min_seeding_time_tag, torrent_tags):
if is_tag_in_torrent(tag, torrent_tags):
if not self.config.dry_run:
torrent.remove_tags(tags=self.min_seeding_time_tag)
torrent.remove_tags(tags=tag)
def _has_reached_min_seeding_time_limit():
def _add_tag_and_reset_limits(tag, reason_msg):
nonlocal torrent_tags
print_log = []
if torrent.seeding_time >= min_seeding_time * 60:
_remove_min_seeding_time_tag()
return True
else:
if not is_tag_in_torrent(self.min_seeding_time_tag, torrent_tags):
print_log += logger.print_line(logger.insert_space(f"Torrent Name: {torrent.name}", 3), self.config.loglevel)
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: {str(timedelta(seconds=torrent.seeding_time))} <="
f" {str(timedelta(minutes=min_seeding_time))}. Removing Share Limits so qBittorrent can continue"
" seeding.",
8,
),
self.config.loglevel,
)
print_log += logger.print_line(
logger.insert_space(f"Adding Tag: {self.min_seeding_time_tag}", 8), self.config.loglevel
)
if not is_tag_in_torrent(tag, torrent_tags):
logger.print_line(logger.insert_space(f"Torrent Name: {torrent.name}", 3), self.config.loglevel)
logger.print_line(logger.insert_space(f"Tracker: {tracker}", 8), self.config.loglevel)
logger.print_line(logger.insert_space(reason_msg, 8), self.config.loglevel)
logger.print_line(logger.insert_space(f"Adding Tag: {tag}", 8), self.config.loglevel)
if not self.config.dry_run:
torrent.add_tags(self.min_seeding_time_tag)
torrent_tags += f", {self.min_seeding_time_tag}"
torrent.add_tags(tag)
torrent_tags += f", {tag}"
torrent.set_share_limits(ratio_limit=-1, seeding_time_limit=-1, inactive_seeding_time_limit=-1)
if reset_upload_speed_on_unmet_minimums:
torrent.set_upload_limit(-1)
if resume_torrent:
torrent.resume()
def _has_reached_min_seeding_time_limit():
if torrent.seeding_time >= min_seeding_time * 60:
_remove_tag(self.min_seeding_time_tag)
return True
else:
reason = (
f"Min seed time not met: {str(timedelta(seconds=torrent.seeding_time))} <= "
f"{str(timedelta(minutes=min_seeding_time))}. Removing Share Limits so qBittorrent can continue seeding."
)
_add_tag_and_reset_limits(self.min_seeding_time_tag, reason)
return False
def _is_less_than_min_num_seeds():
nonlocal torrent_tags
print_log = []
if min_num_seeds == 0 or torrent.num_complete >= min_num_seeds:
if is_tag_in_torrent(self.min_num_seeds_tag, torrent_tags):
if not self.config.dry_run:
torrent.remove_tags(tags=self.min_num_seeds_tag)
_remove_tag(self.min_num_seeds_tag)
return False
else:
if not is_tag_in_torrent(self.min_num_seeds_tag, torrent_tags):
print_log += logger.print_line(logger.insert_space(f"Torrent Name: {torrent.name}", 3), self.config.loglevel)
print_log += logger.print_line(logger.insert_space(f"Tracker: {tracker}", 8), self.config.loglevel)
print_log += logger.print_line(
logger.insert_space(
reason = (
f"Min number of seeds not met: Total Seeds ({torrent.num_complete}) < "
f"min_num_seeds({min_num_seeds}). Removing Share Limits so qBittorrent can continue"
" seeding.",
8,
),
self.config.loglevel,
f"min_num_seeds({min_num_seeds}). Removing Share Limits so qBittorrent can continue seeding."
)
print_log += logger.print_line(
logger.insert_space(f"Adding Tag: {self.min_num_seeds_tag}", 8), self.config.loglevel
)
if not self.config.dry_run:
torrent.add_tags(self.min_num_seeds_tag)
torrent_tags += f", {self.min_num_seeds_tag}"
torrent.set_share_limits(ratio_limit=-1, seeding_time_limit=-1, inactive_seeding_time_limit=-1)
if reset_upload_speed_on_unmet_minimums:
torrent.set_upload_limit(-1)
if resume_torrent:
torrent.resume()
_add_tag_and_reset_limits(self.min_num_seeds_tag, reason)
return True
def _has_reached_min_last_active_time_limit():
nonlocal torrent_tags
print_log = []
now = int(time())
inactive_time_minutes = round((now - torrent.last_activity) / 60)
if inactive_time_minutes >= min_last_active:
if is_tag_in_torrent(self.last_active_tag, torrent_tags):
if not self.config.dry_run:
torrent.remove_tags(tags=self.last_active_tag)
_remove_tag(self.last_active_tag)
return True
else:
if not is_tag_in_torrent(self.last_active_tag, torrent_tags):
print_log += logger.print_line(logger.insert_space(f"Torrent Name: {torrent.name}", 3), self.config.loglevel)
print_log += logger.print_line(logger.insert_space(f"Tracker: {tracker}", 8), self.config.loglevel)
print_log += logger.print_line(
logger.insert_space(
reason = (
f"Min inactive time not met: {str(timedelta(minutes=inactive_time_minutes))} <= "
f" {str(timedelta(minutes=min_last_active))}. Removing Share Limits so qBittorrent can continue"
" seeding.",
8,
),
self.config.loglevel,
f"{str(timedelta(minutes=min_last_active))}. Removing Share Limits so qBittorrent can continue seeding."
)
print_log += logger.print_line(
logger.insert_space(f"Adding Tag: {self.last_active_tag}", 8), self.config.loglevel
)
if not self.config.dry_run:
torrent.add_tags(self.last_active_tag)
torrent_tags += f", {self.last_active_tag}"
torrent.set_share_limits(ratio_limit=-1, seeding_time_limit=-1, inactive_seeding_time_limit=-1)
if reset_upload_speed_on_unmet_minimums:
torrent.set_upload_limit(-1)
if resume_torrent:
torrent.resume()
_add_tag_and_reset_limits(self.last_active_tag, reason)
return False
def _has_reached_seeding_time_limit():
@ -713,7 +734,7 @@ class ShareLimits:
elif max_seeding_time == -2 and self.qbt.global_max_seeding_time_enabled:
seeding_time_limit = self.qbt.global_max_seeding_time
else:
_remove_min_seeding_time_tag()
_remove_tag(self.min_seeding_time_tag)
return False
if seeding_time_limit is not None:
if (torrent.seeding_time >= seeding_time_limit * 60) and _has_reached_min_seeding_time_limit():