mirror of
https://github.com/ManiMatter/decluttarr.git
synced 2026-04-17 21:53:58 +02:00
Changes per review of Dark3clipse
This commit is contained in:
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -121,7 +121,7 @@ jobs:
|
||||
fi
|
||||
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 -f docker/dockerfile . \
|
||||
--platform linux/amd64,linux/arm64 -f docker/Dockerfile . \
|
||||
--progress plain \
|
||||
-t $IMAGE_NAME:$IMAGE_TAG \
|
||||
$TAG_LATEST \
|
||||
|
||||
@@ -98,7 +98,7 @@ How to run this:
|
||||
|
||||
## Getting started
|
||||
|
||||
You can run decluttarr either as local python script, or inside docker.
|
||||
You can run decluttarr either as local python script, or as a docker container.
|
||||
|
||||
### Running locally
|
||||
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
remove_bad_files: # This is turned on
|
||||
# remove_bad_files: # This is turned off
|
||||
|
||||
## Note that this is different from docker-compose (where both exsmples above would be turned off; in docker, "true" or additional options are required as value next to the key)
|
||||
## Note that this is different from docker-compose (where both examples above would be turned off; in docker, "true" or additional options are required as value next to the key)
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#FROM python:3.9-slim-buster
|
||||
# For debugging:
|
||||
# First build:
|
||||
# sudo docker build --no-cache --progress=plain -f ./docker/dockerfile -t decluttarr .
|
||||
# sudo docker build --no-cache --progress=plain -f ./docker/Dockerfile -t decluttarr .
|
||||
|
||||
# Entering image (and printing env variables):
|
||||
# sudo docker run --rm -it -w /app --entrypoint sh decluttarr -c "printenv; exec sh"
|
||||
@@ -54,8 +54,10 @@ class RemovalHandler:
|
||||
if affected_download['protocol'] != 'torrent':
|
||||
return "remove" # handling is only implemented for torrent
|
||||
|
||||
client_implementation = await self.arr.get_download_client_implementation(affected_download['downloadClient'])
|
||||
if client_implementation != "QBittorrent":
|
||||
download_client_name = affected_download["downloadClient"]
|
||||
_, download_client_type = self.settings.download_clients.get_download_client_by_name(download_client_name)
|
||||
|
||||
if download_client_type != "qbittorrent":
|
||||
return "remove" # handling is only implemented for qbit
|
||||
|
||||
if len(self.settings.download_clients.qbittorrent) == 0:
|
||||
|
||||
@@ -9,7 +9,7 @@ STANDARD_EXTENSIONS = [
|
||||
# Movies, TV Shows (Radarr, Sonarr, Whisparr)
|
||||
".webm", ".m4v", ".3gp", ".nsv", ".ty", ".strm", ".rm", ".rmvb", ".m3u", ".ifo", ".mov", ".qt", ".divx", ".xvid", ".bivx", ".nrg", ".pva", ".wmv", ".asf", ".asx", ".ogm", ".ogv", ".m2v", ".avi", ".bin", ".dat", ".dvr-ms", ".mpg", ".mpeg", ".mp4", ".avc", ".vp3", ".svq3", ".nuv", ".viv", ".dv", ".fli", ".flv", ".wpl", ".img", ".iso", ".vob", ".mkv", ".mk3d", ".ts", ".wtv", ".m2ts",
|
||||
# Subs (Radarr, Sonarr, Whisparr)
|
||||
".sub", ".srt", ".idx",
|
||||
".sub", ".srt", ".idx", "vtt",
|
||||
# Audio (Lidarr, Readarr)
|
||||
".aac", ".aif", ".aiff", ".aifc", ".ape", ".flac", ".mp2", ".mp3", ".m4a", ".m4b", ".m4p", ".mp4a", ".oga", ".ogg", ".opus", ".vorbis", ".wma", ".wav", ".wv", "wavepack",
|
||||
# Text (Readarr)
|
||||
|
||||
@@ -9,7 +9,7 @@ class RemoveMissingFiles(RemovalJob):
|
||||
affected_items = []
|
||||
|
||||
for item in self.queue:
|
||||
if self._is_failed_torrent(item) or self._no_elibible_import(item):
|
||||
if self._is_failed_torrent(item) or self._no_eligible_import(item):
|
||||
affected_items.append(item)
|
||||
return affected_items
|
||||
|
||||
@@ -19,7 +19,8 @@ class RemoveMissingFiles(RemovalJob):
|
||||
"status" in item
|
||||
and item["status"] == "warning"
|
||||
and "errorMessage" in item
|
||||
and item["errorMessage"] in [
|
||||
and item["errorMessage"]
|
||||
in [
|
||||
"DownloadClientQbittorrentTorrentStateMissingFiles",
|
||||
"The download is missing files",
|
||||
"qBittorrent is reporting missing files",
|
||||
@@ -27,11 +28,17 @@ class RemoveMissingFiles(RemovalJob):
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _no_elibible_import(item) -> bool:
|
||||
if "status" in item and item["status"] == "completed" and "statusMessages" in item:
|
||||
def _no_eligible_import(item) -> bool:
|
||||
if (
|
||||
"status" in item
|
||||
and item["status"] == "completed"
|
||||
and "statusMessages" in item
|
||||
):
|
||||
for status_message in item["statusMessages"]:
|
||||
if "messages" in status_message:
|
||||
for message in status_message["messages"]:
|
||||
if message.startswith("No files found are eligible for import in"):
|
||||
if message.startswith(
|
||||
"No files found are eligible for import in"
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -66,8 +66,8 @@ class DownloadClients:
|
||||
download_clients = getattr(self, download_client_type, [])
|
||||
|
||||
# Check each client in the list
|
||||
for client in download_clients:
|
||||
if client.name.lower() == name_lower:
|
||||
return client, download_client_type
|
||||
for download_client in download_clients:
|
||||
if download_client.name.lower() == name_lower:
|
||||
return download_client, download_client_type
|
||||
|
||||
return None, None
|
||||
|
||||
@@ -5,32 +5,35 @@ from src.jobs.removal_handler import RemovalHandler
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"qbittorrent_configured, is_private, client_impl, protocol, expected",
|
||||
"qbittorrent_configured, is_private, client_type, protocol, expected",
|
||||
[
|
||||
(True, True, "QBittorrent", "torrent", "private_handling"),
|
||||
(True, False, "QBittorrent", "torrent", "public_handling"),
|
||||
(False, True, "QBittorrent", "torrent", "remove"),
|
||||
(False, False, "QBittorrent", "torrent", "remove"),
|
||||
(True, False, "Transmission", "torrent", "remove"), # unsupported client
|
||||
(True, False, "MyUseNetClient", "usenet", "remove"), # unsupported protocol
|
||||
(True, True, "qbittorrent", "torrent", "private_handling"),
|
||||
(True, False, "qbittorrent", "torrent", "public_handling"),
|
||||
(False, True, "qbittorrent", "torrent", "remove"),
|
||||
(False, False, "qbittorrent", "torrent", "remove"),
|
||||
(True, False, "transmission", "torrent", "remove"), # unsupported client
|
||||
(True, False, "myusenetclient", "usenet", "remove"), # unsupported protocol
|
||||
],
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_handling_method(
|
||||
qbittorrent_configured,
|
||||
is_private,
|
||||
client_impl,
|
||||
client_type,
|
||||
protocol,
|
||||
expected,
|
||||
):
|
||||
# Mock arr
|
||||
arr = AsyncMock()
|
||||
arr.tracker.private = ["A"] if is_private else []
|
||||
arr.get_download_client_implementation.return_value = client_impl
|
||||
|
||||
# Mock settings
|
||||
# Mock settings and get_download_client_by_name
|
||||
settings = MagicMock()
|
||||
settings.download_clients.qbittorrent = ["dummy"] if qbittorrent_configured else []
|
||||
|
||||
# Simulate (client_name, client_type) return
|
||||
settings.download_clients.get_download_client_by_name.return_value = ("client_name", client_type)
|
||||
|
||||
settings.general.private_tracker_handling = "private_handling"
|
||||
settings.general.public_tracker_handling = "public_handling"
|
||||
|
||||
@@ -44,4 +47,4 @@ async def test_get_handling_method(
|
||||
result = await handler._get_handling_method( # pylint: disable=W0212
|
||||
"A", affected_download
|
||||
)
|
||||
assert result == expected
|
||||
assert result == expected
|
||||
Reference in New Issue
Block a user