Skip to content

Commit a8bd1a7

Browse files
author
Asher Awelan
committed
Update photos.py
fix: add pagination support for album folder listing Some iCloud accounts have more albums than are returned in a single response. Previously, the `_fetch_folders` method only fetched the first page of albums, ignoring any `continuationMarker` provided by the Apple Photos API. This patch adds support for pagination, looping through all available pages and aggregating the results. This resolves issues where certain albums (e.g. "Harry Potter") were visible in the iCloud Web UI but missing from tools like `icloudpd --list-albums`. Tested manually by confirming previously missing albums now appear.
1 parent 5fac423 commit a8bd1a7

File tree

1 file changed

+29
-13
lines changed

1 file changed

+29
-13
lines changed

src/pyicloud_ipd/services/photos.py

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -225,21 +225,37 @@ def albums(self) -> Dict[str, "PhotoAlbum"]:
225225
def _fetch_folders(self) -> Sequence[Dict[str, Any]]:
226226
if self.library_type == "shared":
227227
return []
228-
url = ('%s/records/query?%s' %
229-
(self.service_endpoint, urlencode(self.service.params)))
230-
json_data = json.dumps({
231-
"query": {"recordType":"CPLAlbumByPositionLive"},
232-
"zoneID": self.zone_id,
233-
})
234228

235-
request = self.service.session.post(
236-
url,
237-
data=json_data,
238-
headers={'Content-type': 'text/plain'}
239-
)
240-
response = request.json()
229+
all_records = []
230+
continuation_marker = None
231+
232+
while True:
233+
url = ('%s/records/query?%s' %
234+
(self.service_endpoint, urlencode(self.service.params)))
235+
query_payload = {
236+
"query": {"recordType": "CPLAlbumByPositionLive"},
237+
"zoneID": self.zone_id,
238+
}
239+
240+
if continuation_marker:
241+
query_payload["continuationMarker"] = continuation_marker
242+
243+
json_data = json.dumps(query_payload)
244+
245+
request = self.service.session.post(
246+
url,
247+
data=json_data,
248+
headers={'Content-type': 'text/plain'}
249+
)
250+
response = request.json()
251+
252+
all_records.extend(response.get('records', []))
253+
254+
continuation_marker = response.get('continuationMarker')
255+
if not continuation_marker:
256+
break
241257

242-
return typing.cast(Sequence[Dict[str, Any]], response['records'])
258+
return typing.cast(Sequence[Dict[str, Any]], all_records)
243259

244260
@property
245261
def all(self) -> "PhotoAlbum":

0 commit comments

Comments
 (0)