mirror of
https://github.com/StuffAnThings/qbit_manage.git
synced 2024-09-20 15:26:02 +08:00
commit
d01afe9603
|
@ -19,7 +19,7 @@ jobs:
|
||||||
# will not occur.
|
# will not occur.
|
||||||
- name: Dependabot metadata
|
- name: Dependabot metadata
|
||||||
id: dependabot-metadata
|
id: dependabot-metadata
|
||||||
uses: dependabot/fetch-metadata@v1.5.1
|
uses: dependabot/fetch-metadata@v1.6.0
|
||||||
with:
|
with:
|
||||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
# Here the PR gets approved.
|
# Here the PR gets approved.
|
||||||
|
|
|
@ -27,7 +27,7 @@ repos:
|
||||||
args: [--format, parsable, --strict]
|
args: [--format, parsable, --strict]
|
||||||
exclude: ^.github/
|
exclude: ^.github/
|
||||||
- repo: https://github.com/lyz-code/yamlfix
|
- repo: https://github.com/lyz-code/yamlfix
|
||||||
rev: 1.11.0
|
rev: 1.13.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: yamlfix
|
- id: yamlfix
|
||||||
exclude: ^.github/
|
exclude: ^.github/
|
||||||
|
@ -36,18 +36,18 @@ repos:
|
||||||
hooks:
|
hooks:
|
||||||
- id: reorder-python-imports
|
- id: reorder-python-imports
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v3.7.0
|
rev: v3.10.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args: [--py3-plus]
|
args: [--py3-plus]
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 23.3.0
|
rev: 23.7.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
language_version: python3
|
language_version: python3
|
||||||
args: [--line-length, '130', --preview]
|
args: [--line-length, '130', --preview]
|
||||||
- repo: https://github.com/PyCQA/flake8
|
- repo: https://github.com/PyCQA/flake8
|
||||||
rev: 6.0.0
|
rev: 6.1.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
args: [--config=.flake8]
|
args: [--config=.flake8]
|
||||||
|
|
17
CHANGELOG
17
CHANGELOG
|
@ -1,13 +1,12 @@
|
||||||
# Requirements Updated
|
# Requirements Updated
|
||||||
- qbitorrent-api updated to 2023.6.50
|
- qbitorrent-api updated to 2023.7.52
|
||||||
- ruamel.yaml updated to 0.17.32
|
|
||||||
# New Features
|
|
||||||
- Adds min_num_seeds condition to share_limits (Closes [#321](https://github.com/StuffAnThings/qbit_manage/issues/321))
|
|
||||||
|
|
||||||
# Bug Fixes
|
# Bug Fixes
|
||||||
Fixes [#333](https://github.com/StuffAnThings/qbit_manage/issues/333)
|
- Fixes a few webhook bugs with Notifiarr
|
||||||
Fixes [#340](https://github.com/StuffAnThings/qbit_manage/issues/340)
|
- Fixes [#355](https://github.com/StuffAnThings/qbit_manage/issues/355)
|
||||||
Fixes [#343](https://github.com/StuffAnThings/qbit_manage/issues/343)
|
- Fixes [#356](https://github.com/StuffAnThings/qbit_manage/issues/356)
|
||||||
Fixes bug when checking tags in torrents
|
- Fixes [#363](https://github.com/StuffAnThings/qbit_manage/issues/363)
|
||||||
|
- Fixes [#370](https://github.com/StuffAnThings/qbit_manage/issues/370)
|
||||||
|
|
||||||
**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.0.1...v4.0.2
|
|
||||||
|
**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.0.2...v4.0.3
|
||||||
|
|
|
@ -663,10 +663,8 @@ 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"{'Did not delete' if self.dry_run else 'Deleted'} "
|
||||||
f"{filename} from {folder} (Last modified {round(days)} days ago)."
|
f"{filename} from {folder} (Last modified {round(days)} days ago).",
|
||||||
),
|
|
||||||
self.loglevel,
|
self.loglevel,
|
||||||
)
|
)
|
||||||
files += [str(filename)]
|
files += [str(filename)]
|
||||||
|
@ -679,10 +677,8 @@ 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"{'Did not delete' if self.dry_run else 'Deleted'} {num_del} files "
|
||||||
f"({util.human_readable_size(size_bytes)}) from the {location}."
|
f"({util.human_readable_size(size_bytes)}) from the {location}.",
|
||||||
),
|
|
||||||
self.loglevel,
|
self.loglevel,
|
||||||
)
|
)
|
||||||
attr = {
|
attr = {
|
||||||
|
|
|
@ -128,7 +128,7 @@ class CrossSeed:
|
||||||
"torrents": [t_name],
|
"torrents": [t_name],
|
||||||
"torrent_category": t_cat,
|
"torrent_category": t_cat,
|
||||||
"torrent_tag": "cross-seed",
|
"torrent_tag": "cross-seed",
|
||||||
"torrent_tracker": tracker,
|
"torrent_tracker": tracker["url"],
|
||||||
}
|
}
|
||||||
self.notify_attr.append(attr)
|
self.notify_attr.append(attr)
|
||||||
self.torrents_updated.append(t_name)
|
self.torrents_updated.append(t_name)
|
||||||
|
|
|
@ -46,7 +46,7 @@ class ReCheck:
|
||||||
"title": "Resuming Torrent",
|
"title": "Resuming Torrent",
|
||||||
"body": body,
|
"body": body,
|
||||||
"torrents": [t_name],
|
"torrents": [t_name],
|
||||||
"torrent_tag": tracker["tag"],
|
"torrent_tag": ", ".join(tracker["tag"]),
|
||||||
"torrent_category": t_category,
|
"torrent_category": t_category,
|
||||||
"torrent_tracker": tracker["url"],
|
"torrent_tracker": tracker["url"],
|
||||||
"notifiarr_indexer": tracker["notifiarr"],
|
"notifiarr_indexer": tracker["notifiarr"],
|
||||||
|
@ -64,10 +64,8 @@ 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"-- Seeding Time vs Max Seed Time: {timedelta(seconds=torrent.seeding_time)} < "
|
||||||
f"{timedelta(minutes=torrent.max_seeding_time)}"
|
f"{timedelta(minutes=torrent.max_seeding_time)}",
|
||||||
),
|
|
||||||
4,
|
4,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -95,7 +93,7 @@ class ReCheck:
|
||||||
"title": "Resuming Torrent",
|
"title": "Resuming Torrent",
|
||||||
"body": body,
|
"body": body,
|
||||||
"torrents": [t_name],
|
"torrents": [t_name],
|
||||||
"torrent_tag": tracker["tag"],
|
"torrent_tag": ", ".join(tracker["tag"]),
|
||||||
"torrent_category": t_category,
|
"torrent_category": t_category,
|
||||||
"torrent_tracker": tracker["url"],
|
"torrent_tracker": tracker["url"],
|
||||||
"notifiarr_indexer": tracker["notifiarr"],
|
"notifiarr_indexer": tracker["notifiarr"],
|
||||||
|
@ -120,7 +118,7 @@ class ReCheck:
|
||||||
"title": "Rechecking Torrent",
|
"title": "Rechecking Torrent",
|
||||||
"body": body,
|
"body": body,
|
||||||
"torrents": [t_name],
|
"torrents": [t_name],
|
||||||
"torrent_tag": tracker["tag"],
|
"torrent_tag": ", ".join(tracker["tag"]),
|
||||||
"torrent_category": t_category,
|
"torrent_category": t_category,
|
||||||
"torrent_tracker": tracker["url"],
|
"torrent_tracker": tracker["url"],
|
||||||
"notifiarr_indexer": tracker["notifiarr"],
|
"notifiarr_indexer": tracker["notifiarr"],
|
||||||
|
|
|
@ -67,10 +67,8 @@ 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"{'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"to {self.orphaned_dir.replace(self.remote_dir,self.root_dir)}",
|
||||||
),
|
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -142,28 +142,22 @@ 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"{'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".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"{'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".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"{'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".torrent{'s.' if self.stats_untagged > 1 else '.'}",
|
||||||
),
|
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
if self.stats_tagged >= 1:
|
if self.stats_tagged >= 1:
|
||||||
|
|
|
@ -55,6 +55,7 @@ class ShareLimits:
|
||||||
"torrent_max_ratio": group_config["max_ratio"],
|
"torrent_max_ratio": group_config["max_ratio"],
|
||||||
"torrent_max_seeding_time": group_config["max_seeding_time"],
|
"torrent_max_seeding_time": group_config["max_seeding_time"],
|
||||||
"torrent_min_seeding_time": group_config["min_seeding_time"],
|
"torrent_min_seeding_time": group_config["min_seeding_time"],
|
||||||
|
"torrent_min_num_seeds": group_config["min_num_seeds"],
|
||||||
"torrent_limit_upload_speed": group_config["limit_upload_speed"],
|
"torrent_limit_upload_speed": group_config["limit_upload_speed"],
|
||||||
}
|
}
|
||||||
if len(self.torrents_updated) > 0:
|
if len(self.torrents_updated) > 0:
|
||||||
|
@ -196,6 +197,7 @@ class ShareLimits:
|
||||||
"Config Max Seeding Time vs Torrent Max Seeding Time: "
|
"Config Max Seeding Time vs Torrent Max Seeding Time: "
|
||||||
f"{group_config['max_seeding_time']} vs {torrent.max_seeding_time}"
|
f"{group_config['max_seeding_time']} vs {torrent.max_seeding_time}"
|
||||||
)
|
)
|
||||||
|
logger.trace(f"Config Min Num Seeds vs Torrent Num Seeds: {group_config['min_num_seeds']} vs {torrent.num_complete}")
|
||||||
logger.trace(f"check_max_seeding_time: {check_max_seeding_time}")
|
logger.trace(f"check_max_seeding_time: {check_max_seeding_time}")
|
||||||
logger.trace(
|
logger.trace(
|
||||||
"Config Limit Upload Speed vs Torrent Limit Upload Speed: "
|
"Config Limit Upload Speed vs Torrent Limit Upload Speed: "
|
||||||
|
@ -218,8 +220,6 @@ class ShareLimits:
|
||||||
self.stats_tagged += 1
|
self.stats_tagged += 1
|
||||||
self.torrents_updated.append(t_name)
|
self.torrents_updated.append(t_name)
|
||||||
|
|
||||||
# Cleanup torrents if the torrent meets the criteria for deletion and cleanup is enabled
|
|
||||||
if group_config["cleanup"]:
|
|
||||||
tor_reached_seed_limit = self.has_reached_seed_limit(
|
tor_reached_seed_limit = self.has_reached_seed_limit(
|
||||||
torrent=torrent,
|
torrent=torrent,
|
||||||
max_ratio=group_config["max_ratio"],
|
max_ratio=group_config["max_ratio"],
|
||||||
|
@ -229,6 +229,8 @@ class ShareLimits:
|
||||||
resume_torrent=group_config["resume_torrent_after_change"],
|
resume_torrent=group_config["resume_torrent_after_change"],
|
||||||
tracker=tracker["url"],
|
tracker=tracker["url"],
|
||||||
)
|
)
|
||||||
|
# Cleanup torrents if the torrent meets the criteria for deletion and cleanup is enabled
|
||||||
|
if group_config["cleanup"]:
|
||||||
if tor_reached_seed_limit:
|
if tor_reached_seed_limit:
|
||||||
if t_hash not in self.tdel_dict:
|
if t_hash not in self.tdel_dict:
|
||||||
self.tdel_dict[t_hash] = {}
|
self.tdel_dict[t_hash] = {}
|
||||||
|
@ -391,11 +393,9 @@ class ShareLimits:
|
||||||
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(
|
||||||
logger.insert_space(
|
logger.insert_space(
|
||||||
(
|
|
||||||
f"Min seed time not met: {timedelta(seconds=torrent.seeding_time)} <="
|
f"Min seed time not met: {timedelta(seconds=torrent.seeding_time)} <="
|
||||||
f" {timedelta(minutes=min_seeding_time)}. Removing Share Limits so qBittorrent can continue"
|
f" {timedelta(minutes=min_seeding_time)}. Removing Share Limits so qBittorrent can continue"
|
||||||
" seeding."
|
" seeding.",
|
||||||
),
|
|
||||||
8,
|
8,
|
||||||
),
|
),
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
|
@ -423,11 +423,9 @@ class ShareLimits:
|
||||||
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(
|
||||||
logger.insert_space(
|
logger.insert_space(
|
||||||
(
|
|
||||||
f"Min number of seeds not met: Total Seeds ({torrent.num_complete}) < "
|
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"
|
f"min_num_seeds({min_num_seeds}). Removing Share Limits so qBittorrent can continue"
|
||||||
" seeding."
|
" seeding.",
|
||||||
),
|
|
||||||
8,
|
8,
|
||||||
),
|
),
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
|
@ -456,10 +454,8 @@ class ShareLimits:
|
||||||
if seeding_time_limit:
|
if seeding_time_limit:
|
||||||
if (torrent.seeding_time >= seeding_time_limit * 60) and _has_reached_min_seeding_time_limit():
|
if (torrent.seeding_time >= seeding_time_limit * 60) and _has_reached_min_seeding_time_limit():
|
||||||
body += logger.insert_space(
|
body += logger.insert_space(
|
||||||
(
|
|
||||||
f"Seeding Time vs Max Seed Time: {timedelta(seconds=torrent.seeding_time)} >= "
|
f"Seeding Time vs Max Seed Time: {timedelta(seconds=torrent.seeding_time)} >= "
|
||||||
f"{timedelta(minutes=seeding_time_limit)}"
|
f"{timedelta(minutes=seeding_time_limit)}",
|
||||||
),
|
|
||||||
8,
|
8,
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -120,20 +120,16 @@ 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"{'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".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"{'Did not delete' if self.config.dry_run else 'Deleted'} "
|
||||||
f"{self.nohardlinks_tag} tags for {self.stats_untagged} "
|
f"{self.nohardlinks_tag} tags for {self.stats_untagged} "
|
||||||
f".torrent{'s.' if self.stats_untagged > 1 else '.'}"
|
f".torrent{'s.' if self.stats_untagged > 1 else '.'}",
|
||||||
),
|
|
||||||
self.config.loglevel,
|
self.config.loglevel,
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from qbittorrentapi import APIConnectionError
|
|
||||||
from qbittorrentapi import Client
|
from qbittorrentapi import Client
|
||||||
from qbittorrentapi import LoginFailed
|
from qbittorrentapi import LoginFailed
|
||||||
from qbittorrentapi import NotFound404Error
|
from qbittorrentapi import NotFound404Error
|
||||||
|
@ -74,15 +73,10 @@ class Qbt:
|
||||||
except LoginFailed as exc:
|
except LoginFailed as exc:
|
||||||
ex = "Qbittorrent Error: Failed to login. Invalid username/password."
|
ex = "Qbittorrent Error: Failed to login. Invalid username/password."
|
||||||
self.config.notify(ex, "Qbittorrent")
|
self.config.notify(ex, "Qbittorrent")
|
||||||
raise Failed(ex) from exc
|
raise Failed(exc) from exc
|
||||||
except APIConnectionError as exc:
|
|
||||||
ex = "Qbittorrent Error: Unable to connect to the client."
|
|
||||||
self.config.notify(ex, "Qbittorrent")
|
|
||||||
raise Failed(ex) from exc
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
ex = "Qbittorrent Error: Unable to connect to the client."
|
self.config.notify(exc, "Qbittorrent")
|
||||||
self.config.notify(ex, "Qbittorrent")
|
raise Failed(exc) from exc
|
||||||
raise Failed(ex) from exc
|
|
||||||
logger.separator("Getting Torrent List", space=False, border=False)
|
logger.separator("Getting Torrent List", space=False, border=False)
|
||||||
self.torrent_list = self.get_torrents({"sort": "added_on"})
|
self.torrent_list = self.get_torrents({"sort": "added_on"})
|
||||||
|
|
||||||
|
|
|
@ -384,7 +384,18 @@ def move_files(src, dest, mod=False):
|
||||||
shutil.move(src, dest)
|
shutil.move(src, dest)
|
||||||
except PermissionError as perm:
|
except PermissionError as perm:
|
||||||
logger.warning(f"{perm} : Copying files instead.")
|
logger.warning(f"{perm} : Copying files instead.")
|
||||||
|
try:
|
||||||
shutil.copyfile(src, dest)
|
shutil.copyfile(src, dest)
|
||||||
|
except Exception as ex:
|
||||||
|
logger.stacktrace()
|
||||||
|
logger.error(ex)
|
||||||
|
return to_delete
|
||||||
|
if os.path.isfile(src):
|
||||||
|
logger.warning(f"Removing original file: {src}")
|
||||||
|
try:
|
||||||
|
os.remove(src)
|
||||||
|
except OSError as e:
|
||||||
|
logger.warning(f"Error: {e.filename} - {e.strerror}.")
|
||||||
to_delete = True
|
to_delete = True
|
||||||
except FileNotFoundError as file:
|
except FileNotFoundError as file:
|
||||||
logger.warning(f"{file} : source: {src} -> destination: {dest}")
|
logger.warning(f"{file} : source: {src} -> destination: {dest}")
|
||||||
|
@ -501,12 +512,12 @@ class CheckHardLinks:
|
||||||
continue
|
continue
|
||||||
file_size = os.stat(files).st_size
|
file_size = os.stat(files).st_size
|
||||||
file_no_hardlinks = os.stat(files).st_nlink
|
file_no_hardlinks = os.stat(files).st_nlink
|
||||||
logger.trace(f"Checking file: {file}")
|
logger.trace(f"Checking file: {files}")
|
||||||
logger.trace(f"Checking file inum: {os.stat(file).st_ino}")
|
logger.trace(f"Checking file inum: {os.stat(files).st_ino}")
|
||||||
logger.trace(f"Checking file size: {file_size}")
|
logger.trace(f"Checking file size: {file_size}")
|
||||||
logger.trace(f"Checking no of hard links: {file_no_hardlinks}")
|
logger.trace(f"Checking no of hard links: {file_no_hardlinks}")
|
||||||
logger.trace(f"Checking inode_count dict: {self.inode_count.get(os.stat(file).st_ino)}")
|
logger.trace(f"Checking inode_count dict: {self.inode_count.get(os.stat(files).st_ino)}")
|
||||||
if file_no_hardlinks - self.inode_count.get(os.stat(file).st_ino, 1) > 0 and file_size >= (
|
if file_no_hardlinks - self.inode_count.get(os.stat(files).st_ino, 1) > 0 and file_size >= (
|
||||||
largest_file_size * threshold
|
largest_file_size * threshold
|
||||||
):
|
):
|
||||||
check_for_hl = False
|
check_for_hl = False
|
||||||
|
|
|
@ -171,10 +171,8 @@ 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"Number of torrents updated > {GROUP_NOTIFICATION_LIMIT}, grouping notifications"
|
||||||
f"{f' by {group_by}' if group_by else ''}"
|
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")
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
flake8==6.0.0
|
flake8==6.1.0
|
||||||
pre-commit==3.3.3
|
pre-commit==3.3.3
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
bencodepy==0.9.5
|
bencodepy==0.9.5
|
||||||
GitPython==3.1.32
|
GitPython==3.1.32
|
||||||
qbittorrent-api==2023.6.50
|
qbittorrent-api==2023.7.52
|
||||||
requests==2.31.0
|
requests==2.31.0
|
||||||
retrying==1.3.4
|
retrying==1.3.4
|
||||||
ruamel.yaml==0.17.32
|
ruamel.yaml==0.17.32
|
||||||
|
|
Loading…
Reference in a new issue