Ver código fonte

chore: open api

Jason Rasmussen 1 ano atrás
pai
commit
ea6bc8fb10

+ 73 - 1
cli/src/api/open-api/api.ts

@@ -252,6 +252,12 @@ export interface AlbumResponseDto {
      * @memberof AlbumResponseDto
      */
     'ownerId': string;
+    /**
+     * 
+     * @type {Array<RuleResponseDto>}
+     * @memberof AlbumResponseDto
+     */
+    'rules': Array<RuleResponseDto>;
     /**
      * 
      * @type {boolean}
@@ -325,6 +331,12 @@ export interface AllJobStatusResponseDto {
      * @memberof AllJobStatusResponseDto
      */
     'sidecar': JobStatusDto;
+    /**
+     * 
+     * @type {JobStatusDto}
+     * @memberof AllJobStatusResponseDto
+     */
+    'smartAlbum': JobStatusDto;
     /**
      * 
      * @type {JobStatusDto}
@@ -1453,7 +1465,8 @@ export const JobName = {
     BackgroundTask: 'backgroundTask',
     StorageTemplateMigration: 'storageTemplateMigration',
     Search: 'search',
-    Sidecar: 'sidecar'
+    Sidecar: 'sidecar',
+    SmartAlbum: 'smartAlbum'
 } as const;
 
 export type JobName = typeof JobName[keyof typeof JobName];
@@ -1848,6 +1861,59 @@ export interface QueueStatusDto {
      */
     'isPaused': boolean;
 }
+/**
+ * 
+ * @export
+ * @enum {string}
+ */
+
+export const RuleKey = {
+    Person: 'person',
+    TakenAfter: 'taken-after',
+    City: 'city',
+    State: 'state',
+    Country: 'country',
+    Make: 'make',
+    Model: 'model',
+    Location: 'location'
+} as const;
+
+export type RuleKey = typeof RuleKey[keyof typeof RuleKey];
+
+
+/**
+ * 
+ * @export
+ * @interface RuleResponseDto
+ */
+export interface RuleResponseDto {
+    /**
+     * 
+     * @type {string}
+     * @memberof RuleResponseDto
+     */
+    'id': string;
+    /**
+     * 
+     * @type {RuleKey}
+     * @memberof RuleResponseDto
+     */
+    'key': RuleKey;
+    /**
+     * 
+     * @type {string}
+     * @memberof RuleResponseDto
+     */
+    'ownerId': string;
+    /**
+     * 
+     * @type {object}
+     * @memberof RuleResponseDto
+     */
+    'value': object;
+}
+
+
 /**
  * 
  * @export
@@ -2579,6 +2645,12 @@ export interface SystemConfigJobDto {
      * @memberof SystemConfigJobDto
      */
     'sidecar': JobSettingsDto;
