From 0fa4a2203a815d5108186bae9be8b3e35c8bac60 Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 26 Jun 2024 10:37:09 +0200 Subject: [PATCH 001/101] Initial changes for tagless operation --- config.example.toml | 3 +++ qBitrr/arss.py | 3 +++ qBitrr/config.py | 3 +++ qBitrr/env_config.py | 1 + qBitrr/gen_config.py | 6 ++++++ qBitrr/logger.py | 2 ++ qBitrr/tables.py | 8 ++++++++ 7 files changed, 26 insertions(+) diff --git a/config.example.toml b/config.example.toml index 5d3ed7c5..97fa5799 100644 --- a/config.example.toml +++ b/config.example.toml @@ -30,6 +30,9 @@ FailedCategory = "failed" # Add torrents to this category to trigger them to be rechecked properly RecheckCategory = "recheck" +# Tagless operation +Tagless = false + # Ignore Torrents which are younger than this value (in seconds: 600 = 10 Minutes) # Only applicable to Re-check and failed categories IgnoreTorrentsYoungerThan = 600 diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 0b8beba2..c5e63006 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -57,6 +57,7 @@ MovieQueueModel, MoviesFilesModel, SeriesFilesModel, + TorrentLibrary, ) from qBitrr.utils import ( ExpiringSet, @@ -499,6 +500,7 @@ def __init__( self.series_file_model: SeriesFilesModel = None self.model_queue: EpisodeQueueModel | MovieQueueModel = None self.persistent_queue: FilesQueued = None + self.torrent_library: TorrentLibrary = None self.logger.hnotice("Starting %s monitor", self._name) @property @@ -568,6 +570,7 @@ def _get_models( type[EpisodeFilesModel] | type[MoviesFilesModel], type[EpisodeQueueModel] | type[MovieQueueModel], type[SeriesFilesModel] | None, + type[TorrentLibrary] | None, ]: if self.type == "sonarr": if self.series_search: diff --git a/qBitrr/config.py b/qBitrr/config.py index 5684de76..c8dc3b9a 100644 --- a/qBitrr/config.py +++ b/qBitrr/config.py @@ -116,6 +116,9 @@ def process_flags() -> argparse.Namespace | bool: RECHECK_CATEGORY = ENVIRO_CONFIG.settings.recheck_category or CONFIG.get( "Settings.RecheckCategory", fallback="recheck" ) +TAGLESS = ENVIRO_CONFIG.settings.tagless or CONFIG.get( + "Settings.Tagless", fallback=False +) CONSOLE_LOGGING_LEVEL_STRING = ENVIRO_CONFIG.settings.console_level or CONFIG.get_or_raise( "Settings.ConsoleLevel" ) diff --git a/qBitrr/env_config.py b/qBitrr/env_config.py index 9b35e0cd..5ae5cd7e 100644 --- a/qBitrr/env_config.py +++ b/qBitrr/env_config.py @@ -37,6 +37,7 @@ class Settings: search_loop_delay = environ.var(None, converter=Converter.int) failed_category = environ.var(None) recheck_category = environ.var(None) + tagless = environ.var(None, converter=Converter.bool) ignore_torrents_younger_than = environ.var(None, converter=Converter.int) ping_urls = environ.var(None, converter=Converter.list) ffprobe_auto_update = environ.var(None, converter=Converter.bool) diff --git a/qBitrr/gen_config.py b/qBitrr/gen_config.py index ff87631f..83f98465 100755 --- a/qBitrr/gen_config.py +++ b/qBitrr/gen_config.py @@ -86,6 +86,12 @@ def _add_settings_section(config: TOMLDocument): "RecheckCategory", ENVIRO_CONFIG.settings.recheck_category or "recheck", ) + _gen_default_line( + settings, + "Tagless operation", + "Tagless", + ENVIRO_CONFIG.settings.tagless or False, + ) _gen_default_line( settings, [ diff --git a/qBitrr/logger.py b/qBitrr/logger.py index c94f232c..4841cb04 100644 --- a/qBitrr/logger.py +++ b/qBitrr/logger.py @@ -19,6 +19,7 @@ NO_INTERNET_SLEEP_TIMER, PING_URLS, RECHECK_CATEGORY, + TAGLESS, SEARCH_LOOP_DELAY, ) @@ -125,6 +126,7 @@ def log_Debugs(logger): logger.debug("Ping URLs: %s", PING_URLS) logger.debug("Script Config: FailedCategory=%s", FAILED_CATEGORY) logger.debug("Script Config: RecheckCategory=%s", RECHECK_CATEGORY) + logger.debug("Script Config: Tagless=%s", TAGLESS) logger.debug("Script Config: CompletedDownloadFolder=%s", COMPLETED_DOWNLOAD_FOLDER) logger.debug("Script Config: FreeSpace=%s", FREE_SPACE) logger.debug("Script Config: LoopSleepTimer=%s", LOOP_SLEEP_TIMER) diff --git a/qBitrr/tables.py b/qBitrr/tables.py index c7a06aab..570aae10 100644 --- a/qBitrr/tables.py +++ b/qBitrr/tables.py @@ -61,3 +61,11 @@ class MovieQueueModel(Model): class EpisodeQueueModel(Model): EntryId = IntegerField(unique=True) Completed = BooleanField(default=False) + +class TorrentLibrary(Model): + Hash = TextField(null=False) + AllowedSeeding = BooleanField(default=False) + Ignored = BooleanField(default=False) + Imported = BooleanField(default=False) + AllowedStalled = BooleanField(default=False) + FreeSpacePaused = BooleanField(default=False) From 6c942e138572c6d7899d4aadf0520330ccf1da3e Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 13:58:26 +0200 Subject: [PATCH 002/101] Added new fields `AllowStalled` and `StalledDelay` --- config.example.toml | 24 ++++++++++++++++++++++++ qBitrr/arss.py | 35 ++++++++++++++++++++++++----------- qBitrr/gen_config.py | 2 ++ 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/config.example.toml b/config.example.toml index 97fa5799..dba9597c 100644 --- a/config.example.toml +++ b/config.example.toml @@ -217,6 +217,12 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true +# Allow stalled torrents +AllowStalled = false + +# Maximum allowed time for allowed stalled torrents +StalledDelay = 0 + [Sonarr-TV.Torrent.SeedingMode] # Set the maximum allowed download rate for torrents @@ -414,6 +420,12 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true +# Allow stalled torrents +AllowStalled = false + +# Maximum allowed time for allowed stalled torrents +StalledDelay = 0 + [Sonarr-Anime.Torrent.SeedingMode] # Set the maximum allowed download rate for torrents @@ -607,6 +619,12 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true +# Allow stalled torrents +AllowStalled = false + +# Maximum allowed time for allowed stalled torrents +StalledDelay = 0 + [Radarr-1080.Torrent.SeedingMode] # Set the maximum allowed download rate for torrents @@ -813,6 +831,12 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true +# Allow stalled torrents +AllowStalled = false + +# Maximum allowed time for allowed stalled torrents +StalledDelay = 0 + [Radarr-4K.Torrent.SeedingMode] # Set the maximum allowed download rate for torrents diff --git a/qBitrr/arss.py b/qBitrr/arss.py index c5e63006..1be59f7e 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -223,6 +223,8 @@ def __init__( ) self.do_not_remove_slow = CONFIG.get(f"{name}.Torrent.DoNotRemoveSlow", fallback=False) + self.allow_stalled = CONFIG.get(f"{name}.Torrent.AllowStalled", fallback=False) + self.stalled_delay = CONFIG.get(f"{name}.Torrent.StalledDelay", fallback=0) self.search_current_year = None if self.search_in_reverse: self._delta = 1 @@ -492,7 +494,8 @@ def __init__( [ "qBitrr-allowed_seeding", "qBitrr-ignored", - "qbitrr-imported", + "qBitrr-imported", + "qBitrr-allow_stalled" ] ) self.search_setup_completed = False @@ -3780,16 +3783,11 @@ def _should_leave_alone( seeding_time_limit = max(seeding_time_limit_dat, seeding_time_limit_tor) ratio_limit = max(ratio_limit_dat, ratio_limit_tor) - if self.seeding_mode_global_remove_torrent != -1 and self.remove_torrent( - torrent, seeding_time_limit, ratio_limit - ): - remove_torrent = True - return_value = False + if self.seeding_mode_global_remove_torrent != -1: + remove_torrent = self.torrent_limit_check(torrent, seeding_time_limit, ratio_limit) else: - if torrent.ratio >= ratio_limit and ratio_limit != -5: - return_value = False # Seeding ratio met - Can be cleaned up. - if torrent.seeding_time >= seeding_time_limit and seeding_time_limit != -5: - return_value = False # Seeding time met - Can be cleaned up. + remove_torrent = False + return_value = not self.torrent_limit_check(torrent, seeding_time_limit, ratio_limit) if data_settings.get("super_seeding", False) or data_torrent.get("super_seeding", False): return_value = True if "qBitrr-free_space_paused" in torrent.tags: @@ -3981,6 +3979,11 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): "qBitrr-free_space_paused", ] ) + if ( + "qBitrr-allow_stalled" in torrent.tags + and torrent.added_on >= int(time.time()+(self.stalled_delay*60)) + ): + torrent.remove_tags(["qBitrr-allow_stalled"]) if ( self.custom_format_unmet_search and self.custom_format_unmet_check(torrent) @@ -4006,6 +4009,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags + and "qBitrr-allow_stalled" not in torrent.tags ): self._process_single_torrent_stalled_torrent(torrent, "Stalled State") elif ( @@ -4026,6 +4030,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_complete_state(torrent) is False and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags + and "qBitrr-allow_stalled" not in torrent.tags ) and torrent.hash in self.cleaned_torrents: self._process_single_torrent_percentage_threshold(torrent, maximum_eta) # Resume monitored downloads which have been paused. @@ -4081,6 +4086,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and not self.do_not_remove_slow and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags + and "qBitrr-allow_stalled" not in torrent.tags ): self._process_single_torrent_delete_slow(torrent) # Process uncompleted torrents @@ -4097,6 +4103,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_downloading_state(torrent) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags + and "qBitrr-allow_stalled" not in torrent.tags ): self._process_single_torrent_stalled_torrent(torrent, "Unavailable") else: @@ -4227,7 +4234,7 @@ def custom_format_unmet_check(self, torrent: qbittorrentapi.TorrentDictionary) - except KeyError: pass - def remove_torrent( + def torrent_limit_check( self, torrent: qbittorrentapi.TorrentDictionary, seeding_time_limit, ratio_limit ) -> bool: if ( @@ -4247,6 +4254,12 @@ def remove_torrent( return True elif self.seeding_mode_global_remove_torrent == 1 and torrent.ratio >= ratio_limit: return True + elif ( + self.seeding_mode_global_remove_torrent == -1 + and (torrent.ratio >= ratio_limit + or torrent.seeding_time >= seeding_time_limit) + ): + return True else: return False diff --git a/qBitrr/gen_config.py b/qBitrr/gen_config.py index 83f98465..25bc9e0d 100755 --- a/qBitrr/gen_config.py +++ b/qBitrr/gen_config.py @@ -344,6 +344,8 @@ def _gen_default_torrent_table(category: str, cat_default: Table): 0.99, ) _gen_default_line(torrent_table, "Ignore slow torrents.", "DoNotRemoveSlow", True) + _gen_default_line(torrent_table, "Allow stalled torrents", "AllowStalled", False) + _gen_default_line(torrent_table, "Maximum allowed time for allowed stalled torrents", "StalledDelay", 0) _gen_default_seeding_table(category, torrent_table) _gen_default_tracker_tables(category, torrent_table) From f48d18461e9d5640f45c9f2fe0091af96174d583 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:00:24 +0000 Subject: [PATCH 003/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/arss.py | 18 +++++------------- qBitrr/gen_config.py | 4 +++- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 1be59f7e..80f10e53 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -491,12 +491,7 @@ def __init__( self.search_api_command = "MissingEpisodeSearch" self.manager.qbit_manager.client.torrents_create_tags( - [ - "qBitrr-allowed_seeding", - "qBitrr-ignored", - "qBitrr-imported", - "qBitrr-allow_stalled" - ] + ["qBitrr-allowed_seeding", "qBitrr-ignored", "qBitrr-imported", "qBitrr-allow_stalled"] ) self.search_setup_completed = False self.model_file: EpisodeFilesModel | MoviesFilesModel = None @@ -3979,9 +3974,8 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): "qBitrr-free_space_paused", ] ) - if ( - "qBitrr-allow_stalled" in torrent.tags - and torrent.added_on >= int(time.time()+(self.stalled_delay*60)) + if "qBitrr-allow_stalled" in torrent.tags and torrent.added_on >= int( + time.time() + (self.stalled_delay * 60) ): torrent.remove_tags(["qBitrr-allow_stalled"]) if ( @@ -4254,10 +4248,8 @@ def torrent_limit_check( return True elif self.seeding_mode_global_remove_torrent == 1 and torrent.ratio >= ratio_limit: return True - elif ( - self.seeding_mode_global_remove_torrent == -1 - and (torrent.ratio >= ratio_limit - or torrent.seeding_time >= seeding_time_limit) + elif self.seeding_mode_global_remove_torrent == -1 and ( + torrent.ratio >= ratio_limit or torrent.seeding_time >= seeding_time_limit ): return True else: diff --git a/qBitrr/gen_config.py b/qBitrr/gen_config.py index 25bc9e0d..81bebaae 100755 --- a/qBitrr/gen_config.py +++ b/qBitrr/gen_config.py @@ -345,7 +345,9 @@ def _gen_default_torrent_table(category: str, cat_default: Table): ) _gen_default_line(torrent_table, "Ignore slow torrents.", "DoNotRemoveSlow", True) _gen_default_line(torrent_table, "Allow stalled torrents", "AllowStalled", False) - _gen_default_line(torrent_table, "Maximum allowed time for allowed stalled torrents", "StalledDelay", 0) + _gen_default_line( + torrent_table, "Maximum allowed time for allowed stalled torrents", "StalledDelay", 0 + ) _gen_default_seeding_table(category, torrent_table) _gen_default_tracker_tables(category, torrent_table) From 247d777a0ad279037a3367950d12e673652cb7b6 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:05:07 +0200 Subject: [PATCH 004/101] pre-commit fixes --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index f648e954..0b67c446 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -3,4 +3,4 @@ github: [feramance] patreon: qBitrr ko_fi: feramance -custom: [https://www.paypal.me/feramance] +custom: ["https://www.paypal.me/feramance"] \ No newline at end of file From 25dd699e24361fad9ff4e059f9bf2674a8b1e929 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:08:37 +0200 Subject: [PATCH 005/101] Updated branch workflow --- .github/workflows/branch_nightly.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/branch_nightly.yml b/.github/workflows/branch_nightly.yml index ad36b6a9..fb9b2352 100644 --- a/.github/workflows/branch_nightly.yml +++ b/.github/workflows/branch_nightly.yml @@ -3,10 +3,6 @@ name: Branch Nightly on: push: branches: - - v* - - fix* - - dev* - - test* - '!master' defaults: From bcee559f8d7dfd72e4e5f7bf3788e40a481299dd Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:12:05 +0200 Subject: [PATCH 006/101] Pull request checks updates --- .github/workflows/pull_requests.yml | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 328e1ede..145f7de2 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -95,3 +95,56 @@ jobs: name: automated-build-${{ steps.archieve.outputs.NAME }} path: ${{ steps.archieve.outputs.NAME }}.* if-no-files-found: error + docker_image: + name: Build Docker Image + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + if: ${{ ! startsWith(github.event.head_commit.message, '[patch]') && ! startsWith(github.event.head_commit.message, '[minor]') && ! startsWith(github.event.head_commit.message, '[major]') }} + steps: + - id: string + uses: ASzc/change-string-case-action@v6 + with: + string: ${{ github.repository }} + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.ref_name }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Login to Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.REG_TOKEN }} + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: | + feramance/qbitrr + ghcr.io/${{ steps.string.outputs.lowercase }} + tags: | + type=ref,event=pull_request + - name: Build and push Docker images + env: + DOCKER_BUILDKIT: 1 + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max From e5a7a52906254160f0563522464a76521c9c0d7e Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:15:42 +0200 Subject: [PATCH 007/101] PR workflow fixes --- .github/workflows/pull_requests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 145f7de2..9915e871 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -101,7 +101,6 @@ jobs: permissions: packages: write contents: read - if: ${{ ! startsWith(github.event.head_commit.message, '[patch]') && ! startsWith(github.event.head_commit.message, '[minor]') && ! startsWith(github.event.head_commit.message, '[major]') }} steps: - id: string uses: ASzc/change-string-case-action@v6 @@ -135,7 +134,7 @@ jobs: feramance/qbitrr ghcr.io/${{ steps.string.outputs.lowercase }} tags: | - type=ref,event=pull_request + type=ref,event=pr - name: Build and push Docker images env: DOCKER_BUILDKIT: 1 From aaae8d586805de66a600e7a4c6f4571baa5b9f65 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:19:35 +0200 Subject: [PATCH 008/101] More fixes --- .github/workflows/pull_requests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 9915e871..f24a19a5 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -134,7 +134,7 @@ jobs: feramance/qbitrr ghcr.io/${{ steps.string.outputs.lowercase }} tags: | - type=ref,event=pr + type=ref,event=branch - name: Build and push Docker images env: DOCKER_BUILDKIT: 1 From 2197917a7cf8850322295e2a82fafa846fc1ae71 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:23:47 +0200 Subject: [PATCH 009/101] More fixes --- .github/workflows/pull_requests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index f24a19a5..783ca806 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -134,7 +134,7 @@ jobs: feramance/qbitrr ghcr.io/${{ steps.string.outputs.lowercase }} tags: | - type=ref,event=branch + type=raw,value=${{ github.event.pull_request.head.ref }} - name: Build and push Docker images env: DOCKER_BUILDKIT: 1 From 0969478eddc0b34894aa8cf446f125b8f50e34d9 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:27:18 +0200 Subject: [PATCH 010/101] Testing changes --- .github/workflows/pull_requests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 783ca806..ef8b2432 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -109,8 +109,8 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - fetch-depth: 0 - ref: ${{ github.ref_name }} + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx @@ -134,7 +134,7 @@ jobs: feramance/qbitrr ghcr.io/${{ steps.string.outputs.lowercase }} tags: | - type=raw,value=${{ github.event.pull_request.head.ref }} + type=ref,event=pr - name: Build and push Docker images env: DOCKER_BUILDKIT: 1 From 42ee765aa479ebb088712d5fcba5b77d780f91af Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:50:29 +0200 Subject: [PATCH 011/101] Set stalled delay to be actionable if config is set to a value above 0 --- .github/workflows/pull_requests.yml | 2 ++ qBitrr/arss.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index ef8b2432..655abbac 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -24,7 +24,9 @@ jobs: os: - windows-latest - ubuntu-latest + - macOS-latest arch: + - arm64 - x64 steps: - name: Checkout code diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 80f10e53..9e0a6b4c 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3974,8 +3974,10 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): "qBitrr-free_space_paused", ] ) - if "qBitrr-allow_stalled" in torrent.tags and torrent.added_on >= int( - time.time() + (self.stalled_delay * 60) + if ( + "qBitrr-allow_stalled" in torrent.tags + and self.stalled_delay > 0 + and torrent.added_on >= int(time.time() + (self.stalled_delay * 60)) ): torrent.remove_tags(["qBitrr-allow_stalled"]) if ( From 324db4bfa0a8ebb4614a0aa7c7b44a8431f32bcf Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:58:45 +0200 Subject: [PATCH 012/101] Workflow fixes --- .github/workflows/branch_nightly.yml | 1 + .github/workflows/pull_requests.yml | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/workflows/branch_nightly.yml b/.github/workflows/branch_nightly.yml index fb9b2352..17a8b558 100644 --- a/.github/workflows/branch_nightly.yml +++ b/.github/workflows/branch_nightly.yml @@ -3,6 +3,7 @@ name: Branch Nightly on: push: branches: + - '*' - '!master' defaults: diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 655abbac..84fdbeed 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -23,11 +23,23 @@ jobs: - '3.10' os: - windows-latest - - ubuntu-latest - macOS-latest + - ubuntu-latest arch: - - arm64 + - x86 - x64 + - arm64 + exclude: + - os: ubuntu-latest + arch: x86 + - os: ubuntu-latest + arch: arm64 + - os: macOS-latest + arch: x64 + - os: macOS-latest + arch: x86 + - os: windows-latest + arch: arm64 steps: - name: Checkout code uses: actions/checkout@v4 From 11cf6fde6d82cae2f5dea39b4b751195d5339b04 Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 26 Jun 2024 10:10:42 +0200 Subject: [PATCH 013/101] Updated tag name --- qBitrr/arss.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 9e0a6b4c..eceb1e1f 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -223,7 +223,7 @@ def __init__( ) self.do_not_remove_slow = CONFIG.get(f"{name}.Torrent.DoNotRemoveSlow", fallback=False) - self.allow_stalled = CONFIG.get(f"{name}.Torrent.AllowStalled", fallback=False) + self.allowed_stalled = CONFIG.get(f"{name}.Torrent.AllowStalled", fallback=False) self.stalled_delay = CONFIG.get(f"{name}.Torrent.StalledDelay", fallback=0) self.search_current_year = None if self.search_in_reverse: @@ -491,7 +491,7 @@ def __init__( self.search_api_command = "MissingEpisodeSearch" self.manager.qbit_manager.client.torrents_create_tags( - ["qBitrr-allowed_seeding", "qBitrr-ignored", "qBitrr-imported", "qBitrr-allow_stalled"] + ["qBitrr-allowed_seeding", "qBitrr-ignored", "qBitrr-imported", "qBitrr-allowed_stalled"] ) self.search_setup_completed = False self.model_file: EpisodeFilesModel | MoviesFilesModel = None @@ -3975,11 +3975,11 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ] ) if ( - "qBitrr-allow_stalled" in torrent.tags + "qBitrr-allowed_stalled" in torrent.tags and self.stalled_delay > 0 and torrent.added_on >= int(time.time() + (self.stalled_delay * 60)) ): - torrent.remove_tags(["qBitrr-allow_stalled"]) + torrent.remove_tags(["qBitrr-allowed_stalled"]) if ( self.custom_format_unmet_search and self.custom_format_unmet_check(torrent) @@ -4005,7 +4005,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allow_stalled" not in torrent.tags + and "qBitrr-allowed_stalled" not in torrent.tags ): self._process_single_torrent_stalled_torrent(torrent, "Stalled State") elif ( @@ -4026,7 +4026,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_complete_state(torrent) is False and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allow_stalled" not in torrent.tags + and "qBitrr-allowed_stalled" not in torrent.tags ) and torrent.hash in self.cleaned_torrents: self._process_single_torrent_percentage_threshold(torrent, maximum_eta) # Resume monitored downloads which have been paused. @@ -4082,7 +4082,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and not self.do_not_remove_slow and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allow_stalled" not in torrent.tags + and "qBitrr-allowed_stalled" not in torrent.tags ): self._process_single_torrent_delete_slow(torrent) # Process uncompleted torrents @@ -4099,7 +4099,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_downloading_state(torrent) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allow_stalled" not in torrent.tags + and "qBitrr-allowed_stalled" not in torrent.tags ): self._process_single_torrent_stalled_torrent(torrent, "Unavailable") else: From 9323b3967daaaf60ccad595d876be3ca99265b50 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 08:11:32 +0000 Subject: [PATCH 014/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/arss.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index eceb1e1f..806e1e3f 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -491,7 +491,12 @@ def __init__( self.search_api_command = "MissingEpisodeSearch" self.manager.qbit_manager.client.torrents_create_tags( - ["qBitrr-allowed_seeding", "qBitrr-ignored", "qBitrr-imported", "qBitrr-allowed_stalled"] + [ + "qBitrr-allowed_seeding", + "qBitrr-ignored", + "qBitrr-imported", + "qBitrr-allowed_stalled", + ] ) self.search_setup_completed = False self.model_file: EpisodeFilesModel | MoviesFilesModel = None From bc4eba8a9d48886ae096ed2a4bf28c4315ae3e1e Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 26 Jun 2024 10:38:02 +0200 Subject: [PATCH 015/101] Update config defaults --- config.example.toml | 8 ++++---- qBitrr/gen_config.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config.example.toml b/config.example.toml index dba9597c..865e661e 100644 --- a/config.example.toml +++ b/config.example.toml @@ -221,7 +221,7 @@ DoNotRemoveSlow = true AllowStalled = false # Maximum allowed time for allowed stalled torrents -StalledDelay = 0 +StalledDelay = -1 [Sonarr-TV.Torrent.SeedingMode] @@ -424,7 +424,7 @@ DoNotRemoveSlow = true AllowStalled = false # Maximum allowed time for allowed stalled torrents -StalledDelay = 0 +StalledDelay = -1 [Sonarr-Anime.Torrent.SeedingMode] @@ -623,7 +623,7 @@ DoNotRemoveSlow = true AllowStalled = false # Maximum allowed time for allowed stalled torrents -StalledDelay = 0 +StalledDelay = -1 [Radarr-1080.Torrent.SeedingMode] @@ -835,7 +835,7 @@ DoNotRemoveSlow = true AllowStalled = false # Maximum allowed time for allowed stalled torrents -StalledDelay = 0 +StalledDelay = -1 [Radarr-4K.Torrent.SeedingMode] diff --git a/qBitrr/gen_config.py b/qBitrr/gen_config.py index 81bebaae..cb649533 100755 --- a/qBitrr/gen_config.py +++ b/qBitrr/gen_config.py @@ -346,7 +346,7 @@ def _gen_default_torrent_table(category: str, cat_default: Table): _gen_default_line(torrent_table, "Ignore slow torrents.", "DoNotRemoveSlow", True) _gen_default_line(torrent_table, "Allow stalled torrents", "AllowStalled", False) _gen_default_line( - torrent_table, "Maximum allowed time for allowed stalled torrents", "StalledDelay", 0 + torrent_table, "Maximum allowed time for allowed stalled torrents", "StalledDelay", -1 ) _gen_default_seeding_table(category, torrent_table) _gen_default_tracker_tables(category, torrent_table) From 1fa2187357ec0267fc644e9437e9af259c4a755b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:10:37 +0000 Subject: [PATCH 016/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/config.py | 4 +--- qBitrr/logger.py | 2 +- qBitrr/tables.py | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/qBitrr/config.py b/qBitrr/config.py index c8dc3b9a..970d831f 100644 --- a/qBitrr/config.py +++ b/qBitrr/config.py @@ -116,9 +116,7 @@ def process_flags() -> argparse.Namespace | bool: RECHECK_CATEGORY = ENVIRO_CONFIG.settings.recheck_category or CONFIG.get( "Settings.RecheckCategory", fallback="recheck" ) -TAGLESS = ENVIRO_CONFIG.settings.tagless or CONFIG.get( - "Settings.Tagless", fallback=False -) +TAGLESS = ENVIRO_CONFIG.settings.tagless or CONFIG.get("Settings.Tagless", fallback=False) CONSOLE_LOGGING_LEVEL_STRING = ENVIRO_CONFIG.settings.console_level or CONFIG.get_or_raise( "Settings.ConsoleLevel" ) diff --git a/qBitrr/logger.py b/qBitrr/logger.py index 4841cb04..15286a26 100644 --- a/qBitrr/logger.py +++ b/qBitrr/logger.py @@ -19,8 +19,8 @@ NO_INTERNET_SLEEP_TIMER, PING_URLS, RECHECK_CATEGORY, - TAGLESS, SEARCH_LOOP_DELAY, + TAGLESS, ) __all__ = ("run_logs",) diff --git a/qBitrr/tables.py b/qBitrr/tables.py index 570aae10..9be146cc 100644 --- a/qBitrr/tables.py +++ b/qBitrr/tables.py @@ -62,6 +62,7 @@ class EpisodeQueueModel(Model): EntryId = IntegerField(unique=True) Completed = BooleanField(default=False) + class TorrentLibrary(Model): Hash = TextField(null=False) AllowedSeeding = BooleanField(default=False) From 1772d2fe1a021b2ef5902a54c7fcdadde2abdc66 Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 26 Jun 2024 13:25:59 +0200 Subject: [PATCH 017/101] Configuring new database for torrents --- qBitrr/arss.py | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 806e1e3f..e7ae0f49 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -38,6 +38,7 @@ PROCESS_ONLY, QBIT_DISABLED, RECHECK_CATEGORY, + TAGLESS, SEARCH_LOOP_DELAY, SEARCH_ONLY, ) @@ -503,7 +504,7 @@ def __init__( self.series_file_model: SeriesFilesModel = None self.model_queue: EpisodeQueueModel | MovieQueueModel = None self.persistent_queue: FilesQueued = None - self.torrent_library: TorrentLibrary = None + self.torrents: TorrentLibrary = None self.logger.hnotice("Starting %s monitor", self._name) @property @@ -577,10 +578,10 @@ def _get_models( ]: if self.type == "sonarr": if self.series_search: - return EpisodeFilesModel, EpisodeQueueModel, SeriesFilesModel - return EpisodeFilesModel, EpisodeQueueModel, None + return EpisodeFilesModel, EpisodeQueueModel, SeriesFilesModel, TorrentLibrary if TAGLESS else None + return EpisodeFilesModel, EpisodeQueueModel, None, TorrentLibrary if TAGLESS else None elif self.type == "radarr": - return MoviesFilesModel, MovieQueueModel, None + return MoviesFilesModel, MovieQueueModel, None, TorrentLibrary if TAGLESS else None else: raise UnhandledError(f"Well you shouldn't have reached here, Arr.type={self.type}") @@ -4413,7 +4414,7 @@ def register_search_mode(self): }, ) - db1, db2, db3 = self._get_models() + db1, db2, db3, db4 = self._get_models() class Files(db1): class Meta: @@ -4439,6 +4440,28 @@ class Meta: else: self.db.create_tables([Files, Queue, PersistingQueue]) + if db4: + + self.torrent_db = SqliteDatabase(None) + self.torrent_db.init( + str(self._app_data_folder.joinpath("torrents.db")), + pragmas={ + "journal_mode": "wal", + "cache_size": -1 * 64000, # 64MB + "foreign_keys": 1, + "ignore_check_constraints": 0, + "synchronous": 0, + }, + ) + + class Torrents(db4): + class Meta: + database = self.torrent_db + + self.torrent_db.connect() + self.torrent_db.create_tables([Torrents]) + self.torrents = Torrents + self.model_file = Files self.model_queue = Queue self.persistent_queue = PersistingQueue From 1bc39d349127262010f6ea3f3a57791ebafb2084 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 11:26:28 +0000 Subject: [PATCH 018/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/arss.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index e7ae0f49..88e43c26 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -38,9 +38,9 @@ PROCESS_ONLY, QBIT_DISABLED, RECHECK_CATEGORY, - TAGLESS, SEARCH_LOOP_DELAY, SEARCH_ONLY, + TAGLESS, ) from qBitrr.errors import ( DelayLoopException, @@ -578,7 +578,12 @@ def _get_models( ]: if self.type == "sonarr": if self.series_search: - return EpisodeFilesModel, EpisodeQueueModel, SeriesFilesModel, TorrentLibrary if TAGLESS else None + return ( + EpisodeFilesModel, + EpisodeQueueModel, + SeriesFilesModel, + TorrentLibrary if TAGLESS else None, + ) return EpisodeFilesModel, EpisodeQueueModel, None, TorrentLibrary if TAGLESS else None elif self.type == "radarr": return MoviesFilesModel, MovieQueueModel, None, TorrentLibrary if TAGLESS else None @@ -4441,7 +4446,6 @@ class Meta: self.db.create_tables([Files, Queue, PersistingQueue]) if db4: - self.torrent_db = SqliteDatabase(None) self.torrent_db.init( str(self._app_data_folder.joinpath("torrents.db")), From 47ea553ce2c11efe80a2fe0d0a76c7635f544cce Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 26 Jun 2024 13:57:35 +0200 Subject: [PATCH 019/101] Tagging fix --- qBitrr/arss.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 88e43c26..a2943366 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -226,6 +226,8 @@ def __init__( self.do_not_remove_slow = CONFIG.get(f"{name}.Torrent.DoNotRemoveSlow", fallback=False) self.allowed_stalled = CONFIG.get(f"{name}.Torrent.AllowStalled", fallback=False) self.stalled_delay = CONFIG.get(f"{name}.Torrent.StalledDelay", fallback=0) + if self.allowed_stalled and self.stalled_delay > 0: + self.stalled_time_out = ExpiringSet(max_age_seconds=self.stalled_delay*60) self.search_current_year = None if self.search_in_reverse: self._delta = 1 @@ -3978,6 +3980,15 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): torrent.state_enum, ) maximum_eta = _tracker_max_eta + + stalled_ignore = False + if self.allowed_stalled and "qBitrr-allowed_stalled" not in torrent.tags: + self.stalled_time_out.add(torrent.hash) + torrent.add_tags(["qBitrr-allowed_stalled"]) + stalled_ignore = True + elif "qBitrr-allowed_stalled" in torrent.tags and torrent.hash in self.stalled_time_out: + stalled_ignore = True + if "qBitrr-ignored" in torrent.tags: torrent.remove_tags( [ @@ -3985,12 +3996,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): "qBitrr-free_space_paused", ] ) - if ( - "qBitrr-allowed_stalled" in torrent.tags - and self.stalled_delay > 0 - and torrent.added_on >= int(time.time() + (self.stalled_delay * 60)) - ): - torrent.remove_tags(["qBitrr-allowed_stalled"]) + if ( self.custom_format_unmet_search and self.custom_format_unmet_check(torrent) @@ -4016,7 +4022,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allowed_stalled" not in torrent.tags + and not stalled_ignore ): self._process_single_torrent_stalled_torrent(torrent, "Stalled State") elif ( @@ -4037,7 +4043,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_complete_state(torrent) is False and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allowed_stalled" not in torrent.tags + and not stalled_ignore ) and torrent.hash in self.cleaned_torrents: self._process_single_torrent_percentage_threshold(torrent, maximum_eta) # Resume monitored downloads which have been paused. @@ -4093,7 +4099,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and not self.do_not_remove_slow and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allowed_stalled" not in torrent.tags + and not stalled_ignore ): self._process_single_torrent_delete_slow(torrent) # Process uncompleted torrents @@ -4110,7 +4116,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_downloading_state(torrent) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allowed_stalled" not in torrent.tags + and not stalled_ignore ): self._process_single_torrent_stalled_torrent(torrent, "Unavailable") else: From af52a47050196d618f67508adc9ff89a8089e830 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:53:53 +0000 Subject: [PATCH 020/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index a2943366..e5504d29 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -227,7 +227,7 @@ def __init__( self.allowed_stalled = CONFIG.get(f"{name}.Torrent.AllowStalled", fallback=False) self.stalled_delay = CONFIG.get(f"{name}.Torrent.StalledDelay", fallback=0) if self.allowed_stalled and self.stalled_delay > 0: - self.stalled_time_out = ExpiringSet(max_age_seconds=self.stalled_delay*60) + self.stalled_time_out = ExpiringSet(max_age_seconds=self.stalled_delay * 60) self.search_current_year = None if self.search_in_reverse: self._delta = 1 From a5c046678de066c7c90329cadc4480ae6ae070f7 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 28 Jun 2024 08:49:06 +0200 Subject: [PATCH 021/101] Config changes --- config.example.toml | 8 ++++---- qBitrr/gen_config.py | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/config.example.toml b/config.example.toml index 865e661e..1eeef9f7 100644 --- a/config.example.toml +++ b/config.example.toml @@ -220,7 +220,7 @@ DoNotRemoveSlow = true # Allow stalled torrents AllowStalled = false -# Maximum allowed time for allowed stalled torrents +# Maximum allowed time for allowed stalled torrents in minutes StalledDelay = -1 @@ -423,7 +423,7 @@ DoNotRemoveSlow = true # Allow stalled torrents AllowStalled = false -# Maximum allowed time for allowed stalled torrents +# Maximum allowed time for allowed stalled torrents in minutes StalledDelay = -1 @@ -622,7 +622,7 @@ DoNotRemoveSlow = true # Allow stalled torrents AllowStalled = false -# Maximum allowed time for allowed stalled torrents +# Maximum allowed time for allowed stalled torrents in minutes StalledDelay = -1 @@ -834,7 +834,7 @@ DoNotRemoveSlow = true # Allow stalled torrents AllowStalled = false -# Maximum allowed time for allowed stalled torrents +# Maximum allowed time for allowed stalled torrents in minutes StalledDelay = -1 diff --git a/qBitrr/gen_config.py b/qBitrr/gen_config.py index cb649533..b3c9e09a 100755 --- a/qBitrr/gen_config.py +++ b/qBitrr/gen_config.py @@ -346,7 +346,10 @@ def _gen_default_torrent_table(category: str, cat_default: Table): _gen_default_line(torrent_table, "Ignore slow torrents.", "DoNotRemoveSlow", True) _gen_default_line(torrent_table, "Allow stalled torrents", "AllowStalled", False) _gen_default_line( - torrent_table, "Maximum allowed time for allowed stalled torrents", "StalledDelay", -1 + torrent_table, + "Maximum allowed time for allowed stalled torrents in minutes", + "StalledDelay", + -1, ) _gen_default_seeding_table(category, torrent_table) _gen_default_tracker_tables(category, torrent_table) From 18ccb6ebfdc26bcfe42de6c743bdbadb125fd34c Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 28 Jun 2024 10:42:56 +0200 Subject: [PATCH 022/101] added stalled check --- qBitrr/arss.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index e5504d29..350ed032 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3982,12 +3982,20 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): maximum_eta = _tracker_max_eta stalled_ignore = False - if self.allowed_stalled and "qBitrr-allowed_stalled" not in torrent.tags: - self.stalled_time_out.add(torrent.hash) - torrent.add_tags(["qBitrr-allowed_stalled"]) - stalled_ignore = True - elif "qBitrr-allowed_stalled" in torrent.tags and torrent.hash in self.stalled_time_out: - stalled_ignore = True + if torrent.state_enum in ( + TorrentStates.METADATA_DOWNLOAD, + TorrentStates.STALLED_DOWNLOAD, + ): + if self.allowed_stalled and "qBitrr-allowed_stalled" not in torrent.tags: + self.stalled_time_out.add(torrent.hash) + torrent.add_tags(["qBitrr-allowed_stalled"]) + stalled_ignore = True + elif ( + "qBitrr-allowed_stalled" in torrent.tags and torrent.hash in self.stalled_time_out + ): + stalled_ignore = True + else: + torrent.remove_tags(["qBitrr-allowed_stalled"]) if "qBitrr-ignored" in torrent.tags: torrent.remove_tags( From 9ceeecdc758939e4b9e5b8874f9eb1c29ddbed42 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 28 Jun 2024 11:06:09 +0200 Subject: [PATCH 023/101] Adjusted torrent delay behaviour --- qBitrr/arss.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 350ed032..1537969d 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -226,8 +226,6 @@ def __init__( self.do_not_remove_slow = CONFIG.get(f"{name}.Torrent.DoNotRemoveSlow", fallback=False) self.allowed_stalled = CONFIG.get(f"{name}.Torrent.AllowStalled", fallback=False) self.stalled_delay = CONFIG.get(f"{name}.Torrent.StalledDelay", fallback=0) - if self.allowed_stalled and self.stalled_delay > 0: - self.stalled_time_out = ExpiringSet(max_age_seconds=self.stalled_delay * 60) self.search_current_year = None if self.search_in_reverse: self._delta = 1 @@ -3986,14 +3984,23 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): TorrentStates.METADATA_DOWNLOAD, TorrentStates.STALLED_DOWNLOAD, ): - if self.allowed_stalled and "qBitrr-allowed_stalled" not in torrent.tags: - self.stalled_time_out.add(torrent.hash) - torrent.add_tags(["qBitrr-allowed_stalled"]) - stalled_ignore = True - elif ( - "qBitrr-allowed_stalled" in torrent.tags and torrent.hash in self.stalled_time_out - ): - stalled_ignore = True + if self.allowed_stalled: + self.logger.trace( + "Stalled check: %s [Current:%s][Added:%s][Limit:%s]", + torrent.name, + time.time(), + torrent.added_on, + time.time() + timedelta(minutes=self.stalled_delay), + ) + if self.stalled_delay > 0 and torrent.added_on >= time.time() + timedelta( + minutes=self.stalled_delay + ): + stalled_ignore = False + elif "qBitrr-allowed_stalled" not in torrent.tags: + torrent.add_tags(["qBitrr-allowed_stalled"]) + stalled_ignore = True + elif "qBitrr-allowed_stalled" in torrent.tags: + stalled_ignore = True else: torrent.remove_tags(["qBitrr-allowed_stalled"]) From ff2d0f08e108d6507dcba707e439c71a74fd87f1 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 28 Jun 2024 11:14:17 +0200 Subject: [PATCH 024/101] Updated conditions --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 1537969d..e22dd652 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4001,7 +4001,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): stalled_ignore = True elif "qBitrr-allowed_stalled" in torrent.tags: stalled_ignore = True - else: + elif "qBitrr-allowed_stalled" in torrent.tags: torrent.remove_tags(["qBitrr-allowed_stalled"]) if "qBitrr-ignored" in torrent.tags: From 94d0f8be3d0a0e8d12cce6a66dbd2e5fa5fed74a Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 28 Jun 2024 11:41:57 +0200 Subject: [PATCH 025/101] Variable type fix --- qBitrr/arss.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index e22dd652..3e611a54 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3980,9 +3980,13 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): maximum_eta = _tracker_max_eta stalled_ignore = False - if torrent.state_enum in ( - TorrentStates.METADATA_DOWNLOAD, - TorrentStates.STALLED_DOWNLOAD, + if ( + torrent.state_enum + in ( + TorrentStates.METADATA_DOWNLOAD, + TorrentStates.STALLED_DOWNLOAD, + ) + or torrent.availability < 1 ): if self.allowed_stalled: self.logger.trace( @@ -3992,8 +3996,10 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): torrent.added_on, time.time() + timedelta(minutes=self.stalled_delay), ) - if self.stalled_delay > 0 and torrent.added_on >= time.time() + timedelta( - minutes=self.stalled_delay + if ( + self.stalled_delay > 0 + and torrent.added_on + >= time.time() + timedelta(minutes=self.stalled_delay).seconds ): stalled_ignore = False elif "qBitrr-allowed_stalled" not in torrent.tags: From 7241b299a6d397a27ae21dcc57f089ccde2e852c Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 28 Jun 2024 11:45:17 +0200 Subject: [PATCH 026/101] Error fix --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 3e611a54..85c7a708 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3994,7 +3994,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): torrent.name, time.time(), torrent.added_on, - time.time() + timedelta(minutes=self.stalled_delay), + time.time() + timedelta(minutes=self.stalled_delay).seconds, ) if ( self.stalled_delay > 0 From 027903492510767836ba2e7406f2c8fa18c5b5d3 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 28 Jun 2024 11:55:19 +0200 Subject: [PATCH 027/101] Fixed delay condition --- qBitrr/arss.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 85c7a708..fb1af191 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3994,12 +3994,12 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): torrent.name, time.time(), torrent.added_on, - time.time() + timedelta(minutes=self.stalled_delay).seconds, + torrent.added_on + timedelta(minutes=self.stalled_delay).seconds, ) if ( self.stalled_delay > 0 - and torrent.added_on - >= time.time() + timedelta(minutes=self.stalled_delay).seconds + and time.time() + >= torrent.added_on + timedelta(minutes=self.stalled_delay).seconds ): stalled_ignore = False elif "qBitrr-allowed_stalled" not in torrent.tags: From 72ee376d3bfeb013d9eb403a4f5d5eff52974d09 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 28 Jun 2024 11:56:41 +0200 Subject: [PATCH 028/101] Updated logging --- qBitrr/arss.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index fb1af191..5e81d2da 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3992,9 +3992,11 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): self.logger.trace( "Stalled check: %s [Current:%s][Added:%s][Limit:%s]", torrent.name, - time.time(), - torrent.added_on, - torrent.added_on + timedelta(minutes=self.stalled_delay).seconds, + datetime.fromtimestamp(time.time()), + datetime.fromtimestamp(torrent.added_on), + datetime.fromtimestamp( + torrent.added_on + timedelta(minutes=self.stalled_delay).seconds + ), ) if ( self.stalled_delay > 0 From d62c77737e1cb4b15b4d5c29b6597f6e4399636d Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 28 Jun 2024 12:06:35 +0200 Subject: [PATCH 029/101] Upload check --- qBitrr/arss.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 5e81d2da..9a0ac544 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3980,14 +3980,10 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): maximum_eta = _tracker_max_eta stalled_ignore = False - if ( - torrent.state_enum - in ( - TorrentStates.METADATA_DOWNLOAD, - TorrentStates.STALLED_DOWNLOAD, - ) - or torrent.availability < 1 - ): + if torrent.state_enum in ( + TorrentStates.METADATA_DOWNLOAD, + TorrentStates.STALLED_DOWNLOAD, + ) or (torrent.availability < 1 and not self.is_uploading_state(torrent)): if self.allowed_stalled: self.logger.trace( "Stalled check: %s [Current:%s][Added:%s][Limit:%s]", From b9931fbb3f6f3fb16a58ac82eac9cdb1afc4e059 Mon Sep 17 00:00:00 2001 From: Feramance Date: Sat, 29 Jun 2024 13:07:28 +0200 Subject: [PATCH 030/101] Stalled changes --- qBitrr/arss.py | 71 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 9a0ac544..9b6e4f8c 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3980,33 +3980,60 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): maximum_eta = _tracker_max_eta stalled_ignore = False - if torrent.state_enum in ( - TorrentStates.METADATA_DOWNLOAD, - TorrentStates.STALLED_DOWNLOAD, - ) or (torrent.availability < 1 and not self.is_uploading_state(torrent)): - if self.allowed_stalled: + self.logger.trace( + "Stalled check: %s [Current:%s][Added:%s][Limit:%s]", + torrent.name, + datetime.fromtimestamp(time.time()), + datetime.fromtimestamp(torrent.added_on), + datetime.fromtimestamp( + torrent.added_on + timedelta(minutes=self.stalled_delay).seconds + ), + ) + if ( + torrent.state_enum + in ( + TorrentStates.METADATA_DOWNLOAD, + TorrentStates.STALLED_DOWNLOAD, + ) + or ( + torrent.availability < 1 + and not self.is_uploading_state(torrent) + and torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD + ) + ) and self.allowed_stalled: + if ( + self.stalled_delay > 0 + and time.time() >= torrent.added_on + timedelta(minutes=self.stalled_delay).seconds + ): + stalled_ignore = False self.logger.trace( - "Stalled check: %s [Current:%s][Added:%s][Limit:%s]", + "Process stalled, delay expired: %s", + torrent.name, + ) + elif "qBitrr-allowed_stalled" not in torrent.tags: + torrent.add_tags(["qBitrr-allowed_stalled"]) + stalled_ignore = True + self.logger.trace( + "Stalled, adding tag: %s", + torrent.name, + ) + elif "qBitrr-allowed_stalled" in torrent.tags: + stalled_ignore = True + self.logger.trace( + "Stalled: %s", torrent.name, - datetime.fromtimestamp(time.time()), - datetime.fromtimestamp(torrent.added_on), - datetime.fromtimestamp( - torrent.added_on + timedelta(minutes=self.stalled_delay).seconds - ), ) - if ( - self.stalled_delay > 0 - and time.time() - >= torrent.added_on + timedelta(minutes=self.stalled_delay).seconds - ): - stalled_ignore = False - elif "qBitrr-allowed_stalled" not in torrent.tags: - torrent.add_tags(["qBitrr-allowed_stalled"]) - stalled_ignore = True - elif "qBitrr-allowed_stalled" in torrent.tags: - stalled_ignore = True elif "qBitrr-allowed_stalled" in torrent.tags: torrent.remove_tags(["qBitrr-allowed_stalled"]) + self.logger.trace( + "Not stalled: %s", + torrent.name, + ) + else: + self.logger.trace( + "Not stalled: %s", + torrent.name, + ) if "qBitrr-ignored" in torrent.tags: torrent.remove_tags( From 12fa2bfc95aaf21f1d3540f67a8321c23cb16974 Mon Sep 17 00:00:00 2001 From: Feramance Date: Sat, 29 Jun 2024 20:49:46 +0200 Subject: [PATCH 031/101] Log updates --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 9b6e4f8c..df067de3 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4026,7 +4026,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): elif "qBitrr-allowed_stalled" in torrent.tags: torrent.remove_tags(["qBitrr-allowed_stalled"]) self.logger.trace( - "Not stalled: %s", + "Not stalled, removing tag: %s", torrent.name, ) else: From 7d08fd5abda4a55e6fde52ff3b3df546e2588cd7 Mon Sep 17 00:00:00 2001 From: Feramance Date: Sat, 29 Jun 2024 20:58:02 +0200 Subject: [PATCH 032/101] Free space logs adjustement --- qBitrr/arss.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index df067de3..f28a6225 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5098,7 +5098,9 @@ def _process_single_torrent(self, torrent): if self.is_downloading_state(torrent): free_space_test = self.current_free_space free_space_test -= torrent["amount_left"] - self.logger.trace("Resulting free space: %s", free_space_test) + self.logger.trace( + "Resulting free space: %s -> %s", self.current_free_space, free_space_test + ) if ( torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and self.current_free_space < torrent["amount_left"] @@ -5112,7 +5114,9 @@ def _process_single_torrent(self, torrent): and self.current_free_space > torrent["amount_left"] ): self.current_free_space = free_space_test - self.logger.trace("Can download: Free space %s", self.current_free_space) + self.logger.trace( + "Can download: Free space %s -> %s", self.current_free_space, free_space_test + ) torrent.remove_tags(tags=["qBitrr-free_space_paused"]) elif not self.is_downloading_state(torrent) and "qBitrr-free_space_paused" in torrent.tags: self.logger.trace( From a0151b1398d8a0c975484bd3e30bb694d932f3aa Mon Sep 17 00:00:00 2001 From: Feramance Date: Sun, 30 Jun 2024 13:41:59 +0200 Subject: [PATCH 033/101] Stalled updates --- qBitrr/arss.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index f28a6225..5ef8142b 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3979,7 +3979,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) maximum_eta = _tracker_max_eta - stalled_ignore = False + stalled_ignore = True self.logger.trace( "Stalled check: %s [Current:%s][Added:%s][Limit:%s]", torrent.name, @@ -3990,15 +3990,25 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ), ) if ( - torrent.state_enum - in ( - TorrentStates.METADATA_DOWNLOAD, - TorrentStates.STALLED_DOWNLOAD, + ( + torrent.state_enum + in ( + TorrentStates.METADATA_DOWNLOAD, + TorrentStates.STALLED_DOWNLOAD, + ) + and "qBitrr-ignored" not in torrent.tags + and "qBitrr-free_space_paused" not in torrent.tags ) or ( - torrent.availability < 1 - and not self.is_uploading_state(torrent) - and torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD + ( + self.recently_queue.get(torrent.hash, torrent.added_on) + < time_now - self.ignore_torrents_younger_than + and torrent.availability < 1 + ) + and torrent.hash in self.cleaned_torrents + and self.is_downloading_state(torrent) + and "qBitrr-ignored" not in torrent.tags + and "qBitrr-free_space_paused" not in torrent.tags ) ) and self.allowed_stalled: if ( @@ -4012,24 +4022,24 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) elif "qBitrr-allowed_stalled" not in torrent.tags: torrent.add_tags(["qBitrr-allowed_stalled"]) - stalled_ignore = True self.logger.trace( "Stalled, adding tag: %s", torrent.name, ) elif "qBitrr-allowed_stalled" in torrent.tags: - stalled_ignore = True self.logger.trace( "Stalled: %s", torrent.name, ) elif "qBitrr-allowed_stalled" in torrent.tags: torrent.remove_tags(["qBitrr-allowed_stalled"]) + stalled_ignore = False self.logger.trace( "Not stalled, removing tag: %s", torrent.name, ) else: + stalled_ignore = False self.logger.trace( "Not stalled: %s", torrent.name, From 793eb546689f323301fdd5b8ee240d7caace3beb Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 12:51:01 +0200 Subject: [PATCH 034/101] Allow list changes --- qBitrr/arss.py | 60 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 5ef8142b..45984df0 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -129,20 +129,21 @@ def __init__( self.rss_sync_timer = CONFIG.get(f"{name}.RssSyncTimer", fallback=15) self.case_sensitive_matches = CONFIG.get( - f"{name}.Torrent.CaseSensitiveMatches", fallback=[] + f"{name}.Torrent.CaseSensitiveMatches", fallback=False ) self.folder_exclusion_regex = CONFIG.get( - f"{name}.Torrent.FolderExclusionRegex", fallback=[] + f"{name}.Torrent.FolderExclusionRegex", fallback=None ) self.file_name_exclusion_regex = CONFIG.get( - f"{name}.Torrent.FileNameExclusionRegex", fallback=[] + f"{name}.Torrent.FileNameExclusionRegex", fallback=None ) self.file_extension_allowlist = CONFIG.get( - f"{name}.Torrent.FileExtensionAllowlist", fallback=[] + f"{name}.Torrent.FileExtensionAllowlist", fallback=None ) - self.file_extension_allowlist = [ - rf"\{ext}" if ext[:1] != "\\" else ext for ext in self.file_extension_allowlist - ] + if self.file_extension_allowlist: + self.file_extension_allowlist = [ + rf"\{ext}" if ext[:1] != "\\" else ext for ext in self.file_extension_allowlist + ] self.auto_delete = CONFIG.get(f"{name}.Torrent.AutoDelete", fallback=False) self.remove_dead_trackers = CONFIG.get( @@ -276,22 +277,37 @@ def __init__( self.request_search_timer = None if self.case_sensitive_matches: - self.folder_exclusion_regex_re = re.compile( - "|".join(self.folder_exclusion_regex), re.DOTALL + self.folder_exclusion_regex_re = ( + re.compile("|".join(self.folder_exclusion_regex), re.DOTALL) + if self.folder_exclusion_regex_re + else None + ) + self.file_name_exclusion_regex_re = ( + re.compile("|".join(self.file_name_exclusion_regex), re.DOTALL) + if self.file_name_exclusion_regex_re + else None ) - self.file_name_exclusion_regex_re = re.compile( - "|".join(self.file_name_exclusion_regex), re.DOTALL + self.file_extension_allowlist = ( + re.compile("|".join(self.file_extension_allowlist), re.DOTALL) + if self.file_extension_allowlist + else None ) else: - self.folder_exclusion_regex_re = re.compile( - "|".join(self.folder_exclusion_regex), re.IGNORECASE | re.DOTALL + self.folder_exclusion_regex_re = ( + re.compile("|".join(self.folder_exclusion_regex), re.IGNORECASE | re.DOTALL) + if self.folder_exclusion_regex_re + else None ) - self.file_name_exclusion_regex_re = re.compile( - "|".join(self.file_name_exclusion_regex), re.IGNORECASE | re.DOTALL + self.file_name_exclusion_regex_re = ( + re.compile("|".join(self.file_name_exclusion_regex), re.IGNORECASE | re.DOTALL) + if self.file_name_exclusion_regex_re + else None + ) + self.file_extension_allowlist = ( + re.compile("|".join(self.file_extension_allowlist), re.IGNORECASE | re.DOTALL) + if self.file_extension_allowlist + else None ) - self.file_extension_allowlist = re.compile( - "|".join(self.file_extension_allowlist), re.DOTALL - ) self.client = client_cls(host_url=self.uri, api_key=self.apikey) if isinstance(self.client, SonarrAPI): self.type = "sonarr" @@ -2710,7 +2726,11 @@ def folder_cleanup(self, downloads_id: str | None, folder: pathlib.Path): if self.file_is_probeable(file): self.logger.trace("Folder Cleanup: File is a valid media type: %s", file) probeable += 1 - + if not self.file_extension_allowlist: + self.logger.trace("Folder Cleanup: File has an allowed extension: %s", file) + if self.file_is_probeable(file): + self.logger.trace("Folder Cleanup: File is a valid media type: %s", file) + probeable += 1 else: invalid_files.add(file) @@ -4425,7 +4445,7 @@ def _update_bad_queue_items(self): if _m in self.arr_error_codes_to_blocklist: e = entry.get("downloadId") _path_filter.add((e, pathlib.Path(output_path).joinpath(title))) - # self.downloads_with_bad_error_message_blocklist.add(e) + self.downloads_with_bad_error_message_blocklist.add(e) if len(_path_filter): self.needs_cleanup = True self.files_to_explicitly_delete = iter(_path_filter.copy()) From c122001015f4ce0a9b18a7402c0e901d28792c90 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 13:01:25 +0200 Subject: [PATCH 035/101] Quick fix --- qBitrr/arss.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 45984df0..d31df14d 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -279,15 +279,15 @@ def __init__( if self.case_sensitive_matches: self.folder_exclusion_regex_re = ( re.compile("|".join(self.folder_exclusion_regex), re.DOTALL) - if self.folder_exclusion_regex_re + if self.folder_exclusion_regex else None ) self.file_name_exclusion_regex_re = ( re.compile("|".join(self.file_name_exclusion_regex), re.DOTALL) - if self.file_name_exclusion_regex_re + if self.file_name_exclusion_regex else None ) - self.file_extension_allowlist = ( + self.file_extension_allowlist_re = ( re.compile("|".join(self.file_extension_allowlist), re.DOTALL) if self.file_extension_allowlist else None @@ -295,15 +295,15 @@ def __init__( else: self.folder_exclusion_regex_re = ( re.compile("|".join(self.folder_exclusion_regex), re.IGNORECASE | re.DOTALL) - if self.folder_exclusion_regex_re + if self.folder_exclusion_regex else None ) self.file_name_exclusion_regex_re = ( re.compile("|".join(self.file_name_exclusion_regex), re.IGNORECASE | re.DOTALL) - if self.file_name_exclusion_regex_re + if self.file_name_exclusion_regex else None ) - self.file_extension_allowlist = ( + self.file_extension_allowlist_re = ( re.compile("|".join(self.file_extension_allowlist), re.IGNORECASE | re.DOTALL) if self.file_extension_allowlist else None @@ -2719,14 +2719,14 @@ def folder_cleanup(self, downloads_id: str | None, folder: pathlib.Path): if file.is_dir(): self.logger.trace("Folder Cleanup: File is a folder: %s", file) continue - if self.file_extension_allowlist and ( - (match := self.file_extension_allowlist.search(file.suffix)) and match.group() + if self.file_extension_allowlist_re and ( + (match := self.file_extension_allowlist_re.search(file.suffix)) and match.group() ): self.logger.trace("Folder Cleanup: File has an allowed extension: %s", file) if self.file_is_probeable(file): self.logger.trace("Folder Cleanup: File is a valid media type: %s", file) probeable += 1 - if not self.file_extension_allowlist: + if not self.file_extension_allowlist_re: self.logger.trace("Folder Cleanup: File has an allowed extension: %s", file) if self.file_is_probeable(file): self.logger.trace("Folder Cleanup: File is a valid media type: %s", file) @@ -3612,8 +3612,9 @@ def _process_single_torrent_process_files( ) _remove_files.add(file.id) total -= 1 - elif self.file_extension_allowlist and not ( - (match := self.file_extension_allowlist.search(file_path.suffix)) and match.group() + elif self.file_extension_allowlist_re and not ( + (match := self.file_extension_allowlist_re.search(file_path.suffix)) + and match.group() ): self.logger.debug( "Removing File: Not allowed | Extension: %s | %s (%s) | %s ", From 41a45f65be0e54265c56211b5601462b200be234 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 13:10:37 +0200 Subject: [PATCH 036/101] Move new stalled logic to function --- qBitrr/arss.py | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index d31df14d..52547e3c 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3984,27 +3984,12 @@ def _process_single_torrent_trackers(self, torrent: qbittorrentapi.TorrentDictio if add_tags: torrent.add_tags(add_tags) - def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): - if torrent.category != RECHECK_CATEGORY: - self.manager.qbit_manager.cache[torrent.hash] = torrent.category - self._process_single_torrent_trackers(torrent) - self.manager.qbit_manager.name_cache[torrent.hash] = torrent.name - time_now = time.time() - leave_alone, _tracker_max_eta, remove_torrent = self._should_leave_alone(torrent) - self.logger.trace( - "Torrent [%s]: Leave Alone (allow seeding): %s, Max ETA: %s, State[%s]", - torrent.name, - leave_alone, - _tracker_max_eta, - torrent.state_enum, - ) - maximum_eta = _tracker_max_eta - + def stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: float) -> bool: stalled_ignore = True self.logger.trace( "Stalled check: %s [Current:%s][Added:%s][Limit:%s]", torrent.name, - datetime.fromtimestamp(time.time()), + datetime.fromtimestamp(time_now), datetime.fromtimestamp(torrent.added_on), datetime.fromtimestamp( torrent.added_on + timedelta(minutes=self.stalled_delay).seconds @@ -4034,7 +4019,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and self.allowed_stalled: if ( self.stalled_delay > 0 - and time.time() >= torrent.added_on + timedelta(minutes=self.stalled_delay).seconds + and time_now >= torrent.added_on + timedelta(minutes=self.stalled_delay).seconds ): stalled_ignore = False self.logger.trace( @@ -4065,6 +4050,25 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): "Not stalled: %s", torrent.name, ) + return stalled_ignore + + def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): + if torrent.category != RECHECK_CATEGORY: + self.manager.qbit_manager.cache[torrent.hash] = torrent.category + self._process_single_torrent_trackers(torrent) + self.manager.qbit_manager.name_cache[torrent.hash] = torrent.name + time_now = time.time() + leave_alone, _tracker_max_eta, remove_torrent = self._should_leave_alone(torrent) + self.logger.trace( + "Torrent [%s]: Leave Alone (allow seeding): %s, Max ETA: %s, State[%s]", + torrent.name, + leave_alone, + _tracker_max_eta, + torrent.state_enum, + ) + maximum_eta = _tracker_max_eta + + stalled_ignore = self.stalled_check(torrent, time_now) if "qBitrr-ignored" in torrent.tags: torrent.remove_tags( From c04cfd7adc3ad7ee9814196626f69142c8ec0546 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 13:19:59 +0200 Subject: [PATCH 037/101] Removed redundant log --- qBitrr/arss.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 52547e3c..d3a7eca0 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -1232,7 +1232,6 @@ def db_get_files( elif self.type == "radarr": movielist = self.db_get_files_movies() for movies in movielist: - self.logger.trace("Movielist") yield movies[0], movies[1], movies[2], False, len(movielist) def db_maybe_reset_entry_searched_state(self): From 114c158299a0519bf84cb290bc254ad8d49c89eb Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 15:24:39 +0200 Subject: [PATCH 038/101] Free space adjustment --- qBitrr/arss.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index d3a7eca0..5d5d108d 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5133,13 +5133,21 @@ def _process_single_torrent(self, torrent): free_space_test = self.current_free_space free_space_test -= torrent["amount_left"] self.logger.trace( - "Resulting free space: %s -> %s", self.current_free_space, free_space_test + "Result[%s]: Free space %s -> %s", + torrent.name, + self.current_free_space, + free_space_test, ) if ( torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and self.current_free_space < torrent["amount_left"] ): - self.logger.trace("Pause download: Free space %s", self.current_free_space) + self.logger.trace( + "Pause download[%s]: Free space %s -> %s", + torrent.name, + self.current_free_space, + free_space_test, + ) torrent.add_tags(tags=["qBitrr-free_space_paused"]) torrent.remove_tags(tags=["qBitrr-allowed_seeding"]) self._process_single_torrent_pause_disk_space(torrent) @@ -5149,14 +5157,25 @@ def _process_single_torrent(self, torrent): ): self.current_free_space = free_space_test self.logger.trace( - "Can download: Free space %s -> %s", self.current_free_space, free_space_test + "Can download[%s]: Free space %s -> %s", + torrent.name, + self.current_free_space, + free_space_test, ) torrent.remove_tags(tags=["qBitrr-free_space_paused"]) + else: + self.current_free_space = free_space_test + self.logger.trace( + "Downloading[%s]: Free space %s -> %s", + torrent.name, + self.current_free_space, + free_space_test, + ) elif not self.is_downloading_state(torrent) and "qBitrr-free_space_paused" in torrent.tags: self.logger.trace( "Removing tag[%s] for completed torrent[%s]: Free space %s", "qBitrr-free_space_paused", - torrent, + torrent.name, self.current_free_space, ) torrent.remove_tags(tags=["qBitrr-free_space_paused"]) From 115ea00a6d3cc60d6554092a16b2c826316d446d Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 15:32:48 +0200 Subject: [PATCH 039/101] Hotfix --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 5d5d108d..8db7d76a 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5163,7 +5163,7 @@ def _process_single_torrent(self, torrent): free_space_test, ) torrent.remove_tags(tags=["qBitrr-free_space_paused"]) - else: + elif torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD: self.current_free_space = free_space_test self.logger.trace( "Downloading[%s]: Free space %s -> %s", From 387a41716a3dc3011aa709b90b33379d1437a76a Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 15:36:14 +0200 Subject: [PATCH 040/101] Hotfix 2 --- qBitrr/arss.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 8db7d76a..bf4cca9e 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5157,20 +5157,21 @@ def _process_single_torrent(self, torrent): ): self.current_free_space = free_space_test self.logger.trace( - "Can download[%s]: Free space %s -> %s", + "Unpause download[%s]: Free space %s -> %s", torrent.name, self.current_free_space, free_space_test, ) torrent.remove_tags(tags=["qBitrr-free_space_paused"]) - elif torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD: + elif torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and free_space_test > 0: self.current_free_space = free_space_test self.logger.trace( - "Downloading[%s]: Free space %s -> %s", + "Continue downloading[%s]: Free space %s -> %s", torrent.name, self.current_free_space, free_space_test, ) + torrent.remove_tags(tags=["qBitrr-free_space_paused"]) elif not self.is_downloading_state(torrent) and "qBitrr-free_space_paused" in torrent.tags: self.logger.trace( "Removing tag[%s] for completed torrent[%s]: Free space %s", From 273c587bfed21be1ce7a4368f1f6bab12b653cf3 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 15:40:07 +0200 Subject: [PATCH 041/101] Logging adjustments --- qBitrr/arss.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index bf4cca9e..844136eb 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5143,7 +5143,7 @@ def _process_single_torrent(self, torrent): and self.current_free_space < torrent["amount_left"] ): self.logger.trace( - "Pause download[%s]: Free space %s -> %s", + "Pause download [%s]: Free space %s -> %s", torrent.name, self.current_free_space, free_space_test, @@ -5157,7 +5157,7 @@ def _process_single_torrent(self, torrent): ): self.current_free_space = free_space_test self.logger.trace( - "Unpause download[%s]: Free space %s -> %s", + "Unpause download [%s]: Free space %s -> %s", torrent.name, self.current_free_space, free_space_test, @@ -5166,7 +5166,7 @@ def _process_single_torrent(self, torrent): elif torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and free_space_test > 0: self.current_free_space = free_space_test self.logger.trace( - "Continue downloading[%s]: Free space %s -> %s", + "Continue downloading [%s]: Free space %s -> %s", torrent.name, self.current_free_space, free_space_test, @@ -5174,7 +5174,7 @@ def _process_single_torrent(self, torrent): torrent.remove_tags(tags=["qBitrr-free_space_paused"]) elif not self.is_downloading_state(torrent) and "qBitrr-free_space_paused" in torrent.tags: self.logger.trace( - "Removing tag[%s] for completed torrent[%s]: Free space %s", + "Removing tag [%s] for completed torrent[%s]: Free space %s", "qBitrr-free_space_paused", torrent.name, self.current_free_space, From 6abfbec2de34b6de579e56450d64807679968ec1 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 15:41:11 +0200 Subject: [PATCH 042/101] Changed function name --- qBitrr/arss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 844136eb..613cca79 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3983,7 +3983,7 @@ def _process_single_torrent_trackers(self, torrent: qbittorrentapi.TorrentDictio if add_tags: torrent.add_tags(add_tags) - def stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: float) -> bool: + def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: float) -> bool: stalled_ignore = True self.logger.trace( "Stalled check: %s [Current:%s][Added:%s][Limit:%s]", @@ -4067,7 +4067,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) maximum_eta = _tracker_max_eta - stalled_ignore = self.stalled_check(torrent, time_now) + stalled_ignore = self._stalled_check(torrent, time_now) if "qBitrr-ignored" in torrent.tags: torrent.remove_tags( From d860c43b971146018201de439fa905dc71f85fdf Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 15:46:48 +0200 Subject: [PATCH 043/101] Missed a log change and updated log levels --- qBitrr/arss.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 613cca79..25975adb 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5133,7 +5133,7 @@ def _process_single_torrent(self, torrent): free_space_test = self.current_free_space free_space_test -= torrent["amount_left"] self.logger.trace( - "Result[%s]: Free space %s -> %s", + "Result [%s]: Free space %s -> %s", torrent.name, self.current_free_space, free_space_test, @@ -5142,7 +5142,7 @@ def _process_single_torrent(self, torrent): torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and self.current_free_space < torrent["amount_left"] ): - self.logger.trace( + self.logger.info( "Pause download [%s]: Free space %s -> %s", torrent.name, self.current_free_space, @@ -5156,7 +5156,7 @@ def _process_single_torrent(self, torrent): and self.current_free_space > torrent["amount_left"] ): self.current_free_space = free_space_test - self.logger.trace( + self.logger.info( "Unpause download [%s]: Free space %s -> %s", torrent.name, self.current_free_space, @@ -5165,7 +5165,7 @@ def _process_single_torrent(self, torrent): torrent.remove_tags(tags=["qBitrr-free_space_paused"]) elif torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and free_space_test > 0: self.current_free_space = free_space_test - self.logger.trace( + self.logger.info( "Continue downloading [%s]: Free space %s -> %s", torrent.name, self.current_free_space, @@ -5173,7 +5173,7 @@ def _process_single_torrent(self, torrent): ) torrent.remove_tags(tags=["qBitrr-free_space_paused"]) elif not self.is_downloading_state(torrent) and "qBitrr-free_space_paused" in torrent.tags: - self.logger.trace( + self.logger.info( "Removing tag [%s] for completed torrent[%s]: Free space %s", "qBitrr-free_space_paused", torrent.name, From ec063f1ade1886c6329d8479918dea05a9ddf4ef Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 16:10:50 +0200 Subject: [PATCH 044/101] Moved logs --- qBitrr/arss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 25975adb..e59165c2 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5155,22 +5155,22 @@ def _process_single_torrent(self, torrent): torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD and self.current_free_space > torrent["amount_left"] ): - self.current_free_space = free_space_test self.logger.info( "Unpause download [%s]: Free space %s -> %s", torrent.name, self.current_free_space, free_space_test, ) + self.current_free_space = free_space_test torrent.remove_tags(tags=["qBitrr-free_space_paused"]) elif torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and free_space_test > 0: - self.current_free_space = free_space_test self.logger.info( "Continue downloading [%s]: Free space %s -> %s", torrent.name, self.current_free_space, free_space_test, ) + self.current_free_space = free_space_test torrent.remove_tags(tags=["qBitrr-free_space_paused"]) elif not self.is_downloading_state(torrent) and "qBitrr-free_space_paused" in torrent.tags: self.logger.info( From 8c4eaed53829d6d80bf453e6db3431777f7580c7 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 16:12:52 +0200 Subject: [PATCH 045/101] Condition update --- qBitrr/arss.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index e59165c2..b3d0b754 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5138,9 +5138,8 @@ def _process_single_torrent(self, torrent): self.current_free_space, free_space_test, ) - if ( - torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD - and self.current_free_space < torrent["amount_left"] + if torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and ( + self.current_free_space < torrent["amount_left"] or free_space_test < 0 ): self.logger.info( "Pause download [%s]: Free space %s -> %s", From 356717f550cc233132f39daa8ce22fc015ac58b1 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 16:24:37 +0200 Subject: [PATCH 046/101] Further free space adjustments --- qBitrr/arss.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index b3d0b754..e32ebe15 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5138,8 +5138,9 @@ def _process_single_torrent(self, torrent): self.current_free_space, free_space_test, ) - if torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and ( - self.current_free_space < torrent["amount_left"] or free_space_test < 0 + if ( + torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD + and self.current_free_space < torrent["amount_left"] ): self.logger.info( "Pause download [%s]: Free space %s -> %s", @@ -5150,18 +5151,15 @@ def _process_single_torrent(self, torrent): torrent.add_tags(tags=["qBitrr-free_space_paused"]) torrent.remove_tags(tags=["qBitrr-allowed_seeding"]) self._process_single_torrent_pause_disk_space(torrent) - elif ( - torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD - and self.current_free_space > torrent["amount_left"] - ): + elif torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD and free_space_test < 0: self.logger.info( - "Unpause download [%s]: Free space %s -> %s", + "Leave paused [%s]: Free space %s -> %s", torrent.name, self.current_free_space, free_space_test, ) - self.current_free_space = free_space_test - torrent.remove_tags(tags=["qBitrr-free_space_paused"]) + torrent.add_tags(tags=["qBitrr-free_space_paused"]) + torrent.remove_tags(tags=["qBitrr-allowed_seeding"]) elif torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and free_space_test > 0: self.logger.info( "Continue downloading [%s]: Free space %s -> %s", @@ -5171,6 +5169,18 @@ def _process_single_torrent(self, torrent): ) self.current_free_space = free_space_test torrent.remove_tags(tags=["qBitrr-free_space_paused"]) + elif ( + torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD + and self.current_free_space > torrent["amount_left"] + ): + self.logger.info( + "Unpause download [%s]: Free space %s -> %s", + torrent.name, + self.current_free_space, + free_space_test, + ) + self.current_free_space = free_space_test + torrent.remove_tags(tags=["qBitrr-free_space_paused"]) elif not self.is_downloading_state(torrent) and "qBitrr-free_space_paused" in torrent.tags: self.logger.info( "Removing tag [%s] for completed torrent[%s]: Free space %s", From b9da42923848f8ca774941b7e1ecfc19655d41b1 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 16:38:46 +0200 Subject: [PATCH 047/101] File handling fixes --- qBitrr/arss.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index e32ebe15..d85cfbac 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -2718,14 +2718,14 @@ def folder_cleanup(self, downloads_id: str | None, folder: pathlib.Path): if file.is_dir(): self.logger.trace("Folder Cleanup: File is a folder: %s", file) continue - if self.file_extension_allowlist_re and ( + if self.file_extension_allowlist and ( (match := self.file_extension_allowlist_re.search(file.suffix)) and match.group() ): self.logger.trace("Folder Cleanup: File has an allowed extension: %s", file) if self.file_is_probeable(file): self.logger.trace("Folder Cleanup: File is a valid media type: %s", file) probeable += 1 - if not self.file_extension_allowlist_re: + if not self.file_extension_allowlist: self.logger.trace("Folder Cleanup: File has an allowed extension: %s", file) if self.file_is_probeable(file): self.logger.trace("Folder Cleanup: File is a valid media type: %s", file) @@ -3611,7 +3611,7 @@ def _process_single_torrent_process_files( ) _remove_files.add(file.id) total -= 1 - elif self.file_extension_allowlist_re and not ( + elif self.file_extension_allowlist and not ( (match := self.file_extension_allowlist_re.search(file_path.suffix)) and match.group() ): From a5bc8f52de9d0ccc7b53caccb4a6edee8ab18945 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 16:41:43 +0200 Subject: [PATCH 048/101] Quick fix file handling --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index d85cfbac..2b6bf086 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -2725,7 +2725,7 @@ def folder_cleanup(self, downloads_id: str | None, folder: pathlib.Path): if self.file_is_probeable(file): self.logger.trace("Folder Cleanup: File is a valid media type: %s", file) probeable += 1 - if not self.file_extension_allowlist: + elif not self.file_extension_allowlist: self.logger.trace("Folder Cleanup: File has an allowed extension: %s", file) if self.file_is_probeable(file): self.logger.trace("Folder Cleanup: File is a valid media type: %s", file) From 5227eab92d007232f41885b898bccf1dc47ac7c2 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 1 Jul 2024 17:14:57 +0200 Subject: [PATCH 049/101] Changed up config attributes and added initial changes for re-searching functionality --- config.example.toml | 24 ++++++++++++------------ qBitrr/arss.py | 35 ++++++++++++++++++++++++----------- qBitrr/gen_config.py | 4 ++-- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/config.example.toml b/config.example.toml index 1eeef9f7..3d74c2a0 100644 --- a/config.example.toml +++ b/config.example.toml @@ -217,10 +217,10 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true -# Allow stalled torrents -AllowStalled = false +# Re-search stalled torrents +ReSearchStalled = false -# Maximum allowed time for allowed stalled torrents in minutes +# Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite) StalledDelay = -1 @@ -420,10 +420,10 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true -# Allow stalled torrents -AllowStalled = false +# Re-search stalled torrents +ReSearchStalled = false -# Maximum allowed time for allowed stalled torrents in minutes +# Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite) StalledDelay = -1 @@ -619,10 +619,10 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true -# Allow stalled torrents -AllowStalled = false +# Re-search stalled torrents +ReSearchStalled = false -# Maximum allowed time for allowed stalled torrents in minutes +# Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite) StalledDelay = -1 @@ -831,10 +831,10 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true -# Allow stalled torrents -AllowStalled = false +# Re-search stalled torrents +ReSearchStalled = false -# Maximum allowed time for allowed stalled torrents in minutes +# Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite) StalledDelay = -1 diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 2b6bf086..9be50576 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -225,8 +225,10 @@ def __init__( ) self.do_not_remove_slow = CONFIG.get(f"{name}.Torrent.DoNotRemoveSlow", fallback=False) - self.allowed_stalled = CONFIG.get(f"{name}.Torrent.AllowStalled", fallback=False) + self.re_search_stalled = CONFIG.get(f"{name}.Torrent.ReSearchStalled", fallback=False) self.stalled_delay = CONFIG.get(f"{name}.Torrent.StalledDelay", fallback=0) + self.allowed_stalled = True if self.stalled_delay != -1 else False + self.search_current_year = None if self.search_in_reverse: self._delta = 1 @@ -855,16 +857,19 @@ def _process_imports(self) -> None: self.sent_to_scan.add(path) self.import_torrents.clear() - def _process_failed_individual(self, hash_: str, entry: int, skip_blacklist: set[str]) -> None: - if hash_ not in skip_blacklist: - self.logger.debug( - "Blocklisting: %s (%s)", - hash_, - self.manager.qbit_manager.name_cache.get(hash_, "Deleted"), - ) - self.delete_from_queue(id_=entry, blacklist=True) - else: - self.delete_from_queue(id_=entry, blacklist=False) + def _process_failed_individual( + self, hash_: str, entry: int, skip_blacklist: set[str], stalled: bool = False + ) -> None: + if not stalled: + if hash_ not in skip_blacklist: + self.logger.debug( + "Blocklisting: %s (%s)", + hash_, + self.manager.qbit_manager.name_cache.get(hash_, "Deleted"), + ) + self.delete_from_queue(id_=entry, blacklist=True) + else: + self.delete_from_queue(id_=entry, blacklist=False) if hash_ in self.recently_queue: del self.recently_queue[hash_] object_id = self.requeue_cache.get(entry) @@ -4077,6 +4082,14 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ] ) + if "qBitrr-allowed_stalled" in torrent.tags and self.re_search_stalled: + payload = self.process_entries([torrent.hash]) + if payload: + for entry, hash_ in payload: + self._process_failed_individual( + hash_=hash_, entry=entry, skip_blacklist=set(), stalled=True + ) + if ( self.custom_format_unmet_search and self.custom_format_unmet_check(torrent) diff --git a/qBitrr/gen_config.py b/qBitrr/gen_config.py index b3c9e09a..64ca8d2a 100755 --- a/qBitrr/gen_config.py +++ b/qBitrr/gen_config.py @@ -344,10 +344,10 @@ def _gen_default_torrent_table(category: str, cat_default: Table): 0.99, ) _gen_default_line(torrent_table, "Ignore slow torrents.", "DoNotRemoveSlow", True) - _gen_default_line(torrent_table, "Allow stalled torrents", "AllowStalled", False) + _gen_default_line(torrent_table, "Re-search stalled torrents", "ReSearchStalled", False) _gen_default_line( torrent_table, - "Maximum allowed time for allowed stalled torrents in minutes", + "Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite)", "StalledDelay", -1, ) From 36c68de159f93cd381b80eb55c68538613884867 Mon Sep 17 00:00:00 2001 From: Feramance Date: Tue, 2 Jul 2024 09:02:16 +0200 Subject: [PATCH 050/101] Updated blocklisting for stalled torrents, and added config for auto pause resume --- config.example.toml | 5 ++++- qBitrr/arss.py | 16 +++++++++++++--- qBitrr/config.py | 9 +++++++-- qBitrr/env_config.py | 1 + qBitrr/gen_config.py | 8 +++++++- qBitrr/logger.py | 6 +++++- 6 files changed, 37 insertions(+), 8 deletions(-) diff --git a/config.example.toml b/config.example.toml index 3d74c2a0..81361253 100644 --- a/config.example.toml +++ b/config.example.toml @@ -12,7 +12,7 @@ Logging = true # Folder where your completed downloads are put into. Can be found in qBitTorrent -> Options -> Downloads -> Default Save Path (Please note, replace all '\' with '/') CompletedDownloadFolder = "CHANGE_ME" -#The desired amount of free space in the downloads directory [K=kilobytes, M=megabytes, G=gigabytes, T=terabytes] (set to -1 to disable) +#The desired amount of free space in the downloads directory [K=kilobytes, M=megabytes, G=gigabytes, T=terabytes] (set to -1 to disable, this bypasses AutoPauseResume) FreeSpace = "-1" # Time to sleep for if there is no internet (in seconds: 600 = 10 Minutes) @@ -24,6 +24,9 @@ LoopSleepTimer = 5 # Time to sleep between posting search commands (in seconds: 600 = 10 Minutes) SearchLoopDelay = -1 +# Enable automation of pausing and resuming torrents as needed +AutoPauseResume = true + # Add torrents to this category to mark them as failed FailedCategory = "failed" diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 9be50576..bbe8e407 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -28,6 +28,7 @@ from qBitrr.config import ( APPDATA_FOLDER, + AUTO_PAUSE_RESUME, COMPLETED_DOWNLOAD_FOLDER, CONFIG, ENABLE_LOGS, @@ -768,7 +769,7 @@ def _process_ombi_requests(self) -> dict[str, set[str, int]]: def _process_paused(self) -> None: # Bulks pause all torrents flagged for pausing. - if self.pause: + if self.pause and AUTO_PAUSE_RESUME: self.needs_cleanup = True self.logger.debug("Pausing %s torrents", len(self.pause)) for i in self.pause: @@ -870,6 +871,16 @@ def _process_failed_individual( self.delete_from_queue(id_=entry, blacklist=True) else: self.delete_from_queue(id_=entry, blacklist=False) + else: + if hash_ not in skip_blacklist: + self.logger.debug( + "Blocklisting: %s (%s)", + hash_, + self.manager.qbit_manager.name_cache.get(hash_, "Blocklisted"), + ) + self.delete_from_queue(id_=entry, remove_from_client=False, blacklist=True) + else: + self.delete_from_queue(id_=entry, remove_from_client=False, blacklist=False) if hash_ in self.recently_queue: del self.recently_queue[hash_] object_id = self.requeue_cache.get(entry) @@ -1111,7 +1122,7 @@ def _process_file_priority(self) -> None: del self.change_priority[hash_] def _process_resume(self) -> None: - if self.resume: + if self.resume and AUTO_PAUSE_RESUME: self.needs_cleanup = True self.manager.qbit.torrents_resume(torrent_hashes=self.resume) for k in self.resume: @@ -3423,7 +3434,6 @@ def _process_single_torrent_fully_completed_torrent( torrent.name, torrent.hash, ) - # self.pause.add(torrent.hash) content_path = pathlib.Path(torrent.content_path) if content_path.is_dir() and content_path.name == torrent.name: torrent_folder = content_path diff --git a/qBitrr/config.py b/qBitrr/config.py index 970d831f..ab6544ca 100644 --- a/qBitrr/config.py +++ b/qBitrr/config.py @@ -118,9 +118,11 @@ def process_flags() -> argparse.Namespace | bool: ) TAGLESS = ENVIRO_CONFIG.settings.tagless or CONFIG.get("Settings.Tagless", fallback=False) CONSOLE_LOGGING_LEVEL_STRING = ENVIRO_CONFIG.settings.console_level or CONFIG.get_or_raise( - "Settings.ConsoleLevel" + "Settings.ConsoleLevel", fallback="INFO" +) +ENABLE_LOGS = ENVIRO_CONFIG.settings.logging or CONFIG.get_or_raise( + "Settings.Logging", fallback=True ) -ENABLE_LOGS = ENVIRO_CONFIG.settings.logging or CONFIG.get_or_raise("Settings.Logging") COMPLETED_DOWNLOAD_FOLDER = ( ENVIRO_CONFIG.settings.completed_download_folder or CONFIG.get_or_raise("Settings.CompletedDownloadFolder") @@ -135,6 +137,9 @@ def process_flags() -> argparse.Namespace | bool: SEARCH_LOOP_DELAY = ENVIRO_CONFIG.settings.search_loop_delay or CONFIG.get( "Settings.SearchLoopDelay", fallback=-1 ) +AUTO_PAUSE_RESUME = ENVIRO_CONFIG.settings.auto_pause_resume or CONFIG.get_or_raise( + "Settings.AutoPauseResume", fallback=True +) PING_URLS = ENVIRO_CONFIG.settings.ping_urls or CONFIG.get( "Settings.PingURLS", fallback=["one.one.one.one", "dns.google.com"] ) diff --git a/qBitrr/env_config.py b/qBitrr/env_config.py index 5ae5cd7e..34c5eb0b 100644 --- a/qBitrr/env_config.py +++ b/qBitrr/env_config.py @@ -35,6 +35,7 @@ class Settings: no_internet_sleep_timer = environ.var(None, converter=Converter.int) loop_sleep_timer = environ.var(None, converter=Converter.int) search_loop_delay = environ.var(None, converter=Converter.int) + auto_pause_resume = environ.var(None, converter=Converter.bool) failed_category = environ.var(None) recheck_category = environ.var(None) tagless = environ.var(None, converter=Converter.bool) diff --git a/qBitrr/gen_config.py b/qBitrr/gen_config.py index 64ca8d2a..49dba26f 100755 --- a/qBitrr/gen_config.py +++ b/qBitrr/gen_config.py @@ -52,7 +52,7 @@ def _add_settings_section(config: TOMLDocument): ) _gen_default_line( settings, - "The desired amount of free space in the downloads directory [K=kilobytes, M=megabytes, G=gigabytes, T=terabytes] (set to -1 to disable)", + "The desired amount of free space in the downloads directory [K=kilobytes, M=megabytes, G=gigabytes, T=terabytes] (set to -1 to disable, this bypasses AutoPauseResume)", "FreeSpace", ENVIRO_CONFIG.settings.free_space or "-1", ) @@ -74,6 +74,12 @@ def _add_settings_section(config: TOMLDocument): "SearchLoopDelay", ENVIRO_CONFIG.settings.search_loop_delay or -1, ) + _gen_default_line( + settings, + "Enable automation of pausing and resuming torrents as needed", + "AutoPauseResume", + ENVIRO_CONFIG.settings.auto_pause_resume or True, + ) _gen_default_line( settings, "Add torrents to this category to mark them as failed", diff --git a/qBitrr/logger.py b/qBitrr/logger.py index 15286a26..a988e65d 100644 --- a/qBitrr/logger.py +++ b/qBitrr/logger.py @@ -7,10 +7,12 @@ import coloredlogs from qBitrr.config import ( + AUTO_PAUSE_RESUME, COMPLETED_DOWNLOAD_FOLDER, CONFIG, CONSOLE_LOGGING_LEVEL_STRING, COPIED_TO_NEW_DIR, + ENABLE_LOGS, FAILED_CATEGORY, FREE_SPACE, HOME_PATH, @@ -124,13 +126,15 @@ def run_logs(logger: Logger) -> None: def log_Debugs(logger): logger.debug("Log Level: %s", CONSOLE_LOGGING_LEVEL_STRING) logger.debug("Ping URLs: %s", PING_URLS) + logger.debug("Script Config: Logging=%s", ENABLE_LOGS) logger.debug("Script Config: FailedCategory=%s", FAILED_CATEGORY) logger.debug("Script Config: RecheckCategory=%s", RECHECK_CATEGORY) logger.debug("Script Config: Tagless=%s", TAGLESS) logger.debug("Script Config: CompletedDownloadFolder=%s", COMPLETED_DOWNLOAD_FOLDER) logger.debug("Script Config: FreeSpace=%s", FREE_SPACE) logger.debug("Script Config: LoopSleepTimer=%s", LOOP_SLEEP_TIMER) - logger.debug("Script Config: LoopSleepTimer=%s", SEARCH_LOOP_DELAY) + logger.debug("Script Config: SearchLoopDelay=%s", SEARCH_LOOP_DELAY) + logger.debug("Script Config: AutoPauseResume=%s", AUTO_PAUSE_RESUME) logger.debug( "Script Config: NoInternetSleepTimer=%s", NO_INTERNET_SLEEP_TIMER, From 6031cd74783adb1d96227b6c07c1727e35152aac Mon Sep 17 00:00:00 2001 From: Feramance Date: Tue, 2 Jul 2024 09:17:50 +0200 Subject: [PATCH 051/101] Hot fix --- qBitrr/config.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/qBitrr/config.py b/qBitrr/config.py index ab6544ca..f61d3925 100644 --- a/qBitrr/config.py +++ b/qBitrr/config.py @@ -117,12 +117,10 @@ def process_flags() -> argparse.Namespace | bool: "Settings.RecheckCategory", fallback="recheck" ) TAGLESS = ENVIRO_CONFIG.settings.tagless or CONFIG.get("Settings.Tagless", fallback=False) -CONSOLE_LOGGING_LEVEL_STRING = ENVIRO_CONFIG.settings.console_level or CONFIG.get_or_raise( +CONSOLE_LOGGING_LEVEL_STRING = ENVIRO_CONFIG.settings.console_level or CONFIG.get( "Settings.ConsoleLevel", fallback="INFO" ) -ENABLE_LOGS = ENVIRO_CONFIG.settings.logging or CONFIG.get_or_raise( - "Settings.Logging", fallback=True -) +ENABLE_LOGS = ENVIRO_CONFIG.settings.logging or CONFIG.get("Settings.Logging", fallback=True) COMPLETED_DOWNLOAD_FOLDER = ( ENVIRO_CONFIG.settings.completed_download_folder or CONFIG.get_or_raise("Settings.CompletedDownloadFolder") @@ -137,7 +135,7 @@ def process_flags() -> argparse.Namespace | bool: SEARCH_LOOP_DELAY = ENVIRO_CONFIG.settings.search_loop_delay or CONFIG.get( "Settings.SearchLoopDelay", fallback=-1 ) -AUTO_PAUSE_RESUME = ENVIRO_CONFIG.settings.auto_pause_resume or CONFIG.get_or_raise( +AUTO_PAUSE_RESUME = ENVIRO_CONFIG.settings.auto_pause_resume or CONFIG.get( "Settings.AutoPauseResume", fallback=True ) PING_URLS = ENVIRO_CONFIG.settings.ping_urls or CONFIG.get( From 5e1dc55f10bcf17d5031b7b548de537c675bfbc9 Mon Sep 17 00:00:00 2001 From: Feramance Date: Tue, 2 Jul 2024 11:32:25 +0200 Subject: [PATCH 052/101] Re-search and blocklist stalled update --- qBitrr/arss.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index bbe8e407..1d2d7f5d 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4042,15 +4042,28 @@ def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: fl ) elif "qBitrr-allowed_stalled" not in torrent.tags: torrent.add_tags(["qBitrr-allowed_stalled"]) - self.logger.trace( - "Stalled, adding tag: %s", - torrent.name, - ) + if self.re_search_stalled: + payload = self.process_entries([torrent.hash]) + if payload: + for entry, hash_ in payload: + self._process_failed_individual( + hash_=hash_, entry=entry, skip_blacklist=set(), stalled=True + ) + self.logger.trace( + "Stalled, adding tag, blocklosting and re-searching: %s", + torrent.name, + ) + else: + self.logger.trace( + "Stalled, adding tag: %s", + torrent.name, + ) elif "qBitrr-allowed_stalled" in torrent.tags: self.logger.trace( "Stalled: %s", torrent.name, ) + elif "qBitrr-allowed_stalled" in torrent.tags: torrent.remove_tags(["qBitrr-allowed_stalled"]) stalled_ignore = False @@ -4092,14 +4105,6 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ] ) - if "qBitrr-allowed_stalled" in torrent.tags and self.re_search_stalled: - payload = self.process_entries([torrent.hash]) - if payload: - for entry, hash_ in payload: - self._process_failed_individual( - hash_=hash_, entry=entry, skip_blacklist=set(), stalled=True - ) - if ( self.custom_format_unmet_search and self.custom_format_unmet_check(torrent) From f7876cbf9bf9513eafd1c892f09c3e867a7db27c Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 3 Jul 2024 10:14:25 +0200 Subject: [PATCH 053/101] Updated config order and description --- config.example.toml | 6 +++--- qBitrr/gen_config.py | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/config.example.toml b/config.example.toml index 81361253..bd8bed95 100644 --- a/config.example.toml +++ b/config.example.toml @@ -15,6 +15,9 @@ CompletedDownloadFolder = "CHANGE_ME" #The desired amount of free space in the downloads directory [K=kilobytes, M=megabytes, G=gigabytes, T=terabytes] (set to -1 to disable, this bypasses AutoPauseResume) FreeSpace = "-1" +# Enable automation of pausing and resuming torrents as needed (Required enabled for the FreeSpace logic to function) +AutoPauseResume = true + # Time to sleep for if there is no internet (in seconds: 600 = 10 Minutes) NoInternetSleepTimer = 15 @@ -24,9 +27,6 @@ LoopSleepTimer = 5 # Time to sleep between posting search commands (in seconds: 600 = 10 Minutes) SearchLoopDelay = -1 -# Enable automation of pausing and resuming torrents as needed -AutoPauseResume = true - # Add torrents to this category to mark them as failed FailedCategory = "failed" diff --git a/qBitrr/gen_config.py b/qBitrr/gen_config.py index 49dba26f..0d9e1015 100755 --- a/qBitrr/gen_config.py +++ b/qBitrr/gen_config.py @@ -56,6 +56,12 @@ def _add_settings_section(config: TOMLDocument): "FreeSpace", ENVIRO_CONFIG.settings.free_space or "-1", ) + _gen_default_line( + settings, + "Enable automation of pausing and resuming torrents as needed (Required enabled for the FreeSpace logic to function)", + "AutoPauseResume", + ENVIRO_CONFIG.settings.auto_pause_resume or True, + ) _gen_default_line( settings, "Time to sleep for if there is no internet (in seconds: 600 = 10 Minutes)", @@ -74,12 +80,6 @@ def _add_settings_section(config: TOMLDocument): "SearchLoopDelay", ENVIRO_CONFIG.settings.search_loop_delay or -1, ) - _gen_default_line( - settings, - "Enable automation of pausing and resuming torrents as needed", - "AutoPauseResume", - ENVIRO_CONFIG.settings.auto_pause_resume or True, - ) _gen_default_line( settings, "Add torrents to this category to mark them as failed", From 95091e84eb70f561df698290b206fdf691f8ec6a Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 3 Jul 2024 10:55:29 +0200 Subject: [PATCH 054/101] Added auto pause resume check for free space subprocess --- qBitrr/arss.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 1d2d7f5d..2cca707e 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5166,10 +5166,7 @@ def _process_single_torrent(self, torrent): self.current_free_space, free_space_test, ) - if ( - torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD - and self.current_free_space < torrent["amount_left"] - ): + if torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and free_space_test < 0: self.logger.info( "Pause download [%s]: Free space %s -> %s", torrent.name, @@ -5197,10 +5194,7 @@ def _process_single_torrent(self, torrent): ) self.current_free_space = free_space_test torrent.remove_tags(tags=["qBitrr-free_space_paused"]) - elif ( - torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD - and self.current_free_space > torrent["amount_left"] - ): + elif torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD and free_space_test > 0: self.logger.info( "Unpause download [%s]: Free space %s -> %s", torrent.name, @@ -5331,7 +5325,7 @@ def build_arr_instances(self): continue except (OSError, TypeError) as e: self.logger.exception(e) - if FREE_SPACE != "-1": + if FREE_SPACE != "-1" and AUTO_PAUSE_RESUME: managed_object = FreeSpaceManager(self.arr_categories, self) self.managed_objects["FreeSpaceManager"] = managed_object for cat in self.special_categories: From 71e9e578592156a0f08edce6184488d0c0fbd6d6 Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 3 Jul 2024 13:28:22 +0200 Subject: [PATCH 055/101] Changed logic/logging order --- qBitrr/arss.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 2cca707e..7840e951 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4043,16 +4043,16 @@ def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: fl elif "qBitrr-allowed_stalled" not in torrent.tags: torrent.add_tags(["qBitrr-allowed_stalled"]) if self.re_search_stalled: + self.logger.trace( + "Stalled, adding tag, blocklosting and re-searching: %s", + torrent.name, + ) payload = self.process_entries([torrent.hash]) if payload: for entry, hash_ in payload: self._process_failed_individual( hash_=hash_, entry=entry, skip_blacklist=set(), stalled=True ) - self.logger.trace( - "Stalled, adding tag, blocklosting and re-searching: %s", - torrent.name, - ) else: self.logger.trace( "Stalled, adding tag: %s", From 846f8bdf580482df4a6be56a93fbd5a264cf9e5a Mon Sep 17 00:00:00 2001 From: Feramance Date: Thu, 4 Jul 2024 15:48:18 +0200 Subject: [PATCH 056/101] Adjustmenets for re-searching stalled torrents --- qBitrr/arss.py | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 7840e951..e3bb1b73 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -859,28 +859,21 @@ def _process_imports(self) -> None: self.import_torrents.clear() def _process_failed_individual( - self, hash_: str, entry: int, skip_blacklist: set[str], stalled: bool = False + self, hash_: str, entry: int, skip_blacklist: set[str], remove_from_client: bool = True ) -> None: - if not stalled: - if hash_ not in skip_blacklist: - self.logger.debug( - "Blocklisting: %s (%s)", - hash_, - self.manager.qbit_manager.name_cache.get(hash_, "Deleted"), - ) - self.delete_from_queue(id_=entry, blacklist=True) - else: - self.delete_from_queue(id_=entry, blacklist=False) + if hash_ not in skip_blacklist: + self.logger.debug( + "Blocklisting: %s (%s)", + hash_, + self.manager.qbit_manager.name_cache.get(hash_, "Blocklisted"), + ) + self.delete_from_queue( + id_=entry, remove_from_client=remove_from_client, blacklist=True + ) else: - if hash_ not in skip_blacklist: - self.logger.debug( - "Blocklisting: %s (%s)", - hash_, - self.manager.qbit_manager.name_cache.get(hash_, "Blocklisted"), - ) - self.delete_from_queue(id_=entry, remove_from_client=False, blacklist=True) - else: - self.delete_from_queue(id_=entry, remove_from_client=False, blacklist=False) + self.delete_from_queue( + id_=entry, remove_from_client=remove_from_client, blacklist=False + ) if hash_ in self.recently_queue: del self.recently_queue[hash_] object_id = self.requeue_cache.get(entry) @@ -4051,7 +4044,10 @@ def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: fl if payload: for entry, hash_ in payload: self._process_failed_individual( - hash_=hash_, entry=entry, skip_blacklist=set(), stalled=True + hash_=hash_, + entry=entry, + skip_blacklist=set[str], + remove_from_client=False, ) else: self.logger.trace( From b77fefdc01d99a79bd2073ef1e42929599a9031f Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 5 Jul 2024 08:11:37 +0200 Subject: [PATCH 057/101] Small fixes and logging improvements --- qBitrr/arss.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index e3bb1b73..0626f717 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -1626,10 +1626,10 @@ def _db_request_update(self, request_ids: dict[str, set[int | str]]): continue if not self.search_specials and e["seasonNumber"] == 0: continue - if TvdbIds and TvdbIds and "tvdbId" in e and "imdbId" in e: + if TvdbIds and ImdbIds and "tvdbId" in e and "imdbId" in e: if s["tvdbId"] not in TvdbIds or s["imdbId"] not in ImdbIds: continue - if TvdbIds and "imdbId" in e: + if ImdbIds and "imdbId" in e: if s["imdbId"] not in ImdbIds: continue if TvdbIds and "tvdbId" in e: @@ -1639,6 +1639,7 @@ def _db_request_update(self, request_ids: dict[str, set[int | str]]): continue if e["episodeFileId"] != 0: continue + self.logger.trace("Updating requests") self.db_update_single_series(db_entry=e, request=True) elif self.type == "radarr" and any(i in request_ids for i in ["ImdbId", "TmdbId"]): ImdbIds = request_ids.get("ImdbId") @@ -1671,6 +1672,7 @@ def _db_request_update(self, request_ids: dict[str, set[int | str]]): continue if m["hasFile"]: continue + self.logger.trace("Updating requests") self.db_update_single_series(db_entry=m, request=True) def db_overseerr_update(self): @@ -1735,6 +1737,7 @@ def db_update_todays_releases(self): continue if e["episodeFileId"] != 0: continue + self.logger.trace("Updating todays releases") self.db_update_single_series(db_entry=e) except BaseException: self.logger.debug("No episode releases found for today") From c4d200d1ee3946ef38673cdf861dee7fdd56ba3d Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 26 Jun 2024 10:37:09 +0200 Subject: [PATCH 058/101] Initial changes for tagless operation --- qBitrr/arss.py | 1 - qBitrr/logger.py | 1 + qBitrr/tables.py | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 0626f717..4bb3cc3e 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -523,7 +523,6 @@ def __init__( self.series_file_model: SeriesFilesModel = None self.model_queue: EpisodeQueueModel | MovieQueueModel = None self.persistent_queue: FilesQueued = None - self.torrents: TorrentLibrary = None self.logger.hnotice("Starting %s monitor", self._name) @property diff --git a/qBitrr/logger.py b/qBitrr/logger.py index a988e65d..ff311010 100644 --- a/qBitrr/logger.py +++ b/qBitrr/logger.py @@ -21,6 +21,7 @@ NO_INTERNET_SLEEP_TIMER, PING_URLS, RECHECK_CATEGORY, + TAGLESS, SEARCH_LOOP_DELAY, TAGLESS, ) diff --git a/qBitrr/tables.py b/qBitrr/tables.py index 9be146cc..570aae10 100644 --- a/qBitrr/tables.py +++ b/qBitrr/tables.py @@ -62,7 +62,6 @@ class EpisodeQueueModel(Model): EntryId = IntegerField(unique=True) Completed = BooleanField(default=False) - class TorrentLibrary(Model): Hash = TextField(null=False) AllowedSeeding = BooleanField(default=False) From 0f126ef999347d59800c023802bf6f30d1862dc1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:10:37 +0000 Subject: [PATCH 059/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/logger.py | 1 - qBitrr/tables.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/logger.py b/qBitrr/logger.py index ff311010..a988e65d 100644 --- a/qBitrr/logger.py +++ b/qBitrr/logger.py @@ -21,7 +21,6 @@ NO_INTERNET_SLEEP_TIMER, PING_URLS, RECHECK_CATEGORY, - TAGLESS, SEARCH_LOOP_DELAY, TAGLESS, ) diff --git a/qBitrr/tables.py b/qBitrr/tables.py index 570aae10..9be146cc 100644 --- a/qBitrr/tables.py +++ b/qBitrr/tables.py @@ -62,6 +62,7 @@ class EpisodeQueueModel(Model): EntryId = IntegerField(unique=True) Completed = BooleanField(default=False) + class TorrentLibrary(Model): Hash = TextField(null=False) AllowedSeeding = BooleanField(default=False) From 7f79c7171d2d45a0d8c614a03cb7f7dba7aa84ba Mon Sep 17 00:00:00 2001 From: Feramance Date: Tue, 9 Jul 2024 08:08:36 +0200 Subject: [PATCH 060/101] check for qbit disabled --- qBitrr/arss.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index a4069e6a..acaf6a23 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -510,14 +510,15 @@ def __init__( else: self.search_api_command = "MissingEpisodeSearch" - self.manager.qbit_manager.client.torrents_create_tags( - [ - "qBitrr-allowed_seeding", - "qBitrr-ignored", - "qBitrr-imported", - "qBitrr-allowed_stalled", - ] - ) + if not QBIT_DISABLED: + self.manager.qbit_manager.client.torrents_create_tags( + [ + "qBitrr-allowed_seeding", + "qBitrr-ignored", + "qBitrr-imported", + "qBitrr-allowed_stalled", + ] + ) self.search_setup_completed = False self.model_file: EpisodeFilesModel | MoviesFilesModel = None self.series_file_model: SeriesFilesModel = None From 6fe1a8efcf6e55eea20a06bca5ad47e04f158dd9 Mon Sep 17 00:00:00 2001 From: Feramance <38938175+Feramance@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:10:24 +0200 Subject: [PATCH 061/101] Update arss.py Signed-off-by: Feramance <38938175+Feramance@users.noreply.github.com> --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index acaf6a23..c79cf58f 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -516,7 +516,7 @@ def __init__( "qBitrr-allowed_seeding", "qBitrr-ignored", "qBitrr-imported", - "qBitrr-allowed_stalled", + "qBitrr-allowed_stalled" ] ) self.search_setup_completed = False From 2d759a842881c570c3ee57cfbb3a9758428da70b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 17:11:12 +0000 Subject: [PATCH 062/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index c79cf58f..acaf6a23 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -516,7 +516,7 @@ def __init__( "qBitrr-allowed_seeding", "qBitrr-ignored", "qBitrr-imported", - "qBitrr-allowed_stalled" + "qBitrr-allowed_stalled", ] ) self.search_setup_completed = False From 251e2e19bbdbbf563165df1ba5af6307b1581679 Mon Sep 17 00:00:00 2001 From: Shaun Agius Date: Tue, 9 Jul 2024 18:04:39 +0000 Subject: [PATCH 063/101] [skip ci]Automated version bump: v >> v4.8.2 --- .bumpversion.cfg | 2 +- Dockerfile | 2 +- pyproject.toml | 2 +- qBitrr/bundled_data.py | 2 +- setup.cfg | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 4d368c24..fa5e86a9 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 4.8.1 +current_version = 4.8.2 tag = false parse = (?P\d+)\.(?P\d+)\.(?P\d+) serialize = diff --git a/Dockerfile b/Dockerfile index c120c123..697648ea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ FROM python:3.10 LABEL Name="qBitrr" LABEL Maintainer="feramance" -LABEL Version="4.8.1" +LABEL Version="4.8.2" LABEL org.opencontainers.image.source=https://github.com/feramance/qbitrr # Env used by the script to determine if its inside a docker - diff --git a/pyproject.toml b/pyproject.toml index effb4100..46506aa6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ target-version = ['py38'] [tool.poetry] name = "pypi-public" -version = "4.8.1" +version = "4.8.2" description = "A simple script to monitor qBit and communicate with Radarr and Sonarr" authors = ["Drapersniper", "Feramance"] readme = "README.md" diff --git a/qBitrr/bundled_data.py b/qBitrr/bundled_data.py index b766070b..d86e2acf 100644 --- a/qBitrr/bundled_data.py +++ b/qBitrr/bundled_data.py @@ -1,4 +1,4 @@ -version = "4.8.1" +version = "4.8.2" git_hash = "9b49d6b" license_text = ( "Licence can be found on:\n\nhttps://github.com/Feramance/qBitrr/blob/master/LICENSE" diff --git a/setup.cfg b/setup.cfg index 664d5da4..48b7d128 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = qBitrr2 -version = 4.8.1 +version = 4.8.2 description = "A simple Python script to talk to qBittorrent and Arr's" long_description = file: README.md long_description_content_type = text/markdown From 7cc07097e4e3ced8d2bbeff634c3a6660b43be5d Mon Sep 17 00:00:00 2001 From: Shaun Agius Date: Tue, 9 Jul 2024 18:05:31 +0000 Subject: [PATCH 064/101] [skip ci] Update Release Hash for v4.8.2 --- qBitrr/bundled_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/bundled_data.py b/qBitrr/bundled_data.py index d86e2acf..c27099fb 100644 --- a/qBitrr/bundled_data.py +++ b/qBitrr/bundled_data.py @@ -1,5 +1,5 @@ version = "4.8.2" -git_hash = "9b49d6b" +git_hash = "4dd76a7" license_text = ( "Licence can be found on:\n\nhttps://github.com/Feramance/qBitrr/blob/master/LICENSE" ) From 73592060efd73a6128662e21b325a8d4ba5ccbb0 Mon Sep 17 00:00:00 2001 From: Shaun Agius Date: Tue, 9 Jul 2024 18:08:06 +0000 Subject: [PATCH 065/101] [skip ci] Update CHANGELOG.md and Release Notes for v4.8.2 --- CHANGELOG.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e83f934b..f378d4d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## v4.8.2 (09/07/2024) +- [[patch] Merge pull request #94 from Feramance/92-container-keeps-crashing-attributeerror-nonetype-object-has-no-attribute-torrents_create_tags](https://github.com/Feramance/qBitrr/commit/284a33c3ab1565d65956f7ae0886b5009812b619) - @Feramance +- [Update arss.py](https://github.com/Feramance/qBitrr/commit/af01f5b1edc0f3a042a1f9f686fc859b386dd199) - @Feramance +- [Merge branch 'master' of https://github.com/Feramance/Qbitrr into 92-container-keeps-crashing-attributeerror-nonetype-object-has-no-attribute-torrents_create_tags](https://github.com/Feramance/qBitrr/commit/59e52f79587c19bfc98d7a0388b3376562c4bd98) - @Feramance + +--- + ## v4.8.1 (09/07/2024) - [[patch] pull request #91 from Feramance/90-native-apple-silicon-support-docker](https://github.com/Feramance/qBitrr/commit/04e6f8261308729a69bd30359b6f67fadcbe0745) - @Feramance - [Fixed stalled re-search type error](https://github.com/Feramance/qBitrr/commit/7c0dbfbcb0788ad9f9984ffa8ef88c8cf6dfb092) - @Feramance @@ -244,8 +251,3 @@ ## v4.5.7 (01/05/2024) - [[patch] Spelling mistake](https://github.com/Feramance/qBitrr/commit/f64e5143d71f822d7847350749c36a3502010e4c) - @Feramance - ---- - -## v4.5.6 (01/05/2024) -- [[patch] Hopefully last binary build fix](https://github.com/Feramance/qBitrr/commit/25a7404732a4f095bb16535c1350ac7da22c8af8) - @Feramance From 387fd82507db9cda8dc851e6c60ffb2d56aa1820 Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 26 Jun 2024 10:37:09 +0200 Subject: [PATCH 066/101] Initial changes for tagless operation --- qBitrr/arss.py | 1 + qBitrr/logger.py | 1 + qBitrr/tables.py | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index acaf6a23..9648fc3a 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -524,6 +524,7 @@ def __init__( self.series_file_model: SeriesFilesModel = None self.model_queue: EpisodeQueueModel | MovieQueueModel = None self.persistent_queue: FilesQueued = None + self.torrent_library: TorrentLibrary = None self.logger.hnotice("Starting %s monitor", self._name) @property diff --git a/qBitrr/logger.py b/qBitrr/logger.py index a988e65d..ff311010 100644 --- a/qBitrr/logger.py +++ b/qBitrr/logger.py @@ -21,6 +21,7 @@ NO_INTERNET_SLEEP_TIMER, PING_URLS, RECHECK_CATEGORY, + TAGLESS, SEARCH_LOOP_DELAY, TAGLESS, ) diff --git a/qBitrr/tables.py b/qBitrr/tables.py index 9be146cc..570aae10 100644 --- a/qBitrr/tables.py +++ b/qBitrr/tables.py @@ -62,7 +62,6 @@ class EpisodeQueueModel(Model): EntryId = IntegerField(unique=True) Completed = BooleanField(default=False) - class TorrentLibrary(Model): Hash = TextField(null=False) AllowedSeeding = BooleanField(default=False) From 89424d524a121c079086ae68b7dcb5d52a0fb838 Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 13:58:26 +0200 Subject: [PATCH 067/101] Added new fields `AllowStalled` and `StalledDelay` --- config.example.toml | 18 ------------------ qBitrr/arss.py | 25 +++++++------------------ 2 files changed, 7 insertions(+), 36 deletions(-) diff --git a/config.example.toml b/config.example.toml index bd8bed95..ddc8176c 100644 --- a/config.example.toml +++ b/config.example.toml @@ -423,12 +423,6 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true -# Re-search stalled torrents -ReSearchStalled = false - -# Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite) -StalledDelay = -1 - [Sonarr-Anime.Torrent.SeedingMode] # Set the maximum allowed download rate for torrents @@ -622,12 +616,6 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true -# Re-search stalled torrents -ReSearchStalled = false - -# Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite) -StalledDelay = -1 - [Radarr-1080.Torrent.SeedingMode] # Set the maximum allowed download rate for torrents @@ -834,12 +822,6 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true -# Re-search stalled torrents -ReSearchStalled = false - -# Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite) -StalledDelay = -1 - [Radarr-4K.Torrent.SeedingMode] # Set the maximum allowed download rate for torrents diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 9648fc3a..e976a23e 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -510,15 +510,13 @@ def __init__( else: self.search_api_command = "MissingEpisodeSearch" - if not QBIT_DISABLED: - self.manager.qbit_manager.client.torrents_create_tags( - [ - "qBitrr-allowed_seeding", - "qBitrr-ignored", - "qBitrr-imported", - "qBitrr-allowed_stalled", - ] - ) + self.manager.qbit_manager.client.torrents_create_tags( + [ + "qBitrr-allowed_seeding", + "qBitrr-ignored", + "qbitrr-imported", + ] + ) self.search_setup_completed = False self.model_file: EpisodeFilesModel | MoviesFilesModel = None self.series_file_model: SeriesFilesModel = None @@ -4114,7 +4112,6 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): "qBitrr-free_space_paused", ] ) - if ( self.custom_format_unmet_search and self.custom_format_unmet_check(torrent) @@ -4140,7 +4137,6 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and not stalled_ignore ): self._process_single_torrent_stalled_torrent(torrent, "Stalled State") elif ( @@ -4161,7 +4157,6 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_complete_state(torrent) is False and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and not stalled_ignore ) and torrent.hash in self.cleaned_torrents: self._process_single_torrent_percentage_threshold(torrent, maximum_eta) # Resume monitored downloads which have been paused. @@ -4217,7 +4212,6 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and not self.do_not_remove_slow and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and not stalled_ignore ): self._process_single_torrent_delete_slow(torrent) # Process uncompleted torrents @@ -4234,7 +4228,6 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_downloading_state(torrent) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and not stalled_ignore ): self._process_single_torrent_stalled_torrent(torrent, "Unavailable") else: @@ -4385,10 +4378,6 @@ def torrent_limit_check( return True elif self.seeding_mode_global_remove_torrent == 1 and torrent.ratio >= ratio_limit: return True - elif self.seeding_mode_global_remove_torrent == -1 and ( - torrent.ratio >= ratio_limit or torrent.seeding_time >= seeding_time_limit - ): - return True else: return False From 34541095bb392f46267f3be7197ba087fa1fb583 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:00:24 +0000 Subject: [PATCH 068/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/arss.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index e976a23e..4124c9d5 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -514,7 +514,8 @@ def __init__( [ "qBitrr-allowed_seeding", "qBitrr-ignored", - "qbitrr-imported", + "qBitrr-imported", + "qBitrr-allow_stalled" ] ) self.search_setup_completed = False @@ -4112,6 +4113,11 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): "qBitrr-free_space_paused", ] ) + if ( + "qBitrr-allow_stalled" in torrent.tags + and torrent.added_on >= int(time.time()+(self.stalled_delay*60)) + ): + torrent.remove_tags(["qBitrr-allow_stalled"]) if ( self.custom_format_unmet_search and self.custom_format_unmet_check(torrent) @@ -4378,6 +4384,12 @@ def torrent_limit_check( return True elif self.seeding_mode_global_remove_torrent == 1 and torrent.ratio >= ratio_limit: return True + elif ( + self.seeding_mode_global_remove_torrent == -1 + and (torrent.ratio >= ratio_limit + or torrent.seeding_time >= seeding_time_limit) + ): + return True else: return False From 1671a474b767b445a8fbb06ee8a013a4c3b973be Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:50:29 +0200 Subject: [PATCH 069/101] Set stalled delay to be actionable if config is set to a value above 0 --- .github/workflows/pull_requests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 4d82f3d4..c4585e74 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -25,6 +25,7 @@ jobs: - windows-latest - macOS-latest - ubuntu-latest + - macOS-latest arch: - x86 - x64 From 2fa0028a8958b73438c84c7225c913fb3c62caaf Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 24 Jun 2024 14:58:45 +0200 Subject: [PATCH 070/101] Workflow fixes --- .github/workflows/pull_requests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index c4585e74..4d82f3d4 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -25,7 +25,6 @@ jobs: - windows-latest - macOS-latest - ubuntu-latest - - macOS-latest arch: - x86 - x64 From 10b4751fda5c5a32aacce30372c2736da276f082 Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 26 Jun 2024 10:10:42 +0200 Subject: [PATCH 071/101] Updated tag name --- qBitrr/arss.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 4124c9d5..4d64a2ac 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -511,12 +511,7 @@ def __init__( self.search_api_command = "MissingEpisodeSearch" self.manager.qbit_manager.client.torrents_create_tags( - [ - "qBitrr-allowed_seeding", - "qBitrr-ignored", - "qBitrr-imported", - "qBitrr-allow_stalled" - ] + ["qBitrr-allowed_seeding", "qBitrr-ignored", "qBitrr-imported", "qBitrr-allow_stalled"] ) self.search_setup_completed = False self.model_file: EpisodeFilesModel | MoviesFilesModel = None @@ -4115,9 +4110,10 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) if ( "qBitrr-allow_stalled" in torrent.tags - and torrent.added_on >= int(time.time()+(self.stalled_delay*60)) + and self.stalled_delay > 0 + and torrent.added_on >= int(time.time() + (self.stalled_delay * 60)) ): - torrent.remove_tags(["qBitrr-allow_stalled"]) + torrent.remove_tags(["qBitrr-allowed_stalled"]) if ( self.custom_format_unmet_search and self.custom_format_unmet_check(torrent) @@ -4143,6 +4139,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags + and "qBitrr-allow_stalled" not in torrent.tags ): self._process_single_torrent_stalled_torrent(torrent, "Stalled State") elif ( @@ -4163,6 +4160,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_complete_state(torrent) is False and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags + and "qBitrr-allow_stalled" not in torrent.tags ) and torrent.hash in self.cleaned_torrents: self._process_single_torrent_percentage_threshold(torrent, maximum_eta) # Resume monitored downloads which have been paused. @@ -4218,6 +4216,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and not self.do_not_remove_slow and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags + and "qBitrr-allow_stalled" not in torrent.tags ): self._process_single_torrent_delete_slow(torrent) # Process uncompleted torrents @@ -4234,6 +4233,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_downloading_state(torrent) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags + and "qBitrr-allow_stalled" not in torrent.tags ): self._process_single_torrent_stalled_torrent(torrent, "Unavailable") else: From 14c0641ec30c6de4f11bbc780b32de0b6566994c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 08:11:32 +0000 Subject: [PATCH 072/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/arss.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 4d64a2ac..8c987134 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -511,7 +511,12 @@ def __init__( self.search_api_command = "MissingEpisodeSearch" self.manager.qbit_manager.client.torrents_create_tags( - ["qBitrr-allowed_seeding", "qBitrr-ignored", "qBitrr-imported", "qBitrr-allow_stalled"] + [ + "qBitrr-allowed_seeding", + "qBitrr-ignored", + "qBitrr-imported", + "qBitrr-allowed_stalled", + ] ) self.search_setup_completed = False self.model_file: EpisodeFilesModel | MoviesFilesModel = None From e25147fd28a663d14efdf479cc6c5c73a71df609 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:10:37 +0000 Subject: [PATCH 073/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/logger.py | 1 - qBitrr/tables.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/logger.py b/qBitrr/logger.py index ff311010..a988e65d 100644 --- a/qBitrr/logger.py +++ b/qBitrr/logger.py @@ -21,7 +21,6 @@ NO_INTERNET_SLEEP_TIMER, PING_URLS, RECHECK_CATEGORY, - TAGLESS, SEARCH_LOOP_DELAY, TAGLESS, ) diff --git a/qBitrr/tables.py b/qBitrr/tables.py index 570aae10..9be146cc 100644 --- a/qBitrr/tables.py +++ b/qBitrr/tables.py @@ -62,6 +62,7 @@ class EpisodeQueueModel(Model): EntryId = IntegerField(unique=True) Completed = BooleanField(default=False) + class TorrentLibrary(Model): Hash = TextField(null=False) AllowedSeeding = BooleanField(default=False) From a9270131d7d4f17b2d4cb306d9bf5b2f319973e9 Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 26 Jun 2024 13:57:35 +0200 Subject: [PATCH 074/101] Tagging fix --- qBitrr/arss.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 8c987134..77b1da3a 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4103,9 +4103,6 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): torrent.state_enum, ) maximum_eta = _tracker_max_eta - - stalled_ignore = self._stalled_check(torrent, time_now) - if "qBitrr-ignored" in torrent.tags: torrent.remove_tags( [ @@ -4114,7 +4111,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ] ) if ( - "qBitrr-allow_stalled" in torrent.tags + "qBitrr-allowed_stalled" in torrent.tags and self.stalled_delay > 0 and torrent.added_on >= int(time.time() + (self.stalled_delay * 60)) ): @@ -4144,7 +4141,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allow_stalled" not in torrent.tags + and "qBitrr-allowed_stalled" not in torrent.tags ): self._process_single_torrent_stalled_torrent(torrent, "Stalled State") elif ( @@ -4165,7 +4162,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_complete_state(torrent) is False and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allow_stalled" not in torrent.tags + and "qBitrr-allowed_stalled" not in torrent.tags ) and torrent.hash in self.cleaned_torrents: self._process_single_torrent_percentage_threshold(torrent, maximum_eta) # Resume monitored downloads which have been paused. @@ -4221,7 +4218,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and not self.do_not_remove_slow and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allow_stalled" not in torrent.tags + and "qBitrr-allowed_stalled" not in torrent.tags ): self._process_single_torrent_delete_slow(torrent) # Process uncompleted torrents @@ -4238,7 +4235,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_downloading_state(torrent) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allow_stalled" not in torrent.tags + and "qBitrr-allowed_stalled" not in torrent.tags ): self._process_single_torrent_stalled_torrent(torrent, "Unavailable") else: From 5e4b3caf76b7191fe4d43f8db4246e3c939ae923 Mon Sep 17 00:00:00 2001 From: Feramance Date: Tue, 2 Jul 2024 09:02:16 +0200 Subject: [PATCH 075/101] Updated blocklisting for stalled torrents, and added config for auto pause resume --- config.example.toml | 3 +++ qBitrr/gen_config.py | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/config.example.toml b/config.example.toml index ddc8176c..f45ab52e 100644 --- a/config.example.toml +++ b/config.example.toml @@ -27,6 +27,9 @@ LoopSleepTimer = 5 # Time to sleep between posting search commands (in seconds: 600 = 10 Minutes) SearchLoopDelay = -1 +# Enable automation of pausing and resuming torrents as needed +AutoPauseResume = true + # Add torrents to this category to mark them as failed FailedCategory = "failed" diff --git a/qBitrr/gen_config.py b/qBitrr/gen_config.py index 0d9e1015..515f96f8 100755 --- a/qBitrr/gen_config.py +++ b/qBitrr/gen_config.py @@ -80,6 +80,12 @@ def _add_settings_section(config: TOMLDocument): "SearchLoopDelay", ENVIRO_CONFIG.settings.search_loop_delay or -1, ) + _gen_default_line( + settings, + "Enable automation of pausing and resuming torrents as needed", + "AutoPauseResume", + ENVIRO_CONFIG.settings.auto_pause_resume or True, + ) _gen_default_line( settings, "Add torrents to this category to mark them as failed", From b7dbd02025cb4a28e7278c2ee0627c242d0e1641 Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 3 Jul 2024 10:14:25 +0200 Subject: [PATCH 076/101] Updated config order and description --- config.example.toml | 3 --- qBitrr/gen_config.py | 6 ------ 2 files changed, 9 deletions(-) diff --git a/config.example.toml b/config.example.toml index f45ab52e..ddc8176c 100644 --- a/config.example.toml +++ b/config.example.toml @@ -27,9 +27,6 @@ LoopSleepTimer = 5 # Time to sleep between posting search commands (in seconds: 600 = 10 Minutes) SearchLoopDelay = -1 -# Enable automation of pausing and resuming torrents as needed -AutoPauseResume = true - # Add torrents to this category to mark them as failed FailedCategory = "failed" diff --git a/qBitrr/gen_config.py b/qBitrr/gen_config.py index 515f96f8..0d9e1015 100755 --- a/qBitrr/gen_config.py +++ b/qBitrr/gen_config.py @@ -80,12 +80,6 @@ def _add_settings_section(config: TOMLDocument): "SearchLoopDelay", ENVIRO_CONFIG.settings.search_loop_delay or -1, ) - _gen_default_line( - settings, - "Enable automation of pausing and resuming torrents as needed", - "AutoPauseResume", - ENVIRO_CONFIG.settings.auto_pause_resume or True, - ) _gen_default_line( settings, "Add torrents to this category to mark them as failed", From 81f95685c9423410a5e7017702e4d5e3efb30788 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 10 Jul 2024 08:19:03 +0000 Subject: [PATCH 077/101] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- qBitrr/arss.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 77b1da3a..91226c4a 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4386,10 +4386,8 @@ def torrent_limit_check( return True elif self.seeding_mode_global_remove_torrent == 1 and torrent.ratio >= ratio_limit: return True - elif ( - self.seeding_mode_global_remove_torrent == -1 - and (torrent.ratio >= ratio_limit - or torrent.seeding_time >= seeding_time_limit) + elif self.seeding_mode_global_remove_torrent == -1 and ( + torrent.ratio >= ratio_limit or torrent.seeding_time >= seeding_time_limit ): return True else: From c5aff7e5d0f0d91d36526b07e5a004317d28f60b Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 10 Jul 2024 17:08:28 +0200 Subject: [PATCH 078/101] Merge fixes --- qBitrr/arss.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index d9f6a87f..9648fc3a 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4104,6 +4104,9 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): torrent.state_enum, ) maximum_eta = _tracker_max_eta + + stalled_ignore = self._stalled_check(torrent, time_now) + if "qBitrr-ignored" in torrent.tags: torrent.remove_tags( [ @@ -4111,12 +4114,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): "qBitrr-free_space_paused", ] ) - if ( - "qBitrr-allowed_stalled" in torrent.tags - and self.stalled_delay > 0 - and torrent.added_on >= int(time.time() + (self.stalled_delay * 60)) - ): - torrent.remove_tags(["qBitrr-allowed_stalled"]) + if ( self.custom_format_unmet_search and self.custom_format_unmet_check(torrent) @@ -4142,7 +4140,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allowed_stalled" not in torrent.tags + and not stalled_ignore ): self._process_single_torrent_stalled_torrent(torrent, "Stalled State") elif ( @@ -4163,7 +4161,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_complete_state(torrent) is False and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allowed_stalled" not in torrent.tags + and not stalled_ignore ) and torrent.hash in self.cleaned_torrents: self._process_single_torrent_percentage_threshold(torrent, maximum_eta) # Resume monitored downloads which have been paused. @@ -4219,7 +4217,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and not self.do_not_remove_slow and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allowed_stalled" not in torrent.tags + and not stalled_ignore ): self._process_single_torrent_delete_slow(torrent) # Process uncompleted torrents @@ -4236,7 +4234,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): and self.is_downloading_state(torrent) and "qBitrr-ignored" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags - and "qBitrr-allowed_stalled" not in torrent.tags + and not stalled_ignore ): self._process_single_torrent_stalled_torrent(torrent, "Unavailable") else: From ca7faf1087be2bc661e3a56a996bc7e688e5f0fd Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 12 Jul 2024 09:38:30 +0200 Subject: [PATCH 079/101] Connect free space manager to torrent db --- qBitrr/arss.py | 24 +++++++++++++++++++++++- qBitrr/tables.py | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 9648fc3a..c34c15eb 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4572,7 +4572,7 @@ class Meta: if db4: self.torrent_db = SqliteDatabase(None) self.torrent_db.init( - str(self._app_data_folder.joinpath("torrents.db")), + str(self._app_data_folder.joinpath("Torrents.db")), pragmas={ "journal_mode": "wal", "cache_size": -1 * 64000, # 64MB @@ -5146,8 +5146,30 @@ def __init__(self, categories: set[str], manager: ArrManager): ) self.search_missing = False self.session = None + self.register_torrent_database() self.logger.hnotice("Starting %s monitor", self._name) + def register_torrent_database(self): + self.torrent_db = SqliteDatabase(None) + self.torrent_db.init( + str(self._app_data_folder.joinpath("Torrents.db")), + pragmas={ + "journal_mode": "wal", + "cache_size": -1 * 64000, # 64MB + "foreign_keys": 1, + "ignore_check_constraints": 0, + "synchronous": 0, + }, + ) + + class Torrents(TorrentLibrary): + class Meta: + database = self.torrent_db + + self.torrent_db.connect() + self.torrent_db.create_tables([Torrents]) + self.torrents = Torrents + def _process_single_torrent_pause_disk_space(self, torrent: qbittorrentapi.TorrentDictionary): self.logger.info( "Pausing torrent for disk space: " diff --git a/qBitrr/tables.py b/qBitrr/tables.py index 9be146cc..eff1abc4 100644 --- a/qBitrr/tables.py +++ b/qBitrr/tables.py @@ -65,6 +65,7 @@ class EpisodeQueueModel(Model): class TorrentLibrary(Model): Hash = TextField(null=False) + Category = TextField(null=False) AllowedSeeding = BooleanField(default=False) Ignored = BooleanField(default=False) Imported = BooleanField(default=False) From c8e3c2e6bac6f528e7a8f59fc9c3a7dbe2bd0567 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 12 Jul 2024 13:20:15 +0200 Subject: [PATCH 080/101] Appdata folder fix --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index c34c15eb..ee3a7527 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -5152,7 +5152,7 @@ def __init__(self, categories: set[str], manager: ArrManager): def register_torrent_database(self): self.torrent_db = SqliteDatabase(None) self.torrent_db.init( - str(self._app_data_folder.joinpath("Torrents.db")), + str(APPDATA_FOLDER.joinpath("Torrents.db")), pragmas={ "journal_mode": "wal", "cache_size": -1 * 64000, # 64MB From c60e2b4888cb5650136825934bafbf0bd6e489d6 Mon Sep 17 00:00:00 2001 From: Feramance <38938175+Feramance@users.noreply.github.com> Date: Tue, 16 Jul 2024 09:29:20 +0200 Subject: [PATCH 081/101] Update config.example.toml Signed-off-by: Feramance <38938175+Feramance@users.noreply.github.com> --- config.example.toml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/config.example.toml b/config.example.toml index ddc8176c..bd8bed95 100644 --- a/config.example.toml +++ b/config.example.toml @@ -423,6 +423,12 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true +# Re-search stalled torrents +ReSearchStalled = false + +# Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite) +StalledDelay = -1 + [Sonarr-Anime.Torrent.SeedingMode] # Set the maximum allowed download rate for torrents @@ -616,6 +622,12 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true +# Re-search stalled torrents +ReSearchStalled = false + +# Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite) +StalledDelay = -1 + [Radarr-1080.Torrent.SeedingMode] # Set the maximum allowed download rate for torrents @@ -822,6 +834,12 @@ MaximumDeletablePercentage = 0.99 # Ignore slow torrents. DoNotRemoveSlow = true +# Re-search stalled torrents +ReSearchStalled = false + +# Maximum allowed time for allowed stalled torrents in minutes (-1 = Disabled, 0 = Infinite) +StalledDelay = -1 + [Radarr-4K.Torrent.SeedingMode] # Set the maximum allowed download rate for torrents From 1eb29a93fa81b80fdad32f0ab7c02fd8a3d47dcc Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 16 Aug 2024 13:31:44 +0200 Subject: [PATCH 082/101] Update tagless logic --- qBitrr/arss.py | 81 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 15 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 5ea5e760..3b0a403d 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -594,6 +594,56 @@ def is_downloading_state(torrent: TorrentDictionary) -> bool: TorrentStates.PAUSED_DOWNLOAD, ) + def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: + query = self.torrents.select().where(Hash=torrent.hash).execute() + if not query: + self.torrents.insert(Hash=torrent.hash).on_conflict_ignore().execute() + else: + for tag in tags: + if TAGLESS: + if tag == "qBitrr-allowed_seeding": + self.torrents.update(AllowedSeeding=False).where(Hash=torrent.hash) + elif tag == "qBitrr-imported": + self.torrents.update(Imported=False).where(Hash=torrent.hash) + elif tag == "qBitrr-allowed_stalled": + self.torrents.update(AllowedStalled=False).where(Hash=torrent.hash) + elif tag == "qBitrr-free_space_paused": + self.torrents.update(FreeSpacePaused=False).where(Hash=torrent.hash) + else: + if tag == "qBitrr-allowed_seeding": + torrent.remove_tags(tags=["qBitrr-allowed_seeding"]) + elif tag == "qBitrr-imported": + torrent.remove_tags(tags=["qBitrr-imported"]) + elif tag == "qBitrr-allowed_stalled": + torrent.remove_tags(tags=["qBitrr-allowed_stalled"]) + elif tag == "qBitrr-free_space_paused": + torrent.remove_tags(tags=["qBitrr-free_space_paused"]) + + def add_tags(self, torrent: TorrentDictionary, tags: list) -> None: + query = self.torrents.select().where(Hash=torrent.hash).execute() + if not query: + self.torrents.insert(Hash=torrent.hash).on_conflict_ignore().execute() + else: + for tag in tags: + if TAGLESS: + if tag == "qBitrr-allowed_seeding": + self.torrents.update(AllowedSeeding=True).where(Hash=torrent.hash) + elif tag == "qBitrr-imported": + self.torrents.update(Imported=True).where(Hash=torrent.hash) + elif tag == "qBitrr-allowed_stalled": + self.torrents.update(AllowedStalled=True).where(Hash=torrent.hash) + elif tag == "qBitrr-free_space_paused": + self.torrents.update(FreeSpacePaused=True).where(Hash=torrent.hash) + else: + if tag == "qBitrr-allowed_seeding": + torrent.add_tags(tags=["qBitrr-allowed_seeding"]) + elif tag == "qBitrr-imported": + torrent.add_tags(tags=["qBitrr-imported"]) + elif tag == "qBitrr-allowed_stalled": + torrent.add_tags(tags=["qBitrr-allowed_stalled"]) + elif tag == "qBitrr-free_space_paused": + torrent.add_tags(tags=["qBitrr-free_space_paused"]) + def _get_models( self, ) -> tuple[ @@ -861,7 +911,7 @@ def _process_imports(self) -> None: self.import_mode, ex, ) - torrent.add_tags(tags=["qBitrr-imported"]) + self.add_tags(torrent, tags=["qBitrr-imported"]) self.sent_to_scan.add(path) self.import_torrents.clear() @@ -3846,11 +3896,11 @@ def _should_leave_alone( and "qBitrr-allowed_seeding" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags ): - torrent.add_tags(tags=["qBitrr-allowed_seeding"]) + self.add_tags(torrent, tags=["qBitrr-allowed_seeding"]) elif ( not return_value and "qBitrr-allowed_seeding" in torrent.tags ) or "qBitrr-free_space_paused" in torrent.tags: - torrent.remove_tags(tags=["qBitrr-allowed_seeding"]) + self.remove_tags(torrent, tags=["qBitrr-allowed_seeding"]) return ( return_value, data_settings.get("max_eta", self.maximum_eta), @@ -4004,7 +4054,7 @@ def _process_single_torrent_trackers(self, torrent: qbittorrentapi.TorrentDictio current_tags = set(torrent.tags.split(", ")) add_tags = unique_tags.difference(current_tags) if add_tags: - torrent.add_tags(add_tags) + self.add_tags(torrent, add_tags) def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: float) -> bool: stalled_ignore = True @@ -4059,7 +4109,7 @@ def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: fl torrent.name, ) elif "qBitrr-allowed_stalled" not in torrent.tags: - torrent.add_tags(["qBitrr-allowed_stalled"]) + self.add_tags(torrent, ["qBitrr-allowed_stalled"]) if self.re_search_stalled: self.logger.trace( "Stalled, adding tag, blocklosting and re-searching: %s", @@ -4087,7 +4137,7 @@ def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: fl ) elif "qBitrr-allowed_stalled" in torrent.tags: - torrent.remove_tags(["qBitrr-allowed_stalled"]) + self.remove_tags(torrent, ["qBitrr-allowed_stalled"]) stalled_ignore = False self.logger.trace( "Not stalled, removing tag: %s", @@ -4120,11 +4170,12 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): stalled_ignore = self._stalled_check(torrent, time_now) if "qBitrr-ignored" in torrent.tags: - torrent.remove_tags( + self.remove_tags( + torrent, [ "qBitrr-allowed_seeding", "qBitrr-free_space_paused", - ] + ], ) if ( @@ -5217,8 +5268,8 @@ def _process_single_torrent(self, torrent): self.current_free_space, free_space_test, ) - torrent.add_tags(tags=["qBitrr-free_space_paused"]) - torrent.remove_tags(tags=["qBitrr-allowed_seeding"]) + self.add_tags(torrent, tags=["qBitrr-free_space_paused"]) + self.remove_tags(torrent, tags=["qBitrr-allowed_seeding"]) self._process_single_torrent_pause_disk_space(torrent) elif torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD and free_space_test < 0: self.logger.info( @@ -5227,8 +5278,8 @@ def _process_single_torrent(self, torrent): self.current_free_space, free_space_test, ) - torrent.add_tags(tags=["qBitrr-free_space_paused"]) - torrent.remove_tags(tags=["qBitrr-allowed_seeding"]) + self.add_tags(torrent, tags=["qBitrr-free_space_paused"]) + self.remove_tags(torrent, tags=["qBitrr-allowed_seeding"]) elif torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and free_space_test > 0: self.logger.info( "Continue downloading [%s]: Free space %s -> %s", @@ -5237,7 +5288,7 @@ def _process_single_torrent(self, torrent): free_space_test, ) self.current_free_space = free_space_test - torrent.remove_tags(tags=["qBitrr-free_space_paused"]) + self.remove_tags(torrent, tags=["qBitrr-free_space_paused"]) elif torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD and free_space_test > 0: self.logger.info( "Unpause download [%s]: Free space %s -> %s", @@ -5246,7 +5297,7 @@ def _process_single_torrent(self, torrent): free_space_test, ) self.current_free_space = free_space_test - torrent.remove_tags(tags=["qBitrr-free_space_paused"]) + self.remove_tags(torrent, tags=["qBitrr-free_space_paused"]) elif not self.is_downloading_state(torrent) and "qBitrr-free_space_paused" in torrent.tags: self.logger.info( "Removing tag [%s] for completed torrent[%s]: Free space %s", @@ -5254,7 +5305,7 @@ def _process_single_torrent(self, torrent): torrent.name, self.current_free_space, ) - torrent.remove_tags(tags=["qBitrr-free_space_paused"]) + self.remove_tags(torrent, tags=["qBitrr-free_space_paused"]) def process(self): self._process_paused() From e9cc05ab39f44965994405a62b9ab788ee943d8a Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 16 Aug 2024 13:33:38 +0200 Subject: [PATCH 083/101] Removed paramater calls --- qBitrr/arss.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 3b0a403d..56e384c5 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -611,13 +611,13 @@ def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: self.torrents.update(FreeSpacePaused=False).where(Hash=torrent.hash) else: if tag == "qBitrr-allowed_seeding": - torrent.remove_tags(tags=["qBitrr-allowed_seeding"]) + torrent.remove_tags(["qBitrr-allowed_seeding"]) elif tag == "qBitrr-imported": - torrent.remove_tags(tags=["qBitrr-imported"]) + torrent.remove_tags(["qBitrr-imported"]) elif tag == "qBitrr-allowed_stalled": - torrent.remove_tags(tags=["qBitrr-allowed_stalled"]) + torrent.remove_tags(["qBitrr-allowed_stalled"]) elif tag == "qBitrr-free_space_paused": - torrent.remove_tags(tags=["qBitrr-free_space_paused"]) + torrent.remove_tags(["qBitrr-free_space_paused"]) def add_tags(self, torrent: TorrentDictionary, tags: list) -> None: query = self.torrents.select().where(Hash=torrent.hash).execute() @@ -636,13 +636,13 @@ def add_tags(self, torrent: TorrentDictionary, tags: list) -> None: self.torrents.update(FreeSpacePaused=True).where(Hash=torrent.hash) else: if tag == "qBitrr-allowed_seeding": - torrent.add_tags(tags=["qBitrr-allowed_seeding"]) + torrent.add_tags(["qBitrr-allowed_seeding"]) elif tag == "qBitrr-imported": - torrent.add_tags(tags=["qBitrr-imported"]) + torrent.add_tags(["qBitrr-imported"]) elif tag == "qBitrr-allowed_stalled": - torrent.add_tags(tags=["qBitrr-allowed_stalled"]) + torrent.add_tags(["qBitrr-allowed_stalled"]) elif tag == "qBitrr-free_space_paused": - torrent.add_tags(tags=["qBitrr-free_space_paused"]) + torrent.add_tags(["qBitrr-free_space_paused"]) def _get_models( self, @@ -911,7 +911,7 @@ def _process_imports(self) -> None: self.import_mode, ex, ) - self.add_tags(torrent, tags=["qBitrr-imported"]) + self.add_tags(torrent, ["qBitrr-imported"]) self.sent_to_scan.add(path) self.import_torrents.clear() @@ -3896,11 +3896,11 @@ def _should_leave_alone( and "qBitrr-allowed_seeding" not in torrent.tags and "qBitrr-free_space_paused" not in torrent.tags ): - self.add_tags(torrent, tags=["qBitrr-allowed_seeding"]) + self.add_tags(torrent, ["qBitrr-allowed_seeding"]) elif ( not return_value and "qBitrr-allowed_seeding" in torrent.tags ) or "qBitrr-free_space_paused" in torrent.tags: - self.remove_tags(torrent, tags=["qBitrr-allowed_seeding"]) + self.remove_tags(torrent, ["qBitrr-allowed_seeding"]) return ( return_value, data_settings.get("max_eta", self.maximum_eta), @@ -5268,8 +5268,8 @@ def _process_single_torrent(self, torrent): self.current_free_space, free_space_test, ) - self.add_tags(torrent, tags=["qBitrr-free_space_paused"]) - self.remove_tags(torrent, tags=["qBitrr-allowed_seeding"]) + self.add_tags(torrent, ["qBitrr-free_space_paused"]) + self.remove_tags(torrent, ["qBitrr-allowed_seeding"]) self._process_single_torrent_pause_disk_space(torrent) elif torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD and free_space_test < 0: self.logger.info( @@ -5278,8 +5278,8 @@ def _process_single_torrent(self, torrent): self.current_free_space, free_space_test, ) - self.add_tags(torrent, tags=["qBitrr-free_space_paused"]) - self.remove_tags(torrent, tags=["qBitrr-allowed_seeding"]) + self.add_tags(torrent, ["qBitrr-free_space_paused"]) + self.remove_tags(torrent, ["qBitrr-allowed_seeding"]) elif torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD and free_space_test > 0: self.logger.info( "Continue downloading [%s]: Free space %s -> %s", @@ -5288,7 +5288,7 @@ def _process_single_torrent(self, torrent): free_space_test, ) self.current_free_space = free_space_test - self.remove_tags(torrent, tags=["qBitrr-free_space_paused"]) + self.remove_tags(torrent, ["qBitrr-free_space_paused"]) elif torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD and free_space_test > 0: self.logger.info( "Unpause download [%s]: Free space %s -> %s", @@ -5297,7 +5297,7 @@ def _process_single_torrent(self, torrent): free_space_test, ) self.current_free_space = free_space_test - self.remove_tags(torrent, tags=["qBitrr-free_space_paused"]) + self.remove_tags(torrent, ["qBitrr-free_space_paused"]) elif not self.is_downloading_state(torrent) and "qBitrr-free_space_paused" in torrent.tags: self.logger.info( "Removing tag [%s] for completed torrent[%s]: Free space %s", @@ -5305,7 +5305,7 @@ def _process_single_torrent(self, torrent): torrent.name, self.current_free_space, ) - self.remove_tags(torrent, tags=["qBitrr-free_space_paused"]) + self.remove_tags(torrent, ["qBitrr-free_space_paused"]) def process(self): self._process_paused() From df99c95d726ec72c3ca7d3342e9b197627741415 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 16 Aug 2024 13:37:16 +0200 Subject: [PATCH 084/101] Category fix for torrents table --- qBitrr/arss.py | 48 ++++++++++++++++++++++++++++++++++++------------ qBitrr/tables.py | 1 - 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 56e384c5..70d4406e 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -595,20 +595,32 @@ def is_downloading_state(torrent: TorrentDictionary) -> bool: ) def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: - query = self.torrents.select().where(Hash=torrent.hash).execute() + query = ( + self.torrents.select().where(Hash=torrent.hash, Category=torrent.category).execute() + ) if not query: - self.torrents.insert(Hash=torrent.hash).on_conflict_ignore().execute() + self.torrents.insert( + Hash=torrent.hash, Category=torrent.category + ).on_conflict_ignore().execute() else: for tag in tags: if TAGLESS: if tag == "qBitrr-allowed_seeding": - self.torrents.update(AllowedSeeding=False).where(Hash=torrent.hash) + self.torrents.update(AllowedSeeding=False).where( + Hash=torrent.hash, Category=torrent.category + ) elif tag == "qBitrr-imported": - self.torrents.update(Imported=False).where(Hash=torrent.hash) + self.torrents.update(Imported=False).where( + Hash=torrent.hash, Category=torrent.category + ) elif tag == "qBitrr-allowed_stalled": - self.torrents.update(AllowedStalled=False).where(Hash=torrent.hash) + self.torrents.update(AllowedStalled=False).where( + Hash=torrent.hash, Category=torrent.category + ) elif tag == "qBitrr-free_space_paused": - self.torrents.update(FreeSpacePaused=False).where(Hash=torrent.hash) + self.torrents.update(FreeSpacePaused=False).where( + Hash=torrent.hash, Category=torrent.category + ) else: if tag == "qBitrr-allowed_seeding": torrent.remove_tags(["qBitrr-allowed_seeding"]) @@ -620,20 +632,32 @@ def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: torrent.remove_tags(["qBitrr-free_space_paused"]) def add_tags(self, torrent: TorrentDictionary, tags: list) -> None: - query = self.torrents.select().where(Hash=torrent.hash).execute() + query = ( + self.torrents.select().where(Hash=torrent.hash, Category=torrent.category).execute() + ) if not query: - self.torrents.insert(Hash=torrent.hash).on_conflict_ignore().execute() + self.torrents.insert( + Hash=torrent.hash, Category=torrent.category + ).on_conflict_ignore().execute() else: for tag in tags: if TAGLESS: if tag == "qBitrr-allowed_seeding": - self.torrents.update(AllowedSeeding=True).where(Hash=torrent.hash) + self.torrents.update(AllowedSeeding=True).where( + Hash=torrent.hash, Category=torrent.category + ) elif tag == "qBitrr-imported": - self.torrents.update(Imported=True).where(Hash=torrent.hash) + self.torrents.update(Imported=True).where( + Hash=torrent.hash, Category=torrent.category + ) elif tag == "qBitrr-allowed_stalled": - self.torrents.update(AllowedStalled=True).where(Hash=torrent.hash) + self.torrents.update(AllowedStalled=True).where( + Hash=torrent.hash, Category=torrent.category + ) elif tag == "qBitrr-free_space_paused": - self.torrents.update(FreeSpacePaused=True).where(Hash=torrent.hash) + self.torrents.update(FreeSpacePaused=True).where( + Hash=torrent.hash, Category=torrent.category + ) else: if tag == "qBitrr-allowed_seeding": torrent.add_tags(["qBitrr-allowed_seeding"]) diff --git a/qBitrr/tables.py b/qBitrr/tables.py index eff1abc4..d55da13a 100644 --- a/qBitrr/tables.py +++ b/qBitrr/tables.py @@ -67,7 +67,6 @@ class TorrentLibrary(Model): Hash = TextField(null=False) Category = TextField(null=False) AllowedSeeding = BooleanField(default=False) - Ignored = BooleanField(default=False) Imported = BooleanField(default=False) AllowedStalled = BooleanField(default=False) FreeSpacePaused = BooleanField(default=False) From f5ade0726c15863a704c008ef94d83d684cdd6f0 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 16 Aug 2024 13:50:49 +0200 Subject: [PATCH 085/101] Update variable name --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 70d4406e..c0c7ec7a 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -530,7 +530,7 @@ def __init__( self.series_file_model: SeriesFilesModel = None self.model_queue: EpisodeQueueModel | MovieQueueModel = None self.persistent_queue: FilesQueued = None - self.torrent_library: TorrentLibrary = None + self.torrents: TorrentLibrary = None self.logger.hnotice("Starting %s monitor", self._name) @property From 0952b3ae1b995a10998b30d393061be47debd087 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 16 Aug 2024 13:55:38 +0200 Subject: [PATCH 086/101] Added logic to grab db before prcessing torrents --- qBitrr/arss.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index c0c7ec7a..05aadbd0 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4942,6 +4942,7 @@ def run_search_loop(self) -> NoReturn: def run_torrent_loop(self) -> NoReturn: run_logs(self.logger) + self.register_search_mode() self.logger.hnotice("Starting torrent monitoring for %s", self._name) while True: try: From c064f45f2e854ad95d17681dfab34dc72466f85f Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 16 Aug 2024 14:13:46 +0200 Subject: [PATCH 087/101] Updated conditions formatting --- qBitrr/arss.py | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 05aadbd0..68ffb977 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -596,7 +596,9 @@ def is_downloading_state(torrent: TorrentDictionary) -> bool: def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: query = ( - self.torrents.select().where(Hash=torrent.hash, Category=torrent.category).execute() + self.torrents.select() + .where(self.torrents.Hash == torrent.hash & self.torrents.Category == torrent.category) + .execute() ) if not query: self.torrents.insert( @@ -607,19 +609,27 @@ def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: if TAGLESS: if tag == "qBitrr-allowed_seeding": self.torrents.update(AllowedSeeding=False).where( - Hash=torrent.hash, Category=torrent.category + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category ) elif tag == "qBitrr-imported": self.torrents.update(Imported=False).where( - Hash=torrent.hash, Category=torrent.category + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category ) elif tag == "qBitrr-allowed_stalled": self.torrents.update(AllowedStalled=False).where( - Hash=torrent.hash, Category=torrent.category + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category ) elif tag == "qBitrr-free_space_paused": self.torrents.update(FreeSpacePaused=False).where( - Hash=torrent.hash, Category=torrent.category + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category ) else: if tag == "qBitrr-allowed_seeding": @@ -633,7 +643,9 @@ def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: def add_tags(self, torrent: TorrentDictionary, tags: list) -> None: query = ( - self.torrents.select().where(Hash=torrent.hash, Category=torrent.category).execute() + self.torrents.select() + .where(self.torrents.Hash == torrent.hash & self.torrents.Category == torrent.category) + .execute() ) if not query: self.torrents.insert( @@ -644,19 +656,27 @@ def add_tags(self, torrent: TorrentDictionary, tags: list) -> None: if TAGLESS: if tag == "qBitrr-allowed_seeding": self.torrents.update(AllowedSeeding=True).where( - Hash=torrent.hash, Category=torrent.category + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category ) elif tag == "qBitrr-imported": self.torrents.update(Imported=True).where( - Hash=torrent.hash, Category=torrent.category + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category ) elif tag == "qBitrr-allowed_stalled": self.torrents.update(AllowedStalled=True).where( - Hash=torrent.hash, Category=torrent.category + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category ) elif tag == "qBitrr-free_space_paused": self.torrents.update(FreeSpacePaused=True).where( - Hash=torrent.hash, Category=torrent.category + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category ) else: if tag == "qBitrr-allowed_seeding": From ea5731753ac1e9a9323591054b98b71689362ea4 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 16 Aug 2024 14:32:22 +0200 Subject: [PATCH 088/101] Adjusted query to run when not in tagless mode only --- qBitrr/arss.py | 186 +++++++++++++++++++++++++------------------------ 1 file changed, 96 insertions(+), 90 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 68ffb977..3f5a72e1 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -595,98 +595,104 @@ def is_downloading_state(torrent: TorrentDictionary) -> bool: ) def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: - query = ( - self.torrents.select() - .where(self.torrents.Hash == torrent.hash & self.torrents.Category == torrent.category) - .execute() - ) - if not query: - self.torrents.insert( - Hash=torrent.hash, Category=torrent.category - ).on_conflict_ignore().execute() - else: - for tag in tags: - if TAGLESS: - if tag == "qBitrr-allowed_seeding": - self.torrents.update(AllowedSeeding=False).where( - self.torrents.Hash - == torrent.hash & self.torrents.Category - == torrent.category - ) - elif tag == "qBitrr-imported": - self.torrents.update(Imported=False).where( - self.torrents.Hash - == torrent.hash & self.torrents.Category - == torrent.category - ) - elif tag == "qBitrr-allowed_stalled": - self.torrents.update(AllowedStalled=False).where( - self.torrents.Hash - == torrent.hash & self.torrents.Category - == torrent.category - ) - elif tag == "qBitrr-free_space_paused": - self.torrents.update(FreeSpacePaused=False).where( - self.torrents.Hash - == torrent.hash & self.torrents.Category - == torrent.category - ) - else: - if tag == "qBitrr-allowed_seeding": - torrent.remove_tags(["qBitrr-allowed_seeding"]) - elif tag == "qBitrr-imported": - torrent.remove_tags(["qBitrr-imported"]) - elif tag == "qBitrr-allowed_stalled": - torrent.remove_tags(["qBitrr-allowed_stalled"]) - elif tag == "qBitrr-free_space_paused": - torrent.remove_tags(["qBitrr-free_space_paused"]) + for tag in tags: + if TAGLESS: + query = ( + self.torrents.select() + .where( + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category + ) + .execute() + ) + if not query: + self.torrents.insert( + Hash=torrent.hash, Category=torrent.category + ).on_conflict_ignore().execute() + if tag == "qBitrr-allowed_seeding": + self.torrents.update(AllowedSeeding=False).where( + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category + ) + elif tag == "qBitrr-imported": + self.torrents.update(Imported=False).where( + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category + ) + elif tag == "qBitrr-allowed_stalled": + self.torrents.update(AllowedStalled=False).where( + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category + ) + elif tag == "qBitrr-free_space_paused": + self.torrents.update(FreeSpacePaused=False).where( + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category + ) + else: + if tag == "qBitrr-allowed_seeding": + torrent.remove_tags(["qBitrr-allowed_seeding"]) + elif tag == "qBitrr-imported": + torrent.remove_tags(["qBitrr-imported"]) + elif tag == "qBitrr-allowed_stalled": + torrent.remove_tags(["qBitrr-allowed_stalled"]) + elif tag == "qBitrr-free_space_paused": + torrent.remove_tags(["qBitrr-free_space_paused"]) def add_tags(self, torrent: TorrentDictionary, tags: list) -> None: - query = ( - self.torrents.select() - .where(self.torrents.Hash == torrent.hash & self.torrents.Category == torrent.category) - .execute() - ) - if not query: - self.torrents.insert( - Hash=torrent.hash, Category=torrent.category - ).on_conflict_ignore().execute() - else: - for tag in tags: - if TAGLESS: - if tag == "qBitrr-allowed_seeding": - self.torrents.update(AllowedSeeding=True).where( - self.torrents.Hash - == torrent.hash & self.torrents.Category - == torrent.category - ) - elif tag == "qBitrr-imported": - self.torrents.update(Imported=True).where( - self.torrents.Hash - == torrent.hash & self.torrents.Category - == torrent.category - ) - elif tag == "qBitrr-allowed_stalled": - self.torrents.update(AllowedStalled=True).where( - self.torrents.Hash - == torrent.hash & self.torrents.Category - == torrent.category - ) - elif tag == "qBitrr-free_space_paused": - self.torrents.update(FreeSpacePaused=True).where( - self.torrents.Hash - == torrent.hash & self.torrents.Category - == torrent.category - ) - else: - if tag == "qBitrr-allowed_seeding": - torrent.add_tags(["qBitrr-allowed_seeding"]) - elif tag == "qBitrr-imported": - torrent.add_tags(["qBitrr-imported"]) - elif tag == "qBitrr-allowed_stalled": - torrent.add_tags(["qBitrr-allowed_stalled"]) - elif tag == "qBitrr-free_space_paused": - torrent.add_tags(["qBitrr-free_space_paused"]) + for tag in tags: + if TAGLESS: + query = ( + self.torrents.select() + .where( + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category + ) + .execute() + ) + if not query: + self.torrents.insert( + Hash=torrent.hash, Category=torrent.category + ).on_conflict_ignore().execute() + if tag == "qBitrr-allowed_seeding": + self.torrents.update(AllowedSeeding=True).where( + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category + ) + elif tag == "qBitrr-imported": + self.torrents.update(Imported=True).where( + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category + ) + elif tag == "qBitrr-allowed_stalled": + self.torrents.update(AllowedStalled=True).where( + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category + ) + elif tag == "qBitrr-free_space_paused": + self.torrents.update(FreeSpacePaused=True).where( + self.torrents.Hash + == torrent.hash & self.torrents.Category + == torrent.category + ) + else: + if tag == "qBitrr-allowed_seeding": + torrent.add_tags(["qBitrr-allowed_seeding"]) + elif tag == "qBitrr-imported": + torrent.add_tags(["qBitrr-imported"]) + elif tag == "qBitrr-allowed_stalled": + torrent.add_tags(["qBitrr-allowed_stalled"]) + elif tag == "qBitrr-free_space_paused": + torrent.add_tags(["qBitrr-free_space_paused"]) def _get_models( self, From 14a7d2c80f9e37600406dbfc08ce969eff9af59b Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 19 Aug 2024 15:10:55 +0200 Subject: [PATCH 089/101] Reduced datetime formatting --- qBitrr/arss.py | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 3f5a72e1..9c6a8d91 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -1998,7 +1998,11 @@ def minimum_availability_check( self, db_entry: JsonObject, ) -> bool: - if db_entry["year"] > datetime.now().year or db_entry["year"] == 0: + inCinemas = datetime.strptime(db_entry["inCinemas"], "%Y-%m-%dT%H:%M:%SZ") + digitalRelease = datetime.strptime(db_entry["digitalRelease"], "%Y-%m-%dT%H:%M:%SZ") + physicalRelease = datetime.strptime(db_entry["physicalRelease"], "%Y-%m-%dT%H:%M:%SZ") + now = datetime.now() + if db_entry["year"] > now.year or db_entry["year"] == 0: self.logger.trace( "Skipping 1 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], @@ -2008,7 +2012,7 @@ def minimum_availability_check( db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, ) return False - elif db_entry["year"] < datetime.now().year - 1 and db_entry["year"] != 0: + elif db_entry["year"] < now.year - 1 and db_entry["year"] != 0: self.logger.trace( "Grabbing 2 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], @@ -2038,12 +2042,7 @@ def minimum_availability_check( and "physicalRelease" in db_entry and db_entry["minimumAvailability"] == "released" ): - if ( - datetime.strptime(db_entry["digitalRelease"], "%Y-%m-%dT%H:%M:%SZ") - <= datetime.now() - or datetime.strptime(db_entry["physicalRelease"], "%Y-%m-%dT%H:%M:%SZ") - <= datetime.now() - ): + if digitalRelease <= now or physicalRelease <= now: self.logger.trace( "Grabbing 4 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], @@ -2067,10 +2066,7 @@ def minimum_availability_check( "minimumAvailability" ] == "released": if "digitalRelease" in db_entry: - if ( - datetime.strptime(db_entry["digitalRelease"], "%Y-%m-%dT%H:%M:%SZ") - <= datetime.now() - ): + if digitalRelease <= now: self.logger.trace( "Grabbing 6 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], @@ -2091,10 +2087,7 @@ def minimum_availability_check( ) return False elif "physicalRelease" in db_entry: - if ( - datetime.strptime(db_entry["physicalRelease"], "%Y-%m-%dT%H:%M:%SZ") - <= datetime.now() - ): + if physicalRelease <= now: self.logger.trace( "Grabbing 8 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], @@ -2130,7 +2123,7 @@ def minimum_availability_check( ) return True elif "inCinemas" in db_entry and db_entry["minimumAvailability"] == "inCinemas": - if datetime.strptime(db_entry["inCinemas"], "%Y-%m-%dT%H:%M:%SZ") <= datetime.now(): + if inCinemas <= now: self.logger.trace( "Grabbing 11 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], @@ -2152,10 +2145,7 @@ def minimum_availability_check( return False elif "inCinemas" not in db_entry and db_entry["minimumAvailability"] == "inCinemas": if "digitalRelease" in db_entry: - if ( - datetime.strptime(db_entry["digitalRelease"], "%Y-%m-%dT%H:%M:%SZ") - <= datetime.now() - ): + if digitalRelease <= now: self.logger.trace( "Grabbing 13 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], @@ -2176,10 +2166,7 @@ def minimum_availability_check( ) return False elif "physicalRelease" in db_entry: - if ( - datetime.strptime(db_entry["physicalRelease"], "%Y-%m-%dT%H:%M:%SZ") - <= datetime.now() - ): + if physicalRelease <= now: self.logger.trace( "Grabbing 15 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], From 1a74d25c0fac0847e9c491fb823de235f8678c6d Mon Sep 17 00:00:00 2001 From: Feramance Date: Mon, 19 Aug 2024 16:25:54 +0200 Subject: [PATCH 090/101] General Adjustments --- Makefile | 1 + qBitrr2.egg-info/PKG-INFO | 4 +-- requirements.all.txt | 53 +++++++++++++++++++-------------------- requirements.dev.txt | 53 +++++++++++++++++++-------------------- requirements.fast.txt | 10 +++++--- requirements.txt | 10 +++++--- 6 files changed, 67 insertions(+), 64 deletions(-) diff --git a/Makefile b/Makefile index 8836c837..7f990eae 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,7 @@ newenv: .venv/bin/pip install -U wheel $(MAKE) syncenv syncenv: + python.exe -m pip install --upgrade pip pip install -Ur requirements.all.txt help: @echo "$$HELP_BODY" diff --git a/qBitrr2.egg-info/PKG-INFO b/qBitrr2.egg-info/PKG-INFO index 3e55268a..f2529491 100644 --- a/qBitrr2.egg-info/PKG-INFO +++ b/qBitrr2.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: qBitrr2 -Version: 4.7.5 +Version: 4.8.3 Summary: "A simple Python script to talk to qBittorrent and Arr's" Home-page: https://github.com/Feramance/qBitrr Author: Feramance @@ -91,7 +91,7 @@ A simple script to monitor [qBit](https://github.com/qbittorrent/qBittorrent) an ## Notice -I am starting development on qBitrr+ which will be C# based for better overall performance and will also include a WebUI for better refined control on setting and what to search/upgrade etc. Hoping this will be the be all and end all application to manage your Radarr/Sonarr, Overseerr/Ombi and qBittorrent instances in one UI. This is still in it's very early stages and will likely be a couple months before a concrete beta is rolled out (from start of February 2024). Once I have something solid I will remove this notice and add a link to the new qBitrr+, in the meantime I will be sharing periodic updates on my [Patreon](https://patreon.com/qBitrr) +I am starting development on qBitrr+ which will be C# based for better overall performance and will also include a WebUI for better refined control on setting and what to search/upgrade etc. Hoping this will be the be all and end all application to manage your Radarr/Sonarr, Overseerr/Ombi and qBittorrent instances in one UI. This is still in it's very early stages and will likely be a couple months before a concrete alpha is rolled out (from start of February 2024). Once I have something solid I will remove this notice and add a link to the new qBitrr+, in the meantime I will be sharing periodic updates on my [Patreon](https://patreon.com/qBitrr) ## Features diff --git a/requirements.all.txt b/requirements.all.txt index edeada27..937fd7d5 100644 --- a/requirements.all.txt +++ b/requirements.all.txt @@ -6,7 +6,7 @@ # altgraph==0.17.4 # via pyinstaller -attrs==23.2.0 +attrs==24.2.0 # via environ-config backports-tarfile==1.2.0 # via jaraco-context @@ -20,8 +20,6 @@ cachetools==5.3.2 # via qBitrr2 (setup.py) certifi==2024.7.4 # via requests -cffi==1.16.0 - # via cryptography cfgv==3.4.0 # via pre-commit charset-normalizer==3.3.2 @@ -32,12 +30,13 @@ click==8.1.7 # pip-tools colorama==0.4.4 # via + # build + # click # qBitrr2 (setup.py) + # tqdm # twine coloredlogs==15.0.1 # via qBitrr2 (setup.py) -cryptography==42.0.8 - # via secretstorage dill==0.3.8 # via # multiprocess @@ -56,11 +55,11 @@ future==1.0.0 # via ffmpeg-python humanfriendly==10.0 # via coloredlogs -identify==2.5.36 +identify==2.6.0 # via pre-commit idna==3.7 # via requests -importlib-metadata==7.2.1 +importlib-metadata==8.2.0 # via # keyring # twine @@ -74,17 +73,13 @@ jaraco-context==5.3.0 # keyring jaraco-docker==2.0 # via qBitrr2 (setup.py) -jaraco-functools==4.0.1 +jaraco-functools==4.0.2 # via # jaraco-docker # keyring -jeepney==0.8.0 - # via - # keyring - # secretstorage -keyring==25.2.1 +keyring==25.3.0 # via twine -more-itertools==10.3.0 +more-itertools==10.4.0 # via # jaraco-classes # jaraco-functools @@ -92,7 +87,7 @@ multiprocess==0.70.16 # via pathos mypy-extensions==1.0.0 # via black -nh3==0.2.17 +nh3==0.2.18 # via readme-renderer nodeenv==1.9.1 # via pre-commit @@ -111,6 +106,8 @@ pathspec==0.12.1 # via black peewee==3.14.7 # via qBitrr2 (setup.py) +pefile==2023.2.7 + # via pyinstaller ping3==3.0.2 # via qBitrr2 (setup.py) pip-tools==7.3.0 @@ -129,23 +126,27 @@ pre-commit==3.3.3 # via qBitrr2 (setup.py) pyarr==5.2.0 # via qBitrr2 (setup.py) -pycparser==2.22 - # via cffi pygments==2.18.0 # via readme-renderer pyinstaller==5.13.1 # via qBitrr2 (setup.py) -pyinstaller-hooks-contrib==2024.7 +pyinstaller-hooks-contrib==2024.8 # via pyinstaller pyproject-hooks==1.1.0 # via build +pyreadline3==3.4.1 + # via humanfriendly pyupgrade==2.31.0 # via qBitrr2 (setup.py) -pyyaml==6.0.1 +pywin32-ctypes==0.2.3 + # via + # keyring + # pyinstaller +pyyaml==6.0.2 # via pre-commit qbittorrent-api==2023.7.52 # via qBitrr2 (setup.py) -readme-renderer==43.0 +readme-renderer==44.0 # via twine requests==2.32.0 # via @@ -158,11 +159,9 @@ requests-toolbelt==1.0.0 # via twine rfc3986==2.0.0 # via twine -secretstorage==3.3.3 - # via keyring six==1.16.0 # via qbittorrent-api -tokenize-rt==5.2.0 +tokenize-rt==6.0.0 # via pyupgrade tomli==2.0.1 # via @@ -171,11 +170,11 @@ tomli==2.0.1 # pip-tools tomlkit==0.7.2 # via qBitrr2 (setup.py) -tqdm==4.66.4 +tqdm==4.66.5 # via twine twine==3.7.1 # via qBitrr2 (setup.py) -types-requests==2.32.0.20240622 +types-requests==2.32.0.20240712 # via pyarr typing-extensions==4.12.2 # via black @@ -190,9 +189,9 @@ urllib3==2.2.2 # types-requests virtualenv==20.26.3 # via pre-commit -wheel==0.43.0 +wheel==0.44.0 # via pip-tools -zipp==3.19.2 +zipp==3.20.0 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements.dev.txt b/requirements.dev.txt index a4005384..56e8551e 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -6,7 +6,7 @@ # altgraph==0.17.4 # via pyinstaller -attrs==23.2.0 +attrs==24.2.0 # via environ-config backports-tarfile==1.2.0 # via jaraco-context @@ -20,8 +20,6 @@ cachetools==5.3.2 # via qBitrr2 (setup.py) certifi==2024.7.4 # via requests -cffi==1.16.0 - # via cryptography cfgv==3.4.0 # via pre-commit charset-normalizer==3.3.2 @@ -32,12 +30,13 @@ click==8.1.7 # pip-tools colorama==0.4.4 # via + # build + # click # qBitrr2 (setup.py) + # tqdm # twine coloredlogs==15.0.1 # via qBitrr2 (setup.py) -cryptography==42.0.8 - # via secretstorage dill==0.3.8 # via # multiprocess @@ -56,11 +55,11 @@ future==1.0.0 # via ffmpeg-python humanfriendly==10.0 # via coloredlogs -identify==2.5.36 +identify==2.6.0 # via pre-commit idna==3.7 # via requests -importlib-metadata==7.2.1 +importlib-metadata==8.2.0 # via # keyring # twine @@ -74,17 +73,13 @@ jaraco-context==5.3.0 # keyring jaraco-docker==2.0 # via qBitrr2 (setup.py) -jaraco-functools==4.0.1 +jaraco-functools==4.0.2 # via # jaraco-docker # keyring -jeepney==0.8.0 - # via - # keyring - # secretstorage -keyring==25.2.1 +keyring==25.3.0 # via twine -more-itertools==10.3.0 +more-itertools==10.4.0 # via # jaraco-classes # jaraco-functools @@ -92,7 +87,7 @@ multiprocess==0.70.16 # via pathos mypy-extensions==1.0.0 # via black -nh3==0.2.17 +nh3==0.2.18 # via readme-renderer nodeenv==1.9.1 # via pre-commit @@ -111,6 +106,8 @@ pathspec==0.12.1 # via black peewee==3.14.7 # via qBitrr2 (setup.py) +pefile==2023.2.7 + # via pyinstaller ping3==3.0.2 # via qBitrr2 (setup.py) pip-tools==7.3.0 @@ -129,23 +126,27 @@ pre-commit==3.3.3 # via qBitrr2 (setup.py) pyarr==5.2.0 # via qBitrr2 (setup.py) -pycparser==2.22 - # via cffi pygments==2.18.0 # via readme-renderer pyinstaller==5.13.1 # via qBitrr2 (setup.py) -pyinstaller-hooks-contrib==2024.7 +pyinstaller-hooks-contrib==2024.8 # via pyinstaller pyproject-hooks==1.1.0 # via build +pyreadline3==3.4.1 + # via humanfriendly pyupgrade==2.31.0 # via qBitrr2 (setup.py) -pyyaml==6.0.1 +pywin32-ctypes==0.2.3 + # via + # keyring + # pyinstaller +pyyaml==6.0.2 # via pre-commit qbittorrent-api==2023.7.52 # via qBitrr2 (setup.py) -readme-renderer==43.0 +readme-renderer==44.0 # via twine requests==2.32.0 # via @@ -158,11 +159,9 @@ requests-toolbelt==1.0.0 # via twine rfc3986==2.0.0 # via twine -secretstorage==3.3.3 - # via keyring six==1.16.0 # via qbittorrent-api -tokenize-rt==5.2.0 +tokenize-rt==6.0.0 # via pyupgrade tomli==2.0.1 # via @@ -171,11 +170,11 @@ tomli==2.0.1 # pip-tools tomlkit==0.7.2 # via qBitrr2 (setup.py) -tqdm==4.66.4 +tqdm==4.66.5 # via twine twine==3.7.1 # via qBitrr2 (setup.py) -types-requests==2.32.0.20240622 +types-requests==2.32.0.20240712 # via pyarr typing-extensions==4.12.2 # via black @@ -190,9 +189,9 @@ urllib3==2.2.2 # types-requests virtualenv==20.26.3 # via pre-commit -wheel==0.43.0 +wheel==0.44.0 # via pip-tools -zipp==3.19.2 +zipp==3.20.0 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements.fast.txt b/requirements.fast.txt index 23197f5f..8e0c0ad9 100644 --- a/requirements.fast.txt +++ b/requirements.fast.txt @@ -4,7 +4,7 @@ # # pip-compile --extra=fast --output-file=requirements.fast.txt # -attrs==23.2.0 +attrs==24.2.0 # via environ-config backports-tarfile==1.2.0 # via jaraco-context @@ -36,9 +36,9 @@ jaraco-context==5.3.0 # via jaraco-docker jaraco-docker==2.0 # via qBitrr2 (setup.py) -jaraco-functools==4.0.1 +jaraco-functools==4.0.2 # via jaraco-docker -more-itertools==10.3.0 +more-itertools==10.4.0 # via jaraco-functools multiprocess==0.70.16 # via pathos @@ -60,6 +60,8 @@ ppft==1.7.6.8 # via pathos pyarr==5.2.0 # via qBitrr2 (setup.py) +pyreadline3==3.4.1 + # via humanfriendly qbittorrent-api==2023.7.52 # via qBitrr2 (setup.py) requests==2.32.0 @@ -71,7 +73,7 @@ six==1.16.0 # via qbittorrent-api tomlkit==0.7.2 # via qBitrr2 (setup.py) -types-requests==2.32.0.20240622 +types-requests==2.32.0.20240712 # via pyarr ujson==5.4.0 # via qBitrr2 (setup.py) diff --git a/requirements.txt b/requirements.txt index 80a50b1f..3a084cee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # # pip-compile --output-file=requirements.txt # -attrs==23.2.0 +attrs==24.2.0 # via environ-config backports-tarfile==1.2.0 # via jaraco-context @@ -36,9 +36,9 @@ jaraco-context==5.3.0 # via jaraco-docker jaraco-docker==2.0 # via qBitrr2 (setup.py) -jaraco-functools==4.0.1 +jaraco-functools==4.0.2 # via jaraco-docker -more-itertools==10.3.0 +more-itertools==10.4.0 # via jaraco-functools multiprocess==0.70.16 # via pathos @@ -60,6 +60,8 @@ ppft==1.7.6.8 # via pathos pyarr==5.2.0 # via qBitrr2 (setup.py) +pyreadline3==3.4.1 + # via humanfriendly qbittorrent-api==2023.7.52 # via qBitrr2 (setup.py) requests==2.32.0 @@ -71,7 +73,7 @@ six==1.16.0 # via qbittorrent-api tomlkit==0.7.2 # via qBitrr2 (setup.py) -types-requests==2.32.0.20240622 +types-requests==2.32.0.20240712 # via pyarr urllib3==2.2.2 # via From fd4ce7f8c598d4cf1555ef14f1374e07a3d82694 Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 21 Aug 2024 11:51:46 +0200 Subject: [PATCH 091/101] Don't create tags (except ignore tag) if TAGLESS --- qBitrr/arss.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 5ea5e760..7f461c4b 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -516,7 +516,7 @@ def __init__( else: self.search_api_command = "MissingEpisodeSearch" - if not QBIT_DISABLED: + if not QBIT_DISABLED or TAGLESS: self.manager.qbit_manager.client.torrents_create_tags( [ "qBitrr-allowed_seeding", @@ -525,6 +525,12 @@ def __init__( "qBitrr-allowed_stalled", ] ) + elif not QBIT_DISABLED and TAGLESS: + self.manager.qbit_manager.client.torrents_create_tags( + [ + "qBitrr-ignored", + ] + ) self.search_setup_completed = False self.model_file: EpisodeFilesModel | MoviesFilesModel = None self.series_file_model: SeriesFilesModel = None From 0489feafff7e7e15031f6c9fa206b70d9376256c Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 21 Aug 2024 12:08:14 +0200 Subject: [PATCH 092/101] Additional condition changes --- qBitrr/arss.py | 84 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index eebf2fc3..5c4d561f 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -600,6 +600,36 @@ def is_downloading_state(torrent: TorrentDictionary) -> bool: TorrentStates.PAUSED_DOWNLOAD, ) + def in_tags(self, torrent: TorrentDictionary, tag: str) -> bool: + if TAGLESS: + condition = ( + self.torrents.Hash == torrent.hash & self.torrents.Category == torrent.category + ) + if tag == "qBitrr-allowed_seeding": + condition &= self.torrents.AllowedSeeding == True + elif tag == "qBitrr-imported": + condition &= self.torrents.Imported == True + elif tag == "qBitrr-allowed_stalled": + condition &= self.torrents.AllowedStalled == True + elif tag == "qBitrr-free_space_paused": + condition &= self.torrents.FreeSpacePaused == True + query = self.torrents.select().where(condition).execute() + if query: + return True + else: + return False + else: + if "qBitrr-allowed_seeding" in torrent.tags: + return True + elif "qBitrr-imported" in torrent.tags: + return True + elif "qBitrr-allowed_stalled" in torrent.tags: + return True + elif "qBitrr-free_space_paused" in torrent.tags: + return True + else: + return False + def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: for tag in tags: if TAGLESS: @@ -3519,7 +3549,7 @@ def _process_single_torrent_fully_completed_torrent( torrent.name, torrent.hash, ) - elif "qBitrr-imported" not in torrent.tags: + elif not self.in_tags(torrent, "qBitrr-imported"): self.logger.info( "Importing Completed torrent: " "[Progress: %s%%][Added On: %s]" @@ -3932,17 +3962,17 @@ def _should_leave_alone( return_value = not self.torrent_limit_check(torrent, seeding_time_limit, ratio_limit) if data_settings.get("super_seeding", False) or data_torrent.get("super_seeding", False): return_value = True - if "qBitrr-free_space_paused" in torrent.tags: + if self.in_tags(torrent, "qBitrr-free_space_paused"): return_value = True if ( return_value - and "qBitrr-allowed_seeding" not in torrent.tags - and "qBitrr-free_space_paused" not in torrent.tags + and not self.in_tags(torrent, "qBitrr-allowed_seeding") + and not self.in_tags(torrent, "qBitrr-free_space_paused") ): self.add_tags(torrent, ["qBitrr-allowed_seeding"]) elif ( - not return_value and "qBitrr-allowed_seeding" in torrent.tags - ) or "qBitrr-free_space_paused" in torrent.tags: + not return_value and self.in_tags(torrent, "qBitrr-allowed_seeding") + ) or self.in_tags(torrent, "qBitrr-free_space_paused"): self.remove_tags(torrent, ["qBitrr-allowed_seeding"]) return ( return_value, @@ -4127,8 +4157,8 @@ def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: fl TorrentStates.METADATA_DOWNLOAD, TorrentStates.STALLED_DOWNLOAD, ) - and "qBitrr-ignored" not in torrent.tags - and "qBitrr-free_space_paused" not in torrent.tags + and not self.in_tags(torrent, "qBitrr-ignored") + and not self.in_tags(torrent, "qBitrr-free_space_paused") ) or ( ( @@ -4138,8 +4168,8 @@ def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: fl ) and torrent.hash in self.cleaned_torrents and torrent.state_enum in (TorrentStates.DOWNLOADING) - and "qBitrr-ignored" not in torrent.tags - and "qBitrr-free_space_paused" not in torrent.tags + and not self.in_tags(torrent, "qBitrr-ignored") + and not self.in_tags(torrent, "qBitrr-free_space_paused") ) ) and self.allowed_stalled: if ( @@ -4151,7 +4181,7 @@ def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: fl "Process stalled, delay expired: %s", torrent.name, ) - elif "qBitrr-allowed_stalled" not in torrent.tags: + elif not self.in_tags(torrent, "qBitrr-allowed_stalled"): self.add_tags(torrent, ["qBitrr-allowed_stalled"]) if self.re_search_stalled: self.logger.trace( @@ -4173,13 +4203,13 @@ def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: fl "Stalled, adding tag: %s", torrent.name, ) - elif "qBitrr-allowed_stalled" in torrent.tags: + elif self.in_tags(torrent, "qBitrr-allowed_stalled"): self.logger.trace( "Stalled: %s", torrent.name, ) - elif "qBitrr-allowed_stalled" in torrent.tags: + elif self.in_tags(torrent, "qBitrr-allowed_stalled"): self.remove_tags(torrent, ["qBitrr-allowed_stalled"]) stalled_ignore = False self.logger.trace( @@ -4212,7 +4242,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): stalled_ignore = self._stalled_check(torrent, time_now) - if "qBitrr-ignored" in torrent.tags: + if self.in_tags(torrent, "qBitrr-ignored"): self.remove_tags( torrent, [ @@ -4224,8 +4254,8 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): if ( self.custom_format_unmet_search and self.custom_format_unmet_check(torrent) - and "qBitrr-ignored" not in torrent.tags - and "qBitrr-free_space_paused" not in torrent.tags + and not self.in_tags(torrent, "qBitrr-ignored") + and not self.in_tags(torrent, "qBitrr-free_space_paused") ): self._process_single_torrent_delete_cfunmet(torrent) elif remove_torrent and not leave_alone and torrent.amount_left == 0: @@ -4244,8 +4274,8 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): TorrentStates.METADATA_DOWNLOAD, TorrentStates.STALLED_DOWNLOAD, ) - and "qBitrr-ignored" not in torrent.tags - and "qBitrr-free_space_paused" not in torrent.tags + and not self.in_tags(torrent, "qBitrr-ignored") + and not self.in_tags(torrent, "qBitrr-free_space_paused") and not stalled_ignore ): self._process_single_torrent_stalled_torrent(torrent, "Stalled State") @@ -4265,8 +4295,8 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): elif ( torrent.progress >= self.maximum_deletable_percentage and self.is_complete_state(torrent) is False - and "qBitrr-ignored" not in torrent.tags - and "qBitrr-free_space_paused" not in torrent.tags + and not self.in_tags(torrent, "qBitrr-ignored") + and not self.in_tags(torrent, "qBitrr-free_space_paused") and not stalled_ignore ) and torrent.hash in self.cleaned_torrents: self._process_single_torrent_percentage_threshold(torrent, maximum_eta) @@ -4274,7 +4304,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): elif ( torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD and torrent.amount_left != 0 - and "qBitrr-free_space_paused" not in torrent.tags + and not self.in_tags(torrent, "qBitrr-free_space_paused") ): self._process_single_torrent_paused(torrent) # Ignore torrents which have been submitted to their respective Arr @@ -4321,8 +4351,8 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): < time_now - self.ignore_torrents_younger_than and 0 < maximum_eta < torrent.eta and not self.do_not_remove_slow - and "qBitrr-ignored" not in torrent.tags - and "qBitrr-free_space_paused" not in torrent.tags + and not self.in_tags(torrent, "qBitrr-ignored") + and not self.in_tags(torrent, "qBitrr-free_space_paused") and not stalled_ignore ): self._process_single_torrent_delete_slow(torrent) @@ -4338,8 +4368,8 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and torrent.hash in self.cleaned_torrents and self.is_downloading_state(torrent) - and "qBitrr-ignored" not in torrent.tags - and "qBitrr-free_space_paused" not in torrent.tags + and not self.in_tags(torrent, "qBitrr-ignored") + and not self.in_tags(torrent, "qBitrr-free_space_paused") and not stalled_ignore ): self._process_single_torrent_stalled_torrent(torrent, "Unavailable") @@ -5342,7 +5372,9 @@ def _process_single_torrent(self, torrent): ) self.current_free_space = free_space_test self.remove_tags(torrent, ["qBitrr-free_space_paused"]) - elif not self.is_downloading_state(torrent) and "qBitrr-free_space_paused" in torrent.tags: + elif not self.is_downloading_state(torrent) and self.in_tags( + torrent, "qBitrr-free_space_paused" + ): self.logger.info( "Removing tag [%s] for completed torrent[%s]: Free space %s", "qBitrr-free_space_paused", From e532057659f4f38ab5e186ee59e58df8cc615e61 Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 21 Aug 2024 12:10:58 +0200 Subject: [PATCH 093/101] Minimum availability date fixes --- qBitrr/arss.py | 132 +++++++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 60 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 5c4d561f..d62c80f2 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -2034,18 +2034,30 @@ def minimum_availability_check( self, db_entry: JsonObject, ) -> bool: - inCinemas = datetime.strptime(db_entry["inCinemas"], "%Y-%m-%dT%H:%M:%SZ") - digitalRelease = datetime.strptime(db_entry["digitalRelease"], "%Y-%m-%dT%H:%M:%SZ") - physicalRelease = datetime.strptime(db_entry["physicalRelease"], "%Y-%m-%dT%H:%M:%SZ") + inCinemas = ( + datetime.strptime(db_entry["inCinemas"], "%Y-%m-%dT%H:%M:%SZ") + if db_entry["inCinemas"] + else None + ) + digitalRelease = ( + datetime.strptime(db_entry["digitalRelease"], "%Y-%m-%dT%H:%M:%SZ") + if db_entry["digitalRelease"] + else None + ) + physicalRelease = ( + datetime.strptime(db_entry["physicalRelease"], "%Y-%m-%dT%H:%M:%SZ") + if db_entry["physicalRelease"] + else None + ) now = datetime.now() if db_entry["year"] > now.year or db_entry["year"] == 0: self.logger.trace( "Skipping 1 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return False elif db_entry["year"] < now.year - 1 and db_entry["year"] != 0: @@ -2053,9 +2065,9 @@ def minimum_availability_check( "Grabbing 2 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return True elif ( @@ -2068,9 +2080,9 @@ def minimum_availability_check( "Grabbing 3 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return True elif ( @@ -2083,9 +2095,9 @@ def minimum_availability_check( "Grabbing 4 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return True else: @@ -2093,9 +2105,9 @@ def minimum_availability_check( "Skipping 5 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return False elif ("digitalRelease" in db_entry or "physicalRelease" in db_entry) and db_entry[ @@ -2107,9 +2119,9 @@ def minimum_availability_check( "Grabbing 6 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return True else: @@ -2117,9 +2129,9 @@ def minimum_availability_check( "Skipping 7 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return False elif "physicalRelease" in db_entry: @@ -2128,9 +2140,9 @@ def minimum_availability_check( "Grabbing 8 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return True else: @@ -2138,9 +2150,9 @@ def minimum_availability_check( "Skipping 9 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return False elif ( @@ -2153,9 +2165,9 @@ def minimum_availability_check( "Grabbing 10 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return True elif "inCinemas" in db_entry and db_entry["minimumAvailability"] == "inCinemas": @@ -2164,9 +2176,9 @@ def minimum_availability_check( "Grabbing 11 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return True else: @@ -2174,9 +2186,9 @@ def minimum_availability_check( "Skipping 12 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return False elif "inCinemas" not in db_entry and db_entry["minimumAvailability"] == "inCinemas": @@ -2186,9 +2198,9 @@ def minimum_availability_check( "Grabbing 13 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return True else: @@ -2196,9 +2208,9 @@ def minimum_availability_check( "Skipping 14 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return False elif "physicalRelease" in db_entry: @@ -2207,9 +2219,9 @@ def minimum_availability_check( "Grabbing 15 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return True else: @@ -2217,9 +2229,9 @@ def minimum_availability_check( "Skipping 16 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return False else: @@ -2227,9 +2239,9 @@ def minimum_availability_check( "Skipping 17 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return False elif db_entry["minimumAvailability"] == "announced": @@ -2237,9 +2249,9 @@ def minimum_availability_check( "Grabbing 18 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return True else: @@ -2247,9 +2259,9 @@ def minimum_availability_check( "Skipping 19 %s - Minimum Availability: %s, Dates Cinema:%s, Digital:%s, Physical:%s", db_entry["title"], db_entry["minimumAvailability"], - db_entry["inCinemas"] if "inCinemas" in db_entry else None, - db_entry["digitalRelease"] if "digitalRelease" in db_entry else None, - db_entry["physicalRelease"] if "physicalRelease" in db_entry else None, + inCinemas, + digitalRelease, + physicalRelease, ) return False From 78d4853a52e811a22a6cc1fa445ed256a37f1a6e Mon Sep 17 00:00:00 2001 From: Feramance Date: Wed, 21 Aug 2024 15:32:18 +0200 Subject: [PATCH 094/101] LoopSleepTimer adjustments --- qBitrr/arss.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index d62c80f2..bd86c7f2 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -3247,7 +3247,7 @@ def process_torrents(self): raise qbittorrentapi.exceptions.APIError torrents = [t for t in torrents if hasattr(t, "category")] if not len(torrents): - raise DelayLoopException(length=5, type="no_downloads") + raise DelayLoopException(length=LOOP_SLEEP_TIMER, type="no_downloads") if has_internet() is False: self.manager.qbit_manager.should_delay_torrent_scan = True raise DelayLoopException(length=NO_INTERNET_SLEEP_TIMER, type="internet") @@ -5210,7 +5210,7 @@ def process_torrents(self): completed = True torrents = [t for t in torrents if hasattr(t, "category")] if not len(torrents): - raise DelayLoopException(length=5, type="no_downloads") + raise DelayLoopException(length=LOOP_SLEEP_TIMER, type="no_downloads") if has_internet() is False: self.manager.qbit_manager.should_delay_torrent_scan = True raise DelayLoopException(length=NO_INTERNET_SLEEP_TIMER, type="internet") @@ -5416,7 +5416,7 @@ def process_torrents(self): torrents = [t for t in torrents if t.category in self.categories] torrents = [t for t in torrents if "qBitrr-ignored" not in t.tags] if not len(torrents): - raise DelayLoopException(length=5, type="no_downloads") + raise DelayLoopException(length=LOOP_SLEEP_TIMER, type="no_downloads") if has_internet() is False: self.manager.qbit_manager.should_delay_torrent_scan = True raise DelayLoopException(length=NO_INTERNET_SLEEP_TIMER, type="internet") From 25baaf4f2425ba2fbb06c40699894992676745f0 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 23 Aug 2024 00:25:16 +0200 Subject: [PATCH 095/101] digital release fixes and tag updates --- qBitrr/arss.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index bd86c7f2..5c4574ed 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -516,7 +516,7 @@ def __init__( else: self.search_api_command = "MissingEpisodeSearch" - if not QBIT_DISABLED or TAGLESS: + if not QBIT_DISABLED and not TAGLESS: self.manager.qbit_manager.client.torrents_create_tags( [ "qBitrr-allowed_seeding", @@ -2039,11 +2039,14 @@ def minimum_availability_check( if db_entry["inCinemas"] else None ) - digitalRelease = ( - datetime.strptime(db_entry["digitalRelease"], "%Y-%m-%dT%H:%M:%SZ") - if db_entry["digitalRelease"] - else None - ) + try: + digitalRelease = ( + datetime.strptime(db_entry["digitalRelease"], "%Y-%m-%dT%H:%M:%SZ") + if db_entry["digitalRelease"] + else None + ) + except: + digitalRelease = None physicalRelease = ( datetime.strptime(db_entry["physicalRelease"], "%Y-%m-%dT%H:%M:%SZ") if db_entry["physicalRelease"] From 8ca91c3a5203a2eddc02bb51b9479c99daeb7555 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 23 Aug 2024 00:40:41 +0200 Subject: [PATCH 096/101] Key error fixes --- qBitrr/arss.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 5c4574ed..45454b49 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -2036,20 +2036,17 @@ def minimum_availability_check( ) -> bool: inCinemas = ( datetime.strptime(db_entry["inCinemas"], "%Y-%m-%dT%H:%M:%SZ") - if db_entry["inCinemas"] + if "inCinemas" in db_entry + else None + ) + digitalRelease = ( + datetime.strptime(db_entry["digitalRelease"], "%Y-%m-%dT%H:%M:%SZ") + if "digitalRelease" in db_entry else None ) - try: - digitalRelease = ( - datetime.strptime(db_entry["digitalRelease"], "%Y-%m-%dT%H:%M:%SZ") - if db_entry["digitalRelease"] - else None - ) - except: - digitalRelease = None physicalRelease = ( datetime.strptime(db_entry["physicalRelease"], "%Y-%m-%dT%H:%M:%SZ") - if db_entry["physicalRelease"] + if "physicalRelease" in db_entry else None ) now = datetime.now() From e56232cfa6b934b7ce3bb563ef90c63b9e6dceeb Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 23 Aug 2024 11:20:22 +0200 Subject: [PATCH 097/101] Added tag loging to monitor changes when tagless --- qBitrr/arss.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 45454b49..452446d2 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -601,6 +601,7 @@ def is_downloading_state(torrent: TorrentDictionary) -> bool: ) def in_tags(self, torrent: TorrentDictionary, tag: str) -> bool: + retrun_value = False if TAGLESS: condition = ( self.torrents.Hash == torrent.hash & self.torrents.Category == torrent.category @@ -615,22 +616,28 @@ def in_tags(self, torrent: TorrentDictionary, tag: str) -> bool: condition &= self.torrents.FreeSpacePaused == True query = self.torrents.select().where(condition).execute() if query: - return True + retrun_value = True else: - return False + retrun_value = False else: if "qBitrr-allowed_seeding" in torrent.tags: - return True + retrun_value = True elif "qBitrr-imported" in torrent.tags: - return True + retrun_value = True elif "qBitrr-allowed_stalled" in torrent.tags: - return True + retrun_value = True elif "qBitrr-free_space_paused" in torrent.tags: - return True - else: - return False + retrun_value = True + + if retrun_value: + self.logger.trace("Tag %s in %s", tag, torrent.name) + return True + else: + self.logger.trace("Tag %s not in %s", tag, torrent.name) + return False def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: + self.logger.trace("Removing tag %s from %s", tag, torrent.name) for tag in tags: if TAGLESS: query = ( @@ -681,6 +688,7 @@ def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: torrent.remove_tags(["qBitrr-free_space_paused"]) def add_tags(self, torrent: TorrentDictionary, tags: list) -> None: + self.logger.trace("Adding tag %s from %s", tag, torrent.name) for tag in tags: if TAGLESS: query = ( From 060c9538920048d23a303e227e6fc3f08a4e26da Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 23 Aug 2024 11:27:38 +0200 Subject: [PATCH 098/101] Hotfix --- qBitrr/arss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 452446d2..79d3f091 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -637,8 +637,8 @@ def in_tags(self, torrent: TorrentDictionary, tag: str) -> bool: return False def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: - self.logger.trace("Removing tag %s from %s", tag, torrent.name) for tag in tags: + self.logger.trace("Removing tag %s from %s", tag, torrent.name) if TAGLESS: query = ( self.torrents.select() @@ -688,8 +688,8 @@ def remove_tags(self, torrent: TorrentDictionary, tags: list) -> None: torrent.remove_tags(["qBitrr-free_space_paused"]) def add_tags(self, torrent: TorrentDictionary, tags: list) -> None: - self.logger.trace("Adding tag %s from %s", tag, torrent.name) for tag in tags: + self.logger.trace("Adding tag %s from %s", tag, torrent.name) if TAGLESS: query = ( self.torrents.select() From 4e37ce595101d6421cfd0d8db017c149e1a8696b Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 23 Aug 2024 11:35:15 +0200 Subject: [PATCH 099/101] Stalled adjustment --- qBitrr/arss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 79d3f091..8eb3d58f 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4296,7 +4296,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and not self.in_tags(torrent, "qBitrr-ignored") and not self.in_tags(torrent, "qBitrr-free_space_paused") - and not stalled_ignore + and stalled_ignore ): self._process_single_torrent_stalled_torrent(torrent, "Stalled State") elif ( From ca001e865f009ee615994697d1a3b328e76cb3e3 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 23 Aug 2024 11:35:58 +0200 Subject: [PATCH 100/101] STalled adjustment 2 --- qBitrr/arss.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 8eb3d58f..f89a18f9 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -4152,7 +4152,7 @@ def _process_single_torrent_trackers(self, torrent: qbittorrentapi.TorrentDictio def _stalled_check(self, torrent: qbittorrentapi.TorrentDictionary, time_now: float) -> bool: stalled_ignore = True if not self.allowed_stalled: - return stalled_ignore + return False if self.stalled_delay == 0: self.logger.trace( "Stalled check: %s [Current:%s][Added:%s][Limit:No Limit]", @@ -4296,7 +4296,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): ) and not self.in_tags(torrent, "qBitrr-ignored") and not self.in_tags(torrent, "qBitrr-free_space_paused") - and stalled_ignore + and not stalled_ignore ): self._process_single_torrent_stalled_torrent(torrent, "Stalled State") elif ( From c072f9d2c9e6146ab8c318826df0e1d6c3997620 Mon Sep 17 00:00:00 2001 From: Feramance Date: Fri, 23 Aug 2024 11:46:30 +0200 Subject: [PATCH 101/101] Final changes --- requirements.all.txt | 4 ++-- requirements.dev.txt | 4 ++-- requirements.fast.txt | 2 +- requirements.txt | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/requirements.all.txt b/requirements.all.txt index 937fd7d5..ae0d54ed 100644 --- a/requirements.all.txt +++ b/requirements.all.txt @@ -59,7 +59,7 @@ identify==2.6.0 # via pre-commit idna==3.7 # via requests -importlib-metadata==8.2.0 +importlib-metadata==8.4.0 # via # keyring # twine @@ -67,7 +67,7 @@ isort==5.10.1 # via qBitrr2 (setup.py) jaraco-classes==3.4.0 # via keyring -jaraco-context==5.3.0 +jaraco-context==6.0.1 # via # jaraco-docker # keyring diff --git a/requirements.dev.txt b/requirements.dev.txt index 56e8551e..49128851 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -59,7 +59,7 @@ identify==2.6.0 # via pre-commit idna==3.7 # via requests -importlib-metadata==8.2.0 +importlib-metadata==8.4.0 # via # keyring # twine @@ -67,7 +67,7 @@ isort==5.10.1 # via qBitrr2 (setup.py) jaraco-classes==3.4.0 # via keyring -jaraco-context==5.3.0 +jaraco-context==6.0.1 # via # jaraco-docker # keyring diff --git a/requirements.fast.txt b/requirements.fast.txt index 8e0c0ad9..fe219499 100644 --- a/requirements.fast.txt +++ b/requirements.fast.txt @@ -32,7 +32,7 @@ humanfriendly==10.0 # via coloredlogs idna==3.7 # via requests -jaraco-context==5.3.0 +jaraco-context==6.0.1 # via jaraco-docker jaraco-docker==2.0 # via qBitrr2 (setup.py) diff --git a/requirements.txt b/requirements.txt index 3a084cee..5df8e394 100644 --- a/requirements.txt +++ b/requirements.txt @@ -32,7 +32,7 @@ humanfriendly==10.0 # via coloredlogs idna==3.7 # via requests -jaraco-context==5.3.0 +jaraco-context==6.0.1 # via jaraco-docker jaraco-docker==2.0 # via qBitrr2 (setup.py)