Adds running commands via config #149

This commit is contained in:
bobokun 2022-08-21 14:40:57 -04:00
parent c4681beb4e
commit 2e15e35ef5
No known key found for this signature in database
GPG key ID: 9665BA6CF5DC2671
4 changed files with 75 additions and 26 deletions

View file

@ -3,6 +3,19 @@
# Please refer to the link below for more details on how to set up the configuration file
# https://github.com/StuffAnThings/qbit_manage/wiki/Config-Setup
commands:
# The commands defined below will IGNORE any commands used in command line and docker env variables.
dry_run: True
cross_seed: False
recheck: False
cat_update: False
tag_update: False
rem_unregistered: False
tag_tracker_error: False
rem_orphaned: False
tag_nohardlinks: False
skip_recycle: False
qbt:
# qBittorrent parameters
host: "localhost:8080"

View file

@ -31,6 +31,42 @@ class Config:
loaded_yaml = YAML(self.config_path)
self.data = loaded_yaml.data
# Replace env variables with config commands
if "commands" in self.data:
if self.data["commands"] is not None:
logger.info(f"Commands found in {config_file}, ignoring env variables and using config commands instead.")
self.commands = self.data.pop("commands")
if 'dry_run' not in self.commands:
self.commands['dry_run'] = args['dry_run'] if 'dry_run' in args else False
# Add default any missing commands as False
for v in [
'cross_seed',
'recheck',
'cat_update',
'tag_update',
'rem_unregistered',
'tag_tracker_error',
'rem_orphaned',
'tag_nohardlinks',
'skip_recycle',
]:
if v not in self.commands:
self.commands[v] = False
logger.debug(f" --cross-seed (QBT_CROSS_SEED): {self.commands['cross_seed']}")
logger.debug(f" --recheck (QBT_RECHECK): {self.commands['recheck']}")
logger.debug(f" --cat-update (QBT_CAT_UPDATE): {self.commands['cat_update']}")
logger.debug(f" --tag-update (QBT_TAG_UPDATE): {self.commands['tag_update']}")
logger.debug(f" --rem-unregistered (QBT_REM_UNREGISTERED): {self.commands['rem_unregistered']}")
logger.debug(f" --tag-tracker-error (QBT_TAG_TRACKER_ERROR): {self.commands['tag_tracker_error']}")
logger.debug(f" --rem-orphaned (QBT_REM_ORPHANED): {self.commands['rem_orphaned']}")
logger.debug(f" --tag-nohardlinks (QBT_TAG_NOHARDLINKS): {self.commands['tag_nohardlinks']}")
logger.debug(f" --skip-recycle (QBT_SKIP_RECYCLE): {self.commands['skip_recycle']}")
logger.debug(f" --dry-run (QBT_DRY_RUN): {self.commands['dry_run']}")
else:
self.commands = args
if "qbt" in self.data: self.data["qbt"] = self.data.pop("qbt")
self.data["settings"] = self.data.pop("settings") if "settings" in self.data else {}
if "directory" in self.data: self.data["directory"] = self.data.pop("directory")
@ -149,7 +185,7 @@ class Config:
# nohardlinks
self.nohardlinks = None
if "nohardlinks" in self.data and self.args['tag_nohardlinks']:
if "nohardlinks" in self.data and self.commands['tag_nohardlinks']:
self.nohardlinks = {}
for cat in self.data["nohardlinks"]:
if cat in list(self.data["cat"].keys()):
@ -170,7 +206,7 @@ class Config:
self.notify(e, 'Config')
raise Failed(e)
else:
if self.args["tag_nohardlinks"]:
if self.commands["tag_nohardlinks"]:
e = "Config Error: nohardlinks attribute not found"
self.notify(e, 'Config')
raise Failed(e)
@ -186,12 +222,12 @@ class Config:
if "directory" in self.data:
self.root_dir = os.path.join(self.util.check_for_attribute(self.data, "root_dir", parent="directory", default_is_none=True), '')
self.remote_dir = os.path.join(self.util.check_for_attribute(self.data, "remote_dir", parent="directory", default=self.root_dir), '')
if (self.args["cross_seed"] or self.args["tag_nohardlinks"] or self.args["rem_orphaned"]):
if (self.commands["cross_seed"] or self.commands["tag_nohardlinks"] or self.commands["rem_orphaned"]):
self.remote_dir = self.util.check_for_attribute(self.data, "remote_dir", parent="directory", var_type="path", default=self.root_dir)
else:
if self.recyclebin['enabled']:
self.remote_dir = self.util.check_for_attribute(self.data, "remote_dir", parent="directory", var_type="path", default=self.root_dir)
if self.args["cross_seed"]:
if self.commands["cross_seed"]:
self.cross_seed_dir = self.util.check_for_attribute(self.data, "cross_seed", parent="directory", var_type="path")
else:
self.cross_seed_dir = self.util.check_for_attribute(self.data, "cross_seed", parent="directory", default_is_none=True)
@ -325,12 +361,12 @@ class Config:
# Empty the recycle bin
def empty_recycle(self):
dry_run = self.args['dry_run']
dry_run = self.commands['dry_run']
loglevel = 'DRYRUN' if dry_run else 'INFO'
num_del = 0
files = []
size_bytes = 0
if not self.args["skip_recycle"]:
if not self.commands["skip_recycle"]:
if self.recyclebin['enabled'] and self.recyclebin['empty_after_x_days']:
if self.recyclebin['split_by_category']:
if "cat" in self.data and self.data["cat"] is not None:

View file

@ -69,7 +69,7 @@ class Qbt:
# is_complete = Returns the state of torrent (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))
def get_torrent_info(torrent_list):
dry_run = self.config.args['dry_run']
dry_run = self.config.commands['dry_run']
loglevel = 'DRYRUN' if dry_run else 'INFO'
torrentdict = {}
t_obj_unreg = []
@ -152,7 +152,7 @@ class Qbt:
self.torrentinfo = None
self.torrentissue = None
self.torrentvalid = None
if config.args['recheck'] or config.args['cross_seed'] or config.args['rem_unregistered'] or config.args['tag_tracker_error'] or config.args['tag_nohardlinks']:
if config.commands['recheck'] or config.commands['cross_seed'] or config.commands['rem_unregistered'] or config.commands['tag_tracker_error'] or config.commands['tag_nohardlinks']:
# Get an updated torrent dictionary information of the torrents
self.torrentinfo, self.torrentissue, self.torrentvalid = get_torrent_info(self.torrent_list)
@ -160,7 +160,7 @@ class Qbt:
return self.client.torrents.info(**params)
def category(self):
dry_run = self.config.args['dry_run']
dry_run = self.config.commands['dry_run']
loglevel = 'DRYRUN' if dry_run else 'INFO'
num_cat = 0
@ -199,7 +199,7 @@ class Qbt:
self.config.send_notifications(attr)
num_cat += 1
if self.config.args['cat_update']:
if self.config.commands['cat_update']:
logger.separator("Updating Categories", space=False, border=False)
torrent_list = self.get_torrents({'category': '', 'filter': 'completed'})
for torrent in torrent_list:
@ -221,11 +221,11 @@ class Qbt:
return num_cat
def tags(self):
dry_run = self.config.args['dry_run']
dry_run = self.config.commands['dry_run']
loglevel = 'DRYRUN' if dry_run else 'INFO'
num_tags = 0
ignore_tags = self.config.settings['ignoreTags_OnUpdate']
if self.config.args['tag_update']:
if self.config.commands['tag_update']:
logger.separator("Updating Tags", space=False, border=False)
for torrent in self.torrent_list:
check_tags = util.get_list(torrent.tags)
@ -260,7 +260,7 @@ class Qbt:
return num_tags
def set_tags_and_limits(self, torrent, max_ratio, max_seeding_time, limit_upload_speed=None, tags=None, restore=False):
dry_run = self.config.args['dry_run']
dry_run = self.config.commands['dry_run']
loglevel = 'DRYRUN' if dry_run else 'INFO'
body = []
# Print Logs
@ -296,14 +296,14 @@ class Qbt:
return body
def tag_nohardlinks(self):
dry_run = self.config.args['dry_run']
dry_run = self.config.commands['dry_run']
loglevel = 'DRYRUN' if dry_run else 'INFO'
num_tags = 0 # counter for the number of torrents that has no hard links
del_tor = 0 # counter for the number of torrents that has no hard links and meets the criteria for ratio limit/seed limit for deletion
del_tor_cont = 0 # counter for the number of torrents that has no hard links and meets the criteria for ratio limit/seed limit for deletion including contents
num_untag = 0 # counter for number of torrents that previously had no hard links but now have hard links
if self.config.args['tag_nohardlinks']:
if self.config.commands['tag_nohardlinks']:
logger.separator("Tagging Torrents with No Hardlinks", space=False, border=False)
nohardlinks = self.config.nohardlinks
tdel_dict = {} # dictionary to track the torrent names and content path that meet the deletion criteria
@ -440,7 +440,7 @@ class Qbt:
return num_tags, num_untag, del_tor, del_tor_cont
def rem_unregistered(self):
dry_run = self.config.args['dry_run']
dry_run = self.config.commands['dry_run']
loglevel = 'DRYRUN' if dry_run else 'INFO'
del_tor = 0
del_tor_cont = 0
@ -448,8 +448,8 @@ class Qbt:
num_untag = 0
tor_error_summary = ''
tag_error = self.config.settings['tracker_error_tag']
cfg_rem_unregistered = self.config.args['rem_unregistered']
cfg_tag_error = self.config.args['tag_tracker_error']
cfg_rem_unregistered = self.config.commands['rem_unregistered']
cfg_tag_error = self.config.commands['tag_tracker_error']
def tag_tracker_error():
nonlocal dry_run, t_name, msg_up, msg, tracker, t_cat, torrent, tag_error, tor_error_summary, num_tor_error
@ -609,11 +609,11 @@ class Qbt:
# Function used to move any torrents from the cross seed directory to the correct save directory
def cross_seed(self):
dry_run = self.config.args['dry_run']
dry_run = self.config.commands['dry_run']
loglevel = 'DRYRUN' if dry_run else 'INFO'
added = 0 # Keep track of total torrents tagged
tagged = 0 # Track # of torrents tagged that are not cross-seeded
if self.config.args['cross_seed']:
if self.config.commands['cross_seed']:
logger.separator("Checking for Cross-Seed Torrents", space=False, border=False)
# List of categories for all torrents moved
categories = []
@ -697,11 +697,11 @@ class Qbt:
# Function used to recheck paused torrents sorted by size and resume torrents that are completed
def recheck(self):
dry_run = self.config.args['dry_run']
dry_run = self.config.commands['dry_run']
loglevel = 'DRYRUN' if dry_run else 'INFO'
resumed = 0
rechecked = 0
if self.config.args['recheck']:
if self.config.commands['recheck']:
logger.separator("Rechecking Paused Torrents", space=False, border=False)
# sort by size and paused
torrent_list = self.get_torrents({'status_filter': 'paused', 'sort': 'size'})
@ -764,10 +764,10 @@ class Qbt:
return resumed, rechecked
def rem_orphaned(self):
dry_run = self.config.args['dry_run']
dry_run = self.config.commands['dry_run']
loglevel = 'DRYRUN' if dry_run else 'INFO'
orphaned = 0
if self.config.args['rem_orphaned']:
if self.config.commands['rem_orphaned']:
logger.separator("Checking for Orphaned Files", space=False, border=False)
torrent_files = []
root_files = []

View file

@ -72,7 +72,7 @@ class Webhooks:
def start_time_hooks(self, start_time):
if self.run_start_webhooks:
dry_run = self.config.args['dry_run']
dry_run = self.config.commands['dry_run']
if dry_run:
start_type = "Dry-"
else:
@ -82,7 +82,7 @@ class Webhooks:
"title": None,
"body": f"Starting {start_type}Run",
"start_time": start_time.strftime("%Y-%m-%d %H:%M:%S"),
"dry_run": self.config.args['dry_run']
"dry_run": self.config.commands['dry_run']
})
def end_time_hooks(self, start_time, end_time, run_time, next_run, stats, body):