Disable LazyLoading

Remove MangaConnectors from Database
This commit is contained in:
2025-07-21 11:42:17 +02:00
parent 6034937c23
commit 3a46d0fd24
20 changed files with 167 additions and 311 deletions

View File

@@ -1,5 +1,5 @@
using API.Schema.MangaContext; using API.MangaConnectors;
using API.Schema.MangaContext.MangaConnectors; using API.Schema.MangaContext;
using Asp.Versioning; using Asp.Versioning;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using static Microsoft.AspNetCore.Http.StatusCodes; using static Microsoft.AspNetCore.Http.StatusCodes;
@@ -20,7 +20,7 @@ public class MangaConnectorController(MangaContext context) : Controller
[ProducesResponseType<MangaConnector[]>(Status200OK, "application/json")] [ProducesResponseType<MangaConnector[]>(Status200OK, "application/json")]
public IActionResult GetConnectors() public IActionResult GetConnectors()
{ {
return Ok(context.MangaConnectors.Select(c => c.Name).ToArray()); return Ok(Tranga.MangaConnectors.Select(c => c.Name).ToArray());
} }
/// <summary> /// <summary>
@@ -34,7 +34,7 @@ public class MangaConnectorController(MangaContext context) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult GetConnector(string MangaConnectorName) public IActionResult GetConnector(string MangaConnectorName)
{ {
if(context.MangaConnectors.Find(MangaConnectorName) is not { } connector) if(Tranga.MangaConnectors.FirstOrDefault(c => c.Name.Equals(MangaConnectorName, StringComparison.InvariantCultureIgnoreCase)) is not { } connector)
return NotFound(); return NotFound();
return Ok(connector); return Ok(connector);
@@ -49,7 +49,7 @@ public class MangaConnectorController(MangaContext context) : Controller
public IActionResult GetEnabledConnectors() public IActionResult GetEnabledConnectors()
{ {
return Ok(context.MangaConnectors.Where(c => c.Enabled).ToArray()); return Ok(Tranga.MangaConnectors.Where(c => c.Enabled).ToArray());
} }
/// <summary> /// <summary>
@@ -61,7 +61,7 @@ public class MangaConnectorController(MangaContext context) : Controller
public IActionResult GetDisabledConnectors() public IActionResult GetDisabledConnectors()
{ {
return Ok(context.MangaConnectors.Where(c => c.Enabled == false).ToArray()); return Ok(Tranga.MangaConnectors.Where(c => c.Enabled == false).ToArray());
} }
/// <summary> /// <summary>
@@ -78,7 +78,7 @@ public class MangaConnectorController(MangaContext context) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult SetEnabled(string MangaConnectorName, bool Enabled) public IActionResult SetEnabled(string MangaConnectorName, bool Enabled)
{ {
if(context.MangaConnectors.Find(MangaConnectorName) is not { } connector) if(Tranga.MangaConnectors.FirstOrDefault(c => c.Name.Equals(MangaConnectorName, StringComparison.InvariantCultureIgnoreCase)) is not { } connector)
return NotFound(); return NotFound();
connector.Enabled = Enabled; connector.Enabled = Enabled;

View File

@@ -1,5 +1,5 @@
using API.Schema.MangaContext; using API.MangaConnectors;
using API.Schema.MangaContext.MangaConnectors; using API.Schema.MangaContext;
using API.Workers; using API.Workers;
using Asp.Versioning; using Asp.Versioning;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -368,7 +368,7 @@ public class MangaController(MangaContext context) : Controller
{ {
if (context.Mangas.Find(MangaId) is null) if (context.Mangas.Find(MangaId) is null)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
if(context.MangaConnectors.Find(MangaConnectorName) is null) if(Tranga.MangaConnectors.FirstOrDefault(c => c.Name.Equals(MangaConnectorName, StringComparison.InvariantCultureIgnoreCase)) is not { } connector)
return NotFound(nameof(MangaConnectorName)); return NotFound(nameof(MangaConnectorName));
if (context.MangaConnectorToManga.FirstOrDefault(id => id.MangaConnectorName == MangaConnectorName && id.ObjId == MangaId) is not { } mcId) if (context.MangaConnectorToManga.FirstOrDefault(id => id.MangaConnectorName == MangaConnectorName && id.ObjId == MangaId) is not { } mcId)

View File

@@ -1,5 +1,5 @@
using API.MangaConnectors;
using API.Schema.MangaContext; using API.Schema.MangaContext;
using API.Schema.MangaContext.MangaConnectors;
using Asp.Versioning; using Asp.Versioning;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using static Microsoft.AspNetCore.Http.StatusCodes; using static Microsoft.AspNetCore.Http.StatusCodes;
@@ -26,7 +26,7 @@ public class SearchController(MangaContext context) : Controller
[ProducesResponseType(Status406NotAcceptable)] [ProducesResponseType(Status406NotAcceptable)]
public IActionResult SearchManga(string MangaConnectorName, string Query) public IActionResult SearchManga(string MangaConnectorName, string Query)
{ {
if(context.MangaConnectors.Find(MangaConnectorName) is not { } connector) if(Tranga.MangaConnectors.FirstOrDefault(c => c.Name.Equals(MangaConnectorName, StringComparison.InvariantCultureIgnoreCase)) is not { } connector)
return NotFound(); return NotFound();
if (connector.Enabled is false) if (connector.Enabled is false)
return StatusCode(Status412PreconditionFailed); return StatusCode(Status412PreconditionFailed);
@@ -56,7 +56,7 @@ public class SearchController(MangaContext context) : Controller
[ProducesResponseType(Status500InternalServerError)] [ProducesResponseType(Status500InternalServerError)]
public IActionResult GetMangaFromUrl([FromBody]string url) public IActionResult GetMangaFromUrl([FromBody]string url)
{ {
if (context.MangaConnectors.Find("Global") is not { } connector) if(Tranga.MangaConnectors.FirstOrDefault(c => c.Name.Equals("Global", StringComparison.InvariantCultureIgnoreCase)) is not { } connector)
return StatusCode(Status500InternalServerError, "Could not find Global Connector."); return StatusCode(Status500InternalServerError, "Could not find Global Connector.");
if(connector.GetMangaFromUrl(url) is not { } manga) if(connector.GetMangaFromUrl(url) is not { } manga)

View File

@@ -1,8 +1,9 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using API.MangaDownloadClients; using API.MangaDownloadClients;
using API.Schema.MangaContext;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace API.Schema.MangaContext.MangaConnectors; namespace API.MangaConnectors;
public class ComickIo : MangaConnector public class ComickIo : MangaConnector
{ {

View File

@@ -1,17 +1,17 @@
namespace API.Schema.MangaContext.MangaConnectors; using API.Schema.MangaContext;
namespace API.MangaConnectors;
public class Global : MangaConnector public class Global : MangaConnector
{ {
private MangaContext context { get; init; } public Global() : base("Global", ["all"], [""], "")
public Global(MangaContext context) : base("Global", ["all"], [""], "")
{ {
this.context = context;
} }
public override (Manga, MangaConnectorId<Manga>)[] SearchManga(string mangaSearchName) public override (Manga, MangaConnectorId<Manga>)[] SearchManga(string mangaSearchName)
{ {
//Get all enabled Connectors //Get all enabled Connectors
MangaConnector[] enabledConnectors = context.MangaConnectors.Where(c => c.Enabled && c.Name != "Global").ToArray(); MangaConnector[] enabledConnectors = Tranga.MangaConnectors.Where(c => c.Enabled && c.Name != "Global").ToArray();
//Create Task for each MangaConnector to search simultaneously //Create Task for each MangaConnector to search simultaneously
Task<(Manga, MangaConnectorId<Manga>)[]>[] tasks = Task<(Manga, MangaConnectorId<Manga>)[]>[] tasks =
@@ -32,7 +32,7 @@ public class Global : MangaConnector
public override (Manga, MangaConnectorId<Manga>)? GetMangaFromUrl(string url) public override (Manga, MangaConnectorId<Manga>)? GetMangaFromUrl(string url)
{ {
MangaConnector? mc = context.MangaConnectors.ToArray().FirstOrDefault(c => c.UrlMatchesConnector(url)); MangaConnector? mc = Tranga.MangaConnectors.FirstOrDefault(c => c.UrlMatchesConnector(url));
return mc?.GetMangaFromUrl(url) ?? null; return mc?.GetMangaFromUrl(url) ?? null;
} }
@@ -44,11 +44,15 @@ public class Global : MangaConnector
public override (Chapter, MangaConnectorId<Chapter>)[] GetChapters(MangaConnectorId<Manga> manga, public override (Chapter, MangaConnectorId<Chapter>)[] GetChapters(MangaConnectorId<Manga> manga,
string? language = null) string? language = null)
{ {
return manga.MangaConnector.GetChapters(manga, language); if (!Tranga.TryGetMangaConnector(manga.MangaConnectorName, out MangaConnector? mangaConnector))
return [];
return mangaConnector.GetChapters(manga, language);
} }
internal override string[] GetChapterImageUrls(MangaConnectorId<Chapter> chapterId) internal override string[] GetChapterImageUrls(MangaConnectorId<Chapter> chapterId)
{ {
return chapterId.MangaConnector.GetChapterImageUrls(chapterId); if (!Tranga.TryGetMangaConnector(chapterId.MangaConnectorName, out MangaConnector? mangaConnector))
return [];
return mangaConnector.GetChapterImageUrls(chapterId);
} }
} }

View File

@@ -2,11 +2,12 @@
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using API.MangaDownloadClients; using API.MangaDownloadClients;
using API.Schema.MangaContext;
using log4net; using log4net;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace API.Schema.MangaContext.MangaConnectors; namespace API.MangaConnectors;
[PrimaryKey("Name")] [PrimaryKey("Name")]
public abstract class MangaConnector(string name, string[] supportedLanguages, string[] baseUris, string iconUrl) public abstract class MangaConnector(string name, string[] supportedLanguages, string[] baseUris, string iconUrl)

View File

@@ -1,8 +1,9 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using API.MangaDownloadClients; using API.MangaDownloadClients;
using API.Schema.MangaContext;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace API.Schema.MangaContext.MangaConnectors; namespace API.MangaConnectors;
public class MangaDex : MangaConnector public class MangaDex : MangaConnector
{ {

View File

@@ -11,7 +11,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace API.Migrations.Manga namespace API.Migrations.Manga
{ {
[DbContext(typeof(MangaContext))] [DbContext(typeof(MangaContext))]
[Migration("20250703192023_Initial")] [Migration("20250721093858_Initial")]
partial class Initial partial class Initial
{ {
/// <inheritdoc /> /// <inheritdoc />
@@ -24,6 +24,39 @@ namespace API.Migrations.Manga
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("API.MangaConnectors.MangaConnector", b =>
{
b.Property<string>("Name")
.HasMaxLength(32)
.HasColumnType("character varying(32)");
b.PrimitiveCollection<string[]>("BaseUris")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("text[]");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("IconUrl")
.IsRequired()
.HasMaxLength(2048)
.HasColumnType("character varying(2048)");
b.PrimitiveCollection<string[]>("SupportedLanguages")
.IsRequired()
.HasMaxLength(8)
.HasColumnType("text[]");
b.HasKey("Name");
b.ToTable("MangaConnector");
b.HasDiscriminator<string>("Name").HasValue("MangaConnector");
b.UseTphMappingStrategy();
});
modelBuilder.Entity("API.Schema.MangaContext.Author", b => modelBuilder.Entity("API.Schema.MangaContext.Author", b =>
{ {
b.Property<string>("Key") b.Property<string>("Key")
@@ -177,8 +210,6 @@ namespace API.Migrations.Manga
b.HasKey("Key"); b.HasKey("Key");
b.HasIndex("MangaConnectorName");
b.HasIndex("ObjId"); b.HasIndex("ObjId");
b.ToTable("MangaConnectorToChapter"); b.ToTable("MangaConnectorToChapter");
@@ -213,46 +244,11 @@ namespace API.Migrations.Manga
b.HasKey("Key"); b.HasKey("Key");
b.HasIndex("MangaConnectorName");
b.HasIndex("ObjId"); b.HasIndex("ObjId");
b.ToTable("MangaConnectorToManga"); b.ToTable("MangaConnectorToManga");
}); });
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectors.MangaConnector", b =>
{
b.Property<string>("Name")
.HasMaxLength(32)
.HasColumnType("character varying(32)");
b.PrimitiveCollection<string[]>("BaseUris")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("text[]");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("IconUrl")
.IsRequired()
.HasMaxLength(2048)
.HasColumnType("character varying(2048)");
b.PrimitiveCollection<string[]>("SupportedLanguages")
.IsRequired()
.HasMaxLength(8)
.HasColumnType("text[]");
b.HasKey("Name");
b.ToTable("MangaConnectors");
b.HasDiscriminator<string>("Name").HasValue("MangaConnector");
b.UseTphMappingStrategy();
});
modelBuilder.Entity("API.Schema.MangaContext.MangaTag", b => modelBuilder.Entity("API.Schema.MangaContext.MangaTag", b =>
{ {
b.Property<string>("Tag") b.Property<string>("Tag")
@@ -332,23 +328,23 @@ namespace API.Migrations.Manga
b.ToTable("MangaTagToManga"); b.ToTable("MangaTagToManga");
}); });
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectors.ComickIo", b => modelBuilder.Entity("API.MangaConnectors.ComickIo", b =>
{ {
b.HasBaseType("API.Schema.MangaContext.MangaConnectors.MangaConnector"); b.HasBaseType("API.MangaConnectors.MangaConnector");
b.HasDiscriminator().HasValue("ComickIo"); b.HasDiscriminator().HasValue("ComickIo");
}); });
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectors.Global", b => modelBuilder.Entity("API.MangaConnectors.Global", b =>
{ {
b.HasBaseType("API.Schema.MangaContext.MangaConnectors.MangaConnector"); b.HasBaseType("API.MangaConnectors.MangaConnector");
b.HasDiscriminator().HasValue("Global"); b.HasDiscriminator().HasValue("Global");
}); });
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectors.MangaDex", b => modelBuilder.Entity("API.MangaConnectors.MangaDex", b =>
{ {
b.HasBaseType("API.Schema.MangaContext.MangaConnectors.MangaConnector"); b.HasBaseType("API.MangaConnectors.MangaConnector");
b.HasDiscriminator().HasValue("MangaDex"); b.HasDiscriminator().HasValue("MangaDex");
}); });
@@ -445,39 +441,23 @@ namespace API.Migrations.Manga
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId<API.Schema.MangaContext.Chapter>", b => modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId<API.Schema.MangaContext.Chapter>", b =>
{ {
b.HasOne("API.Schema.MangaContext.MangaConnectors.MangaConnector", "MangaConnector")
.WithMany()
.HasForeignKey("MangaConnectorName")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("API.Schema.MangaContext.Chapter", "Obj") b.HasOne("API.Schema.MangaContext.Chapter", "Obj")
.WithMany("MangaConnectorIds") .WithMany("MangaConnectorIds")
.HasForeignKey("ObjId") .HasForeignKey("ObjId")
.OnDelete(DeleteBehavior.NoAction) .OnDelete(DeleteBehavior.NoAction)
.IsRequired(); .IsRequired();
b.Navigation("MangaConnector");
b.Navigation("Obj"); b.Navigation("Obj");
}); });
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId<API.Schema.MangaContext.Manga>", b => modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId<API.Schema.MangaContext.Manga>", b =>
{ {
b.HasOne("API.Schema.MangaContext.MangaConnectors.MangaConnector", "MangaConnector")
.WithMany()
.HasForeignKey("MangaConnectorName")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("API.Schema.MangaContext.Manga", "Obj") b.HasOne("API.Schema.MangaContext.Manga", "Obj")
.WithMany("MangaConnectorIds") .WithMany("MangaConnectorIds")
.HasForeignKey("ObjId") .HasForeignKey("ObjId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("MangaConnector");
b.Navigation("Obj"); b.Navigation("Obj");
}); });

View File

@@ -36,7 +36,7 @@ namespace API.Migrations.Manga
}); });
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "MangaConnectors", name: "MangaConnector",
columns: table => new columns: table => new
{ {
Name = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false), Name = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
@@ -47,7 +47,7 @@ namespace API.Migrations.Manga
}, },
constraints: table => constraints: table =>
{ {
table.PrimaryKey("PK_MangaConnectors", x => x.Name); table.PrimaryKey("PK_MangaConnector", x => x.Name);
}); });
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
@@ -201,12 +201,6 @@ namespace API.Migrations.Manga
constraints: table => constraints: table =>
{ {
table.PrimaryKey("PK_MangaConnectorToManga", x => x.Key); table.PrimaryKey("PK_MangaConnectorToManga", x => x.Key);
table.ForeignKey(
name: "FK_MangaConnectorToManga_MangaConnectors_MangaConnectorName",
column: x => x.MangaConnectorName,
principalTable: "MangaConnectors",
principalColumn: "Name",
onDelete: ReferentialAction.Cascade);
table.ForeignKey( table.ForeignKey(
name: "FK_MangaConnectorToManga_Mangas_ObjId", name: "FK_MangaConnectorToManga_Mangas_ObjId",
column: x => x.ObjId, column: x => x.ObjId,
@@ -283,12 +277,6 @@ namespace API.Migrations.Manga
column: x => x.ObjId, column: x => x.ObjId,
principalTable: "Chapters", principalTable: "Chapters",
principalColumn: "Key"); principalColumn: "Key");
table.ForeignKey(
name: "FK_MangaConnectorToChapter_MangaConnectors_MangaConnectorName",
column: x => x.MangaConnectorName,
principalTable: "MangaConnectors",
principalColumn: "Name",
onDelete: ReferentialAction.Cascade);
}); });
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
@@ -311,21 +299,11 @@ namespace API.Migrations.Manga
table: "Link", table: "Link",
column: "MangaKey"); column: "MangaKey");
migrationBuilder.CreateIndex(
name: "IX_MangaConnectorToChapter_MangaConnectorName",
table: "MangaConnectorToChapter",
column: "MangaConnectorName");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_MangaConnectorToChapter_ObjId", name: "IX_MangaConnectorToChapter_ObjId",
table: "MangaConnectorToChapter", table: "MangaConnectorToChapter",
column: "ObjId"); column: "ObjId");
migrationBuilder.CreateIndex(
name: "IX_MangaConnectorToManga_MangaConnectorName",
table: "MangaConnectorToManga",
column: "MangaConnectorName");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_MangaConnectorToManga_ObjId", name: "IX_MangaConnectorToManga_ObjId",
table: "MangaConnectorToManga", table: "MangaConnectorToManga",
@@ -359,6 +337,9 @@ namespace API.Migrations.Manga
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Link"); name: "Link");
migrationBuilder.DropTable(
name: "MangaConnector");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "MangaConnectorToChapter"); name: "MangaConnectorToChapter");
@@ -377,9 +358,6 @@ namespace API.Migrations.Manga
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Chapters"); name: "Chapters");
migrationBuilder.DropTable(
name: "MangaConnectors");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Tags"); name: "Tags");

