mirror of
https://github.com/immich-app/immich.git
synced 2025-04-13 19:46:24 +02:00
refactor(server): asset stats (#3253)
* refactor(server): asset stats * chore: open api
This commit is contained in:
parent
05e1a6d949
commit
f952bc0b64
29 changed files with 601 additions and 844 deletions
cli/src/api/open-api
mobile/openapi
server
immich-openapi-specs.json
src
domain/asset
immich
api-v1/asset
controllers
infra/repositories
test/repositories
web/src
api/open-api
lib/components/shared-components/side-bar
routes/(user)/photos
194
cli/src/api/open-api/api.ts
generated
194
cli/src/api/open-api/api.ts
generated
|
@ -486,43 +486,6 @@ export interface AssetCountByTimeBucketResponseDto {
|
|||
*/
|
||||
'buckets': Array<AssetCountByTimeBucket>;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface AssetCountByUserIdResponseDto
|
||||
*/
|
||||
export interface AssetCountByUserIdResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetCountByUserIdResponseDto
|
||||
*/
|
||||
'audio': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetCountByUserIdResponseDto
|
||||
*/
|
||||
'photos': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetCountByUserIdResponseDto
|
||||
*/
|
||||
'videos': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetCountByUserIdResponseDto
|
||||
*/
|
||||
'other': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetCountByUserIdResponseDto
|
||||
*/
|
||||
'total': number;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
@ -724,6 +687,31 @@ export interface AssetResponseDto {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface AssetStatsResponseDto
|
||||
*/
|
||||
export interface AssetStatsResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetStatsResponseDto
|
||||
*/
|
||||
'images': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetStatsResponseDto
|
||||
*/
|
||||
'videos': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetStatsResponseDto
|
||||
*/
|
||||
'total': number;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
@ -4892,44 +4880,6 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
|||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getArchivedAssetCountByUserId: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/asset/stat/archive`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
|
||||
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication cookie required
|
||||
|
||||
// authentication api_key required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
|
||||
|
||||
// authentication bearer required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
@ -5079,8 +5029,8 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
|||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getAssetCountByUserId: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/asset/count-by-user-id`;
|
||||
getAssetSearchTerms: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/asset/search-terms`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
|
@ -5114,11 +5064,13 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
|||
},
|
||||
/**
|
||||
*
|
||||
* @param {boolean} [isArchived]
|
||||
* @param {boolean} [isFavorite]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getAssetSearchTerms: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/asset/search-terms`;
|
||||
getAssetStats: async (isArchived?: boolean, isFavorite?: boolean, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/asset/statistics`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
|
@ -5139,6 +5091,14 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
|||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
if (isArchived !== undefined) {
|
||||
localVarQueryParameter['isArchived'] = isArchived;
|
||||
}
|
||||
|
||||
if (isFavorite !== undefined) {
|
||||
localVarQueryParameter['isFavorite'] = isFavorite;
|
||||
}
|
||||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
|
@ -5887,15 +5847,6 @@ export const AssetApiFp = function(configuration?: Configuration) {
|
|||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAllAssets(userId, isFavorite, isArchived, withoutThumbs, skip, ifNoneMatch, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getArchivedAssetCountByUserId(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AssetCountByUserIdResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getArchivedAssetCountByUserId(options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
* Get a single asset\'s information
|
||||
* @param {string} id
|
||||
|
@ -5932,17 +5883,19 @@ export const AssetApiFp = function(configuration?: Configuration) {
|
|||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getAssetCountByUserId(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AssetCountByUserIdResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetCountByUserId(options);
|
||||
async getAssetSearchTerms(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<string>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetSearchTerms(options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {boolean} [isArchived]
|
||||
* @param {boolean} [isFavorite]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getAssetSearchTerms(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<string>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetSearchTerms(options);
|
||||
async getAssetStats(isArchived?: boolean, isFavorite?: boolean, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AssetStatsResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetStats(isArchived, isFavorite, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
|
@ -6160,14 +6113,6 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath
|
|||
getAllAssets(requestParameters: AssetApiGetAllAssetsRequest = {}, options?: AxiosRequestConfig): AxiosPromise<Array<AssetResponseDto>> {
|
||||
return localVarFp.getAllAssets(requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.withoutThumbs, requestParameters.skip, requestParameters.ifNoneMatch, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getArchivedAssetCountByUserId(options?: AxiosRequestConfig): AxiosPromise<AssetCountByUserIdResponseDto> {
|
||||
return localVarFp.getArchivedAssetCountByUserId(options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Get a single asset\'s information
|
||||
* @param {AssetApiGetAssetByIdRequest} requestParameters Request parameters.
|
||||
|
@ -6200,16 +6145,17 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath
|
|||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getAssetCountByUserId(options?: AxiosRequestConfig): AxiosPromise<AssetCountByUserIdResponseDto> {
|
||||
return localVarFp.getAssetCountByUserId(options).then((request) => request(axios, basePath));
|
||||
getAssetSearchTerms(options?: AxiosRequestConfig): AxiosPromise<Array<string>> {
|
||||
return localVarFp.getAssetSearchTerms(options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {AssetApiGetAssetStatsRequest} requestParameters Request parameters.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getAssetSearchTerms(options?: AxiosRequestConfig): AxiosPromise<Array<string>> {
|
||||
return localVarFp.getAssetSearchTerms(options).then((request) => request(axios, basePath));
|
||||
getAssetStats(requestParameters: AssetApiGetAssetStatsRequest = {}, options?: AxiosRequestConfig): AxiosPromise<AssetStatsResponseDto> {
|
||||
return localVarFp.getAssetStats(requestParameters.isArchived, requestParameters.isFavorite, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
|
@ -6523,6 +6469,27 @@ export interface AssetApiGetAssetCountByTimeBucketRequest {
|
|||
readonly getAssetCountByTimeBucketDto: GetAssetCountByTimeBucketDto
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for getAssetStats operation in AssetApi.
|
||||
* @export
|
||||
* @interface AssetApiGetAssetStatsRequest
|
||||
*/
|
||||
export interface AssetApiGetAssetStatsRequest {
|
||||
/**
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof AssetApiGetAssetStats
|
||||
*/
|
||||
readonly isArchived?: boolean
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof AssetApiGetAssetStats
|
||||
*/
|
||||
readonly isFavorite?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for getAssetThumbnail operation in AssetApi.
|
||||
* @export
|
||||
|
@ -6915,16 +6882,6 @@ export class AssetApi extends BaseAPI {
|
|||
return AssetApiFp(this.configuration).getAllAssets(requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.withoutThumbs, requestParameters.skip, requestParameters.ifNoneMatch, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof AssetApi
|
||||
*/
|
||||
public getArchivedAssetCountByUserId(options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getArchivedAssetCountByUserId(options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single asset\'s information
|
||||
* @param {AssetApiGetAssetByIdRequest} requestParameters Request parameters.
|
||||
|
@ -6964,18 +6921,19 @@ export class AssetApi extends BaseAPI {
|
|||
* @throws {RequiredError}
|
||||
* @memberof AssetApi
|
||||
*/
|
||||
public getAssetCountByUserId(options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getAssetCountByUserId(options).then((request) => request(this.axios, this.basePath));
|
||||
public getAssetSearchTerms(options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getAssetSearchTerms(options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {AssetApiGetAssetStatsRequest} requestParameters Request parameters.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof AssetApi
|
||||
*/
|
||||
public getAssetSearchTerms(options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getAssetSearchTerms(options).then((request) => request(this.axios, this.basePath));
|
||||
public getAssetStats(requestParameters: AssetApiGetAssetStatsRequest = {}, options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getAssetStats(requestParameters.isArchived, requestParameters.isFavorite, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
6
mobile/openapi/.openapi-generator/FILES
generated
6
mobile/openapi/.openapi-generator/FILES
generated
|
@ -23,11 +23,11 @@ doc/AssetBulkUploadCheckResponseDto.md
|
|||
doc/AssetBulkUploadCheckResult.md
|
||||
doc/AssetCountByTimeBucket.md
|
||||
doc/AssetCountByTimeBucketResponseDto.md
|
||||
doc/AssetCountByUserIdResponseDto.md
|
||||
doc/AssetFileUploadResponseDto.md
|
||||
doc/AssetIdsDto.md
|
||||
doc/AssetIdsResponseDto.md
|
||||
doc/AssetResponseDto.md
|
||||
doc/AssetStatsResponseDto.md
|
||||
doc/AssetTypeEnum.md
|
||||
doc/AudioCodec.md
|
||||
doc/AuthDeviceResponseDto.md
|
||||
|
@ -163,11 +163,11 @@ lib/model/asset_bulk_upload_check_response_dto.dart
|
|||
lib/model/asset_bulk_upload_check_result.dart
|
||||
lib/model/asset_count_by_time_bucket.dart
|
||||
lib/model/asset_count_by_time_bucket_response_dto.dart
|
||||
lib/model/asset_count_by_user_id_response_dto.dart
|
||||
lib/model/asset_file_upload_response_dto.dart
|
||||
lib/model/asset_ids_dto.dart
|
||||
lib/model/asset_ids_response_dto.dart
|
||||
lib/model/asset_response_dto.dart
|
||||
lib/model/asset_stats_response_dto.dart
|
||||
lib/model/asset_type_enum.dart
|
||||
lib/model/audio_codec.dart
|
||||
lib/model/auth_device_response_dto.dart
|
||||
|
@ -272,11 +272,11 @@ test/asset_bulk_upload_check_response_dto_test.dart
|
|||
test/asset_bulk_upload_check_result_test.dart
|
||||
test/asset_count_by_time_bucket_response_dto_test.dart
|
||||
test/asset_count_by_time_bucket_test.dart
|
||||
test/asset_count_by_user_id_response_dto_test.dart
|
||||
test/asset_file_upload_response_dto_test.dart
|
||||
test/asset_ids_dto_test.dart
|
||||
test/asset_ids_response_dto_test.dart
|
||||
test/asset_response_dto_test.dart
|
||||
test/asset_stats_response_dto_test.dart
|
||||
test/asset_type_enum_test.dart
|
||||
test/audio_codec_test.dart
|
||||
test/auth_device_response_dto_test.dart
|
||||
|
|
5
mobile/openapi/README.md
generated
5
mobile/openapi/README.md
generated
|
@ -94,12 +94,11 @@ Class | Method | HTTP request | Description
|
|||
*AssetApi* | [**downloadArchive**](doc//AssetApi.md#downloadarchive) | **POST** /asset/download |
|
||||
*AssetApi* | [**downloadFile**](doc//AssetApi.md#downloadfile) | **POST** /asset/download/{id} |
|
||||
*AssetApi* | [**getAllAssets**](doc//AssetApi.md#getallassets) | **GET** /asset |
|
||||
*AssetApi* | [**getArchivedAssetCountByUserId**](doc//AssetApi.md#getarchivedassetcountbyuserid) | **GET** /asset/stat/archive |
|
||||
*AssetApi* | [**getAssetById**](doc//AssetApi.md#getassetbyid) | **GET** /asset/assetById/{id} |
|
||||
*AssetApi* | [**getAssetByTimeBucket**](doc//AssetApi.md#getassetbytimebucket) | **POST** /asset/time-bucket |
|
||||
*AssetApi* | [**getAssetCountByTimeBucket**](doc//AssetApi.md#getassetcountbytimebucket) | **POST** /asset/count-by-time-bucket |
|
||||
*AssetApi* | [**getAssetCountByUserId**](doc//AssetApi.md#getassetcountbyuserid) | **GET** /asset/count-by-user-id |
|
||||
*AssetApi* | [**getAssetSearchTerms**](doc//AssetApi.md#getassetsearchterms) | **GET** /asset/search-terms |
|
||||
*AssetApi* | [**getAssetStats**](doc//AssetApi.md#getassetstats) | **GET** /asset/statistics |
|
||||
*AssetApi* | [**getAssetThumbnail**](doc//AssetApi.md#getassetthumbnail) | **GET** /asset/thumbnail/{id} |
|
||||
*AssetApi* | [**getCuratedLocations**](doc//AssetApi.md#getcuratedlocations) | **GET** /asset/curated-locations |
|
||||
*AssetApi* | [**getCuratedObjects**](doc//AssetApi.md#getcuratedobjects) | **GET** /asset/curated-objects |
|
||||
|
@ -194,11 +193,11 @@ Class | Method | HTTP request | Description
|
|||
- [AssetBulkUploadCheckResult](doc//AssetBulkUploadCheckResult.md)
|
||||
- [AssetCountByTimeBucket](doc//AssetCountByTimeBucket.md)
|
||||
- [AssetCountByTimeBucketResponseDto](doc//AssetCountByTimeBucketResponseDto.md)
|
||||
- [AssetCountByUserIdResponseDto](doc//AssetCountByUserIdResponseDto.md)
|
||||
- [AssetFileUploadResponseDto](doc//AssetFileUploadResponseDto.md)
|
||||
- [AssetIdsDto](doc//AssetIdsDto.md)
|
||||
- [AssetIdsResponseDto](doc//AssetIdsResponseDto.md)
|
||||
- [AssetResponseDto](doc//AssetResponseDto.md)
|
||||
- [AssetStatsResponseDto](doc//AssetStatsResponseDto.md)
|
||||
- [AssetTypeEnum](doc//AssetTypeEnum.md)
|
||||
- [AudioCodec](doc//AudioCodec.md)
|
||||
- [AuthDeviceResponseDto](doc//AuthDeviceResponseDto.md)
|
||||
|
|
162
mobile/openapi/doc/AssetApi.md
generated
162
mobile/openapi/doc/AssetApi.md
generated
|
@ -16,12 +16,11 @@ Method | HTTP request | Description
|
|||
[**downloadArchive**](AssetApi.md#downloadarchive) | **POST** /asset/download |
|
||||
[**downloadFile**](AssetApi.md#downloadfile) | **POST** /asset/download/{id} |
|
||||
[**getAllAssets**](AssetApi.md#getallassets) | **GET** /asset |
|
||||
[**getArchivedAssetCountByUserId**](AssetApi.md#getarchivedassetcountbyuserid) | **GET** /asset/stat/archive |
|
||||
[**getAssetById**](AssetApi.md#getassetbyid) | **GET** /asset/assetById/{id} |
|
||||
[**getAssetByTimeBucket**](AssetApi.md#getassetbytimebucket) | **POST** /asset/time-bucket |
|
||||
[**getAssetCountByTimeBucket**](AssetApi.md#getassetcountbytimebucket) | **POST** /asset/count-by-time-bucket |
|
||||
[**getAssetCountByUserId**](AssetApi.md#getassetcountbyuserid) | **GET** /asset/count-by-user-id |
|
||||
[**getAssetSearchTerms**](AssetApi.md#getassetsearchterms) | **GET** /asset/search-terms |
|
||||
[**getAssetStats**](AssetApi.md#getassetstats) | **GET** /asset/statistics |
|
||||
[**getAssetThumbnail**](AssetApi.md#getassetthumbnail) | **GET** /asset/thumbnail/{id} |
|
||||
[**getCuratedLocations**](AssetApi.md#getcuratedlocations) | **GET** /asset/curated-locations |
|
||||
[**getCuratedObjects**](AssetApi.md#getcuratedobjects) | **GET** /asset/curated-objects |
|
||||
|
@ -445,57 +444,6 @@ Name | Type | Description | Notes
|
|||
|
||||
[[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)
|
||||
|
||||
# **getArchivedAssetCountByUserId**
|
||||
> AssetCountByUserIdResponseDto getArchivedAssetCountByUserId()
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
```dart
|
||||
import 'package:openapi/api.dart';
|
||||
// TODO Configure API key authorization: cookie
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
||||
// TODO Configure API key authorization: api_key
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
||||
// TODO Configure HTTP Bearer authorization: bearer
|
||||
// Case 1. Use String Token
|
||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
||||
// Case 2. Use Function which generate token.
|
||||
// String yourTokenGeneratorFunction() { ... }
|
||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||
|
||||
final api_instance = AssetApi();
|
||||
|
||||
try {
|
||||
final result = api_instance.getArchivedAssetCountByUserId();
|
||||
print(result);
|
||||
} catch (e) {
|
||||
print('Exception when calling AssetApi->getArchivedAssetCountByUserId: $e\n');
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
This endpoint does not need any parameter.
|
||||
|
||||
### Return type
|
||||
|
||||
[**AssetCountByUserIdResponseDto**](AssetCountByUserIdResponseDto.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **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)
|
||||
|
||||
# **getAssetById**
|
||||
> AssetResponseDto getAssetById(id, key)
|
||||
|
||||
|
@ -665,57 +613,6 @@ Name | Type | Description | Notes
|
|||
|
||||
[[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)
|
||||
|
||||
# **getAssetCountByUserId**
|
||||
> AssetCountByUserIdResponseDto getAssetCountByUserId()
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
```dart
|
||||
import 'package:openapi/api.dart';
|
||||
// TODO Configure API key authorization: cookie
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
||||
// TODO Configure API key authorization: api_key
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
||||
// TODO Configure HTTP Bearer authorization: bearer
|
||||
// Case 1. Use String Token
|
||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
||||
// Case 2. Use Function which generate token.
|
||||
// String yourTokenGeneratorFunction() { ... }
|
||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||
|
||||
final api_instance = AssetApi();
|
||||
|
||||
try {
|
||||
final result = api_instance.getAssetCountByUserId();
|
||||
print(result);
|
||||
} catch (e) {
|
||||
print('Exception when calling AssetApi->getAssetCountByUserId: $e\n');
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
This endpoint does not need any parameter.
|
||||
|
||||
### Return type
|
||||
|
||||
[**AssetCountByUserIdResponseDto**](AssetCountByUserIdResponseDto.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **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)
|
||||
|
||||
# **getAssetSearchTerms**
|
||||
> List<String> getAssetSearchTerms()
|
||||
|
||||
|
@ -767,6 +664,63 @@ 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)
|
||||
|
||||
# **getAssetStats**
|
||||
> AssetStatsResponseDto getAssetStats(isArchived, isFavorite)
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
```dart
|
||||
import 'package:openapi/api.dart';
|
||||
// TODO Configure API key authorization: cookie
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKey = 'YOUR_API_KEY';
|
||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('cookie').apiKeyPrefix = 'Bearer';
|
||||
// TODO Configure API key authorization: api_key
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKey = 'YOUR_API_KEY';
|
||||
// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
|
||||
//defaultApiClient.getAuthentication<ApiKeyAuth>('api_key').apiKeyPrefix = 'Bearer';
|
||||
// TODO Configure HTTP Bearer authorization: bearer
|
||||
// Case 1. Use String Token
|
||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken('YOUR_ACCESS_TOKEN');
|
||||
// Case 2. Use Function which generate token.
|
||||
// String yourTokenGeneratorFunction() { ... }
|
||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||
|
||||
final api_instance = AssetApi();
|
||||
final isArchived = true; // bool |
|
||||
final isFavorite = true; // bool |
|
||||
|
||||
try {
|
||||
final result = api_instance.getAssetStats(isArchived, isFavorite);
|
||||
print(result);
|
||||
} catch (e) {
|
||||
print('Exception when calling AssetApi->getAssetStats: $e\n');
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**isArchived** | **bool**| | [optional]
|
||||
**isFavorite** | **bool**| | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
[**AssetStatsResponseDto**](AssetStatsResponseDto.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer)
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **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)
|
||||
|
||||
# **getAssetThumbnail**
|
||||
> MultipartFile getAssetThumbnail(id, format, key)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# openapi.model.AssetCountByUserIdResponseDto
|
||||
# openapi.model.AssetStatsResponseDto
|
||||
|
||||
## Load the model package
|
||||
```dart
|
||||
|
@ -8,11 +8,9 @@ import 'package:openapi/api.dart';
|
|||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**audio** | **int** | | [default to 0]
|
||||
**photos** | **int** | | [default to 0]
|
||||
**videos** | **int** | | [default to 0]
|
||||
**other** | **int** | | [default to 0]
|
||||
**total** | **int** | | [default to 0]
|
||||
**images** | **int** | |
|
||||
**videos** | **int** | |
|
||||
**total** | **int** | |
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
2
mobile/openapi/lib/api.dart
generated
2
mobile/openapi/lib/api.dart
generated
|
@ -60,11 +60,11 @@ part 'model/asset_bulk_upload_check_response_dto.dart';
|
|||
part 'model/asset_bulk_upload_check_result.dart';
|
||||
part 'model/asset_count_by_time_bucket.dart';
|
||||
part 'model/asset_count_by_time_bucket_response_dto.dart';
|
||||
part 'model/asset_count_by_user_id_response_dto.dart';
|
||||
part 'model/asset_file_upload_response_dto.dart';
|
||||
part 'model/asset_ids_dto.dart';
|
||||
part 'model/asset_ids_response_dto.dart';
|
||||
part 'model/asset_response_dto.dart';
|
||||
part 'model/asset_stats_response_dto.dart';
|
||||
part 'model/asset_type_enum.dart';
|
||||
part 'model/audio_codec.dart';
|
||||
part 'model/auth_device_response_dto.dart';
|
||||
|
|
140
mobile/openapi/lib/api/asset_api.dart
generated
140
mobile/openapi/lib/api/asset_api.dart
generated
|
@ -440,47 +440,6 @@ class AssetApi {
|
|||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /asset/stat/archive' operation and returns the [Response].
|
||||
Future<Response> getArchivedAssetCountByUserIdWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/asset/stat/archive';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
Future<AssetCountByUserIdResponseDto?> getArchivedAssetCountByUserId() async {
|
||||
final response = await getArchivedAssetCountByUserIdWithHttpInfo();
|
||||
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), 'AssetCountByUserIdResponseDto',) as AssetCountByUserIdResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Get a single asset's information
|
||||
///
|
||||
/// Note: This method returns the HTTP [Response].
|
||||
|
@ -639,47 +598,6 @@ class AssetApi {
|
|||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /asset/count-by-user-id' operation and returns the [Response].
|
||||
Future<Response> getAssetCountByUserIdWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/asset/count-by-user-id';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
Future<AssetCountByUserIdResponseDto?> getAssetCountByUserId() async {
|
||||
final response = await getAssetCountByUserIdWithHttpInfo();
|
||||
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), 'AssetCountByUserIdResponseDto',) as AssetCountByUserIdResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /asset/search-terms' operation and returns the [Response].
|
||||
Future<Response> getAssetSearchTermsWithHttpInfo() async {
|
||||
// ignore: prefer_const_declarations
|
||||
|
@ -724,6 +642,64 @@ class AssetApi {
|
|||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /asset/statistics' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [bool] isArchived:
|
||||
///
|
||||
/// * [bool] isFavorite:
|
||||
Future<Response> getAssetStatsWithHttpInfo({ bool? isArchived, bool? isFavorite, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/asset/statistics';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
if (isArchived != null) {
|
||||
queryParams.addAll(_queryParams('', 'isArchived', isArchived));
|
||||
}
|
||||
if (isFavorite != null) {
|
||||
queryParams.addAll(_queryParams('', 'isFavorite', isFavorite));
|
||||
}
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
formParams,
|
||||
contentTypes.isEmpty ? null : contentTypes.first,
|
||||
);
|
||||
}
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [bool] isArchived:
|
||||
///
|
||||
/// * [bool] isFavorite:
|
||||
Future<AssetStatsResponseDto?> getAssetStats({ bool? isArchived, bool? isFavorite, }) async {
|
||||
final response = await getAssetStatsWithHttpInfo( isArchived: isArchived, isFavorite: isFavorite, );
|
||||
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), 'AssetStatsResponseDto',) as AssetStatsResponseDto;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /asset/thumbnail/{id}' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
|
|
4
mobile/openapi/lib/api_client.dart
generated
4
mobile/openapi/lib/api_client.dart
generated
|
@ -215,8 +215,6 @@ class ApiClient {
|
|||
return AssetCountByTimeBucket.fromJson(value);
|
||||
case 'AssetCountByTimeBucketResponseDto':
|
||||
return AssetCountByTimeBucketResponseDto.fromJson(value);
|
||||
case 'AssetCountByUserIdResponseDto':
|
||||
return AssetCountByUserIdResponseDto.fromJson(value);
|
||||
case 'AssetFileUploadResponseDto':
|
||||
return AssetFileUploadResponseDto.fromJson(value);
|
||||
case 'AssetIdsDto':
|
||||
|
@ -225,6 +223,8 @@ class ApiClient {
|
|||
return AssetIdsResponseDto.fromJson(value);
|
||||
case 'AssetResponseDto':
|
||||
return AssetResponseDto.fromJson(value);
|
||||
case 'AssetStatsResponseDto':
|
||||
return AssetStatsResponseDto.fromJson(value);
|
||||
case 'AssetTypeEnum':
|
||||
return AssetTypeEnumTypeTransformer().decode(value);
|
||||
case 'AudioCodec':
|
||||
|
|
|
@ -1,130 +0,0 @@
|
|||
//
|
||||
// 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 AssetCountByUserIdResponseDto {
|
||||
/// Returns a new [AssetCountByUserIdResponseDto] instance.
|
||||
AssetCountByUserIdResponseDto({
|
||||
this.audio = 0,
|
||||
this.photos = 0,
|
||||
this.videos = 0,
|
||||
this.other = 0,
|
||||
this.total = 0,
|
||||
});
|
||||
|
||||
int audio;
|
||||
|
||||
int photos;
|
||||
|
||||
int videos;
|
||||
|
||||
int other;
|
||||
|
||||
int total;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is AssetCountByUserIdResponseDto &&
|
||||
other.audio == audio &&
|
||||
other.photos == photos &&
|
||||
other.videos == videos &&
|
||||
other.other == other &&
|
||||
other.total == total;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(audio.hashCode) +
|
||||
(photos.hashCode) +
|
||||
(videos.hashCode) +
|
||||
(other.hashCode) +
|
||||
(total.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AssetCountByUserIdResponseDto[audio=$audio, photos=$photos, videos=$videos, other=$other, total=$total]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'audio'] = this.audio;
|
||||
json[r'photos'] = this.photos;
|
||||
json[r'videos'] = this.videos;
|
||||
json[r'other'] = this.other;
|
||||
json[r'total'] = this.total;
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [AssetCountByUserIdResponseDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static AssetCountByUserIdResponseDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return AssetCountByUserIdResponseDto(
|
||||
audio: mapValueOfType<int>(json, r'audio')!,
|
||||
photos: mapValueOfType<int>(json, r'photos')!,
|
||||
videos: mapValueOfType<int>(json, r'videos')!,
|
||||
other: mapValueOfType<int>(json, r'other')!,
|
||||
total: mapValueOfType<int>(json, r'total')!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<AssetCountByUserIdResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <AssetCountByUserIdResponseDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = AssetCountByUserIdResponseDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, AssetCountByUserIdResponseDto> mapFromJson(dynamic json) {
|
||||
final map = <String, AssetCountByUserIdResponseDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = AssetCountByUserIdResponseDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of AssetCountByUserIdResponseDto-objects as value to a dart map
|
||||
static Map<String, List<AssetCountByUserIdResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<AssetCountByUserIdResponseDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = AssetCountByUserIdResponseDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'audio',
|
||||
'photos',
|
||||
'videos',
|
||||
'other',
|
||||
'total',
|
||||
};
|
||||
}
|
||||
|
114
mobile/openapi/lib/model/asset_stats_response_dto.dart
generated
Normal file
114
mobile/openapi/lib/model/asset_stats_response_dto.dart
generated
Normal file
|
@ -0,0 +1,114 @@
|
|||
//
|
||||
// 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 AssetStatsResponseDto {
|
||||
/// Returns a new [AssetStatsResponseDto] instance.
|
||||
AssetStatsResponseDto({
|
||||
required this.images,
|
||||
required this.videos,
|
||||
required this.total,
|
||||
});
|
||||
|
||||
int images;
|
||||
|
||||
int videos;
|
||||
|
||||
int total;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is AssetStatsResponseDto &&
|
||||
other.images == images &&
|
||||
other.videos == videos &&
|
||||
other.total == total;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(images.hashCode) +
|
||||
(videos.hashCode) +
|
||||
(total.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'AssetStatsResponseDto[images=$images, videos=$videos, total=$total]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
json[r'images'] = this.images;
|
||||
json[r'videos'] = this.videos;
|
||||
json[r'total'] = this.total;
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [AssetStatsResponseDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static AssetStatsResponseDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return AssetStatsResponseDto(
|
||||
images: mapValueOfType<int>(json, r'images')!,
|
||||
videos: mapValueOfType<int>(json, r'videos')!,
|
||||
total: mapValueOfType<int>(json, r'total')!,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<AssetStatsResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <AssetStatsResponseDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = AssetStatsResponseDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, AssetStatsResponseDto> mapFromJson(dynamic json) {
|
||||
final map = <String, AssetStatsResponseDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = AssetStatsResponseDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of AssetStatsResponseDto-objects as value to a dart map
|
||||
static Map<String, List<AssetStatsResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<AssetStatsResponseDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = AssetStatsResponseDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'images',
|
||||
'videos',
|
||||
'total',
|
||||
};
|
||||
}
|
||||
|
13
mobile/openapi/test/asset_api_test.dart
generated
13
mobile/openapi/test/asset_api_test.dart
generated
|
@ -60,11 +60,6 @@ void main() {
|
|||
// TODO
|
||||
});
|
||||
|
||||
//Future<AssetCountByUserIdResponseDto> getArchivedAssetCountByUserId() async
|
||||
test('test getArchivedAssetCountByUserId', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// Get a single asset's information
|
||||
//
|
||||
//Future<AssetResponseDto> getAssetById(String id, { String key }) async
|
||||
|
@ -82,13 +77,13 @@ void main() {
|
|||
// TODO
|
||||
});
|
||||
|
||||
//Future<AssetCountByUserIdResponseDto> getAssetCountByUserId() async
|
||||
test('test getAssetCountByUserId', () async {
|
||||
//Future<List<String>> getAssetSearchTerms() async
|
||||
test('test getAssetSearchTerms', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
//Future<List<String>> getAssetSearchTerms() async
|
||||
test('test getAssetSearchTerms', () async {
|
||||
//Future<AssetStatsResponseDto> getAssetStats({ bool isArchived, bool isFavorite }) async
|
||||
test('test getAssetStats', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
|
|
|
@ -11,32 +11,22 @@
|
|||
import 'package:openapi/api.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
// tests for AssetCountByUserIdResponseDto
|
||||
// tests for AssetStatsResponseDto
|
||||
void main() {
|
||||
// final instance = AssetCountByUserIdResponseDto();
|
||||
// final instance = AssetStatsResponseDto();
|
||||
|
||||
group('test AssetCountByUserIdResponseDto', () {
|
||||
// int audio (default value: 0)
|
||||
test('to test the property `audio`', () async {
|
||||
group('test AssetStatsResponseDto', () {
|
||||
// int images
|
||||
test('to test the property `images`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int photos (default value: 0)
|
||||
test('to test the property `photos`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int videos (default value: 0)
|
||||
// int videos
|
||||
test('to test the property `videos`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int other (default value: 0)
|
||||
test('to test the property `other`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int total (default value: 0)
|
||||
// int total
|
||||
test('to test the property `total`', () async {
|
||||
// TODO
|
||||
});
|
|
@ -984,38 +984,6 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/asset/count-by-user-id": {
|
||||
"get": {
|
||||
"operationId": "getAssetCountByUserId",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AssetCountByUserIdResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Asset"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer": []
|
||||
},
|
||||
{
|
||||
"cookie": []
|
||||
},
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/asset/curated-locations": {
|
||||
"get": {
|
||||
"operationId": "getCuratedLocations",
|
||||
|
@ -1608,17 +1576,34 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/asset/stat/archive": {
|
||||
"/asset/statistics": {
|
||||
"get": {
|
||||
"operationId": "getArchivedAssetCountByUserId",
|
||||
"parameters": [],
|
||||
"operationId": "getAssetStats",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "isArchived",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isFavorite",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AssetCountByUserIdResponseDto"
|
||||
"$ref": "#/components/schemas/AssetStatsResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4786,38 +4771,6 @@
|
|||
"buckets"
|
||||
]
|
||||
},
|
||||
"AssetCountByUserIdResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"audio": {
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"photos": {
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"videos": {
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"other": {
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"audio",
|
||||
"photos",
|
||||
"videos",
|
||||
"other",
|
||||
"total"
|
||||
]
|
||||
},
|
||||
"AssetFileUploadResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -4970,6 +4923,25 @@
|
|||
"checksum"
|
||||
]
|
||||
},
|
||||
"AssetStatsResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"images": {
|
||||
"type": "integer"
|
||||
},
|
||||
"videos": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"images",
|
||||
"videos",
|
||||
"total"
|
||||
]
|
||||
},
|
||||
"AssetTypeEnum": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
import { AssetEntity, AssetType } from '@app/infra/entities';
|
||||
import { Paginated, PaginationOptions } from '../domain.util';
|
||||
|
||||
export type AssetStats = Record<AssetType, number>;
|
||||
|
||||
export interface AssetStatsOptions {
|
||||
isFavorite?: boolean;
|
||||
isArchived?: boolean;
|
||||
}
|
||||
|
||||
export interface AssetSearchOptions {
|
||||
isVisible?: boolean;
|
||||
type?: AssetType;
|
||||
|
@ -55,4 +62,5 @@ export interface IAssetRepository {
|
|||
save(asset: Partial<AssetEntity>): Promise<AssetEntity>;
|
||||
findLivePhotoMatch(options: LivePhotoSearchOptions): Promise<AssetEntity | null>;
|
||||
getMapMarkers(ownerId: string, options?: MapMarkerSearchOptions): Promise<MapMarker[]>;
|
||||
getStatistics(ownerId: string, options: AssetStatsOptions): Promise<AssetStats>;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { AssetType } from '@app/infra/entities';
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
import {
|
||||
assetEntityStub,
|
||||
|
@ -10,9 +11,9 @@ import {
|
|||
import { when } from 'jest-when';
|
||||
import { Readable } from 'stream';
|
||||
import { IStorageRepository } from '../storage';
|
||||
import { IAssetRepository } from './asset.repository';
|
||||
import { AssetStats, IAssetRepository } from './asset.repository';
|
||||
import { AssetService } from './asset.service';
|
||||
import { DownloadResponseDto } from './index';
|
||||
import { AssetStatsResponseDto, DownloadResponseDto } from './dto';
|
||||
import { mapAsset } from './response-dto';
|
||||
|
||||
const downloadResponse: DownloadResponseDto = {
|
||||
|
@ -25,6 +26,19 @@ const downloadResponse: DownloadResponseDto = {
|
|||
],
|
||||
};
|
||||
|
||||
const stats: AssetStats = {
|
||||
[AssetType.IMAGE]: 10,
|
||||
[AssetType.VIDEO]: 23,
|
||||
[AssetType.AUDIO]: 0,
|
||||
[AssetType.OTHER]: 0,
|
||||
};
|
||||
|
||||
const statResponse: AssetStatsResponseDto = {
|
||||
images: 10,
|
||||
videos: 23,
|
||||
total: 33,
|
||||
};
|
||||
|
||||
describe(AssetService.name, () => {
|
||||
let sut: AssetService;
|
||||
let accessMock: IAccessRepositoryMock;
|
||||
|
@ -287,4 +301,30 @@ describe(AssetService.name, () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getStatistics', () => {
|
||||
it('should get the statistics for a user, excluding archived assets', async () => {
|
||||
assetMock.getStatistics.mockResolvedValue(stats);
|
||||
await expect(sut.getStatistics(authStub.admin, { isArchived: false })).resolves.toEqual(statResponse);
|
||||
expect(assetMock.getStatistics).toHaveBeenCalledWith(authStub.admin.id, { isArchived: false });
|
||||
});
|
||||
|
||||
it('should get the statistics for a user for archived assets', async () => {
|
||||
assetMock.getStatistics.mockResolvedValue(stats);
|
||||
await expect(sut.getStatistics(authStub.admin, { isArchived: true })).resolves.toEqual(statResponse);
|
||||
expect(assetMock.getStatistics).toHaveBeenCalledWith(authStub.admin.id, { isArchived: true });
|
||||
});
|
||||
|
||||
it('should get the statistics for a user for favorite assets', async () => {
|
||||
assetMock.getStatistics.mockResolvedValue(stats);
|
||||
await expect(sut.getStatistics(authStub.admin, { isFavorite: true })).resolves.toEqual(statResponse);
|
||||
expect(assetMock.getStatistics).toHaveBeenCalledWith(authStub.admin.id, { isFavorite: true });
|
||||
});
|
||||
|
||||
it('should get the statistics for a user for all assets', async () => {
|
||||
assetMock.getStatistics.mockResolvedValue(stats);
|
||||
await expect(sut.getStatistics(authStub.admin, {})).resolves.toEqual(statResponse);
|
||||
expect(assetMock.getStatistics).toHaveBeenCalledWith(authStub.admin.id, {});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ import { HumanReadableSize, usePagination } from '../domain.util';
|
|||
import { ImmichReadStream, IStorageRepository } from '../storage';
|
||||
import { IAssetRepository } from './asset.repository';
|
||||
import { AssetIdsDto, DownloadArchiveInfo, DownloadDto, DownloadResponseDto, MemoryLaneDto } from './dto';
|
||||
import { AssetStatsDto, mapStats } from './dto/asset-statistics.dto';
|
||||
import { MapMarkerDto } from './dto/map-marker.dto';
|
||||
import { mapAsset, MapMarkerResponseDto } from './response-dto';
|
||||
import { MemoryLaneResponseDto } from './response-dto/memory-lane-response.dto';
|
||||
|
@ -155,4 +156,9 @@ export class AssetService {
|
|||
|
||||
throw new BadRequestException('assetIds, albumId, or userId is required');
|
||||
}
|
||||
|
||||
async getStatistics(authUser: AuthUserDto, dto: AssetStatsDto) {
|
||||
const stats = await this.assetRepository.getStatistics(authUser.id, dto);
|
||||
return mapStats(stats);
|
||||
}
|
||||
}
|
||||
|
|
37
server/src/domain/asset/dto/asset-statistics.dto.ts
Normal file
37
server/src/domain/asset/dto/asset-statistics.dto.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { AssetType } from '@app/infra/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform } from 'class-transformer';
|
||||
import { IsBoolean, IsOptional } from 'class-validator';
|
||||
import { toBoolean } from '../../domain.util';
|
||||
import { AssetStats } from '../asset.repository';
|
||||
|
||||
export class AssetStatsDto {
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@IsOptional()
|
||||
isArchived?: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
@IsOptional()
|
||||
isFavorite?: boolean;
|
||||
}
|
||||
|
||||
export class AssetStatsResponseDto {
|
||||
@ApiProperty({ type: 'integer' })
|
||||
images!: number;
|
||||
|
||||
@ApiProperty({ type: 'integer' })
|
||||
videos!: number;
|
||||
|
||||
@ApiProperty({ type: 'integer' })
|
||||
total!: number;
|
||||
}
|
||||
|
||||
export const mapStats = (stats: AssetStats): AssetStatsResponseDto => {
|
||||
return {
|
||||
images: stats[AssetType.IMAGE],
|
||||
videos: stats[AssetType.VIDEO],
|
||||
total: Object.values(stats).reduce((total, value) => total + value, 0),
|
||||
};
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
export * from './asset-ids.dto';
|
||||
export * from './asset-statistics.dto';
|
||||
export * from './download.dto';
|
||||
export * from './map-marker.dto';
|
||||
export * from './memory-lane.dto';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { AssetEntity, AssetType, ExifEntity } from '@app/infra/entities';
|
||||
import { AssetEntity, ExifEntity } from '@app/infra/entities';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { IsNull, Not } from 'typeorm';
|
||||
|
@ -11,7 +11,6 @@ import { GetAssetCountByTimeBucketDto, TimeGroupEnum } from './dto/get-asset-cou
|
|||
import { SearchPropertiesDto } from './dto/search-properties.dto';
|
||||
import { UpdateAssetDto } from './dto/update-asset.dto';
|
||||
import { AssetCountByTimeBucket } from './response-dto/asset-count-by-time-group-response.dto';
|
||||
import { AssetCountByUserIdResponseDto } from './response-dto/asset-count-by-user-id-response.dto';
|
||||
import { CuratedLocationsResponseDto } from './response-dto/curated-locations-response.dto';
|
||||
import { CuratedObjectsResponseDto } from './response-dto/curated-objects-response.dto';
|
||||
|
||||
|
@ -38,8 +37,6 @@ export interface IAssetRepository {
|
|||
getDetectedObjectsByUserId(userId: string): Promise<CuratedObjectsResponseDto[]>;
|
||||
getSearchPropertiesByUserId(userId: string): Promise<SearchPropertiesDto[]>;
|
||||
getAssetCountByTimeBucket(userId: string, dto: GetAssetCountByTimeBucketDto): Promise<AssetCountByTimeBucket[]>;
|
||||
getAssetCountByUserId(userId: string): Promise<AssetCountByUserIdResponseDto>;
|
||||
getArchivedAssetCountByUserId(userId: string): Promise<AssetCountByUserIdResponseDto>;
|
||||
getAssetByTimeBucket(userId: string, getAssetByTimeBucketDto: GetAssetByTimeBucketDto): Promise<AssetEntity[]>;
|
||||
getAssetsByChecksums(userId: string, checksums: Buffer[]): Promise<AssetCheck[]>;
|
||||
getExistingAssets(userId: string, checkDuplicateAssetDto: CheckExistingAssetsDto): Promise<string[]>;
|
||||
|
@ -55,35 +52,6 @@ export class AssetRepository implements IAssetRepository {
|
|||
@InjectRepository(ExifEntity) private exifRepository: Repository<ExifEntity>,
|
||||
) {}
|
||||
|
||||
async getAssetCountByUserId(ownerId: string): Promise<AssetCountByUserIdResponseDto> {
|
||||
// Get asset count by AssetType
|
||||
const items = await this.assetRepository
|
||||
.createQueryBuilder('asset')
|
||||
.select(`COUNT(asset.id)`, 'count')
|
||||
.addSelect(`asset.type`, 'type')
|
||||
.where('"ownerId" = :ownerId', { ownerId: ownerId })
|
||||
.andWhere('asset.isVisible = true')
|
||||
.groupBy('asset.type')
|
||||
.getRawMany();
|
||||
|
||||
return this.getAssetCount(items);
|
||||
}
|
||||
|
||||
async getArchivedAssetCountByUserId(ownerId: string): Promise<AssetCountByUserIdResponseDto> {
|
||||
// Get archived asset count by AssetType
|
||||
const items = await this.assetRepository
|
||||
.createQueryBuilder('asset')
|
||||
.select(`COUNT(asset.id)`, 'count')
|
||||
.addSelect(`asset.type`, 'type')
|
||||
.where('"ownerId" = :ownerId', { ownerId: ownerId })
|
||||
.andWhere('asset.isVisible = true')
|
||||
.andWhere('asset.isArchived = true')
|
||||
.groupBy('asset.type')
|
||||
.getRawMany();
|
||||
|
||||
return this.getAssetCount(items);
|
||||
}
|
||||
|
||||
async getAssetByTimeBucket(userId: string, dto: GetAssetByTimeBucketDto): Promise<AssetEntity[]> {
|
||||
// Get asset entity from a list of time buckets
|
||||
let builder = this.assetRepository
|
||||
|
@ -337,29 +305,6 @@ export class AssetRepository implements IAssetRepository {
|
|||
return assets.map((asset) => asset.deviceAssetId);
|
||||
}
|
||||
|
||||
private getAssetCount(items: any): AssetCountByUserIdResponseDto {
|
||||
const assetCountByUserId = new AssetCountByUserIdResponseDto();
|
||||
|
||||
// asset type to dto property mapping
|
||||
const map: Record<AssetType, keyof AssetCountByUserIdResponseDto> = {
|
||||
[AssetType.AUDIO]: 'audio',
|
||||
[AssetType.IMAGE]: 'photos',
|
||||
[AssetType.VIDEO]: 'videos',
|
||||
[AssetType.OTHER]: 'other',
|
||||
};
|
||||
|
||||
for (const item of items) {
|
||||
const count = Number(item.count) || 0;
|
||||
const assetType = item.type as AssetType;
|
||||
const type = map[assetType];
|
||||
|
||||
assetCountByUserId[type] = count;
|
||||
assetCountByUserId.total += count;
|
||||
}
|
||||
|
||||
return assetCountByUserId;
|
||||
}
|
||||
|
||||
getByOriginalPath(originalPath: string): Promise<AssetOwnerCheck | null> {
|
||||
return this.assetRepository.findOne({
|
||||
select: {
|
||||
|
|
|
@ -38,7 +38,6 @@ import { ServeFileDto } from './dto/serve-file.dto';
|
|||
import { UpdateAssetDto } from './dto/update-asset.dto';
|
||||
import { AssetBulkUploadCheckResponseDto } from './response-dto/asset-check-response.dto';
|
||||
import { AssetCountByTimeBucketResponseDto } from './response-dto/asset-count-by-time-group-response.dto';
|
||||
import { AssetCountByUserIdResponseDto } from './response-dto/asset-count-by-user-id-response.dto';
|
||||
import { AssetFileUploadResponseDto } from './response-dto/asset-file-upload-response.dto';
|
||||
import { CheckDuplicateAssetResponseDto } from './response-dto/check-duplicate-asset-response.dto';
|
||||
import { CheckExistingAssetsResponseDto } from './response-dto/check-existing-assets-response.dto';
|
||||
|
@ -173,15 +172,6 @@ export class AssetController {
|
|||
return this.assetService.getAssetCountByTimeBucket(authUser, dto);
|
||||
}
|
||||
|
||||
@Get('/count-by-user-id')
|
||||
getAssetCountByUserId(@AuthUser() authUser: AuthUserDto): Promise<AssetCountByUserIdResponseDto> {
|
||||
return this.assetService.getAssetCountByUserId(authUser);
|
||||
}
|
||||
|
||||
@Get('/stat/archive')
|
||||
getArchivedAssetCountByUserId(@AuthUser() authUser: AuthUserDto): Promise<AssetCountByUserIdResponseDto> {
|
||||
return this.assetService.getArchivedAssetCountByUserId(authUser);
|
||||
}
|
||||
/**
|
||||
* Get all AssetEntity belong to the user
|
||||
*/
|
||||
|
|
|
@ -26,7 +26,6 @@ import { CreateAssetDto } from './dto/create-asset.dto';
|
|||
import { TimeGroupEnum } from './dto/get-asset-count-by-time-bucket.dto';
|
||||
import { AssetRejectReason, AssetUploadAction } from './response-dto/asset-check-response.dto';
|
||||
import { AssetCountByTimeBucket } from './response-dto/asset-count-by-time-group-response.dto';
|
||||
import { AssetCountByUserIdResponseDto } from './response-dto/asset-count-by-user-id-response.dto';
|
||||
|
||||
const _getCreateAssetDto = (): CreateAssetDto => {
|
||||
const createAssetDto = new CreateAssetDto();
|
||||
|
@ -103,24 +102,6 @@ const _getAssetCountByTimeBucket = (): AssetCountByTimeBucket[] => {
|
|||
return [result1, result2];
|
||||
};
|
||||
|
||||
const _getAssetCountByUserId = (): AssetCountByUserIdResponseDto => {
|
||||
const result = new AssetCountByUserIdResponseDto();
|
||||
|
||||
result.videos = 2;
|
||||
result.photos = 2;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const _getArchivedAssetsCountByUserId = (): AssetCountByUserIdResponseDto => {
|
||||
const result = new AssetCountByUserIdResponseDto();
|
||||
|
||||
result.videos = 1;
|
||||
result.photos = 2;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const uploadFile = {
|
||||
nullAuth: {
|
||||
authUser: null,
|
||||
|
@ -197,8 +178,6 @@ describe('AssetService', () => {
|
|||
getSearchPropertiesByUserId: jest.fn(),
|
||||
getAssetByTimeBucket: jest.fn(),
|
||||
getAssetsByChecksums: jest.fn(),
|
||||
getAssetCountByUserId: jest.fn(),
|
||||
getArchivedAssetCountByUserId: jest.fn(),
|
||||
getExistingAssets: jest.fn(),
|
||||
getByOriginalPath: jest.fn(),
|
||||
};
|
||||
|
@ -467,20 +446,6 @@ describe('AssetService', () => {
|
|||
expect(result.buckets.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('get asset count by user id', async () => {
|
||||
const assetCount = _getAssetCountByUserId();
|
||||
assetRepositoryMock.getAssetCountByUserId.mockResolvedValue(assetCount);
|
||||
|
||||
await expect(sut.getAssetCountByUserId(authStub.user1)).resolves.toEqual(assetCount);
|
||||
});
|
||||
|
||||
it('get archived asset count by user id', async () => {
|
||||
const assetCount = _getArchivedAssetsCountByUserId();
|
||||
assetRepositoryMock.getArchivedAssetCountByUserId.mockResolvedValue(assetCount);
|
||||
|
||||
await expect(sut.getArchivedAssetCountByUserId(authStub.user1)).resolves.toEqual(assetCount);
|
||||
});
|
||||
|
||||
describe('deleteAll', () => {
|
||||
it('should return failed status when an asset is missing', async () => {
|
||||
assetRepositoryMock.get.mockResolvedValue(null);
|
||||
|
|
|
@ -58,7 +58,6 @@ import {
|
|||
AssetCountByTimeBucketResponseDto,
|
||||
mapAssetCountByTimeBucket,
|
||||
} from './response-dto/asset-count-by-time-group-response.dto';
|
||||
import { AssetCountByUserIdResponseDto } from './response-dto/asset-count-by-user-id-response.dto';
|
||||
import { AssetFileUploadResponseDto } from './response-dto/asset-file-upload-response.dto';
|
||||
import { CheckDuplicateAssetResponseDto } from './response-dto/check-duplicate-asset-response.dto';
|
||||
import { CheckExistingAssetsResponseDto } from './response-dto/check-existing-assets-response.dto';
|
||||
|
@ -536,14 +535,6 @@ export class AssetService {
|
|||
return mapAssetCountByTimeBucket(result);
|
||||
}
|
||||
|
||||
getAssetCountByUserId(authUser: AuthUserDto): Promise<AssetCountByUserIdResponseDto> {
|
||||
return this._assetRepository.getAssetCountByUserId(authUser.id);
|
||||
}
|
||||
|
||||
getArchivedAssetCountByUserId(authUser: AuthUserDto): Promise<AssetCountByUserIdResponseDto> {
|
||||
return this._assetRepository.getArchivedAssetCountByUserId(authUser.id);
|
||||
}
|
||||
|
||||
getExifPermission(authUser: AuthUserDto) {
|
||||
return !authUser.isPublicUser || authUser.isShowExif;
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class AssetCountByUserIdResponseDto {
|
||||
@ApiProperty({ type: 'integer' })
|
||||
audio = 0;
|
||||
|
||||
@ApiProperty({ type: 'integer' })
|
||||
photos = 0;
|
||||
|
||||
@ApiProperty({ type: 'integer' })
|
||||
videos = 0;
|
||||
|
||||
@ApiProperty({ type: 'integer' })
|
||||
other = 0;
|
||||
|
||||
@ApiProperty({ type: 'integer' })
|
||||
total = 0;
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
import {
|
||||
AssetIdsDto,
|
||||
AssetService,
|
||||
AssetStatsDto,
|
||||
AssetStatsResponseDto,
|
||||
AuthUserDto,
|
||||
DownloadDto,
|
||||
DownloadResponseDto,
|
||||
|
@ -53,4 +55,9 @@ export class AssetController {
|
|||
downloadFile(@AuthUser() authUser: AuthUserDto, @Param() { id }: UUIDParamDto) {
|
||||
return this.service.downloadFile(authUser, id).then(asStreamableFile);
|
||||
}
|
||||
|
||||
@Get('statistics')
|
||||
getAssetStats(@AuthUser() authUser: AuthUserDto, @Query() dto: AssetStatsDto): Promise<AssetStatsResponseDto> {
|
||||
return this.service.getStatistics(authUser, dto);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import {
|
||||
AssetSearchOptions,
|
||||
AssetStats,
|
||||
AssetStatsOptions,
|
||||
IAssetRepository,
|
||||
LivePhotoSearchOptions,
|
||||
MapMarker,
|
||||
|
@ -321,4 +323,38 @@ export class AssetRepository implements IAssetRepository {
|
|||
lon: asset.exifInfo!.longitude!,
|
||||
}));
|
||||
}
|
||||
|
||||
async getStatistics(ownerId: string, options: AssetStatsOptions): Promise<AssetStats> {
|
||||
let builder = await this.repository
|
||||
.createQueryBuilder('asset')
|
||||
.select(`COUNT(asset.id)`, 'count')
|
||||
.addSelect(`asset.type`, 'type')
|
||||
.where('"ownerId" = :ownerId', { ownerId })
|
||||
.andWhere('asset.isVisible = true')
|
||||
.groupBy('asset.type');
|
||||
|
||||
const { isArchived, isFavorite } = options;
|
||||
if (isArchived !== undefined) {
|
||||
builder = builder.andWhere(`asset.isArchived = :isArchived`, { isArchived });
|
||||
}
|
||||
|
||||
if (isFavorite !== undefined) {
|
||||
builder = builder.andWhere(`asset.isFavorite = :isFavorite`, { isFavorite });
|
||||
}
|
||||
|
||||
const items = await builder.getRawMany();
|
||||
|
||||
const result: AssetStats = {
|
||||
[AssetType.AUDIO]: 0,
|
||||
[AssetType.IMAGE]: 0,
|
||||
[AssetType.VIDEO]: 0,
|
||||
[AssetType.OTHER]: 0,
|
||||
};
|
||||
|
||||
for (const item of items) {
|
||||
result[item.type as AssetType] = Number(item.count) || 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,5 +18,6 @@ export const newAssetRepositoryMock = (): jest.Mocked<IAssetRepository> => {
|
|||
save: jest.fn(),
|
||||
findLivePhotoMatch: jest.fn(),
|
||||
getMapMarkers: jest.fn(),
|
||||
getStatistics: jest.fn(),
|
||||
};
|
||||
};
|
||||
|
|
195
web/src/api/open-api/api.ts
generated
195
web/src/api/open-api/api.ts
generated
|
@ -486,43 +486,6 @@ export interface AssetCountByTimeBucketResponseDto {
|
|||
*/
|
||||
'buckets': Array<AssetCountByTimeBucket>;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface AssetCountByUserIdResponseDto
|
||||
*/
|
||||
export interface AssetCountByUserIdResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetCountByUserIdResponseDto
|
||||
*/
|
||||
'audio': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetCountByUserIdResponseDto
|
||||
*/
|
||||
'photos': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetCountByUserIdResponseDto
|
||||
*/
|
||||
'videos': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetCountByUserIdResponseDto
|
||||
*/
|
||||
'other': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetCountByUserIdResponseDto
|
||||
*/
|
||||
'total': number;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
@ -724,6 +687,31 @@ export interface AssetResponseDto {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface AssetStatsResponseDto
|
||||
*/
|
||||
export interface AssetStatsResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetStatsResponseDto
|
||||
*/
|
||||
'images': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetStatsResponseDto
|
||||
*/
|
||||
'videos': number;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AssetStatsResponseDto
|
||||
*/
|
||||
'total': number;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
|
@ -4901,44 +4889,6 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
|||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getArchivedAssetCountByUserId: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/asset/stat/archive`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
|
||||
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication cookie required
|
||||
|
||||
// authentication api_key required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration)
|
||||
|
||||
// authentication bearer required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
@ -5088,8 +5038,8 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
|||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getAssetCountByUserId: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/asset/count-by-user-id`;
|
||||
getAssetSearchTerms: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/asset/search-terms`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
|
@ -5123,11 +5073,13 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
|||
},
|
||||
/**
|
||||
*
|
||||
* @param {boolean} [isArchived]
|
||||
* @param {boolean} [isFavorite]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getAssetSearchTerms: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/asset/search-terms`;
|
||||
getAssetStats: async (isArchived?: boolean, isFavorite?: boolean, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/asset/statistics`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
|
@ -5148,6 +5100,14 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
|
|||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
if (isArchived !== undefined) {
|
||||
localVarQueryParameter['isArchived'] = isArchived;
|
||||
}
|
||||
|
||||
if (isFavorite !== undefined) {
|
||||
localVarQueryParameter['isFavorite'] = isFavorite;
|
||||
}
|
||||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
|
@ -5896,15 +5856,6 @@ export const AssetApiFp = function(configuration?: Configuration) {
|
|||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAllAssets(userId, isFavorite, isArchived, withoutThumbs, skip, ifNoneMatch, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getArchivedAssetCountByUserId(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AssetCountByUserIdResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getArchivedAssetCountByUserId(options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
* Get a single asset\'s information
|
||||
* @param {string} id
|
||||
|
@ -5941,17 +5892,19 @@ export const AssetApiFp = function(configuration?: Configuration) {
|
|||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getAssetCountByUserId(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AssetCountByUserIdResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetCountByUserId(options);
|
||||
async getAssetSearchTerms(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<string>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetSearchTerms(options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {boolean} [isArchived]
|
||||
* @param {boolean} [isFavorite]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async getAssetSearchTerms(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<string>>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetSearchTerms(options);
|
||||
async getAssetStats(isArchived?: boolean, isFavorite?: boolean, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<AssetStatsResponseDto>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetStats(isArchived, isFavorite, options);
|
||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||
},
|
||||
/**
|
||||
|
@ -6177,14 +6130,6 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath
|
|||
getAllAssets(userId?: string, isFavorite?: boolean, isArchived?: boolean, withoutThumbs?: boolean, skip?: number, ifNoneMatch?: string, options?: any): AxiosPromise<Array<AssetResponseDto>> {
|
||||
return localVarFp.getAllAssets(userId, isFavorite, isArchived, withoutThumbs, skip, ifNoneMatch, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getArchivedAssetCountByUserId(options?: any): AxiosPromise<AssetCountByUserIdResponseDto> {
|
||||
return localVarFp.getArchivedAssetCountByUserId(options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Get a single asset\'s information
|
||||
* @param {string} id
|
||||
|
@ -6218,16 +6163,18 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath
|
|||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getAssetCountByUserId(options?: any): AxiosPromise<AssetCountByUserIdResponseDto> {
|
||||
return localVarFp.getAssetCountByUserId(options).then((request) => request(axios, basePath));
|
||||
getAssetSearchTerms(options?: any): AxiosPromise<Array<string>> {
|
||||
return localVarFp.getAssetSearchTerms(options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @param {boolean} [isArchived]
|
||||
* @param {boolean} [isFavorite]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
getAssetSearchTerms(options?: any): AxiosPromise<Array<string>> {
|
||||
return localVarFp.getAssetSearchTerms(options).then((request) => request(axios, basePath));
|
||||
getAssetStats(isArchived?: boolean, isFavorite?: boolean, options?: any): AxiosPromise<AssetStatsResponseDto> {
|
||||
return localVarFp.getAssetStats(isArchived, isFavorite, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
|
@ -6565,6 +6512,27 @@ export interface AssetApiGetAssetCountByTimeBucketRequest {
|
|||
readonly getAssetCountByTimeBucketDto: GetAssetCountByTimeBucketDto
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for getAssetStats operation in AssetApi.
|
||||
* @export
|
||||
* @interface AssetApiGetAssetStatsRequest
|
||||
*/
|
||||
export interface AssetApiGetAssetStatsRequest {
|
||||
/**
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof AssetApiGetAssetStats
|
||||
*/
|
||||
readonly isArchived?: boolean
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof AssetApiGetAssetStats
|
||||
*/
|
||||
readonly isFavorite?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Request parameters for getAssetThumbnail operation in AssetApi.
|
||||
* @export
|
||||
|
@ -6957,16 +6925,6 @@ export class AssetApi extends BaseAPI {
|
|||
return AssetApiFp(this.configuration).getAllAssets(requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.withoutThumbs, requestParameters.skip, requestParameters.ifNoneMatch, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof AssetApi
|
||||
*/
|
||||
public getArchivedAssetCountByUserId(options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getArchivedAssetCountByUserId(options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single asset\'s information
|
||||
* @param {AssetApiGetAssetByIdRequest} requestParameters Request parameters.
|
||||
|
@ -7006,18 +6964,19 @@ export class AssetApi extends BaseAPI {
|
|||
* @throws {RequiredError}
|
||||
* @memberof AssetApi
|
||||
*/
|
||||
public getAssetCountByUserId(options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getAssetCountByUserId(options).then((request) => request(this.axios, this.basePath));
|
||||
public getAssetSearchTerms(options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getAssetSearchTerms(options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {AssetApiGetAssetStatsRequest} requestParameters Request parameters.
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof AssetApi
|
||||
*/
|
||||
public getAssetSearchTerms(options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getAssetSearchTerms(options).then((request) => request(this.axios, this.basePath));
|
||||
public getAssetStats(requestParameters: AssetApiGetAssetStatsRequest = {}, options?: AxiosRequestConfig) {
|
||||
return AssetApiFp(this.configuration).getAssetStats(requestParameters.isArchived, requestParameters.isFavorite, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { api } from '@api';
|
||||
import { AssetApiGetAssetStatsRequest, api } from '@api';
|
||||
import AccountMultipleOutline from 'svelte-material-icons/AccountMultipleOutline.svelte';
|
||||
import AccountMultiple from 'svelte-material-icons/AccountMultiple.svelte';
|
||||
import ImageAlbum from 'svelte-material-icons/ImageAlbum.svelte';
|
||||
|
@ -18,31 +18,9 @@
|
|||
import { locale } from '$lib/stores/preferences.store';
|
||||
import SideBarSection from './side-bar-section.svelte';
|
||||
|
||||
const getAssetCount = async () => {
|
||||
const { data: allAssetCount } = await api.assetApi.getAssetCountByUserId();
|
||||
const { data: archivedCount } = await api.assetApi.getArchivedAssetCountByUserId();
|
||||
|
||||
return {
|
||||
videos: allAssetCount.videos - archivedCount.videos,
|
||||
photos: allAssetCount.photos - archivedCount.photos,
|
||||
};
|
||||
};
|
||||
|
||||
const getFavoriteCount = async () => {
|
||||
try {
|
||||
const { data: assets } = await api.assetApi.getAllAssets({
|
||||
isFavorite: true,
|
||||
withoutThumbs: true,
|
||||
});
|
||||
|
||||
return {
|
||||
favorites: assets.length,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
favorites: 0,
|
||||
};
|
||||
}
|
||||
const getStats = async (dto: AssetApiGetAssetStatsRequest) => {
|
||||
const { data: stats } = await api.assetApi.getAssetStats(dto);
|
||||
return stats;
|
||||
};
|
||||
|
||||
const getAlbumCount = async () => {
|
||||
|
@ -54,22 +32,6 @@
|
|||
}
|
||||
};
|
||||
|
||||
const getArchivedAssetsCount = async () => {
|
||||
try {
|
||||
const { data: assetCount } = await api.assetApi.getArchivedAssetCountByUserId();
|
||||
|
||||
return {
|
||||
videos: assetCount.videos,
|
||||
photos: assetCount.photos,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
videos: 0,
|
||||
photos: 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const isFavoritesSelected = $page.route.id === '/(user)/favorites';
|
||||
const isPhotosSelected = $page.route.id === '/(user)/photos';
|
||||
const isSharingSelected = $page.route.id === '/(user)/sharing';
|
||||
|
@ -83,12 +45,12 @@
|
|||
isSelected={isPhotosSelected}
|
||||
>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
{#await getAssetCount()}
|
||||
{#await getStats({ isArchived: false })}
|
||||
<LoadingSpinner />
|
||||
{:then data}
|
||||
<div>
|
||||
<p>{data.videos.toLocaleString($locale)} Videos</p>
|
||||
<p>{data.photos.toLocaleString($locale)} Photos</p>
|
||||
<p>{data.images.toLocaleString($locale)} Photos</p>
|
||||
</div>
|
||||
{/await}
|
||||
</svelte:fragment>
|
||||
|
@ -129,11 +91,12 @@
|
|||
isSelected={isFavoritesSelected}
|
||||
>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
{#await getFavoriteCount()}
|
||||
{#await getStats({ isFavorite: true })}
|
||||
<LoadingSpinner />
|
||||
{:then data}
|
||||
<div>
|
||||
<p>{data.favorites} Favorites</p>
|
||||
<p>{data.videos.toLocaleString($locale)} Videos</p>
|
||||
<p>{data.images.toLocaleString($locale)} Photos</p>
|
||||
</div>
|
||||
{/await}
|
||||
</svelte:fragment>
|
||||
|
@ -155,12 +118,12 @@
|
|||
<a data-sveltekit-preload-data="hover" href={AppRoute.ARCHIVE} draggable="false">
|
||||
<SideBarButton title="Archive" logo={ArchiveArrowDownOutline} isSelected={$page.route.id === '/(user)/archive'}>
|
||||
<svelte:fragment slot="moreInformation">
|
||||
{#await getArchivedAssetsCount()}
|
||||
{#await getStats({ isArchived: true })}
|
||||
<LoadingSpinner />
|
||||
{:then data}
|
||||
<div>
|
||||
<p>{data.videos.toLocaleString($locale)} Videos</p>
|
||||
<p>{data.photos.toLocaleString($locale)} Photos</p>
|
||||
<p>{data.images.toLocaleString($locale)} Photos</p>
|
||||
</div>
|
||||
{/await}
|
||||
</svelte:fragment>
|
||||
|
|
|
@ -10,22 +10,22 @@
|
|||
import AssetGrid from '$lib/components/photos-page/asset-grid.svelte';
|
||||
import AssetSelectContextMenu from '$lib/components/photos-page/asset-select-context-menu.svelte';
|
||||
import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte';
|
||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||
import { assetInteractionStore, isMultiSelectStoreState, selectedAssets } from '$lib/stores/asset-interaction.store';
|
||||
import { assetStore } from '$lib/stores/assets.store';
|
||||
import { openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||
import { api } from '@api';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
|
||||
import Plus from 'svelte-material-icons/Plus.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { api } from '@api';
|
||||
import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
|
||||
import { openFileUploadDialog } from '$lib/utils/file-uploader';
|
||||
|
||||
export let data: PageData;
|
||||
let assetCount = 1;
|
||||
|
||||
onMount(async () => {
|
||||
const { data: allAssetCount } = await api.assetApi.getAssetCountByUserId();
|
||||
assetCount = allAssetCount.total;
|
||||
const { data: stats } = await api.assetApi.getAssetStats();
|
||||
assetCount = stats.total;
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
|
|
Loading…
Add table
Reference in a new issue