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(); + } } }