+    /**
+     * 
+     * @type {JobSettingsDto}
+     * @memberof SystemConfigJobDto
+     */
+    'smartAlbum': JobSettingsDto;
     /**
      * 
      * @type {JobSettingsDto}

+ 6 - 0
mobile/openapi/.openapi-generator/FILES

@@ -73,6 +73,8 @@ doc/PersonApi.md
 doc/PersonResponseDto.md
 doc/PersonUpdateDto.md
 doc/QueueStatusDto.md
+doc/RuleKey.md
+doc/RuleResponseDto.md
 doc/SearchAlbumResponseDto.md
 doc/SearchApi.md
 doc/SearchAssetDto.md
@@ -210,6 +212,8 @@ lib/model/people_update_item.dart
 lib/model/person_response_dto.dart
 lib/model/person_update_dto.dart
 lib/model/queue_status_dto.dart
+lib/model/rule_key.dart
+lib/model/rule_response_dto.dart
 lib/model/search_album_response_dto.dart
 lib/model/search_asset_dto.dart
 lib/model/search_asset_response_dto.dart
@@ -326,6 +330,8 @@ test/person_api_test.dart
 test/person_response_dto_test.dart
 test/person_update_dto_test.dart
 test/queue_status_dto_test.dart
+test/rule_key_test.dart
+test/rule_response_dto_test.dart
 test/search_album_response_dto_test.dart
 test/search_api_test.dart
 test/search_asset_dto_test.dart

+ 2 - 0
mobile/openapi/README.md

@@ -240,6 +240,8 @@ Class | Method | HTTP request | Description
  - [PersonResponseDto](doc//PersonResponseDto.md)
  - [PersonUpdateDto](doc//PersonUpdateDto.md)
  - [QueueStatusDto](doc//QueueStatusDto.md)
+ - [RuleKey](doc//RuleKey.md)
+ - [RuleResponseDto](doc//RuleResponseDto.md)
  - [SearchAlbumResponseDto](doc//SearchAlbumResponseDto.md)
  - [SearchAssetDto](doc//SearchAssetDto.md)
  - [SearchAssetResponseDto](doc//SearchAssetResponseDto.md)

+ 1 - 0
mobile/openapi/doc/AlbumResponseDto.md

@@ -20,6 +20,7 @@ Name | Type | Description | Notes
 **lastModifiedAssetTimestamp** | [**DateTime**](DateTime.md) |  | [optional] 
 **owner** | [**UserResponseDto**](UserResponseDto.md) |  | 
 **ownerId** | **String** |  | 
+**rules** | [**List<RuleResponseDto>**](RuleResponseDto.md) |  | [default to const []]
 **shared** | **bool** |  | 
 **sharedUsers** | [**List<UserResponseDto>**](UserResponseDto.md) |  | [default to const []]
 **startDate** | [**DateTime**](DateTime.md) |  | [optional] 

+ 1 - 0
mobile/openapi/doc/AllJobStatusResponseDto.md

@@ -15,6 +15,7 @@ Name | Type | Description | Notes
 **recognizeFaces** | [**JobStatusDto**](JobStatusDto.md) |  | 
 **search** | [**JobStatusDto**](JobStatusDto.md) |  | 
 **sidecar** | [**JobStatusDto**](JobStatusDto.md) |  | 
+**smartAlbum** | [**JobStatusDto**](JobStatusDto.md) |  | 
 **storageTemplateMigration** | [**JobStatusDto**](JobStatusDto.md) |  | 
 **thumbnailGeneration** | [**JobStatusDto**](JobStatusDto.md) |  | 
 **videoConversion** | [**JobStatusDto**](JobStatusDto.md) |  | 

+ 14 - 0
mobile/openapi/doc/RuleKey.md

@@ -0,0 +1,14 @@
+# openapi.model.RuleKey
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+

+ 18 - 0
mobile/openapi/doc/RuleResponseDto.md

@@ -0,0 +1,18 @@
+# openapi.model.RuleResponseDto
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **String** |  | 
+**key** | [**RuleKey**](RuleKey.md) |  | 
+**ownerId** | **String** |  | 
+**value** | [**Object**](.md) |  | 
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+

+ 1 - 0
mobile/openapi/doc/SystemConfigJobDto.md

@@ -15,6 +15,7 @@ Name | Type | Description | Notes
 **recognizeFaces** | [**JobSettingsDto**](JobSettingsDto.md) |  | 
 **search** | [**JobSettingsDto**](JobSettingsDto.md) |  | 
 **sidecar** | [**JobSettingsDto**](JobSettingsDto.md) |  | 
+**smartAlbum** | [**JobSettingsDto**](JobSettingsDto.md) |  | 
 **storageTemplateMigration** | [**JobSettingsDto**](JobSettingsDto.md) |  | 
 **thumbnailGeneration** | [**JobSettingsDto**](JobSettingsDto.md) |  | 
 **videoConversion** | [**JobSettingsDto**](JobSettingsDto.md) |  | 

+ 2 - 0
mobile/openapi/lib/api.dart

@@ -105,6 +105,8 @@ part 'model/people_update_item.dart';
 part 'model/person_response_dto.dart';
 part 'model/person_update_dto.dart';
 part 'model/queue_status_dto.dart';
+part 'model/rule_key.dart';
+part 'model/rule_response_dto.dart';
 part 'model/search_album_response_dto.dart';
 part 'model/search_asset_dto.dart';
 part 'model/search_asset_response_dto.dart';

+ 4 - 0
mobile/openapi/lib/api_client.dart

@@ -305,6 +305,10 @@ class ApiClient {
           return PersonUpdateDto.fromJson(value);
         case 'QueueStatusDto':
           return QueueStatusDto.fromJson(value);
+        case 'RuleKey':
+          return RuleKeyTypeTransformer().decode(value);
+        case 'RuleResponseDto':
+          return RuleResponseDto.fromJson(value);
         case 'SearchAlbumResponseDto':
           return SearchAlbumResponseDto.fromJson(value);
         case 'SearchAssetDto':

+ 3 - 0
mobile/openapi/lib/api_helper.dart

@@ -70,6 +70,9 @@ String parameterToString(dynamic value) {
   if (value is JobName) {
     return JobNameTypeTransformer().encode(value).toString();
   }
+  if (value is RuleKey) {
+    return RuleKeyTypeTransformer().encode(value).toString();
+  }
   if (value is SharedLinkType) {
     return SharedLinkTypeTypeTransformer().encode(value).toString();
   }

+ 9 - 1
mobile/openapi/lib/model/album_response_dto.dart

@@ -25,6 +25,7 @@ class AlbumResponseDto {
     this.lastModifiedAssetTimestamp,
     required this.owner,
     required this.ownerId,
+    this.rules = const [],
     required this.shared,
     this.sharedUsers = const [],
     this.startDate,
@@ -67,6 +68,8 @@ class AlbumResponseDto {
 
   String ownerId;
 
+  List<RuleResponseDto> rules;
+
   bool shared;
 
   List<UserResponseDto> sharedUsers;
@@ -95,6 +98,7 @@ class AlbumResponseDto {
      other.lastModifiedAssetTimestamp == lastModifiedAssetTimestamp &&
      other.owner == owner &&
      other.ownerId == ownerId &&
+     other.rules == rules &&
      other.shared == shared &&
      other.sharedUsers == sharedUsers &&
      other.startDate == startDate &&
@@ -115,13 +119,14 @@ class AlbumResponseDto {
     (lastModifiedAssetTimestamp == null ? 0 : lastModifiedAssetTimestamp!.hashCode) +
     (owner.hashCode) +
     (ownerId.hashCode) +
+    (rules.hashCode) +
     (shared.hashCode) +
     (sharedUsers.hashCode) +
     (startDate == null ? 0 : startDate!.hashCode) +
     (updatedAt.hashCode);
 
   @override
-  String toString() => 'AlbumResponseDto[albumName=$albumName, albumThumbnailAssetId=$albumThumbnailAssetId, assetCount=$assetCount, assets=$assets, createdAt=$createdAt, description=$description, endDate=$endDate, hasSharedLink=$hasSharedLink, id=$id, lastModifiedAssetTimestamp=$lastModifiedAssetTimestamp, owner=$owner, ownerId=$ownerId, shared=$shared, sharedUsers=$sharedUsers, startDate=$startDate, updatedAt=$updatedAt]';
+  String toString() => 'AlbumResponseDto[albumName=$albumName, albumThumbnailAssetId=$albumThumbnailAssetId, assetCount=$assetCount, assets=$assets, createdAt=$createdAt, description=$description, endDate=$endDate, hasSharedLink=$hasSharedLink, id=$id, lastModifiedAssetTimestamp=$lastModifiedAssetTimestamp, owner=$owner, ownerId=$ownerId, rules=$rules, shared=$shared, sharedUsers=$sharedUsers, startDate=$startDate, updatedAt=$updatedAt]';
 
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
@@ -149,6 +154,7 @@ class AlbumResponseDto {
     }
       json[r'owner'] = this.owner;
       json[r'ownerId'] = this.ownerId;
+      json[r'rules'] = this.rules;
       json[r'shared'] = this.shared;
       json[r'sharedUsers'] = this.sharedUsers;
     if (this.startDate != null) {
@@ -180,6 +186,7 @@ class AlbumResponseDto {
         lastModifiedAssetTimestamp: mapDateTime(json, r'lastModifiedAssetTimestamp', ''),
         owner: UserResponseDto.fromJson(json[r'owner'])!,
         ownerId: mapValueOfType<String>(json, r'ownerId')!,
+        rules: RuleResponseDto.listFromJson(json[r'rules']),
         shared: mapValueOfType<bool>(json, r'shared')!,
         sharedUsers: UserResponseDto.listFromJson(json[r'sharedUsers']),
         startDate: mapDateTime(json, r'startDate', ''),
@@ -241,6 +248,7 @@ class AlbumResponseDto {
     'id',
     'owner',
     'ownerId',
+    'rules',
     'shared',
     'sharedUsers',
     'updatedAt',

+ 9 - 1
mobile/openapi/lib/model/all_job_status_response_dto.dart

@@ -20,6 +20,7 @@ class AllJobStatusResponseDto {
     required this.recognizeFaces,
     required this.search,
     required this.sidecar,
+    required this.smartAlbum,
     required this.storageTemplateMigration,
     required this.thumbnailGeneration,
     required this.videoConversion,
@@ -39,6 +40,8 @@ class AllJobStatusResponseDto {
 
   JobStatusDto sidecar;
 
+  JobStatusDto smartAlbum;
+
   JobStatusDto storageTemplateMigration;
 
   JobStatusDto thumbnailGeneration;
@@ -54,6 +57,7 @@ class AllJobStatusResponseDto {
      other.recognizeFaces == recognizeFaces &&
      other.search == search &&
      other.sidecar == sidecar &&
+     other.smartAlbum == smartAlbum &&
      other.storageTemplateMigration == storageTemplateMigration &&
      other.thumbnailGeneration == thumbnailGeneration &&
      other.videoConversion == videoConversion;
@@ -68,12 +72,13 @@ class AllJobStatusResponseDto {
     (recognizeFaces.hashCode) +
     (search.hashCode) +
     (sidecar.hashCode) +
+    (smartAlbum.hashCode) +
     (storageTemplateMigration.hashCode) +
     (thumbnailGeneration.hashCode) +
     (videoConversion.hashCode);
 
   @override
-  String toString() => 'AllJobStatusResponseDto[backgroundTask=$backgroundTask, clipEncoding=$clipEncoding, metadataExtraction=$metadataExtraction, objectTagging=$objectTagging, recognizeFaces=$recognizeFaces, search=$search, sidecar=$sidecar, storageTemplateMigration=$storageTemplateMigration, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion]';
+  String toString() => 'AllJobStatusResponseDto[backgroundTask=$backgroundTask, clipEncoding=$clipEncoding, metadataExtraction=$metadataExtraction, objectTagging=$objectTagging, recognizeFaces=$recognizeFaces, search=$search, sidecar=$sidecar, smartAlbum=$smartAlbum, storageTemplateMigration=$storageTemplateMigration, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion]';
 
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
@@ -84,6 +89,7 @@ class AllJobStatusResponseDto {
       json[r'recognizeFaces'] = this.recognizeFaces;
       json[r'search'] = this.search;
       json[r'sidecar'] = this.sidecar;
+      json[r'smartAlbum'] = this.smartAlbum;
       json[r'storageTemplateMigration'] = this.storageTemplateMigration;
       json[r'thumbnailGeneration'] = this.thumbnailGeneration;
       json[r'videoConversion'] = this.videoConversion;
@@ -105,6 +111,7 @@ class AllJobStatusResponseDto {
         recognizeFaces: JobStatusDto.fromJson(json[r'recognizeFaces'])!,
         search: JobStatusDto.fromJson(json[r'search'])!,
         sidecar: JobStatusDto.fromJson(json[r'sidecar'])!,
+        smartAlbum: JobStatusDto.fromJson(json[r'smartAlbum'])!,
         storageTemplateMigration: JobStatusDto.fromJson(json[r'storageTemplateMigration'])!,
         thumbnailGeneration: JobStatusDto.fromJson(json[r'thumbnailGeneration'])!,
         videoConversion: JobStatusDto.fromJson(json[r'videoConversion'])!,
@@ -162,6 +169,7 @@ class AllJobStatusResponseDto {
     'recognizeFaces',
     'search',
     'sidecar',
+    'smartAlbum',
     'storageTemplateMigration',
     'thumbnailGeneration',
     'videoConversion',

+ 3 - 0
mobile/openapi/lib/model/job_name.dart

@@ -33,6 +33,7 @@ class JobName {
   static const storageTemplateMigration = JobName._(r'storageTemplateMigration');
   static const search = JobName._(r'search');
   static const sidecar = JobName._(r'sidecar');
+  static const smartAlbum = JobName._(r'smartAlbum');
 
   /// List of all possible values in this [enum][JobName].
   static const values = <JobName>[
@@ -46,6 +47,7 @@ class JobName {
     storageTemplateMigration,
     search,
     sidecar,
+    smartAlbum,
   ];
 
   static JobName? fromJson(dynamic value) => JobNameTypeTransformer().decode(value);
@@ -94,6 +96,7 @@ class JobNameTypeTransformer {
         case r'storageTemplateMigration': return JobName.storageTemplateMigration;
         case r'search': return JobName.search;
         case r'sidecar': return JobName.sidecar;
+        case r'smartAlbum': return JobName.smartAlbum;
         default:
           if (!allowNull) {
             throw ArgumentError('Unknown enum value to decode: $data');

+ 103 - 0
mobile/openapi/lib/model/rule_key.dart

@@ -0,0 +1,103 @@
+//
+// 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 RuleKey {
+  /// Instantiate a new enum with the provided [value].
+  const RuleKey._(this.value);
+
+  /// The underlying value of this enum member.
+  final String value;
+
+  @override
+  String toString() => value;
+
+  String toJson() => value;
+
+  static const person = RuleKey._(r'person');
+  static const takenAfter = RuleKey._(r'taken-after');
+  static const city = RuleKey._(r'city');
+  static const state = RuleKey._(r'state');
+  static const country = RuleKey._(r'country');
+  static const make = RuleKey._(r'make');
+  static const model = RuleKey._(r'model');
+  static const location = RuleKey._(r'location');
+
+  /// List of all possible values in this [enum][RuleKey].
+  static const values = <RuleKey>[
+    person,
+    takenAfter,
+    city,
+    state,
+    country,
+    make,
+    model,
+    location,
+  ];
+
+  static RuleKey? fromJson(dynamic value) => RuleKeyTypeTransformer().decode(value);
+
+  static List<RuleKey>? listFromJson(dynamic json, {bool growable = false,}) {
+    final result = <RuleKey>[];
+    if (json is List && json.isNotEmpty) {
+      for (final row in json) {
+        final value = RuleKey.fromJson(row);
+        if (value != null) {
+          result.add(value);
+        }
+      }
+    }
+    return result.toList(growable: growable);
+  }
+}
+
+/// Transformation class that can [encode] an instance of [RuleKey] to String,
+/// and [decode] dynamic data back to [RuleKey].
+class RuleKeyTypeTransformer {
+  factory RuleKeyTypeTransformer() => _instance ??= const RuleKeyTypeTransformer._();
+
+  const RuleKeyTypeTransformer._();
+
+  String encode(RuleKey data) => data.value;
+
+  /// Decodes a [dynamic value][data] to a RuleKey.
+  ///
+  /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully,
+  /// then null is returned. However, if [allowNull] is false and the [dynamic value][data]
+  /// cannot be decoded successfully, then an [UnimplementedError] is thrown.
+  ///
+  /// The [allowNull] is very handy when an API changes and a new enum value is added or removed,
+  /// and users are still using an old app with the old code.
+  RuleKey? decode(dynamic data, {bool allowNull = true}) {
+    if (data != null) {
+      switch (data) {
+        case r'person': return RuleKey.person;
+        case r'taken-after': return RuleKey.takenAfter;
+        case r'city': return RuleKey.city;
+        case r'state': return RuleKey.state;
+        case r'country': return RuleKey.country;
+        case r'make': return RuleKey.make;
+        case r'model': return RuleKey.model;
+        case r'location': return RuleKey.location;
+        default:
+          if (!allowNull) {
+            throw ArgumentError('Unknown enum value to decode: $data');
+          }
+      }
+    }
+    return null;
+  }
+
+  /// Singleton [RuleKeyTypeTransformer] instance.
+  static RuleKeyTypeTransformer? _instance;
+}
+

+ 122 - 0
mobile/openapi/lib/model/rule_response_dto.dart

@@ -0,0 +1,122 @@
+//
+// 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 RuleResponseDto {
+  /// Returns a new [RuleResponseDto] instance.
+  RuleResponseDto({
+    required this.id,
+    required this.key,
+    required this.ownerId,
+    required this.value,
+  });
+
+  String id;
+
+  RuleKey key;
+
+  String ownerId;
+
+  Object value;
+
+  @override
+  bool operator ==(Object other) => identical(this, other) || other is RuleResponseDto &&
+     other.id == id &&
+     other.key == key &&
+     other.ownerId == ownerId &&
+     other.value == value;
+
+  @override
+  int get hashCode =>
+    // ignore: unnecessary_parenthesis
+    (id.hashCode) +
+    (key.hashCode) +
+    (ownerId.hashCode) +
+    (value.hashCode);
+
+  @override
+  String toString() => 'RuleResponseDto[id=$id, key=$key, ownerId=$ownerId, value=$value]';
+
+  Map<String, dynamic> toJson() {
+    final json = <String, dynamic>{};
+      json[r'id'] = this.id;
+      json[r'key'] = this.key;
+      json[r'ownerId'] = this.ownerId;
+      json[r'value'] = this.value;
+    return json;
+  }
+
+  /// Returns a new [RuleResponseDto] instance and imports its values from
+  /// [value] if it's a [Map], null otherwise.
+  // ignore: prefer_constructors_over_static_methods
+  static RuleResponseDto? fromJson(dynamic value) {
+    if (value is Map) {
+      final json = value.cast<String, dynamic>();
+
+      return RuleResponseDto(
+        id: mapValueOfType<String>(json, r'id')!,
+        key: RuleKey.fromJson(json[r'key'])!,
+        ownerId: mapValueOfType<String>(json, r'ownerId')!,
+        value: mapValueOfType<Object>(json, r'value')!,
+      );
+    }
+    return null;
+  }
+
+  static List<RuleResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
+    final result = <RuleResponseDto>[];
+    if (json is List && json.isNotEmpty) {
+      for (final row in json) {
+        final value = RuleResponseDto.fromJson(row);
+        if (value != null) {
+          result.add(value);
+        }
+      }
+    }
+    return result.toList(growable: growable);
+  }
+
+  static Map<String, RuleResponseDto> mapFromJson(dynamic json) {
+    final map = <String, RuleResponseDto>{};
+    if (json is Map && json.isNotEmpty) {
+      json = json.cast<String, dynamic>(); // ignore: parameter_assignments
+      for (final entry in json.entries) {
+        final value = RuleResponseDto.fromJson(entry.value);
+        if (value != null) {
+          map[entry.key] = value;
+        }
+      }
+    }
+    return map;
+  }
+
+  // maps a json object with a list of RuleResponseDto-objects as value to a dart map
+  static Map<String, List<RuleResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
+    final map = <String, List<RuleResponseDto>>{};
+    if (json is Map && json.isNotEmpty) {
+      // ignore: parameter_assignments
+      json = json.cast<String, dynamic>();
+      for (final entry in json.entries) {
+        map[entry.key] = RuleResponseDto.listFromJson(entry.value, growable: growable,);
+      }
+    }
+    return map;
+  }
+
+  /// The list of required keys that must be present in a JSON.
+  static const requiredKeys = <String>{
+    'id',
+    'key',
+    'ownerId',
+    'value',
+  };
+}
+

+ 9 - 1
mobile/openapi/lib/model/system_config_job_dto.dart

@@ -20,6 +20,7 @@ class SystemConfigJobDto {
     required this.recognizeFaces,
     required this.search,
     required this.sidecar,
+    required this.smartAlbum,
     required this.storageTemplateMigration,
     required this.thumbnailGeneration,
     required this.videoConversion,
@@ -39,6 +40,8 @@ class SystemConfigJobDto {
 
   JobSettingsDto sidecar;
 
+  JobSettingsDto smartAlbum;
+
   JobSettingsDto storageTemplateMigration;
 
   JobSettingsDto thumbnailGeneration;
@@ -54,6 +57,7 @@ class SystemConfigJobDto {
      other.recognizeFaces == recognizeFaces &&
      other.search == search &&
      other.sidecar == sidecar &&
+     other.smartAlbum == smartAlbum &&
      other.storageTemplateMigration == storageTemplateMigration &&
      other.thumbnailGeneration == thumbnailGeneration &&
      other.videoConversion == videoConversion;
@@ -68,12 +72,13 @@ class SystemConfigJobDto {
     (recognizeFaces.hashCode) +
     (search.hashCode) +
     (sidecar.hashCode) +
+    (smartAlbum.hashCode) +
     (storageTemplateMigration.hashCode) +
     (thumbnailGeneration.hashCode) +
     (videoConversion.hashCode);
 
   @override
-  String toString() => 'SystemConfigJobDto[backgroundTask=$backgroundTask, clipEncoding=$clipEncoding, metadataExtraction=$metadataExtraction, objectTagging=$objectTagging, recognizeFaces=$recognizeFaces, search=$search, sidecar=$sidecar, storageTemplateMigration=$storageTemplateMigration, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion]';
+  String toString() => 'SystemConfigJobDto[backgroundTask=$backgroundTask, clipEncoding=$clipEncoding, metadataExtraction=$metadataExtraction, objectTagging=$objectTagging, recognizeFaces=$recognizeFaces, search=$search, sidecar=$sidecar, smartAlbum=$smartAlbum, storageTemplateMigration=$storageTemplateMigration, thumbnailGeneration=$thumbnailGeneration, videoConversion=$videoConversion]';
 
   Map<String, dynamic> toJson() {
     final json = <String, dynamic>{};
@@ -84,6 +89,7 @@ class SystemConfigJobDto {
       json[r'recognizeFaces'] = this.recognizeFaces;
       json[r'search'] = this.search;
       json[r'sidecar'] = this.sidecar;
+      json[r'smartAlbum'] = this.smartAlbum;
       json[r'storageTemplateMigration'] = this.storageTemplateMigration;
       json[r'thumbnailGeneration'] = this.thumbnailGeneration;
       json[r'videoConversion'] = this.videoConversion;
@@ -105,6 +111,7 @@ class SystemConfigJobDto {
         recognizeFaces: JobSettingsDto.fromJson(json[r'recognizeFaces'])!,
         search: JobSettingsDto.fromJson(json[r'search'])!,
         sidecar: JobSettingsDto.fromJson(json[r'sidecar'])!,
+        smartAlbum: JobSettingsDto.fromJson(json[r'smartAlbum'])!,
         storageTemplateMigration: JobSettingsDto.fromJson(json[r'storageTemplateMigration'])!,
         thumbnailGeneration: JobSettingsDto.fromJson(json[r'thumbnailGeneration'])!,
         videoConversion: JobSettingsDto.fromJson(json[r'videoConversion'])!,
@@ -162,6 +169,7 @@ class SystemConfigJobDto {
     'recognizeFaces',
     'search',
     'sidecar',
+    'smartAlbum',
     'storageTemplateMigration',
     'thumbnailGeneration',
     'videoConversion',

+ 5 - 0
mobile/openapi/test/album_response_dto_test.dart

@@ -76,6 +76,11 @@ void main() {
       // TODO
     });
 
+    // List<RuleResponseDto> rules (default value: const [])
+    test('to test the property `rules`', () async {
+      // TODO
+    });
+
     // bool shared
     test('to test the property `shared`', () async {
       // TODO

+ 5 - 0
mobile/openapi/test/all_job_status_response_dto_test.dart

@@ -51,6 +51,11 @@ void main() {
       // TODO
     });
 
+    // JobStatusDto smartAlbum
+    test('to test the property `smartAlbum`', () async {
+      // TODO
+    });
+
     // JobStatusDto storageTemplateMigration
     test('to test the property `storageTemplateMigration`', () async {
       // TODO

+ 21 - 0
mobile/openapi/test/rule_key_test.dart

@@ -0,0 +1,21 @@
+//
+// AUTO-GENERATED FILE, DO NOT MODIFY!
+//
+// @dart=2.12
+
+// ignore_for_file: unused_element, unused_import
+// ignore_for_file: always_put_required_named_parameters_first
+// ignore_for_file: constant_identifier_names
+// ignore_for_file: lines_longer_than_80_chars
+
+import 'package:openapi/api.dart';
+import 'package:test/test.dart';
+
+// tests for RuleKey
+void main() {
+
+  group('test RuleKey', () {
+
+  });
+
+}

+ 42 - 0
mobile/openapi/test/rule_response_dto_test.dart

@@ -0,0 +1,42 @@
+//
+// AUTO-GENERATED FILE, DO NOT MODIFY!
+//
+// @dart=2.12
+
+// ignore_for_file: unused_element, unused_import
+// ignore_for_file: always_put_required_named_parameters_first
+// ignore_for_file: constant_identifier_names
+// ignore_for_file: lines_longer_than_80_chars
+
+import 'package:openapi/api.dart';
+import 'package:test/test.dart';
+
+// tests for RuleResponseDto
+void main() {
+  // final instance = RuleResponseDto();
+
+  group('test RuleResponseDto', () {
+    // String id
+    test('to test the property `id`', () async {
+      // TODO
+    });
+
+    // RuleKey key
+    test('to test the property `key`', () async {
+      // TODO
+    });
+
+    // String ownerId
+    test('to test the property `ownerId`', () async {
+      // TODO
+    });
+
+    // Object value
+    test('to test the property `value`', () async {
+      // TODO
+    });
+
+
+  });
+
+}

+ 5 - 0
mobile/openapi/test/system_config_job_dto_test.dart

@@ -51,6 +51,11 @@ void main() {
       // TODO
     });
 
+    // JobSettingsDto smartAlbum
+    test('to test the property `smartAlbum`', () async {
+      // TODO
+    });
+
     // JobSettingsDto storageTemplateMigration
     test('to test the property `storageTemplateMigration`', () async {
       // TODO

+ 73 - 1
web/src/api/open-api/api.ts

@@ -252,6 +252,12 @@ export interface AlbumResponseDto {
      * @memberof AlbumResponseDto
      */
     'ownerId': string;
