diff --git a/.github/workflows/Dependabot Auto-approve.yml b/.github/workflows/Dependabot Auto-approve.yml index b22c6a7e..1c0ccd5b 100644 --- a/.github/workflows/Dependabot Auto-approve.yml +++ b/.github/workflows/Dependabot Auto-approve.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.0.0 + uses: dependabot/fetch-metadata@v2.1.0 with: github-token: ${{ secrets.PAT }} - name: Enable auto-merge for Dependabot PRs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 46a07e85..27c59cd0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,7 +53,7 @@ jobs: git_tag_gpgsign: true id: import_gpg - name: Git Auto Commit - uses: stefanzweifel/git-auto-commit-action@v5.0.0 + uses: stefanzweifel/git-auto-commit-action@v5.0.1 with: commit_message: '[skip ci]Automated version bump: v${{ github.job.get_current_version.current_version.outputs.VERSION }} >> v${{ steps.new_version.outputs.VERSION }}' tagging_message: v${{ steps.new_version.outputs.VERSION }} @@ -132,7 +132,7 @@ jobs: git_tag_gpgsign: true id: import_gpg - name: Git Auto Commit - uses: stefanzweifel/git-auto-commit-action@v5.0.0 + uses: stefanzweifel/git-auto-commit-action@v5.0.1 with: commit_message: '[skip ci] Update Release Hash for v${{needs.bump_version.outputs.NEW_RELEASE}}' commit_options: -S @@ -330,7 +330,7 @@ jobs: git_tag_gpgsign: true id: import_gpg - name: Git Auto Commit - uses: stefanzweifel/git-auto-commit-action@v5.0.0 + uses: stefanzweifel/git-auto-commit-action@v5.0.1 with: commit_message: '[skip ci] Update CHANGELOG.md and Release Notes for v${{needs.bump_version.outputs.NEW_RELEASE}}' commit_options: -S diff --git a/qBitrr/arss.py b/qBitrr/arss.py index 3c494f06..4a9195a9 100755 --- a/qBitrr/arss.py +++ b/qBitrr/arss.py @@ -118,12 +118,6 @@ def __init__( self._name, self.completed_folder, ) - self.min_free_space = FREE_SPACE - if self.min_free_space != "-1": - self.current_free_space = shutil.disk_usage(self.completed_folder).free - parse_size( - self.min_free_space - ) - self.logger.trace("Current free space: %s", self.current_free_space) self.apikey = CONFIG.get_or_raise(f"{name}.APIKey") self.re_search = CONFIG.get(f"{name}.ReSearch", fallback=False) self.import_mode = CONFIG.get(f"{name}.importMode", fallback="Auto") @@ -488,7 +482,6 @@ def __init__( [ "qBitrr-allowed_seeding", "qBitrr-ignored", - "qBitrr-free_space_paused", "qbitrr-imported", ] ) @@ -2962,15 +2955,7 @@ def process_torrents(self): raise DelayLoopException(length=NO_INTERNET_SLEEP_TIMER, type="delay") self.api_calls() self.refresh_download_queue() - if self.min_free_space != "-1": - self.current_free_space = shutil.disk_usage( - self.completed_folder - ).free - parse_size(self.min_free_space) - self.logger.trace("Current free space: %s", self.current_free_space) - sorted_torrents = sorted(torrents, key=lambda t: t["priority"]) - else: - sorted_torrents = torrents - for torrent in sorted_torrents: + for torrent in torrents: with contextlib.suppress(qbittorrentapi.NotFound404Error): self._process_single_torrent(torrent) self.process() @@ -3327,24 +3312,6 @@ def _process_single_torrent_missing_files(self, torrent: qbittorrentapi.TorrentD # We do not want to blacklist these!! self.remove_from_qbit.add(torrent.hash) - def _process_single_torrent_pause_disk_space(self, torrent: qbittorrentapi.TorrentDictionary): - self.logger.info( - "Pausing torrent for disk space: " - "[Progress: %s%%][Added On: %s]" - "[Availability: %s%%][Time Left: %s]" - "[Last active: %s] " - "| [%s] | %s (%s)", - round(torrent.progress * 100, 2), - datetime.fromtimestamp(self.recently_queue.get(torrent.hash, torrent.added_on)), - round(torrent.availability * 100, 2), - timedelta(seconds=torrent.eta), - datetime.fromtimestamp(torrent.last_activity), - torrent.state_enum, - torrent.name, - torrent.hash, - ) - self.pause.add(torrent.hash) - def _process_single_torrent_uploading( self, torrent: qbittorrentapi.TorrentDictionary, leave_alone: bool ): @@ -3700,33 +3667,6 @@ 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.is_downloading_state(torrent) and self.min_free_space != "-1": - free_space_test = self.current_free_space - free_space_test -= torrent["amount_left"] - self.logger.trace("Resulting free space: %s", 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) - torrent.add_tags(tags=["qBitrr-free_space_paused"]) - torrent.remove_tags(tags=["qBitrr-allowed_seeding"]) - elif ( - torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD - 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) - torrent.remove_tags(tags=["qBitrr-free_space_paused"]) - elif self.is_complete_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, - self.current_free_space, - ) - torrent.remove_tags(tags=["qBitrr-free_space_paused"]) - if self.seeding_mode_global_remove_torrent != -1 and self.remove_torrent( torrent, seeding_time_limit, ratio_limit ): @@ -3928,12 +3868,7 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): "qBitrr-free_space_paused", ] ) - if ( - "qBitrr-free_space_paused" in torrent.tags - and torrent.state_enum != TorrentStates.PAUSED_DOWNLOAD - ): - self._process_single_torrent_pause_disk_space(torrent) - elif self.custom_format_unmet_search and self.custom_format_unmet_check(torrent): + if self.custom_format_unmet_search and self.custom_format_unmet_check(torrent): self._process_single_torrent_delete_cfunmet(torrent) elif remove_torrent and not leave_alone and torrent.amount_left == 0: self._process_single_torrent_delete_ratio_seed(torrent) @@ -4051,8 +3986,6 @@ def _process_single_torrent(self, torrent: qbittorrentapi.TorrentDictionary): self._process_single_completed_paused_torrent(torrent, leave_alone) else: self._process_single_torrent_unprocessed(torrent) - if "qBitrr-free_space_paused" in torrent.tags: - self._process_single_torrent_pause_disk_space(torrent) def custom_format_unmet_check(self, torrent: qbittorrentapi.TorrentDictionary) -> bool: try: @@ -4758,7 +4691,19 @@ def __init__( self.timed_skip = ExpiringSet(max_age_seconds=self.ignore_torrents_younger_than) self.tracker_delay = ExpiringSet(max_age_seconds=600) self._LOG_LEVEL = self.manager.qbit_manager.logger.level - self.logger = logging.getLogger(f"qBitrr.{self._name}") + if ENABLE_LOGS: + LOGS_FOLDER = HOME_PATH.joinpath("logs") + LOGS_FOLDER.mkdir(parents=True, exist_ok=True) + LOGS_FOLDER.chmod(mode=0o777) + logfile = LOGS_FOLDER.joinpath(self._name + ".log") + if pathlib.Path(logfile).is_file(): + logold = LOGS_FOLDER.joinpath(self._name + ".log.old") + logfile.rename(logold) + fh = logging.FileHandler(logfile) + self.logger = logging.getLogger(f"qBitrr.{self._name}") + self.logger.addHandler(fh) + else: + self.logger = logging.getLogger(f"qBitrr.{self._name}") run_logs(self.logger) self.search_missing = False self.session = None @@ -4877,11 +4822,178 @@ def run_search_loop(self): return +class FreeSpaceManager(Arr): + def __init__(self, categories: set[str]): + self._name = "FreeSpaceManager" + self.categories = categories + self.pause = set() + self.resume = set() + self._LOG_LEVEL = self.manager.qbit_manager.logger.level + if ENABLE_LOGS: + LOGS_FOLDER = HOME_PATH.joinpath("logs") + LOGS_FOLDER.mkdir(parents=True, exist_ok=True) + LOGS_FOLDER.chmod(mode=0o777) + logfile = LOGS_FOLDER.joinpath(self._name + ".log") + if pathlib.Path(logfile).is_file(): + logold = LOGS_FOLDER.joinpath(self._name + ".log.old") + logfile.rename(logold) + fh = logging.FileHandler(logfile) + self.logger = logging.getLogger(f"qBitrr.{self._name}") + self.logger.addHandler(fh) + else: + self.logger = logging.getLogger(f"qBitrr.{self._name}") + run_logs(self.logger) + self.min_free_space = FREE_SPACE + self.current_free_space = shutil.disk_usage(self.completed_folder).free - parse_size( + self.min_free_space + ) + self.completed_folder = pathlib.Path(COMPLETED_DOWNLOAD_FOLDER) + if self.min_free_space != "-1": + self.current_free_space = shutil.disk_usage(self.completed_folder).free - parse_size( + self.min_free_space + ) + self.logger.trace("Current free space: %s", self.current_free_space) + self.manager.qbit_manager.client.torrents_create_tags( + [ + "qBitrr-free_space_paused", + ] + ) + + def _process_single_torrent_pause_disk_space(self, torrent: qbittorrentapi.TorrentDictionary): + self.logger.info( + "Pausing torrent for disk space: " + "[Progress: %s%%][Added On: %s]" + "[Availability: %s%%][Time Left: %s]" + "[Last active: %s] " + "| [%s] | %s (%s)", + round(torrent.progress * 100, 2), + datetime.fromtimestamp(self.recently_queue.get(torrent.hash, torrent.added_on)), + round(torrent.availability * 100, 2), + timedelta(seconds=torrent.eta), + datetime.fromtimestamp(torrent.last_activity), + torrent.state_enum, + torrent.name, + torrent.hash, + ) + self.pause.add(torrent.hash) + + def _process_single_torrent_resume_disk_space(self, torrent: qbittorrentapi.TorrentDictionary): + self.logger.info( + "Resuming torrent for disk space: " + "[Progress: %s%%][Added On: %s]" + "[Availability: %s%%][Time Left: %s]" + "[Last active: %s] " + "| [%s] | %s (%s)", + round(torrent.progress * 100, 2), + datetime.fromtimestamp(self.recently_queue.get(torrent.hash, torrent.added_on)), + round(torrent.availability * 100, 2), + timedelta(seconds=torrent.eta), + datetime.fromtimestamp(torrent.last_activity), + torrent.state_enum, + torrent.name, + torrent.hash, + ) + self.resume.add(torrent.hash) + + 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) + 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) + torrent.add_tags(tags=["qBitrr-free_space_paused"]) + torrent.remove_tags(tags=["qBitrr-allowed_seeding"]) + self._process_single_torrent_pause_disk_space(torrent.hash) + elif ( + torrent.state_enum == TorrentStates.PAUSED_DOWNLOAD + 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) + torrent.remove_tags(tags=["qBitrr-free_space_paused"]) + self._process_single_torrent_resume_disk_space(torrent.hash) + elif self.is_complete_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, + self.current_free_space, + ) + torrent.remove_tags(tags=["qBitrr-free_space_paused"]) + + def process(self): + self._process_paused() + self._process_resume() + + def process_torrents(self): + try: + try: + completed = True + while completed: + try: + completed = False + torrents = self.manager.qbit_manager.client.torrents.info( + status_filter="all", + category=self.category, + sort="added_on", + reverse=False, + ) + except qbittorrentapi.exceptions.APIError: + completed = True + torrents = [t for t in torrents if hasattr(t, "category")] + torrents = [t for t in torrents if t.category in self.categories] + if not len(torrents): + raise DelayLoopException(length=5, 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") + if self.manager.qbit_manager.should_delay_torrent_scan: + raise DelayLoopException(length=NO_INTERNET_SLEEP_TIMER, type="delay") + if self.min_free_space != "-1": + self.current_free_space = shutil.disk_usage( + self.completed_folder + ).free - parse_size(self.min_free_space) + self.logger.trace("Current free space: %s", self.current_free_space) + sorted_torrents = sorted(torrents, key=lambda t: t["priority"]) + else: + sorted_torrents = torrents + for torrent in sorted_torrents: + with contextlib.suppress(qbittorrentapi.NotFound404Error): + self._process_single_torrent(torrent) + self.process() + except NoConnectionrException as e: + self.logger.error(e.message) + except qbittorrentapi.exceptions.APIError as e: + self.logger.error("The qBittorrent API returned an unexpected error") + self.logger.debug("Unexpected APIError from qBitTorrent", exc_info=e) + raise DelayLoopException(length=300, type="qbit") + except qbittorrentapi.exceptions.APIConnectionError as e: + self.logger.warning("Max retries exceeded") + raise DelayLoopException(length=300, type="qbit") + except DelayLoopException: + raise + except KeyboardInterrupt: + self.logger.hnotice("Detected Ctrl+C - Terminating process") + sys.exit(0) + except Exception as e: + self.logger.error(e, exc_info=sys.exc_info()) + except KeyboardInterrupt: + self.logger.hnotice("Detected Ctrl+C - Terminating process") + sys.exit(0) + except DelayLoopException: + raise + + class ArrManager: def __init__(self, qbitmanager: qBitManager): self.groups: set[str] = set() self.uris: set[str] = set() self.special_categories: set[str] = {FAILED_CATEGORY, RECHECK_CATEGORY} + self.arr_categories: set[str] = set() self.category_allowlist: set[str] = self.special_categories.copy() self.completed_folders: set[pathlib.Path] = set() self.managed_objects: dict[str, Arr] = {} @@ -4916,6 +5028,7 @@ def build_arr_instances(self): self.groups.add(name) self.uris.add(managed_object.uri) self.managed_objects[managed_object.category] = managed_object + self.arr_categories.add(managed_object.category) except KeyError as e: self.logger.critical(e) except ValueError as e: @@ -4924,6 +5037,8 @@ def build_arr_instances(self): continue except (OSError, TypeError) as e: self.logger.exception(e) + if FREE_SPACE != "-1": + managed_object = FreeSpaceManager(self, self.arr_categories) for cat in self.special_categories: managed_object = PlaceHolderArr(cat, self) self.managed_objects[cat] = managed_object diff --git a/qBitrr2.egg-info/PKG-INFO b/qBitrr2.egg-info/PKG-INFO index a5030bf6..a4701b6c 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.4.1 +Version: 4.4.2 Summary: "A simple Python script to talk to qBittorrent and Arr's" Home-page: https://github.com/Feramance/qBitrr Author: Feramance @@ -34,7 +34,7 @@ Requires-Dist: coloredlogs==15.0.1 Requires-Dist: environ-config==23.2.0 Requires-Dist: ffmpeg-python==0.2.0 Requires-Dist: jaraco.docker==2.0 -Requires-Dist: packaging==21.3 +Requires-Dist: packaging==22.0 Requires-Dist: pathos==0.2.8 Requires-Dist: peewee==3.14.7 Requires-Dist: ping3==3.0.2 diff --git a/qBitrr2.egg-info/requires.txt b/qBitrr2.egg-info/requires.txt index 2a572bce..c95cc258 100644 --- a/qBitrr2.egg-info/requires.txt +++ b/qBitrr2.egg-info/requires.txt @@ -4,7 +4,7 @@ coloredlogs==15.0.1 environ-config==23.2.0 ffmpeg-python==0.2.0 jaraco.docker==2.0 -packaging==21.3 +packaging==22.0 pathos==0.2.8 peewee==3.14.7 ping3==3.0.2 diff --git a/requirements.all.txt b/requirements.all.txt index adf7eaef..59bd7616 100644 --- a/requirements.all.txt +++ b/requirements.all.txt @@ -8,9 +8,11 @@ altgraph==0.17.4 # via pyinstaller attrs==23.2.0 # via environ-config +backports-tarfile==1.1.1 + # via jaraco-context black==24.3.0 # via qBitrr2 (setup.py) -build==1.1.1 +build==1.2.1 # via pip-tools bump2version==1.0.1 # via qBitrr2 (setup.py) @@ -41,21 +43,21 @@ dill==0.3.8 # pathos distlib==0.3.8 # via virtualenv -docutils==0.20.1 +docutils==0.21.2 # via readme-renderer environ-config==23.2.0 # via qBitrr2 (setup.py) ffmpeg-python==0.2.0 # via qBitrr2 (setup.py) -filelock==3.13.3 +filelock==3.13.4 # via virtualenv future==1.0.0 # via ffmpeg-python humanfriendly==10.0 # via coloredlogs -identify==2.5.35 +identify==2.5.36 # via pre-commit -idna==3.6 +idna==3.7 # via requests importlib-metadata==7.1.0 # via @@ -63,19 +65,19 @@ importlib-metadata==7.1.0 # twine isort==5.10.1 # via qBitrr2 (setup.py) -jaraco-classes==3.3.1 +jaraco-classes==3.4.0 # via keyring -jaraco-context==4.3.0 +jaraco-context==5.3.0 # via # jaraco-docker # keyring jaraco-docker==2.0 # via qBitrr2 (setup.py) -jaraco-functools==4.0.0 +jaraco-functools==4.0.1 # via # jaraco-docker # keyring -keyring==25.0.0 +keyring==25.1.0 # via twine more-itertools==10.2.0 # via @@ -85,15 +87,16 @@ multiprocess==0.70.16 # via pathos mypy-extensions==1.0.0 # via black -nh3==0.2.15 +nh3==0.2.17 # via readme-renderer nodeenv==1.8.0 # via pre-commit overrides==7.7.0 # via pyarr -packaging==21.3 +packaging==22.0 # via # build + # pyinstaller-hooks-contrib # qBitrr2 (setup.py) # qbittorrent-api pathos==0.2.8 @@ -110,7 +113,7 @@ pip-tools==7.3.0 # via qBitrr2 (setup.py) pkginfo==1.10.0 # via twine -platformdirs==4.2.0 +platformdirs==4.2.1 # via # black # virtualenv @@ -126,10 +129,8 @@ pygments==2.17.2 # via readme-renderer pyinstaller==5.13.1 # via qBitrr2 (setup.py) -pyinstaller-hooks-contrib==2023.11 +pyinstaller-hooks-contrib==2024.5 # via pyinstaller -pyparsing==3.1.2 - # via packaging pyproject-hooks==1.0.0 # via build pyreadline3==3.4.1 @@ -173,7 +174,7 @@ tqdm==4.66.2 # via twine twine==3.7.1 # via qBitrr2 (setup.py) -types-requests==2.31.0.20240311 +types-requests==2.31.0.20240406 # via pyarr ujson==5.4.0 # via qBitrr2 (setup.py) @@ -184,7 +185,7 @@ urllib3==2.2.1 # qbittorrent-api # requests # types-requests -virtualenv==20.25.1 +virtualenv==20.26.0 # via pre-commit wheel==0.43.0 # via pip-tools diff --git a/requirements.dev.txt b/requirements.dev.txt index 1e70dd9a..e7ed0ec3 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -8,9 +8,11 @@ altgraph==0.17.4 # via pyinstaller attrs==23.2.0 # via environ-config +backports-tarfile==1.1.1 + # via jaraco-context black==24.3.0 # via qBitrr2 (setup.py) -build==1.1.1 +build==1.2.1 # via pip-tools bump2version==1.0.1 # via qBitrr2 (setup.py) @@ -41,21 +43,21 @@ dill==0.3.8 # pathos distlib==0.3.8 # via virtualenv -docutils==0.20.1 +docutils==0.21.2 # via readme-renderer environ-config==23.2.0 # via qBitrr2 (setup.py) ffmpeg-python==0.2.0 # via qBitrr2 (setup.py) -filelock==3.13.3 +filelock==3.13.4 # via virtualenv future==1.0.0 # via ffmpeg-python humanfriendly==10.0 # via coloredlogs -identify==2.5.35 +identify==2.5.36 # via pre-commit -idna==3.6 +idna==3.7 # via requests importlib-metadata==7.1.0 # via @@ -63,19 +65,19 @@ importlib-metadata==7.1.0 # twine isort==5.10.1 # via qBitrr2 (setup.py) -jaraco-classes==3.3.1 +jaraco-classes==3.4.0 # via keyring -jaraco-context==4.3.0 +jaraco-context==5.3.0 # via # jaraco-docker # keyring jaraco-docker==2.0 # via qBitrr2 (setup.py) -jaraco-functools==4.0.0 +jaraco-functools==4.0.1 # via # jaraco-docker # keyring -keyring==25.0.0 +keyring==25.1.0 # via twine more-itertools==10.2.0 # via @@ -85,15 +87,16 @@ multiprocess==0.70.16 # via pathos mypy-extensions==1.0.0 # via black -nh3==0.2.15 +nh3==0.2.17 # via readme-renderer nodeenv==1.8.0 # via pre-commit overrides==7.7.0 # via pyarr -packaging==21.3 +packaging==22.0 # via # build + # pyinstaller-hooks-contrib # qBitrr2 (setup.py) # qbittorrent-api pathos==0.2.8 @@ -110,7 +113,7 @@ pip-tools==7.3.0 # via qBitrr2 (setup.py) pkginfo==1.10.0 # via twine -platformdirs==4.2.0 +platformdirs==4.2.1 # via # black # virtualenv @@ -126,10 +129,8 @@ pygments==2.17.2 # via readme-renderer pyinstaller==5.13.1 # via qBitrr2 (setup.py) -pyinstaller-hooks-contrib==2023.11 +pyinstaller-hooks-contrib==2024.5 # via pyinstaller -pyparsing==3.1.2 - # via packaging pyproject-hooks==1.0.0 # via build pyreadline3==3.4.1 @@ -173,7 +174,7 @@ tqdm==4.66.2 # via twine twine==3.7.1 # via qBitrr2 (setup.py) -types-requests==2.31.0.20240311 +types-requests==2.31.0.20240406 # via pyarr ujson==5.4.0 # via qBitrr2 (setup.py) @@ -184,7 +185,7 @@ urllib3==2.2.1 # qbittorrent-api # requests # types-requests -virtualenv==20.25.1 +virtualenv==20.26.0 # via pre-commit wheel==0.43.0 # via pip-tools diff --git a/requirements.fast.txt b/requirements.fast.txt index 32f77e0d..d5bc70a1 100644 --- a/requirements.fast.txt +++ b/requirements.fast.txt @@ -6,6 +6,8 @@ # attrs==23.2.0 # via environ-config +backports-tarfile==1.1.1 + # via jaraco-context cachetools==5.3.2 # via qBitrr2 (setup.py) certifi==2024.2.2 @@ -28,13 +30,13 @@ future==1.0.0 # via ffmpeg-python humanfriendly==10.0 # via coloredlogs -idna==3.6 +idna==3.7 # via requests -jaraco-context==4.3.0 +jaraco-context==5.3.0 # via jaraco-docker jaraco-docker==2.0 # via qBitrr2 (setup.py) -jaraco-functools==4.0.0 +jaraco-functools==4.0.1 # via jaraco-docker more-itertools==10.2.0 # via jaraco-functools @@ -42,7 +44,7 @@ multiprocess==0.70.16 # via pathos overrides==7.7.0 # via pyarr -packaging==21.3 +packaging==22.0 # via # qBitrr2 (setup.py) # qbittorrent-api @@ -58,8 +60,6 @@ ppft==1.7.6.8 # via pathos pyarr==5.2.0 # via qBitrr2 (setup.py) -pyparsing==3.1.2 - # via packaging pyreadline3==3.4.1 # via humanfriendly qbittorrent-api==2023.7.52 @@ -73,7 +73,7 @@ six==1.16.0 # via qbittorrent-api tomlkit==0.7.2 # via qBitrr2 (setup.py) -types-requests==2.31.0.20240311 +types-requests==2.31.0.20240406 # via pyarr ujson==5.4.0 # via qBitrr2 (setup.py) diff --git a/requirements.txt b/requirements.txt index 66d38700..fd9bd37e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,8 @@ # attrs==23.2.0 # via environ-config +backports-tarfile==1.1.1 + # via jaraco-context cachetools==5.3.2 # via qBitrr2 (setup.py) certifi==2024.2.2 @@ -28,13 +30,13 @@ future==1.0.0 # via ffmpeg-python humanfriendly==10.0 # via coloredlogs -idna==3.6 +idna==3.7 # via requests -jaraco-context==4.3.0 +jaraco-context==5.3.0 # via jaraco-docker jaraco-docker==2.0 # via qBitrr2 (setup.py) -jaraco-functools==4.0.0 +jaraco-functools==4.0.1 # via jaraco-docker more-itertools==10.2.0 # via jaraco-functools @@ -42,7 +44,7 @@ multiprocess==0.70.16 # via pathos overrides==7.7.0 # via pyarr -packaging==21.3 +packaging==22.0 # via # qBitrr2 (setup.py) # qbittorrent-api @@ -58,8 +60,6 @@ ppft==1.7.6.8 # via pathos pyarr==5.2.0 # via qBitrr2 (setup.py) -pyparsing==3.1.2 - # via packaging pyreadline3==3.4.1 # via humanfriendly qbittorrent-api==2023.7.52 @@ -73,7 +73,7 @@ six==1.16.0 # via qbittorrent-api tomlkit==0.7.2 # via qBitrr2 (setup.py) -types-requests==2.31.0.20240311 +types-requests==2.31.0.20240406 # via pyarr urllib3==2.2.1 # via diff --git a/setup.cfg b/setup.cfg index acd800c5..a3ce65ae 100644 --- a/setup.cfg +++ b/setup.cfg @@ -42,7 +42,7 @@ install_requires = environ-config==23.2.0 ffmpeg-python==0.2.0 jaraco.docker==2.0 - packaging==21.3 + packaging==22.0 pathos==0.2.8 peewee==3.14.7 ping3==3.0.2