diff --git a/README.md b/README.md index ae6744b..d8ed125 100644 --- a/README.md +++ b/README.md @@ -194,22 +194,23 @@ services: # # --- Jobs (short notation) --- # If you want to go with the most basic settings, you can just turn them all on: - # REMOVE_BAD_FILES: True - # REMOVE_FAILED_DOWNLOADS: True - # REMOVE_FAILED_IMPORTS: True - # REMOVE_METADATA_MISSING: True - # REMOVE_MISSING_FILES: True - # REMOVE_ORPHANS: True - # REMOVE_SLOW: True - # REMOVE_STALLED: True - # REMOVE_UNMONITORED: True - # SEARCH_BETTER_CONTENT: True - # SEARCH_MISSING_CONTENT: True + REMOVE_BAD_FILES: True + REMOVE_FAILED_DOWNLOADS: True + REMOVE_FAILED_IMPORTS: True + REMOVE_METADATA_MISSING: True + REMOVE_MISSING_FILES: True + REMOVE_ORPHANS: True + REMOVE_SLOW: True + REMOVE_STALLED: True + REMOVE_UNMONITORED: True + SEARCH_BETTER_CONTENT: True + SEARCH_MISSING_CONTENT: True # # --- OR: Jobs (with job-specific settings) --- # Alternatively, you can use the below notation, which for certain jobs allows you to set additioanl parameters # As written above, these can also be set as Job Defaults so you don't have to specify them as granular as below. - # REMOVE_BAD_FILES: True + # REMOVE_BAD_FILES: | + # keep_archives: True # REMOVE_FAILED_DOWNLOADS: True # REMOVE_FAILED_IMPORTS: True # REMOVE_METADATA_MISSING: | @@ -392,11 +393,15 @@ This is the interesting section. It defines which job you want decluttarr to run - Trailer - Sample -- If all files of a torrent are marked as 'not download' then the torrent will be removed and blacklisted -- Note that this is only supported when qBittorrent is configured in decluttarr and it will turn on the setting 'Keep unselected files in ".unwanted" folder' in qBittorrent -- Type: Boolean -- Permissible Values: True, False -- Is Mandatory: No (Defaults to False) +- If all files of a torrent are marked as 'not download' then the torrent will be removed and blacklisted +- Note that this is only supported when qBittorrent is configured in decluttarr and it will turn on the setting 'Keep unselected files in ".unwanted" folder' in qBittorrent +- Type: Boolean or Dict +- Permissible Values: True, False or keep_archives (bool) +- Is Mandatory: No (Defaults to False) +- Note: + - If you turn keep_archives on (default: false), packaged files (rar, zip, 7zip, etc.) are not removed + - This may be helpful if you use a tool such as [unpackerr](https://github.com/Unpackerr/unpackerr) that can handle it + - However, you may also find that these packages may contain bad/malicious files (which will not removed by decluttarr) #### REMOVE_FAILED_DOWNLOADS diff --git a/config/config_example.yaml b/config/config_example.yaml index 6c0b750..0eb28f6 100644 --- a/config/config_example.yaml +++ b/config/config_example.yaml @@ -16,6 +16,7 @@ job_defaults: jobs: remove_bad_files: + # keep_archives: true remove_failed_downloads: remove_failed_imports: message_patterns: diff --git a/src/jobs/remove_bad_files.py b/src/jobs/remove_bad_files.py index 99ff7ec..5d5ca5c 100644 --- a/src/jobs/remove_bad_files.py +++ b/src/jobs/remove_bad_files.py @@ -18,6 +18,11 @@ class RemoveBadFiles(RemovalJob): ".epub", ".kepub", ".mobi", ".azw3", ".pdf", ] + # Archives can be handled by tools such as unpackerr: + archive_extensions = [ + ".rar", ".tar", ".tgz", ".gz", ".zip", ".7z", ".bz2", ".tbz2", ".iso", + ] + bad_keywords = ["Sample", "Trailer"] bad_keyword_limit = 500 # Megabyte; do not remove items larger than that # fmt: on @@ -167,7 +172,13 @@ class RemoveBadFiles(RemovalJob): def _is_bad_extension(self, file): """Check if the file has a bad extension.""" - return file['file_extension'].lower() not in self.good_extensions + return file['file_extension'].lower() not in self.get_good_extensions() + + def get_good_extensions(self): + extensions = list(self.good_extensions) + if self.job.keep_archives: + extensions += self.archive_extensions + return extensions def _contains_bad_keyword(self, file): """Check if the file path contains a bad keyword and is smaller than the limit.""" diff --git a/src/settings/_jobs.py b/src/settings/_jobs.py index 3ae99b0..62331f5 100644 --- a/src/settings/_jobs.py +++ b/src/settings/_jobs.py @@ -7,6 +7,7 @@ class JobParams: """Represents individual job settings, with an 'enabled' flag and optional parameters.""" enabled: bool = False + keep_archives = False message_patterns: list max_strikes: int min_speed: int @@ -16,6 +17,7 @@ class JobParams: def __init__( self, enabled=None, + keep_archives=None, message_patterns=None, max_strikes=None, min_speed=None, @@ -23,6 +25,7 @@ class JobParams: min_days_between_searches=None, ): self.enabled = enabled + self.keep_archives = keep_archives self.message_patterns = message_patterns self.max_strikes = max_strikes self.min_speed = min_speed @@ -42,6 +45,7 @@ class JobParams: class JobDefaults: """Represents default job settings.""" + keep_archives: bool = False max_strikes: int = 3 max_concurrent_searches: int = 3 min_days_between_searches: int = 7 @@ -70,7 +74,9 @@ class Jobs: del self.job_defaults def _set_job_defaults(self): - self.remove_bad_files = JobParams() + self.remove_bad_files = JobParams( + keep_archives=self.job_defaults.keep_archives + ) self.remove_failed_downloads = JobParams() self.remove_failed_imports = JobParams( message_patterns=self.job_defaults.message_patterns