View File

@@ -21,6 +21,39 @@ namespace API.Migrations.Manga
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("API.MangaConnectors.MangaConnector", b =>
{
b.Property<string>("Name")
.HasMaxLength(32)
.HasColumnType("character varying(32)");
b.PrimitiveCollection<string[]>("BaseUris")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("text[]");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("IconUrl")
.IsRequired()
.HasMaxLength(2048)
.HasColumnType("character varying(2048)");
b.PrimitiveCollection<string[]>("SupportedLanguages")
.IsRequired()
.HasMaxLength(8)
.HasColumnType("text[]");
b.HasKey("Name");
b.ToTable("MangaConnector");
b.HasDiscriminator<string>("Name").HasValue("MangaConnector");
b.UseTphMappingStrategy();
});
modelBuilder.Entity("API.Schema.MangaContext.Author", b => modelBuilder.Entity("API.Schema.MangaContext.Author", b =>
{ {
b.Property<string>("Key") b.Property<string>("Key")
@@ -174,8 +207,6 @@ namespace API.Migrations.Manga
b.HasKey("Key"); b.HasKey("Key");
b.HasIndex("MangaConnectorName");
b.HasIndex("ObjId"); b.HasIndex("ObjId");
b.ToTable("MangaConnectorToChapter"); b.ToTable("MangaConnectorToChapter");
@@ -210,46 +241,11 @@ namespace API.Migrations.Manga
b.HasKey("Key"); b.HasKey("Key");
b.HasIndex("MangaConnectorName");
b.HasIndex("ObjId"); b.HasIndex("ObjId");
b.ToTable("MangaConnectorToManga"); b.ToTable("MangaConnectorToManga");
}); });
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectors.MangaConnector", b =>
{
b.Property<string>("Name")
.HasMaxLength(32)
.HasColumnType("character varying(32)");
b.PrimitiveCollection<string[]>("BaseUris")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("text[]");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("IconUrl")
.IsRequired()
.HasMaxLength(2048)
.HasColumnType("character varying(2048)");
b.PrimitiveCollection<string[]>("SupportedLanguages")
.IsRequired()
.HasMaxLength(8)
.HasColumnType("text[]");
b.HasKey("Name");
b.ToTable("MangaConnectors");
b.HasDiscriminator<string>("Name").HasValue("MangaConnector");
b.UseTphMappingStrategy();
});
modelBuilder.Entity("API.Schema.MangaContext.MangaTag", b => modelBuilder.Entity("API.Schema.MangaContext.MangaTag", b =>
{ {
b.Property<string>("Tag") b.Property<string>("Tag")
@@ -329,23 +325,23 @@ namespace API.Migrations.Manga
b.ToTable("MangaTagToManga"); b.ToTable("MangaTagToManga");
}); });
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectors.ComickIo", b => modelBuilder.Entity("API.MangaConnectors.ComickIo", b =>
{ {
b.HasBaseType("API.Schema.MangaContext.MangaConnectors.MangaConnector"); b.HasBaseType("API.MangaConnectors.MangaConnector");
b.HasDiscriminator().HasValue("ComickIo"); b.HasDiscriminator().HasValue("ComickIo");
}); });
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectors.Global", b => modelBuilder.Entity("API.MangaConnectors.Global", b =>
{ {
b.HasBaseType("API.Schema.MangaContext.MangaConnectors.MangaConnector"); b.HasBaseType("API.MangaConnectors.MangaConnector");
b.HasDiscriminator().HasValue("Global"); b.HasDiscriminator().HasValue("Global");
}); });
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectors.MangaDex", b => modelBuilder.Entity("API.MangaConnectors.MangaDex", b =>
{ {
b.HasBaseType("API.Schema.MangaContext.MangaConnectors.MangaConnector"); b.HasBaseType("API.MangaConnectors.MangaConnector");
b.HasDiscriminator().HasValue("MangaDex"); b.HasDiscriminator().HasValue("MangaDex");
}); });
@@ -442,39 +438,23 @@ namespace API.Migrations.Manga
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId<API.Schema.MangaContext.Chapter>", b => modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId<API.Schema.MangaContext.Chapter>", b =>
{ {
b.HasOne("API.Schema.MangaContext.MangaConnectors.MangaConnector", "MangaConnector")
.WithMany()
.HasForeignKey("MangaConnectorName")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("API.Schema.MangaContext.Chapter", "Obj") b.HasOne("API.Schema.MangaContext.Chapter", "Obj")
.WithMany("MangaConnectorIds") .WithMany("MangaConnectorIds")
.HasForeignKey("ObjId") .HasForeignKey("ObjId")
.OnDelete(DeleteBehavior.NoAction) .OnDelete(DeleteBehavior.NoAction)
.IsRequired(); .IsRequired();
b.Navigation("MangaConnector");
b.Navigation("Obj"); b.Navigation("Obj");
}); });
modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId<API.Schema.MangaContext.Manga>", b => modelBuilder.Entity("API.Schema.MangaContext.MangaConnectorId<API.Schema.MangaContext.Manga>", b =>
{ {
b.HasOne("API.Schema.MangaContext.MangaConnectors.MangaConnector", "MangaConnector")
.WithMany()
.HasForeignKey("MangaConnectorName")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("API.Schema.MangaContext.Manga", "Obj") b.HasOne("API.Schema.MangaContext.Manga", "Obj")
.WithMany("MangaConnectorIds") .WithMany("MangaConnectorIds")
.HasForeignKey("ObjId") .HasForeignKey("ObjId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("MangaConnector");
b.Navigation("Obj"); b.Navigation("Obj");
}); });

