From 78c8a73af82f87812e9c47be047a20343d6c369c Mon Sep 17 00:00:00 2001 From: Steven Marks Date: Mon, 17 Apr 2023 13:18:33 +0000 Subject: [PATCH 1/7] feat(base): added get_quality_profile_schema() --- pyarr/base.py | 8 +++++++ pyarr/lidarr.py | 42 ++++++++++++++++++++++++--------- pyarr/request_handler.py | 1 - tests/test_lidarr.py | 50 +++++++++++----------------------------- tests/test_radarr.py | 5 ++++ tests/test_readarr.py | 5 ++++ tests/test_sonarr.py | 5 ++++ 7 files changed, 67 insertions(+), 49 deletions(-) diff --git a/pyarr/base.py b/pyarr/base.py index 5a1a71f..0a73b34 100644 --- a/pyarr/base.py +++ b/pyarr/base.py @@ -392,6 +392,14 @@ def upd_quality_definition(self, id_: int, data: JsonObject) -> JsonObject: """ return self._put(f"qualitydefinition/{id_}", self.ver_uri, data=data) + def get_quality_profile_schema(self) -> JsonArray: + """Get the schemas for quality profiles + + Returns: + JsonArray: List of dictionaries with items + """ + return self._get("qualityprofile/schema", self.ver_uri) + # INDEXER # GET /indexer/schema diff --git a/pyarr/lidarr.py b/pyarr/lidarr.py index 592f706..0909f58 100644 --- a/pyarr/lidarr.py +++ b/pyarr/lidarr.py @@ -744,23 +744,43 @@ def get_retag( # POST /qualityprofile def add_quality_profile( - self, name: str, upgrades_allowed: bool, cutoff: int, items: list + self, + name: str, + upgrade_allowed: bool, + cutoff: int, + schema: dict[str, Any], + language: dict, + min_format_score: int = 0, + cutoff_format_score: int = 0, + format_items: list = None, ) -> JsonObject: - """Add new quality profile + """Add new quality profile. Args: name (str): Name of the profile - upgrades_allowed (bool): Are upgrades in quality allowed? + upgrade_allowed (bool): Are upgrades in quality allowed? cutoff (int): ID of quality definition to cutoff at. Must be an allowed definition ID. - items (list): Add a list of items (from `get_quality_definition()`) + schema (dict[str, Any]): Add the profile schema (from `get_quality_profile_schema()`) + language (dict): Language profile (from `get_language()`) + min_format_score (int, optional): Minimum format score. Defaults to 0. + cutoff_format_score (int, optional): Cutoff format score. Defaults to 0. + format_items (list, optional): Format items. Defaults to []. + + Note: + Update the result from `get_quality_profile_schema()` set the items you need + from `"allowed": false` to `"allowed": true`. See tests for more details. Returns: JsonObject: An object containing the profile """ - data = { - "name": name, - "upgradeAllowed": upgrades_allowed, - "cutoff": cutoff, - "items": items, - } - return self._post("qualityprofile", self.ver_uri, data=data) + if format_items is None: + format_items = [] + schema["name"] = name + schema["upgradeAllowed"] = upgrade_allowed + schema["cutoff"] = cutoff + schema["formatItems"] = format_items + schema["language"] = language + schema["minFormatScore"] = min_format_score + schema["cutoffFormatScore"] = cutoff_format_score + + return self._post("qualityprofile", self.ver_uri, data=schema) diff --git a/pyarr/request_handler.py b/pyarr/request_handler.py index a50b40f..0b538c3 100644 --- a/pyarr/request_handler.py +++ b/pyarr/request_handler.py @@ -252,7 +252,6 @@ def _process_response( if res.status_code == 502: raise PyarrBadGateway("Bad Gateway. Check your server is accessible.") - print(res.status_code) content_type = res.headers.get("Content-Type", "") if "application/json" in content_type: return res.json() diff --git a/tests/test_lidarr.py b/tests/test_lidarr.py index e91943d..1abf55a 100644 --- a/tests/test_lidarr.py +++ b/tests/test_lidarr.py @@ -799,45 +799,16 @@ def test_get_history(lidarr_client: LidarrAPI): def test_add_quality_profile(lidarr_client: LidarrAPI): + language = lidarr_client.get_language()[0] + schema = lidarr_client.get_quality_profile_schema() + schema["items"][1]["allowed"] = True + data = lidarr_client.add_quality_profile( name="music", - upgrades_allowed=True, - cutoff=1005, - items=[ - {"quality": {"id": 0, "name": "Unknown"}, "items": [], "allowed": True}, - { - "name": "Lossless", - "items": [ - { - "quality": {"id": 7, "name": "ALAC"}, - "items": [], - "allowed": True, - }, - { - "quality": {"id": 6, "name": "FLAC"}, - "items": [], - "allowed": True, - }, - { - "quality": {"id": 35, "name": "APE"}, - "items": [], - "allowed": True, - }, - { - "quality": {"id": 36, "name": "WavPack"}, - "items": [], - "allowed": True, - }, - { - "quality": {"id": 21, "name": "FLAC 24bit"}, - "items": [], - "allowed": True, - }, - ], - "allowed": True, - "id": 1005, - }, - ], + upgrade_allowed=True, + cutoff=schema["items"][1]["id"], + schema=schema, + language=language, ) assert isinstance(data, dict) @@ -874,6 +845,11 @@ def test_upd_quality_definition(lidarr_client: LidarrAPI): assert data["maxSize"] == rand_float +def test_get_quality_profile_schema(lidarr_client: LidarrAPI): + data = lidarr_client.get_quality_profile_schema() + assert isinstance(data, dict) + + def test_get_indexer_schema(lidarr_client: LidarrAPI): data = lidarr_client.get_indexer_schema() assert isinstance(data, list) diff --git a/tests/test_radarr.py b/tests/test_radarr.py index a93cedd..d692deb 100644 --- a/tests/test_radarr.py +++ b/tests/test_radarr.py @@ -595,6 +595,11 @@ def test_get_language(radarr_client: RadarrAPI): assert isinstance(data, dict) +def test_get_quality_profile_schema(radarr_client: RadarrAPI): + data = radarr_client.get_quality_profile_schema() + assert isinstance(data, dict) + + @pytest.mark.usefixtures @responses.activate def test_get_blocklist_by_movie_id(radarr_mock_client: RadarrAPI): diff --git a/tests/test_readarr.py b/tests/test_readarr.py index b91a3a8..c51bccf 100644 --- a/tests/test_readarr.py +++ b/tests/test_readarr.py @@ -358,6 +358,11 @@ def test_get_language(readarr_client: ReadarrAPI): assert isinstance(data, dict) +def test_get_quality_profile_schema(readarr_client: ReadarrAPI): + data = readarr_client.get_quality_profile_schema() + assert isinstance(data, dict) + + @pytest.mark.usefixtures @responses.activate def test_get_queue(readarr_mock_client: ReadarrAPI): diff --git a/tests/test_sonarr.py b/tests/test_sonarr.py index 427dcfa..98b0261 100644 --- a/tests/test_sonarr.py +++ b/tests/test_sonarr.py @@ -605,6 +605,11 @@ def test_upd_quality_definition(sonarr_client: SonarrAPI): assert data["maxSize"] == rand_float +def test_get_quality_profile_schema(sonarr_client: SonarrAPI): + data = sonarr_client.get_quality_profile_schema() + assert isinstance(data, dict) + + @pytest.mark.usefixtures @responses.activate def test_get_queue(sonarr_mock_client: SonarrAPI): From d2cd0614b94850d3f84feff60699dc69d607c494 Mon Sep 17 00:00:00 2001 From: Steven Marks Date: Mon, 17 Apr 2023 14:32:46 +0000 Subject: [PATCH 2/7] fix: radarr add_quality_profile --- pyarr/base.py | 8 ++++++-- pyarr/models/common.py | 2 +- pyarr/models/sonarr.py | 11 +++++++++++ pyarr/radarr.py | 44 ++++++++++++++++++++++++++++++++---------- pyarr/sonarr.py | 11 +++++++---- tests/test_lidarr.py | 4 ++-- tests/test_radarr.py | 13 ++++++++----- tests/test_sonarr.py | 2 +- 8 files changed, 70 insertions(+), 25 deletions(-) diff --git a/pyarr/base.py b/pyarr/base.py index 0a73b34..16c567f 100644 --- a/pyarr/base.py +++ b/pyarr/base.py @@ -17,6 +17,7 @@ PyarrSortDirection, ) from pyarr.models.lidarr import LidarrImportListSchema +from pyarr.models.sonarr import SonarrHistorySortKey from pyarr.types import JsonArray, JsonObject from .request_handler import RequestHandler @@ -218,7 +219,7 @@ def get_history( self, page: Optional[int] = None, page_size: Optional[int] = None, - sort_key: Optional[PyarrHistorySortKey] = None, + sort_key: Optional[Union[PyarrHistorySortKey, SonarrHistorySortKey]] = None, sort_dir: Optional[PyarrSortDirection] = None, ) -> JsonObject: """Gets history (grabs/failures/completed) @@ -232,7 +233,10 @@ def get_history( Returns: JsonObject: Dictionary with items """ - params: dict[str, Union[int, PyarrHistorySortKey, PyarrSortDirection]] = {} + params: dict[ + str, + Union[int, PyarrHistorySortKey, SonarrHistorySortKey, PyarrSortDirection], + ] = {} if page: params["page"] = page diff --git a/pyarr/models/common.py b/pyarr/models/common.py index 1edd1c9..412df43 100644 --- a/pyarr/models/common.py +++ b/pyarr/models/common.py @@ -23,7 +23,7 @@ within Arr api docs. """ -PyarrHistorySortKey = Literal["time"] +PyarrHistorySortKey = Literal["id", "date", "eventType"] """History sort keys Note: diff --git a/pyarr/models/sonarr.py b/pyarr/models/sonarr.py index df70659..488e827 100644 --- a/pyarr/models/sonarr.py +++ b/pyarr/models/sonarr.py @@ -99,3 +99,14 @@ "status", "timeleft", ] + + +SonarrHistorySortKey = Literal[ + "id", "date", "eventType", "series.title", "episode.title" +] +"""Sonarr History sort keys + +Note: + There may be more, but these are not well documented + within Arr api docs. +""" diff --git a/pyarr/radarr.py b/pyarr/radarr.py index ee2f0d7..c19f39b 100644 --- a/pyarr/radarr.py +++ b/pyarr/radarr.py @@ -541,26 +541,50 @@ def get_custom_filter(self) -> JsonArray: # POST /qualityprofile def add_quality_profile( - self, name: str, upgrades_allowed: bool, cutoff: int, items: list + self, + name: str, + schema: dict[str, Any], + cutoff: int, + upgrade_allowed: Optional[bool] = None, + language: Optional[dict[str, Any]] = None, + min_format_score: Optional[int] = None, + cutoff_format_score: Optional[int] = None, + format_items: Optional[list] = None, ) -> JsonObject: """Add new quality profile Args: name (str): Name of the profile - upgrades_allowed (bool): Are upgrades in quality allowed? + schema (dict[str, Any]): Add the profile schema (from `get_quality_profile_schema()`) cutoff (int): ID of quality definition to cutoff at. Must be an allowed definition ID. - items (list): Add a list of items (from `get_quality_definition()`) + upgrade_allowed (bool, optional): Are upgrades in quality allowed?. Default provided by schema. + language (dict, optional): Language profile (from `get_language()`). Default provided by schema. + min_format_score (int, optional): Minimum format score. Default provided by schema. + cutoff_format_score (int, optional): Cutoff format score. Default provided by schema. + format_items (list, optional): Format items. Default provided by schema. + + Note: + Update the result from `get_quality_profile_schema()` set the items you need + from `"allowed": false` to `"allowed": true`. See tests for more details. Returns: JsonObject: An object containing the profile """ - data = { - "name": name, - "upgradeAllowed": upgrades_allowed, - "cutoff": cutoff, - "items": items, - } - return self._post("qualityprofile", self.ver_uri, data=data) + schema["name"] = name + schema["cutoff"] = cutoff + + if format_items is not None: + schema["formatItems"] = format_items + if language is not None: + schema["language"] = language + if upgrade_allowed is not None: + schema["upgradeAllowed"] = upgrade_allowed + if min_format_score is not None: + schema["minFormatScore"] = min_format_score + if cutoff_format_score is not None: + schema["cutoffFormatScore"] = cutoff_format_score + + return self._post("qualityprofile", self.ver_uri, data=schema) # GET /manualimport def get_manual_import( diff --git a/pyarr/sonarr.py b/pyarr/sonarr.py index 946d997..fadcae6 100644 --- a/pyarr/sonarr.py +++ b/pyarr/sonarr.py @@ -9,7 +9,7 @@ from .base import BaseArrAPI from .models.common import PyarrHistorySortKey, PyarrSortDirection -from .models.sonarr import SonarrCommands, SonarrSortKey +from .models.sonarr import SonarrCommands, SonarrHistorySortKey, SonarrSortKey class SonarrAPI(BaseArrAPI): @@ -601,7 +601,7 @@ def get_history( self, page: Optional[int] = None, page_size: Optional[int] = None, - sort_key: Optional[PyarrHistorySortKey] = None, + sort_key: Optional[Union[PyarrHistorySortKey, SonarrHistorySortKey]] = None, sort_dir: Optional[PyarrSortDirection] = None, id_: Optional[int] = None, ) -> JsonObject: @@ -610,14 +610,17 @@ def get_history( Args: page (Optional[int], optional): Page number to return. Defaults to None. page_size (Optional[int], optional): Number of items per page. Defaults to None. - sort_key (Optional[PyarrHistorySortKey], optional): Field to sort by. Defaults to None. + sort_key (Optional[Union[PyarrHistorySortKey, SonarrHistorySortKey]], optional): Field to sort by. Defaults to None. sort_dir (Optional[PyarrSortDirection], optional): Direction to sort the items. Defaults to None. id_ (Optional[int], optional): Filter to a specific episode ID. Defaults to None. Returns: JsonObject: Dictionary with items """ - params: dict[str, Union[int, PyarrHistorySortKey, PyarrSortDirection]] = {} + params: dict[ + str, + Union[int, PyarrHistorySortKey, SonarrHistorySortKey, PyarrSortDirection], + ] = {} if page: params["page"] = page diff --git a/tests/test_lidarr.py b/tests/test_lidarr.py index 1abf55a..5912092 100644 --- a/tests/test_lidarr.py +++ b/tests/test_lidarr.py @@ -784,13 +784,13 @@ def test_get_history(lidarr_client: LidarrAPI): data = lidarr_client.get_history( page=1, page_size=10, - sort_key="time", + sort_key="date", sort_dir="default", ) assert isinstance(data, dict) with contextlib.suppress(PyarrMissingArgument): - data = lidarr_client.get_history(sort_key="time") + data = lidarr_client.get_history(sort_key="date") assert False with contextlib.suppress(PyarrMissingArgument): diff --git a/tests/test_radarr.py b/tests/test_radarr.py index d692deb..e57f2e9 100644 --- a/tests/test_radarr.py +++ b/tests/test_radarr.py @@ -68,13 +68,16 @@ def test_get_command(radarr_client: RadarrAPI): def test_add_quality_profile(radarr_client: RadarrAPI): - data = radarr_client.get_quality_definition() - assert isinstance(data, list) - - test_items = [data[0], data[3], data[5]] + language = radarr_client.get_language()[0] + schema = radarr_client.get_quality_profile_schema() + schema["items"][1]["allowed"] = True data = radarr_client.add_quality_profile( - name="Testing", upgrades_allowed=True, cutoff=3, items=test_items + name="Testing", + upgrade_allowed=True, + cutoff=schema["items"][1]["quality"]["id"], + schema=schema, + language=language, ) assert isinstance(data, dict) diff --git a/tests/test_sonarr.py b/tests/test_sonarr.py index 98b0261..e39e9ce 100644 --- a/tests/test_sonarr.py +++ b/tests/test_sonarr.py @@ -293,7 +293,7 @@ def test_get_history(sonarr_client: SonarrAPI): data = sonarr_client.get_history( page=1, page_size=10, - sort_key="time", + sort_key="date", sort_dir="default", id_=episodes[0]["id"], ) From ed0086f09425369fc926c5be2da0df0f3e3d4055 Mon Sep 17 00:00:00 2001 From: Steven Marks Date: Mon, 17 Apr 2023 16:15:27 +0000 Subject: [PATCH 3/7] fix: get_history --- pyarr/base.py | 9 ++++++--- pyarr/models/common.py | 15 ++++++++++++++- pyarr/models/lidarr.py | 3 +++ pyarr/models/sonarr.py | 11 ----------- pyarr/sonarr.py | 8 ++++---- tests/test_lidarr.py | 15 ++++++++------- tests/test_radarr.py | 17 +++++++++-------- tests/test_readarr.py | 22 ++++++++++++++++++++++ tests/test_sonarr.py | 17 +++++++++-------- 9 files changed, 75 insertions(+), 42 deletions(-) diff --git a/pyarr/base.py b/pyarr/base.py index 16c567f..b785333 100644 --- a/pyarr/base.py +++ b/pyarr/base.py @@ -17,7 +17,6 @@ PyarrSortDirection, ) from pyarr.models.lidarr import LidarrImportListSchema -from pyarr.models.sonarr import SonarrHistorySortKey from pyarr.types import JsonArray, JsonObject from .request_handler import RequestHandler @@ -219,7 +218,7 @@ def get_history( self, page: Optional[int] = None, page_size: Optional[int] = None, - sort_key: Optional[Union[PyarrHistorySortKey, SonarrHistorySortKey]] = None, + sort_key: Optional[PyarrHistorySortKey] = None, sort_dir: Optional[PyarrSortDirection] = None, ) -> JsonObject: """Gets history (grabs/failures/completed) @@ -235,7 +234,11 @@ def get_history( """ params: dict[ str, - Union[int, PyarrHistorySortKey, SonarrHistorySortKey, PyarrSortDirection], + Union[ + int, + PyarrHistorySortKey, + PyarrSortDirection, + ], ] = {} if page: diff --git a/pyarr/models/common.py b/pyarr/models/common.py index 412df43..a045a49 100644 --- a/pyarr/models/common.py +++ b/pyarr/models/common.py @@ -23,9 +23,22 @@ within Arr api docs. """ -PyarrHistorySortKey = Literal["id", "date", "eventType"] +PyarrHistorySortKey = Literal[ + "id", + "date", + "eventType", + "series.title", + "episode.title", + "movieFile.relativePath", + "sourceTitle", + "status", +] """History sort keys +series.title (Sonarr) +episode.title (Sonarr) +status (Lidarr only) + Note: There may be more, but these are not well documented within Arr api docs. diff --git a/pyarr/models/lidarr.py b/pyarr/models/lidarr.py index 1029574..dddfe01 100644 --- a/pyarr/models/lidarr.py +++ b/pyarr/models/lidarr.py @@ -50,3 +50,6 @@ "SpotifyPlaylist", "SpotifySavedAlbums", ] + +#: Lidarr History Sort Keys +LidarrHistorySortKey = Literal["sourceTitle", "status"] diff --git a/pyarr/models/sonarr.py b/pyarr/models/sonarr.py index 488e827..df70659 100644 --- a/pyarr/models/sonarr.py +++ b/pyarr/models/sonarr.py @@ -99,14 +99,3 @@ "status", "timeleft", ] - - -SonarrHistorySortKey = Literal[ - "id", "date", "eventType", "series.title", "episode.title" -] -"""Sonarr History sort keys - -Note: - There may be more, but these are not well documented - within Arr api docs. -""" diff --git a/pyarr/sonarr.py b/pyarr/sonarr.py index fadcae6..ee0540a 100644 --- a/pyarr/sonarr.py +++ b/pyarr/sonarr.py @@ -9,7 +9,7 @@ from .base import BaseArrAPI from .models.common import PyarrHistorySortKey, PyarrSortDirection -from .models.sonarr import SonarrCommands, SonarrHistorySortKey, SonarrSortKey +from .models.sonarr import SonarrCommands, SonarrSortKey class SonarrAPI(BaseArrAPI): @@ -601,7 +601,7 @@ def get_history( self, page: Optional[int] = None, page_size: Optional[int] = None, - sort_key: Optional[Union[PyarrHistorySortKey, SonarrHistorySortKey]] = None, + sort_key: Optional[PyarrHistorySortKey] = None, sort_dir: Optional[PyarrSortDirection] = None, id_: Optional[int] = None, ) -> JsonObject: @@ -610,7 +610,7 @@ def get_history( Args: page (Optional[int], optional): Page number to return. Defaults to None. page_size (Optional[int], optional): Number of items per page. Defaults to None. - sort_key (Optional[Union[PyarrHistorySortKey, SonarrHistorySortKey]], optional): Field to sort by. Defaults to None. + sort_key (Optional[PyarrHistorySortKey], optional): Field to sort by. Defaults to None. sort_dir (Optional[PyarrSortDirection], optional): Direction to sort the items. Defaults to None. id_ (Optional[int], optional): Filter to a specific episode ID. Defaults to None. @@ -619,7 +619,7 @@ def get_history( """ params: dict[ str, - Union[int, PyarrHistorySortKey, SonarrHistorySortKey, PyarrSortDirection], + Union[int, PyarrHistorySortKey, PyarrSortDirection], ] = {} if page: diff --git a/tests/test_lidarr.py b/tests/test_lidarr.py index 5912092..8fc75a0 100644 --- a/tests/test_lidarr.py +++ b/tests/test_lidarr.py @@ -781,13 +781,14 @@ def test_get_history(lidarr_client: LidarrAPI): data = lidarr_client.get_history() assert isinstance(data, dict) - data = lidarr_client.get_history( - page=1, - page_size=10, - sort_key="date", - sort_dir="default", - ) - assert isinstance(data, dict) + for key in ["id", "date", "eventType", "status"]: + data = lidarr_client.get_history( + page=1, + page_size=10, + sort_key=key, + sort_dir="default", + ) + assert isinstance(data, dict) with contextlib.suppress(PyarrMissingArgument): data = lidarr_client.get_history(sort_key="date") diff --git a/tests/test_radarr.py b/tests/test_radarr.py index e57f2e9..e73938a 100644 --- a/tests/test_radarr.py +++ b/tests/test_radarr.py @@ -196,16 +196,17 @@ def test_get_history(radarr_client: RadarrAPI): data = radarr_client.get_history() assert isinstance(data, dict) - data = radarr_client.get_history( - page=1, - page_size=10, - sort_key="time", - sort_dir="default", - ) - assert isinstance(data, dict) + for key in ["id", "date", "eventType"]: + data = radarr_client.get_history( + page=1, + page_size=10, + sort_key=key, + sort_dir="default", + ) + assert isinstance(data, dict) with contextlib.suppress(PyarrMissingArgument): - data = radarr_client.get_history(sort_key="time") + data = radarr_client.get_history(sort_key="date") assert False with contextlib.suppress(PyarrMissingArgument): diff --git a/tests/test_readarr.py b/tests/test_readarr.py index c51bccf..a4e6f75 100644 --- a/tests/test_readarr.py +++ b/tests/test_readarr.py @@ -363,6 +363,28 @@ def test_get_quality_profile_schema(readarr_client: ReadarrAPI): assert isinstance(data, dict) +def test_get_history(readarr_client: ReadarrAPI): + data = readarr_client.get_history() + assert isinstance(data, dict) + + for key in ["id", "date", "eventType"]: + data = readarr_client.get_history( + page=1, + page_size=10, + sort_key=key, + sort_dir="default", + ) + assert isinstance(data, dict) + + with contextlib.suppress(PyarrMissingArgument): + data = readarr_client.get_history(sort_key="date") + assert False + + with contextlib.suppress(PyarrMissingArgument): + data = readarr_client.get_history(sort_dir="descending") + assert False + + @pytest.mark.usefixtures @responses.activate def test_get_queue(readarr_mock_client: ReadarrAPI): diff --git a/tests/test_sonarr.py b/tests/test_sonarr.py index e39e9ce..1c88c89 100644 --- a/tests/test_sonarr.py +++ b/tests/test_sonarr.py @@ -290,14 +290,15 @@ def test_get_history(sonarr_client: SonarrAPI): data = sonarr_client.get_history() assert isinstance(data, dict) - data = sonarr_client.get_history( - page=1, - page_size=10, - sort_key="date", - sort_dir="default", - id_=episodes[0]["id"], - ) - assert isinstance(data, dict) + for key in ["id", "date", "eventType", "series.title", "episode.title"]: + data = sonarr_client.get_history( + page=1, + page_size=10, + sort_key=key, + sort_dir="default", + id_=episodes[0]["id"], + ) + assert isinstance(data, dict) with contextlib.suppress(PyarrMissingArgument): data = sonarr_client.get_history(sort_key="time") From 89fbfd213de2d8ad685b8adb9b9647d8ea360f01 Mon Sep 17 00:00:00 2001 From: Steven Marks Date: Mon, 17 Apr 2023 16:28:54 +0000 Subject: [PATCH 4/7] feat: added edition endpoint --- pyarr/readarr.py | 13 +++++++++++++ tests/test_readarr.py | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/pyarr/readarr.py b/pyarr/readarr.py index ef1781c..ec5e2c3 100644 --- a/pyarr/readarr.py +++ b/pyarr/readarr.py @@ -841,3 +841,16 @@ def upd_manual_import(self, data: JsonObject) -> JsonObject: JsonObject: Dictionary of updated record """ return self._put("manualimport", self.ver_uri, data=data) + + # GET /edition + def get_edition(self, id_: int) -> JsonObject: + """Get edition's for specific book + + Args: + id_ (int): Database ID of book + + Returns: + JsonObject: Dictionary of editions + """ + + return self._get("edition", self.ver_uri, params={"bookId": id_}) diff --git a/tests/test_readarr.py b/tests/test_readarr.py index a4e6f75..6e3cf28 100644 --- a/tests/test_readarr.py +++ b/tests/test_readarr.py @@ -264,6 +264,14 @@ def test_get_book(readarr_client: ReadarrAPI): assert isinstance(data, dict) +@pytest.mark.usefixtures +def test_upd_book(readarr_client: ReadarrAPI): + book = readarr_client.get_book() + + data = readarr_client.get_edition(id_=book[0]["id"]) + assert isinstance(data, dict) + + @pytest.mark.usefixtures def test_upd_book(readarr_client: ReadarrAPI): book = readarr_client.get_book() From 9efb00cd5474b71beff2cc10ee0b0ab4132a3d41 Mon Sep 17 00:00:00 2001 From: Steven Marks Date: Tue, 18 Apr 2023 08:36:58 +0000 Subject: [PATCH 5/7] ci: fix upd_series sonarr test that was incorrect --- tests/test_sonarr.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_sonarr.py b/tests/test_sonarr.py index 1c88c89..108beb5 100644 --- a/tests/test_sonarr.py +++ b/tests/test_sonarr.py @@ -189,9 +189,11 @@ def test_get_episode(sonarr_client: SonarrAPI): def test_upd_series(sonarr_client: SonarrAPI): series = sonarr_client.get_series() + series["monitored"] = False - data = sonarr_client.upd_series(data=series[0]["id"]) + data = sonarr_client.upd_series(data=series[0]) assert isinstance(data, dict) + assert data["monitored"] is False def test_get_episodes_by_series_id(sonarr_client: SonarrAPI): From baabe5933db2c78e0066b6ff5e86265aebbe53e6 Mon Sep 17 00:00:00 2001 From: Steven Marks Date: Tue, 18 Apr 2023 08:50:22 +0000 Subject: [PATCH 6/7] refactor: remove unnecissary exception --- pyarr/sonarr.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/pyarr/sonarr.py b/pyarr/sonarr.py index ee0540a..147c862 100644 --- a/pyarr/sonarr.py +++ b/pyarr/sonarr.py @@ -518,14 +518,7 @@ def add_series( "searchForMissingEpisodes": search_for_missing_episodes, } - response: dict[str, Any] = self._post("series", self.ver_uri, data=series) - for item in response: - if "errorMessage" in item: - raise Exception(item) - else: - continue - - return response + return self._post("series", self.ver_uri, data=series) # PUT /series def upd_series(self, data: JsonObject) -> JsonObject: From bc699b4c80d573196d7ced3f196b3ce5a72b17f4 Mon Sep 17 00:00:00 2001 From: Steven Marks Date: Tue, 18 Apr 2023 15:22:33 +0000 Subject: [PATCH 7/7] fix: readarr upd_book now functioning as expected --- pyarr/readarr.py | 17 +++++++++++------ tests/test_readarr.py | 20 +++++--------------- tests/test_sonarr.py | 2 +- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/pyarr/readarr.py b/pyarr/readarr.py index ec5e2c3..66b73ed 100644 --- a/pyarr/readarr.py +++ b/pyarr/readarr.py @@ -432,20 +432,25 @@ def add_book( return self._post("book", self.ver_uri, data=book) # PUT /book/{id} - def upd_book(self, id_: int, data: JsonObject) -> JsonObject: - """Update the given book, currently only monitored is changed, all other modifications are ignored. + def upd_book(self, book: JsonObject, editions: JsonArray) -> JsonObject: + """Update the given book. Note: - To be used in conjunction with get_book() + To be used in conjunction with get_book() and get_edition() + + Currently only monitored states are updated (for the book and edition). Args: id_ (int): Book database ID to update - data (JsonObject): All parameters to update book + book (JsonObject): All parameters to update book + editions (JsonArray): List of editions to update book from `get_edition()` Returns: JsonObject: Dictionary with updated record """ - return self._put(f"book/{id_}", self.ver_uri, data=data) + book["editions"] = editions + + return self._put("book", self.ver_uri, data=book) # PUT /book/monitor def upd_book_monitor( @@ -843,7 +848,7 @@ def upd_manual_import(self, data: JsonObject) -> JsonObject: return self._put("manualimport", self.ver_uri, data=data) # GET /edition - def get_edition(self, id_: int) -> JsonObject: + def get_edition(self, id_: int) -> JsonArray: """Get edition's for specific book Args: diff --git a/tests/test_readarr.py b/tests/test_readarr.py index 6e3cf28..84405f0 100644 --- a/tests/test_readarr.py +++ b/tests/test_readarr.py @@ -212,7 +212,6 @@ def test_add_delay_profile(readarr_client: ReadarrAPI): assert data["minimumCustomFormatScore"] == 10 -@pytest.mark.usefixtures def test_get_missing(readarr_client: ReadarrAPI): data = readarr_client.get_missing() assert isinstance(data, dict) @@ -233,7 +232,6 @@ def test_get_missing(readarr_client: ReadarrAPI): assert False -@pytest.mark.usefixtures def test_get_cutoff(readarr_client: ReadarrAPI): data = readarr_client.get_cutoff() assert isinstance(data, dict) @@ -255,7 +253,6 @@ def test_get_cutoff(readarr_client: ReadarrAPI): assert False -@pytest.mark.usefixtures def test_get_book(readarr_client: ReadarrAPI): data = readarr_client.get_book() assert isinstance(data, list) @@ -264,20 +261,19 @@ def test_get_book(readarr_client: ReadarrAPI): assert isinstance(data, dict) -@pytest.mark.usefixtures def test_upd_book(readarr_client: ReadarrAPI): book = readarr_client.get_book() + editions = readarr_client.get_edition(book[0]["id"]) - data = readarr_client.get_edition(id_=book[0]["id"]) + data = readarr_client.upd_book(book=book[0], editions=editions) assert isinstance(data, dict) -@pytest.mark.usefixtures -def test_upd_book(readarr_client: ReadarrAPI): +def test_get_edition(readarr_client: ReadarrAPI): book = readarr_client.get_book() - data = readarr_client.upd_book(id_=book[0]["id"], data=book[0]) - assert isinstance(data, dict) + data = readarr_client.get_edition(id_=book[0]["id"]) + assert isinstance(data, list) def test_upd_book_monitor(readarr_client: ReadarrAPI): @@ -290,7 +286,6 @@ def test_upd_book_monitor(readarr_client: ReadarrAPI): assert data[0]["monitored"] == False -@pytest.mark.usefixtures def test_add_author(readarr_client: ReadarrAPI): qual_profile = readarr_client.get_quality_profile() meta_profile = readarr_client.get_metadata_profile() @@ -312,7 +307,6 @@ def test_add_author(readarr_client: ReadarrAPI): assert isinstance(data, dict) -@pytest.mark.usefixtures def test_upd_author(readarr_client: ReadarrAPI): author = readarr_client.get_author() author[0]["monitored"] = True @@ -322,7 +316,6 @@ def test_upd_author(readarr_client: ReadarrAPI): assert data["monitored"] == True -@pytest.mark.usefixtures def test_get_author(readarr_client: ReadarrAPI): data = readarr_client.get_author() assert isinstance(data, list) @@ -331,7 +324,6 @@ def test_get_author(readarr_client: ReadarrAPI): assert isinstance(data, dict) -@pytest.mark.usefixtures def test_get_metadata_profile(readarr_client: ReadarrAPI): data = readarr_client.get_metadata_profile() assert isinstance(data, list) @@ -340,7 +332,6 @@ def test_get_metadata_profile(readarr_client: ReadarrAPI): assert isinstance(data, dict) -@pytest.mark.usefixtures def test_get_delay_profile(readarr_client: ReadarrAPI): data = readarr_client.get_delay_profile() assert isinstance(data, list) @@ -349,7 +340,6 @@ def test_get_delay_profile(readarr_client: ReadarrAPI): assert isinstance(data, dict) -@pytest.mark.usefixtures def test_get_release_profile(readarr_client: ReadarrAPI): data = readarr_client.get_release_profile() assert isinstance(data, list) diff --git a/tests/test_sonarr.py b/tests/test_sonarr.py index 108beb5..1aa4a21 100644 --- a/tests/test_sonarr.py +++ b/tests/test_sonarr.py @@ -189,7 +189,7 @@ def test_get_episode(sonarr_client: SonarrAPI): def test_upd_series(sonarr_client: SonarrAPI): series = sonarr_client.get_series() - series["monitored"] = False + series[0]["monitored"] = False data = sonarr_client.upd_series(data=series[0]) assert isinstance(data, dict)