diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ec71083..c26810d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 \ diff --git a/README.md b/README.md index b15caa6..427b5d9 100644 --- a/README.md +++ b/README.md @@ -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) ``` diff --git a/docker/dockerfile b/docker/Dockerfile similarity index 98% rename from docker/dockerfile rename to docker/Dockerfile index fb28d61..12be11c 100644 --- a/docker/dockerfile +++ b/docker/Dockerfile @@ -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" diff --git a/src/jobs/removal_handler.py b/src/jobs/removal_handler.py index feb2387..5bdacdf 100644 --- a/src/jobs/removal_handler.py +++ b/src/jobs/removal_handler.py @@ -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: diff --git a/src/jobs/remove_bad_files.py b/src/jobs/remove_bad_files.py index 00657d8..ff56dc0 100644 --- a/src/jobs/remove_bad_files.py +++ b/src/jobs/remove_bad_files.py @@ -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) diff --git a/src/jobs/remove_missing_files.py b/src/jobs/remove_missing_files.py index 68ea994..cce69fd 100644 --- a/src/jobs/remove_missing_files.py +++ b/src/jobs/remove_missing_files.py @@ -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 diff --git a/src/settings/_download_clients.py b/src/settings/_download_clients.py index 4ecb8a4..8bb47b4 100644 --- a/src/settings/_download_clients.py +++ b/src/settings/_download_clients.py @@ -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 diff --git a/tests/jobs/test_removal_handler.py b/tests/jobs/test_removal_handler.py index 21a2e84..d9f2849 100644 --- a/tests/jobs/test_removal_handler.py +++ b/tests/jobs/test_removal_handler.py @@ -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 \ No newline at end of file