View File

@@ -1,8 +1,8 @@
using System.Reflection; using System.Reflection;
using API; using API;
using API.MangaConnectors;
using API.Schema.LibraryContext; using API.Schema.LibraryContext;
using API.Schema.MangaContext; using API.Schema.MangaContext;
using API.Schema.MangaContext.MangaConnectors;
using API.Schema.NotificationsContext; using API.Schema.NotificationsContext;
using Asp.Versioning; using Asp.Versioning;
using Asp.Versioning.Builder; using Asp.Versioning.Builder;
@@ -109,14 +109,6 @@ using (IServiceScope scope = app.Services.CreateScope())
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>(); MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
context.Database.Migrate(); context.Database.Migrate();
MangaConnector[] connectors =
[
new MangaDex(),
new ComickIo(),
new Global(scope.ServiceProvider.GetService<MangaContext>()!)
];
MangaConnector[] newConnectors = connectors.Where(c => !context.MangaConnectors.Contains(c)).ToArray();
context.MangaConnectors.AddRange(newConnectors);
if (!context.FileLibraries.Any()) if (!context.FileLibraries.Any())
context.FileLibraries.Add(new FileLibrary(Tranga.Settings.DownloadLocation, "Default FileLibrary")); context.FileLibraries.Add(new FileLibrary(Tranga.Settings.DownloadLocation, "Default FileLibrary"));

