1
0
mirror of https://github.com/immich-app/immich.git synced 2025-08-08 23:07:06 +02:00

feat: support iOS LivePhoto backup (#950)

This commit is contained in:
Alex
2022-11-18 23:12:54 -06:00
committed by GitHub
parent 83e2cabbcc
commit 8bc64be77b
30 changed files with 678 additions and 243 deletions

View File

@ -43,48 +43,51 @@ class AlbumResponseDto {
List<AssetResponseDto> assets;
@override
bool operator ==(Object other) => identical(this, other) || other is AlbumResponseDto &&
other.assetCount == assetCount &&
other.id == id &&
other.ownerId == ownerId &&
other.albumName == albumName &&
other.createdAt == createdAt &&
other.albumThumbnailAssetId == albumThumbnailAssetId &&
other.shared == shared &&
other.sharedUsers == sharedUsers &&
other.assets == assets;
bool operator ==(Object other) =>
identical(this, other) ||
other is AlbumResponseDto &&
other.assetCount == assetCount &&
other.id == id &&
other.ownerId == ownerId &&
other.albumName == albumName &&
other.createdAt == createdAt &&
other.albumThumbnailAssetId == albumThumbnailAssetId &&
other.shared == shared &&
other.sharedUsers == sharedUsers &&
other.assets == assets;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(assetCount.hashCode) +
(id.hashCode) +
(ownerId.hashCode) +
(albumName.hashCode) +
(createdAt.hashCode) +
(albumThumbnailAssetId == null ? 0 : albumThumbnailAssetId!.hashCode) +
(shared.hashCode) +
(sharedUsers.hashCode) +
(assets.hashCode);
// ignore: unnecessary_parenthesis
(assetCount.hashCode) +
(id.hashCode) +
(ownerId.hashCode) +
(albumName.hashCode) +
(createdAt.hashCode) +
(albumThumbnailAssetId == null ? 0 : albumThumbnailAssetId!.hashCode) +
(shared.hashCode) +
(sharedUsers.hashCode) +
(assets.hashCode);
@override
String toString() => 'AlbumResponseDto[assetCount=$assetCount, id=$id, ownerId=$ownerId, albumName=$albumName, createdAt=$createdAt, albumThumbnailAssetId=$albumThumbnailAssetId, shared=$shared, sharedUsers=$sharedUsers, assets=$assets]';
String toString() =>
'AlbumResponseDto[assetCount=$assetCount, id=$id, ownerId=$ownerId, albumName=$albumName, createdAt=$createdAt, albumThumbnailAssetId=$albumThumbnailAssetId, shared=$shared, sharedUsers=$sharedUsers, assets=$assets]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
_json[r'assetCount'] = assetCount;
_json[r'id'] = id;
_json[r'ownerId'] = ownerId;
_json[r'albumName'] = albumName;
_json[r'createdAt'] = createdAt;
_json[r'assetCount'] = assetCount;
_json[r'id'] = id;
_json[r'ownerId'] = ownerId;
_json[r'albumName'] = albumName;
_json[r'createdAt'] = createdAt;
if (albumThumbnailAssetId != null) {
_json[r'albumThumbnailAssetId'] = albumThumbnailAssetId;
} else {
_json[r'albumThumbnailAssetId'] = null;
}
_json[r'shared'] = shared;
_json[r'sharedUsers'] = sharedUsers;
_json[r'assets'] = assets;
_json[r'shared'] = shared;
_json[r'sharedUsers'] = sharedUsers;
_json[r'assets'] = assets;
return _json;
}
@ -98,13 +101,13 @@ class AlbumResponseDto {
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "AlbumResponseDto[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "AlbumResponseDto[$key]" has a null value in JSON.');
});
return true;
}());
// assert(() {
// requiredKeys.forEach((key) {
// assert(json.containsKey(key), 'Required key "AlbumResponseDto[$key]" is missing from JSON.');
// assert(json[key] != null, 'Required key "AlbumResponseDto[$key]" has a null value in JSON.');
// });
// return true;
// }());
return AlbumResponseDto(
assetCount: mapValueOfType<int>(json, r'assetCount')!,
@ -112,7 +115,8 @@ class AlbumResponseDto {
ownerId: mapValueOfType<String>(json, r'ownerId')!,
albumName: mapValueOfType<String>(json, r'albumName')!,
createdAt: mapValueOfType<String>(json, r'createdAt')!,
albumThumbnailAssetId: mapValueOfType<String>(json, r'albumThumbnailAssetId'),
albumThumbnailAssetId:
mapValueOfType<String>(json, r'albumThumbnailAssetId'),
shared: mapValueOfType<bool>(json, r'shared')!,
sharedUsers: UserResponseDto.listFromJson(json[r'sharedUsers'])!,
assets: AssetResponseDto.listFromJson(json[r'assets'])!,
@ -121,7 +125,10 @@ class AlbumResponseDto {
return null;
}
static List<AlbumResponseDto>? listFromJson(dynamic json, {bool growable = false,}) {
static List<AlbumResponseDto>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <AlbumResponseDto>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
@ -149,12 +156,18 @@ class AlbumResponseDto {
}
// maps a json object with a list of AlbumResponseDto-objects as value to a dart map
static Map<String, List<AlbumResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
static Map<String, List<AlbumResponseDto>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<AlbumResponseDto>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = AlbumResponseDto.listFromJson(entry.value, growable: growable,);
final value = AlbumResponseDto.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
@ -176,4 +189,3 @@ class AlbumResponseDto {
'assets',
};
}

View File

@ -29,6 +29,7 @@ class AssetResponseDto {
required this.encodedVideoPath,
this.exifInfo,
this.smartInfo,
required this.livePhotoVideoId,
});
AssetTypeEnum type;
@ -75,70 +76,77 @@ class AssetResponseDto {
///
SmartInfoResponseDto? smartInfo;
String? livePhotoVideoId;
@override
bool operator ==(Object other) => identical(this, other) || other is AssetResponseDto &&
other.type == type &&
other.id == id &&
other.deviceAssetId == deviceAssetId &&
other.ownerId == ownerId &&
other.deviceId == deviceId &&
other.originalPath == originalPath &&
other.resizePath == resizePath &&
other.createdAt == createdAt &&
other.modifiedAt == modifiedAt &&
other.isFavorite == isFavorite &&
other.mimeType == mimeType &&
other.duration == duration &&
other.webpPath == webpPath &&
other.encodedVideoPath == encodedVideoPath &&
other.exifInfo == exifInfo &&
other.smartInfo == smartInfo;
bool operator ==(Object other) =>
identical(this, other) ||
other is AssetResponseDto &&
other.type == type &&
other.id == id &&
other.deviceAssetId == deviceAssetId &&
other.ownerId == ownerId &&
other.deviceId == deviceId &&
other.originalPath == originalPath &&
other.resizePath == resizePath &&
other.createdAt == createdAt &&
other.modifiedAt == modifiedAt &&
other.isFavorite == isFavorite &&
other.mimeType == mimeType &&
other.duration == duration &&
other.webpPath == webpPath &&
other.encodedVideoPath == encodedVideoPath &&
other.exifInfo == exifInfo &&
other.smartInfo == smartInfo &&
other.livePhotoVideoId == livePhotoVideoId;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(type.hashCode) +
(id.hashCode) +
(deviceAssetId.hashCode) +
(ownerId.hashCode) +
(deviceId.hashCode) +
(originalPath.hashCode) +
(resizePath == null ? 0 : resizePath!.hashCode) +
(createdAt.hashCode) +
(modifiedAt.hashCode) +
(isFavorite.hashCode) +
(mimeType == null ? 0 : mimeType!.hashCode) +
(duration.hashCode) +
(webpPath == null ? 0 : webpPath!.hashCode) +
(encodedVideoPath == null ? 0 : encodedVideoPath!.hashCode) +
(exifInfo == null ? 0 : exifInfo!.hashCode) +
(smartInfo == null ? 0 : smartInfo!.hashCode);
// ignore: unnecessary_parenthesis
(type.hashCode) +
(id.hashCode) +
(deviceAssetId.hashCode) +
(ownerId.hashCode) +
(deviceId.hashCode) +
(originalPath.hashCode) +
(resizePath == null ? 0 : resizePath!.hashCode) +
(createdAt.hashCode) +
(modifiedAt.hashCode) +
(isFavorite.hashCode) +
(mimeType == null ? 0 : mimeType!.hashCode) +
(duration.hashCode) +
(webpPath == null ? 0 : webpPath!.hashCode) +
(encodedVideoPath == null ? 0 : encodedVideoPath!.hashCode) +
(exifInfo == null ? 0 : exifInfo!.hashCode) +
(smartInfo == null ? 0 : smartInfo!.hashCode) +
(livePhotoVideoId == null ? 0 : livePhotoVideoId!.hashCode);
@override
String toString() => 'AssetResponseDto[type=$type, id=$id, deviceAssetId=$deviceAssetId, ownerId=$ownerId, deviceId=$deviceId, originalPath=$originalPath, resizePath=$resizePath, createdAt=$createdAt, modifiedAt=$modifiedAt, isFavorite=$isFavorite, mimeType=$mimeType, duration=$duration, webpPath=$webpPath, encodedVideoPath=$encodedVideoPath, exifInfo=$exifInfo, smartInfo=$smartInfo]';
String toString() =>
'AssetResponseDto[type=$type, id=$id, deviceAssetId=$deviceAssetId, ownerId=$ownerId, deviceId=$deviceId, originalPath=$originalPath, resizePath=$resizePath, createdAt=$createdAt, modifiedAt=$modifiedAt, isFavorite=$isFavorite, mimeType=$mimeType, duration=$duration, webpPath=$webpPath, encodedVideoPath=$encodedVideoPath, exifInfo=$exifInfo, smartInfo=$smartInfo, livePhotoVideoId=$livePhotoVideoId]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
_json[r'type'] = type;
_json[r'id'] = id;
_json[r'deviceAssetId'] = deviceAssetId;
_json[r'ownerId'] = ownerId;
_json[r'deviceId'] = deviceId;
_json[r'originalPath'] = originalPath;
_json[r'type'] = type;
_json[r'id'] = id;
_json[r'deviceAssetId'] = deviceAssetId;
_json[r'ownerId'] = ownerId;
_json[r'deviceId'] = deviceId;
_json[r'originalPath'] = originalPath;
if (resizePath != null) {
_json[r'resizePath'] = resizePath;
} else {
_json[r'resizePath'] = null;
}
_json[r'createdAt'] = createdAt;
_json[r'modifiedAt'] = modifiedAt;
_json[r'isFavorite'] = isFavorite;
_json[r'createdAt'] = createdAt;
_json[r'modifiedAt'] = modifiedAt;
_json[r'isFavorite'] = isFavorite;
if (mimeType != null) {
_json[r'mimeType'] = mimeType;
} else {
_json[r'mimeType'] = null;
}
_json[r'duration'] = duration;
_json[r'duration'] = duration;
if (webpPath != null) {
_json[r'webpPath'] = webpPath;
} else {
@ -159,6 +167,11 @@ class AssetResponseDto {
} else {
_json[r'smartInfo'] = null;
}
if (livePhotoVideoId != null) {
_json[r'livePhotoVideoId'] = livePhotoVideoId;
} else {
_json[r'livePhotoVideoId'] = null;
}
return _json;
}
@ -172,13 +185,13 @@ class AssetResponseDto {
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "AssetResponseDto[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "AssetResponseDto[$key]" has a null value in JSON.');
});
return true;
}());
// assert(() {
// requiredKeys.forEach((key) {
// assert(json.containsKey(key), 'Required key "AssetResponseDto[$key]" is missing from JSON.');
// assert(json[key] != null, 'Required key "AssetResponseDto[$key]" has a null value in JSON.');
// });
// return true;
// }());
return AssetResponseDto(
type: AssetTypeEnum.fromJson(json[r'type'])!,
@ -197,12 +210,16 @@ class AssetResponseDto {
encodedVideoPath: mapValueOfType<String>(json, r'encodedVideoPath'),
exifInfo: ExifResponseDto.fromJson(json[r'exifInfo']),
smartInfo: SmartInfoResponseDto.fromJson(json[r'smartInfo']),
livePhotoVideoId: mapValueOfType<String>(json, r'livePhotoVideoId'),
);
}
return null;
}
static List<AssetResponseDto>? listFromJson(dynamic json, {bool growable = false,}) {
static List<AssetResponseDto>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <AssetResponseDto>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
@ -230,12 +247,18 @@ class AssetResponseDto {
}
// maps a json object with a list of AssetResponseDto-objects as value to a dart map
static Map<String, List<AssetResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
static Map<String, List<AssetResponseDto>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<AssetResponseDto>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = AssetResponseDto.listFromJson(entry.value, growable: growable,);
final value = AssetResponseDto.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
@ -260,6 +283,6 @@ class AssetResponseDto {
'duration',
'webpPath',
'encodedVideoPath',
'livePhotoVideoId',
};
}