diff --git a/back/src/Kyoo.Abstractions/Models/LibraryItem.cs b/back/src/Kyoo.Abstractions/Models/Attributes/OneOf.cs
similarity index 55%
rename from back/src/Kyoo.Abstractions/Models/LibraryItem.cs
rename to back/src/Kyoo.Abstractions/Models/Attributes/OneOf.cs
index 14fc8aa0..de064603 100644
--- a/back/src/Kyoo.Abstractions/Models/LibraryItem.cs
+++ b/back/src/Kyoo.Abstractions/Models/Attributes/OneOf.cs
@@ -17,33 +17,17 @@
// along with Kyoo. If not, see .
using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Text.Json.Serialization;
-using Kyoo.Utils;
-namespace Kyoo.Abstractions.Models
+namespace Kyoo.Abstractions.Models.Attributes;
+
+///
+/// An attribute to inform that this interface is a type union
+///
+[AttributeUsage(AttributeTargets.Interface)]
+public class OneOfAttribute : Attribute
{
///
- /// The type of item, ether a show, a movie or a collection.
+ /// The types this union concist of.
///
- public enum ItemKind
- {
- ///
- /// The is a .
- ///
- Show,
-
- ///
- /// The is a Movie.
- ///
- Movie,
-
- ///
- /// The is a .
- ///
- Collection
- }
-
- public interface ILibraryItem : IResource, IThumbnails, IMetadata, IAddedDate { }
+ public Type[] Types { get; set; }
}
diff --git a/back/src/Kyoo.Abstractions/Models/ILibraryItem.cs b/back/src/Kyoo.Abstractions/Models/ILibraryItem.cs
new file mode 100644
index 00000000..bdeb61d5
--- /dev/null
+++ b/back/src/Kyoo.Abstractions/Models/ILibraryItem.cs
@@ -0,0 +1,27 @@
+// Kyoo - A portable and vast media library solution.
+// Copyright (c) Kyoo.
+//
+// See AUTHORS.md and LICENSE file in the project root for full license information.
+//
+// Kyoo is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// Kyoo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Kyoo. If not, see .
+
+using Kyoo.Abstractions.Models.Attributes;
+
+namespace Kyoo.Abstractions.Models;
+
+///
+/// A show, a movie or a collection.
+///
+[OneOf(Types = new[] { typeof(Show), typeof(Movie), typeof(Collection) })]
+public interface ILibraryItem : IResource, IThumbnails, IMetadata, IAddedDate { }
diff --git a/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs b/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs
index f7e70dd1..0eac4667 100644
--- a/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs
+++ b/back/src/Kyoo.Core/Controllers/Repositories/LibraryItemRepository.cs
@@ -98,7 +98,7 @@ namespace Kyoo.Core.Controllers
// TODO: Implement default sort by
Sort.Default => $"coalesce({string.Join(", ", tables.Select(x => $"{x}.name"))})",
Sort.By(string key, bool desc) => $"coalesce({string.Join(", ", tables.Select(x => $"{x}.{key}"))}) {(desc ? "desc" : "asc")}",
- Sort.Random(var seed) => $"md5({seed} || coalesce({string.Join(", ", tables.Select(x => $"{x}.id"))}))",
+ Sort.Random(var seed) => $"md5('{seed}' || coalesce({string.Join(", ", tables.Select(x => $"{x}.id"))}))",
Sort.Conglomerate(var list) => string.Join(", ", list.Select(x => ProcessSort(x, tables))),
_ => throw new SwitchExpressionException(),
};
diff --git a/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs b/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
index d9ca24dc..a2e086e5 100644
--- a/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
+++ b/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
@@ -16,7 +16,9 @@
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see .
+using System;
using System.Collections.Generic;
+using System.Linq;
using System.Reflection;
using Kyoo.Abstractions.Models;
using Kyoo.Abstractions.Models.Attributes;
@@ -58,8 +60,7 @@ namespace Kyoo.Core.Api
{
property.ShouldSerialize = _ =>
{
- ICollection? fields = (ICollection)_httpContextAccessor.HttpContext!.Items["fields"]!;
- if (fields == null)
+ if (_httpContextAccessor.HttpContext!.Items["fields"] is not ICollection fields)
return false;
return fields.Contains(member.Name);
};
@@ -71,5 +72,43 @@ namespace Kyoo.Core.Api
property.ShouldDeserialize = _ => false;
return property;
}
+
+ protected override IList CreateProperties(Type type, MemberSerialization memberSerialization)
+ {
+ IList properties = base.CreateProperties(type, memberSerialization);
+
+ if (properties.All(x => x.PropertyName != "kind"))
+ {
+ properties.Add(new JsonProperty()
+ {
+ DeclaringType = type,
+ PropertyName = "kind",
+ UnderlyingName = "kind",
+ PropertyType = typeof(string),
+ ValueProvider = new FixedValueProvider(type.Name),
+ Readable = true,
+ Writable = false,
+ TypeNameHandling = TypeNameHandling.None,
+ });
+ }
+
+ return properties;
+ }
+
+ public class FixedValueProvider : IValueProvider
+ {
+ private readonly object _value;
+
+ public FixedValueProvider(object value)
+ {
+ _value = value;
+ }
+
+ public object GetValue(object target)
+ => _value;
+
+ public void SetValue(object target, object? value)
+ => throw new NotImplementedException();
+ }
}
}