diff --git a/churchtools_api/calendar.py b/churchtools_api/calendar.py index fc4a28d..48cfb59 100644 --- a/churchtools_api/calendar.py +++ b/churchtools_api/calendar.py @@ -232,24 +232,10 @@ def create_calender_appointment( # noqa: PLR0913 return None result_data = json.loads(response.content)["data"] - if image: - if not image_options: - image_options = { - "crop": { - "top": "0.00000", - "bottom": "0.00000", - "left": "0.00000", - "right": "0.00000", - }, - "focus": {"x": "0.50000", "y": "0.50000"}, - } - self.file_upload( - source_filepath=image, - domain_type="appointment_image", - domain_identifier=result_data["id"], - image_options=image_options, - ) + self._handle_calendar_image( + appointment_id=result_data["id"], image=image, image_options=image_options + ) return result_data @@ -347,25 +333,11 @@ def update_calender_appointment( logger.warning(json.loads(response.content).get("errors")) return None - if "image" in kwargs: - image_options = kwargs.get( - "image_options", - { - "crop": { - "top": "0.00000", - "bottom": "0.00000", - "left": "0.00000", - "right": "0.00000", - }, - "focus": {"x": "0.50000", "y": "0.50000"}, - }, - ) - self.file_upload( - source_filepath=kwargs.get("image"), - domain_type="appointment_image", - domain_identifier=appointment_id, - image_options=image_options, - ) + self._handle_calendar_image( + appointment_id=appointment_id, + image=kwargs.get("image"), + image_options=kwargs.get("image_options"), + ) return json.loads(response.content)["data"] @@ -394,3 +366,38 @@ def delete_calender_appointment( return False return True + + def _handle_calendar_image( + self, + appointment_id: int, + image: Path | None = None, + image_options: dict | None = None, + ) -> None: + """Function which covers nested update of image and options if specified. + + Args: + appointment_id: id of the individual calendar appointment + + image: path to a file which should be uploaded. Defaults to None + image_options: additional crop and focus dict to alter image + """ + if image: + if not image_options: + image_options = { + "image_options": { + "crop": { + "top": "0.0", + "bottom": "0.0", + "left": "0.0", + "right": "0.0", + }, + "focus": {"x": "0.5", "y": "0.5"}, + } + } + + self.file_upload( + source_filepath=image, + domain_type="appointment_image", + domain_identifier=appointment_id, + image_options=image_options, + ) diff --git a/churchtools_api/files.py b/churchtools_api/files.py index fcb5948..159b3c9 100644 --- a/churchtools_api/files.py +++ b/churchtools_api/files.py @@ -259,6 +259,8 @@ def file_download_from_url(self, file_url: str, target_path: str) -> bool: def set_image_options(self, image_id: int, image_options: dict | None) -> bool: """API endpoint used to PUT image options to an existing image. + serializes nested dict before sending as json put + Args: image_id: id of the image image_options: dict defining the crop and focus of image. @@ -269,26 +271,31 @@ def set_image_options(self, image_id: int, image_options: dict | None) -> bool: """ if not image_options: image_options = { - "crop": { - "top": "0.00000", - "bottom": "0.00000", - "left": "0.00000", - "right": "0.00000", - }, - "focus": {"x": "0.50000", "y": "0.50000"}, + "image_options": { + "crop": { + "top": "0.0", + "bottom": "0.0", + "left": "0.0", + "right": "0.0", + }, + "focus": {"x": "0.5", "y": "0.5"}, + } } + image_options_serialized = { + "image_options": json.dumps(image_options["image_options"]) + } url = f"{self.domain}/api/images/{image_id}/options" - logger.error( - "Open CT support issue ...136046 - setting " - "image options destroys ability to set them" + logger.warning( + "Open CT support issue ...136046" + "image option is applied but wrong dtype after update" ) - # TODO @bensteUEM: setting image options is not + # TODO @bensteUEM: setting image options is not correctly # applied when using endpoint from CT API # https://github.com/bensteUEM/ChurchToolsAPI/issues/122 - with self.session.put(url=url, json=image_options) as response: + with self.session.put(url=url, json=image_options_serialized) as response: if response.status_code != requests.codes.ok: return False diff --git a/tests/test_churchtools_api_calendars.py b/tests/test_churchtools_api_calendars.py index 1d7c6fb..0461ea2 100644 --- a/tests/test_churchtools_api_calendars.py +++ b/tests/test_churchtools_api_calendars.py @@ -170,9 +170,6 @@ def test_get_calendar_appointments_none(self) -> None: assert result is None - @pytest.mark.skip("incomplete implementation #122") - # TODO @bensteUEM: imageOption not changeable if not set before ... - # https://github.com/bensteUEM/ChurchToolsAPI/issues/122 def test_create_edit_delete_calendar_appointment( self, caplog: pytest.LogCaptureFixture ) -> None: @@ -232,9 +229,7 @@ def test_create_edit_delete_calendar_appointment( ) elif expected_key == "image": assert check_appointment[expected_key]["name"] == expected_value.name - # TODO @bensteUEM: imageOption not changeable if not set before ... - # https://github.com/bensteUEM/ChurchToolsAPI/issues/122 - pytest.fail("incomplete implementation #122") + assert isinstance(check_appointment[expected_key]["imageOption"], dict) elif expected_key == "address": for ( expected_address_key, diff --git a/tests/test_churchtools_api_files.py b/tests/test_churchtools_api_files.py index 7efe37b..f449260 100644 --- a/tests/test_churchtools_api_files.py +++ b/tests/test_churchtools_api_files.py @@ -5,8 +5,6 @@ import logging.config from pathlib import Path -import pytest - from tests.test_churchtools_api_abstract import TestsChurchToolsApiAbstract logger = logging.getLogger(__name__) @@ -140,9 +138,6 @@ def test_file_upload_replace_delete(self) -> None: len(song["arrangements"][0]["files"]) == 0 ), "check that files are deleted" - @pytest.mark.skip(reason="#122 - image options not applyable") - # TODO @bensteUEM: CT Bug 136046 - # https://github.com/bensteUEM/ChurchToolsAPI/issues/122 def test_file_upload_delete_calendar_image(self) -> None: """Test which tries to upload a calendar_image to a calendar appointment. @@ -152,18 +147,32 @@ def test_file_upload_delete_calendar_image(self) -> None: SAMPLE_CALENDAR_APPOINTMENT_ID = 332233 SAMPLE_IMAGE_PATH = Path("samples/pinguin.png") + image_options = { + "image_options": { + "crop": { + "top": "0.0", + "bottom": "0.0", + "left": "0.0", + "right": "0.0", + }, + "focus": {"x": "0.5", "y": "0.5"}, + } + } + is_successful_created = self.api.file_upload( source_filepath=SAMPLE_IMAGE_PATH, domain_type="appointment_image", domain_identifier=SAMPLE_CALENDAR_APPOINTMENT_ID, + image_options=image_options, ) assert is_successful_created result_appointment = self.api.get_calendar_appointments( calendar_ids=[SAMPLE_CALENDAR_ID], appointment_id=SAMPLE_CALENDAR_APPOINTMENT_ID, - ) - assert result_appointment["image"] == SAMPLE_IMAGE_PATH.name + )[0] + assert result_appointment["image"]["name"] == SAMPLE_IMAGE_PATH.name + assert isinstance(result_appointment["image"]["imageOption"], dict) is_successful_delete = self.api.file_delete( domain_type="appointment_image",