+    /**
+     * 
+     * @type {Array<RuleResponseDto>}
+     * @memberof AlbumResponseDto
+     */
+    'rules': Array<RuleResponseDto>;
     /**
      * 
      * @type {boolean}
@@ -325,6 +331,12 @@ export interface AllJobStatusResponseDto {
      * @memberof AllJobStatusResponseDto
      */
     'sidecar': JobStatusDto;
+    /**
+     * 
+     * @type {JobStatusDto}
+     * @memberof AllJobStatusResponseDto
+     */
+    'smartAlbum': JobStatusDto;
     /**
      * 
      * @type {JobStatusDto}
@@ -1453,7 +1465,8 @@ export const JobName = {
     BackgroundTask: 'backgroundTask',
     StorageTemplateMigration: 'storageTemplateMigration',
     Search: 'search',
-    Sidecar: 'sidecar'
+    Sidecar: 'sidecar',
+    SmartAlbum: 'smartAlbum'
 } as const;
 
 export type JobName = typeof JobName[keyof typeof JobName];
@@ -1848,6 +1861,59 @@ export interface QueueStatusDto {
      */
     'isPaused': boolean;
 }
+/**
+ * 
+ * @export
+ * @enum {string}
+ */
+
+export const RuleKey = {
+    Person: 'person',
+    TakenAfter: 'taken-after',
+    City: 'city',
+    State: 'state',
+    Country: 'country',
+    Make: 'make',
+    Model: 'model',
+    Location: 'location'
+} as const;
+
+export type RuleKey = typeof RuleKey[keyof typeof RuleKey];
+
+
+/**
+ * 
+ * @export
+ * @interface RuleResponseDto
+ */
+export interface RuleResponseDto {
+    /**
+     * 
+     * @type {string}
+     * @memberof RuleResponseDto
+     */
+    'id': string;
+    /**
+     * 
+     * @type {RuleKey}
+     * @memberof RuleResponseDto
+     */
+    'key': RuleKey;
+    /**
+     * 
+     * @type {string}
+     * @memberof RuleResponseDto
+     */
+    'ownerId': string;
+    /**
+     * 
+     * @type {object}
+     * @memberof RuleResponseDto
+     */
+    'value': object;
+}
+
+
 /**
  * 
  * @export
@@ -2579,6 +2645,12 @@ export interface SystemConfigJobDto {
      * @memberof SystemConfigJobDto
      */
     'sidecar': JobSettingsDto;
+    /**
+     * 
+     * @type {JobSettingsDto}
+     * @memberof SystemConfigJobDto
+     */
+    'smartAlbum': JobSettingsDto;
     /**
      * 
      * @type {JobSettingsDto}