-
-
Save Tatsh/0b5a10a2d25f6c8466290401d2026055 to your computer and use it in GitHub Desktop.
| #!/usr/bin/env python | |
| from __future__ import print_function | |
| import json | |
| import sys | |
| from authentication import authenticate | |
| from future.moves.urllib.parse import urlencode | |
| if __name__ == '__main__': | |
| username = sys.argv[1] | |
| password = sys.argv[2] | |
| smtp_username = smtp_password = smtp_host = smtp_port = smtp_no_tls = notification_email = None | |
| print('Logging in') | |
| icloud = authenticate(username, password, smtp_username, smtp_password, smtp_host, smtp_port, smtp_no_tls, notification_email) | |
| photos = icloud.photos.all | |
| operations = [] | |
| url = '{}/records/modify?{}'.format(icloud.photos._service_endpoint, urlencode(icloud.photos.params)) | |
| headers = {'Content-type': 'text/plain'} | |
| seen_record_names = [] | |
| for photo in photos: | |
| # Avoid duplicate operations | |
| if photo._asset_record['recordName'] in seen_record_names: | |
| continue | |
| seen_record_names.append(photo._asset_record['recordName']) | |
| mr = {'fields': {'isDeleted': {'value': 1}}} | |
| mr['recordChangeTag'] = photo._asset_record['recordChangeTag'] | |
| mr['recordName'] = photo._asset_record['recordName'] | |
| mr['recordType'] = 'CPLAsset' | |
| op = dict( | |
| operationType='update', | |
| record=mr, | |
| ) | |
| operations.append(op) | |
| # Limit to 100 photos at a time | |
| if len(operations) >= 100: | |
| post_data = json.dumps(dict( | |
| atomic=True, | |
| desiredKeys=['isDeleted'], | |
| operations=operations, | |
| zoneID={'zoneName': 'PrimarySync'}, | |
| )) | |
| print('Deleting 100 photos') | |
| print(icloud.photos.session.post(url, | |
| data=post_data, | |
| headers=headers).json()) | |
| operations = [] |
Hi, combining the previous comments and making some further changes, the following process worked for me:
git clone https://github.com/ndbroadbent/icloud_photos_downloader
cd icloud_photos_downloader
cd icloudpd
curl -sfLO https://gist.github.com/Tatsh/0b5a10a2d25f6c8466290401d2026055/raw/77d23ca0d1448f8e8eb4f208dfcfe84781d98d67/delall-icloud-photos.py
Change the line:
icloud = authenticate(username, password, smtp_username, smtp_password, smtp_host, smtp_port, smtp_no_tls, notification_email)
to
icloud = authenticate(username, password)
Install icloudpd dependencies by installing icloudpd (Its documentation talks about how to do this)
Finally, run:
python delall-icloud-photos.py
The first time you run this, it will perform two factor authentication.
It will work well afterwards.
i am getting below error
File "delall-icloud-photos.py", line 10, in
username = sys.argv[1]
IndexError: list index out of range
I just had a similar issue. Made a quick script to do it :
https://github.com/zakirangwala/icloud-photo-manager
Works for me
from pyicloud import PyiCloudService
from pyicloud.exceptions import PyiCloudAPIResponseException
import sys
import time
# Your credentials
EMAIL = '[email protected]'
PASSWORD = 'xxxxxxx' # Enter your password here
def handle_2fa(api):
if api.requires_2fa:
print("Two-factor authentication required")
code = input("Enter the code you received: ")
result = api.validate_2fa_code(code)
print("2FA validation result:", result)
if api.requires_2sa:
print("Two-step authentication required")
devices = api.trusted_devices
print("Your trusted devices:")
for i, device in enumerate(devices):
device_name = device.get('deviceName')
phone_number = device.get('phoneNumber')
if device_name:
print(f" {i}: {device_name}")
else:
print(f" {i}: SMS to {phone_number}")
device = devices[int(input("Which device to use? "))]
if not api.send_verification_code(device):
print("Failed to send verification code")
sys.exit(1)
code = input("Enter verification code: ")
if not api.validate_verification_code(device, code):
print("Invalid verification code")
sys.exit(1)
try:
# Create connection with retries
max_retries = 3
retry_count = 0
while retry_count < max_retries:
try:
api = PyiCloudService(EMAIL, PASSWORD)
handle_2fa(api) # Handle 2FA if required
break
except PyiCloudAPIResponseException as e:
retry_count += 1
if retry_count == max_retries:
raise e
print(f"Attempt {retry_count} failed, trying again in 5 seconds...")
time.sleep(5)
count = 1
# Iterate through all photos
for photo in api.photos.all:
print(f"Count : {count}")
print(f"Filename: {photo.filename}") # Added filename output for verification
count += 1
# Uncomment this block when you're ready to delete photos
try:
photo.delete()
print(f"Deleted photo: {photo.filename}")
except Exception as e:
print(f"Failed to delete photo: {photo.filename}. Error: {e}")
except PyiCloudAPIResponseException as e:
print(f"iCloud API Error: {e}")
print("Make sure your credentials are correct and two-factor authentication is properly set up")
except Exception as e:
print(f"An error occurred: {e}")
is this still working or does anyone know any other way to delete all icloud photos instead of waiting 30 days before automatically deleted by icloud? I have deleted them from my ios device first but need to wait 30 days to be removed from my icloud account.