diff --git a/VERSION b/VERSION index ffd6923..4250999 100755 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.0.9-develop12 +4.0.9-develop13 diff --git a/config/config.yml.sample b/config/config.yml.sample index a433020..5f8b7e2 100755 --- a/config/config.yml.sample +++ b/config/config.yml.sample @@ -29,10 +29,16 @@ settings: 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_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 + share_limits_min_seeding_time_tag: MinSeedTimeNotReached # Tag to be added to torrents that have not yet reached the minimum seeding time + share_limits_min_num_seeds_tag: MinSeedsNotMet # Tag to be added to torrents that have not yet reached the minimum number of seeds + share_limits_last_active_tag: LastActiveLimitNotReached # Tag to be added to torrents that have not yet reached the last active limit 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 - cross-seed + - MinSeedTimeNotReached + - MinSeedsNotMet + - LastActiveLimitNotReached cross_seed_tag: cross-seed # Will set the tag of any torrents that are added by cross-seed command cat_filter_completed: True # Filters for completed torrents only when running cat_update command share_limits_filter_completed: True # Filters for completed torrents only when running share_limits command diff --git a/modules/config.py b/modules/config.py index 23bd265..a45fc13 100755 --- a/modules/config.py +++ b/modules/config.py @@ -168,6 +168,15 @@ class Config: "share_limits_tag": self.util.check_for_attribute( self.data, "share_limits_tag", parent="settings", default=share_limits_tag ), + "share_limits_min_seeding_time_tag": self.util.check_for_attribute( + self.data, "share_limits_min_seeding_time_tag", parent="settings", default="MinSeedTimeNotReached" + ), + "share_limits_min_num_seeds_tag": self.util.check_for_attribute( + self.data, "share_limits_min_num_seeds_tag", parent="settings", default="MinSeedsNotMet" + ), + "share_limits_last_active_tag": self.util.check_for_attribute( + self.data, "share_limits_last_active_tag", parent="settings", default="LastActiveLimitNotReached" + ), "cross_seed_tag": self.util.check_for_attribute(self.data, "cross_seed_tag", parent="settings", default="cross-seed"), "cat_filter_completed": self.util.check_for_attribute( self.data, "cat_filter_completed", parent="settings", var_type="bool", default=True @@ -183,13 +192,23 @@ class Config: self.tracker_error_tag = self.settings["tracker_error_tag"] self.nohardlinks_tag = self.settings["nohardlinks_tag"] self.share_limits_tag = self.settings["share_limits_tag"] + self.share_limits_min_seeding_time_tag = self.settings["share_limits_min_seeding_time_tag"] + self.share_limits_min_num_seeds_tag = self.settings["share_limits_min_num_seeds_tag"] + self.share_limits_last_active_tag = self.settings["share_limits_last_active_tag"] self.cross_seed_tag = self.settings["cross_seed_tag"] - default_ignore_tags = [self.nohardlinks_tag, self.tracker_error_tag, "cross-seed"] + self.default_ignore_tags = [ + self.nohardlinks_tag, + self.tracker_error_tag, + self.cross_seed_tag, + self.share_limits_min_seeding_time_tag, + self.share_limits_min_num_seeds_tag, + self.share_limits_last_active_tag, + ] self.settings["ignoreTags_OnUpdate"] = self.util.check_for_attribute( - self.data, "ignoreTags_OnUpdate", parent="settings", default=default_ignore_tags, var_type="list" + self.data, "ignoreTags_OnUpdate", parent="settings", default=self.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'" + # "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") diff --git a/modules/core/share_limits.py b/modules/core/share_limits.py index 5ede08f..5a71d9a 100644 --- a/modules/core/share_limits.py +++ b/modules/core/share_limits.py @@ -8,10 +8,6 @@ from modules.webhooks import GROUP_NOTIFICATION_LIMIT logger = util.logger -MIN_SEEDING_TIME_TAG = "MinSeedTimeNotReached" -MIN_NUM_SEEDS_TAG = "MinSeedsNotMet" -LAST_ACTIVE_TAG = "LastActiveLimitNotReached" - class ShareLimits: def __init__(self, qbit_manager): @@ -32,6 +28,9 @@ class ShareLimits: 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_tag = qbit_manager.config.share_limits_tag # tag for share limits + self.min_seeding_time_tag = qbit_manager.config.share_limits_min_seeding_time_tag # tag for min seeding time + self.min_num_seeds_tag = qbit_manager.config.share_limits_min_num_seeds_tag # tag for min num seeds + self.last_active_tag = qbit_manager.config.share_limits_last_active_tag # tag for last active self.group_tag = None # tag for the share limit group self.update_share_limits() @@ -212,9 +211,9 @@ class ShareLimits: 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 ( - not is_tag_in_torrent(MIN_SEEDING_TIME_TAG, torrent.tags) - and not is_tag_in_torrent(MIN_NUM_SEEDS_TAG, torrent.tags) - and not is_tag_in_torrent(LAST_ACTIVE_TAG, torrent.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) ): 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) @@ -372,11 +371,11 @@ class ShareLimits: max_ratio = torrent.max_ratio if max_seeding_time is None: max_seeding_time = torrent.max_seeding_time - if is_tag_in_torrent(MIN_SEEDING_TIME_TAG, torrent.tags): + if is_tag_in_torrent(self.min_seeding_time_tag, torrent.tags): return [] - if is_tag_in_torrent(MIN_NUM_SEEDS_TAG, torrent.tags): + if is_tag_in_torrent(self.min_num_seeds_tag, torrent.tags): return [] - if is_tag_in_torrent(LAST_ACTIVE_TAG, torrent.tags): + if is_tag_in_torrent(self.last_active_tag, torrent.tags): return [] torrent.set_share_limits(ratio_limit=max_ratio, seeding_time_limit=max_seeding_time, inactive_seeding_time_limit=-2) return body @@ -390,12 +389,12 @@ class ShareLimits: def _has_reached_min_seeding_time_limit(): print_log = [] if torrent.seeding_time >= min_seeding_time * 60: - if is_tag_in_torrent(MIN_SEEDING_TIME_TAG, torrent.tags): + if is_tag_in_torrent(self.min_seeding_time_tag, torrent.tags): if not self.config.dry_run: - torrent.remove_tags(tags=MIN_SEEDING_TIME_TAG) + torrent.remove_tags(tags=self.min_seeding_time_tag) return True else: - if not is_tag_in_torrent(MIN_SEEDING_TIME_TAG, torrent.tags): + 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( @@ -408,10 +407,10 @@ class ShareLimits: self.config.loglevel, ) print_log += logger.print_line( - logger.insert_space(f"Adding Tag: {MIN_SEEDING_TIME_TAG}", 8), self.config.loglevel + logger.insert_space(f"Adding Tag: {self.min_seeding_time_tag}", 8), self.config.loglevel ) if not self.config.dry_run: - torrent.add_tags(MIN_SEEDING_TIME_TAG) + torrent.add_tags(self.min_seeding_time_tag) torrent.set_share_limits(ratio_limit=-1, seeding_time_limit=-1, inactive_seeding_time_limit=-1) if resume_torrent: torrent.resume() @@ -420,12 +419,12 @@ class ShareLimits: 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 is_tag_in_torrent(self.min_num_seeds_tag, torrent.tags): if not self.config.dry_run: - torrent.remove_tags(tags=MIN_NUM_SEEDS_TAG) + torrent.remove_tags(tags=self.min_num_seeds_tag) return False else: - if not is_tag_in_torrent(MIN_NUM_SEEDS_TAG, torrent.tags): + 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( @@ -438,10 +437,10 @@ class ShareLimits: self.config.loglevel, ) print_log += logger.print_line( - logger.insert_space(f"Adding Tag: {MIN_NUM_SEEDS_TAG}", 8), self.config.loglevel + logger.insert_space(f"Adding Tag: {self.min_num_seeds_tag}", 8), self.config.loglevel ) if not self.config.dry_run: - torrent.add_tags(MIN_NUM_SEEDS_TAG) + torrent.add_tags(self.min_num_seeds_tag) torrent.set_share_limits(ratio_limit=-1, seeding_time_limit=-1, inactive_seeding_time_limit=-1) if resume_torrent: torrent.resume() @@ -452,12 +451,12 @@ class ShareLimits: now = int(time()) inactive_time_minutes = round((now - torrent.last_activity) / 60) if inactive_time_minutes >= last_active: - if is_tag_in_torrent(LAST_ACTIVE_TAG, torrent.tags): + if is_tag_in_torrent(self.last_active_tag, torrent.tags): if not self.config.dry_run: - torrent.remove_tags(tags=LAST_ACTIVE_TAG) + torrent.remove_tags(tags=self.last_active_tag) return True else: - if not is_tag_in_torrent(LAST_ACTIVE_TAG, torrent.tags): + 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( @@ -469,9 +468,11 @@ class ShareLimits: ), self.config.loglevel, ) - print_log += logger.print_line(logger.insert_space(f"Adding Tag: {LAST_ACTIVE_TAG}", 8), self.config.loglevel) + 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(LAST_ACTIVE_TAG) + torrent.add_tags(self.last_active_tag) torrent.set_share_limits(ratio_limit=-1, seeding_time_limit=-1, inactive_seeding_time_limit=-1) if resume_torrent: torrent.resume() diff --git a/modules/core/tags.py b/modules/core/tags.py index 7eaf243..8d72c58 100644 --- a/modules/core/tags.py +++ b/modules/core/tags.py @@ -10,6 +10,7 @@ class Tags: self.client = qbit_manager.client self.stats = 0 self.share_limits_tag = qbit_manager.config.share_limits_tag # suffix tag for share limits + self.default_ignore_tags = qbit_manager.config.default_ignore_tags # default ignore tags self.torrents_updated = [] # List of torrents updated self.notify_attr = [] # List of single torrent attributes to send to notifiarr @@ -19,6 +20,7 @@ class Tags: def tags(self): """Update tags for torrents""" ignore_tags = self.config.settings["ignoreTags_OnUpdate"] + ignore_tags.extend(tag for tag in self.default_ignore_tags if tag not in ignore_tags) 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_tag not in tag]