Adds min_num_seeds (Adds #321)

This commit is contained in:
bobokun 2023-06-24 12:40:20 -04:00
parent 42efc219ad
commit 73838407e6
No known key found for this signature in database
GPG key ID: B73932169607D927
5 changed files with 73 additions and 12 deletions

View file

@ -1 +1 @@
4.0.2-develop6 4.0.2-develop7

View file

@ -176,6 +176,7 @@ share_limits:
# Will default to -1 (no limit) if not specified for the group. # Will default to -1 (no limit) if not specified for the group.
max_seeding_time: 129600 max_seeding_time: 129600
# <OPTIONAL> min_seeding_time <int>: Will prevent torrent deletion by cleanup variable if torrent has not yet minimum seeding time (minutes). # <OPTIONAL> min_seeding_time <int>: Will prevent torrent deletion by cleanup variable if torrent has not yet minimum seeding time (minutes).
# If the torrent has not yet reached this minimum seeding time, it will change the share limits back to no limits and resume the torrent to continue seeding.
# Will default to 0 if not specified for the group. # Will default to 0 if not specified for the group.
min_seeding_time: 43200 min_seeding_time: 43200
# <OPTIONAL> Limit Upload Speed <int>: Will limit the upload speed KiB/s (KiloBytes/second) (`-1` : No Limit) # <OPTIONAL> Limit Upload Speed <int>: Will limit the upload speed KiB/s (KiloBytes/second) (`-1` : No Limit)
@ -187,6 +188,10 @@ share_limits:
# <OPTIONAL> add_group_to_tag <bool>: This adds your grouping as a tag with a prefix defined in settings . Default is true # <OPTIONAL> add_group_to_tag <bool>: This adds your grouping as a tag with a prefix defined in settings . Default is true
# Example: A grouping defined as noHL will have a tag set to ~share_limit.noHL (if using the default prefix) # Example: A grouping defined as noHL will have a tag set to ~share_limit.noHL (if using the default prefix)
add_group_to_tag: true add_group_to_tag: true
# <OPTIONAL> min_num_seeds <int>: This will prevent torrent deletion by cleanup variable if the number of seeds is less than the value set here.
# If the torrent has less number of seeds than the min_num_seeds, the share limits will be changed back to no limits and resume the torrent to continue seeding.
# Will default to 0 if not specified for the group.
min_num_seeds: 0
cross-seed: cross-seed:
priority: 2 priority: 2
include_all_tags: include_all_tags:

View file

@ -432,6 +432,17 @@ class Config:
do_print=False, do_print=False,
save=False, save=False,
) )
self.share_limits[group]["min_num_seeds"] = self.util.check_for_attribute(
self.data,
"min_num_seeds",
parent="share_limits",
subparent=group,
var_type="int",
min_int=0,
default=0,
do_print=False,
save=False,
)
self.share_limits[group]["resume_torrent_after_change"] = self.util.check_for_attribute( self.share_limits[group]["resume_torrent_after_change"] = self.util.check_for_attribute(
self.data, self.data,
"resume_torrent_after_change", "resume_torrent_after_change",

View file

@ -7,6 +7,9 @@ from modules.webhooks import GROUP_NOTIFICATION_LIMIT
logger = util.logger logger = util.logger
MIN_SEEDING_TIME_TAG = "MinSeedTimeNotReached"
MIN_NUM_SEEDS_TAG = "MinSeedsNotMet"
class ShareLimits: class ShareLimits:
def __init__(self, qbit_manager): def __init__(self, qbit_manager):
@ -204,7 +207,9 @@ class ShareLimits:
if ( if (
check_max_ratio or check_max_seeding_time or check_limit_upload_speed or share_limits_not_yet_tagged check_max_ratio or check_max_seeding_time or check_limit_upload_speed or share_limits_not_yet_tagged
) and hash_not_prev_checked: ) and hash_not_prev_checked:
if not is_tag_in_torrent("MinSeedTimeNotReached", torrent.tags): if not is_tag_in_torrent(MIN_SEEDING_TIME_TAG, torrent.tags) or not is_tag_in_torrent(
MIN_NUM_SEEDS_TAG, torrent.tags
):
logger.print_line(logger.insert_space(f"Torrent Name: {t_name}", 3), self.config.loglevel) 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) logger.print_line(logger.insert_space(f'Tracker: {tracker["url"]}', 8), self.config.loglevel)
if self.group_tag: if self.group_tag:
@ -220,6 +225,7 @@ class ShareLimits:
max_ratio=group_config["max_ratio"], max_ratio=group_config["max_ratio"],
max_seeding_time=group_config["max_seeding_time"], max_seeding_time=group_config["max_seeding_time"],
min_seeding_time=group_config["min_seeding_time"], min_seeding_time=group_config["min_seeding_time"],
min_num_seeds=group_config["min_num_seeds"],
resume_torrent=group_config["resume_torrent_after_change"], resume_torrent=group_config["resume_torrent_after_change"],
tracker=tracker["url"], tracker=tracker["url"],
) )
@ -359,24 +365,28 @@ class ShareLimits:
max_ratio = torrent.max_ratio max_ratio = torrent.max_ratio
if max_seeding_time is None: if max_seeding_time is None:
max_seeding_time = torrent.max_seeding_time max_seeding_time = torrent.max_seeding_time
if is_tag_in_torrent("MinSeedTimeNotReached", torrent.tags): if is_tag_in_torrent(MIN_SEEDING_TIME_TAG, torrent.tags):
return []
if is_tag_in_torrent(MIN_NUM_SEEDS_TAG, torrent.tags):
return [] return []
torrent.set_share_limits(max_ratio, max_seeding_time) torrent.set_share_limits(max_ratio, max_seeding_time)
return body return body
def has_reached_seed_limit(self, torrent, max_ratio, max_seeding_time, min_seeding_time, resume_torrent, tracker): def has_reached_seed_limit(
self, torrent, max_ratio, max_seeding_time, min_seeding_time, min_num_seeds, resume_torrent, tracker
):
"""Check if torrent has reached seed limit""" """Check if torrent has reached seed limit"""
body = "" body = ""
def _has_reached_min_seeding_time_limit(): def _has_reached_min_seeding_time_limit():
print_log = [] print_log = []
if torrent.seeding_time >= min_seeding_time * 60: if torrent.seeding_time >= min_seeding_time * 60:
if is_tag_in_torrent("MinSeedTimeNotReached", torrent.tags): if is_tag_in_torrent(MIN_SEEDING_TIME_TAG, torrent.tags):
if not self.config.dry_run: if not self.config.dry_run:
torrent.remove_tags(tags="MinSeedTimeNotReached") torrent.remove_tags(tags=MIN_SEEDING_TIME_TAG)
return True return True
else: else:
if not is_tag_in_torrent("MinSeedTimeNotReached", torrent.tags): if not is_tag_in_torrent(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"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"Tracker: {tracker}", 8), self.config.loglevel)
print_log += logger.print_line( print_log += logger.print_line(
@ -391,15 +401,47 @@ class ShareLimits:
self.config.loglevel, self.config.loglevel,
) )
print_log += logger.print_line( print_log += logger.print_line(
logger.insert_space("Adding Tag: MinSeedTimeNotReached", 8), self.config.loglevel logger.insert_space(f"Adding Tag: {MIN_SEEDING_TIME_TAG}", 8), self.config.loglevel
) )
if not self.config.dry_run: if not self.config.dry_run:
torrent.add_tags("MinSeedTimeNotReached") torrent.add_tags(MIN_SEEDING_TIME_TAG)
torrent.set_share_limits(-1, -1) torrent.set_share_limits(-1, -1)
if resume_torrent: if resume_torrent:
torrent.resume() torrent.resume()
return False return False
def _is_less_than_min_num_seeds():
print_log = []
if min_num_seeds == 0 or torrent.num_complete >= min_num_seeds:
if is_tag_in_torrent(MIN_NUM_SEEDS_TAG, torrent.tags):
if not self.config.dry_run:
torrent.remove_tags(tags=MIN_NUM_SEEDS_TAG)
return False
else:
if not is_tag_in_torrent(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(
(
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,
)
print_log += logger.print_line(
logger.insert_space(f"Adding Tag: {MIN_NUM_SEEDS_TAG}", 8), self.config.loglevel
)
if not self.config.dry_run:
torrent.add_tags(MIN_NUM_SEEDS_TAG)
torrent.set_share_limits(-1, -1)
if resume_torrent:
torrent.resume()
return True
def _has_reached_seeding_time_limit(): def _has_reached_seeding_time_limit():
nonlocal body nonlocal body
seeding_time_limit = None seeding_time_limit = None
@ -423,6 +465,9 @@ class ShareLimits:
return True return True
return False return False
if min_num_seeds is not None:
if _is_less_than_min_num_seeds():
return body
if max_ratio is not None: if max_ratio is not None:
if max_ratio >= 0: if max_ratio >= 0:
if torrent.ratio >= max_ratio and _has_reached_min_seeding_time_limit(): if torrent.ratio >= max_ratio and _has_reached_min_seeding_time_limit():

View file

@ -34,14 +34,14 @@ def get_list(data, lower=False, split=True, int_list=False):
return [d.strip() for d in str(data).split(",")] return [d.strip() for d in str(data).split(",")]
def is_tag_in_torrent(tag, torrent_tags, exact=True): def is_tag_in_torrent(check_tag, torrent_tags, exact=True):
"""Check if tag is in torrent_tags""" """Check if tag is in torrent_tags"""
tags = get_list(torrent_tags) tags = get_list(torrent_tags)
if exact: if exact:
return tag in tags return check_tag in tags
else: else:
for t in tags: for t in tags:
if tag in t: if check_tag in t:
return t return t
return False return False