View File

@@ -13,30 +13,12 @@ namespace API.Schema.MangaContext;
public class Chapter : Identifiable, IComparable<Chapter> public class Chapter : Identifiable, IComparable<Chapter>
{ {
[StringLength(64)] [Required] public string ParentMangaId { get; init; } = null!; [StringLength(64)] [Required] public string ParentMangaId { get; init; } = null!;
private Manga? _parentManga; [JsonIgnore] public Manga ParentManga = null!;
[JsonIgnore]
public Manga ParentManga
{
get => _lazyLoader.Load(this, ref _parentManga) ?? throw new InvalidOperationException();
init
{
ParentMangaId = value.Key;
_parentManga = value;
}
}
[NotMapped] [NotMapped]
public Dictionary<string, string> IdsOnMangaConnectors => public Dictionary<string, string> IdsOnMangaConnectors =>
MangaConnectorIds.ToDictionary(id => id.MangaConnectorName, id => id.IdOnConnectorSite); MangaConnectorIds.ToDictionary(id => id.MangaConnectorName, id => id.IdOnConnectorSite);
[JsonIgnore] public ICollection<MangaConnectorId<Chapter>> MangaConnectorIds = null!;
private ICollection<MangaConnectorId<Chapter>>? _mangaConnectorIds;
[JsonIgnore]
public ICollection<MangaConnectorId<Chapter>> MangaConnectorIds
{
get => _lazyLoader.Load(this, ref _mangaConnectorIds) ?? throw new InvalidOperationException();
init => _mangaConnectorIds = value;
}
public int? VolumeNumber { get; private set; } public int? VolumeNumber { get; private set; }
[StringLength(10)] [Required] public string ChapterNumber { get; private set; } [StringLength(10)] [Required] public string ChapterNumber { get; private set; }
@@ -48,8 +30,6 @@ public class Chapter : Identifiable, IComparable<Chapter>
[Required] public bool Downloaded { get; internal set; } [Required] public bool Downloaded { get; internal set; }
[NotMapped] public string FullArchiveFilePath => Path.Join(ParentManga.FullDirectoryPath, FileName); [NotMapped] public string FullArchiveFilePath => Path.Join(ParentManga.FullDirectoryPath, FileName);
private readonly ILazyLoader _lazyLoader = null!;
public Chapter(Manga parentManga, string chapterNumber, public Chapter(Manga parentManga, string chapterNumber,
int? volumeNumber, string? title = null) int? volumeNumber, string? title = null)
: base(TokenGen.CreateToken(typeof(Chapter), parentManga.Key, chapterNumber)) : base(TokenGen.CreateToken(typeof(Chapter), parentManga.Key, chapterNumber))
@@ -66,10 +46,9 @@ public class Chapter : Identifiable, IComparable<Chapter>
/// <summary> /// <summary>
/// EF ONLY!!! /// EF ONLY!!!
/// </summary> /// </summary>
internal Chapter(ILazyLoader lazyLoader, string key, int? volumeNumber, string chapterNumber, string? title, string fileName, bool downloaded) internal Chapter(string key, int? volumeNumber, string chapterNumber, string? title, string fileName, bool downloaded)
: base(key) : base(key)
{ {
this._lazyLoader = lazyLoader;
this.VolumeNumber = volumeNumber; this.VolumeNumber = volumeNumber;
this.ChapterNumber = chapterNumber; this.ChapterNumber = chapterNumber;
this.Title = title; this.Title = title;

View File

@@ -18,17 +18,7 @@ public class Manga : Identifiable
[JsonIgnore] [Url] [StringLength(512)] public string CoverUrl { get; internal set; } [JsonIgnore] [Url] [StringLength(512)] public string CoverUrl { get; internal set; }
[Required] public MangaReleaseStatus ReleaseStatus { get; internal set; } [Required] public MangaReleaseStatus ReleaseStatus { get; internal set; }
[StringLength(64)] public string? LibraryId { get; private set; } [StringLength(64)] public string? LibraryId { get; private set; }
private FileLibrary? _library; [JsonIgnore] public FileLibrary? Library = null!;
[JsonIgnore]
public FileLibrary? Library
{
get => _lazyLoader.Load(this, ref _library);
set
{
LibraryId = value?.Key;
_library = value;
}
}
public ICollection<Author> Authors { get; internal set; }= null!; public ICollection<Author> Authors { get; internal set; }= null!;
public ICollection<MangaTag> MangaTags { get; internal set; }= null!; public ICollection<MangaTag> MangaTags { get; internal set; }= null!;
@@ -45,25 +35,11 @@ public class Manga : Identifiable
public string? FullDirectoryPath => Library is not null ? Path.Join(Library.BasePath, DirectoryName) : null; public string? FullDirectoryPath => Library is not null ? Path.Join(Library.BasePath, DirectoryName) : null;
[NotMapped] public ICollection<string> ChapterIds => Chapters.Select(c => c.Key).ToList(); [NotMapped] public ICollection<string> ChapterIds => Chapters.Select(c => c.Key).ToList();
private ICollection<Chapter>? _chapters; [JsonIgnore] public ICollection<Chapter> Chapters = null!;
[JsonIgnore]
public ICollection<Chapter> Chapters
{
get => _lazyLoader.Load(this, ref _chapters) ?? throw new InvalidOperationException();
init => _chapters = value;
}
[NotMapped] public Dictionary<string, string> IdsOnMangaConnectors => [NotMapped] public Dictionary<string, string> IdsOnMangaConnectors =>
MangaConnectorIds.ToDictionary(id => id.MangaConnectorName, id => id.IdOnConnectorSite); MangaConnectorIds.ToDictionary(id => id.MangaConnectorName, id => id.IdOnConnectorSite);
private ICollection<MangaConnectorId<Manga>>? _mangaConnectorIds; [JsonIgnore] public ICollection<MangaConnectorId<Manga>> MangaConnectorIds = null!;
[JsonIgnore]
public ICollection<MangaConnectorId<Manga>> MangaConnectorIds
{
get => _lazyLoader.Load(this, ref _mangaConnectorIds) ?? throw new InvalidOperationException();
private set => _mangaConnectorIds = value;
}
private readonly ILazyLoader _lazyLoader = null!;
public Manga(string name, string description, string coverUrl, MangaReleaseStatus releaseStatus, public Manga(string name, string description, string coverUrl, MangaReleaseStatus releaseStatus,
ICollection<Author> authors, ICollection<MangaTag> mangaTags, ICollection<Link> links, ICollection<AltTitle> altTitles, ICollection<Author> authors, ICollection<MangaTag> mangaTags, ICollection<Link> links, ICollection<AltTitle> altTitles,
@@ -89,12 +65,11 @@ public class Manga : Identifiable
/// <summary> /// <summary>
/// EF ONLY!!! /// EF ONLY!!!
/// </summary> /// </summary>
public Manga(ILazyLoader lazyLoader, string key, string name, string description, string coverUrl, public Manga(string key, string name, string description, string coverUrl,
MangaReleaseStatus releaseStatus, MangaReleaseStatus releaseStatus,
string directoryName, float ignoreChaptersBefore, string? libraryId, uint? year, string? originalLanguage) string directoryName, float ignoreChaptersBefore, string? libraryId, uint? year, string? originalLanguage)
: base(key) : base(key)
{ {
this._lazyLoader = lazyLoader;
this.Name = name; this.Name = name;
this.Description = description; this.Description = description;
this.CoverUrl = coverUrl; this.CoverUrl = coverUrl;

View File

@@ -1,7 +1,6 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using API.Schema.MangaContext.MangaConnectors; using API.MangaConnectors;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace API.Schema.MangaContext; namespace API.Schema.MangaContext;
@@ -10,43 +9,19 @@ namespace API.Schema.MangaContext;
public class MangaConnectorId<T> : Identifiable where T : Identifiable public class MangaConnectorId<T> : Identifiable where T : Identifiable
{ {
[StringLength(64)] [Required] public string ObjId { get; private set; } = null!; [StringLength(64)] [Required] public string ObjId { get; private set; } = null!;
[JsonIgnore] private T? _obj; [JsonIgnore] public T Obj = null!;
[JsonIgnore]
public T Obj
{
get => _lazyLoader.Load(this, ref _obj) ?? throw new InvalidOperationException();
internal set
{
ObjId = value.Key;
_obj = value;
}
}
[StringLength(32)] [Required] public string MangaConnectorName { get; private set; } = null!; [StringLength(32)] [Required] public string MangaConnectorName { get; private set; } = null!;
[JsonIgnore] private MangaConnector? _mangaConnector;
[JsonIgnore]
public MangaConnector MangaConnector
{
get => _lazyLoader.Load(this, ref _mangaConnector) ?? throw new InvalidOperationException();
init
{
MangaConnectorName = value.Name;
_mangaConnector = value;
}
}
[StringLength(256)] [Required] public string IdOnConnectorSite { get; init; } [StringLength(256)] [Required] public string IdOnConnectorSite { get; init; }
[Url] [StringLength(512)] public string? WebsiteUrl { get; internal init; } [Url] [StringLength(512)] public string? WebsiteUrl { get; internal init; }
public bool UseForDownload { get; internal set; } public bool UseForDownload { get; internal set; }
private readonly ILazyLoader _lazyLoader = null!;
public MangaConnectorId(T obj, MangaConnector mangaConnector, string idOnConnectorSite, string? websiteUrl, bool useForDownload = false) public MangaConnectorId(T obj, MangaConnector mangaConnector, string idOnConnectorSite, string? websiteUrl, bool useForDownload = false)
: base(TokenGen.CreateToken(typeof(MangaConnectorId<T>), mangaConnector.Name, idOnConnectorSite)) : base(TokenGen.CreateToken(typeof(MangaConnectorId<T>), mangaConnector.Name, idOnConnectorSite))
{ {
this.Obj = obj; this.Obj = obj;
this.MangaConnector = mangaConnector; this.MangaConnectorName = mangaConnector.Name;
this.IdOnConnectorSite = idOnConnectorSite; this.IdOnConnectorSite = idOnConnectorSite;
this.WebsiteUrl = websiteUrl; this.WebsiteUrl = websiteUrl;
this.UseForDownload = useForDownload; this.UseForDownload = useForDownload;
@@ -55,10 +30,9 @@ public class MangaConnectorId<T> : Identifiable where T : Identifiable
/// <summary> /// <summary>
/// EF CORE ONLY!!! /// EF CORE ONLY!!!
/// </summary> /// </summary>
public MangaConnectorId(ILazyLoader lazyLoader, string key, string objId, string mangaConnectorName, string idOnConnectorSite, bool useForDownload, string? websiteUrl) public MangaConnectorId(string key, string objId, string mangaConnectorName, string idOnConnectorSite, bool useForDownload, string? websiteUrl)
: base(key) : base(key)
{ {
this._lazyLoader = lazyLoader;
this.ObjId = objId; this.ObjId = objId;
this.MangaConnectorName = mangaConnectorName; this.MangaConnectorName = mangaConnectorName;
this.IdOnConnectorSite = idOnConnectorSite; this.IdOnConnectorSite = idOnConnectorSite;
@@ -66,5 +40,5 @@ public class MangaConnectorId<T> : Identifiable where T : Identifiable
this.UseForDownload = useForDownload; this.UseForDownload = useForDownload;
} }
public override string ToString() => $"{base.ToString()} {_obj}"; public override string ToString() => $"{base.ToString()} {Obj}";
} }

View File

@@ -1,4 +1,4 @@
using API.Schema.MangaContext.MangaConnectors; using API.MangaConnectors;
using API.Schema.MangaContext.MetadataFetchers; using API.Schema.MangaContext.MetadataFetchers;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -6,7 +6,6 @@ namespace API.Schema.MangaContext;
public class MangaContext(DbContextOptions<MangaContext> options) : TrangaBaseContext<MangaContext>(options) public class MangaContext(DbContextOptions<MangaContext> options) : TrangaBaseContext<MangaContext>(options)
{ {
public DbSet<MangaConnector> MangaConnectors { get; set; }
public DbSet<Manga> Mangas { get; set; } public DbSet<Manga> Mangas { get; set; }
public DbSet<FileLibrary> FileLibraries { get; set; } public DbSet<FileLibrary> FileLibraries { get; set; }
public DbSet<Chapter> Chapters { get; set; } public DbSet<Chapter> Chapters { get; set; }
@@ -31,26 +30,12 @@ public class MangaContext(DbContextOptions<MangaContext> options) : TrangaBaseCo
.WithOne(c => c.ParentManga) .WithOne(c => c.ParentManga)
.HasForeignKey(c => c.ParentMangaId) .HasForeignKey(c => c.ParentMangaId)
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Manga>()
.Navigation(m => m.Chapters)
.EnableLazyLoading();
modelBuilder.Entity<Chapter>()
.Navigation(c => c.ParentManga)
.EnableLazyLoading();
//Chapter has MangaConnectorIds //Chapter has MangaConnectorIds
modelBuilder.Entity<Chapter>() modelBuilder.Entity<Chapter>()
.HasMany<MangaConnectorId<Chapter>>(c => c.MangaConnectorIds) .HasMany<MangaConnectorId<Chapter>>(c => c.MangaConnectorIds)
.WithOne(id => id.Obj) .WithOne(id => id.Obj)
.HasForeignKey(id => id.ObjId) .HasForeignKey(id => id.ObjId)
.OnDelete(DeleteBehavior.NoAction); .OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<MangaConnectorId<Chapter>>()
.HasOne<MangaConnector>(id => id.MangaConnector)
.WithMany()
.HasForeignKey(id => id.MangaConnectorName)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<MangaConnectorId<Chapter>>()
.Navigation(entry => entry.MangaConnector)
.EnableLazyLoading();
//Manga owns MangaAltTitles //Manga owns MangaAltTitles
modelBuilder.Entity<Manga>() modelBuilder.Entity<Manga>()
.OwnsMany<AltTitle>(m => m.AltTitles) .OwnsMany<AltTitle>(m => m.AltTitles)
@@ -95,17 +80,6 @@ public class MangaContext(DbContextOptions<MangaContext> options) : TrangaBaseCo
.WithOne(id => id.Obj) .WithOne(id => id.Obj)
.HasForeignKey(id => id.ObjId) .HasForeignKey(id => id.ObjId)
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Manga>()
.Navigation(m => m.MangaConnectorIds)
.EnableLazyLoading();
modelBuilder.Entity<MangaConnectorId<Manga>>()
.HasOne<MangaConnector>(id => id.MangaConnector)
.WithMany()
.HasForeignKey(id => id.MangaConnectorName)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<MangaConnectorId<Manga>>()
.Navigation(entry => entry.MangaConnector)
.EnableLazyLoading();
//FileLibrary has many Mangas //FileLibrary has many Mangas
@@ -114,9 +88,6 @@ public class MangaContext(DbContextOptions<MangaContext> options) : TrangaBaseCo
.WithOne(m => m.Library) .WithOne(m => m.Library)
.HasForeignKey(m => m.LibraryId) .HasForeignKey(m => m.LibraryId)
.OnDelete(DeleteBehavior.SetNull); .OnDelete(DeleteBehavior.SetNull);
modelBuilder.Entity<Manga>()
.Navigation(m => m.Library)
.EnableLazyLoading();
modelBuilder.Entity<MetadataFetcher>() modelBuilder.Entity<MetadataFetcher>()
.HasDiscriminator<string>(nameof(MetadataEntry)) .HasDiscriminator<string>(nameof(MetadataEntry))

View File

@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using API.MangaConnectors;
using API.Schema.LibraryContext; using API.Schema.LibraryContext;
using API.Schema.MangaContext; using API.Schema.MangaContext;
using API.Schema.MangaContext.MetadataFetchers; using API.Schema.MangaContext.MetadataFetchers;
@@ -25,6 +26,7 @@ public static class Tranga
public static Thread PeriodicWorkerStarterThread { get; } = new (WorkerStarter); public static Thread PeriodicWorkerStarterThread { get; } = new (WorkerStarter);
private static readonly ILog Log = LogManager.GetLogger(typeof(Tranga)); private static readonly ILog Log = LogManager.GetLogger(typeof(Tranga));
internal static readonly MetadataFetcher[] MetadataFetchers = [new MyAnimeList()]; internal static readonly MetadataFetcher[] MetadataFetchers = [new MyAnimeList()];
internal static readonly MangaConnector[] MangaConnectors = [new Global(), new MangaDex(), new ComickIo()];
internal static TrangaSettings Settings = TrangaSettings.Load(); internal static TrangaSettings Settings = TrangaSettings.Load();
internal static readonly UpdateMetadataWorker UpdateMetadataWorker = new (); internal static readonly UpdateMetadataWorker UpdateMetadataWorker = new ();
@@ -52,6 +54,13 @@ public static class Tranga
AddWorker(StartNewChapterDownloadsWorker); AddWorker(StartNewChapterDownloadsWorker);
AddWorker(RemoveOldNotificationsWorker); AddWorker(RemoveOldNotificationsWorker);
} }
internal static bool TryGetMangaConnector(string name, [NotNullWhen(true)]out MangaConnector? mangaConnector)
{
mangaConnector =
MangaConnectors.FirstOrDefault(c => c.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
return mangaConnector != null;
}
internal static HashSet<BaseWorker> AllWorkers { get; private set; } = new (); internal static HashSet<BaseWorker> AllWorkers { get; private set; } = new ();

View File

@@ -1,8 +1,8 @@
using System.IO.Compression; using System.IO.Compression;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using API.MangaConnectors;
using API.MangaDownloadClients; using API.MangaDownloadClients;
using API.Schema.MangaContext; using API.Schema.MangaContext;
using API.Schema.MangaContext.MangaConnectors;
using SixLabors.ImageSharp; using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing;
@@ -17,17 +17,18 @@ public class DownloadChapterFromMangaconnectorWorker(MangaConnectorId<Chapter> c
internal readonly string MangaConnectorIdId = chId.Key; internal readonly string MangaConnectorIdId = chId.Key;
protected override BaseWorker[] DoWorkInternal() protected override BaseWorker[] DoWorkInternal()
{ {
if (DbContext.MangaConnectorToChapter.Find(MangaConnectorIdId) is not { } MangaConnectorId) if (DbContext.MangaConnectorToChapter.Find(MangaConnectorIdId) is not { } mangaConnectorId)
return []; //TODO Exception? return []; //TODO Exception?
MangaConnector mangaConnector = MangaConnectorId.MangaConnector; if (!Tranga.TryGetMangaConnector(mangaConnectorId.MangaConnectorName, out MangaConnector? mangaConnector))
Chapter chapter = MangaConnectorId.Obj; return []; //TODO Exception?
Chapter chapter = mangaConnectorId.Obj;
if (chapter.Downloaded) if (chapter.Downloaded)
{ {
Log.Info("Chapter was already downloaded."); Log.Info("Chapter was already downloaded.");
return []; return [];
} }
string[] imageUrls = mangaConnector.GetChapterImageUrls(MangaConnectorId); string[] imageUrls = mangaConnector.GetChapterImageUrls(mangaConnectorId);
if (imageUrls.Length < 1) if (imageUrls.Length < 1)
{ {
Log.Info($"No imageUrls for chapter {chapter}"); Log.Info($"No imageUrls for chapter {chapter}");
@@ -147,10 +148,15 @@ public class DownloadChapterFromMangaconnectorWorker(MangaConnectorId<Chapter> c
} }
//TODO MangaConnector Selection //TODO MangaConnector Selection
MangaConnectorId<Manga> mcId = manga.MangaConnectorIds.First(); MangaConnectorId<Manga> mangaConnectorId = manga.MangaConnectorIds.First();
if (!Tranga.TryGetMangaConnector(mangaConnectorId.MangaConnectorName, out MangaConnector? mangaConnector))
{
Log.Error($"MangaConnector with name {mangaConnectorId.MangaConnectorName} could not be found");
return;
}
Log.Info($"Copying cover to {publicationFolder}"); Log.Info($"Copying cover to {publicationFolder}");
string? fileInCache = manga.CoverFileNameInCache ?? mcId.MangaConnector.SaveCoverImageToCache(mcId); string? fileInCache = manga.CoverFileNameInCache ?? mangaConnector.SaveCoverImageToCache(mangaConnectorId);
if (fileInCache is null) if (fileInCache is null)
{ {
Log.Error($"File {fileInCache} does not exist"); Log.Error($"File {fileInCache} does not exist");

View File

@@ -1,5 +1,5 @@
using API.MangaConnectors;
using API.Schema.MangaContext; using API.Schema.MangaContext;
using API.Schema.MangaContext.MangaConnectors;
namespace API.Workers; namespace API.Workers;
@@ -9,12 +9,13 @@ public class DownloadCoverFromMangaconnectorWorker(MangaConnectorId<Manga> mcId,
internal readonly string MangaConnectorIdId = mcId.Key; internal readonly string MangaConnectorIdId = mcId.Key;
protected override BaseWorker[] DoWorkInternal() protected override BaseWorker[] DoWorkInternal()
{ {
if (DbContext.MangaConnectorToManga.Find(MangaConnectorIdId) is not { } MangaConnectorId) if (DbContext.MangaConnectorToManga.Find(MangaConnectorIdId) is not { } mangaConnectorId)
return []; //TODO Exception? return []; //TODO Exception?
MangaConnector mangaConnector = MangaConnectorId.MangaConnector; if (!Tranga.TryGetMangaConnector(mangaConnectorId.MangaConnectorName, out MangaConnector? mangaConnector))
Manga manga = MangaConnectorId.Obj; return []; //TODO Exception?
Manga manga = mangaConnectorId.Obj;
manga.CoverFileNameInCache = mangaConnector.SaveCoverImageToCache(MangaConnectorId); manga.CoverFileNameInCache = mangaConnector.SaveCoverImageToCache(mangaConnectorId);
DbContext.Sync(); DbContext.Sync();
return []; return [];

View File

@@ -1,5 +1,5 @@
using API.MangaConnectors;
using API.Schema.MangaContext; using API.Schema.MangaContext;
using API.Schema.MangaContext.MangaConnectors;
namespace API.Workers; namespace API.Workers;
@@ -9,13 +9,14 @@ public class RetrieveMangaChaptersFromMangaconnectorWorker(MangaConnectorId<Mang
internal readonly string MangaConnectorIdId = mcId.Key; internal readonly string MangaConnectorIdId = mcId.Key;
protected override BaseWorker[] DoWorkInternal() protected override BaseWorker[] DoWorkInternal()
{ {
if (DbContext.MangaConnectorToManga.Find(MangaConnectorIdId) is not { } MangaConnectorId) if (DbContext.MangaConnectorToManga.Find(MangaConnectorIdId) is not { } mangaConnectorId)
return []; //TODO Exception? return []; //TODO Exception?
MangaConnector mangaConnector = MangaConnectorId.MangaConnector; if (!Tranga.TryGetMangaConnector(mangaConnectorId.MangaConnectorName, out MangaConnector? mangaConnector))
Manga manga = MangaConnectorId.Obj; return []; //TODO Exception?
Manga manga = mangaConnectorId.Obj;
// This gets all chapters that are not downloaded // This gets all chapters that are not downloaded
(Chapter, MangaConnectorId<Chapter>)[] allChapters = (Chapter, MangaConnectorId<Chapter>)[] allChapters =
mangaConnector.GetChapters(MangaConnectorId, language).DistinctBy(c => c.Item1.Key).ToArray(); mangaConnector.GetChapters(mangaConnectorId, language).DistinctBy(c => c.Item1.Key).ToArray();
int addedChapters = 0; int addedChapters = 0;
foreach ((Chapter chapter, MangaConnectorId<Chapter> mcId) newChapter in allChapters) foreach ((Chapter chapter, MangaConnectorId<Chapter> mcId) newChapter in allChapters)

View File

@@ -1,4 +1,5 @@
using API.Schema.MangaContext; using API.Schema.MangaContext;
using Microsoft.EntityFrameworkCore;
namespace API.Workers; namespace API.Workers;
@@ -10,7 +11,9 @@ public class StartNewChapterDownloadsWorker(TimeSpan? interval = null, IEnumerab
public TimeSpan Interval { get; set; } = interval ?? TimeSpan.FromMinutes(1); public TimeSpan Interval { get; set; } = interval ?? TimeSpan.FromMinutes(1);
protected override BaseWorker[] DoWorkInternal() protected override BaseWorker[] DoWorkInternal()
{ {
IQueryable<MangaConnectorId<Chapter>> mangaConnectorIds = DbContext.MangaConnectorToChapter.Where(id => id.Obj.Downloaded == false && id.UseForDownload); IQueryable<MangaConnectorId<Chapter>> mangaConnectorIds = DbContext.MangaConnectorToChapter
.Include(id => id.Obj)
.Where(id => id.Obj.Downloaded == false && id.UseForDownload);
List<BaseWorker> newWorkers = new(); List<BaseWorker> newWorkers = new();
foreach (MangaConnectorId<Chapter> mangaConnectorId in mangaConnectorIds) foreach (MangaConnectorId<Chapter> mangaConnectorId in mangaConnectorIds)