diff --git a/src/Kyoo.Abstractions/Models/Attributes/Serializer/SerializeAsAttribute.cs b/src/Kyoo.Abstractions/Models/Attributes/Serializer/SerializeAsAttribute.cs deleted file mode 100644 index 6e2a8983..00000000 --- a/src/Kyoo.Abstractions/Models/Attributes/Serializer/SerializeAsAttribute.cs +++ /dev/null @@ -1,51 +0,0 @@ -// 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 System; - -namespace Kyoo.Abstractions.Models.Attributes -{ - /// - /// Change the way the field is serialized. It allow one to use a string format like formatting instead of the default value. - /// This can be disabled for a request by setting the "internal" query string parameter to true. - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] - public class SerializeAsAttribute : Attribute - { - /// - /// The format string to use. - /// - public string Format { get; } - - /// - /// Create a new with the selected format. - /// - /// - /// The format string can contains any property within {}. It will be replaced by the actual value of the property. - /// You can also use the special value {HOST} that will put the webhost address. - /// - /// - /// The show's poster serialized uses this format string: {HOST}/api/shows/{Slug}/poster - /// - /// The format to use - public SerializeAsAttribute(string format) - { - Format = format; - } - } -} diff --git a/src/Kyoo.Abstractions/Models/LibraryItem.cs b/src/Kyoo.Abstractions/Models/LibraryItem.cs index c572f6a4..7dfbb4ea 100644 --- a/src/Kyoo.Abstractions/Models/LibraryItem.cs +++ b/src/Kyoo.Abstractions/Models/LibraryItem.cs @@ -19,7 +19,6 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; -using Kyoo.Abstractions.Models.Attributes; namespace Kyoo.Abstractions.Models { @@ -86,14 +85,6 @@ namespace Kyoo.Abstractions.Models /// public Dictionary Images { get; set; } - /// - /// The path of this item's poster. - /// By default, the http path for this poster is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/{Type:l}/{Slug}/poster")] - public string Poster => Images?.GetValueOrDefault(Models.Images.Poster); - /// /// The type of this item (ether a collection, a show or a movie). /// diff --git a/src/Kyoo.Abstractions/Models/Resources/Collection.cs b/src/Kyoo.Abstractions/Models/Resources/Collection.cs index 5f48fee1..101781f4 100644 --- a/src/Kyoo.Abstractions/Models/Resources/Collection.cs +++ b/src/Kyoo.Abstractions/Models/Resources/Collection.cs @@ -16,7 +16,6 @@ // 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 Kyoo.Abstractions.Models.Attributes; @@ -42,15 +41,6 @@ namespace Kyoo.Abstractions.Models /// public Dictionary Images { get; set; } - /// - /// The path of this poster. - /// By default, the http path for this poster is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/collection/{Slug}/poster")] - [Obsolete("Use Images instead of this, this is only kept for the API response.")] - public string Poster => Images?.GetValueOrDefault(Models.Images.Poster); - /// /// The description of this collection. /// diff --git a/src/Kyoo.Abstractions/Models/Resources/Episode.cs b/src/Kyoo.Abstractions/Models/Resources/Episode.cs index 83f82b08..42e9ecee 100644 --- a/src/Kyoo.Abstractions/Models/Resources/Episode.cs +++ b/src/Kyoo.Abstractions/Models/Resources/Episode.cs @@ -127,15 +127,6 @@ namespace Kyoo.Abstractions.Models /// public Dictionary Images { get; set; } - /// - /// The path of this episode's thumbnail. - /// By default, the http path for the thumbnail is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/episodes/{Slug}/thumbnail")] - [Obsolete("Use Images instead of this, this is only kept for the API response.")] - public string Thumb => Images?.GetValueOrDefault(Models.Images.Thumbnail); - /// /// The title of this episode. /// diff --git a/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs b/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs index e2d83e78..1fdb34f0 100644 --- a/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs +++ b/src/Kyoo.Abstractions/Models/Resources/Interfaces/IThumbnails.cs @@ -34,8 +34,6 @@ namespace Kyoo.Abstractions.Models /// An arbitrary index should not be used, instead use indexes from /// public Dictionary Images { get; set; } - - // TODO remove Posters properties add them via the json serializer for every IThumbnails } /// @@ -63,5 +61,17 @@ namespace Kyoo.Abstractions.Models /// A video of a few minutes that tease the content. /// public const int Trailer = 3; + + /// + /// Retrieve the name of an image using it's ID. It is also used by the serializer to retrieve all named images. + /// If a plugin adds a new image type, it should add it's value and name here to allow the serializer to add it. + /// + public static Dictionary ImageName { get; } = new() + { + [Poster] = nameof(Poster), + [Thumbnail] = nameof(Thumbnail), + [Logo] = nameof(Logo), + [Trailer] = nameof(Trailer) + }; } } diff --git a/src/Kyoo.Abstractions/Models/Resources/People.cs b/src/Kyoo.Abstractions/Models/Resources/People.cs index e1070545..71f9012d 100644 --- a/src/Kyoo.Abstractions/Models/Resources/People.cs +++ b/src/Kyoo.Abstractions/Models/Resources/People.cs @@ -16,7 +16,6 @@ // 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 Kyoo.Abstractions.Models.Attributes; @@ -41,15 +40,6 @@ namespace Kyoo.Abstractions.Models /// public Dictionary Images { get; set; } - /// - /// The path of this poster. - /// By default, the http path for this poster is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/people/{Slug}/poster")] - [Obsolete("Use Images instead of this, this is only kept for the API response.")] - public string Poster => Images?.GetValueOrDefault(Models.Images.Poster); - /// [EditableRelation] [LoadableRelation] public ICollection ExternalIDs { get; set; } diff --git a/src/Kyoo.Abstractions/Models/Resources/Provider.cs b/src/Kyoo.Abstractions/Models/Resources/Provider.cs index 74401045..e1c10de3 100644 --- a/src/Kyoo.Abstractions/Models/Resources/Provider.cs +++ b/src/Kyoo.Abstractions/Models/Resources/Provider.cs @@ -16,7 +16,6 @@ // 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 Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models.Attributes; @@ -44,15 +43,6 @@ namespace Kyoo.Abstractions.Models /// public Dictionary Images { get; set; } - /// - /// The path of this provider's logo. - /// By default, the http path for this logo is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/providers/{Slug}/logo")] - [Obsolete("Use Images instead of this, this is only kept for the API response.")] - public string Logo => Images?.GetValueOrDefault(Models.Images.Logo); - /// /// The list of libraries that uses this provider. /// diff --git a/src/Kyoo.Abstractions/Models/Resources/Season.cs b/src/Kyoo.Abstractions/Models/Resources/Season.cs index f219f483..29d22d44 100644 --- a/src/Kyoo.Abstractions/Models/Resources/Season.cs +++ b/src/Kyoo.Abstractions/Models/Resources/Season.cs @@ -98,15 +98,6 @@ namespace Kyoo.Abstractions.Models /// public Dictionary Images { get; set; } - /// - /// The path of this poster. - /// By default, the http path for this poster is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/seasons/{Slug}/thumb")] - [Obsolete("Use Images instead of this, this is only kept for the API response.")] - public string Poster => Images?.GetValueOrDefault(Models.Images.Poster); - /// [EditableRelation] [LoadableRelation] public ICollection ExternalIDs { get; set; } diff --git a/src/Kyoo.Abstractions/Models/Resources/Show.cs b/src/Kyoo.Abstractions/Models/Resources/Show.cs index 87e00052..97061446 100644 --- a/src/Kyoo.Abstractions/Models/Resources/Show.cs +++ b/src/Kyoo.Abstractions/Models/Resources/Show.cs @@ -82,33 +82,6 @@ namespace Kyoo.Abstractions.Models /// public Dictionary Images { get; set; } - /// - /// The path of this show's poster. - /// By default, the http path for this poster is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/shows/{Slug}/poster")] - [Obsolete("Use Images instead of this, this is only kept for the API response.")] - public string Poster => Images?.GetValueOrDefault(Models.Images.Poster); - - /// - /// The path of this show's logo. - /// By default, the http path for this logo is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/shows/{Slug}/logo")] - [Obsolete("Use Images instead of this, this is only kept for the API response.")] - public string Logo => Images?.GetValueOrDefault(Models.Images.Logo); - - /// - /// The path of this show's backdrop. - /// By default, the http path for this backdrop is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/shows/{Slug}/backdrop")] - [Obsolete("Use Images instead of this, this is only kept for the API response.")] - public string Backdrop => Images?.GetValueOrDefault(Models.Images.Thumbnail); - /// /// True if this show represent a movie, false otherwise. /// diff --git a/src/Kyoo.Abstractions/Models/WatchItem.cs b/src/Kyoo.Abstractions/Models/WatchItem.cs index 5bbf0fb8..3af919b9 100644 --- a/src/Kyoo.Abstractions/Models/WatchItem.cs +++ b/src/Kyoo.Abstractions/Models/WatchItem.cs @@ -101,27 +101,6 @@ namespace Kyoo.Abstractions.Models /// public bool IsMovie { get; set; } - /// - /// The path of this item's poster. - /// By default, the http path for the poster is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/show/{ShowSlug}/poster")] public string Poster { get; set; } - - /// - /// The path of this item's logo. - /// By default, the http path for the logo is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/show/{ShowSlug}/logo")] public string Logo { get; set; } - - /// - /// The path of this item's backdrop. - /// By default, the http path for the backdrop is returned from the public API. - /// This can be disabled using the internal query flag. - /// - [SerializeAs("{HOST}/api/show/{ShowSlug}/backdrop")] public string Backdrop { get; set; } - /// /// The container of the video file of this episode. /// Common containers are mp4, mkv, avi and so on. diff --git a/src/Kyoo.Core/Views/Helper/ApiHelper.cs b/src/Kyoo.Core/Views/Helper/ApiHelper.cs index a1e2c617..60adae50 100644 --- a/src/Kyoo.Core/Views/Helper/ApiHelper.cs +++ b/src/Kyoo.Core/Views/Helper/ApiHelper.cs @@ -36,7 +36,7 @@ namespace Kyoo.Core.Api /// Make an expression (like /// /// compatible with strings). If the expressions are not strings, the given is - /// constructed but if the expressions are strings, this method make the compatible with + /// constructed but if the expressions are strings, this method make the compatible with /// strings. /// /// diff --git a/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs b/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs index 0fef35fc..0fb6ee72 100644 --- a/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs +++ b/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs @@ -16,6 +16,7 @@ // 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.Reflection; using Kyoo.Abstractions.Models; @@ -70,13 +71,74 @@ namespace Kyoo.Core.Api property.ShouldSerialize = _ => false; if (member.GetCustomAttribute() != null) property.ShouldDeserialize = _ => false; - - // TODO use http context to disable serialize as. - // TODO check https://stackoverflow.com/questions/53288633/net-core-api-custom-json-resolver-based-on-request-values - // SerializeAsAttribute serializeAs = member.GetCustomAttribute(); - // if (serializeAs != null) - // property.ValueProvider = new SerializeAsProvider(serializeAs.Format, _host); return property; } + + /// + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + IList properties = base.CreateProperties(type, memberSerialization); + if (!type.IsAssignableTo(typeof(IThumbnails))) + return properties; + foreach ((int id, string image) in Images.ImageName) + { + properties.Add(new JsonProperty + { + DeclaringType = type, + PropertyName = image.ToLower(), + UnderlyingName = image, + PropertyType = typeof(string), + Readable = true, + Writable = false, + ItemIsReference = false, + TypeNameHandling = TypeNameHandling.None, + ShouldSerialize = x => + { + IThumbnails thumb = (IThumbnails)x; + return thumb.Images?.ContainsKey(id) == true; + }, + ValueProvider = new ThumbnailProvider(id) + }); + } + + return properties; + } + + /// + /// A custom that uses the + /// . as a value. + /// + private class ThumbnailProvider : IValueProvider + { + /// + /// The index/ID of the image to retrieve/set. + /// + private readonly int _imageIndex; + + /// + /// Create a new . + /// + /// The index/ID of the image to retrieve/set. + public ThumbnailProvider(int imageIndex) + { + _imageIndex = imageIndex; + } + + /// + public void SetValue(object target, object value) + { + if (target is not IThumbnails thumb) + throw new ArgumentException($"The given object is not an Thumbnail."); + thumb.Images[_imageIndex] = value as string; + } + + /// + public object GetValue(object target) + { + if (target is IThumbnails thumb) + return thumb.Images?.GetValueOrDefault(_imageIndex); + return null; + } + } } } diff --git a/src/Kyoo.Core/Views/Helper/Serializers/SerializeAsProvider.cs b/src/Kyoo.Core/Views/Helper/Serializers/SerializeAsProvider.cs deleted file mode 100644 index ff104fa7..00000000 --- a/src/Kyoo.Core/Views/Helper/Serializers/SerializeAsProvider.cs +++ /dev/null @@ -1,77 +0,0 @@ -// 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 System; -using System.Linq; -using System.Reflection; -using System.Text.RegularExpressions; -using Newtonsoft.Json.Serialization; - -namespace Kyoo.Core.Api -{ - public class SerializeAsProvider : IValueProvider - { - private readonly string _format; - private readonly Uri _host; - - public SerializeAsProvider(string format, Uri host) - { - _format = format; - _host = host; - } - - public object GetValue(object target) - { - return Regex.Replace(_format, @"(? - { - string value = x.Groups[1].Value; - string modifier = x.Groups[3].Value; - - if (value == "HOST") - return _host.ToString().TrimEnd('/'); - - PropertyInfo properties = target.GetType() - .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) - .FirstOrDefault(y => y.Name == value); - if (properties == null) - return null; - object objValue = properties.GetValue(target); - if (objValue is not string ret) - ret = objValue?.ToString(); - if (ret == null) - throw new ArgumentException($"Invalid serializer replacement {value}"); - - foreach (char modification in modifier) - { - ret = modification switch - { - 'l' => ret.ToLowerInvariant(), - 'u' => ret.ToUpperInvariant(), - _ => throw new ArgumentException($"Invalid serializer modificator {modification}.") - }; - } - return ret; - }); - } - - public void SetValue(object target, object value) - { - // Values are ignored and should not be editable, except if the internal value is set. - } - } -} diff --git a/src/Kyoo.Postgresql/Migrations/20210801171613_Initial.Designer.cs b/src/Kyoo.Postgresql/Migrations/20210801171613_Initial.Designer.cs index 0f7db480..02a66b0d 100644 --- a/src/Kyoo.Postgresql/Migrations/20210801171613_Initial.Designer.cs +++ b/src/Kyoo.Postgresql/Migrations/20210801171613_Initial.Designer.cs @@ -15,7 +15,8 @@ namespace Kyoo.Postgresql.Migrations [Migration("20210801171613_Initial")] partial class Initial { - protected override void BuildTargetModel(ModelBuilder modelBuilder) + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder diff --git a/src/Kyoo.Postgresql/Migrations/20210801171641_Triggers.Designer.cs b/src/Kyoo.Postgresql/Migrations/20210801171641_Triggers.Designer.cs index 51d369e9..de520a04 100644 --- a/src/Kyoo.Postgresql/Migrations/20210801171641_Triggers.Designer.cs +++ b/src/Kyoo.Postgresql/Migrations/20210801171641_Triggers.Designer.cs @@ -15,6 +15,7 @@ namespace Kyoo.Postgresql.Migrations [Migration("20210801171641_Triggers")] partial class Triggers { + /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 diff --git a/src/Kyoo.SqLite/Migrations/20210801171534_Initial.Designer.cs b/src/Kyoo.SqLite/Migrations/20210801171534_Initial.Designer.cs index d01507a7..e912d60a 100644 --- a/src/Kyoo.SqLite/Migrations/20210801171534_Initial.Designer.cs +++ b/src/Kyoo.SqLite/Migrations/20210801171534_Initial.Designer.cs @@ -12,6 +12,7 @@ namespace Kyoo.SqLite.Migrations [Migration("20210801171534_Initial")] partial class Initial { + /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 diff --git a/src/Kyoo.SqLite/Migrations/20210801171544_Triggers.Designer.cs b/src/Kyoo.SqLite/Migrations/20210801171544_Triggers.Designer.cs index 0ca18ed6..1576e9e3 100644 --- a/src/Kyoo.SqLite/Migrations/20210801171544_Triggers.Designer.cs +++ b/src/Kyoo.SqLite/Migrations/20210801171544_Triggers.Designer.cs @@ -12,6 +12,7 @@ namespace Kyoo.SqLite.Migrations [Migration("20210801171544_Triggers")] partial class Triggers { + /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618