chore(server): remove old asset search (#9104)

* chore(server): remove old asset search

* chore: remove more unused search code
This commit is contained in:
Jason Rasmussen 2024-04-27 08:57:39 -04:00 committed by GitHub
parent 0c60aaf557
commit 5a49de5592
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 30 additions and 1801 deletions

View File

@ -104,7 +104,6 @@ Class | Method | HTTP request | Description
*AssetApi* | [**getMemoryLane**](doc//AssetApi.md#getmemorylane) | **GET** /asset/memory-lane |
*AssetApi* | [**getRandom**](doc//AssetApi.md#getrandom) | **GET** /asset/random |
*AssetApi* | [**runAssetJobs**](doc//AssetApi.md#runassetjobs) | **POST** /asset/jobs |
*AssetApi* | [**searchAssets**](doc//AssetApi.md#searchassets) | **GET** /assets |
*AssetApi* | [**serveFile**](doc//AssetApi.md#servefile) | **GET** /asset/file/{id} |
*AssetApi* | [**updateAsset**](doc//AssetApi.md#updateasset) | **PUT** /asset/{id} |
*AssetApi* | [**updateAssets**](doc//AssetApi.md#updateassets) | **PUT** /asset |
@ -164,7 +163,6 @@ Class | Method | HTTP request | Description
*SearchApi* | [**getAssetsByCity**](doc//SearchApi.md#getassetsbycity) | **GET** /search/cities |
*SearchApi* | [**getExploreData**](doc//SearchApi.md#getexploredata) | **GET** /search/explore |
*SearchApi* | [**getSearchSuggestions**](doc//SearchApi.md#getsearchsuggestions) | **GET** /search/suggestions |
*SearchApi* | [**search**](doc//SearchApi.md#search) | **GET** /search |
*SearchApi* | [**searchMetadata**](doc//SearchApi.md#searchmetadata) | **POST** /search/metadata |
*SearchApi* | [**searchPerson**](doc//SearchApi.md#searchperson) | **GET** /search/person |
*SearchApi* | [**searchPlaces**](doc//SearchApi.md#searchplaces) | **GET** /search/places |

View File

@ -21,7 +21,6 @@ Method | HTTP request | Description
[**getMemoryLane**](AssetApi.md#getmemorylane) | **GET** /asset/memory-lane |
[**getRandom**](AssetApi.md#getrandom) | **GET** /asset/random |
[**runAssetJobs**](AssetApi.md#runassetjobs) | **POST** /asset/jobs |
[**searchAssets**](AssetApi.md#searchassets) | **GET** /assets |
[**serveFile**](AssetApi.md#servefile) | **GET** /asset/file/{id} |
[**updateAsset**](AssetApi.md#updateasset) | **PUT** /asset/{id} |
[**updateAssets**](AssetApi.md#updateassets) | **PUT** /asset |
@ -729,149 +728,6 @@ void (empty response body)
[[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)
# **searchAssets**
> List<AssetResponseDto> searchAssets(checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isNotInAlbum, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, personIds, previewPath, resizePath, size, state, takenAfter, takenBefore, thumbnailPath, trashedAfter, trashedBefore, type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked)
### 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 checksum = checksum_example; // String |
final city = city_example; // String |
final country = country_example; // String |
final createdAfter = 2013-10-20T19:20:30+01:00; // DateTime |
final createdBefore = 2013-10-20T19:20:30+01:00; // DateTime |
final deviceAssetId = deviceAssetId_example; // String |
final deviceId = deviceId_example; // String |
final encodedVideoPath = encodedVideoPath_example; // String |
final id = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String |
final isArchived = true; // bool |
final isEncoded = true; // bool |
final isExternal = true; // bool |
final isFavorite = true; // bool |
final isMotion = true; // bool |
final isNotInAlbum = true; // bool |
final isOffline = true; // bool |
final isReadOnly = true; // bool |
final isVisible = true; // bool |
final lensModel = lensModel_example; // String |
final libraryId = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String |
final make = make_example; // String |
final model = model_example; // String |
final order = ; // AssetOrder |
final originalFileName = originalFileName_example; // String |
final originalPath = originalPath_example; // String |
final page = 8.14; // num |
final personIds = []; // List<String> |
final previewPath = previewPath_example; // String |
final resizePath = resizePath_example; // String |
final size = 8.14; // num |
final state = state_example; // String |
final takenAfter = 2013-10-20T19:20:30+01:00; // DateTime |
final takenBefore = 2013-10-20T19:20:30+01:00; // DateTime |
final thumbnailPath = thumbnailPath_example; // String |
final trashedAfter = 2013-10-20T19:20:30+01:00; // DateTime |
final trashedBefore = 2013-10-20T19:20:30+01:00; // DateTime |
final type = ; // AssetTypeEnum |
final updatedAfter = 2013-10-20T19:20:30+01:00; // DateTime |
final updatedBefore = 2013-10-20T19:20:30+01:00; // DateTime |
final webpPath = webpPath_example; // String |
final withArchived = true; // bool |
final withDeleted = true; // bool |
final withExif = true; // bool |
final withPeople = true; // bool |
final withStacked = true; // bool |
try {
final result = api_instance.searchAssets(checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isNotInAlbum, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, personIds, previewPath, resizePath, size, state, takenAfter, takenBefore, thumbnailPath, trashedAfter, trashedBefore, type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked);
print(result);
} catch (e) {
print('Exception when calling AssetApi->searchAssets: $e\n');
}
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**checksum** | **String**| | [optional]
**city** | **String**| | [optional]
**country** | **String**| | [optional]
**createdAfter** | **DateTime**| | [optional]
**createdBefore** | **DateTime**| | [optional]
**deviceAssetId** | **String**| | [optional]
**deviceId** | **String**| | [optional]
**encodedVideoPath** | **String**| | [optional]
**id** | **String**| | [optional]
**isArchived** | **bool**| | [optional]
**isEncoded** | **bool**| | [optional]
**isExternal** | **bool**| | [optional]
**isFavorite** | **bool**| | [optional]
**isMotion** | **bool**| | [optional]
**isNotInAlbum** | **bool**| | [optional]
**isOffline** | **bool**| | [optional]
**isReadOnly** | **bool**| | [optional]
**isVisible** | **bool**| | [optional]
**lensModel** | **String**| | [optional]
**libraryId** | **String**| | [optional]
**make** | **String**| | [optional]
**model** | **String**| | [optional]
**order** | [**AssetOrder**](.md)| | [optional]
**originalFileName** | **String**| | [optional]
**originalPath** | **String**| | [optional]
**page** | **num**| | [optional]
**personIds** | [**List<String>**](String.md)| | [optional] [default to const []]
**previewPath** | **String**| | [optional]
**resizePath** | **String**| | [optional]
**size** | **num**| | [optional]
**state** | **String**| | [optional]
**takenAfter** | **DateTime**| | [optional]
**takenBefore** | **DateTime**| | [optional]
**thumbnailPath** | **String**| | [optional]
**trashedAfter** | **DateTime**| | [optional]
**trashedBefore** | **DateTime**| | [optional]
**type** | [**AssetTypeEnum**](.md)| | [optional]
**updatedAfter** | **DateTime**| | [optional]
**updatedBefore** | **DateTime**| | [optional]
**webpPath** | **String**| | [optional]
**withArchived** | **bool**| | [optional] [default to false]
**withDeleted** | **bool**| | [optional]
**withExif** | **bool**| | [optional]
**withPeople** | **bool**| | [optional]
**withStacked** | **bool**| | [optional]
### Return type
[**List<AssetResponseDto>**](AssetResponseDto.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)
# **serveFile**
> MultipartFile serveFile(id, isThumb, isWeb, key)

View File

@ -12,7 +12,6 @@ Method | HTTP request | Description
[**getAssetsByCity**](SearchApi.md#getassetsbycity) | **GET** /search/cities |
[**getExploreData**](SearchApi.md#getexploredata) | **GET** /search/explore |
[**getSearchSuggestions**](SearchApi.md#getsearchsuggestions) | **GET** /search/suggestions |
[**search**](SearchApi.md#search) | **GET** /search |
[**searchMetadata**](SearchApi.md#searchmetadata) | **POST** /search/metadata |
[**searchPerson**](SearchApi.md#searchperson) | **GET** /search/person |
[**searchPlaces**](SearchApi.md#searchplaces) | **GET** /search/places |
@ -184,79 +183,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)
# **search**
> SearchResponseDto search(clip, motion, page, q, query, recent, size, smart, type, withArchived)
### 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 = SearchApi();
final clip = true; // bool |
final motion = true; // bool |
final page = 8.14; // num |
final q = q_example; // String |
final query = query_example; // String |
final recent = true; // bool |
final size = 8.14; // num |
final smart = true; // bool |
final type = type_example; // String |
final withArchived = true; // bool |
try {
final result = api_instance.search(clip, motion, page, q, query, recent, size, smart, type, withArchived);
print(result);
} catch (e) {
print('Exception when calling SearchApi->search: $e\n');
}
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**clip** | **bool**| | [optional]
**motion** | **bool**| | [optional]
**page** | **num**| | [optional]
**q** | **String**| | [optional]
**query** | **String**| | [optional]
**recent** | **bool**| | [optional]
**size** | **num**| | [optional]
**smart** | **bool**| | [optional]
**type** | **String**| | [optional]
**withArchived** | **bool**| | [optional]
### Return type
[**SearchResponseDto**](SearchResponseDto.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)
# **searchMetadata**
> SearchResponseDto searchMetadata(metadataSearchDto)

View File

@ -742,368 +742,6 @@ class AssetApi {
}
}
/// Performs an HTTP 'GET /assets' operation and returns the [Response].
/// Parameters:
///
/// * [String] checksum:
///
/// * [String] city:
///
/// * [String] country:
///
/// * [DateTime] createdAfter:
///
/// * [DateTime] createdBefore:
///
/// * [String] deviceAssetId:
///
/// * [String] deviceId:
///
/// * [String] encodedVideoPath:
///
/// * [String] id:
///
/// * [bool] isArchived:
///
/// * [bool] isEncoded:
///
/// * [bool] isExternal:
///
/// * [bool] isFavorite:
///
/// * [bool] isMotion:
///
/// * [bool] isNotInAlbum:
///
/// * [bool] isOffline:
///
/// * [bool] isReadOnly:
///
/// * [bool] isVisible:
///
/// * [String] lensModel:
///
/// * [String] libraryId:
///
/// * [String] make:
///
/// * [String] model:
///
/// * [AssetOrder] order:
///
/// * [String] originalFileName:
///
/// * [String] originalPath:
///
/// * [num] page:
///
/// * [List<String>] personIds:
///
/// * [String] previewPath:
///
/// * [String] resizePath:
///
/// * [num] size:
///
/// * [String] state:
///
/// * [DateTime] takenAfter:
///
/// * [DateTime] takenBefore:
///
/// * [String] thumbnailPath:
///
/// * [DateTime] trashedAfter:
///
/// * [DateTime] trashedBefore:
///
/// * [AssetTypeEnum] type:
///
/// * [DateTime] updatedAfter:
///
/// * [DateTime] updatedBefore:
///
/// * [String] webpPath:
///
/// * [bool] withArchived:
///
/// * [bool] withDeleted:
///
/// * [bool] withExif:
///
/// * [bool] withPeople:
///
/// * [bool] withStacked:
Future<Response> searchAssetsWithHttpInfo({ String? checksum, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceAssetId, String? deviceId, String? encodedVideoPath, String? id, bool? isArchived, bool? isEncoded, bool? isExternal, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, bool? isReadOnly, bool? isVisible, String? lensModel, String? libraryId, String? make, String? model, AssetOrder? order, String? originalFileName, String? originalPath, num? page, List<String>? personIds, String? previewPath, String? resizePath, num? size, String? state, DateTime? takenAfter, DateTime? takenBefore, String? thumbnailPath, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, String? webpPath, bool? withArchived, bool? withDeleted, bool? withExif, bool? withPeople, bool? withStacked, }) async {
// ignore: prefer_const_declarations
final path = r'/assets';
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
if (checksum != null) {
queryParams.addAll(_queryParams('', 'checksum', checksum));
}
if (city != null) {
queryParams.addAll(_queryParams('', 'city', city));
}
if (country != null) {
queryParams.addAll(_queryParams('', 'country', country));
}
if (createdAfter != null) {
queryParams.addAll(_queryParams('', 'createdAfter', createdAfter));
}
if (createdBefore != null) {
queryParams.addAll(_queryParams('', 'createdBefore', createdBefore));
}
if (deviceAssetId != null) {
queryParams.addAll(_queryParams('', 'deviceAssetId', deviceAssetId));
}
if (deviceId != null) {
queryParams.addAll(_queryParams('', 'deviceId', deviceId));
}
if (encodedVideoPath != null) {
queryParams.addAll(_queryParams('', 'encodedVideoPath', encodedVideoPath));
}
if (id != null) {
queryParams.addAll(_queryParams('', 'id', id));
}
if (isArchived != null) {
queryParams.addAll(_queryParams('', 'isArchived', isArchived));
}
if (isEncoded != null) {
queryParams.addAll(_queryParams('', 'isEncoded', isEncoded));
}
if (isExternal != null) {
queryParams.addAll(_queryParams('', 'isExternal', isExternal));
}
if (isFavorite != null) {
queryParams.addAll(_queryParams('', 'isFavorite', isFavorite));
}
if (isMotion != null) {
queryParams.addAll(_queryParams('', 'isMotion', isMotion));
}
if (isNotInAlbum != null) {
queryParams.addAll(_queryParams('', 'isNotInAlbum', isNotInAlbum));
}
if (isOffline != null) {
queryParams.addAll(_queryParams('', 'isOffline', isOffline));
}
if (isReadOnly != null) {
queryParams.addAll(_queryParams('', 'isReadOnly', isReadOnly));
}
if (isVisible != null) {
queryParams.addAll(_queryParams('', 'isVisible', isVisible));
}
if (lensModel != null) {
queryParams.addAll(_queryParams('', 'lensModel', lensModel));
}
if (libraryId != null) {
queryParams.addAll(_queryParams('', 'libraryId', libraryId));
}
if (make != null) {
queryParams.addAll(_queryParams('', 'make', make));
}
if (model != null) {
queryParams.addAll(_queryParams('', 'model', model));
}
if (order != null) {
queryParams.addAll(_queryParams('', 'order', order));
}
if (originalFileName != null) {
queryParams.addAll(_queryParams('', 'originalFileName', originalFileName));
}
if (originalPath != null) {
queryParams.addAll(_queryParams('', 'originalPath', originalPath));
}
if (page != null) {
queryParams.addAll(_queryParams('', 'page', page));
}
if (personIds != null) {
queryParams.addAll(_queryParams('multi', 'personIds', personIds));
}
if (previewPath != null) {
queryParams.addAll(_queryParams('', 'previewPath', previewPath));
}
if (resizePath != null) {
queryParams.addAll(_queryParams('', 'resizePath', resizePath));
}
if (size != null) {
queryParams.addAll(_queryParams('', 'size', size));
}
if (state != null) {
queryParams.addAll(_queryParams('', 'state', state));
}
if (takenAfter != null) {
queryParams.addAll(_queryParams('', 'takenAfter', takenAfter));
}
if (takenBefore != null) {
queryParams.addAll(_queryParams('', 'takenBefore', takenBefore));
}
if (thumbnailPath != null) {
queryParams.addAll(_queryParams('', 'thumbnailPath', thumbnailPath));
}
if (trashedAfter != null) {
queryParams.addAll(_queryParams('', 'trashedAfter', trashedAfter));
}
if (trashedBefore != null) {
queryParams.addAll(_queryParams('', 'trashedBefore', trashedBefore));
}
if (type != null) {
queryParams.addAll(_queryParams('', 'type', type));
}
if (updatedAfter != null) {
queryParams.addAll(_queryParams('', 'updatedAfter', updatedAfter));
}
if (updatedBefore != null) {
queryParams.addAll(_queryParams('', 'updatedBefore', updatedBefore));
}
if (webpPath != null) {
queryParams.addAll(_queryParams('', 'webpPath', webpPath));
}
if (withArchived != null) {
queryParams.addAll(_queryParams('', 'withArchived', withArchived));
}
if (withDeleted != null) {
queryParams.addAll(_queryParams('', 'withDeleted', withDeleted));
}
if (withExif != null) {
queryParams.addAll(_queryParams('', 'withExif', withExif));
}
if (withPeople != null) {
queryParams.addAll(_queryParams('', 'withPeople', withPeople));
}
if (withStacked != null) {
queryParams.addAll(_queryParams('', 'withStacked', withStacked));
}
const contentTypes = <String>[];
return apiClient.invokeAPI(
path,
'GET',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Parameters:
///
/// * [String] checksum:
///
/// * [String] city:
///
/// * [String] country:
///
/// * [DateTime] createdAfter:
///
/// * [DateTime] createdBefore:
///
/// * [String] deviceAssetId:
///
/// * [String] deviceId:
///
/// * [String] encodedVideoPath:
///
/// * [String] id:
///
/// * [bool] isArchived:
///
/// * [bool] isEncoded:
///
/// * [bool] isExternal:
///
/// * [bool] isFavorite:
///
/// * [bool] isMotion:
///
/// * [bool] isNotInAlbum:
///
/// * [bool] isOffline:
///
/// * [bool] isReadOnly:
///
/// * [bool] isVisible:
///
/// * [String] lensModel:
///
/// * [String] libraryId:
///
/// * [String] make:
///
/// * [String] model:
///
/// * [AssetOrder] order:
///
/// * [String] originalFileName:
///
/// * [String] originalPath:
///
/// * [num] page:
///
/// * [List<String>] personIds:
///
/// * [String] previewPath:
///
/// * [String] resizePath:
///
/// * [num] size:
///
/// * [String] state:
///
/// * [DateTime] takenAfter:
///
/// * [DateTime] takenBefore:
///
/// * [String] thumbnailPath:
///
/// * [DateTime] trashedAfter:
///
/// * [DateTime] trashedBefore:
///
/// * [AssetTypeEnum] type:
///
/// * [DateTime] updatedAfter:
///
/// * [DateTime] updatedBefore:
///
/// * [String] webpPath:
///
/// * [bool] withArchived:
///
/// * [bool] withDeleted:
///
/// * [bool] withExif:
///
/// * [bool] withPeople:
///
/// * [bool] withStacked:
Future<List<AssetResponseDto>?> searchAssets({ String? checksum, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceAssetId, String? deviceId, String? encodedVideoPath, String? id, bool? isArchived, bool? isEncoded, bool? isExternal, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, bool? isReadOnly, bool? isVisible, String? lensModel, String? libraryId, String? make, String? model, AssetOrder? order, String? originalFileName, String? originalPath, num? page, List<String>? personIds, String? previewPath, String? resizePath, num? size, String? state, DateTime? takenAfter, DateTime? takenBefore, String? thumbnailPath, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, String? webpPath, bool? withArchived, bool? withDeleted, bool? withExif, bool? withPeople, bool? withStacked, }) async {
final response = await searchAssetsWithHttpInfo( checksum: checksum, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, deviceAssetId: deviceAssetId, deviceId: deviceId, encodedVideoPath: encodedVideoPath, id: id, isArchived: isArchived, isEncoded: isEncoded, isExternal: isExternal, isFavorite: isFavorite, isMotion: isMotion, isNotInAlbum: isNotInAlbum, isOffline: isOffline, isReadOnly: isReadOnly, isVisible: isVisible, lensModel: lensModel, libraryId: libraryId, make: make, model: model, order: order, originalFileName: originalFileName, originalPath: originalPath, page: page, personIds: personIds, previewPath: previewPath, resizePath: resizePath, size: size, state: state, takenAfter: takenAfter, takenBefore: takenBefore, thumbnailPath: thumbnailPath, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, webpPath: webpPath, withArchived: withArchived, withDeleted: withDeleted, withExif: withExif, withPeople: withPeople, withStacked: withStacked, );
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
final responseBody = await _decodeBodyBytes(response);
return (await apiClient.deserializeAsync(responseBody, 'List<AssetResponseDto>') as List)
.cast<AssetResponseDto>()
.toList(growable: false);
}
return null;
}
/// Performs an HTTP 'GET /asset/file/{id}' operation and returns the [Response].
/// Parameters:
///

View File

@ -184,120 +184,6 @@ class SearchApi {
return null;
}
/// Performs an HTTP 'GET /search' operation and returns the [Response].
/// Parameters:
///
/// * [bool] clip:
///
/// * [bool] motion:
///
/// * [num] page:
///
/// * [String] q:
///
/// * [String] query:
///
/// * [bool] recent:
///
/// * [num] size:
///
/// * [bool] smart:
///
/// * [String] type:
///
/// * [bool] withArchived:
Future<Response> searchWithHttpInfo({ bool? clip, bool? motion, num? page, String? q, String? query, bool? recent, num? size, bool? smart, String? type, bool? withArchived, }) async {
// ignore: prefer_const_declarations
final path = r'/search';
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
if (clip != null) {
queryParams.addAll(_queryParams('', 'clip', clip));
}
if (motion != null) {
queryParams.addAll(_queryParams('', 'motion', motion));
}
if (page != null) {
queryParams.addAll(_queryParams('', 'page', page));
}
if (q != null) {
queryParams.addAll(_queryParams('', 'q', q));
}
if (query != null) {
queryParams.addAll(_queryParams('', 'query', query));
}
if (recent != null) {
queryParams.addAll(_queryParams('', 'recent', recent));
}
if (size != null) {
queryParams.addAll(_queryParams('', 'size', size));
}
if (smart != null) {
queryParams.addAll(_queryParams('', 'smart', smart));
}
if (type != null) {
queryParams.addAll(_queryParams('', 'type', type));
}
if (withArchived != null) {
queryParams.addAll(_queryParams('', 'withArchived', withArchived));
}
const contentTypes = <String>[];
return apiClient.invokeAPI(
path,
'GET',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Parameters:
///
/// * [bool] clip:
///
/// * [bool] motion:
///
/// * [num] page:
///
/// * [String] q:
///
/// * [String] query:
///
/// * [bool] recent:
///
/// * [num] size:
///
/// * [bool] smart:
///
/// * [String] type:
///
/// * [bool] withArchived:
Future<SearchResponseDto?> search({ bool? clip, bool? motion, num? page, String? q, String? query, bool? recent, num? size, bool? smart, String? type, bool? withArchived, }) async {
final response = await searchWithHttpInfo( clip: clip, motion: motion, page: page, q: q, query: query, recent: recent, size: size, smart: smart, type: type, withArchived: withArchived, );
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), 'SearchResponseDto',) as SearchResponseDto;
}
return null;
}
/// Performs an HTTP 'POST /search/metadata' operation and returns the [Response].
/// Parameters:
///

View File

@ -85,11 +85,6 @@ void main() {
// TODO
});
//Future<List<AssetResponseDto>> searchAssets({ String checksum, String city, String country, DateTime createdAfter, DateTime createdBefore, String deviceAssetId, String deviceId, String encodedVideoPath, String id, bool isArchived, bool isEncoded, bool isExternal, bool isFavorite, bool isMotion, bool isNotInAlbum, bool isOffline, bool isReadOnly, bool isVisible, String lensModel, String libraryId, String make, String model, AssetOrder order, String originalFileName, String originalPath, num page, List<String> personIds, String previewPath, String resizePath, num size, String state, DateTime takenAfter, DateTime takenBefore, String thumbnailPath, DateTime trashedAfter, DateTime trashedBefore, AssetTypeEnum type, DateTime updatedAfter, DateTime updatedBefore, String webpPath, bool withArchived, bool withDeleted, bool withExif, bool withPeople, bool withStacked }) async
test('test searchAssets', () async {
// TODO
});
//Future<MultipartFile> serveFile(String id, { bool isThumb, bool isWeb, String key }) async
test('test serveFile', () async {
// TODO

View File

@ -32,11 +32,6 @@ void main() {
// TODO
});
//Future<SearchResponseDto> search({ bool clip, bool motion, num page, String q, String query, bool recent, num size, bool smart, String type, bool withArchived }) async
test('test search', () async {
// TODO
});
//Future<SearchResponseDto> searchMetadata(MetadataSearchDto metadataSearchDto) async
test('test searchMetadata', () async {
// TODO

View File

@ -1823,423 +1823,6 @@
]
}
},
"/assets": {
"get": {
"deprecated": true,
"operationId": "searchAssets",
"parameters": [
{
"name": "checksum",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "city",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "country",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "createdAfter",
"required": false,
"in": "query",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "createdBefore",
"required": false,
"in": "query",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "deviceAssetId",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "deviceId",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "encodedVideoPath",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "id",
"required": false,
"in": "query",
"schema": {
"format": "uuid",
"type": "string"
}
},
{
"name": "isArchived",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "isEncoded",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "isExternal",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "isFavorite",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "isMotion",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "isNotInAlbum",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "isOffline",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "isReadOnly",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "isVisible",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "lensModel",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "libraryId",
"required": false,
"in": "query",
"schema": {
"format": "uuid",
"type": "string"
}
},
{
"name": "make",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "model",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "order",
"required": false,
"in": "query",
"schema": {
"$ref": "#/components/schemas/AssetOrder"
}
},
{
"name": "originalFileName",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "originalPath",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "page",
"required": false,
"in": "query",
"schema": {
"minimum": 1,
"type": "number"
}
},
{
"name": "personIds",
"required": false,
"in": "query",
"schema": {
"format": "uuid",
"type": "array",
"items": {
"type": "string"
}
}
},
{
"name": "previewPath",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "resizePath",
"required": false,
"in": "query",
"deprecated": true,
"schema": {
"type": "string"
}
},
{
"name": "size",
"required": false,
"in": "query",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "state",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "takenAfter",
"required": false,
"in": "query",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "takenBefore",
"required": false,
"in": "query",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "thumbnailPath",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "trashedAfter",
"required": false,
"in": "query",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "trashedBefore",
"required": false,
"in": "query",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "type",
"required": false,
"in": "query",
"schema": {
"$ref": "#/components/schemas/AssetTypeEnum"
}
},
{
"name": "updatedAfter",
"required": false,
"in": "query",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "updatedBefore",
"required": false,
"in": "query",
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"name": "webpPath",
"required": false,
"in": "query",
"deprecated": true,
"schema": {
"type": "string"
}
},
{
"name": "withArchived",
"required": false,
"in": "query",
"schema": {
"default": false,
"type": "boolean"
}
},
{
"name": "withDeleted",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "withExif",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "withPeople",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "withStacked",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/AssetResponseDto"
},
"type": "array"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Asset"
]
}
},
"/audit/deletes": {
"get": {
"operationId": "getAuditDeletes",
@ -4383,130 +3966,6 @@
]
}
},
"/search": {
"get": {
"deprecated": true,
"operationId": "search",
"parameters": [
{
"name": "clip",
"required": false,
"in": "query",
"deprecated": true,
"schema": {
"type": "boolean"
}
},
{
"name": "motion",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "page",
"required": false,
"in": "query",
"schema": {
"minimum": 1,
"type": "number"
}
},
{
"name": "q",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "query",
"required": false,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "recent",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "size",
"required": false,
"in": "query",
"schema": {
"minimum": 1,
"maximum": 1000,
"type": "number"
}
},
{
"name": "smart",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "type",
"required": false,
"in": "query",
"schema": {
"enum": [
"IMAGE",
"VIDEO",
"AUDIO",
"OTHER"
],
"type": "string"
}
},
{
"name": "withArchived",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Search"
]
}
},
"/search/cities": {
"get": {
"operationId": "getAssetsByCity",

View File

@ -600,31 +600,6 @@ export type FileChecksumResponseDto = {
export type FileReportFixDto = {
items: FileReportItemDto[];
};
export type SearchFacetCountResponseDto = {
count: number;
value: string;
};
export type SearchFacetResponseDto = {
counts: SearchFacetCountResponseDto[];
fieldName: string;
};
export type SearchAlbumResponseDto = {
count: number;
facets: SearchFacetResponseDto[];
items: AlbumResponseDto[];
total: number;
};
export type SearchAssetResponseDto = {
count: number;
facets: SearchFacetResponseDto[];
items: AssetResponseDto[];
nextPage: string | null;
total: number;
};
export type SearchResponseDto = {
albums: SearchAlbumResponseDto;
assets: SearchAssetResponseDto;
};
export type SearchExploreItem = {
data: AssetResponseDto;
value: string;
@ -680,6 +655,31 @@ export type MetadataSearchDto = {
withPeople?: boolean;
withStacked?: boolean;
};
export type SearchFacetCountResponseDto = {
count: number;
value: string;
};
export type SearchFacetResponseDto = {
counts: SearchFacetCountResponseDto[];
fieldName: string;
};
export type SearchAlbumResponseDto = {
count: number;
facets: SearchFacetResponseDto[];
items: AlbumResponseDto[];
total: number;
};
export type SearchAssetResponseDto = {
count: number;
facets: SearchFacetResponseDto[];
items: AssetResponseDto[];
nextPage: string | null;
total: number;
};
export type SearchResponseDto = {
albums: SearchAlbumResponseDto;
assets: SearchAssetResponseDto;
};
export type PlacesResponseDto = {
admin1name?: string;
admin2name?: string;
@ -1530,106 +1530,6 @@ export function updateAsset({ id, updateAssetDto }: {
body: updateAssetDto
})));
}
export function searchAssets({ checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isNotInAlbum, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, personIds, previewPath, resizePath, size, state, takenAfter, takenBefore, thumbnailPath, trashedAfter, trashedBefore, $type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked }: {
checksum?: string;
city?: string;
country?: string;
createdAfter?: string;
createdBefore?: string;
deviceAssetId?: string;
deviceId?: string;
encodedVideoPath?: string;
id?: string;
isArchived?: boolean;
isEncoded?: boolean;
isExternal?: boolean;
isFavorite?: boolean;
isMotion?: boolean;
isNotInAlbum?: boolean;
isOffline?: boolean;
isReadOnly?: boolean;
isVisible?: boolean;
lensModel?: string;
libraryId?: string;
make?: string;
model?: string;
order?: AssetOrder;
originalFileName?: string;
originalPath?: string;
page?: number;
personIds?: string[];
previewPath?: string;
resizePath?: string;
size?: number;
state?: string;
takenAfter?: string;
takenBefore?: string;
thumbnailPath?: string;
trashedAfter?: string;
trashedBefore?: string;
$type?: AssetTypeEnum;
updatedAfter?: string;
updatedBefore?: string;
webpPath?: string;
withArchived?: boolean;
withDeleted?: boolean;
withExif?: boolean;
withPeople?: boolean;
withStacked?: boolean;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: AssetResponseDto[];
}>(`/assets${QS.query(QS.explode({
checksum,
city,
country,
createdAfter,
createdBefore,
deviceAssetId,
deviceId,
encodedVideoPath,
id,
isArchived,
isEncoded,
isExternal,
isFavorite,
isMotion,
isNotInAlbum,
isOffline,
isReadOnly,
isVisible,
lensModel,
libraryId,
make,
model,
order,
originalFileName,
originalPath,
page,
personIds,
previewPath,
resizePath,
size,
state,
takenAfter,
takenBefore,
thumbnailPath,
trashedAfter,
trashedBefore,
"type": $type,
updatedAfter,
updatedBefore,
webpPath,
withArchived,
withDeleted,
withExif,
withPeople,
withStacked
}))}`, {
...opts
}));
}
export function getAuditDeletes({ after, entityType, userId }: {
after: string;
entityType: EntityType;
@ -2201,36 +2101,6 @@ export function fixAuditFiles({ fileReportFixDto }: {
body: fileReportFixDto
})));
}
export function search({ clip, motion, page, q, query, recent, size, smart, $type, withArchived }: {
clip?: boolean;
motion?: boolean;
page?: number;
q?: string;
query?: string;
recent?: boolean;
size?: number;
smart?: boolean;
$type?: "IMAGE" | "VIDEO" | "AUDIO" | "OTHER";
withArchived?: boolean;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: SearchResponseDto;
}>(`/search${QS.query(QS.explode({
clip,
motion,
page,
q,
query,
recent,
size,
smart,
"type": $type,
withArchived
}))}`, {
...opts
}));
}
export function getAssetsByCity(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;

View File

@ -1,5 +1,5 @@
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { ApiTags } from '@nestjs/swagger';
import { AssetResponseDto, MemoryLaneResponseDto } from 'src/dtos/asset-response.dto';
import {
AssetBulkDeleteDto,
@ -12,30 +12,13 @@ import {
UpdateAssetDto,
} from 'src/dtos/asset.dto';
import { AuthDto } from 'src/dtos/auth.dto';
import { MapMarkerDto, MapMarkerResponseDto, MemoryLaneDto, MetadataSearchDto } from 'src/dtos/search.dto';
import { MapMarkerDto, MapMarkerResponseDto, MemoryLaneDto } from 'src/dtos/search.dto';
import { UpdateStackParentDto } from 'src/dtos/stack.dto';
import { Auth, Authenticated, SharedLinkRoute } from 'src/middleware/auth.guard';
import { Route } from 'src/middleware/file-upload.interceptor';
import { AssetService } from 'src/services/asset.service';
import { SearchService } from 'src/services/search.service';
import { UUIDParamDto } from 'src/validation';
@ApiTags('Asset')
@Controller('assets')
@Authenticated()
export class AssetsController {
constructor(private searchService: SearchService) {}
@Get()
@ApiOperation({ deprecated: true })
async searchAssets(@Auth() auth: AuthDto, @Query() dto: MetadataSearchDto): Promise<AssetResponseDto[]> {
const {
assets: { items },
} = await this.searchService.searchMetadata(auth, dto);
return items;
}
}
@ApiTags('Asset')
@Controller(Route.ASSET)
@Authenticated()

View File

@ -3,7 +3,7 @@ import { AlbumController } from 'src/controllers/album.controller';
import { APIKeyController } from 'src/controllers/api-key.controller';
import { AppController } from 'src/controllers/app.controller';
import { AssetControllerV1 } from 'src/controllers/asset-v1.controller';
import { AssetController, AssetsController } from 'src/controllers/asset.controller';
import { AssetController } from 'src/controllers/asset.controller';
import { AuditController } from 'src/controllers/audit.controller';
import { AuthController } from 'src/controllers/auth.controller';
import { DownloadController } from 'src/controllers/download.controller';
@ -34,7 +34,6 @@ export const controllers = [
AppController,
AssetController,
AssetControllerV1,
AssetsController,
AuditController,
AuthController,
DownloadController,

View File

@ -1,12 +1,11 @@
import { Body, Controller, Get, HttpCode, HttpStatus, Post, Query } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { ApiTags } from '@nestjs/swagger';
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
import { AuthDto } from 'src/dtos/auth.dto';
import { PersonResponseDto } from 'src/dtos/person.dto';
import {
MetadataSearchDto,
PlacesResponseDto,
SearchDto,
SearchExploreResponseDto,
SearchPeopleDto,
SearchPlacesDto,
@ -23,12 +22,6 @@ import { SearchService } from 'src/services/search.service';
export class SearchController {
constructor(private service: SearchService) {}
@Get()
@ApiOperation({ deprecated: true })
search(@Auth() auth: AuthDto, @Query() dto: SearchDto): Promise<SearchResponseDto> {
return this.service.search(auth, dto);
}
@Post('metadata')
@HttpCode(HttpStatus.OK)
searchMetadata(@Auth() auth: AuthDto, @Body() dto: MetadataSearchDto): Promise<SearchResponseDto> {

View File

@ -199,53 +199,6 @@ export class SmartSearchDto extends BaseSearchDto {
query!: string;
}
// TODO: remove after implementing new search filters
/** @deprecated */
export class SearchDto {
@IsString()
@IsNotEmpty()
@Optional()
q?: string;
@IsString()
@IsNotEmpty()
@Optional()
query?: string;
@ValidateBoolean({ optional: true })
smart?: boolean;
/** @deprecated */
@ValidateBoolean({ optional: true })
clip?: boolean;
@IsEnum(AssetType)
@Optional()
type?: AssetType;
@ValidateBoolean({ optional: true })
recent?: boolean;
@ValidateBoolean({ optional: true })
motion?: boolean;
@ValidateBoolean({ optional: true })
withArchived?: boolean;
@IsInt()
@Min(1)
@Type(() => Number)
@Optional()
page?: number;
@IsInt()
@Min(1)
@Max(1000)
@Type(() => Number)
@Optional()
size?: number;
}
export class SearchPlacesDto {
@IsString()
@IsNotEmpty()

View File

@ -129,10 +129,6 @@ export interface AssetExploreOptions extends AssetExploreFieldOptions {
unnest?: boolean;
}
export interface MetadataSearchOptions {
numResults: number;
}
export interface AssetFullSyncOptions {
ownerId: string;
lastCreationDate?: Date;
@ -188,7 +184,6 @@ export interface IAssetRepository {
upsertJobStatus(jobStatus: Partial<AssetJobStatusEntity>): Promise<void>;
getAssetIdByCity(userId: string, options: AssetExploreFieldOptions): Promise<SearchExploreItem<string>>;
getAssetIdByTag(userId: string, options: AssetExploreFieldOptions): Promise<SearchExploreItem<string>>;
searchMetadata(query: string, userIds: string[], options: MetadataSearchOptions): Promise<AssetEntity[]>;
getAllForUserFullSync(options: AssetFullSyncOptions): Promise<AssetEntity[]>;
getChangedDeltaSync(options: AssetDeltaSyncOptions): Promise<AssetEntity[]>;
}

View File

@ -5,29 +5,6 @@ import { Paginated } from 'src/utils/pagination';
export const ISearchRepository = 'ISearchRepository';
export enum SearchStrategy {
SMART = 'SMART',
TEXT = 'TEXT',
}
export interface SearchFilter {
id?: string;
userId: string;
type?: AssetType;
isFavorite?: boolean;
isArchived?: boolean;
city?: string;
state?: string;
country?: string;
make?: string;
model?: string;
objects?: string[];
tags?: string[];
recent?: boolean;
motion?: boolean;
debug?: boolean;
}
export interface SearchResult<T> {
/** total matches */
total: number;

View File

@ -738,37 +738,6 @@ WHERE
LIMIT
12
-- AssetRepository.searchMetadata
SELECT
asset.*,
e.*,
COALESCE("si"."tags", array[]::text[]) AS "tags",
COALESCE("si"."objects", array[]::text[]) AS "objects"
FROM
"assets" "asset"
INNER JOIN "exif" "e" ON asset."id" = e."assetId"
LEFT JOIN "smart_info" "si" ON si."assetId" = asset."id"
WHERE
(
"asset"."isVisible" = true
AND "asset"."ownerId" IN ($1)
AND "asset"."isArchived" = $2
AND (
(
e."exifTextSearchableColumn" || COALESCE(
si."smartInfoTextSearchableColumn",
to_tsvector('english', '')
)
) @@ PLAINTO_TSQUERY('english', $3)
OR asset."originalFileName" = $4
)
)
AND ("asset"."deletedAt" IS NULL)
ORDER BY
"asset"."fileCreatedAt" DESC
LIMIT
250
-- AssetRepository.getAllForUserFullSync
SELECT
"asset"."id" AS "asset_id",

View File

@ -1,6 +1,5 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import path from 'node:path';
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
import { AlbumEntity, AssetOrder } from 'src/entities/album.entity';
import { AssetJobStatusEntity } from 'src/entities/asset-job-status.entity';
@ -23,7 +22,6 @@ import {
LivePhotoSearchOptions,
MapMarker,
MapMarkerSearchOptions,
MetadataSearchOptions,
MonthDay,
TimeBucketItem,
TimeBucketOptions,
@ -700,94 +698,6 @@ export class AssetRepository implements IAssetRepository {
return builder;
}
@GenerateSql({ params: [DummyValue.STRING, [DummyValue.UUID], { numResults: 250 }] })
async searchMetadata(
query: string,
userIds: string[],
{ numResults }: MetadataSearchOptions,
): Promise<AssetEntity[]> {
const rows = await this.getBuilder({
userIds: userIds,
exifInfo: false,
isArchived: false,
})
.select('asset.*')
.addSelect('e.*')
.addSelect('COALESCE(si.tags, array[]::text[])', 'tags')
.addSelect('COALESCE(si.objects, array[]::text[])', 'objects')
.innerJoin('exif', 'e', 'asset."id" = e."assetId"')
.leftJoin('smart_info', 'si', 'si."assetId" = asset."id"')
.andWhere(
new Brackets((qb) => {
qb.where(
`(e."exifTextSearchableColumn" || COALESCE(si."smartInfoTextSearchableColumn", to_tsvector('english', '')))
@@ PLAINTO_TSQUERY('english', :query)`,
{ query },
).orWhere('asset."originalFileName" = :path', { path: path.parse(query).name });
}),
)
.addOrderBy('asset.fileCreatedAt', 'DESC')
.limit(numResults)
.getRawMany();
return rows.map(
({
tags,
objects,
country,
state,
city,
description,
model,
make,
dateTimeOriginal,
exifImageHeight,
exifImageWidth,
exposureTime,
fNumber,
fileSizeInByte,
focalLength,
iso,
latitude,
lensModel,
longitude,
modifyDate,
projectionType,
timeZone,
...assetInfo
}) =>
({
exifInfo: {
city,
country,
dateTimeOriginal,
description,
exifImageHeight,
exifImageWidth,
exposureTime,
fNumber,
fileSizeInByte,
focalLength,
iso,
latitude,
lensModel,
longitude,
make,
model,
modifyDate,
projectionType,
state,
timeZone,
},
smartInfo: {
tags,
objects,
},
...assetInfo,
}) as AssetEntity,
);
}
@GenerateSql({
params: [
{

View File

@ -1,6 +1,4 @@
import { mapAsset } from 'src/dtos/asset-response.dto';
import { SearchDto } from 'src/dtos/search.dto';
import { SystemConfigKey } from 'src/entities/system-config.entity';
import { IAssetRepository } from 'src/interfaces/asset.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.interface';
@ -97,119 +95,4 @@ describe(SearchService.name, () => {
expect(result).toEqual(expectedResponse);
});
});
describe('search', () => {
it('should throw an error if query is missing', async () => {
await expect(sut.search(authStub.user1, { q: '' })).rejects.toThrow('Missing query');
});
it('should search by metadata if `clip` option is false', async () => {
const dto: SearchDto = { q: 'test query', clip: false };
assetMock.searchMetadata.mockResolvedValueOnce([assetStub.image]);
partnerMock.getAll.mockResolvedValueOnce([]);
const expectedResponse = {
albums: {
total: 0,
count: 0,
items: [],
facets: [],
},
assets: {
total: 1,
count: 1,
items: [mapAsset(assetStub.image)],
facets: [],
nextPage: null,
},
};
const result = await sut.search(authStub.user1, dto);
expect(result).toEqual(expectedResponse);
expect(assetMock.searchMetadata).toHaveBeenCalledWith(dto.q, [authStub.user1.user.id], { numResults: 250 });
expect(searchMock.searchSmart).not.toHaveBeenCalled();
});
it('should search archived photos if `withArchived` option is true', async () => {
const dto: SearchDto = { q: 'test query', clip: true, withArchived: true };
const embedding = [1, 2, 3];
searchMock.searchSmart.mockResolvedValueOnce({ items: [assetStub.image], hasNextPage: false });
machineMock.encodeText.mockResolvedValueOnce(embedding);
partnerMock.getAll.mockResolvedValueOnce([]);
const expectedResponse = {
albums: {
total: 0,
count: 0,
items: [],
facets: [],
},
assets: {
total: 1,
count: 1,
items: [mapAsset(assetStub.image)],
facets: [],
nextPage: null,
},
};
const result = await sut.search(authStub.user1, dto);
expect(result).toEqual(expectedResponse);
expect(searchMock.searchSmart).toHaveBeenCalledWith(
{ page: 1, size: 100 },
{
userIds: [authStub.user1.user.id],
embedding,
withArchived: true,
},
);
expect(assetMock.searchMetadata).not.toHaveBeenCalled();
});
it('should search by CLIP if `clip` option is true', async () => {
const dto: SearchDto = { q: 'test query', clip: true };
const embedding = [1, 2, 3];
searchMock.searchSmart.mockResolvedValueOnce({ items: [assetStub.image], hasNextPage: false });
machineMock.encodeText.mockResolvedValueOnce(embedding);
partnerMock.getAll.mockResolvedValueOnce([]);
const expectedResponse = {
albums: {
total: 0,
count: 0,
items: [],
facets: [],
},
assets: {
total: 1,
count: 1,
items: [mapAsset(assetStub.image)],
facets: [],
nextPage: null,
},
};
const result = await sut.search(authStub.user1, dto);
expect(result).toEqual(expectedResponse);
expect(searchMock.searchSmart).toHaveBeenCalledWith(
{ page: 1, size: 100 },
{
userIds: [authStub.user1.user.id],
embedding,
withArchived: false,
},
);
expect(assetMock.searchMetadata).not.toHaveBeenCalled();
});
it.each([
{ key: SystemConfigKey.MACHINE_LEARNING_ENABLED },
{ key: SystemConfigKey.MACHINE_LEARNING_CLIP_ENABLED },
])('should throw an error if clip is requested but disabled', async ({ key }) => {
const dto: SearchDto = { q: 'test query', clip: true };
configMock.load.mockResolvedValue([{ key, value: false }]);
await expect(sut.search(authStub.user1, dto)).rejects.toThrow('Smart search is not enabled');
});
});
});

View File

@ -6,7 +6,6 @@ import { PersonResponseDto } from 'src/dtos/person.dto';
import {
MetadataSearchDto,
PlacesResponseDto,
SearchDto,
SearchPeopleDto,
SearchPlacesDto,
SearchResponseDto,
@ -23,7 +22,7 @@ import { IMachineLearningRepository } from 'src/interfaces/machine-learning.inte
import { IMetadataRepository } from 'src/interfaces/metadata.interface';
import { IPartnerRepository } from 'src/interfaces/partner.interface';
import { IPersonRepository } from 'src/interfaces/person.interface';
import { ISearchRepository, SearchExploreItem, SearchStrategy } from 'src/interfaces/search.interface';
import { ISearchRepository, SearchExploreItem } from 'src/interfaces/search.interface';
import { ISystemConfigRepository } from 'src/interfaces/system-config.interface';
@Injectable()
@ -145,60 +144,6 @@ export class SearchService {
}
}
// TODO: remove after implementing new search filters
/** @deprecated */
async search(auth: AuthDto, dto: SearchDto): Promise<SearchResponseDto> {
await this.configCore.requireFeature(FeatureFlag.SEARCH);
const { machineLearning } = await this.configCore.getConfig();
const query = dto.q || dto.query;
if (!query) {
throw new Error('Missing query');
}
let strategy = SearchStrategy.TEXT;
if (dto.smart || dto.clip) {
await this.configCore.requireFeature(FeatureFlag.SMART_SEARCH);
strategy = SearchStrategy.SMART;
}
const userIds = await this.getUserIdsToSearch(auth);
const page = dto.page ?? 1;
let nextPage: string | null = null;
let assets: AssetEntity[] = [];
switch (strategy) {
case SearchStrategy.SMART: {
const embedding = await this.machineLearning.encodeText(
machineLearning.url,
{ text: query },
machineLearning.clip,
);
const { hasNextPage, items } = await this.searchRepository.searchSmart(
{ page, size: dto.size || 100 },
{
userIds,
embedding,
withArchived: !!dto.withArchived,
},
);
if (hasNextPage) {
nextPage = (page + 1).toString();
}
assets = items;
break;
}
case SearchStrategy.TEXT: {
assets = await this.assetRepository.searchMetadata(query, userIds, { numResults: dto.size || 250 });
}
default: {
break;
}
}
return this.mapResponse(assets, nextPage);
}
private async getUserIdsToSearch(auth: AuthDto): Promise<string[]> {
const userIds: string[] = [auth.user.id];
const partners = await this.partnerRepository.getAll(auth.user.id);

View File

@ -35,7 +35,6 @@ export const newAssetRepositoryMock = (): Mocked<IAssetRepository> => {
softDeleteAll: vitest.fn(),
getAssetIdByCity: vitest.fn(),
getAssetIdByTag: vitest.fn(),
searchMetadata: vitest.fn(),
getAllForUserFullSync: vitest.fn(),
getChangedDeltaSync: vitest.fn(),
};