Skip to content

Commit

Permalink
delete in library icloud-photos-downloader#802
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreyNikiforov authored May 24, 2024
1 parent 28e78a7 commit 24d99c0
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 15 deletions.
23 changes: 13 additions & 10 deletions src/icloudpd/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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(
Expand All @@ -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']
)


Expand Down Expand Up @@ -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)

Expand Down
10 changes: 5 additions & 5 deletions tests/test_autodelete_photos.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 24d99c0

Please sign in to comment.