Skip to content

Commit

Permalink
fix crash when itemtype is not present in Apple response (#988)
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreyNikiforov authored Nov 3, 2024
1 parent 2967f82 commit 9f54cbf
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 101 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- fix: crashes when no imagetype sent by Apple [ref](https://github.com/boredazfcuk/docker-icloudpd/issues/680)

## 1.24.2 (2024-11-02)

- fix: errors for accounts with salt started with zero byte [#975](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/975)
Expand Down
2 changes: 1 addition & 1 deletion src/icloudpd/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ def state_(icloud: PyiCloudService) -> Callable[[Counter, PhotoAsset], bool]:
def download_photo_(counter: Counter, photo: PhotoAsset) -> bool:
"""internal function for actually downloading the photos"""

if skip_videos and photo.item_type != AssetItemType.IMAGE:
if skip_videos and photo.item_type == AssetItemType.MOVIE:
logger.debug(
"Skipping %s, only downloading photos." + "(Item type was: %s)",
photo.filename,
Expand Down
10 changes: 6 additions & 4 deletions src/pyicloud_ipd/services/photos.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,13 +704,15 @@ def dimensions(self) -> Tuple[int, int]:
self._master_record['fields']['resOriginalHeight']['value'])

@property
def item_type(self) -> AssetItemType:
def item_type(self) -> Optional[AssetItemType]:
fields = self._master_record['fields']
if 'itemType' not in fields:
raise ValueError(f"Cannot find itemType in {fields!r}")
# raise ValueError(f"Cannot find itemType in {fields!r}")
return None
item_type_field = fields['itemType']
if 'value' not in item_type_field:
raise ValueError(f"Cannot find value in itemType {item_type_field!r}")
# raise ValueError(f"Cannot find value in itemType {item_type_field!r}")
return None
item_type = item_type_field['value']
if item_type in self.ITEM_TYPES:
return self.ITEM_TYPES[item_type]
Expand Down Expand Up @@ -777,7 +779,7 @@ def versions(self) -> Dict[VersionSize, AssetVersion]:
# version['type'] = None

# Change live photo movie file extension to .MOV
if (self.item_type == AssetItemType.IMAGE and
if ((self.item_type or AssetItemType.IMAGE) == AssetItemType.IMAGE and
version['type'] == "com.apple.quicktime-movie"):
version['filename'] = self._service.lp_filename_generator(self.filename) # without size
else:
Expand Down
92 changes: 44 additions & 48 deletions tests/test_download_photos.py
Original file line number Diff line number Diff line change
Expand Up @@ -1003,62 +1003,58 @@ def astimezone(self, _tz: (Optional[Any]) = None) -> NoReturn:
def test_missing_item_type(self) -> None:
base_dir = os.path.join(self.fixtures_path, inspect.stack()[0][3])

with mock.patch("icloudpd.download.download_media") as dp_patched:
dp_patched.return_value = True

data_dir, result = run_icloudpd_test(
self.assertEqual,
self.root_path,
base_dir,
"listing_photos_bad_item_type.yml",
[],
[],
[
"--username",
"[email protected]",
"--password",
"password1",
"--recent",
"1",
"--no-progress-bar",
"--threads-num",
"1",
],
)
files_to_download = [
("2018/07/31", "IMG_7409.JPG"),
]

dp_patched.assert_not_called()
_, result = run_icloudpd_test(
self.assertEqual,
self.root_path,
base_dir,
"listing_photos_missing_item_type.yml",
[],
files_to_download,
[
"--username",
"[email protected]",
"--password",
"password1",
"--recent",
"1",
"--no-progress-bar",
"--skip-live-photos",
],
)

self.assertIsInstance(result.exception, ValueError)
assert result.exit_code == 0

def test_missing_item_type_value(self) -> None:
base_dir = os.path.join(self.fixtures_path, inspect.stack()[0][3])

with mock.patch("icloudpd.download.download_media") as dp_patched:
dp_patched.return_value = True

data_dir, result = run_icloudpd_test(
self.assertEqual,
self.root_path,
base_dir,
"listing_photos_missing_item_type_value.yml",
[],
[],
[
"--username",
"[email protected]",
"--password",
"password1",
"--recent",
"1",
"--no-progress-bar",
"--threads-num",
"1",
],
)
files_to_download = [
("2018/07/31", "IMG_7409.JPG"),
]

dp_patched.assert_not_called()
_, result = run_icloudpd_test(
self.assertEqual,
self.root_path,
base_dir,
"listing_photos_missing_item_type_value.yml",
[],
files_to_download,
[
"--username",
"[email protected]",
"--password",
"password1",
"--recent",
"1",
"--no-progress-bar",
"--skip-live-photos",
],
)

self.assertIsInstance(result.exception, ValueError)
assert result.exit_code == 0

def test_download_and_dedupe_existing_photos(self) -> None:
base_dir = os.path.join(self.fixtures_path, inspect.stack()[0][3])
Expand Down
96 changes: 48 additions & 48 deletions tests/test_download_photos_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -952,62 +952,62 @@ def astimezone(self, _tz: (Optional[Any]) = None) -> NoReturn:
def test_missing_item_type_name_id7(self) -> None:
base_dir = os.path.join(self.fixtures_path, inspect.stack()[0][3])

with mock.patch("icloudpd.download.download_media") as dp_patched:
dp_patched.return_value = True

data_dir, result = run_icloudpd_test(
self.assertEqual,
self.root_path,
base_dir,
"listing_photos_bad_item_type.yml",
[],
[],
[
"--username",
"[email protected]",
"--password",
"password1",
"--recent",
"1",
"--no-progress-bar",
"--file-match-policy",
"name-id7",
],
)
files_to_download = [
("2018/07/31", "IMG_7409_QVk2Yyt.JPG"),
]

dp_patched.assert_not_called()
_, result = run_icloudpd_test(
self.assertEqual,
self.root_path,
base_dir,
"listing_photos_missing_item_type.yml",
[],
files_to_download,
[
"--username",
"[email protected]",
"--password",
"password1",
"--recent",
"1",
"--no-progress-bar",
"--file-match-policy",
"name-id7",
"--skip-live-photos",
],
)

self.assertIsInstance(result.exception, ValueError)
assert result.exit_code == 0

def test_missing_item_type_value_name_id7(self) -> None:
base_dir = os.path.join(self.fixtures_path, inspect.stack()[0][3])

with mock.patch("icloudpd.download.download_media") as dp_patched:
dp_patched.return_value = True

data_dir, result = run_icloudpd_test(
self.assertEqual,
self.root_path,
base_dir,
"listing_photos_missing_item_type_value.yml",
[],
[],
[
"--username",
"[email protected]",
"--password",
"password1",
"--recent",
"1",
"--no-progress-bar",
"--file-match-policy",
"name-id7",
],
)
files_to_download = [
("2018/07/31", "IMG_7409_QVk2Yyt.JPG"),
]

dp_patched.assert_not_called()
_, result = run_icloudpd_test(
self.assertEqual,
self.root_path,
base_dir,
"listing_photos_missing_item_type_value.yml",
[],
files_to_download,
[
"--username",
"[email protected]",
"--password",
"password1",
"--recent",
"1",
"--no-progress-bar",
"--file-match-policy",
"name-id7",
"--skip-live-photos",
],
)

self.assertIsInstance(result.exception, ValueError)
assert result.exit_code == 0

def test_download_and_dedupe_existing_photos_name_id7(self) -> None:
base_dir = os.path.join(self.fixtures_path, inspect.stack()[0][3])
Expand Down

0 comments on commit 9f54cbf

Please sign in to comment.