From 8c490b1d2c62fe2d75da3b25c09947e7548deaa5 Mon Sep 17 00:00:00 2001 From: Russell Martin Date: Thu, 2 Nov 2023 11:19:27 -0400 Subject: [PATCH] Add support for `torrents/count` (closes #365) --- CHANGELOG.md | 3 + src/qbittorrentapi/torrents.py | 115 ++++++++++++++++++--------------- tests/test_torrents.py | 13 ++++ 3 files changed, 80 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b4b7b38e..fb1842e9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ Change Log ========== +### v2023.mm.56 (dd mmm 2023) +- Add support for ``torrents/count`` (#366) + ### v2023.11.55 (6 nov 2023) - Remove Python 2 platform tag from published wheel (#369) diff --git a/src/qbittorrentapi/torrents.py b/src/qbittorrentapi/torrents.py index 4098839a4..e015712d8 100644 --- a/src/qbittorrentapi/torrents.py +++ b/src/qbittorrentapi/torrents.py @@ -422,6 +422,15 @@ def _normalize_torrent_files( raise TorrentFileError(io_err) return files + def torrents_count(self) -> int: + """Retrieve count of torrents.""" + return self._post_cast( + _name=APINames.Torrents, + _method="count", + response_class=int, + version_introduced="2.9.3", + ) + ########################################################################## # INDIVIDUAL TORRENT ENDPOINTS ########################################################################## @@ -2280,57 +2289,6 @@ def __init__(self, client: TorrentsAPIMixIn) -> None: ) self.addPeers = self.add_peers - @wraps(TorrentsAPIMixIn.torrents_add) - def add( - self, - urls: Iterable[str] | None = None, - torrent_files: TorrentFilesT | None = None, - save_path: str | None = None, - cookie: str | None = None, - category: str | None = None, - is_skip_checking: bool | None = None, - is_paused: bool | None = None, - is_root_folder: bool | None = None, - rename: str | None = None, - upload_limit: str | int | None = None, - download_limit: str | int | None = None, - use_auto_torrent_management: bool | None = None, - is_sequential_download: bool | None = None, - is_first_last_piece_priority: bool | None = None, - tags: Iterable[str] | None = None, - content_layout: None | (Literal["Original", "Subfolder", "NoSubFolder"]) = None, - ratio_limit: str | float | None = None, - seeding_time_limit: str | int | None = None, - download_path: str | None = None, - use_download_path: bool | None = None, - stop_condition: Literal["MetadataReceived", "FilesChecked"] | None = None, - **kwargs: APIKwargsT, - ) -> str: - return self._client.torrents_add( - urls=urls, - torrent_files=torrent_files, - save_path=save_path, - cookie=cookie, - category=category, - is_skip_checking=is_skip_checking, - is_paused=is_paused, - is_root_folder=is_root_folder, - rename=rename, - upload_limit=upload_limit, - download_limit=download_limit, - is_sequential_download=is_sequential_download, - use_auto_torrent_management=use_auto_torrent_management, - is_first_last_piece_priority=is_first_last_piece_priority, - tags=tags, - content_layout=content_layout, - ratio_limit=ratio_limit, - seeding_time_limit=seeding_time_limit, - download_path=download_path, - use_download_path=use_download_path, - stop_condition=stop_condition, - **kwargs, - ) - class _ActionForAllTorrents(ClientCache["TorrentsAPIMixIn"]): def __init__( self, @@ -2697,6 +2655,61 @@ def errored( **kwargs, ) + @wraps(TorrentsAPIMixIn.torrents_add) + def add( + self, + urls: Iterable[str] | None = None, + torrent_files: TorrentFilesT | None = None, + save_path: str | None = None, + cookie: str | None = None, + category: str | None = None, + is_skip_checking: bool | None = None, + is_paused: bool | None = None, + is_root_folder: bool | None = None, + rename: str | None = None, + upload_limit: str | int | None = None, + download_limit: str | int | None = None, + use_auto_torrent_management: bool | None = None, + is_sequential_download: bool | None = None, + is_first_last_piece_priority: bool | None = None, + tags: Iterable[str] | None = None, + content_layout: None | (Literal["Original", "Subfolder", "NoSubFolder"]) = None, + ratio_limit: str | float | None = None, + seeding_time_limit: str | int | None = None, + download_path: str | None = None, + use_download_path: bool | None = None, + stop_condition: Literal["MetadataReceived", "FilesChecked"] | None = None, + **kwargs: APIKwargsT, + ) -> str: + return self._client.torrents_add( + urls=urls, + torrent_files=torrent_files, + save_path=save_path, + cookie=cookie, + category=category, + is_skip_checking=is_skip_checking, + is_paused=is_paused, + is_root_folder=is_root_folder, + rename=rename, + upload_limit=upload_limit, + download_limit=download_limit, + is_sequential_download=is_sequential_download, + use_auto_torrent_management=use_auto_torrent_management, + is_first_last_piece_priority=is_first_last_piece_priority, + tags=tags, + content_layout=content_layout, + ratio_limit=ratio_limit, + seeding_time_limit=seeding_time_limit, + download_path=download_path, + use_download_path=use_download_path, + stop_condition=stop_condition, + **kwargs, + ) + + @wraps(TorrentsAPIMixIn.torrents_count) + def count(self) -> int: + return self._client.torrents_count() + @wraps(TorrentsAPIMixIn.torrents_properties) def properties( self, diff --git a/tests/test_torrents.py b/tests/test_torrents.py index b0f13b77f..9ca97603b 100644 --- a/tests/test_torrents.py +++ b/tests/test_torrents.py @@ -320,6 +320,19 @@ def test_torrents_add_download_path(client, use_download_path, tmp_path): check(lambda: mkpath(torrent.info.download_path), download_path) +@pytest.mark.skipif_before_api_version("2.9.3") +@pytest.mark.parametrize("count_func", ["torrents_count", "torrents.count"]) +def test_count(client, count_func): + assert client.func(count_func)() == 1 + + +@pytest.mark.skipif_after_api_version("2.9.3") +@pytest.mark.parametrize("count_func", ["torrents_count", "torrents.count"]) +def test_count_not_implemented(client, count_func): + with pytest.raises(NotImplementedError): + assert client.func(count_func)() == 1 + + @pytest.mark.parametrize( "properties_func", ["torrents_properties", "torrents.properties"] )