Remove APISerializable and APIJsonSerializer

This commit is contained in:
Glax 2024-12-16 18:55:52 +01:00
parent 77c5903cf1
commit 87274aca19
14 changed files with 9 additions and 134 deletions

View File

@ -1,61 +0,0 @@
using System.Reflection;
using System.Text.Json;
using API.Schema;
using API.Schema.Jobs;
using API.Schema.LibraryConnectors;
using API.Schema.NotificationConnectors;
using Newtonsoft.Json;
using JsonSerializer = Newtonsoft.Json.JsonSerializer;
namespace API;
internal class ApiJsonSerializer : System.Text.Json.Serialization.JsonConverter<APISerializable>
{
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Job);
public override APISerializable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Span<char> dest = stackalloc char[1024];
string json = "";
while (reader.Read())
{
reader.CopyString(dest);
json += dest.ToString();
}
JsonReader jr = new JsonTextReader(new StringReader(json));
return new JobJsonDeserializer().ReadJson(jr, typeToConvert, null, JsonSerializer.Create(new JsonSerializerSettings())) as Job;
}
public override void Write(Utf8JsonWriter writer, APISerializable value, JsonSerializerOptions options)
{
writer.WriteStartObject();
foreach (PropertyInfo info in value.GetType().GetProperties())
{
if(info.PropertyType == typeof(string))
writer.WriteString(LowerCamelCase(info.Name), (string)info.GetValue(value)!);
else if(info.PropertyType == typeof(bool))
writer.WriteBoolean(LowerCamelCase(info.Name), (bool)info.GetValue(value)!);
else if(info.PropertyType == typeof(int))
writer.WriteNumber(LowerCamelCase(info.Name), (int)info.GetValue(value)!);
else if(info.PropertyType == typeof(ulong))
writer.WriteNumber(LowerCamelCase(info.Name), (ulong)info.GetValue(value)!);
else if(info.PropertyType == typeof(JobType))
writer.WriteString(LowerCamelCase(info.Name), Enum.GetName((JobType)info.GetValue(value)!));
else if(info.PropertyType == typeof(JobState))
writer.WriteString(LowerCamelCase(info.Name), Enum.GetName((JobState)info.GetValue(value)!));
else if(info.PropertyType == typeof(NotificationConnectorType))
writer.WriteString(LowerCamelCase(info.Name), Enum.GetName((NotificationConnectorType)info.GetValue(value)!));
else if(info.PropertyType == typeof(LibraryType))
writer.WriteString(LowerCamelCase(info.Name), Enum.GetName((LibraryType)info.GetValue(value)!));
else if(info.PropertyType == typeof(DateTime))
writer.WriteString(LowerCamelCase(info.Name), ((DateTime)info.GetValue(value)!).ToUniversalTime().ToString("u").Replace(' ','T'));
}
writer.WriteEndObject();
}
private static string LowerCamelCase(string s)
{
return char.ToLowerInvariant(s[0]) + s.Substring(1);
}
}

View File

@ -1,23 +0,0 @@
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER $APP_UID
WORKDIR /app
EXPOSE 8080
EXPOSE 8081
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["API/API.csproj", "API/"]
RUN dotnet restore "API/API.csproj"
COPY . .
WORKDIR "/src/API"
RUN dotnet build "API.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "API.dll"]

View File

