Skip to content

Commit a8ecb88

Browse files
remove cache (#1146)
1 parent 3c8a2a5 commit a8ecb88

File tree

3 files changed

+65
-78
lines changed

3 files changed

+65
-78
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
- feat: `--skip-created-before` to limit assets by creation date [#466](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/466) [#1111](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/1111)
6+
- bug: `--watch-with-interval` does not process updates from iCloud [#1144](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/1144) [#1142](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/1142)
67

78
## 1.27.5 (2025-05-08)
89

src/icloudpd/base.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,36 +1294,36 @@ def core(
12941294
logger.info("Authentication completed successfully")
12951295
return 0
12961296

1297-
download_photo = downloader(icloud)
1298-
1299-
# Access to the selected library. Defaults to the primary photos object.
1300-
library_object: PhotoLibrary = icloud.photos
1301-
13021297
if list_libraries:
13031298
library_names = (
13041299
icloud.photos.private_libraries.keys() | icloud.photos.shared_libraries.keys()
13051300
)
13061301
print(*library_names, sep="\n")
13071302

13081303
else:
1304+
download_photo = downloader(icloud)
1305+
1306+
# After 6 or 7 runs within 1h Apple blocks the API for some time. In that
1307+
# case exit.
1308+
try:
1309+
# Access to the selected library. Defaults to the primary photos object.
1310+
library_object: PhotoLibrary = icloud.photos
1311+
if library:
1312+
if library in icloud.photos.private_libraries:
1313+
library_object = icloud.photos.private_libraries[library]
1314+
elif library in icloud.photos.shared_libraries:
1315+
library_object = icloud.photos.shared_libraries[library]
1316+
else:
1317+
logger.error("Unknown library: %s", library)
1318+
return 1
1319+
except PyiCloudAPIResponseException as err:
1320+
# For later: come up with a nicer message to the user. For now take the
1321+
# exception text
1322+
logger.error("error?? %s", err)
1323+
return 1
1324+
13091325
while True:
1310-
# After 6 or 7 runs within 1h Apple blocks the API for some time. In that
1311-
# case exit.
1312-
try:
1313-
if library:
1314-
if library in icloud.photos.private_libraries:
1315-
library_object = icloud.photos.private_libraries[library]
1316-
elif library in icloud.photos.shared_libraries:
1317-
library_object = icloud.photos.shared_libraries[library]
1318-
else:
1319-
logger.error("Unknown library: %s", library)
1320-
return 1
1321-
photos = library_object.albums[album] if album else library_object.all
1322-
except PyiCloudAPIResponseException as err:
1323-
# For later: come up with a nicer message to the user. For now take the
1324-
# exception text
1325-
logger.error("error?? %s", err)
1326-
return 1
1326+
photos = library_object.albums[album] if album else library_object.all
13271327

13281328
if list_albums:
13291329
print("Albums:")

src/pyicloud_ipd/services/photos.py

Lines changed: 42 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,6 @@ def __init__(self, service: "PhotosService", zone_id: Dict[str, Any], library_ty
161161
self.library_type = library_type
162162
self.service_endpoint = self.service.get_service_endpoint(library_type)
163163

164-
self._albums: Optional[Dict[str, PhotoAlbum]] = None
165-
self._all: Optional[PhotoAlbum] = None
166-
self._recently_deleted: Optional[PhotoAlbum] = None
167-
168164
url = ('%s/records/query?%s' %
169165
(self.service_endpoint, urlencode(self.service.params)))
170166
json_data = json.dumps({
@@ -186,41 +182,40 @@ def __init__(self, service: "PhotosService", zone_id: Dict[str, Any], library_ty
186182

187183
@property
188184
def albums(self) -> Dict[str, "PhotoAlbum"]:
189-
if not self._albums:
190-
self._albums = {
185+
albums = {
191186
name: PhotoAlbum(self.service, self.service_endpoint, name, zone_id=self.zone_id, **props) # type: ignore[arg-type] # dynamically builing params
192187
for (name, props) in self.SMART_FOLDERS.items()
193188
}
194189

195-
for folder in self._fetch_folders():
196-
# FIXME: Handle subfolders
197-
if folder['recordName'] in ('----Root-Folder----',
198-
'----Project-Root-Folder----') or \
199-
(folder['fields'].get('isDeleted') and
200-
folder['fields']['isDeleted']['value']):
201-
continue
190+
for folder in self._fetch_folders():
191+
# FIXME: Handle subfolders
192+
if folder['recordName'] in ('----Root-Folder----',
193+
'----Project-Root-Folder----') or \
194+
(folder['fields'].get('isDeleted') and
195+
folder['fields']['isDeleted']['value']):
196+
continue
197+
198+
folder_id = folder['recordName']
199+
folder_obj_type = \
200+
"CPLContainerRelationNotDeletedByAssetDate:%s" % folder_id
201+
folder_name = base64.b64decode(
202+
folder['fields']['albumNameEnc']['value']).decode('utf-8')
203+
query_filter = [{
204+
"fieldName": "parentId",
205+
"comparator": "EQUALS",
206+
"fieldValue": {
207+
"type": "STRING",
208+
"value": folder_id
209+
}
210+
}]
211+
212+
album = PhotoAlbum(self.service, self.service_endpoint, folder_name,
213+
'CPLContainerRelationLiveByAssetDate',
214+
folder_obj_type, 'ASCENDING', query_filter,
215+
zone_id=self.zone_id)
216+
albums[folder_name] = album
202217

203-
folder_id = folder['recordName']
204-
folder_obj_type = \
205-
"CPLContainerRelationNotDeletedByAssetDate:%s" % folder_id
206-
folder_name = base64.b64decode(
207-
folder['fields']['albumNameEnc']['value']).decode('utf-8')
208-
query_filter = [{
209-
"fieldName": "parentId",
210-
"comparator": "EQUALS",
211-
"fieldValue": {
212-
"type": "STRING",
213-
"value": folder_id
214-
}
215-
}]
216-
217-
album = PhotoAlbum(self.service, self.service_endpoint, folder_name,
218-
'CPLContainerRelationLiveByAssetDate',
219-
folder_obj_type, 'ASCENDING', query_filter,
220-
zone_id=self.zone_id)
221-
self._albums[folder_name] = album
222-
223-
return self._albums
218+
return albums
224219

225220
def _fetch_folders(self) -> Sequence[Dict[str, Any]]:
226221
if self.library_type == "shared":
@@ -243,15 +238,11 @@ def _fetch_folders(self) -> Sequence[Dict[str, Any]]:
243238

244239
@property
245240
def all(self) -> "PhotoAlbum":
246-
if not self._all:
247-
self._all = PhotoAlbum(self.service, self.service_endpoint, "", zone_id=self.zone_id, **self.WHOLE_COLLECTION) # type: ignore[arg-type] # dynamically builing params
248-
return self._all
241+
return PhotoAlbum(self.service, self.service_endpoint, "", zone_id=self.zone_id, **self.WHOLE_COLLECTION) # type: ignore[arg-type] # dynamically builing params
249242

250243
@property
251244
def recently_deleted(self) -> "PhotoAlbum":
252-
if not self._recently_deleted:
253-
self._recently_deleted = PhotoAlbum(self.service, self.service_endpoint, "", zone_id=self.zone_id, **self.RECENTLY_DELETED) # type: ignore[arg-type] # dynamically builing params
254-
return self._recently_deleted
245+
return PhotoAlbum(self.service, self.service_endpoint, "", zone_id=self.zone_id, **self.RECENTLY_DELETED) # type: ignore[arg-type] # dynamically builing params
255246

256247
class PhotosService(PhotoLibrary):
257248
"""The 'Photos' iCloud service.
@@ -357,8 +348,6 @@ def __init__(self, service:PhotosService, service_endpoint: str, name: str, list
357348
self.page_size = page_size
358349
self.exception_handler: Optional[Callable[[Exception, int], None]] = None
359350

360-
self._len: Optional[int] = None
361-
362351
if zone_id:
363352
self._zone_id: Dict[str, Any] = zone_id
364353
else:
@@ -372,21 +361,18 @@ def __iter__(self) -> Generator["PhotoAsset", Any, None]:
372361
return self.photos
373362

374363
def __len__(self) -> int:
375-
if self._len is None:
376-
url = ('%s/internal/records/query/batch?%s' %
377-
(self.service_endpoint,
378-
urlencode(self.service.params)))
379-
request = self.service.session.post(
380-
url,
381-
data=json.dumps(self._count_query_gen(self.obj_type)),
382-
headers={'Content-type': 'text/plain'}
383-
)
384-
response = request.json()
385-
386-
self._len = (response["batch"][0]["records"][0]["fields"]
387-
["itemCount"]["value"])
364+
url = ('%s/internal/records/query/batch?%s' %
365+
(self.service_endpoint,
366+
urlencode(self.service.params)))
367+
request = self.service.session.post(
368+
url,
369+
data=json.dumps(self._count_query_gen(self.obj_type)),
370+
headers={'Content-type': 'text/plain'}
371+
)
372+
response = request.json()
388373

389-
return self._len
374+
return int(response["batch"][0]["records"][0]["fields"]
375+
["itemCount"]["value"])
390376

391377
# Perform the request in a separate method so that we
392378
# can mock it to test session errors.

0 commit comments

Comments
 (0)