Use json for images instead of multiples columns

This commit is contained in:
Zoe Roux 2024-04-19 21:10:47 +02:00
parent 5b4dc1e9b0
commit e1c04bef51
No known key found for this signature in database
9 changed files with 34 additions and 44 deletions

View File

@ -17,12 +17,9 @@
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
using Kyoo.Abstractions.Models.Attributes;
namespace Kyoo.Abstractions.Models;
@ -49,9 +46,13 @@ public interface IThumbnails
}
[JsonConverter(typeof(ImageConvertor))]
[SqlFirstColumn(nameof(Source))]
public class Image
{
/// <summary>
/// A unique identifier for the image. Used for proper http caches.
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// The original image from another server.
/// </summary>
@ -63,6 +64,21 @@ public class Image
[MaxLength(32)]
public string Blurhash { get; set; }
/// <summary>
/// The url to access the image in low quality.
/// </summary>
public string Low => $"/thumbnails/{Id}?quality=low";
/// <summary>
/// The url to access the image in medium quality.
/// </summary>
public string Medium => $"/thumbnails/{Id}?quality=medium";
/// <summary>
/// The url to access the image in high quality.
/// </summary>
public string High => $"/thumbnails/{Id}?quality=high";
public Image() { }
[JsonConstructor]
@ -97,6 +113,9 @@ public class Image
writer.WriteStartObject();
writer.WriteString("source", value.Source);
writer.WriteString("blurhash", value.Blurhash);
writer.WriteString("low", value.Low);
writer.WriteString("medium", value.Medium);
writer.WriteString("high", value.High);
writer.WriteEndObject();
}
}

View File

@ -25,7 +25,6 @@ using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
using Kyoo.Abstractions.Models;
using Kyoo.Abstractions.Models.Attributes;
using Microsoft.AspNetCore.Http;
using static System.Text.Json.JsonNamingPolicy;
namespace Kyoo.Utils;

View File

@ -252,7 +252,7 @@ public static class DapperHelper
this IDbConnection db,
FormattableString command,
Dictionary<string, Type> config,
Func<List<object?>, T> mapper,
Func<IList<object?>, T> mapper,
Func<Guid, Task<T>> get,
SqlVariableContext context,
Include<T>? include,
@ -327,23 +327,6 @@ public static class DapperHelper
? ExpendProjections(typeV, prefix, include)
: null;
if (typeV.IsAssignableTo(typeof(IThumbnails)))
{
string posterProj = string.Join(
", ",
new[] { "poster", "thumbnail", "logo" }.Select(x =>
$"{prefix}{x}_source as source, {prefix}{x}_blurhash as blurhash"
)
);
projection = string.IsNullOrEmpty(projection)
? posterProj
: $"{projection}, {posterProj}";
types.InsertRange(
types.IndexOf(typeV) + 1,
Enumerable.Repeat(typeof(Image), 3)
);
}
if (string.IsNullOrEmpty(projection))
return leadingComa;
return $", {projection}{leadingComa}";
@ -355,19 +338,7 @@ public static class DapperHelper
types.ToArray(),
items =>
{
List<object?> nItems = new(items.Length);
for (int i = 0; i < items.Length; i++)
{
if (types[i] == typeof(Image))
continue;
nItems.Add(items[i]);
if (items[i] is not IThumbnails thumbs)
continue;
thumbs.Poster = items[++i] as Image;
thumbs.Thumbnail = items[++i] as Image;
thumbs.Logo = items[++i] as Image;
}
return mapIncludes(mapper(nItems), nItems.Skip(config.Count));
return mapIncludes(mapper(items), items.Skip(config.Count));
},
ParametersDictionary.LoadFrom(cmd),
splitOn: string.Join(
@ -384,7 +355,7 @@ public static class DapperHelper
this IDbConnection db,
FormattableString command,
Dictionary<string, Type> config,
Func<List<object?>, T> mapper,
Func<IList<object?>, T> mapper,
SqlVariableContext context,
Include<T>? include,
Filter<T>? filter,

View File

@ -37,7 +37,7 @@ public abstract class DapperRepository<T> : IRepository<T>
protected abstract Dictionary<string, Type> Config { get; }
protected abstract T Mapper(List<object?> items);
protected abstract T Mapper(IList<object?> items);
protected DbConnection Database { get; init; }

View File

@ -67,7 +67,7 @@ public class LibraryItemRepository : DapperRepository<ILibraryItem>
{ "c", typeof(Collection) }
};
protected override ILibraryItem Mapper(List<object?> items)
protected override ILibraryItem Mapper(IList<object?> items)
{
if (items[0] is Show show && show.Id != Guid.Empty)
return show;

View File

@ -49,7 +49,7 @@ public class NewsRepository : DapperRepository<INews>
protected override Dictionary<string, Type> Config =>
new() { { "e", typeof(Episode) }, { "m", typeof(Movie) }, };
protected override INews Mapper(List<object?> items)
protected override INews Mapper(IList<object?> items)
{
if (items[0] is Episode episode && episode.Id != Guid.Empty)
return episode;

View File

@ -135,7 +135,7 @@ public class WatchStatusRepository(
{ "_mw", typeof(MovieWatchStatus) },
};
protected IWatchlist Mapper(List<object?> items)
protected IWatchlist Mapper(IList<object?> items)
{
if (items[0] is Show show && show.Id != Guid.Empty)
{

View File

@ -201,9 +201,9 @@ public abstract class DatabaseContext : DbContext
private static void _HasImages<T>(ModelBuilder modelBuilder)
where T : class, IThumbnails
{
modelBuilder.Entity<T>().OwnsOne(x => x.Poster);
modelBuilder.Entity<T>().OwnsOne(x => x.Thumbnail);
modelBuilder.Entity<T>().OwnsOne(x => x.Logo);
modelBuilder.Entity<T>().OwnsOne(x => x.Poster, x => x.ToJson());
modelBuilder.Entity<T>().OwnsOne(x => x.Thumbnail, x => x.ToJson());
modelBuilder.Entity<T>().OwnsOne(x => x.Logo, x => x.ToJson());
}
private static void _HasAddedDate<T>(ModelBuilder modelBuilder)

View File

@ -94,6 +94,7 @@ public class PostgresContext(DbContextOptions options, IHttpContextAccessor acce
typeof(Dictionary<string, ExternalToken>),
new JsonTypeHandler<Dictionary<string, ExternalToken>>()
);
SqlMapper.AddTypeHandler(typeof(Image), new JsonTypeHandler<Image>());
SqlMapper.AddTypeHandler(typeof(List<string>), new ListTypeHandler<string>());
SqlMapper.AddTypeHandler(typeof(List<Genre>), new ListTypeHandler<Genre>());
SqlMapper.AddTypeHandler(typeof(Wrapper), new Wrapper.Handler());