@ -28,7 +28,6 @@ builder.Services.AddCors(options =>
builder.Services.AddMvc().AddJsonOptions(opts => builder.Services.AddMvc().AddJsonOptions(opts =>
{ {
opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
opts.JsonSerializerOptions.Converters.Add(new ApiJsonSerializer());
}); });
builder.Services.AddApiVersioning(option => builder.Services.AddApiVersioning(option =>

View File

@ -1,3 +0,0 @@
namespace API.Schema;
public interface APISerializable;

View File

@ -1,5 +1,4 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace API.Schema; namespace API.Schema;

View File

@ -6,7 +6,7 @@ using Newtonsoft.Json;
namespace API.Schema.Jobs; namespace API.Schema.Jobs;
[PrimaryKey("JobId")] [PrimaryKey("JobId")]
public abstract class Job : APISerializable public abstract class Job
{ {
[MaxLength(64)] [MaxLength(64)]
public string JobId { get; init; } public string JobId { get; init; }

View File

@ -4,7 +4,7 @@ using Microsoft.EntityFrameworkCore;
namespace API.Schema.LibraryConnectors; namespace API.Schema.LibraryConnectors;
[PrimaryKey("LibraryConnectorId")] [PrimaryKey("LibraryConnectorId")]
public abstract class LibraryConnector(string libraryConnectorId, LibraryType libraryType, string baseUrl, string auth) : APISerializable public abstract class LibraryConnector(string libraryConnectorId, LibraryType libraryType, string baseUrl, string auth)
{ {
[MaxLength(64)] [MaxLength(64)]
public string LibraryConnectorId { get; } = libraryConnectorId; public string LibraryConnectorId { get; } = libraryConnectorId;

View File

@ -1,5 +1,4 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace API.Schema; namespace API.Schema;
@ -11,7 +10,4 @@ public class Link(string linkProvider, string linkUrl)
public string LinkId { get; init; } = TokenGen.CreateToken(typeof(Link), 64); public string LinkId { get; init; } = TokenGen.CreateToken(typeof(Link), 64);
public string LinkProvider { get; init; } = linkProvider; public string LinkProvider { get; init; } = linkProvider;
public string LinkUrl { get; init; } = linkUrl; public string LinkUrl { get; init; } = linkUrl;
[ForeignKey("MangaId")]
public virtual Manga Manga { get; init; }
} }

View File

@ -71,9 +71,6 @@ public class Manga(
[ForeignKey("AltTitleIds")] [ForeignKey("AltTitleIds")]
public virtual MangaAltTitle[] AltTitles { get; } public virtual MangaAltTitle[] AltTitles { get; }
[ForeignKey("ChapterIds")]
public virtual Chapter[] Chapters { get; internal set; }
public MoveFileOrFolderJob UpdateFolderName(string downloadLocation, string newName) public MoveFileOrFolderJob UpdateFolderName(string downloadLocation, string newName)
{ {
string oldName = this.FolderName; string oldName = this.FolderName;

View File

@ -12,7 +12,4 @@ public class MangaAltTitle(string language, string title)
[MaxLength(8)] [MaxLength(8)]
public string Language { get; init; } = language; public string Language { get; init; } = language;
public string Title { get; set; } = title; public string Title { get; set; } = title;
[ForeignKey("MangaId")]
public virtual Manga Manga { get; init; }
} }

View File

@ -14,11 +14,6 @@ public abstract class MangaConnector(string name, string[] supportedLanguages, s
public string[] SupportedLanguages { get; init; } = supportedLanguages; public string[] SupportedLanguages { get; init; } = supportedLanguages;
public string[] BaseUris { get; init; } = baseUris; public string[] BaseUris { get; init; } = baseUris;
[JsonIgnore]
[ForeignKey("MangaIds")]
public virtual Manga[] Mangas { get; internal set; } = [];
public abstract (Manga, Author[], MangaTag[], Link[], MangaAltTitle[])[] GetManga(string publicationTitle = ""); public abstract (Manga, Author[], MangaTag[], Link[], MangaAltTitle[])[] GetManga(string publicationTitle = "");
public abstract (Manga, Author[], MangaTag[], Link[], MangaAltTitle[])? GetMangaFromUrl(string url); public abstract (Manga, Author[], MangaTag[], Link[], MangaAltTitle[])? GetMangaFromUrl(string url);

View File

@ -7,7 +7,4 @@ namespace API.Schema;
public class MangaTag(string tag) public class MangaTag(string tag)
{ {
public string Tag { get; init; } = tag; public string Tag { get; init; } = tag;
[ForeignKey("MangaIds")]
public virtual Manga[] Mangas { get; internal set; } = [];
} }

View File

@ -6,7 +6,7 @@ using Newtonsoft.Json;
namespace API.Schema.NotificationConnectors; namespace API.Schema.NotificationConnectors;
[PrimaryKey("NotificationConnectorId")] [PrimaryKey("NotificationConnectorId")]
public abstract class NotificationConnector(string notificationConnectorId, NotificationConnectorType notificationConnectorType) : APISerializable public abstract class NotificationConnector(string notificationConnectorId, NotificationConnectorType notificationConnectorType)
{ {
[MaxLength(64)] [MaxLength(64)]
public string NotificationConnectorId { get; } = notificationConnectorId; public string NotificationConnectorId { get; } = notificationConnectorId;

View File

@ -52,9 +52,7 @@ public class PgsqlContext(DbContextOptions<PgsqlContext> options) : DbContext(op
.HasValue<UpdateMetadataJob>(JobType.UpdateMetaDataJob); .HasValue<UpdateMetadataJob>(JobType.UpdateMetaDataJob);
modelBuilder.Entity<Chapter>() modelBuilder.Entity<Chapter>()
.HasOne<Manga>(c => c.ParentManga) .HasOne<Manga>(c => c.ParentManga);
.WithMany(m => m.Chapters)
.HasForeignKey(c => c.ParentMangaId);
modelBuilder.Entity<Manga>() modelBuilder.Entity<Manga>()
.HasOne<Chapter>(m => m.LatestChapterAvailable) .HasOne<Chapter>(m => m.LatestChapterAvailable)
@ -63,30 +61,14 @@ public class PgsqlContext(DbContextOptions<PgsqlContext> options) : DbContext(op
.HasOne<Chapter>(m => m.LatestChapterDownloaded) .HasOne<Chapter>(m => m.LatestChapterDownloaded)
.WithOne(); .WithOne();
modelBuilder.Entity<Manga>() modelBuilder.Entity<Manga>()
.HasOne<MangaConnector>(m => m.MangaConnector) .HasOne<MangaConnector>(m => m.MangaConnector);
.WithMany(c => c.Mangas)
.HasForeignKey(m => m.MangaConnectorName);
modelBuilder.Entity<Manga>() modelBuilder.Entity<Manga>()
.HasMany<Author>(m => m.Authors) .HasMany<Author>(m => m.Authors);
.WithMany(a => a.Mangas)
.UsingEntity(
"MangaAuthor",
l => l.HasOne(typeof(Manga)).WithMany().HasForeignKey("MangaId").HasPrincipalKey("MangaId"),
r => r.HasOne(typeof(Author)).WithMany().HasForeignKey("AuthorId").HasPrincipalKey("AuthorId"),
j => j.HasKey("MangaId", "AuthorId"));
modelBuilder.Entity<Manga>() modelBuilder.Entity<Manga>()
.HasMany<MangaTag>(m => m.Tags) .HasMany<MangaTag>(m => m.Tags);
.WithMany(t => t.Mangas)
.UsingEntity(
"MangaTag",
l => l.HasOne(typeof(Manga)).WithMany().HasForeignKey("MangaId").HasPrincipalKey("MangaId"),
r => r.HasOne(typeof(MangaTag)).WithMany().HasForeignKey("Tag").HasPrincipalKey("Tag"),
j => j.HasKey("MangaId", "Tag"));
modelBuilder.Entity<Manga>() modelBuilder.Entity<Manga>()
.HasMany<Link>(m => m.Links) .HasMany<Link>(m => m.Links);
.WithOne(c => c.Manga);
modelBuilder.Entity<Manga>() modelBuilder.Entity<Manga>()
.HasMany<MangaAltTitle>(m => m.AltTitles) .HasMany<MangaAltTitle>(m => m.AltTitles);
.WithOne(c => c.Manga);
} }
} }