diff --git a/cli/src/api/open-api/api.ts b/cli/src/api/open-api/api.ts index 956f19ba7bb50..8ade1d5fde43c 100644 --- a/cli/src/api/open-api/api.ts +++ b/cli/src/api/open-api/api.ts @@ -1132,6 +1132,37 @@ export interface DownloadArchiveInfo { */ 'size': number; } +/** + * + * @export + * @interface DownloadInfoDto + */ +export interface DownloadInfoDto { + /** + * + * @type {string} + * @memberof DownloadInfoDto + */ + 'albumId'?: string; + /** + * + * @type {number} + * @memberof DownloadInfoDto + */ + 'archiveSize'?: number; + /** + * + * @type {Array} + * @memberof DownloadInfoDto + */ + 'assetIds'?: Array; + /** + * + * @type {string} + * @memberof DownloadInfoDto + */ + 'userId'?: string; +} /** * * @export @@ -4880,7 +4911,7 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration downloadArchive: async (assetIdsDto: AssetIdsDto, key?: string, options: AxiosRequestConfig = {}): Promise => { // verify required parameter 'assetIdsDto' is not null or undefined assertParamExists('downloadArchive', 'assetIdsDto', assetIdsDto) - const localVarPath = `/asset/download`; + const localVarPath = `/asset/download/archive`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); let baseOptions; @@ -5379,16 +5410,15 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration }, /** * - * @param {Array} [assetIds] - * @param {string} [albumId] - * @param {string} [userId] - * @param {number} [archiveSize] + * @param {DownloadInfoDto} downloadInfoDto * @param {string} [key] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getDownloadInfo: async (assetIds?: Array, albumId?: string, userId?: string, archiveSize?: number, key?: string, options: AxiosRequestConfig = {}): Promise => { - const localVarPath = `/asset/download`; + getDownloadInfo: async (downloadInfoDto: DownloadInfoDto, key?: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'downloadInfoDto' is not null or undefined + assertParamExists('getDownloadInfo', 'downloadInfoDto', downloadInfoDto) + const localVarPath = `/asset/download/info`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); let baseOptions; @@ -5396,7 +5426,7 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration baseOptions = configuration.baseOptions; } - const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; @@ -5409,31 +5439,18 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration // http bearer authentication required await setBearerAuthToObject(localVarHeaderParameter, configuration) - if (assetIds) { - localVarQueryParameter['assetIds'] = assetIds; - } - - if (albumId !== undefined) { - localVarQueryParameter['albumId'] = albumId; - } - - if (userId !== undefined) { - localVarQueryParameter['userId'] = userId; - } - - if (archiveSize !== undefined) { - localVarQueryParameter['archiveSize'] = archiveSize; - } - if (key !== undefined) { localVarQueryParameter['key'] = key; } + localVarHeaderParameter['Content-Type'] = 'application/json'; + setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(downloadInfoDto, localVarRequestOptions, configuration) return { url: toPathString(localVarUrlObj), @@ -6141,16 +6158,13 @@ export const AssetApiFp = function(configuration?: Configuration) { }, /** * - * @param {Array} [assetIds] - * @param {string} [albumId] - * @param {string} [userId] - * @param {number} [archiveSize] + * @param {DownloadInfoDto} downloadInfoDto * @param {string} [key] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async getDownloadInfo(assetIds?: Array, albumId?: string, userId?: string, archiveSize?: number, key?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.getDownloadInfo(assetIds, albumId, userId, archiveSize, key, options); + async getDownloadInfo(downloadInfoDto: DownloadInfoDto, key?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getDownloadInfo(downloadInfoDto, key, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** @@ -6406,8 +6420,8 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getDownloadInfo(requestParameters: AssetApiGetDownloadInfoRequest = {}, options?: AxiosRequestConfig): AxiosPromise { - return localVarFp.getDownloadInfo(requestParameters.assetIds, requestParameters.albumId, requestParameters.userId, requestParameters.archiveSize, requestParameters.key, options).then((request) => request(axios, basePath)); + getDownloadInfo(requestParameters: AssetApiGetDownloadInfoRequest, options?: AxiosRequestConfig): AxiosPromise { + return localVarFp.getDownloadInfo(requestParameters.downloadInfoDto, requestParameters.key, options).then((request) => request(axios, basePath)); }, /** * @@ -6788,31 +6802,10 @@ export interface AssetApiGetByTimeBucketRequest { export interface AssetApiGetDownloadInfoRequest { /** * - * @type {Array} + * @type {DownloadInfoDto} * @memberof AssetApiGetDownloadInfo */ - readonly assetIds?: Array - - /** - * - * @type {string} - * @memberof AssetApiGetDownloadInfo - */ - readonly albumId?: string - - /** - * - * @type {string} - * @memberof AssetApiGetDownloadInfo - */ - readonly userId?: string - - /** - * - * @type {number} - * @memberof AssetApiGetDownloadInfo - */ - readonly archiveSize?: number + readonly downloadInfoDto: DownloadInfoDto /** * @@ -7281,8 +7274,8 @@ export class AssetApi extends BaseAPI { * @throws {RequiredError} * @memberof AssetApi */ - public getDownloadInfo(requestParameters: AssetApiGetDownloadInfoRequest = {}, options?: AxiosRequestConfig) { - return AssetApiFp(this.configuration).getDownloadInfo(requestParameters.assetIds, requestParameters.albumId, requestParameters.userId, requestParameters.archiveSize, requestParameters.key, options).then((request) => request(this.axios, this.basePath)); + public getDownloadInfo(requestParameters: AssetApiGetDownloadInfoRequest, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).getDownloadInfo(requestParameters.downloadInfoDto, requestParameters.key, options).then((request) => request(this.axios, this.basePath)); } /** diff --git a/mobile/openapi/.openapi-generator/FILES b/mobile/openapi/.openapi-generator/FILES index ea0993be8ca6c..bf485ef08b552 100644 --- a/mobile/openapi/.openapi-generator/FILES +++ b/mobile/openapi/.openapi-generator/FILES @@ -45,6 +45,7 @@ doc/DeleteAssetDto.md doc/DeleteAssetResponseDto.md doc/DeleteAssetStatus.md doc/DownloadArchiveInfo.md +doc/DownloadInfoDto.md doc/DownloadResponseDto.md doc/ExifResponseDto.md doc/ImportAssetDto.md @@ -186,6 +187,7 @@ lib/model/delete_asset_dto.dart lib/model/delete_asset_response_dto.dart lib/model/delete_asset_status.dart lib/model/download_archive_info.dart +lib/model/download_info_dto.dart lib/model/download_response_dto.dart lib/model/exif_response_dto.dart lib/model/import_asset_dto.dart @@ -298,6 +300,7 @@ test/delete_asset_dto_test.dart test/delete_asset_response_dto_test.dart test/delete_asset_status_test.dart test/download_archive_info_test.dart +test/download_info_dto_test.dart test/download_response_dto_test.dart test/exif_response_dto_test.dart test/import_asset_dto_test.dart diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index 1e20582fae1d1..9167613b255d4 100644 --- a/mobile/openapi/README.md +++ b/mobile/openapi/README.md @@ -91,7 +91,7 @@ Class | Method | HTTP request | Description *AssetApi* | [**checkDuplicateAsset**](doc//AssetApi.md#checkduplicateasset) | **POST** /asset/check | *AssetApi* | [**checkExistingAssets**](doc//AssetApi.md#checkexistingassets) | **POST** /asset/exist | *AssetApi* | [**deleteAsset**](doc//AssetApi.md#deleteasset) | **DELETE** /asset | -*AssetApi* | [**downloadArchive**](doc//AssetApi.md#downloadarchive) | **POST** /asset/download | +*AssetApi* | [**downloadArchive**](doc//AssetApi.md#downloadarchive) | **POST** /asset/download/archive | *AssetApi* | [**downloadFile**](doc//AssetApi.md#downloadfile) | **POST** /asset/download/{id} | *AssetApi* | [**getAllAssets**](doc//AssetApi.md#getallassets) | **GET** /asset | *AssetApi* | [**getAssetById**](doc//AssetApi.md#getassetbyid) | **GET** /asset/assetById/{id} | @@ -101,7 +101,7 @@ Class | Method | HTTP request | Description *AssetApi* | [**getByTimeBucket**](doc//AssetApi.md#getbytimebucket) | **GET** /asset/time-bucket | *AssetApi* | [**getCuratedLocations**](doc//AssetApi.md#getcuratedlocations) | **GET** /asset/curated-locations | *AssetApi* | [**getCuratedObjects**](doc//AssetApi.md#getcuratedobjects) | **GET** /asset/curated-objects | -*AssetApi* | [**getDownloadInfo**](doc//AssetApi.md#getdownloadinfo) | **GET** /asset/download | +*AssetApi* | [**getDownloadInfo**](doc//AssetApi.md#getdownloadinfo) | **POST** /asset/download/info | *AssetApi* | [**getMapMarkers**](doc//AssetApi.md#getmapmarkers) | **GET** /asset/map-marker | *AssetApi* | [**getMemoryLane**](doc//AssetApi.md#getmemorylane) | **GET** /asset/memory-lane | *AssetApi* | [**getTimeBuckets**](doc//AssetApi.md#gettimebuckets) | **GET** /asset/time-buckets | @@ -216,6 +216,7 @@ Class | Method | HTTP request | Description - [DeleteAssetResponseDto](doc//DeleteAssetResponseDto.md) - [DeleteAssetStatus](doc//DeleteAssetStatus.md) - [DownloadArchiveInfo](doc//DownloadArchiveInfo.md) + - [DownloadInfoDto](doc//DownloadInfoDto.md) - [DownloadResponseDto](doc//DownloadResponseDto.md) - [ExifResponseDto](doc//ExifResponseDto.md) - [ImportAssetDto](doc//ImportAssetDto.md) diff --git a/mobile/openapi/doc/AssetApi.md b/mobile/openapi/doc/AssetApi.md index 2999f2de2a894..5c1c7bb4bfb2c 100644 --- a/mobile/openapi/doc/AssetApi.md +++ b/mobile/openapi/doc/AssetApi.md @@ -13,7 +13,7 @@ Method | HTTP request | Description [**checkDuplicateAsset**](AssetApi.md#checkduplicateasset) | **POST** /asset/check | [**checkExistingAssets**](AssetApi.md#checkexistingassets) | **POST** /asset/exist | [**deleteAsset**](AssetApi.md#deleteasset) | **DELETE** /asset | -[**downloadArchive**](AssetApi.md#downloadarchive) | **POST** /asset/download | +[**downloadArchive**](AssetApi.md#downloadarchive) | **POST** /asset/download/archive | [**downloadFile**](AssetApi.md#downloadfile) | **POST** /asset/download/{id} | [**getAllAssets**](AssetApi.md#getallassets) | **GET** /asset | [**getAssetById**](AssetApi.md#getassetbyid) | **GET** /asset/assetById/{id} | @@ -23,7 +23,7 @@ Method | HTTP request | Description [**getByTimeBucket**](AssetApi.md#getbytimebucket) | **GET** /asset/time-bucket | [**getCuratedLocations**](AssetApi.md#getcuratedlocations) | **GET** /asset/curated-locations | [**getCuratedObjects**](AssetApi.md#getcuratedobjects) | **GET** /asset/curated-objects | -[**getDownloadInfo**](AssetApi.md#getdownloadinfo) | **GET** /asset/download | +[**getDownloadInfo**](AssetApi.md#getdownloadinfo) | **POST** /asset/download/info | [**getMapMarkers**](AssetApi.md#getmapmarkers) | **GET** /asset/map-marker | [**getMemoryLane**](AssetApi.md#getmemorylane) | **GET** /asset/memory-lane | [**getTimeBuckets**](AssetApi.md#gettimebuckets) | **GET** /asset/time-buckets | @@ -842,7 +842,7 @@ This endpoint does not need any parameter. [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) # **getDownloadInfo** -> DownloadResponseDto getDownloadInfo(assetIds, albumId, userId, archiveSize, key) +> DownloadResponseDto getDownloadInfo(downloadInfoDto, key) @@ -865,14 +865,11 @@ import 'package:openapi/api.dart'; //defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); final api_instance = AssetApi(); -final assetIds = []; // List | -final albumId = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String | -final userId = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String | -final archiveSize = 8.14; // num | +final downloadInfoDto = DownloadInfoDto(); // DownloadInfoDto | final key = key_example; // String | try { - final result = api_instance.getDownloadInfo(assetIds, albumId, userId, archiveSize, key); + final result = api_instance.getDownloadInfo(downloadInfoDto, key); print(result); } catch (e) { print('Exception when calling AssetApi->getDownloadInfo: $e\n'); @@ -883,10 +880,7 @@ try { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **assetIds** | [**List**](String.md)| | [optional] [default to const []] - **albumId** | **String**| | [optional] - **userId** | **String**| | [optional] - **archiveSize** | **num**| | [optional] + **downloadInfoDto** | [**DownloadInfoDto**](DownloadInfoDto.md)| | **key** | **String**| | [optional] ### Return type @@ -899,7 +893,7 @@ Name | Type | Description | Notes ### HTTP request headers - - **Content-Type**: Not defined + - **Content-Type**: application/json - **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) diff --git a/mobile/openapi/doc/DownloadInfoDto.md b/mobile/openapi/doc/DownloadInfoDto.md new file mode 100644 index 0000000000000..14d5d1e712ea8 --- /dev/null +++ b/mobile/openapi/doc/DownloadInfoDto.md @@ -0,0 +1,18 @@ +# openapi.model.DownloadInfoDto + +## Load the model package +```dart +import 'package:openapi/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**albumId** | **String** | | [optional] +**archiveSize** | **int** | | [optional] +**assetIds** | **List** | | [optional] [default to const []] +**userId** | **String** | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index 644244a103b14..a38d8784e3411 100644 --- a/mobile/openapi/lib/api.dart +++ b/mobile/openapi/lib/api.dart @@ -81,6 +81,7 @@ part 'model/delete_asset_dto.dart'; part 'model/delete_asset_response_dto.dart'; part 'model/delete_asset_status.dart'; part 'model/download_archive_info.dart'; +part 'model/download_info_dto.dart'; part 'model/download_response_dto.dart'; part 'model/exif_response_dto.dart'; part 'model/import_asset_dto.dart'; diff --git a/mobile/openapi/lib/api/asset_api.dart b/mobile/openapi/lib/api/asset_api.dart index 6f4c391bf8a10..ba9f1d5a1f598 100644 --- a/mobile/openapi/lib/api/asset_api.dart +++ b/mobile/openapi/lib/api/asset_api.dart @@ -230,7 +230,7 @@ class AssetApi { return null; } - /// Performs an HTTP 'POST /asset/download' operation and returns the [Response]. + /// Performs an HTTP 'POST /asset/download/archive' operation and returns the [Response]. /// Parameters: /// /// * [AssetIdsDto] assetIdsDto (required): @@ -238,7 +238,7 @@ class AssetApi { /// * [String] key: Future downloadArchiveWithHttpInfo(AssetIdsDto assetIdsDto, { String? key, }) async { // ignore: prefer_const_declarations - final path = r'/asset/download'; + final path = r'/asset/download/archive'; // ignore: prefer_final_locals Object? postBody = assetIdsDto; @@ -853,51 +853,33 @@ class AssetApi { return null; } - /// Performs an HTTP 'GET /asset/download' operation and returns the [Response]. + /// Performs an HTTP 'POST /asset/download/info' operation and returns the [Response]. /// Parameters: /// - /// * [List] assetIds: - /// - /// * [String] albumId: - /// - /// * [String] userId: - /// - /// * [num] archiveSize: + /// * [DownloadInfoDto] downloadInfoDto (required): /// /// * [String] key: - Future getDownloadInfoWithHttpInfo({ List? assetIds, String? albumId, String? userId, num? archiveSize, String? key, }) async { + Future getDownloadInfoWithHttpInfo(DownloadInfoDto downloadInfoDto, { String? key, }) async { // ignore: prefer_const_declarations - final path = r'/asset/download'; + final path = r'/asset/download/info'; // ignore: prefer_final_locals - Object? postBody; + Object? postBody = downloadInfoDto; final queryParams = []; final headerParams = {}; final formParams = {}; - if (assetIds != null) { - queryParams.addAll(_queryParams('multi', 'assetIds', assetIds)); - } - if (albumId != null) { - queryParams.addAll(_queryParams('', 'albumId', albumId)); - } - if (userId != null) { - queryParams.addAll(_queryParams('', 'userId', userId)); - } - if (archiveSize != null) { - queryParams.addAll(_queryParams('', 'archiveSize', archiveSize)); - } if (key != null) { queryParams.addAll(_queryParams('', 'key', key)); } - const contentTypes = []; + const contentTypes = ['application/json']; return apiClient.invokeAPI( path, - 'GET', + 'POST', queryParams, postBody, headerParams, @@ -908,17 +890,11 @@ class AssetApi { /// Parameters: /// - /// * [List] assetIds: - /// - /// * [String] albumId: - /// - /// * [String] userId: - /// - /// * [num] archiveSize: + /// * [DownloadInfoDto] downloadInfoDto (required): /// /// * [String] key: - Future getDownloadInfo({ List? assetIds, String? albumId, String? userId, num? archiveSize, String? key, }) async { - final response = await getDownloadInfoWithHttpInfo( assetIds: assetIds, albumId: albumId, userId: userId, archiveSize: archiveSize, key: key, ); + Future getDownloadInfo(DownloadInfoDto downloadInfoDto, { String? key, }) async { + final response = await getDownloadInfoWithHttpInfo(downloadInfoDto, key: key, ); 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 fd1252cc7846c..eb76c12c58dfc 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -257,6 +257,8 @@ class ApiClient { return DeleteAssetStatusTypeTransformer().decode(value); case 'DownloadArchiveInfo': return DownloadArchiveInfo.fromJson(value); + case 'DownloadInfoDto': + return DownloadInfoDto.fromJson(value); case 'DownloadResponseDto': return DownloadResponseDto.fromJson(value); case 'ExifResponseDto': diff --git a/mobile/openapi/lib/model/download_info_dto.dart b/mobile/openapi/lib/model/download_info_dto.dart new file mode 100644 index 0000000000000..fa3a06eeaccee --- /dev/null +++ b/mobile/openapi/lib/model/download_info_dto.dart @@ -0,0 +1,150 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// 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 DownloadInfoDto { + /// Returns a new [DownloadInfoDto] instance. + DownloadInfoDto({ + this.albumId, + this.archiveSize, + this.assetIds = const [], + this.userId, + }); + + /// + /// 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? albumId; + + /// + /// 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. + /// + int? archiveSize; + + List assetIds; + + /// + /// 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? userId; + + @override + bool operator ==(Object other) => identical(this, other) || other is DownloadInfoDto && + other.albumId == albumId && + other.archiveSize == archiveSize && + other.assetIds == assetIds && + other.userId == userId; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (albumId == null ? 0 : albumId!.hashCode) + + (archiveSize == null ? 0 : archiveSize!.hashCode) + + (assetIds.hashCode) + + (userId == null ? 0 : userId!.hashCode); + + @override + String toString() => 'DownloadInfoDto[albumId=$albumId, archiveSize=$archiveSize, assetIds=$assetIds, userId=$userId]'; + + Map toJson() { + final json = {}; + if (this.albumId != null) { + json[r'albumId'] = this.albumId; + } else { + // json[r'albumId'] = null; + } + if (this.archiveSize != null) { + json[r'archiveSize'] = this.archiveSize; + } else { + // json[r'archiveSize'] = null; + } + json[r'assetIds'] = this.assetIds; + if (this.userId != null) { + json[r'userId'] = this.userId; + } else { + // json[r'userId'] = null; + } + return json; + } + + /// Returns a new [DownloadInfoDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static DownloadInfoDto? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + return DownloadInfoDto( + albumId: mapValueOfType(json, r'albumId'), + archiveSize: mapValueOfType(json, r'archiveSize'), + assetIds: json[r'assetIds'] is List + ? (json[r'assetIds'] as List).cast() + : const [], + userId: mapValueOfType(json, r'userId'), + ); + } + 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 = DownloadInfoDto.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 = DownloadInfoDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of DownloadInfoDto-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] = DownloadInfoDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/test/asset_api_test.dart b/mobile/openapi/test/asset_api_test.dart index 588902a14c392..ebb472c4a0522 100644 --- a/mobile/openapi/test/asset_api_test.dart +++ b/mobile/openapi/test/asset_api_test.dart @@ -97,7 +97,7 @@ void main() { // TODO }); - //Future getDownloadInfo({ List assetIds, String albumId, String userId, num archiveSize, String key }) async + //Future getDownloadInfo(DownloadInfoDto downloadInfoDto, { String key }) async test('test getDownloadInfo', () async { // TODO }); diff --git a/mobile/openapi/test/download_info_dto_test.dart b/mobile/openapi/test/download_info_dto_test.dart new file mode 100644 index 0000000000000..5efd4e11eb481 --- /dev/null +++ b/mobile/openapi/test/download_info_dto_test.dart @@ -0,0 +1,42 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// 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 + +import 'package:openapi/api.dart'; +import 'package:test/test.dart'; + +// tests for DownloadInfoDto +void main() { + // final instance = DownloadInfoDto(); + + group('test DownloadInfoDto', () { + // String albumId + test('to test the property `albumId`', () async { + // TODO + }); + + // int archiveSize + test('to test the property `archiveSize`', () async { + // TODO + }); + + // List assetIds (default value: const []) + test('to test the property `assetIds`', () async { + // TODO + }); + + // String userId + test('to test the property `userId`', () async { + // TODO + }); + + + }); + +} diff --git a/server/immich-openapi-specs.json b/server/immich-openapi-specs.json index 59543353fb44e..f193eb25e4a71 100644 --- a/server/immich-openapi-specs.json +++ b/server/immich-openapi-specs.json @@ -1026,84 +1026,7 @@ ] } }, - "/asset/download": { - "get": { - "operationId": "getDownloadInfo", - "parameters": [ - { - "name": "assetIds", - "required": false, - "in": "query", - "schema": { - "format": "uuid", - "type": "array", - "items": { - "type": "string" - } - } - }, - { - "name": "albumId", - "required": false, - "in": "query", - "schema": { - "format": "uuid", - "type": "string" - } - }, - { - "name": "userId", - "required": false, - "in": "query", - "schema": { - "format": "uuid", - "type": "string" - } - }, - { - "name": "archiveSize", - "required": false, - "in": "query", - "schema": { - "type": "number" - } - }, - { - "name": "key", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DownloadResponseDto" - } - } - }, - "description": "" - } - }, - "security": [ - { - "bearer": [] - }, - { - "cookie": [] - }, - { - "api_key": [] - } - ], - "tags": [ - "Asset" - ] - }, + "/asset/download/archive": { "post": { "operationId": "downloadArchive", "parameters": [ @@ -1155,6 +1078,57 @@ ] } }, + "/asset/download/info": { + "post": { + "operationId": "getDownloadInfo", + "parameters": [ + { + "name": "key", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DownloadInfoDto" + } + } + }, + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DownloadResponseDto" + } + } + }, + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "tags": [ + "Asset" + ] + } + }, "/asset/download/{id}": { "post": { "operationId": "downloadFile", @@ -5549,6 +5523,29 @@ ], "type": "object" }, + "DownloadInfoDto": { + "properties": { + "albumId": { + "format": "uuid", + "type": "string" + }, + "archiveSize": { + "type": "integer" + }, + "assetIds": { + "items": { + "format": "uuid", + "type": "string" + }, + "type": "array" + }, + "userId": { + "format": "uuid", + "type": "string" + } + }, + "type": "object" + }, "DownloadResponseDto": { "properties": { "archives": { diff --git a/server/src/domain/asset/asset.service.ts b/server/src/domain/asset/asset.service.ts index fdd6df6efd716..ac655b8077009 100644 --- a/server/src/domain/asset/asset.service.ts +++ b/server/src/domain/asset/asset.service.ts @@ -13,7 +13,7 @@ import { IAssetRepository } from './asset.repository'; import { AssetIdsDto, DownloadArchiveInfo, - DownloadDto, + DownloadInfoDto, DownloadResponseDto, MemoryLaneDto, TimeBucketAssetDto, @@ -176,7 +176,7 @@ export class AssetService { return this.storageRepository.createReadStream(asset.originalPath, mimeTypes.lookup(asset.originalPath)); } - async getDownloadInfo(authUser: AuthUserDto, dto: DownloadDto): Promise { + async getDownloadInfo(authUser: AuthUserDto, dto: DownloadInfoDto): Promise { const targetSize = dto.archiveSize || HumanReadableSize.GiB * 4; const archives: DownloadArchiveInfo[] = []; let archive: DownloadArchiveInfo = { size: 0, assetIds: [] }; @@ -234,7 +234,7 @@ export class AssetService { return { stream: zip.stream }; } - private async getDownloadAssets(authUser: AuthUserDto, dto: DownloadDto): Promise> { + private async getDownloadAssets(authUser: AuthUserDto, dto: DownloadInfoDto): Promise> { const PAGINATION_SIZE = 2500; if (dto.assetIds) { diff --git a/server/src/domain/asset/dto/download.dto.ts b/server/src/domain/asset/dto/download.dto.ts index c2cf85685aa8a..604a8ea5fb3b4 100644 --- a/server/src/domain/asset/dto/download.dto.ts +++ b/server/src/domain/asset/dto/download.dto.ts @@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsInt, IsOptional, IsPositive } from 'class-validator'; import { ValidateUUID } from '../../domain.util'; -export class DownloadDto { +export class DownloadInfoDto { @ValidateUUID({ each: true, optional: true }) assetIds?: string[]; @@ -15,6 +15,7 @@ export class DownloadDto { @IsInt() @IsPositive() @IsOptional() + @ApiProperty({ type: 'integer' }) archiveSize?: number; } diff --git a/server/src/immich/controllers/asset.controller.ts b/server/src/immich/controllers/asset.controller.ts index ba3de02cc5925..b55cbb870d307 100644 --- a/server/src/immich/controllers/asset.controller.ts +++ b/server/src/immich/controllers/asset.controller.ts @@ -5,7 +5,7 @@ import { AssetStatsDto, AssetStatsResponseDto, AuthUserDto, - DownloadDto, + DownloadInfoDto, DownloadResponseDto, MapMarkerResponseDto, MemoryLaneDto, @@ -39,13 +39,13 @@ export class AssetController { } @SharedLinkRoute() - @Get('download') - getDownloadInfo(@AuthUser() authUser: AuthUserDto, @Query() dto: DownloadDto): Promise { + @Post('download/info') + getDownloadInfo(@AuthUser() authUser: AuthUserDto, @Body() dto: DownloadInfoDto): Promise { return this.service.getDownloadInfo(authUser, dto); } @SharedLinkRoute() - @Post('download') + @Post('download/archive') @HttpCode(HttpStatus.OK) @ApiOkResponse({ content: { 'application/octet-stream': { schema: { type: 'string', format: 'binary' } } } }) downloadArchive(@AuthUser() authUser: AuthUserDto, @Body() dto: AssetIdsDto): Promise { diff --git a/web/src/api/open-api/api.ts b/web/src/api/open-api/api.ts index 956f19ba7bb50..8ade1d5fde43c 100644 --- a/web/src/api/open-api/api.ts +++ b/web/src/api/open-api/api.ts @@ -1132,6 +1132,37 @@ export interface DownloadArchiveInfo { */ 'size': number; } +/** + * + * @export + * @interface DownloadInfoDto + */ +export interface DownloadInfoDto { + /** + * + * @type {string} + * @memberof DownloadInfoDto + */ + 'albumId'?: string; + /** + * + * @type {number} + * @memberof DownloadInfoDto + */ + 'archiveSize'?: number; + /** + * + * @type {Array} + * @memberof DownloadInfoDto + */ + 'assetIds'?: Array; + /** + * + * @type {string} + * @memberof DownloadInfoDto + */ + 'userId'?: string; +} /** * * @export @@ -4880,7 +4911,7 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration downloadArchive: async (assetIdsDto: AssetIdsDto, key?: string, options: AxiosRequestConfig = {}): Promise => { // verify required parameter 'assetIdsDto' is not null or undefined assertParamExists('downloadArchive', 'assetIdsDto', assetIdsDto) - const localVarPath = `/asset/download`; + const localVarPath = `/asset/download/archive`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); let baseOptions; @@ -5379,16 +5410,15 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration }, /** * - * @param {Array} [assetIds] - * @param {string} [albumId] - * @param {string} [userId] - * @param {number} [archiveSize] + * @param {DownloadInfoDto} downloadInfoDto * @param {string} [key] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getDownloadInfo: async (assetIds?: Array, albumId?: string, userId?: string, archiveSize?: number, key?: string, options: AxiosRequestConfig = {}): Promise => { - const localVarPath = `/asset/download`; + getDownloadInfo: async (downloadInfoDto: DownloadInfoDto, key?: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'downloadInfoDto' is not null or undefined + assertParamExists('getDownloadInfo', 'downloadInfoDto', downloadInfoDto) + const localVarPath = `/asset/download/info`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); let baseOptions; @@ -5396,7 +5426,7 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration baseOptions = configuration.baseOptions; } - const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; const localVarHeaderParameter = {} as any; const localVarQueryParameter = {} as any; @@ -5409,31 +5439,18 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration // http bearer authentication required await setBearerAuthToObject(localVarHeaderParameter, configuration) - if (assetIds) { - localVarQueryParameter['assetIds'] = assetIds; - } - - if (albumId !== undefined) { - localVarQueryParameter['albumId'] = albumId; - } - - if (userId !== undefined) { - localVarQueryParameter['userId'] = userId; - } - - if (archiveSize !== undefined) { - localVarQueryParameter['archiveSize'] = archiveSize; - } - if (key !== undefined) { localVarQueryParameter['key'] = key; } + localVarHeaderParameter['Content-Type'] = 'application/json'; + setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(downloadInfoDto, localVarRequestOptions, configuration) return { url: toPathString(localVarUrlObj), @@ -6141,16 +6158,13 @@ export const AssetApiFp = function(configuration?: Configuration) { }, /** * - * @param {Array} [assetIds] - * @param {string} [albumId] - * @param {string} [userId] - * @param {number} [archiveSize] + * @param {DownloadInfoDto} downloadInfoDto * @param {string} [key] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async getDownloadInfo(assetIds?: Array, albumId?: string, userId?: string, archiveSize?: number, key?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.getDownloadInfo(assetIds, albumId, userId, archiveSize, key, options); + async getDownloadInfo(downloadInfoDto: DownloadInfoDto, key?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getDownloadInfo(downloadInfoDto, key, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** @@ -6406,8 +6420,8 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getDownloadInfo(requestParameters: AssetApiGetDownloadInfoRequest = {}, options?: AxiosRequestConfig): AxiosPromise { - return localVarFp.getDownloadInfo(requestParameters.assetIds, requestParameters.albumId, requestParameters.userId, requestParameters.archiveSize, requestParameters.key, options).then((request) => request(axios, basePath)); + getDownloadInfo(requestParameters: AssetApiGetDownloadInfoRequest, options?: AxiosRequestConfig): AxiosPromise { + return localVarFp.getDownloadInfo(requestParameters.downloadInfoDto, requestParameters.key, options).then((request) => request(axios, basePath)); }, /** * @@ -6788,31 +6802,10 @@ export interface AssetApiGetByTimeBucketRequest { export interface AssetApiGetDownloadInfoRequest { /** * - * @type {Array} + * @type {DownloadInfoDto} * @memberof AssetApiGetDownloadInfo */ - readonly assetIds?: Array - - /** - * - * @type {string} - * @memberof AssetApiGetDownloadInfo - */ - readonly albumId?: string - - /** - * - * @type {string} - * @memberof AssetApiGetDownloadInfo - */ - readonly userId?: string - - /** - * - * @type {number} - * @memberof AssetApiGetDownloadInfo - */ - readonly archiveSize?: number + readonly downloadInfoDto: DownloadInfoDto /** * @@ -7281,8 +7274,8 @@ export class AssetApi extends BaseAPI { * @throws {RequiredError} * @memberof AssetApi */ - public getDownloadInfo(requestParameters: AssetApiGetDownloadInfoRequest = {}, options?: AxiosRequestConfig) { - return AssetApiFp(this.configuration).getDownloadInfo(requestParameters.assetIds, requestParameters.albumId, requestParameters.userId, requestParameters.archiveSize, requestParameters.key, options).then((request) => request(this.axios, this.basePath)); + public getDownloadInfo(requestParameters: AssetApiGetDownloadInfoRequest, options?: AxiosRequestConfig) { + return AssetApiFp(this.configuration).getDownloadInfo(requestParameters.downloadInfoDto, requestParameters.key, options).then((request) => request(this.axios, this.basePath)); } /** diff --git a/web/src/lib/utils/asset-utils.ts b/web/src/lib/utils/asset-utils.ts index 0a8ff758d2e17..cb29b503a0a29 100644 --- a/web/src/lib/utils/asset-utils.ts +++ b/web/src/lib/utils/asset-utils.ts @@ -1,6 +1,6 @@ import { notificationController, NotificationType } from '$lib/components/shared-components/notification/notification'; import { downloadManager } from '$lib/stores/download'; -import { api, AssetApiGetDownloadInfoRequest, BulkIdResponseDto, AssetResponseDto, DownloadResponseDto } from '@api'; +import { api, BulkIdResponseDto, AssetResponseDto, DownloadResponseDto, DownloadInfoDto } from '@api'; import { handleError } from './handle-error'; export const addAssetsToAlbum = async ( @@ -32,15 +32,11 @@ const downloadBlob = (data: Blob, filename: string) => { URL.revokeObjectURL(url); }; -export const downloadArchive = async ( - fileName: string, - options: Omit, - key?: string, -) => { +export const downloadArchive = async (fileName: string, options: DownloadInfoDto, key?: string) => { let downloadInfo: DownloadResponseDto | null = null; try { - const { data } = await api.assetApi.getDownloadInfo({ ...options, key }); + const { data } = await api.assetApi.getDownloadInfo({ downloadInfoDto: options, key }); downloadInfo = data; } catch (error) { handleError(error, 'Unable to download files');