diff --git a/src/icloudpd/base.py b/src/icloudpd/base.py index 79f1ab034..fc8a22a7b 100644 --- a/src/icloudpd/base.py +++ b/src/icloudpd/base.py @@ -10,7 +10,7 @@ from icloudpd.email_notifications import send_2sa_notification from icloudpd import download from icloudpd.authentication import authenticator, TwoStepAuthRequiredError -from pyicloud_ipd.services.photos import PhotoAsset, PhotoLibrary +from pyicloud_ipd.services.photos import PhotoAsset, PhotoLibrary, PhotosService from pyicloud_ipd.exceptions import PyiCloudAPIResponseException from pyicloud_ipd.base import PyiCloudService from tzlocal import get_localzone @@ -603,15 +603,16 @@ def download_photo_(counter: Counter, photo: PhotoAsset) -> bool: def delete_photo( logger: logging.Logger, - icloud: PyiCloudService, + photo_service: PhotosService, + library_object: PhotoLibrary, photo: PhotoAsset) -> None: """Delete a photo from the iCloud account.""" clean_filename_local = clean_filename(photo.filename) logger.debug( "Deleting %s in iCloud...", clean_filename_local) # pylint: disable=W0212 - url = f"{icloud.photos._service_endpoint}/records/modify?"\ - f"{urllib.parse.urlencode(icloud.photos.params)}" + url = f"{photo_service._service_endpoint}/records/modify?"\ + f"{urllib.parse.urlencode(photo_service.params)}" post_data = json.dumps( { "atomic": True, @@ -625,10 +626,10 @@ def delete_photo( "recordType": "CPLAsset", } }], - "zoneID": {"zoneName": "PrimarySync"} + "zoneID": library_object.zone_id } ) - icloud.photos.session.post( + photo_service.session.post( url, data=post_data, headers={ "Content-type": "application/json"}) logger.info( @@ -637,12 +638,14 @@ def delete_photo( def delete_photo_dry_run( logger: logging.Logger, - _icloud: PyiCloudService, + _photo_service: PhotosService, + library_object: PhotoLibrary, photo: PhotoAsset) -> None: """Dry run for deleting a photo from the iCloud""" logger.info( - "[DRY RUN] Would delete %s in iCloud", - clean_filename(photo.filename) + "[DRY RUN] Would delete %s in iCloud library %s", + clean_filename(photo.filename), + library_object.zone_id['zoneName'] ) @@ -911,7 +914,7 @@ def should_break(counter: Counter) -> bool: def delete_cmd() -> None: delete_local = delete_photo_dry_run if dry_run else delete_photo - delete_local(logger, icloud, item) + delete_local(logger, icloud.photos, library_object, item) retrier(delete_cmd, error_handler) diff --git a/tests/test_autodelete_photos.py b/tests/test_autodelete_photos.py index fde95a061..d4ae99e61 100644 --- a/tests/test_autodelete_photos.py +++ b/tests/test_autodelete_photos.py @@ -11,7 +11,7 @@ import pytz from tzlocal import get_localzone from click.testing import CliRunner -from pyicloud_ipd.services.photos import PhotoAsset +from pyicloud_ipd.services.photos import PhotoAsset, PhotoLibrary, PhotosService from pyicloud_ipd.base import PyiCloudService from pyicloud_ipd.exceptions import PyiCloudAPIResponseException from icloudpd.base import main @@ -357,7 +357,7 @@ def test_retry_delete_after_download_session_error(self) -> None: with vcr.use_cassette(os.path.join(self.vcr_path, "download_autodelete_photos.yml")): - def mock_raise_response_error(a0_:logging.Logger, a1_:PyiCloudService, a2_:PhotoAsset) -> None: + def mock_raise_response_error(a0_:logging.Logger, a1_:PhotosService, a2_:PhotoLibrary, a3_:PhotoAsset) -> None: if not hasattr(self, f"already_raised_session_exception{inspect.stack()[0][3]}"): setattr(self, f"already_raised_session_exception{inspect.stack()[0][3]}", True) raise PyiCloudAPIResponseException( @@ -450,7 +450,7 @@ def test_retry_fail_delete_after_download_session_error(self) -> None: with vcr.use_cassette(os.path.join(self.vcr_path, "download_autodelete_photos.yml")): - def mock_raise_response_error(a0_:logging.Logger, a1_:PyiCloudService, a2_:PhotoAsset) -> None: + def mock_raise_response_error(a0_:logging.Logger, a1_:PhotosService, a2_:PhotoLibrary, a3_:PhotoAsset) -> None: raise PyiCloudAPIResponseException("Invalid global session", "100") with mock.patch("time.sleep") as sleep_mock: @@ -540,7 +540,7 @@ def test_retry_delete_after_download_internal_error(self) -> None: with vcr.use_cassette(os.path.join(self.vcr_path, "download_autodelete_photos.yml")): - def mock_raise_response_error(a0_:logging.Logger, a1_:PyiCloudService, a2_:PhotoAsset) -> None: + def mock_raise_response_error(a0_:logging.Logger, a1_:PhotosService, a2_:PhotoLibrary, a3_:PhotoAsset) -> None: if not hasattr(self, f"already_raised_session_exception{inspect.stack()[0][3]}"): setattr(self, f"already_raised_session_exception{inspect.stack()[0][3]}", True) raise PyiCloudAPIResponseException( @@ -621,7 +621,7 @@ def test_retry_fail_delete_after_download_internal_error(self) -> None: with vcr.use_cassette(os.path.join(self.vcr_path, "download_autodelete_photos.yml")): - def mock_raise_response_error(a0_:logging.Logger, a1_:PyiCloudService, a2_:PhotoAsset) -> None: + def mock_raise_response_error(a0_:logging.Logger, a1_:PhotosService, a2_:PhotoLibrary, a3_:PhotoAsset) -> None: raise PyiCloudAPIResponseException("INTERNAL_ERROR", "INTERNAL_ERROR") with mock.patch("time.sleep") as sleep_mock: