From 8ee5d3039ada5b9f60cea204d98e49833478ab3a Mon Sep 17 00:00:00 2001 From: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com> Date: Wed, 15 Apr 2026 21:00:33 +0200 Subject: [PATCH] chore!: remove deviceId and deviceAssetId (#27818) chore: remove deviceId and deviceAssetId --- cli/src/commands/asset.ts | 2 - docs/docs/guides/python-file-upload.md | 2 - e2e/src/specs/server/api/asset.e2e-spec.ts | 29 --- e2e/src/specs/server/api/search.e2e-spec.ts | 1 - e2e/src/specs/web/duplicates.e2e-spec.ts | 4 +- .../ui/generators/timeline/rest-response.ts | 2 - .../ui/mock-network/broken-asset-network.ts | 2 - e2e/src/utils.ts | 7 - mobile/openapi/README.md | 5 - mobile/openapi/lib/api.dart | 2 - mobile/openapi/lib/api/assets_api.dart | 144 +----------- mobile/openapi/lib/api/deprecated_api.dart | 62 ------ mobile/openapi/lib/api/search_api.dart | 15 +- mobile/openapi/lib/api_client.dart | 4 - .../openapi/lib/model/asset_response_dto.dart | 20 +- .../lib/model/check_existing_assets_dto.dart | 111 ---------- .../check_existing_assets_response_dto.dart | 102 --------- .../lib/model/metadata_search_dto.dart | 38 +--- .../openapi/lib/model/random_search_dto.dart | 20 +- .../openapi/lib/model/smart_search_dto.dart | 20 +- .../lib/model/statistics_search_dto.dart | 20 +- open-api/immich-openapi-specs.json | 205 ------------------ open-api/typescript-sdk/src/fetch-client.ts | 60 +---- .../asset-media.controller.spec.ts | 24 -- .../src/controllers/asset-media.controller.ts | 17 -- server/src/controllers/asset.controller.ts | 12 - server/src/database.ts | 4 - server/src/dtos/asset-media-response.dto.ts | 7 - server/src/dtos/asset-media.dto.ts | 10 - server/src/dtos/asset-response.dto.ts | 6 - server/src/dtos/asset.dto.ts | 7 - server/src/dtos/search.dto.ts | 2 - server/src/queries/asset.job.repository.sql | 2 - server/src/queries/asset.repository.sql | 14 +- server/src/repositories/asset.repository.ts | 35 +-- server/src/repositories/search.repository.ts | 2 - ...6263790468-DropDeviceIdAndDeviceAssetId.ts | 11 + server/src/schema/tables/asset.table.ts | 6 - .../src/services/asset-media.service.spec.ts | 15 -- server/src/services/asset-media.service.ts | 17 -- server/src/services/asset.service.spec.ts | 14 -- server/src/services/asset.service.ts | 4 - server/src/services/library.service.spec.ts | 1 - server/src/services/library.service.ts | 5 +- server/src/services/metadata.service.spec.ts | 6 - server/src/services/metadata.service.ts | 2 - server/src/utils/database.ts | 2 - server/src/utils/duplicate.spec.ts | 2 - server/test/factories/asset.factory.ts | 2 - server/test/mappers.ts | 2 - server/test/medium.factory.ts | 2 - .../services/asset-media.service.spec.ts | 14 +- .../repositories/asset.repository.mock.ts | 2 - web/src/lib/utils/file-uploader.ts | 5 +- web/src/test-data/factories/asset-factory.ts | 2 - 55 files changed, 31 insertions(+), 1102 deletions(-) delete mode 100644 mobile/openapi/lib/model/check_existing_assets_dto.dart delete mode 100644 mobile/openapi/lib/model/check_existing_assets_response_dto.dart create mode 100644 server/src/schema/migrations/1776263790468-DropDeviceIdAndDeviceAssetId.ts diff --git a/cli/src/commands/asset.ts b/cli/src/commands/asset.ts index c3ad820547..2c6430c83a 100644 --- a/cli/src/commands/asset.ts +++ b/cli/src/commands/asset.ts @@ -404,8 +404,6 @@ const uploadFile = async (input: string, stats: Stats): Promise { const { body, status } = await request(app) .post('/assets') .set('Authorization', `Bearer ${quotaUser.accessToken}`) - .field('deviceAssetId', 'example-image') - .field('deviceId', 'e2e') .field('fileCreatedAt', new Date().toISOString()) .field('fileModifiedAt', new Date().toISOString()) .attach('assetData', makeRandomImage(), 'example.jpg'); @@ -1109,8 +1107,6 @@ describe('/asset', () => { const { body, status } = await request(app) .post('/assets') .set('Authorization', `Bearer ${quotaUser.accessToken}`) - .field('deviceAssetId', 'example-image') - .field('deviceId', 'e2e') .field('fileCreatedAt', new Date().toISOString()) .field('fileModifiedAt', new Date().toISOString()) .attach('assetData', randomBytes(2014), 'example.jpg'); @@ -1164,29 +1160,4 @@ describe('/asset', () => { expect(video.checksum).toStrictEqual(checksum); }); }); - - describe('POST /assets/exist', () => { - it('ignores invalid deviceAssetIds', async () => { - const response = await utils.checkExistingAssets(user1.accessToken, { - deviceId: 'test-assets-exist', - deviceAssetIds: ['invalid', 'INVALID'], - }); - - expect(response.existingIds).toHaveLength(0); - }); - - it('returns the IDs of existing assets', async () => { - await utils.createAsset(user1.accessToken, { - deviceId: 'test-assets-exist', - deviceAssetId: 'test-asset-0', - }); - - const response = await utils.checkExistingAssets(user1.accessToken, { - deviceId: 'test-assets-exist', - deviceAssetIds: ['test-asset-0'], - }); - - expect(response.existingIds).toEqual(['test-asset-0']); - }); - }); }); diff --git a/e2e/src/specs/server/api/search.e2e-spec.ts b/e2e/src/specs/server/api/search.e2e-spec.ts index 2f6ea75f77..4ee021b1e4 100644 --- a/e2e/src/specs/server/api/search.e2e-spec.ts +++ b/e2e/src/specs/server/api/search.e2e-spec.ts @@ -74,7 +74,6 @@ describe('/search', () => { const bytes = await readFile(join(testAssetDir, filename)); assets.push( await utils.createAsset(admin.accessToken, { - deviceAssetId: `test-${filename}`, assetData: { bytes, filename }, ...dto, }), diff --git a/e2e/src/specs/web/duplicates.e2e-spec.ts b/e2e/src/specs/web/duplicates.e2e-spec.ts index 34f11cdf78..c39e9019d3 100644 --- a/e2e/src/specs/web/duplicates.e2e-spec.ts +++ b/e2e/src/specs/web/duplicates.e2e-spec.ts @@ -16,8 +16,8 @@ test.describe('Duplicates Utility', () => { test.beforeEach(async ({ context }) => { [firstAsset, secondAsset] = await Promise.all([ - utils.createAsset(admin.accessToken, { deviceAssetId: 'duplicate-a' }), - utils.createAsset(admin.accessToken, { deviceAssetId: 'duplicate-b' }), + utils.createAsset(admin.accessToken, {}), + utils.createAsset(admin.accessToken, {}), ]); await updateAssets( diff --git a/e2e/src/ui/generators/timeline/rest-response.ts b/e2e/src/ui/generators/timeline/rest-response.ts index 0c4bd06dc3..de8aa3ee05 100644 --- a/e2e/src/ui/generators/timeline/rest-response.ts +++ b/e2e/src/ui/generators/timeline/rest-response.ts @@ -315,11 +315,9 @@ export function toAssetResponseDto(asset: MockTimelineAsset, owner?: UserRespons return { id: asset.id, - deviceAssetId: `device-${asset.id}`, ownerId: asset.ownerId, owner: owner || defaultOwner, libraryId: `library-${asset.ownerId}`, - deviceId: `device-${asset.ownerId}`, type: asset.isVideo ? AssetTypeEnum.Video : AssetTypeEnum.Image, originalPath: `/original/${asset.id}.${asset.isVideo ? 'mp4' : 'jpg'}`, originalFileName: `${asset.id}.${asset.isVideo ? 'mp4' : 'jpg'}`, diff --git a/e2e/src/ui/mock-network/broken-asset-network.ts b/e2e/src/ui/mock-network/broken-asset-network.ts index eff93a8d72..75d579e1ef 100644 --- a/e2e/src/ui/mock-network/broken-asset-network.ts +++ b/e2e/src/ui/mock-network/broken-asset-network.ts @@ -16,7 +16,6 @@ export const createMockStackAsset = (ownerId: string): AssetResponseDto => { const now = new Date().toISOString(); return { id: assetId, - deviceAssetId: `device-${assetId}`, ownerId, owner: { id: ownerId, @@ -27,7 +26,6 @@ export const createMockStackAsset = (ownerId: string): AssetResponseDto => { avatarColor: 'blue' as never, }, libraryId: `library-${ownerId}`, - deviceId: `device-${ownerId}`, type: AssetTypeEnum.Image, originalPath: `/original/${assetId}.jpg`, originalFileName: `${assetId}.jpg`, diff --git a/e2e/src/utils.ts b/e2e/src/utils.ts index f9dd11a1ec..aa4c3b8499 100644 --- a/e2e/src/utils.ts +++ b/e2e/src/utils.ts @@ -3,7 +3,6 @@ import { AssetMediaResponseDto, AssetResponseDto, AssetVisibility, - CheckExistingAssetsDto, CreateAlbumDto, CreateLibraryDto, JobCreateDto, @@ -20,7 +19,6 @@ import { UserAdminCreateDto, UserPreferencesUpdateDto, ValidateLibraryDto, - checkExistingAssets, createAlbum, createApiKey, createJob, @@ -343,8 +341,6 @@ export const utils = { }, ) => { const _dto = { - deviceAssetId: 'test-1', - deviceId: 'test', fileCreatedAt: new Date().toISOString(), fileModifiedAt: new Date().toISOString(), ...dto, @@ -416,9 +412,6 @@ export const utils = { getAssetInfo: (accessToken: string, id: string) => getAssetInfo({ id }, { headers: asBearerAuth(accessToken) }), - checkExistingAssets: (accessToken: string, checkExistingAssetsDto: CheckExistingAssetsDto) => - checkExistingAssets({ checkExistingAssetsDto }, { headers: asBearerAuth(accessToken) }), - searchAssets: async (accessToken: string, dto: MetadataSearchDto) => { return searchAssets({ metadataSearchDto: dto }, { headers: asBearerAuth(accessToken) }); }, diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index c893ce33a5..e95790b020 100644 --- a/mobile/openapi/README.md +++ b/mobile/openapi/README.md @@ -96,14 +96,12 @@ Class | Method | HTTP request | Description *AlbumsApi* | [**updateAlbumInfo**](doc//AlbumsApi.md#updatealbuminfo) | **PATCH** /albums/{id} | Update an album *AlbumsApi* | [**updateAlbumUser**](doc//AlbumsApi.md#updatealbumuser) | **PUT** /albums/{id}/user/{userId} | Update user role *AssetsApi* | [**checkBulkUpload**](doc//AssetsApi.md#checkbulkupload) | **POST** /assets/bulk-upload-check | Check bulk upload -*AssetsApi* | [**checkExistingAssets**](doc//AssetsApi.md#checkexistingassets) | **POST** /assets/exist | Check existing assets *AssetsApi* | [**copyAsset**](doc//AssetsApi.md#copyasset) | **PUT** /assets/copy | Copy asset *AssetsApi* | [**deleteAssetMetadata**](doc//AssetsApi.md#deleteassetmetadata) | **DELETE** /assets/{id}/metadata/{key} | Delete asset metadata by key *AssetsApi* | [**deleteAssets**](doc//AssetsApi.md#deleteassets) | **DELETE** /assets | Delete assets *AssetsApi* | [**deleteBulkAssetMetadata**](doc//AssetsApi.md#deletebulkassetmetadata) | **DELETE** /assets/metadata | Delete asset metadata *AssetsApi* | [**downloadAsset**](doc//AssetsApi.md#downloadasset) | **GET** /assets/{id}/original | Download original asset *AssetsApi* | [**editAsset**](doc//AssetsApi.md#editasset) | **PUT** /assets/{id}/edits | Apply edits to an existing asset -*AssetsApi* | [**getAllUserAssetsByDeviceId**](doc//AssetsApi.md#getalluserassetsbydeviceid) | **GET** /assets/device/{deviceId} | Retrieve assets by device ID *AssetsApi* | [**getAssetEdits**](doc//AssetsApi.md#getassetedits) | **GET** /assets/{id}/edits | Retrieve edits for an existing asset *AssetsApi* | [**getAssetInfo**](doc//AssetsApi.md#getassetinfo) | **GET** /assets/{id} | Retrieve an asset *AssetsApi* | [**getAssetMetadata**](doc//AssetsApi.md#getassetmetadata) | **GET** /assets/{id}/metadata | Get asset metadata @@ -142,7 +140,6 @@ Class | Method | HTTP request | Description *DatabaseBackupsAdminApi* | [**startDatabaseRestoreFlow**](doc//DatabaseBackupsAdminApi.md#startdatabaserestoreflow) | **POST** /admin/database-backups/start-restore | Start database backup restore flow *DatabaseBackupsAdminApi* | [**uploadDatabaseBackup**](doc//DatabaseBackupsAdminApi.md#uploaddatabasebackup) | **POST** /admin/database-backups/upload | Upload database backup *DeprecatedApi* | [**createPartnerDeprecated**](doc//DeprecatedApi.md#createpartnerdeprecated) | **POST** /partners/{id} | Create a partner -*DeprecatedApi* | [**getAllUserAssetsByDeviceId**](doc//DeprecatedApi.md#getalluserassetsbydeviceid) | **GET** /assets/device/{deviceId} | Retrieve assets by device ID *DeprecatedApi* | [**getQueuesLegacy**](doc//DeprecatedApi.md#getqueueslegacy) | **GET** /jobs | Retrieve queue counts and status *DeprecatedApi* | [**runQueueCommandLegacy**](doc//DeprecatedApi.md#runqueuecommandlegacy) | **PUT** /jobs/{name} | Run jobs *DownloadApi* | [**downloadArchive**](doc//DownloadApi.md#downloadarchive) | **POST** /download/archive | Download asset archive @@ -396,8 +393,6 @@ Class | Method | HTTP request | Description - [CastResponse](doc//CastResponse.md) - [CastUpdate](doc//CastUpdate.md) - [ChangePasswordDto](doc//ChangePasswordDto.md) - - [CheckExistingAssetsDto](doc//CheckExistingAssetsDto.md) - - [CheckExistingAssetsResponseDto](doc//CheckExistingAssetsResponseDto.md) - [Colorspace](doc//Colorspace.md) - [ContributorCountResponseDto](doc//ContributorCountResponseDto.md) - [CreateAlbumDto](doc//CreateAlbumDto.md) diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index b64f222791..15bc8190dc 100644 --- a/mobile/openapi/lib/api.dart +++ b/mobile/openapi/lib/api.dart @@ -142,8 +142,6 @@ part 'model/cq_mode.dart'; part 'model/cast_response.dart'; part 'model/cast_update.dart'; part 'model/change_password_dto.dart'; -part 'model/check_existing_assets_dto.dart'; -part 'model/check_existing_assets_response_dto.dart'; part 'model/colorspace.dart'; part 'model/contributor_count_response_dto.dart'; part 'model/create_album_dto.dart'; diff --git a/mobile/openapi/lib/api/assets_api.dart b/mobile/openapi/lib/api/assets_api.dart index 9e0183536e..5046376168 100644 --- a/mobile/openapi/lib/api/assets_api.dart +++ b/mobile/openapi/lib/api/assets_api.dart @@ -72,62 +72,6 @@ class AssetsApi { return null; } - /// Check existing assets - /// - /// Checks if multiple assets exist on the server and returns all existing - used by background backup - /// - /// Note: This method returns the HTTP [Response]. - /// - /// Parameters: - /// - /// * [CheckExistingAssetsDto] checkExistingAssetsDto (required): - Future checkExistingAssetsWithHttpInfo(CheckExistingAssetsDto checkExistingAssetsDto,) async { - // ignore: prefer_const_declarations - final apiPath = r'/assets/exist'; - - // ignore: prefer_final_locals - Object? postBody = checkExistingAssetsDto; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - const contentTypes = ['application/json']; - - - return apiClient.invokeAPI( - apiPath, - 'POST', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - /// Check existing assets - /// - /// Checks if multiple assets exist on the server and returns all existing - used by background backup - /// - /// Parameters: - /// - /// * [CheckExistingAssetsDto] checkExistingAssetsDto (required): - Future checkExistingAssets(CheckExistingAssetsDto checkExistingAssetsDto,) async { - final response = await checkExistingAssetsWithHttpInfo(checkExistingAssetsDto,); - if (response.statusCode >= HttpStatus.badRequest) { - throw ApiException(response.statusCode, await _decodeBodyBytes(response)); - } - // When a remote server returns no body with a status of 204, we shall not decode it. - // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" - // FormatException when trying to decode an empty string. - if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { - return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'CheckExistingAssetsResponseDto',) as CheckExistingAssetsResponseDto; - - } - return null; - } - /// Copy asset /// /// Copy asset information like albums, tags, etc. from one asset to another. @@ -472,68 +416,6 @@ class AssetsApi { return null; } - /// Retrieve assets by device ID - /// - /// Get all asset of a device that are in the database, ID only. - /// - /// Note: This method returns the HTTP [Response]. - /// - /// Parameters: - /// - /// * [String] deviceId (required): - /// Device ID - Future getAllUserAssetsByDeviceIdWithHttpInfo(String deviceId,) async { - // ignore: prefer_const_declarations - final apiPath = r'/assets/device/{deviceId}' - .replaceAll('{deviceId}', deviceId); - - // ignore: prefer_final_locals - Object? postBody; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - const contentTypes = []; - - - return apiClient.invokeAPI( - apiPath, - 'GET', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - /// Retrieve assets by device ID - /// - /// Get all asset of a device that are in the database, ID only. - /// - /// Parameters: - /// - /// * [String] deviceId (required): - /// Device ID - Future?> getAllUserAssetsByDeviceId(String deviceId,) async { - final response = await getAllUserAssetsByDeviceIdWithHttpInfo(deviceId,); - if (response.statusCode >= HttpStatus.badRequest) { - throw ApiException(response.statusCode, await _decodeBodyBytes(response)); - } - // When a remote server returns no body with a status of 204, we shall not decode it. - // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" - // FormatException when trying to decode an empty string. - if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { - final responseBody = await _decodeBodyBytes(response); - return (await apiClient.deserializeAsync(responseBody, 'List') as List) - .cast() - .toList(growable: false); - - } - return null; - } - /// Retrieve edits for an existing asset /// /// Retrieve a series of edit actions (crop, rotate, mirror) associated with the specified asset. @@ -1339,12 +1221,6 @@ class AssetsApi { /// * [MultipartFile] assetData (required): /// Asset file data /// - /// * [String] deviceAssetId (required): - /// Device asset ID - /// - /// * [String] deviceId (required): - /// Device ID - /// /// * [DateTime] fileCreatedAt (required): /// File creation date /// @@ -1377,7 +1253,7 @@ class AssetsApi { /// Sidecar file data /// /// * [AssetVisibility] visibility: - Future uploadAssetWithHttpInfo(MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, String? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async { + Future uploadAssetWithHttpInfo(MultipartFile assetData, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, String? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async { // ignore: prefer_const_declarations final apiPath = r'/assets'; @@ -1408,14 +1284,6 @@ class AssetsApi { mp.fields[r'assetData'] = assetData.field; mp.files.add(assetData); } - if (deviceAssetId != null) { - hasFields = true; - mp.fields[r'deviceAssetId'] = parameterToString(deviceAssetId); - } - if (deviceId != null) { - hasFields = true; - mp.fields[r'deviceId'] = parameterToString(deviceId); - } if (duration != null) { hasFields = true; mp.fields[r'duration'] = parameterToString(duration); @@ -1477,12 +1345,6 @@ class AssetsApi { /// * [MultipartFile] assetData (required): /// Asset file data /// - /// * [String] deviceAssetId (required): - /// Device asset ID - /// - /// * [String] deviceId (required): - /// Device ID - /// /// * [DateTime] fileCreatedAt (required): /// File creation date /// @@ -1515,8 +1377,8 @@ class AssetsApi { /// Sidecar file data /// /// * [AssetVisibility] visibility: - Future uploadAsset(MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, String? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async { - final response = await uploadAssetWithHttpInfo(assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, slug: slug, xImmichChecksum: xImmichChecksum, duration: duration, filename: filename, isFavorite: isFavorite, livePhotoVideoId: livePhotoVideoId, metadata: metadata, sidecarData: sidecarData, visibility: visibility, ); + Future uploadAsset(MultipartFile assetData, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, String? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async { + final response = await uploadAssetWithHttpInfo(assetData, fileCreatedAt, fileModifiedAt, key: key, slug: slug, xImmichChecksum: xImmichChecksum, duration: duration, filename: filename, isFavorite: isFavorite, livePhotoVideoId: livePhotoVideoId, metadata: metadata, sidecarData: sidecarData, visibility: visibility, ); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api/deprecated_api.dart b/mobile/openapi/lib/api/deprecated_api.dart index 5fa5df88b6..a437cd5837 100644 --- a/mobile/openapi/lib/api/deprecated_api.dart +++ b/mobile/openapi/lib/api/deprecated_api.dart @@ -73,68 +73,6 @@ class DeprecatedApi { return null; } - /// Retrieve assets by device ID - /// - /// Get all asset of a device that are in the database, ID only. - /// - /// Note: This method returns the HTTP [Response]. - /// - /// Parameters: - /// - /// * [String] deviceId (required): - /// Device ID - Future getAllUserAssetsByDeviceIdWithHttpInfo(String deviceId,) async { - // ignore: prefer_const_declarations - final apiPath = r'/assets/device/{deviceId}' - .replaceAll('{deviceId}', deviceId); - - // ignore: prefer_final_locals - Object? postBody; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - const contentTypes = []; - - - return apiClient.invokeAPI( - apiPath, - 'GET', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - /// Retrieve assets by device ID - /// - /// Get all asset of a device that are in the database, ID only. - /// - /// Parameters: - /// - /// * [String] deviceId (required): - /// Device ID - Future?> getAllUserAssetsByDeviceId(String deviceId,) async { - final response = await getAllUserAssetsByDeviceIdWithHttpInfo(deviceId,); - if (response.statusCode >= HttpStatus.badRequest) { - throw ApiException(response.statusCode, await _decodeBodyBytes(response)); - } - // When a remote server returns no body with a status of 204, we shall not decode it. - // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" - // FormatException when trying to decode an empty string. - if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { - final responseBody = await _decodeBodyBytes(response); - return (await apiClient.deserializeAsync(responseBody, 'List') as List) - .cast() - .toList(growable: false); - - } - return null; - } - /// Retrieve queue counts and status /// /// Retrieve the counts of the current queue, as well as the current status. diff --git a/mobile/openapi/lib/api/search_api.dart b/mobile/openapi/lib/api/search_api.dart index 46fc8594a8..730627d4a1 100644 --- a/mobile/openapi/lib/api/search_api.dart +++ b/mobile/openapi/lib/api/search_api.dart @@ -368,9 +368,6 @@ class SearchApi { /// * [DateTime] createdBefore: /// Filter by creation date (before) /// - /// * [String] deviceId: - /// Device ID to filter by - /// /// * [bool] isEncoded: /// Filter by encoded status /// @@ -446,7 +443,7 @@ class SearchApi { /// /// * [bool] withExif: /// Include EXIF data in response - Future searchLargeAssetsWithHttpInfo({ List? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceId, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List? personIds, num? rating, num? size, String? state, List? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async { + Future searchLargeAssetsWithHttpInfo({ List? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List? personIds, num? rating, num? size, String? state, List? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async { // ignore: prefer_const_declarations final apiPath = r'/search/large-assets'; @@ -472,9 +469,6 @@ class SearchApi { if (createdBefore != null) { queryParams.addAll(_queryParams('', 'createdBefore', createdBefore)); } - if (deviceId != null) { - queryParams.addAll(_queryParams('', 'deviceId', deviceId)); - } if (isEncoded != null) { queryParams.addAll(_queryParams('', 'isEncoded', isEncoded)); } @@ -589,9 +583,6 @@ class SearchApi { /// * [DateTime] createdBefore: /// Filter by creation date (before) /// - /// * [String] deviceId: - /// Device ID to filter by - /// /// * [bool] isEncoded: /// Filter by encoded status /// @@ -667,8 +658,8 @@ class SearchApi { /// /// * [bool] withExif: /// Include EXIF data in response - Future?> searchLargeAssets({ List? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceId, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List? personIds, num? rating, num? size, String? state, List? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async { - final response = await searchLargeAssetsWithHttpInfo( albumIds: albumIds, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, deviceId: deviceId, isEncoded: isEncoded, isFavorite: isFavorite, isMotion: isMotion, isNotInAlbum: isNotInAlbum, isOffline: isOffline, lensModel: lensModel, libraryId: libraryId, make: make, minFileSize: minFileSize, model: model, ocr: ocr, personIds: personIds, rating: rating, size: size, state: state, tagIds: tagIds, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, visibility: visibility, withDeleted: withDeleted, withExif: withExif, ); + Future?> searchLargeAssets({ List? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List? personIds, num? rating, num? size, String? state, List? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async { + final response = await searchLargeAssetsWithHttpInfo( albumIds: albumIds, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, isEncoded: isEncoded, isFavorite: isFavorite, isMotion: isMotion, isNotInAlbum: isNotInAlbum, isOffline: isOffline, lensModel: lensModel, libraryId: libraryId, make: make, minFileSize: minFileSize, model: model, ocr: ocr, personIds: personIds, rating: rating, size: size, state: state, tagIds: tagIds, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, visibility: visibility, withDeleted: withDeleted, withExif: withExif, ); if (response.statusCode >= HttpStatus.badRequest) { throw ApiException(response.statusCode, await _decodeBodyBytes(response)); } diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index c54a7bafa8..c4782a2340 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -330,10 +330,6 @@ class ApiClient { return CastUpdate.fromJson(value); case 'ChangePasswordDto': return ChangePasswordDto.fromJson(value); - case 'CheckExistingAssetsDto': - return CheckExistingAssetsDto.fromJson(value); - case 'CheckExistingAssetsResponseDto': - return CheckExistingAssetsResponseDto.fromJson(value); case 'Colorspace': return ColorspaceTypeTransformer().decode(value); case 'ContributorCountResponseDto': diff --git a/mobile/openapi/lib/model/asset_response_dto.dart b/mobile/openapi/lib/model/asset_response_dto.dart index d185761f54..a9d346b155 100644 --- a/mobile/openapi/lib/model/asset_response_dto.dart +++ b/mobile/openapi/lib/model/asset_response_dto.dart @@ -15,8 +15,6 @@ class AssetResponseDto { AssetResponseDto({ required this.checksum, required this.createdAt, - required this.deviceAssetId, - required this.deviceId, this.duplicateId, required this.duration, this.exifInfo, @@ -56,12 +54,6 @@ class AssetResponseDto { /// The UTC timestamp when the asset was originally uploaded to Immich. DateTime createdAt; - /// Device asset ID - String deviceAssetId; - - /// Device ID - String deviceId; - /// Duplicate group ID String? duplicateId; @@ -179,8 +171,6 @@ class AssetResponseDto { bool operator ==(Object other) => identical(this, other) || other is AssetResponseDto && other.checksum == checksum && other.createdAt == createdAt && - other.deviceAssetId == deviceAssetId && - other.deviceId == deviceId && other.duplicateId == duplicateId && other.duration == duration && other.exifInfo == exifInfo && @@ -218,8 +208,6 @@ class AssetResponseDto { // ignore: unnecessary_parenthesis (checksum.hashCode) + (createdAt.hashCode) + - (deviceAssetId.hashCode) + - (deviceId.hashCode) + (duplicateId == null ? 0 : duplicateId!.hashCode) + (duration.hashCode) + (exifInfo == null ? 0 : exifInfo!.hashCode) + @@ -253,14 +241,12 @@ class AssetResponseDto { (width == null ? 0 : width!.hashCode); @override - String toString() => 'AssetResponseDto[checksum=$checksum, createdAt=$createdAt, deviceAssetId=$deviceAssetId, deviceId=$deviceId, duplicateId=$duplicateId, duration=$duration, exifInfo=$exifInfo, fileCreatedAt=$fileCreatedAt, fileModifiedAt=$fileModifiedAt, hasMetadata=$hasMetadata, height=$height, id=$id, isArchived=$isArchived, isEdited=$isEdited, isFavorite=$isFavorite, isOffline=$isOffline, isTrashed=$isTrashed, libraryId=$libraryId, livePhotoVideoId=$livePhotoVideoId, localDateTime=$localDateTime, originalFileName=$originalFileName, originalMimeType=$originalMimeType, originalPath=$originalPath, owner=$owner, ownerId=$ownerId, people=$people, resized=$resized, stack=$stack, tags=$tags, thumbhash=$thumbhash, type=$type, unassignedFaces=$unassignedFaces, updatedAt=$updatedAt, visibility=$visibility, width=$width]'; + String toString() => 'AssetResponseDto[checksum=$checksum, createdAt=$createdAt, duplicateId=$duplicateId, duration=$duration, exifInfo=$exifInfo, fileCreatedAt=$fileCreatedAt, fileModifiedAt=$fileModifiedAt, hasMetadata=$hasMetadata, height=$height, id=$id, isArchived=$isArchived, isEdited=$isEdited, isFavorite=$isFavorite, isOffline=$isOffline, isTrashed=$isTrashed, libraryId=$libraryId, livePhotoVideoId=$livePhotoVideoId, localDateTime=$localDateTime, originalFileName=$originalFileName, originalMimeType=$originalMimeType, originalPath=$originalPath, owner=$owner, ownerId=$ownerId, people=$people, resized=$resized, stack=$stack, tags=$tags, thumbhash=$thumbhash, type=$type, unassignedFaces=$unassignedFaces, updatedAt=$updatedAt, visibility=$visibility, width=$width]'; Map toJson() { final json = {}; json[r'checksum'] = this.checksum; json[r'createdAt'] = this.createdAt.toUtc().toIso8601String(); - json[r'deviceAssetId'] = this.deviceAssetId; - json[r'deviceId'] = this.deviceId; if (this.duplicateId != null) { json[r'duplicateId'] = this.duplicateId; } else { @@ -350,8 +336,6 @@ class AssetResponseDto { return AssetResponseDto( checksum: mapValueOfType(json, r'checksum')!, createdAt: mapDateTime(json, r'createdAt', r'')!, - deviceAssetId: mapValueOfType(json, r'deviceAssetId')!, - deviceId: mapValueOfType(json, r'deviceId')!, duplicateId: mapValueOfType(json, r'duplicateId'), duration: mapValueOfType(json, r'duration')!, exifInfo: ExifResponseDto.fromJson(json[r'exifInfo']), @@ -436,8 +420,6 @@ class AssetResponseDto { static const requiredKeys = { 'checksum', 'createdAt', - 'deviceAssetId', - 'deviceId', 'duration', 'fileCreatedAt', 'fileModifiedAt', diff --git a/mobile/openapi/lib/model/check_existing_assets_dto.dart b/mobile/openapi/lib/model/check_existing_assets_dto.dart deleted file mode 100644 index 6e4a471092..0000000000 --- a/mobile/openapi/lib/model/check_existing_assets_dto.dart +++ /dev/null @@ -1,111 +0,0 @@ -// -// AUTO-GENERATED FILE, DO NOT MODIFY! -// -// @dart=2.18 - -// ignore_for_file: unused_element, unused_import -// ignore_for_file: always_put_required_named_parameters_first -// ignore_for_file: constant_identifier_names -// ignore_for_file: lines_longer_than_80_chars - -part of openapi.api; - -class CheckExistingAssetsDto { - /// Returns a new [CheckExistingAssetsDto] instance. - CheckExistingAssetsDto({ - this.deviceAssetIds = const [], - required this.deviceId, - }); - - /// Device asset IDs to check - List deviceAssetIds; - - /// Device ID - String deviceId; - - @override - bool operator ==(Object other) => identical(this, other) || other is CheckExistingAssetsDto && - _deepEquality.equals(other.deviceAssetIds, deviceAssetIds) && - other.deviceId == deviceId; - - @override - int get hashCode => - // ignore: unnecessary_parenthesis - (deviceAssetIds.hashCode) + - (deviceId.hashCode); - - @override - String toString() => 'CheckExistingAssetsDto[deviceAssetIds=$deviceAssetIds, deviceId=$deviceId]'; - - Map toJson() { - final json = {}; - json[r'deviceAssetIds'] = this.deviceAssetIds; - json[r'deviceId'] = this.deviceId; - return json; - } - - /// Returns a new [CheckExistingAssetsDto] instance and imports its values from - /// [value] if it's a [Map], null otherwise. - // ignore: prefer_constructors_over_static_methods - static CheckExistingAssetsDto? fromJson(dynamic value) { - upgradeDto(value, "CheckExistingAssetsDto"); - if (value is Map) { - final json = value.cast(); - - return CheckExistingAssetsDto( - deviceAssetIds: json[r'deviceAssetIds'] is Iterable - ? (json[r'deviceAssetIds'] as Iterable).cast().toList(growable: false) - : const [], - deviceId: mapValueOfType(json, r'deviceId')!, - ); - } - return null; - } - - static List listFromJson(dynamic json, {bool growable = false,}) { - final result = []; - if (json is List && json.isNotEmpty) { - for (final row in json) { - final value = CheckExistingAssetsDto.fromJson(row); - if (value != null) { - result.add(value); - } - } - } - return result.toList(growable: growable); - } - - static Map mapFromJson(dynamic json) { - final map = {}; - if (json is Map && json.isNotEmpty) { - json = json.cast(); // ignore: parameter_assignments - for (final entry in json.entries) { - final value = CheckExistingAssetsDto.fromJson(entry.value); - if (value != null) { - map[entry.key] = value; - } - } - } - return map; - } - - // maps a json object with a list of CheckExistingAssetsDto-objects as value to a dart map - static Map> mapListFromJson(dynamic json, {bool growable = false,}) { - final map = >{}; - if (json is Map && json.isNotEmpty) { - // ignore: parameter_assignments - json = json.cast(); - for (final entry in json.entries) { - map[entry.key] = CheckExistingAssetsDto.listFromJson(entry.value, growable: growable,); - } - } - return map; - } - - /// The list of required keys that must be present in a JSON. - static const requiredKeys = { - 'deviceAssetIds', - 'deviceId', - }; -} - diff --git a/mobile/openapi/lib/model/check_existing_assets_response_dto.dart b/mobile/openapi/lib/model/check_existing_assets_response_dto.dart deleted file mode 100644 index 9fb13f100f..0000000000 --- a/mobile/openapi/lib/model/check_existing_assets_response_dto.dart +++ /dev/null @@ -1,102 +0,0 @@ -// -// AUTO-GENERATED FILE, DO NOT MODIFY! -// -// @dart=2.18 - -// ignore_for_file: unused_element, unused_import -// ignore_for_file: always_put_required_named_parameters_first -// ignore_for_file: constant_identifier_names -// ignore_for_file: lines_longer_than_80_chars - -part of openapi.api; - -class CheckExistingAssetsResponseDto { - /// Returns a new [CheckExistingAssetsResponseDto] instance. - CheckExistingAssetsResponseDto({ - this.existingIds = const [], - }); - - /// Existing asset IDs - List existingIds; - - @override - bool operator ==(Object other) => identical(this, other) || other is CheckExistingAssetsResponseDto && - _deepEquality.equals(other.existingIds, existingIds); - - @override - int get hashCode => - // ignore: unnecessary_parenthesis - (existingIds.hashCode); - - @override - String toString() => 'CheckExistingAssetsResponseDto[existingIds=$existingIds]'; - - Map toJson() { - final json = {}; - json[r'existingIds'] = this.existingIds; - return json; - } - - /// Returns a new [CheckExistingAssetsResponseDto] instance and imports its values from - /// [value] if it's a [Map], null otherwise. - // ignore: prefer_constructors_over_static_methods - static CheckExistingAssetsResponseDto? fromJson(dynamic value) { - upgradeDto(value, "CheckExistingAssetsResponseDto"); - if (value is Map) { - final json = value.cast(); - - return CheckExistingAssetsResponseDto( - existingIds: json[r'existingIds'] is Iterable - ? (json[r'existingIds'] as Iterable).cast().toList(growable: false) - : const [], - ); - } - return null; - } - - static List listFromJson(dynamic json, {bool growable = false,}) { - final result = []; - if (json is List && json.isNotEmpty) { - for (final row in json) { - final value = CheckExistingAssetsResponseDto.fromJson(row); - if (value != null) { - result.add(value); - } - } - } - return result.toList(growable: growable); - } - - static Map mapFromJson(dynamic json) { - final map = {}; - if (json is Map && json.isNotEmpty) { - json = json.cast(); // ignore: parameter_assignments - for (final entry in json.entries) { - final value = CheckExistingAssetsResponseDto.fromJson(entry.value); - if (value != null) { - map[entry.key] = value; - } - } - } - return map; - } - - // maps a json object with a list of CheckExistingAssetsResponseDto-objects as value to a dart map - static Map> mapListFromJson(dynamic json, {bool growable = false,}) { - final map = >{}; - if (json is Map && json.isNotEmpty) { - // ignore: parameter_assignments - json = json.cast(); - for (final entry in json.entries) { - map[entry.key] = CheckExistingAssetsResponseDto.listFromJson(entry.value, growable: growable,); - } - } - return map; - } - - /// The list of required keys that must be present in a JSON. - static const requiredKeys = { - 'existingIds', - }; -} - diff --git a/mobile/openapi/lib/model/metadata_search_dto.dart b/mobile/openapi/lib/model/metadata_search_dto.dart index 0e8d509a16..d49ea7a4e5 100644 --- a/mobile/openapi/lib/model/metadata_search_dto.dart +++ b/mobile/openapi/lib/model/metadata_search_dto.dart @@ -20,8 +20,6 @@ class MetadataSearchDto { this.createdAfter, this.createdBefore, this.description, - this.deviceAssetId, - this.deviceId, this.encodedVideoPath, this.id, this.isEncoded, @@ -104,24 +102,6 @@ class MetadataSearchDto { /// String? description; - /// Filter by device asset ID - /// - /// Please note: This property should have been non-nullable! Since the specification file - /// does not include a default value (using the "default:" property), however, the generated - /// source code must fall back to having a nullable type. - /// Consider adding a "default:" property in the specification file to hide this note. - /// - String? deviceAssetId; - - /// Device ID to filter by - /// - /// Please note: This property should have been non-nullable! Since the specification file - /// does not include a default value (using the "default:" property), however, the generated - /// source code must fall back to having a nullable type. - /// Consider adding a "default:" property in the specification file to hide this note. - /// - String? deviceId; - /// Filter by encoded video file path /// /// Please note: This property should have been non-nullable! Since the specification file @@ -403,8 +383,6 @@ class MetadataSearchDto { other.createdAfter == createdAfter && other.createdBefore == createdBefore && other.description == description && - other.deviceAssetId == deviceAssetId && - other.deviceId == deviceId && other.encodedVideoPath == encodedVideoPath && other.id == id && other.isEncoded == isEncoded && @@ -451,8 +429,6 @@ class MetadataSearchDto { (createdAfter == null ? 0 : createdAfter!.hashCode) + (createdBefore == null ? 0 : createdBefore!.hashCode) + (description == null ? 0 : description!.hashCode) + - (deviceAssetId == null ? 0 : deviceAssetId!.hashCode) + - (deviceId == null ? 0 : deviceId!.hashCode) + (encodedVideoPath == null ? 0 : encodedVideoPath!.hashCode) + (id == null ? 0 : id!.hashCode) + (isEncoded == null ? 0 : isEncoded!.hashCode) + @@ -490,7 +466,7 @@ class MetadataSearchDto { (withStacked == null ? 0 : withStacked!.hashCode); @override - String toString() => 'MetadataSearchDto[albumIds=$albumIds, checksum=$checksum, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, description=$description, deviceAssetId=$deviceAssetId, deviceId=$deviceId, encodedVideoPath=$encodedVideoPath, id=$id, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, ocr=$ocr, order=$order, originalFileName=$originalFileName, originalPath=$originalPath, page=$page, personIds=$personIds, previewPath=$previewPath, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, thumbnailPath=$thumbnailPath, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]'; + String toString() => 'MetadataSearchDto[albumIds=$albumIds, checksum=$checksum, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, description=$description, encodedVideoPath=$encodedVideoPath, id=$id, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, ocr=$ocr, order=$order, originalFileName=$originalFileName, originalPath=$originalPath, page=$page, personIds=$personIds, previewPath=$previewPath, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, thumbnailPath=$thumbnailPath, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]'; Map toJson() { final json = {}; @@ -529,16 +505,6 @@ class MetadataSearchDto { } else { // json[r'description'] = null; } - if (this.deviceAssetId != null) { - json[r'deviceAssetId'] = this.deviceAssetId; - } else { - // json[r'deviceAssetId'] = null; - } - if (this.deviceId != null) { - json[r'deviceId'] = this.deviceId; - } else { - // json[r'deviceId'] = null; - } if (this.encodedVideoPath != null) { json[r'encodedVideoPath'] = this.encodedVideoPath; } else { @@ -743,8 +709,6 @@ class MetadataSearchDto { createdAfter: mapDateTime(json, r'createdAfter', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/'), createdBefore: mapDateTime(json, r'createdBefore', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/'), description: mapValueOfType(json, r'description'), - deviceAssetId: mapValueOfType(json, r'deviceAssetId'), - deviceId: mapValueOfType(json, r'deviceId'), encodedVideoPath: mapValueOfType(json, r'encodedVideoPath'), id: mapValueOfType(json, r'id'), isEncoded: mapValueOfType(json, r'isEncoded'), diff --git a/mobile/openapi/lib/model/random_search_dto.dart b/mobile/openapi/lib/model/random_search_dto.dart index 904561a033..3f33d8f850 100644 --- a/mobile/openapi/lib/model/random_search_dto.dart +++ b/mobile/openapi/lib/model/random_search_dto.dart @@ -18,7 +18,6 @@ class RandomSearchDto { this.country, this.createdAfter, this.createdBefore, - this.deviceId, this.isEncoded, this.isFavorite, this.isMotion, @@ -75,15 +74,6 @@ class RandomSearchDto { /// DateTime? createdBefore; - /// Device ID to filter by - /// - /// Please note: This property should have been non-nullable! Since the specification file - /// does not include a default value (using the "default:" property), however, the generated - /// source code must fall back to having a nullable type. - /// Consider adding a "default:" property in the specification file to hide this note. - /// - String? deviceId; - /// Filter by encoded status /// /// Please note: This property should have been non-nullable! Since the specification file @@ -290,7 +280,6 @@ class RandomSearchDto { other.country == country && other.createdAfter == createdAfter && other.createdBefore == createdBefore && - other.deviceId == deviceId && other.isEncoded == isEncoded && other.isFavorite == isFavorite && other.isMotion == isMotion && @@ -327,7 +316,6 @@ class RandomSearchDto { (country == null ? 0 : country!.hashCode) + (createdAfter == null ? 0 : createdAfter!.hashCode) + (createdBefore == null ? 0 : createdBefore!.hashCode) + - (deviceId == null ? 0 : deviceId!.hashCode) + (isEncoded == null ? 0 : isEncoded!.hashCode) + (isFavorite == null ? 0 : isFavorite!.hashCode) + (isMotion == null ? 0 : isMotion!.hashCode) + @@ -357,7 +345,7 @@ class RandomSearchDto { (withStacked == null ? 0 : withStacked!.hashCode); @override - String toString() => 'RandomSearchDto[albumIds=$albumIds, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, ocr=$ocr, personIds=$personIds, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]'; + String toString() => 'RandomSearchDto[albumIds=$albumIds, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, ocr=$ocr, personIds=$personIds, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]'; Map toJson() { final json = {}; @@ -386,11 +374,6 @@ class RandomSearchDto { } else { // json[r'createdBefore'] = null; } - if (this.deviceId != null) { - json[r'deviceId'] = this.deviceId; - } else { - // json[r'deviceId'] = null; - } if (this.isEncoded != null) { json[r'isEncoded'] = this.isEncoded; } else { @@ -553,7 +536,6 @@ class RandomSearchDto { country: mapValueOfType(json, r'country'), createdAfter: mapDateTime(json, r'createdAfter', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/'), createdBefore: mapDateTime(json, r'createdBefore', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/'), - deviceId: mapValueOfType(json, r'deviceId'), isEncoded: mapValueOfType(json, r'isEncoded'), isFavorite: mapValueOfType(json, r'isFavorite'), isMotion: mapValueOfType(json, r'isMotion'), diff --git a/mobile/openapi/lib/model/smart_search_dto.dart b/mobile/openapi/lib/model/smart_search_dto.dart index 9c1192ff34..bf1465223e 100644 --- a/mobile/openapi/lib/model/smart_search_dto.dart +++ b/mobile/openapi/lib/model/smart_search_dto.dart @@ -18,7 +18,6 @@ class SmartSearchDto { this.country, this.createdAfter, this.createdBefore, - this.deviceId, this.isEncoded, this.isFavorite, this.isMotion, @@ -77,15 +76,6 @@ class SmartSearchDto { /// DateTime? createdBefore; - /// Device ID to filter by - /// - /// Please note: This property should have been non-nullable! Since the specification file - /// does not include a default value (using the "default:" property), however, the generated - /// source code must fall back to having a nullable type. - /// Consider adding a "default:" property in the specification file to hide this note. - /// - String? deviceId; - /// Filter by encoded status /// /// Please note: This property should have been non-nullable! Since the specification file @@ -312,7 +302,6 @@ class SmartSearchDto { other.country == country && other.createdAfter == createdAfter && other.createdBefore == createdBefore && - other.deviceId == deviceId && other.isEncoded == isEncoded && other.isFavorite == isFavorite && other.isMotion == isMotion && @@ -351,7 +340,6 @@ class SmartSearchDto { (country == null ? 0 : country!.hashCode) + (createdAfter == null ? 0 : createdAfter!.hashCode) + (createdBefore == null ? 0 : createdBefore!.hashCode) + - (deviceId == null ? 0 : deviceId!.hashCode) + (isEncoded == null ? 0 : isEncoded!.hashCode) + (isFavorite == null ? 0 : isFavorite!.hashCode) + (isMotion == null ? 0 : isMotion!.hashCode) + @@ -383,7 +371,7 @@ class SmartSearchDto { (withExif == null ? 0 : withExif!.hashCode); @override - String toString() => 'SmartSearchDto[albumIds=$albumIds, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, language=$language, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, ocr=$ocr, page=$page, personIds=$personIds, query=$query, queryAssetId=$queryAssetId, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif]'; + String toString() => 'SmartSearchDto[albumIds=$albumIds, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, language=$language, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, ocr=$ocr, page=$page, personIds=$personIds, query=$query, queryAssetId=$queryAssetId, rating=$rating, size=$size, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility, withDeleted=$withDeleted, withExif=$withExif]'; Map toJson() { final json = {}; @@ -412,11 +400,6 @@ class SmartSearchDto { } else { // json[r'createdBefore'] = null; } - if (this.deviceId != null) { - json[r'deviceId'] = this.deviceId; - } else { - // json[r'deviceId'] = null; - } if (this.isEncoded != null) { json[r'isEncoded'] = this.isEncoded; } else { @@ -589,7 +572,6 @@ class SmartSearchDto { country: mapValueOfType(json, r'country'), createdAfter: mapDateTime(json, r'createdAfter', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/'), createdBefore: mapDateTime(json, r'createdBefore', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/'), - deviceId: mapValueOfType(json, r'deviceId'), isEncoded: mapValueOfType(json, r'isEncoded'), isFavorite: mapValueOfType(json, r'isFavorite'), isMotion: mapValueOfType(json, r'isMotion'), diff --git a/mobile/openapi/lib/model/statistics_search_dto.dart b/mobile/openapi/lib/model/statistics_search_dto.dart index 729b7f127c..d0070e8e12 100644 --- a/mobile/openapi/lib/model/statistics_search_dto.dart +++ b/mobile/openapi/lib/model/statistics_search_dto.dart @@ -19,7 +19,6 @@ class StatisticsSearchDto { this.createdAfter, this.createdBefore, this.description, - this.deviceId, this.isEncoded, this.isFavorite, this.isMotion, @@ -80,15 +79,6 @@ class StatisticsSearchDto { /// String? description; - /// Device ID to filter by - /// - /// Please note: This property should have been non-nullable! Since the specification file - /// does not include a default value (using the "default:" property), however, the generated - /// source code must fall back to having a nullable type. - /// Consider adding a "default:" property in the specification file to hide this note. - /// - String? deviceId; - /// Filter by encoded status /// /// Please note: This property should have been non-nullable! Since the specification file @@ -248,7 +238,6 @@ class StatisticsSearchDto { other.createdAfter == createdAfter && other.createdBefore == createdBefore && other.description == description && - other.deviceId == deviceId && other.isEncoded == isEncoded && other.isFavorite == isFavorite && other.isMotion == isMotion && @@ -281,7 +270,6 @@ class StatisticsSearchDto { (createdAfter == null ? 0 : createdAfter!.hashCode) + (createdBefore == null ? 0 : createdBefore!.hashCode) + (description == null ? 0 : description!.hashCode) + - (deviceId == null ? 0 : deviceId!.hashCode) + (isEncoded == null ? 0 : isEncoded!.hashCode) + (isFavorite == null ? 0 : isFavorite!.hashCode) + (isMotion == null ? 0 : isMotion!.hashCode) + @@ -306,7 +294,7 @@ class StatisticsSearchDto { (visibility == null ? 0 : visibility!.hashCode); @override - String toString() => 'StatisticsSearchDto[albumIds=$albumIds, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, description=$description, deviceId=$deviceId, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, ocr=$ocr, personIds=$personIds, rating=$rating, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility]'; + String toString() => 'StatisticsSearchDto[albumIds=$albumIds, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, description=$description, isEncoded=$isEncoded, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, ocr=$ocr, personIds=$personIds, rating=$rating, state=$state, tagIds=$tagIds, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, visibility=$visibility]'; Map toJson() { final json = {}; @@ -340,11 +328,6 @@ class StatisticsSearchDto { } else { // json[r'description'] = null; } - if (this.deviceId != null) { - json[r'deviceId'] = this.deviceId; - } else { - // json[r'deviceId'] = null; - } if (this.isEncoded != null) { json[r'isEncoded'] = this.isEncoded; } else { @@ -483,7 +466,6 @@ class StatisticsSearchDto { createdAfter: mapDateTime(json, r'createdAfter', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/'), createdBefore: mapDateTime(json, r'createdBefore', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/'), description: mapValueOfType(json, r'description'), - deviceId: mapValueOfType(json, r'deviceId'), isEncoded: mapValueOfType(json, r'isEncoded'), isFavorite: mapValueOfType(json, r'isFavorite'), isMotion: mapValueOfType(json, r'isMotion'), diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 1b2e6af587..fd6f9c5151 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -3084,126 +3084,6 @@ "x-immich-state": "Stable" } }, - "/assets/device/{deviceId}": { - "get": { - "deprecated": true, - "description": "Get all asset of a device that are in the database, ID only.", - "operationId": "getAllUserAssetsByDeviceId", - "parameters": [ - { - "name": "deviceId", - "required": true, - "in": "path", - "description": "Device ID", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "items": { - "type": "string" - }, - "type": "array" - } - } - }, - "description": "" - } - }, - "security": [ - { - "bearer": [] - }, - { - "cookie": [] - }, - { - "api_key": [] - } - ], - "summary": "Retrieve assets by device ID", - "tags": [ - "Assets", - "Deprecated" - ], - "x-immich-history": [ - { - "version": "v1", - "state": "Added" - }, - { - "version": "v2", - "state": "Deprecated" - } - ], - "x-immich-state": "Deprecated" - } - }, - "/assets/exist": { - "post": { - "description": "Checks if multiple assets exist on the server and returns all existing - used by background backup", - "operationId": "checkExistingAssets", - "parameters": [], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CheckExistingAssetsDto" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CheckExistingAssetsResponseDto" - } - } - }, - "description": "" - } - }, - "security": [ - { - "bearer": [] - }, - { - "cookie": [] - }, - { - "api_key": [] - } - ], - "summary": "Check existing assets", - "tags": [ - "Assets" - ], - "x-immich-history": [ - { - "version": "v1", - "state": "Added" - }, - { - "version": "v1", - "state": "Beta" - }, - { - "version": "v2", - "state": "Stable" - } - ], - "x-immich-permission": "asset.upload", - "x-immich-state": "Stable" - } - }, "/assets/jobs": { "post": { "description": "Run a specific job on a set of assets.", @@ -9255,15 +9135,6 @@ "type": "string" } }, - { - "name": "deviceId", - "required": false, - "in": "query", - "description": "Device ID to filter by", - "schema": { - "type": "string" - } - }, { "name": "isEncoded", "required": false, @@ -16343,14 +16214,6 @@ "format": "binary", "type": "string" }, - "deviceAssetId": { - "description": "Device asset ID", - "type": "string" - }, - "deviceId": { - "description": "Device ID", - "type": "string" - }, "duration": { "description": "Duration (for videos)", "type": "string" @@ -16401,8 +16264,6 @@ }, "required": [ "assetData", - "deviceAssetId", - "deviceId", "fileCreatedAt", "fileModifiedAt" ], @@ -16718,14 +16579,6 @@ "format": "date-time", "type": "string" }, - "deviceAssetId": { - "description": "Device asset ID", - "type": "string" - }, - "deviceId": { - "description": "Device ID", - "type": "string" - }, "duplicateId": { "description": "Duplicate group ID", "nullable": true, @@ -16907,8 +16760,6 @@ "required": [ "checksum", "createdAt", - "deviceAssetId", - "deviceId", "duration", "fileCreatedAt", "fileModifiedAt", @@ -17184,42 +17035,6 @@ ], "type": "object" }, - "CheckExistingAssetsDto": { - "properties": { - "deviceAssetIds": { - "description": "Device asset IDs to check", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - }, - "deviceId": { - "description": "Device ID", - "type": "string" - } - }, - "required": [ - "deviceAssetIds", - "deviceId" - ], - "type": "object" - }, - "CheckExistingAssetsResponseDto": { - "properties": { - "existingIds": { - "description": "Existing asset IDs", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "existingIds" - ], - "type": "object" - }, "Colorspace": { "description": "Colorspace", "enum": [ @@ -18794,14 +18609,6 @@ "description": "Filter by description text", "type": "string" }, - "deviceAssetId": { - "description": "Filter by device asset ID", - "type": "string" - }, - "deviceId": { - "description": "Device ID to filter by", - "type": "string" - }, "encodedVideoPath": { "description": "Filter by encoded video file path", "type": "string" @@ -20675,10 +20482,6 @@ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", "type": "string" }, - "deviceId": { - "description": "Device ID to filter by", - "type": "string" - }, "isEncoded": { "description": "Filter by encoded status", "type": "boolean" @@ -22054,10 +21857,6 @@ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$", "type": "string" }, - "deviceId": { - "description": "Device ID to filter by", - "type": "string" - }, "isEncoded": { "description": "Filter by encoded status", "type": "boolean" @@ -22337,10 +22136,6 @@ "description": "Filter by description text", "type": "string" }, - "deviceId": { - "description": "Device ID to filter by", - "type": "string" - }, "isEncoded": { "description": "Filter by encoded status", "type": "boolean" diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index a452d86b8c..fd7b800f93 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -557,10 +557,6 @@ export type AssetResponseDto = { checksum: string; /** The UTC timestamp when the asset was originally uploaded to Immich. */ createdAt: string; - /** Device asset ID */ - deviceAssetId: string; - /** Device ID */ - deviceId: string; /** Duplicate group ID */ duplicateId?: string | null; /** Video duration (for videos) */ @@ -773,10 +769,6 @@ export type AssetMetadataUpsertItemDto = { export type AssetMediaCreateDto = { /** Asset file data */ assetData: Blob; - /** Device asset ID */ - deviceAssetId: string; - /** Device ID */ - deviceId: string; /** Duration (for videos) */ duration?: string; /** File creation date */ @@ -863,16 +855,6 @@ export type AssetCopyDto = { /** Target asset ID */ targetId: string; }; -export type CheckExistingAssetsDto = { - /** Device asset IDs to check */ - deviceAssetIds: string[]; - /** Device ID */ - deviceId: string; -}; -export type CheckExistingAssetsResponseDto = { - /** Existing asset IDs */ - existingIds: string[]; -}; export type AssetJobsDto = { /** Asset IDs */ assetIds: string[]; @@ -1661,10 +1643,6 @@ export type MetadataSearchDto = { createdBefore?: string; /** Filter by description text */ description?: string; - /** Filter by device asset ID */ - deviceAssetId?: string; - /** Device ID to filter by */ - deviceId?: string; /** Filter by encoded video file path */ encodedVideoPath?: string; /** Filter by asset ID */ @@ -1790,8 +1768,6 @@ export type RandomSearchDto = { createdAfter?: string; /** Filter by creation date (before) */ createdBefore?: string; - /** Device ID to filter by */ - deviceId?: string; /** Filter by encoded status */ isEncoded?: boolean; /** Filter by favorite status */ @@ -1856,8 +1832,6 @@ export type SmartSearchDto = { createdAfter?: string; /** Filter by creation date (before) */ createdBefore?: string; - /** Device ID to filter by */ - deviceId?: string; /** Filter by encoded status */ isEncoded?: boolean; /** Filter by favorite status */ @@ -1928,8 +1902,6 @@ export type StatisticsSearchDto = { createdBefore?: string; /** Filter by description text */ description?: string; - /** Device ID to filter by */ - deviceId?: string; /** Filter by encoded status */ isEncoded?: boolean; /** Filter by favorite status */ @@ -3958,34 +3930,6 @@ export function copyAsset({ assetCopyDto }: { body: assetCopyDto }))); } -/** - * Retrieve assets by device ID - */ -export function getAllUserAssetsByDeviceId({ deviceId }: { - deviceId: string; -}, opts?: Oazapfts.RequestOpts) { - return oazapfts.ok(oazapfts.fetchJson<{ - status: 200; - data: string[]; - }>(`/assets/device/${encodeURIComponent(deviceId)}`, { - ...opts - })); -} -/** - * Check existing assets - */ -export function checkExistingAssets({ checkExistingAssetsDto }: { - checkExistingAssetsDto: CheckExistingAssetsDto; -}, opts?: Oazapfts.RequestOpts) { - return oazapfts.ok(oazapfts.fetchJson<{ - status: 200; - data: CheckExistingAssetsResponseDto; - }>("/assets/exist", oazapfts.json({ - ...opts, - method: "POST", - body: checkExistingAssetsDto - }))); -} /** * Run an asset job */ @@ -5365,13 +5309,12 @@ export function getExploreData(opts?: Oazapfts.RequestOpts) { /** * Search large assets */ -export function searchLargeAssets({ albumIds, city, country, createdAfter, createdBefore, deviceId, isEncoded, isFavorite, isMotion, isNotInAlbum, isOffline, lensModel, libraryId, make, minFileSize, model, ocr, personIds, rating, size, state, tagIds, takenAfter, takenBefore, trashedAfter, trashedBefore, $type, updatedAfter, updatedBefore, visibility, withDeleted, withExif }: { +export function searchLargeAssets({ albumIds, city, country, createdAfter, createdBefore, isEncoded, isFavorite, isMotion, isNotInAlbum, isOffline, lensModel, libraryId, make, minFileSize, model, ocr, personIds, rating, size, state, tagIds, takenAfter, takenBefore, trashedAfter, trashedBefore, $type, updatedAfter, updatedBefore, visibility, withDeleted, withExif }: { albumIds?: string[]; city?: string | null; country?: string | null; createdAfter?: string; createdBefore?: string; - deviceId?: string; isEncoded?: boolean; isFavorite?: boolean; isMotion?: boolean; @@ -5408,7 +5351,6 @@ export function searchLargeAssets({ albumIds, city, country, createdAfter, creat country, createdAfter, createdBefore, - deviceId, isEncoded, isFavorite, isMotion, diff --git a/server/src/controllers/asset-media.controller.spec.ts b/server/src/controllers/asset-media.controller.spec.ts index 71206c3855..7ccd0d644d 100644 --- a/server/src/controllers/asset-media.controller.spec.ts +++ b/server/src/controllers/asset-media.controller.spec.ts @@ -9,8 +9,6 @@ import { automock, ControllerContext, controllerSetup, mockBaseService } from 't const makeUploadDto = (options?: { omit: string }): Record => { const dto: Record = { - deviceAssetId: 'example-image', - deviceId: 'TEST', fileCreatedAt: new Date().toISOString(), fileModifiedAt: new Date().toISOString(), isFavorite: 'false', @@ -87,28 +85,6 @@ describe(AssetMediaController.name, () => { ); }); - it('should require `deviceAssetId`', async () => { - const { status, body } = await request(ctx.getHttpServer()) - .post('/assets') - .attach('assetData', assetData, filename) - .field({ ...makeUploadDto({ omit: 'deviceAssetId' }) }); - expect(status).toBe(400); - expect(body).toEqual( - factory.responses.badRequest(['[deviceAssetId] Invalid input: expected string, received undefined']), - ); - }); - - it('should require `deviceId`', async () => { - const { status, body } = await request(ctx.getHttpServer()) - .post('/assets') - .attach('assetData', assetData, filename) - .field({ ...makeUploadDto({ omit: 'deviceId' }) }); - expect(status).toBe(400); - expect(body).toEqual( - factory.responses.badRequest(['[deviceId] Invalid input: expected string, received undefined']), - ); - }); - it('should require `fileCreatedAt`', async () => { const { status, body } = await request(ctx.getHttpServer()) .post('/assets') diff --git a/server/src/controllers/asset-media.controller.ts b/server/src/controllers/asset-media.controller.ts index dbb906fd02..240e5b8b3c 100644 --- a/server/src/controllers/asset-media.controller.ts +++ b/server/src/controllers/asset-media.controller.ts @@ -21,14 +21,12 @@ import { AssetBulkUploadCheckResponseDto, AssetMediaResponseDto, AssetMediaStatus, - CheckExistingAssetsResponseDto, } from 'src/dtos/asset-media-response.dto'; import { AssetBulkUploadCheckDto, AssetMediaCreateDto, AssetMediaOptionsDto, AssetMediaSize, - CheckExistingAssetsDto, } from 'src/dtos/asset-media.dto'; import { AssetDownloadOriginalDto } from 'src/dtos/asset.dto'; import { AuthDto } from 'src/dtos/auth.dto'; @@ -179,21 +177,6 @@ export class AssetMediaController { await sendFile(res, next, () => this.service.playbackVideo(auth, id), this.logger); } - @Post('exist') - @Authenticated({ permission: Permission.AssetUpload }) - @Endpoint({ - summary: 'Check existing assets', - description: 'Checks if multiple assets exist on the server and returns all existing - used by background backup', - history: new HistoryBuilder().added('v1').beta('v1').stable('v2'), - }) - @HttpCode(HttpStatus.OK) - checkExistingAssets( - @Auth() auth: AuthDto, - @Body() dto: CheckExistingAssetsDto, - ): Promise { - return this.service.checkExistingAssets(auth, dto); - } - @Post('bulk-upload-check') @Authenticated({ permission: Permission.AssetUpload }) @Endpoint({ diff --git a/server/src/controllers/asset.controller.ts b/server/src/controllers/asset.controller.ts index d36a9dd7fd..1c9afebc1b 100644 --- a/server/src/controllers/asset.controller.ts +++ b/server/src/controllers/asset.controller.ts @@ -15,7 +15,6 @@ import { AssetMetadataUpsertDto, AssetStatsDto, AssetStatsResponseDto, - DeviceIdDto, UpdateAssetDto, } from 'src/dtos/asset.dto'; import { AuthDto } from 'src/dtos/auth.dto'; @@ -31,17 +30,6 @@ import { UUIDParamDto } from 'src/validation'; export class AssetController { constructor(private service: AssetService) {} - @Get('/device/:deviceId') - @Endpoint({ - summary: 'Retrieve assets by device ID', - description: 'Get all asset of a device that are in the database, ID only.', - history: new HistoryBuilder().added('v1').deprecated('v2'), - }) - @Authenticated() - getAllUserAssetsByDeviceId(@Auth() auth: AuthDto, @Param() { deviceId }: DeviceIdDto) { - return this.service.getUserAssetsByDeviceId(auth, deviceId); - } - @Get('statistics') @Authenticated({ permission: Permission.AssetStatistics }) @Endpoint({ diff --git a/server/src/database.ts b/server/src/database.ts index f8065ffd2c..7235af46fa 100644 --- a/server/src/database.ts +++ b/server/src/database.ts @@ -114,8 +114,6 @@ export type Asset = { id: string; checksum: Buffer; checksumAlgorithm: ChecksumAlgorithm; - deviceAssetId: string; - deviceId: string; fileCreatedAt: Date; fileModifiedAt: Date; isExternal: boolean; @@ -333,8 +331,6 @@ export const columns = { 'asset.id', 'asset.checksum', 'asset.checksumAlgorithm', - 'asset.deviceAssetId', - 'asset.deviceId', 'asset.fileCreatedAt', 'asset.fileModifiedAt', 'asset.isExternal', diff --git a/server/src/dtos/asset-media-response.dto.ts b/server/src/dtos/asset-media-response.dto.ts index fa3c472765..ab79b8428c 100644 --- a/server/src/dtos/asset-media-response.dto.ts +++ b/server/src/dtos/asset-media-response.dto.ts @@ -49,12 +49,5 @@ const AssetBulkUploadCheckResponseSchema = z }) .meta({ id: 'AssetBulkUploadCheckResponseDto' }); -const CheckExistingAssetsResponseSchema = z - .object({ - existingIds: z.array(z.string()).describe('Existing asset IDs'), - }) - .meta({ id: 'CheckExistingAssetsResponseDto' }); - export class AssetMediaResponseDto extends createZodDto(AssetMediaResponseSchema) {} export class AssetBulkUploadCheckResponseDto extends createZodDto(AssetBulkUploadCheckResponseSchema) {} -export class CheckExistingAssetsResponseDto extends createZodDto(CheckExistingAssetsResponseSchema) {} diff --git a/server/src/dtos/asset-media.dto.ts b/server/src/dtos/asset-media.dto.ts index 7178d4184e..cd9c7de641 100644 --- a/server/src/dtos/asset-media.dto.ts +++ b/server/src/dtos/asset-media.dto.ts @@ -36,8 +36,6 @@ export enum UploadFieldName { } const AssetMediaBaseSchema = z.object({ - deviceAssetId: z.string().describe('Device asset ID'), - deviceId: z.string().describe('Device ID'), fileCreatedAt: isoDatetimeToDate.describe('File creation date'), fileModifiedAt: isoDatetimeToDate.describe('File modification date'), duration: z.string().optional().describe('Duration (for videos)'), @@ -71,14 +69,6 @@ const AssetBulkUploadCheckSchema = z }) .meta({ id: 'AssetBulkUploadCheckDto' }); -const CheckExistingAssetsSchema = z - .object({ - deviceAssetIds: z.array(z.string()).min(1).describe('Device asset IDs to check'), - deviceId: z.string().describe('Device ID'), - }) - .meta({ id: 'CheckExistingAssetsDto' }); - export class AssetMediaOptionsDto extends createZodDto(AssetMediaOptionsSchema) {} export class AssetMediaCreateDto extends createZodDto(AssetMediaCreateSchema) {} export class AssetBulkUploadCheckDto extends createZodDto(AssetBulkUploadCheckSchema) {} -export class CheckExistingAssetsDto extends createZodDto(CheckExistingAssetsSchema) {} diff --git a/server/src/dtos/asset-response.dto.ts b/server/src/dtos/asset-response.dto.ts index a95d2f3c1e..b4a398b573 100644 --- a/server/src/dtos/asset-response.dto.ts +++ b/server/src/dtos/asset-response.dto.ts @@ -72,8 +72,6 @@ export const AssetResponseSchema = SanitizedAssetResponseSchema.extend( .string() .meta({ format: 'date-time' }) .describe('The UTC timestamp when the asset was originally uploaded to Immich.'), - deviceAssetId: z.string().describe('Device asset ID'), - deviceId: z.string().describe('Device ID'), ownerId: z.string().describe('Owner user ID'), owner: UserResponseSchema.optional(), libraryId: z @@ -137,8 +135,6 @@ export type MapAsset = { status: AssetStatus; checksum: Buffer; checksumAlgorithm: ChecksumAlgorithm; - deviceAssetId: string; - deviceId: string; duplicateId: string | null; duration: string | null; edits?: ShallowDehydrateObject[]; @@ -239,10 +235,8 @@ export function mapAsset(entity: MaybeDehydrated, options: AssetMapOpt return { id: entity.id, createdAt: asDateString(entity.createdAt), - deviceAssetId: entity.deviceAssetId, ownerId: entity.ownerId, owner: entity.owner ? mapUser(entity.owner) : undefined, - deviceId: entity.deviceId, libraryId: entity.libraryId, type: entity.type, originalPath: entity.originalPath, diff --git a/server/src/dtos/asset.dto.ts b/server/src/dtos/asset.dto.ts index c05462c554..1362a86ed7 100644 --- a/server/src/dtos/asset.dto.ts +++ b/server/src/dtos/asset.dto.ts @@ -6,12 +6,6 @@ import { AssetStats } from 'src/repositories/asset.repository'; import { IsNotSiblingOf, isoDatetimeToDate, latitudeSchema, longitudeSchema, stringToBool } from 'src/validation'; import z from 'zod'; -const DeviceIdSchema = z - .object({ - deviceId: z.string().describe('Device ID'), - }) - .meta({ id: 'DeviceIdDto' }); - const UpdateAssetBaseSchema = z .object({ isFavorite: z.boolean().optional().describe('Mark as favorite'), @@ -182,7 +176,6 @@ export const mapStats = (stats: AssetStats): AssetStatsResponseDto => { }; }; -export class DeviceIdDto extends createZodDto(DeviceIdSchema) {} export class AssetBulkUpdateDto extends createZodDto(AssetBulkUpdateSchema) {} export class UpdateAssetDto extends createZodDto(UpdateAssetSchema) {} export class AssetBulkDeleteDto extends createZodDto(AssetBulkDeleteSchema) {} diff --git a/server/src/dtos/search.dto.ts b/server/src/dtos/search.dto.ts index 43da0b8709..c0362cdb5d 100644 --- a/server/src/dtos/search.dto.ts +++ b/server/src/dtos/search.dto.ts @@ -9,7 +9,6 @@ import z from 'zod'; const BaseSearchSchema = z.object({ libraryId: z.uuidv4().nullish().describe('Library ID to filter by'), - deviceId: z.string().optional().describe('Device ID to filter by'), type: AssetTypeSchema.optional(), isEncoded: z.boolean().optional().describe('Filter by encoded status'), isFavorite: z.boolean().optional().describe('Filter by favorite status'), @@ -68,7 +67,6 @@ const LargeAssetSearchSchema = BaseSearchWithResultsSchema.extend({ const MetadataSearchSchema = RandomSearchSchema.extend({ id: z.uuidv4().optional().describe('Filter by asset ID'), - deviceAssetId: z.string().optional().describe('Filter by device asset ID'), description: z.string().trim().optional().describe('Filter by description text'), checksum: z.string().optional().describe('Filter by file checksum'), originalFileName: z.string().trim().optional().describe('Filter by original file name'), diff --git a/server/src/queries/asset.job.repository.sql b/server/src/queries/asset.job.repository.sql index 333d4ace81..bd903f3952 100644 --- a/server/src/queries/asset.job.repository.sql +++ b/server/src/queries/asset.job.repository.sql @@ -250,8 +250,6 @@ select "asset"."id", "asset"."checksum", "asset"."checksumAlgorithm", - "asset"."deviceAssetId", - "asset"."deviceId", "asset"."fileCreatedAt", "asset"."fileModifiedAt", "asset"."isExternal", diff --git a/server/src/queries/asset.repository.sql b/server/src/queries/asset.repository.sql index 88cd9c08d5..ebc2de90e1 100644 --- a/server/src/queries/asset.repository.sql +++ b/server/src/queries/asset.repository.sql @@ -242,17 +242,6 @@ where limit $3 --- AssetRepository.getAllByDeviceId -select - "deviceAssetId" -from - "asset" -where - "ownerId" = $1::uuid - and "deviceId" = $2 - and "visibility" != $3 - and "deletedAt" is null - -- AssetRepository.getLivePhotoCount select count(*) as "count" @@ -312,9 +301,8 @@ limit -- AssetRepository.updateAll update "asset" set - "deviceId" = $1 where - "id" = any ($2::uuid[]) + "id" = any ($1::uuid[]) -- AssetRepository.getByChecksum select diff --git a/server/src/repositories/asset.repository.ts b/server/src/repositories/asset.repository.ts index 686a0345a4..784cf68b5b 100644 --- a/server/src/repositories/asset.repository.ts +++ b/server/src/repositories/asset.repository.ts @@ -448,18 +448,6 @@ export class AssetRepository { await this.db.deleteFrom('asset').where('ownerId', '=', ownerId).execute(); } - async getByDeviceIds(ownerId: string, deviceId: string, deviceAssetIds: string[]): Promise { - const assets = await this.db - .selectFrom('asset') - .select(['deviceAssetId']) - .where('deviceAssetId', 'in', deviceAssetIds) - .where('deviceId', '=', deviceId) - .where('ownerId', '=', asUuid(ownerId)) - .execute(); - - return assets.map((asset) => asset.deviceAssetId); - } - @GenerateSql({ params: [DummyValue.UUID, DummyValue.STRING] }) getByLibraryIdAndOriginalPath(libraryId: string, originalPath: string) { return this.db @@ -471,27 +459,6 @@ export class AssetRepository { .executeTakeFirst(); } - /** - * Get assets by device's Id on the database - * @param ownerId - * @param deviceId - * - * @returns Promise - Array of assetIds belong to the device - */ - @GenerateSql({ params: [DummyValue.UUID, DummyValue.STRING] }) - async getAllByDeviceId(ownerId: string, deviceId: string): Promise { - const items = await this.db - .selectFrom('asset') - .select(['deviceAssetId']) - .where('ownerId', '=', asUuid(ownerId)) - .where('deviceId', '=', deviceId) - .where('visibility', '!=', AssetVisibility.Hidden) - .where('deletedAt', 'is', null) - .execute(); - - return items.map((asset) => asset.deviceAssetId); - } - @GenerateSql({ params: [DummyValue.UUID] }) async getLivePhotoCount(motionId: string): Promise { const [{ count }] = await this.db @@ -568,7 +535,7 @@ export class AssetRepository { .executeTakeFirst(); } - @GenerateSql({ params: [[DummyValue.UUID], { deviceId: DummyValue.STRING }] }) + @GenerateSql({ params: [[DummyValue.UUID], {}] }) @Chunked() async updateAll(ids: string[], options: Updateable): Promise { if (ids.length === 0) { diff --git a/server/src/repositories/search.repository.ts b/server/src/repositories/search.repository.ts index 8f8a5be0bd..171102a660 100644 --- a/server/src/repositories/search.repository.ts +++ b/server/src/repositories/search.repository.ts @@ -14,12 +14,10 @@ import { isValidInteger } from 'src/validation'; export interface SearchAssetIdOptions { checksum?: Buffer; - deviceAssetId?: string; id?: string; } export interface SearchUserIdOptions { - deviceId?: string; libraryId?: string | null; userIds?: string[]; } diff --git a/server/src/schema/migrations/1776263790468-DropDeviceIdAndDeviceAssetId.ts b/server/src/schema/migrations/1776263790468-DropDeviceIdAndDeviceAssetId.ts new file mode 100644 index 0000000000..97ed6eceda --- /dev/null +++ b/server/src/schema/migrations/1776263790468-DropDeviceIdAndDeviceAssetId.ts @@ -0,0 +1,11 @@ +import { Kysely, sql } from 'kysely'; + +export async function up(db: Kysely): Promise { + await sql`ALTER TABLE "asset" DROP COLUMN "deviceAssetId";`.execute(db); + await sql`ALTER TABLE "asset" DROP COLUMN "deviceId";`.execute(db); +} + +export async function down(db: Kysely): Promise { + await sql`ALTER TABLE "asset" ADD "deviceAssetId" character varying NOT NULL;`.execute(db); + await sql`ALTER TABLE "asset" ADD "deviceId" character varying NOT NULL;`.execute(db); +} diff --git a/server/src/schema/tables/asset.table.ts b/server/src/schema/tables/asset.table.ts index 7418dab102..e19a52af9c 100644 --- a/server/src/schema/tables/asset.table.ts +++ b/server/src/schema/tables/asset.table.ts @@ -65,15 +65,9 @@ export class AssetTable { @PrimaryGeneratedColumn() id!: Generated; - @Column() - deviceAssetId!: string; - @ForeignKeyColumn(() => UserTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false }) ownerId!: string; - @Column() - deviceId!: string; - @Column() type!: AssetType; diff --git a/server/src/services/asset-media.service.spec.ts b/server/src/services/asset-media.service.spec.ts index 3dba0c6d34..ce8ecac72c 100644 --- a/server/src/services/asset-media.service.spec.ts +++ b/server/src/services/asset-media.service.spec.ts @@ -145,8 +145,6 @@ const uploadTests = [ ]; const createDto = Object.freeze({ - deviceAssetId: 'deviceAssetId', - deviceId: 'deviceId', fileCreatedAt: new Date('2022-06-19T23:41:36.910Z'), fileModifiedAt: new Date('2022-06-19T23:41:36.910Z'), isFavorite: false, @@ -156,8 +154,6 @@ const createDto = Object.freeze({ const assetEntity = Object.freeze({ id: 'id_1', ownerId: 'user_id_1', - deviceAssetId: 'device_asset_id_1', - deviceId: 'device_id_1', type: AssetType.Video, originalPath: 'fake_path/asset_1.jpeg', fileModifiedAt: new Date('2022-06-19T23:41:36.910Z'), @@ -765,17 +761,6 @@ describe(AssetMediaService.name, () => { }); }); - describe('checkExistingAssets', () => { - it('should get existing asset ids', async () => { - mocks.asset.getByDeviceIds.mockResolvedValue(['42']); - await expect( - sut.checkExistingAssets(authStub.admin, { deviceId: '420', deviceAssetIds: ['69'] }), - ).resolves.toEqual({ existingIds: ['42'] }); - - expect(mocks.asset.getByDeviceIds).toHaveBeenCalledWith(userStub.admin.id, '420', ['69']); - }); - }); - describe('bulkUploadCheck', () => { it('should accept hex and base64 checksums', async () => { const file1 = Buffer.from('d2947b871a706081be194569951b7db246907957', 'hex'); diff --git a/server/src/services/asset-media.service.ts b/server/src/services/asset-media.service.ts index 74e7d08012..74aaa8fcbd 100644 --- a/server/src/services/asset-media.service.ts +++ b/server/src/services/asset-media.service.ts @@ -9,14 +9,12 @@ import { AssetMediaStatus, AssetRejectReason, AssetUploadAction, - CheckExistingAssetsResponseDto, } from 'src/dtos/asset-media-response.dto'; import { AssetBulkUploadCheckDto, AssetMediaCreateDto, AssetMediaOptionsDto, AssetMediaSize, - CheckExistingAssetsDto, UploadFieldName, } from 'src/dtos/asset-media.dto'; import { AssetDownloadOriginalDto } from 'src/dtos/asset.dto'; @@ -251,18 +249,6 @@ export class AssetMediaService extends BaseService { }); } - async checkExistingAssets( - auth: AuthDto, - checkExistingAssetsDto: CheckExistingAssetsDto, - ): Promise { - const existingIds = await this.assetRepository.getByDeviceIds( - auth.user.id, - checkExistingAssetsDto.deviceId, - checkExistingAssetsDto.deviceAssetIds, - ); - return { existingIds }; - } - async bulkUploadCheck(auth: AuthDto, dto: AssetBulkUploadCheckDto): Promise { const checksums: Buffer[] = dto.assets.map((asset) => fromChecksum(asset.checksum)); const results = await this.assetRepository.getByChecksums(auth.user.id, checksums); @@ -340,9 +326,6 @@ export class AssetMediaService extends BaseService { checksumAlgorithm: ChecksumAlgorithm.sha1File, originalPath: file.originalPath, - deviceAssetId: dto.deviceAssetId, - deviceId: dto.deviceId, - fileCreatedAt: dto.fileCreatedAt, fileModifiedAt: dto.fileModifiedAt, localDateTime: dto.fileCreatedAt, diff --git a/server/src/services/asset.service.spec.ts b/server/src/services/asset.service.spec.ts index bef6f332d3..13462a3246 100755 --- a/server/src/services/asset.service.spec.ts +++ b/server/src/services/asset.service.spec.ts @@ -685,20 +685,6 @@ describe(AssetService.name, () => { }); }); - describe('getUserAssetsByDeviceId', () => { - it('get assets by device id', async () => { - const assets = [AssetFactory.create(), AssetFactory.create()]; - - mocks.asset.getAllByDeviceId.mockResolvedValue(assets.map((asset) => asset.deviceAssetId)); - - const deviceId = 'device-id'; - const result = await sut.getUserAssetsByDeviceId(authStub.user1, deviceId); - - expect(result.length).toEqual(2); - expect(result).toEqual(assets.map((asset) => asset.deviceAssetId)); - }); - }); - describe('upsertMetadata', () => { it('should throw a bad request exception if duplicate keys are sent', async () => { const asset = AssetFactory.create(); diff --git a/server/src/services/asset.service.ts b/server/src/services/asset.service.ts index dde358234b..613029fe3c 100644 --- a/server/src/services/asset.service.ts +++ b/server/src/services/asset.service.ts @@ -59,10 +59,6 @@ export class AssetService extends BaseService { return mapStats(stats); } - async getUserAssetsByDeviceId(auth: AuthDto, deviceId: string) { - return this.assetRepository.getAllByDeviceId(auth.user.id, deviceId); - } - async get(auth: AuthDto, id: string): Promise { await this.requireAccess({ auth, permission: Permission.AssetRead, ids: [id] }); diff --git a/server/src/services/library.service.spec.ts b/server/src/services/library.service.spec.ts index 9a2ec00815..5b43ed9f61 100644 --- a/server/src/services/library.service.spec.ts +++ b/server/src/services/library.service.spec.ts @@ -570,7 +570,6 @@ describe(LibraryService.name, () => { ownerId: library.ownerId, libraryId: library.id, originalPath: '/data/user1/photo.jpg', - deviceId: 'Library Import', type: AssetType.Image, originalFileName: 'photo.jpg', isExternal: true, diff --git a/server/src/services/library.service.ts b/server/src/services/library.service.ts index 81e8c99d49..085650be6f 100644 --- a/server/src/services/library.service.ts +++ b/server/src/services/library.service.ts @@ -2,7 +2,7 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { Insertable } from 'kysely'; import { R_OK } from 'node:constants'; import { Stats } from 'node:fs'; -import path, { basename, isAbsolute, parse } from 'node:path'; +import path, { isAbsolute, parse } from 'node:path'; import picomatch from 'picomatch'; import { JOBS_LIBRARY_PAGINATION_SIZE } from 'src/constants'; import { StorageCore } from 'src/cores/storage.core'; @@ -411,9 +411,6 @@ export class LibraryService extends BaseService { fileCreatedAt: stat.mtime, fileModifiedAt: stat.mtime, localDateTime: stat.mtime, - // TODO: device asset id is deprecated, remove it - deviceAssetId: `${basename(assetPath)}`.replaceAll(/\s+/g, ''), - deviceId: 'Library Import', type: mimeTypes.isVideo(assetPath) ? AssetType.Video : AssetType.Image, originalFileName: parse(assetPath).base, isExternal: true, diff --git a/server/src/services/metadata.service.spec.ts b/server/src/services/metadata.service.spec.ts index f9d17079e3..245bb441a6 100644 --- a/server/src/services/metadata.service.spec.ts +++ b/server/src/services/metadata.service.spec.ts @@ -654,8 +654,6 @@ describe(MetadataService.name, () => { expect(mocks.asset.create).toHaveBeenCalledWith({ checksum: expect.any(Buffer), checksumAlgorithm: ChecksumAlgorithm.sha1File, - deviceAssetId: 'NONE', - deviceId: 'NONE', fileCreatedAt: asset.fileCreatedAt, fileModifiedAt: asset.fileModifiedAt, id: motionAsset.id, @@ -708,8 +706,6 @@ describe(MetadataService.name, () => { expect(mocks.asset.create).toHaveBeenCalledWith({ checksum: expect.any(Buffer), checksumAlgorithm: ChecksumAlgorithm.sha1File, - deviceAssetId: 'NONE', - deviceId: 'NONE', fileCreatedAt: asset.fileCreatedAt, fileModifiedAt: asset.fileModifiedAt, id: motionAsset.id, @@ -762,8 +758,6 @@ describe(MetadataService.name, () => { expect(mocks.asset.create).toHaveBeenCalledWith({ checksum: expect.any(Buffer), checksumAlgorithm: ChecksumAlgorithm.sha1File, - deviceAssetId: 'NONE', - deviceId: 'NONE', fileCreatedAt: asset.fileCreatedAt, fileModifiedAt: asset.fileModifiedAt, id: motionAsset.id, diff --git a/server/src/services/metadata.service.ts b/server/src/services/metadata.service.ts index c2cf66ad57..c548d94c74 100644 --- a/server/src/services/metadata.service.ts +++ b/server/src/services/metadata.service.ts @@ -681,8 +681,6 @@ export class MetadataService extends BaseService { originalPath: StorageCore.getAndroidMotionPath(asset, motionAssetId), originalFileName: `${parse(asset.originalFileName).name}.mp4`, visibility: AssetVisibility.Hidden, - deviceAssetId: 'NONE', - deviceId: 'NONE', }); isNewMotionAsset = true; diff --git a/server/src/utils/database.ts b/server/src/utils/database.ts index d25d99b491..44a4b37ad7 100644 --- a/server/src/utils/database.ts +++ b/server/src/utils/database.ts @@ -351,8 +351,6 @@ export function searchAssetBuilder(kysely: Kysely, options: AssetSearchBuild .where('asset_exif.rating', options.rating === null ? 'is' : '=', options.rating!), ) .$if(!!options.checksum, (qb) => qb.where('asset.checksum', '=', options.checksum!)) - .$if(!!options.deviceAssetId, (qb) => qb.where('asset.deviceAssetId', '=', options.deviceAssetId!)) - .$if(!!options.deviceId, (qb) => qb.where('asset.deviceId', '=', options.deviceId!)) .$if(!!options.id, (qb) => qb.where('asset.id', '=', asUuid(options.id!))) .$if(!!options.libraryId, (qb) => qb.where('asset.libraryId', '=', asUuid(options.libraryId!))) .$if(!!options.userIds, (qb) => qb.where('asset.ownerId', '=', anyUuid(options.userIds!))) diff --git a/server/src/utils/duplicate.spec.ts b/server/src/utils/duplicate.spec.ts index 9c8822518b..d63f0d3e32 100644 --- a/server/src/utils/duplicate.spec.ts +++ b/server/src/utils/duplicate.spec.ts @@ -21,8 +21,6 @@ const createAsset = ( width: 1920, height: 1080, createdAt: new Date().toISOString(), - deviceAssetId: 'device-asset-1', - deviceId: 'device-1', ownerId: 'owner-1', originalPath: '/path/to/asset', originalFileName: 'asset.jpg', diff --git a/server/test/factories/asset.factory.ts b/server/test/factories/asset.factory.ts index 9caec31d6f..0a992719e3 100644 --- a/server/test/factories/asset.factory.ts +++ b/server/test/factories/asset.factory.ts @@ -54,8 +54,6 @@ export class AssetFactory { status: AssetStatus.Active, checksum: newSha1(), checksumAlgorithm: ChecksumAlgorithm.sha1File, - deviceAssetId: '', - deviceId: '', duplicateId: null, duration: null, fileCreatedAt: new Date(now++), diff --git a/server/test/mappers.ts b/server/test/mappers.ts index ed2c9431f3..edd85a386d 100644 --- a/server/test/mappers.ts +++ b/server/test/mappers.ts @@ -127,8 +127,6 @@ export const getForMetadataExtraction = (asset: ReturnType> = {}) => { const id = asset.id || newUuid(); const now = newDate(); const defaults: Insertable = { - deviceAssetId: '', - deviceId: '', originalFileName: '', checksum: randomBytes(32), checksumAlgorithm: ChecksumAlgorithm.sha1File, diff --git a/server/test/medium/specs/services/asset-media.service.spec.ts b/server/test/medium/specs/services/asset-media.service.spec.ts index f10844ca4a..1cfe8e9f84 100644 --- a/server/test/medium/specs/services/asset-media.service.spec.ts +++ b/server/test/medium/specs/services/asset-media.service.spec.ts @@ -52,8 +52,6 @@ describe(AssetService.name, () => { sut.uploadAsset( auth, { - deviceId: 'some-id', - deviceAssetId: 'some-id', fileModifiedAt: new Date(), fileCreatedAt: new Date(), assetData: Buffer.from('some data'), @@ -66,7 +64,7 @@ describe(AssetService.name, () => { }); expect(ctx.getMock(EventRepository).emit).toHaveBeenCalledWith('AssetCreate', { - asset: expect.objectContaining({ deviceAssetId: 'some-id' }), + asset: expect.objectContaining({}), }); }); @@ -87,8 +85,6 @@ describe(AssetService.name, () => { sut.uploadAsset( auth, { - deviceId: 'some-id', - deviceAssetId: 'some-id', fileModifiedAt: new Date(), fileCreatedAt: new Date(), assetData: Buffer.from('some data'), @@ -125,8 +121,6 @@ describe(AssetService.name, () => { const auth = factory.auth({ user: { id: user.id }, sharedLink }); const file = mediumFactory.uploadFile(); const uploadDto = { - deviceId: 'some-id', - deviceAssetId: 'some-id', fileModifiedAt: new Date(), fileCreatedAt: new Date(), assetData: Buffer.from('some data'), @@ -166,8 +160,6 @@ describe(AssetService.name, () => { const auth = factory.auth({ user: { id: user.id }, sharedLink }); const uploadDto = { - deviceId: 'some-id', - deviceAssetId: 'some-id', fileModifiedAt: new Date(), fileCreatedAt: new Date(), assetData: Buffer.from('some data'), @@ -206,8 +198,6 @@ describe(AssetService.name, () => { const auth = factory.auth({ user: { id: user.id }, sharedLink }); const uploadDto = { - deviceId: 'some-id', - deviceAssetId: 'some-id', fileModifiedAt: new Date(), fileCreatedAt: new Date(), assetData: Buffer.from('some data'), @@ -248,8 +238,6 @@ describe(AssetService.name, () => { const auth = factory.auth({ user: { id: user.id }, sharedLink }); const uploadDto = { - deviceId: 'some-id', - deviceAssetId: 'some-id', fileModifiedAt: new Date(), fileCreatedAt: new Date(), assetData: Buffer.from('some data'), diff --git a/server/test/repositories/asset.repository.mock.ts b/server/test/repositories/asset.repository.mock.ts index f3d6693578..e3a1dbdf05 100644 --- a/server/test/repositories/asset.repository.mock.ts +++ b/server/test/repositories/asset.repository.mock.ts @@ -15,12 +15,10 @@ export const newAssetRepositoryMock = (): Mocked fileUploader({ assetFile: file, deviceAssetId, albumId, isLockedAssets })), + uploadExecutionQueue.addTask(() => fileUploader({ deviceAssetId, assetFile: file, albumId, isLockedAssets })), ); } else { toastManager.warning(get(t)('unsupported_file_type', { values: { file: file.name, type: file.type } }), { @@ -132,6 +132,7 @@ type FileUploaderParams = { albumId?: string; replaceAssetId?: string; isLockedAssets?: boolean; + // TODO rework the asset uploader and remove this deviceAssetId: string; }; @@ -151,8 +152,6 @@ async function fileUploader({ try { const formData = new FormData(); for (const [key, value] of Object.entries({ - deviceAssetId, - deviceId: 'WEB', fileCreatedAt, fileModifiedAt: new Date(assetFile.lastModified).toISOString(), isFavorite: 'false', diff --git a/web/src/test-data/factories/asset-factory.ts b/web/src/test-data/factories/asset-factory.ts index f3d2e80747..10800bfb8f 100644 --- a/web/src/test-data/factories/asset-factory.ts +++ b/web/src/test-data/factories/asset-factory.ts @@ -7,9 +7,7 @@ import { Sync } from 'factory.ts'; export const assetFactory = Sync.makeFactory({ id: Sync.each(() => faker.string.uuid()), createdAt: Sync.each(() => faker.date.past().toISOString()), - deviceAssetId: Sync.each(() => faker.string.uuid()), ownerId: Sync.each(() => faker.string.uuid()), - deviceId: '', libraryId: Sync.each(() => faker.string.uuid()), type: Sync.each(() => faker.helpers.enumValue(AssetTypeEnum)), originalPath: Sync.each(() => faker.system.filePath()),