mirror of
https://github.com/StuffAnThings/qbit_manage.git
synced 2024-09-20 07:16:04 +08:00
black formatting + precommit updates
This commit is contained in:
parent
d0421f2b7d
commit
2f779e1960
|
@ -45,7 +45,7 @@ repos:
|
|||
hooks:
|
||||
- id: black
|
||||
language_version: python3
|
||||
args: [--line-length, '130']
|
||||
args: [--line-length, '130', --preview]
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 6.0.0
|
||||
hooks:
|
||||
|
|
10
Makefile
10
Makefile
|
@ -6,7 +6,11 @@ venv: requirements.txt setup.py tox.ini
|
|||
|
||||
.PHONY: test
|
||||
test:
|
||||
tox
|
||||
tox -e tests
|
||||
|
||||
.PHONY: pre-commit
|
||||
pre-commit:
|
||||
tox -e pre-commit
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
@ -14,3 +18,7 @@ clean:
|
|||
find -name '__pycache__' -delete
|
||||
rm -rf .tox
|
||||
rm -rf venv
|
||||
|
||||
.PHONY: install-hooks
|
||||
install-hooks:
|
||||
tox -e install-hooks
|
||||
|
|
|
@ -308,7 +308,7 @@ class Config:
|
|||
else:
|
||||
priority = max(priorities) + 1
|
||||
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(
|
||||
self.data,
|
||||
|
@ -543,14 +543,18 @@ class Config:
|
|||
)
|
||||
if self.commands["rem_orphaned"]:
|
||||
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"
|
||||
] else self.orphaned["exclude_patterns"]
|
||||
(
|
||||
self.orphaned["exclude_patterns"].append(exclude_orphaned)
|
||||
if exclude_orphaned not in self.orphaned["exclude_patterns"]
|
||||
else self.orphaned["exclude_patterns"]
|
||||
)
|
||||
if self.recyclebin["enabled"]:
|
||||
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"
|
||||
] else self.orphaned["exclude_patterns"]
|
||||
(
|
||||
self.orphaned["exclude_patterns"].append(exclude_recycle)
|
||||
if exclude_recycle not in self.orphaned["exclude_patterns"]
|
||||
else self.orphaned["exclude_patterns"]
|
||||
)
|
||||
|
||||
# Connect to Qbittorrent
|
||||
self.qbt = None
|
||||
|
@ -640,8 +644,10 @@ class Config:
|
|||
if empty_after_x_days <= days:
|
||||
num_del += 1
|
||||
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,
|
||||
)
|
||||
files += [str(filename)]
|
||||
|
@ -654,8 +660,10 @@ class Config:
|
|||
for path in location_path_list:
|
||||
util.remove_empty_directories(path, "**/*")
|
||||
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,
|
||||
)
|
||||
attr = {
|
||||
|
|
|
@ -64,8 +64,10 @@ class ReCheck:
|
|||
)
|
||||
logger.debug(
|
||||
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,
|
||||
)
|
||||
)
|
||||
|
@ -85,7 +87,7 @@ class ReCheck:
|
|||
):
|
||||
self.stats_resumed += 1
|
||||
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,
|
||||
)
|
||||
attr = {
|
||||
|
|
|
@ -67,8 +67,10 @@ class RemoveOrphaned:
|
|||
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(
|
||||
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,
|
||||
)
|
||||
|
||||
|
|
|
@ -145,22 +145,28 @@ class RemoveUnregistered:
|
|||
if self.stats_deleted >= 1 or self.stats_deleted_contents >= 1:
|
||||
if self.stats_deleted >= 1:
|
||||
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,
|
||||
)
|
||||
if self.stats_deleted_contents >= 1:
|
||||
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,
|
||||
)
|
||||
else:
|
||||
logger.print_line("No unregistered torrents found.", self.config.loglevel)
|
||||
if self.stats_untagged >= 1:
|
||||
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,
|
||||
)
|
||||
if self.stats_tagged >= 1:
|
||||
|
|
|
@ -62,7 +62,7 @@ class TagNoHardLinks:
|
|||
self.stats_untagged += 1
|
||||
body = []
|
||||
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,
|
||||
)
|
||||
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)
|
||||
if self.stats_tagged >= 1:
|
||||
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,
|
||||
)
|
||||
else:
|
||||
logger.print_line("No torrents to tag with no hardlinks.", self.config.loglevel)
|
||||
if self.stats_untagged >= 1:
|
||||
logger.print_line(
|
||||
f"{'Did not delete' if self.config.dry_run else 'Deleted'} "
|
||||
f"{self.nohardlinks_tag} 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'} "
|
||||
f"{self.nohardlinks_tag} tags for {self.stats_untagged} "
|
||||
f".torrent{'s.' if self.stats_untagged > 1 else '.'}"
|
||||
),
|
||||
self.config.loglevel,
|
||||
)
|
||||
|
|
|
@ -171,8 +171,10 @@ class Webhooks:
|
|||
def notify(self, torrents_updated=[], payload={}, group_by=""):
|
||||
if len(torrents_updated) > GROUP_NOTIFICATION_LIMIT:
|
||||
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":
|
||||
group_attr = group_notifications_by_key(payload, "torrent_category")
|
||||
|
@ -189,10 +191,14 @@ class Webhooks:
|
|||
attr = {
|
||||
"function": group_attr[group]["function"],
|
||||
"title": f"{group_attr[group]['title']} for {group}",
|
||||
"body": group_attr[group]["body"]
|
||||
if only_one_torrent_updated
|
||||
else f"Updated {num_torrents_updated} "
|
||||
f"{'torrent' if only_one_torrent_updated else 'torrents'} with {group_by} '{group}'",
|
||||
"body": (
|
||||
group_attr[group]["body"]
|
||||
if only_one_torrent_updated
|
||||
else (
|
||||
f"Updated {num_torrents_updated} "
|
||||
f"{'torrent' if only_one_torrent_updated else 'torrents'} with {group_by} '{group}'"
|
||||
)
|
||||
),
|
||||
"torrents": group_attr[group]["torrents"],
|
||||
}
|
||||
if group_by == "category":
|
||||
|
|
|
@ -61,8 +61,10 @@ parser.add_argument(
|
|||
action="store",
|
||||
default="config.yml",
|
||||
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"
|
||||
"config files using *. Example: tv.yml or config*.yml",
|
||||
help=(
|
||||
"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(
|
||||
"-lf",
|
||||
|
@ -103,8 +105,10 @@ parser.add_argument(
|
|||
dest="tag_update",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="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)",
|
||||
help=(
|
||||
"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(
|
||||
"-ru",
|
||||
|
@ -136,10 +140,12 @@ parser.add_argument(
|
|||
dest="tag_nohardlinks",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Use this to tag any torrents that do not have any hard links associated with any of the files. "
|
||||
"This is useful for those that use Sonarr/Radarr which hard link your media files with the torrents for seeding. "
|
||||
"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.",
|
||||
help=(
|
||||
"Use this to tag any torrents that do not have any hard links associated with any of the files. "
|
||||
"This is useful for those that use Sonarr/Radarr which hard link your media files with the torrents for seeding. "
|
||||
"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(
|
||||
"-sl",
|
||||
|
@ -147,9 +153,11 @@ parser.add_argument(
|
|||
dest="share_limits",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Use this to help apply and manage your torrent share limits based on your tags/categories."
|
||||
"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.",
|
||||
help=(
|
||||
"Use this to help apply and manage your torrent share limits based on your tags/categories."
|
||||
"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(
|
||||
"-sc",
|
||||
|
@ -422,7 +430,9 @@ def start():
|
|||
next_run = nxt_run["next_run"]
|
||||
body = logger.separator(
|
||||
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]
|
||||
return next_run, body
|
||||
|
||||
|
|
|
@ -184,8 +184,8 @@ def main():
|
|||
print(
|
||||
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"--- Torrents have multiple hard links\n"
|
||||
f"--- No torrents exists!"
|
||||
"--- Torrents have multiple hard links\n"
|
||||
"--- No torrents exists!"
|
||||
)
|
||||
|
||||
quit_program(0)
|
||||
|
|
6
setup.py
6
setup.py
|
@ -30,8 +30,10 @@ setup(
|
|||
# repository. For example: MIT
|
||||
license="MIT",
|
||||
# Short description of your library
|
||||
description="This tool will help manage tedious tasks in qBittorrent and automate them. "
|
||||
"Tag, categorize, remove Orphaned data, remove unregistered torrents and much much more.",
|
||||
description=(
|
||||
"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=long_description,
|
||||
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
|
||||
|
||||
[testenv]
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/requirements-dev.txt
|
||||
passenv = HOME SSH_AUTH_SOCK USER
|
||||
commands =
|
||||
pre-commit install -f --install-hooks
|
||||
pre-commit run --all-files --show-diff-on-failure
|
||||
|
||||
[testenv:venv]
|
||||
envdir = venv
|
||||
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]
|
||||
max-line-length = 130
|
||||
|
||||
|
|
Loading…
Reference in a new issue