mirror of
https://github.com/StuffAnThings/qbit_manage.git
synced 2025-10-10 22:06:58 +08:00
black formatting + precommit updates
This commit is contained in:
parent
d0421f2b7d
commit
2f779e1960
13 changed files with 117 additions and 57 deletions
|
@ -45,7 +45,7 @@ repos:
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
language_version: python3
|
language_version: python3
|
||||||
args: [--line-length, '130']
|
args: [--line-length, '130', --preview]
|
||||||
- repo: https://github.com/PyCQA/flake8
|
- repo: https://github.com/PyCQA/flake8
|
||||||
rev: 6.0.0
|
rev: 6.0.0
|
||||||
hooks:
|
hooks:
|
||||||
|
|
10
Makefile
10
Makefile
|
@ -6,7 +6,11 @@ venv: requirements.txt setup.py tox.ini
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
tox
|
tox -e tests
|
||||||
|
|
||||||
|
.PHONY: pre-commit
|
||||||
|
pre-commit:
|
||||||
|
tox -e pre-commit
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
@ -14,3 +18,7 @@ clean:
|
||||||
find -name '__pycache__' -delete
|
find -name '__pycache__' -delete
|
||||||
rm -rf .tox
|
rm -rf .tox
|
||||||
rm -rf venv
|
rm -rf venv
|
||||||
|
|
||||||
|
.PHONY: install-hooks
|
||||||
|
install-hooks:
|
||||||
|
tox -e install-hooks
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
4.0.1-develop2
|
4.0.1-develop3
|
||||||
|
|
|
@ -308,7 +308,7 @@ class Config:
|
||||||
else:
|
else:
|
||||||
priority = max(priorities) + 1
|
priority = max(priorities) + 1
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Priority not defined for the grouping '{key}' in share_limits. " f"Setting priority to {priority}"
|
f"Priority not defined for the grouping '{key}' in share_limits. Setting priority to {priority}"
|
||||||
)
|
)
|
||||||
value["priority"] = self.util.check_for_attribute(
|
value["priority"] = self.util.check_for_attribute(
|
||||||
self.data,
|
self.data,
|
||||||
|
@ -543,14 +543,18 @@ class Config:
|
||||||
)
|
)
|
||||||
if self.commands["rem_orphaned"]:
|
if self.commands["rem_orphaned"]:
|
||||||
exclude_orphaned = f"**{os.sep}{os.path.basename(self.orphaned_dir.rstrip(os.sep))}{os.sep}*"
|
exclude_orphaned = f"**{os.sep}{os.path.basename(self.orphaned_dir.rstrip(os.sep))}{os.sep}*"
|
||||||
self.orphaned["exclude_patterns"].append(exclude_orphaned) if exclude_orphaned not in self.orphaned[
|
(
|
||||||
"exclude_patterns"
|
self.orphaned["exclude_patterns"].append(exclude_orphaned)
|
||||||
] else self.orphaned["exclude_patterns"]
|
if exclude_orphaned not in self.orphaned["exclude_patterns"]
|
||||||
|
else self.orphaned["exclude_patterns"]
|
||||||
|
)
|
||||||
if self.recyclebin["enabled"]:
|
if self.recyclebin["enabled"]:
|
||||||
exclude_recycle = f"**{os.sep}{os.path.basename(self.recycle_dir.rstrip(os.sep))}{os.sep}*"
|
exclude_recycle = f"**{os.sep}{os.path.basename(self.recycle_dir.rstrip(os.sep))}{os.sep}*"
|
||||||
self.orphaned["exclude_patterns"].append(exclude_recycle) if exclude_recycle not in self.orphaned[
|
(
|
||||||
"exclude_patterns"
|
self.orphaned["exclude_patterns"].append(exclude_recycle)
|
||||||
] else self.orphaned["exclude_patterns"]
|
if exclude_recycle not in self.orphaned["exclude_patterns"]
|
||||||
|
else self.orphaned["exclude_patterns"]
|
||||||
|
)
|
||||||
|
|
||||||
# Connect to Qbittorrent
|
# Connect to Qbittorrent
|
||||||
self.qbt = None
|
self.qbt = None
|
||||||
|
@ -640,8 +644,10 @@ class Config:
|
||||||
if empty_after_x_days <= days:
|
if empty_after_x_days <= days:
|
||||||
num_del += 1
|
num_del += 1
|
||||||
body += logger.print_line(
|
body += logger.print_line(
|
||||||
f"{'Did not delete' if self.dry_run else 'Deleted'} "
|
(
|
||||||
f"{filename} from {folder} (Last modified {round(days)} days ago).",
|
f"{'Did not delete' if self.dry_run else 'Deleted'} "
|
||||||
|
f"{filename} from {folder} (Last modified {round(days)} days ago)."
|
||||||
|
),
|
||||||
self.loglevel,
|
self.loglevel,
|
||||||
)
|
)
|
||||||
files += [str(filename)]
|
files += [str(filename)]
|
||||||
|
@ -654,8 +660,10 @@ class Config:
|
||||||
for path in location_path_list:
|
for path in location_path_list:
|
||||||
util.remove_empty_directories(path, "**/*")
|
util.remove_empty_directories(path, "**/*")
|
||||||
body += logger.print_line(
|
body += logger.print_line(
|
||||||
f"{'Did not delete' if self.dry_run else 'Deleted'} {num_del} files "
|
(
|
||||||
f"({util.human_readable_size(size_bytes)}) from the {location}.",
|
f"{'Did not delete' if self.dry_run else 'Deleted'} {num_del} files "
|
||||||
|
f"({util.human_readable_size(size_bytes)}) from the {location}."
|
||||||
|
),
|
||||||
self.loglevel,
|
self.loglevel,
|
||||||
)
|
)
|
||||||
attr = {
|
attr = {
|
||||||
|
|
|
@ -64,8 +64,10 @@ class ReCheck:
|
||||||
)
|
)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
logger.insert_space(
|
logger.insert_space(
|
||||||
f"-- Seeding Time vs Max Seed Time: {timedelta(seconds=torrent.seeding_time)} < "
|
(
|
||||||
f"{timedelta(minutes=torrent.max_seeding_time)}",
|
f"-- Seeding Time vs Max Seed Time: {timedelta(seconds=torrent.seeding_time)} < "
|
||||||
|
f"{timedelta(minutes=torrent.max_seeding_time)}"
|
||||||
|
),
|
||||||
4,
|
4,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -85,7 +87,7 @@ class ReCheck:
|
||||||
):
|
):
|
||||||
self.stats_resumed += 1
|
self.stats_resumed += 1
|
||||||
body = logger.print_line(
|
body = logger.print_line(
|
||||||
f"{'Not Resuming' if self.config.dry_run else 'Resuming'} [{tracker['tag']}] - " f"{t_name}",
|
f"{'Not Resuming' if self.config.dry_run else 'Resuming'} [{tracker['tag']}] - {t_name}",
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
attr = {
|
attr = {
|
||||||
|
|
|
@ -67,8 +67,10 @@ class RemoveOrphaned:
|
||||||
logger.print_line(f"{num_orphaned} Orphaned files found", self.config.loglevel)
|
logger.print_line(f"{num_orphaned} Orphaned files found", self.config.loglevel)
|
||||||
body += logger.print_line("\n".join(orphaned_files), self.config.loglevel)
|
body += logger.print_line("\n".join(orphaned_files), self.config.loglevel)
|
||||||
body += logger.print_line(
|
body += logger.print_line(
|
||||||
f"{'Not moving' if self.config.dry_run else 'Moving'} {num_orphaned} Orphaned files "
|
(
|
||||||
f"to {self.orphaned_dir.replace(self.remote_dir,self.root_dir)}",
|
f"{'Not moving' if self.config.dry_run else 'Moving'} {num_orphaned} Orphaned files "
|
||||||
|
f"to {self.orphaned_dir.replace(self.remote_dir,self.root_dir)}"
|
||||||
|
),
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -145,22 +145,28 @@ class RemoveUnregistered:
|
||||||
if self.stats_deleted >= 1 or self.stats_deleted_contents >= 1:
|
if self.stats_deleted >= 1 or self.stats_deleted_contents >= 1:
|
||||||
if self.stats_deleted >= 1:
|
if self.stats_deleted >= 1:
|
||||||
logger.print_line(
|
logger.print_line(
|
||||||
f"{'Did not delete' if self.config.dry_run else 'Deleted'} {self.stats_deleted} "
|
(
|
||||||
f".torrent{'s' if self.stats_deleted > 1 else ''} but not content files.",
|
f"{'Did not delete' if self.config.dry_run else 'Deleted'} {self.stats_deleted} "
|
||||||
|
f".torrent{'s' if self.stats_deleted > 1 else ''} but not content files."
|
||||||
|
),
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
if self.stats_deleted_contents >= 1:
|
if self.stats_deleted_contents >= 1:
|
||||||
logger.print_line(
|
logger.print_line(
|
||||||
f"{'Did not delete' if self.config.dry_run else 'Deleted'} {self.stats_deleted_contents} "
|
(
|
||||||
f".torrent{'s' if self.stats_deleted_contents > 1 else ''} AND content files.",
|
f"{'Did not delete' if self.config.dry_run else 'Deleted'} {self.stats_deleted_contents} "
|
||||||
|
f".torrent{'s' if self.stats_deleted_contents > 1 else ''} AND content files."
|
||||||
|
),
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logger.print_line("No unregistered torrents found.", self.config.loglevel)
|
logger.print_line("No unregistered torrents found.", self.config.loglevel)
|
||||||
if self.stats_untagged >= 1:
|
if self.stats_untagged >= 1:
|
||||||
logger.print_line(
|
logger.print_line(
|
||||||
f"{'Did not delete' if self.config.dry_run else 'Deleted'} {self.tag_error} tags for {self.stats_untagged} "
|
(
|
||||||
f".torrent{'s.' if self.stats_untagged > 1 else '.'}",
|
f"{'Did not delete' if self.config.dry_run else 'Deleted'} {self.tag_error} tags for {self.stats_untagged} "
|
||||||
|
f".torrent{'s.' if self.stats_untagged > 1 else '.'}"
|
||||||
|
),
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
if self.stats_tagged >= 1:
|
if self.stats_tagged >= 1:
|
||||||
|
|
|
@ -62,7 +62,7 @@ class TagNoHardLinks:
|
||||||
self.stats_untagged += 1
|
self.stats_untagged += 1
|
||||||
body = []
|
body = []
|
||||||
body += logger.print_line(
|
body += logger.print_line(
|
||||||
f"Previous Tagged {self.nohardlinks_tag} " f"Torrent Name: {torrent.name} has hardlinks found now.",
|
f"Previous Tagged {self.nohardlinks_tag} Torrent Name: {torrent.name} has hardlinks found now.",
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
body += logger.print_line(logger.insert_space(f"Removed Tag: {self.nohardlinks_tag}", 6), self.config.loglevel)
|
body += logger.print_line(logger.insert_space(f"Removed Tag: {self.nohardlinks_tag}", 6), self.config.loglevel)
|
||||||
|
@ -121,16 +121,20 @@ class TagNoHardLinks:
|
||||||
self.check_previous_nohardlinks_tagged_torrents(has_nohardlinks, torrent, tracker, category)
|
self.check_previous_nohardlinks_tagged_torrents(has_nohardlinks, torrent, tracker, category)
|
||||||
if self.stats_tagged >= 1:
|
if self.stats_tagged >= 1:
|
||||||
logger.print_line(
|
logger.print_line(
|
||||||
f"{'Did not Tag' if self.config.dry_run else 'Added Tag'} for {self.stats_tagged} "
|
(
|
||||||
f".torrent{'s.' if self.stats_tagged > 1 else '.'}",
|
f"{'Did not Tag' if self.config.dry_run else 'Added Tag'} for {self.stats_tagged} "
|
||||||
|
f".torrent{'s.' if self.stats_tagged > 1 else '.'}"
|
||||||
|
),
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logger.print_line("No torrents to tag with no hardlinks.", self.config.loglevel)
|
logger.print_line("No torrents to tag with no hardlinks.", self.config.loglevel)
|
||||||
if self.stats_untagged >= 1:
|
if self.stats_untagged >= 1:
|
||||||
logger.print_line(
|
logger.print_line(
|
||||||
f"{'Did not delete' if self.config.dry_run else 'Deleted'} "
|
(
|
||||||
f"{self.nohardlinks_tag} tags for {self.stats_untagged} "
|
f"{'Did not delete' if self.config.dry_run else 'Deleted'} "
|
||||||
f".torrent{'s.' if self.stats_untagged > 1 else '.'}",
|
f"{self.nohardlinks_tag} tags for {self.stats_untagged} "
|
||||||
|
f".torrent{'s.' if self.stats_untagged > 1 else '.'}"
|
||||||
|
),
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
|
|
|
@ -171,8 +171,10 @@ class Webhooks:
|
||||||
def notify(self, torrents_updated=[], payload={}, group_by=""):
|
def notify(self, torrents_updated=[], payload={}, group_by=""):
|
||||||
if len(torrents_updated) > GROUP_NOTIFICATION_LIMIT:
|
if len(torrents_updated) > GROUP_NOTIFICATION_LIMIT:
|
||||||
logger.trace(
|
logger.trace(
|
||||||
f"Number of torrents updated > {GROUP_NOTIFICATION_LIMIT}, grouping notifications"
|
(
|
||||||
f"{f' by {group_by}' if group_by else ''}",
|
f"Number of torrents updated > {GROUP_NOTIFICATION_LIMIT}, grouping notifications"
|
||||||
|
f"{f' by {group_by}' if group_by else ''}"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
if group_by == "category":
|
if group_by == "category":
|
||||||
group_attr = group_notifications_by_key(payload, "torrent_category")
|
group_attr = group_notifications_by_key(payload, "torrent_category")
|
||||||
|
@ -189,10 +191,14 @@ class Webhooks:
|
||||||
attr = {
|
attr = {
|
||||||
"function": group_attr[group]["function"],
|
"function": group_attr[group]["function"],
|
||||||
"title": f"{group_attr[group]['title']} for {group}",
|
"title": f"{group_attr[group]['title']} for {group}",
|
||||||
"body": group_attr[group]["body"]
|
"body": (
|
||||||
if only_one_torrent_updated
|
group_attr[group]["body"]
|
||||||
else f"Updated {num_torrents_updated} "
|
if only_one_torrent_updated
|
||||||
f"{'torrent' if only_one_torrent_updated else 'torrents'} with {group_by} '{group}'",
|
else (
|
||||||
|
f"Updated {num_torrents_updated} "
|
||||||
|
f"{'torrent' if only_one_torrent_updated else 'torrents'} with {group_by} '{group}'"
|
||||||
|
)
|
||||||
|
),
|
||||||
"torrents": group_attr[group]["torrents"],
|
"torrents": group_attr[group]["torrents"],
|
||||||
}
|
}
|
||||||
if group_by == "category":
|
if group_by == "category":
|
||||||
|
|
|
@ -61,8 +61,10 @@ parser.add_argument(
|
||||||
action="store",
|
action="store",
|
||||||
default="config.yml",
|
default="config.yml",
|
||||||
type=str,
|
type=str,
|
||||||
help="This is used if you want to use a different name for your config.yml or if you want to load multiple"
|
help=(
|
||||||
"config files using *. Example: tv.yml or config*.yml",
|
"This is used if you want to use a different name for your config.yml or if you want to load multiple"
|
||||||
|
"config files using *. Example: tv.yml or config*.yml"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-lf",
|
"-lf",
|
||||||
|
@ -103,8 +105,10 @@ parser.add_argument(
|
||||||
dest="tag_update",
|
dest="tag_update",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=False,
|
||||||
help="Use this if you would like to update your tags and/or set seed goals/limit upload speed by tag."
|
help=(
|
||||||
" (Only adds tags to untagged torrents)",
|
"Use this if you would like to update your tags and/or set seed goals/limit upload speed by tag."
|
||||||
|
" (Only adds tags to untagged torrents)"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-ru",
|
"-ru",
|
||||||
|
@ -136,10 +140,12 @@ parser.add_argument(
|
||||||
dest="tag_nohardlinks",
|
dest="tag_nohardlinks",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=False,
|
||||||
help="Use this to tag any torrents that do not have any hard links associated with any of the files. "
|
help=(
|
||||||
"This is useful for those that use Sonarr/Radarr which hard link your media files with the torrents for seeding. "
|
"Use this to tag any torrents that do not have any hard links associated with any of the files. "
|
||||||
"When files get upgraded they no longer become linked with your media therefore will be tagged with a new tag noHL. "
|
"This is useful for those that use Sonarr/Radarr which hard link your media files with the torrents for seeding. "
|
||||||
"You can then safely delete/remove these torrents to free up any extra space that is not being used by your media folder.",
|
"When files get upgraded they no longer become linked with your media therefore will be tagged with a new tag noHL. "
|
||||||
|
"You can then safely delete/remove these torrents to free up any extra space that is not being used by your media folder."
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-sl",
|
"-sl",
|
||||||
|
@ -147,9 +153,11 @@ parser.add_argument(
|
||||||
dest="share_limits",
|
dest="share_limits",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
default=False,
|
||||||
help="Use this to help apply and manage your torrent share limits based on your tags/categories."
|
help=(
|
||||||
"This can apply a max ratio, seed time limits to your torrents or limit your torrent upload speed as well."
|
"Use this to help apply and manage your torrent share limits based on your tags/categories."
|
||||||
"Share limits are applied in the order of priority specified.",
|
"This can apply a max ratio, seed time limits to your torrents or limit your torrent upload speed as well."
|
||||||
|
"Share limits are applied in the order of priority specified."
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-sc",
|
"-sc",
|
||||||
|
@ -422,7 +430,9 @@ def start():
|
||||||
next_run = nxt_run["next_run"]
|
next_run = nxt_run["next_run"]
|
||||||
body = logger.separator(
|
body = logger.separator(
|
||||||
f"Finished Run\n{os.linesep.join(stats_summary) if len(stats_summary)>0 else ''}"
|
f"Finished Run\n{os.linesep.join(stats_summary) if len(stats_summary)>0 else ''}"
|
||||||
f"\nRun Time: {run_time}\n{next_run_str if len(next_run_str)>0 else ''}".replace("\n\n", "\n").rstrip()
|
f"\nRun Time: {run_time}\n{next_run_str if len(next_run_str)>0 else ''}".replace(
|
||||||
|
"\n\n", "\n"
|
||||||
|
).rstrip()
|
||||||
)[0]
|
)[0]
|
||||||
return next_run, body
|
return next_run, body
|
||||||
|
|
||||||
|
|
|
@ -184,8 +184,8 @@ def main():
|
||||||
print(
|
print(
|
||||||
f"--- Torrent ages are below threshold of '{MIN_TORRENT_AGE} days'\n"
|
f"--- Torrent ages are below threshold of '{MIN_TORRENT_AGE} days'\n"
|
||||||
f"--- Torrent seed ratios are below threshold of '{MIN_TORRENT_SHARE_RATIO}'\n"
|
f"--- Torrent seed ratios are below threshold of '{MIN_TORRENT_SHARE_RATIO}'\n"
|
||||||
f"--- Torrents have multiple hard links\n"
|
"--- Torrents have multiple hard links\n"
|
||||||
f"--- No torrents exists!"
|
"--- No torrents exists!"
|
||||||
)
|
)
|
||||||
|
|
||||||
quit_program(0)
|
quit_program(0)
|
||||||
|
|
6
setup.py
6
setup.py
|
@ -30,8 +30,10 @@ setup(
|
||||||
# repository. For example: MIT
|
# repository. For example: MIT
|
||||||
license="MIT",
|
license="MIT",
|
||||||
# Short description of your library
|
# Short description of your library
|
||||||
description="This tool will help manage tedious tasks in qBittorrent and automate them. "
|
description=(
|
||||||
"Tag, categorize, remove Orphaned data, remove unregistered torrents and much much more.",
|
"This tool will help manage tedious tasks in qBittorrent and automate them. "
|
||||||
|
"Tag, categorize, remove Orphaned data, remove unregistered torrents and much much more."
|
||||||
|
),
|
||||||
# Long description of your library
|
# Long description of your library
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
long_description_content_type="text/markdown",
|
long_description_content_type="text/markdown",
|
||||||
|
|
20
tox.ini
20
tox.ini
|
@ -5,16 +5,28 @@ tox_pip_extensions_ext_pip_custom_platform = true
|
||||||
tox_pip_extensions_ext_venv_update = true
|
tox_pip_extensions_ext_venv_update = true
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps = -r{toxinidir}/requirements.txt
|
deps =
|
||||||
|
-r{toxinidir}/requirements.txt
|
||||||
|
-r{toxinidir}/requirements-dev.txt
|
||||||
passenv = HOME SSH_AUTH_SOCK USER
|
passenv = HOME SSH_AUTH_SOCK USER
|
||||||
commands =
|
|
||||||
pre-commit install -f --install-hooks
|
|
||||||
pre-commit run --all-files --show-diff-on-failure
|
|
||||||
|
|
||||||
[testenv:venv]
|
[testenv:venv]
|
||||||
envdir = venv
|
envdir = venv
|
||||||
commands =
|
commands =
|
||||||
|
|
||||||
|
[testenv:install-hooks]
|
||||||
|
deps = pre-commit
|
||||||
|
commands = pre-commit install -f --install-hooks
|
||||||
|
|
||||||
|
[testenv:pre-commit]
|
||||||
|
deps = pre-commit
|
||||||
|
commands = pre-commit run --all-files
|
||||||
|
|
||||||
|
[testenv:tests]
|
||||||
|
commands =
|
||||||
|
pre-commit install -f --install-hooks
|
||||||
|
pre-commit run --all-files
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
max-line-length = 130
|
max-line-length = 130
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue