mirror of
https://github.com/C9Glax/tranga.git
synced 2025-05-30 00:53:02 +02:00
Compare commits
4 Commits
02ab3d8cae
...
9659f2a68a
Author | SHA1 | Date | |
---|---|---|---|
9659f2a68a | |||
d474868116 | |||
b1312c4164 | |||
33856f9927 |
724
API/Migrations/pgsql/20250518183729_Remove-UpdateSingleChapterDownloaded-Job.Designer.cs
generated
Normal file
724
API/Migrations/pgsql/20250518183729_Remove-UpdateSingleChapterDownloaded-Job.Designer.cs
generated
Normal file
@ -0,0 +1,724 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using API.Schema.Contexts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace API.Migrations.pgsql
|
||||
{
|
||||
[DbContext(typeof(PgsqlContext))]
|
||||
[Migration("20250518183729_Remove-UpdateSingleChapterDownloaded-Job")]
|
||||
partial class RemoveUpdateSingleChapterDownloadedJob
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.5")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("API.Schema.Author", b =>
|
||||
{
|
||||
b.Property<string>("AuthorId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("AuthorName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("character varying(128)");
|
||||
|
||||
b.HasKey("AuthorId");
|
||||
|
||||
b.ToTable("Authors");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Chapter", b =>
|
||||
{
|
||||
b.Property<string>("ChapterId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("ChapterNumber")
|
||||
.IsRequired()
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("character varying(10)");
|
||||
|
||||
b.Property<bool>("Downloaded")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("FileName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("IdOnConnectorSite")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("ParentMangaId")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasMaxLength(2048)
|
||||
.HasColumnType("character varying(2048)");
|
||||
|
||||
b.Property<int?>("VolumeNumber")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("ChapterId");
|
||||
|
||||
b.HasIndex("ParentMangaId");
|
||||
|
||||
b.ToTable("Chapters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.Job", b =>
|
||||
{
|
||||
b.Property<string>("JobId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<byte>("JobType")
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.Property<DateTime>("LastExecution")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("ParentJobId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<decimal>("RecurrenceMs")
|
||||
.HasColumnType("numeric(20,0)");
|
||||
|
||||
b.Property<byte>("state")
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.HasKey("JobId");
|
||||
|
||||
b.HasIndex("ParentJobId");
|
||||
|
||||
b.ToTable("Jobs");
|
||||
|
||||
b.HasDiscriminator<byte>("JobType");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.LocalLibrary", b =>
|
||||
{
|
||||
b.Property<string>("LocalLibraryId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("BasePath")
|
||||
.IsRequired()
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("LibraryName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)");
|
||||
|
||||
b.HasKey("LocalLibraryId");
|
||||
|
||||
b.ToTable("LocalLibraries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Manga", b =>
|
||||
{
|
||||
b.Property<string>("MangaId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("CoverFileNameInCache")
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)");
|
||||
|
||||
b.Property<string>("CoverUrl")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("DirectoryName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1024)
|
||||
.HasColumnType("character varying(1024)");
|
||||
|
||||
b.Property<string>("IdOnConnectorSite")
|
||||
.IsRequired()
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<float>("IgnoreChaptersBefore")
|
||||
.HasColumnType("real");
|
||||
|
||||
b.Property<string>("LibraryId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("MangaConnectorName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("character varying(32)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)");
|
||||
|
||||
b.Property<string>("OriginalLanguage")
|
||||
.HasMaxLength(8)
|
||||
.HasColumnType("character varying(8)");
|
||||
|
||||
b.Property<byte>("ReleaseStatus")
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.Property<string>("WebsiteUrl")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("character varying(512)");
|
||||
|
||||
b.Property<long?>("Year")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("MangaId");
|
||||
|
||||
b.HasIndex("LibraryId");
|
||||
|
||||
b.HasIndex("MangaConnectorName");
|
||||
|
||||
b.ToTable("Mangas");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.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.MangaTag", b =>
|
||||
{
|
||||
b.Property<string>("Tag")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasKey("Tag");
|
||||
|
||||
b.ToTable("Tags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AuthorToManga", b =>
|
||||
{
|
||||
b.Property<string>("AuthorIds")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("MangaIds")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasKey("AuthorIds", "MangaIds");
|
||||
|
||||
b.HasIndex("MangaIds");
|
||||
|
||||
b.ToTable("AuthorToManga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("JobJob", b =>
|
||||
{
|
||||
b.Property<string>("DependsOnJobsJobId")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("JobId")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasKey("DependsOnJobsJobId", "JobId");
|
||||
|
||||
b.HasIndex("JobId");
|
||||
|
||||
b.ToTable("JobJob");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MangaTagToManga", b =>
|
||||
{
|
||||
b.Property<string>("MangaTagIds")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("MangaIds")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasKey("MangaTagIds", "MangaIds");
|
||||
|
||||
b.HasIndex("MangaIds");
|
||||
|
||||
b.ToTable("MangaTagToManga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadAvailableChaptersJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.ToTable("Jobs", t =>
|
||||
{
|
||||
t.Property("MangaId")
|
||||
.HasColumnName("DownloadAvailableChaptersJob_MangaId");
|
||||
});
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)1);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadMangaCoverJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)4);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadSingleChapterJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("ChapterId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("ChapterId");
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)0);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.MoveFileOrFolderJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("FromLocation")
|
||||
.IsRequired()
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("ToLocation")
|
||||
.IsRequired()
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)3);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.MoveMangaLibraryJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("ToLibraryId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.HasIndex("ToLibraryId");
|
||||
|
||||
b.ToTable("Jobs", t =>
|
||||
{
|
||||
t.Property("MangaId")
|
||||
.HasColumnName("MoveMangaLibraryJob_MangaId");
|
||||
});
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)7);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.RetrieveChaptersJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("Language")
|
||||
.IsRequired()
|
||||
.HasMaxLength(8)
|
||||
.HasColumnType("character varying(8)");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.ToTable("Jobs", t =>
|
||||
{
|
||||
t.Property("MangaId")
|
||||
.HasColumnName("RetrieveChaptersJob_MangaId");
|
||||
});
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)5);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.UpdateChaptersDownloadedJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.ToTable("Jobs", t =>
|
||||
{
|
||||
t.Property("MangaId")
|
||||
.HasColumnName("UpdateChaptersDownloadedJob_MangaId");
|
||||
});
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)6);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.UpdateCoverJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.ToTable("Jobs", t =>
|
||||
{
|
||||
t.Property("MangaId")
|
||||
.HasColumnName("UpdateCoverJob_MangaId");
|
||||
});
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)9);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.ComickIo", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("ComickIo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.Global", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("Global");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.MangaDex", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("MangaDex");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Chapter", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "ParentManga")
|
||||
.WithMany("Chapters")
|
||||
.HasForeignKey("ParentMangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("ParentManga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.Job", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Jobs.Job", "ParentJob")
|
||||
.WithMany()
|
||||
.HasForeignKey("ParentJobId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.Navigation("ParentJob");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Manga", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.LocalLibrary", "Library")
|
||||
.WithMany()
|
||||
.HasForeignKey("LibraryId")
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
|
||||
b.HasOne("API.Schema.MangaConnectors.MangaConnector", "MangaConnector")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaConnectorName")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.OwnsMany("API.Schema.Link", "Links", b1 =>
|
||||
{
|
||||
b1.Property<string>("LinkId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b1.Property<string>("LinkProvider")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b1.Property<string>("LinkUrl")
|
||||
.IsRequired()
|
||||
.HasMaxLength(2048)
|
||||
.HasColumnType("character varying(2048)");
|
||||
|
||||
b1.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b1.HasKey("LinkId");
|
||||
|
||||
b1.HasIndex("MangaId");
|
||||
|
||||
b1.ToTable("Link");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("MangaId");
|
||||
});
|
||||
|
||||
b.OwnsMany("API.Schema.MangaAltTitle", "AltTitles", b1 =>
|
||||
{
|
||||
b1.Property<string>("AltTitleId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b1.Property<string>("Language")
|
||||
.IsRequired()
|
||||
.HasMaxLength(8)
|
||||
.HasColumnType("character varying(8)");
|
||||
|
||||
b1.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b1.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b1.HasKey("AltTitleId");
|
||||
|
||||
b1.HasIndex("MangaId");
|
||||
|
||||
b1.ToTable("MangaAltTitle");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("MangaId");
|
||||
});
|
||||
|
||||
b.Navigation("AltTitles");
|
||||
|
||||
b.Navigation("Library");
|
||||
|
||||
b.Navigation("Links");
|
||||
|
||||
b.Navigation("MangaConnector");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AuthorToManga", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Author", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("AuthorIds")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("API.Schema.Manga", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaIds")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("JobJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Jobs.Job", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("DependsOnJobsJobId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("API.Schema.Jobs.Job", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("JobId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MangaTagToManga", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaIds")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("API.Schema.MangaTag", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaTagIds")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadAvailableChaptersJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "Manga")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Manga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadMangaCoverJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "Manga")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Manga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadSingleChapterJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Chapter", "Chapter")
|
||||
.WithMany()
|
||||
.HasForeignKey("ChapterId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Chapter");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.MoveMangaLibraryJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "Manga")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("API.Schema.LocalLibrary", "ToLibrary")
|
||||
.WithMany()
|
||||
.HasForeignKey("ToLibraryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Manga");
|
||||
|
||||
b.Navigation("ToLibrary");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.RetrieveChaptersJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "Manga")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Manga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.UpdateChaptersDownloadedJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "Manga")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Manga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.UpdateCoverJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "Manga")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Manga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Manga", b =>
|
||||
{
|
||||
b.Navigation("Chapters");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace API.Migrations.pgsql
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class RemoveUpdateSingleChapterDownloadedJob : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Jobs_Chapters_UpdateSingleChapterDownloadedJob_ChapterId",
|
||||
table: "Jobs");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Jobs_UpdateSingleChapterDownloadedJob_ChapterId",
|
||||
table: "Jobs");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "UpdateSingleChapterDownloadedJob_ChapterId",
|
||||
table: "Jobs");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "UpdateSingleChapterDownloadedJob_ChapterId",
|
||||
table: "Jobs",
|
||||
type: "character varying(64)",
|
||||
maxLength: 64,
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Jobs_UpdateSingleChapterDownloadedJob_ChapterId",
|
||||
table: "Jobs",
|
||||
column: "UpdateSingleChapterDownloadedJob_ChapterId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Jobs_Chapters_UpdateSingleChapterDownloadedJob_ChapterId",
|
||||
table: "Jobs",
|
||||
column: "UpdateSingleChapterDownloadedJob_ChapterId",
|
||||
principalTable: "Chapters",
|
||||
principalColumn: "ChapterId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
@ -457,26 +457,6 @@ namespace API.Migrations.pgsql
|
||||
b.HasDiscriminator().HasValue((byte)9);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.UpdateSingleChapterDownloadedJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("ChapterId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("ChapterId");
|
||||
|
||||
b.ToTable("Jobs", t =>
|
||||
{
|
||||
t.Property("ChapterId")
|
||||
.HasColumnName("UpdateSingleChapterDownloadedJob_ChapterId");
|
||||
});
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)8);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.ComickIo", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
@ -731,17 +711,6 @@ namespace API.Migrations.pgsql
|
||||
b.Navigation("Manga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.UpdateSingleChapterDownloadedJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Chapter", "Chapter")
|
||||
.WithMany()
|
||||
.HasForeignKey("ChapterId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Chapter");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Manga", b =>
|
||||
{
|
||||
b.Navigation("Chapters");
|
||||
|
@ -124,7 +124,7 @@ using (IServiceScope scope = app.Services.CreateScope())
|
||||
context.Jobs.AddRange(context.Jobs.Where(j => j.JobType == JobType.DownloadAvailableChaptersJob)
|
||||
.Include(downloadAvailableChaptersJob => ((DownloadAvailableChaptersJob)downloadAvailableChaptersJob).Manga)
|
||||
.ToList()
|
||||
.Select(dacj => new UpdateChaptersDownloadedJob(((DownloadAvailableChaptersJob)dacj).Manga, 0)));
|
||||
.Select(dacj => new UpdateChaptersDownloadedJob(((DownloadAvailableChaptersJob)dacj).Manga, 0, dacj)));
|
||||
context.Jobs.RemoveRange(context.Jobs.Where(j => j.state == JobState.Completed && j.RecurrenceMs < 1));
|
||||
foreach (Job job in context.Jobs.Where(j => j.state == JobState.Running))
|
||||
{
|
||||
|
@ -39,8 +39,7 @@ public class PgsqlContext(DbContextOptions<PgsqlContext> options) : DbContext(op
|
||||
.HasValue<DownloadMangaCoverJob>(JobType.DownloadMangaCoverJob)
|
||||
.HasValue<RetrieveChaptersJob>(JobType.RetrieveChaptersJob)
|
||||
.HasValue<UpdateCoverJob>(JobType.UpdateCoverJob)
|
||||
.HasValue<UpdateChaptersDownloadedJob>(JobType.UpdateChaptersDownloadedJob)
|
||||
.HasValue<UpdateSingleChapterDownloadedJob>(JobType.UpdateSingleChapterDownloadedJob);
|
||||
.HasValue<UpdateChaptersDownloadedJob>(JobType.UpdateChaptersDownloadedJob);
|
||||
|
||||
//Job specification
|
||||
modelBuilder.Entity<DownloadAvailableChaptersJob>()
|
||||
|
@ -167,7 +167,7 @@ public class DownloadSingleChapterJob : Job
|
||||
string newFilePath = Path.Join(publicationFolder, $"cover.{Path.GetFileName(fileInCache).Split('.')[^1]}" );
|
||||
File.Copy(fileInCache, newFilePath, true);
|
||||
if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
File.SetUnixFileMode(newFilePath, GroupRead | GroupWrite | UserRead | UserWrite);
|
||||
File.SetUnixFileMode(newFilePath, GroupRead | GroupWrite | UserRead | UserWrite | OtherRead | OtherWrite);
|
||||
Log.Debug($"Copied cover from {fileInCache} to {newFilePath}");
|
||||
}
|
||||
|
||||
|
@ -66,32 +66,31 @@ public abstract class Job
|
||||
this.Log = LogManager.GetLogger(this.GetType());
|
||||
}
|
||||
|
||||
public IEnumerable<Job> Run(PgsqlContext context)
|
||||
public IEnumerable<Job> Run(PgsqlContext context, ref bool running)
|
||||
{
|
||||
Log.Info($"Running job {JobId}");
|
||||
DateTime jobStart = DateTime.UtcNow;
|
||||
context.Attach(this);
|
||||
Job[]? ret = null;
|
||||
|
||||
try
|
||||
{
|
||||
this.state = JobState.Running;
|
||||
context.SaveChanges();
|
||||
running = true;
|
||||
ret = RunInternal(context).ToArray();
|
||||
Log.Info($"Job {JobId} completed. Generated {ret.Length} new jobs.");
|
||||
this.state = this.RecurrenceMs > 0 ? JobState.CompletedWaiting : JobState.Completed;
|
||||
this.LastExecution = DateTime.UtcNow;
|
||||
context.Jobs.AddRange(ret);
|
||||
Log.Info($"Job {JobId} completed. Generated {ret.Length} new jobs.");
|
||||
context.SaveChanges();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is not DbUpdateException)
|
||||
{
|
||||
Log.Error($"Failed to run job {JobId}", e);
|
||||
this.state = JobState.Failed;
|
||||
this.Enabled = false;
|
||||
this.LastExecution = DateTime.UtcNow;
|
||||
Log.Error($"Failed to run job {JobId}", e);
|
||||
context.SaveChanges();
|
||||
}
|
||||
else
|
||||
@ -99,6 +98,19 @@ public abstract class Job
|
||||
Log.Error($"Failed to update Database {JobId}", e);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (ret != null)
|
||||
{
|
||||
context.Jobs.AddRange(ret);
|
||||
context.SaveChanges();
|
||||
}
|
||||
}
|
||||
catch (DbUpdateException e)
|
||||
{
|
||||
Log.Error($"Failed to update Database {JobId}", e);
|
||||
}
|
||||
|
||||
Log.Info($"Finished Job {JobId}! (took {DateTime.UtcNow.Subtract(jobStart).TotalMilliseconds}ms)");
|
||||
return ret ?? [];
|
||||
|
@ -5,12 +5,10 @@ public enum JobType : byte
|
||||
{
|
||||
DownloadSingleChapterJob = 0,
|
||||
DownloadAvailableChaptersJob = 1,
|
||||
UpdateMetaDataJob = 2,
|
||||
MoveFileOrFolderJob = 3,
|
||||
DownloadMangaCoverJob = 4,
|
||||
RetrieveChaptersJob = 5,
|
||||
UpdateChaptersDownloadedJob = 6,
|
||||
MoveMangaLibraryJob = 7,
|
||||
UpdateSingleChapterDownloadedJob = 8,
|
||||
UpdateCoverJob = 9,
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using API.Schema.Contexts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@ -36,6 +37,20 @@ public class UpdateChaptersDownloadedJob : Job
|
||||
|
||||
protected override IEnumerable<Job> RunInternal(PgsqlContext context)
|
||||
{
|
||||
return Manga.Chapters.Select(c => new UpdateSingleChapterDownloadedJob(c, this));
|
||||
context.Entry(Manga).Reference<LocalLibrary>(m => m.Library).Load();
|
||||
foreach (Chapter mangaChapter in Manga.Chapters)
|
||||
{
|
||||
mangaChapter.Downloaded = mangaChapter.CheckDownloaded();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
context.SaveChanges();
|
||||
}
|
||||
catch (DbUpdateException e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using API.Schema.Contexts;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace API.Schema.Jobs;
|
||||
|
||||
public class UpdateSingleChapterDownloadedJob : Job
|
||||
{
|
||||
[StringLength(64)] [Required] public string ChapterId { get; init; }
|
||||
|
||||
private Chapter _chapter = null!;
|
||||
|
||||
[JsonIgnore]
|
||||
public Chapter Chapter
|
||||
{
|
||||
get => LazyLoader.Load(this, ref _chapter);
|
||||
init => _chapter = value;
|
||||
}
|
||||
|
||||
public UpdateSingleChapterDownloadedJob(Chapter chapter, Job? parentJob = null, ICollection<Job>? dependsOnJobs = null)
|
||||
: base(TokenGen.CreateToken(typeof(UpdateSingleChapterDownloadedJob)), JobType.UpdateSingleChapterDownloadedJob, 0, parentJob, dependsOnJobs)
|
||||
{
|
||||
this.ChapterId = chapter.ChapterId;
|
||||
this.Chapter = chapter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EF ONLY!!!
|
||||
/// </summary>
|
||||
internal UpdateSingleChapterDownloadedJob(ILazyLoader lazyLoader, string jobId, ulong recurrenceMs, string chapterId, string? parentJobId)
|
||||
: base(lazyLoader, jobId, JobType.UpdateSingleChapterDownloadedJob, recurrenceMs, parentJobId)
|
||||
{
|
||||
this.ChapterId = chapterId;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Job> RunInternal(PgsqlContext context)
|
||||
{
|
||||
context.Entry(Chapter).Reference<Manga>(c => c.ParentManga).Load();
|
||||
context.Entry(Chapter.ParentManga).Reference<LocalLibrary>(m => m.Library).Load();
|
||||
Chapter.Downloaded = Chapter.CheckDownloaded();
|
||||
|
||||
try
|
||||
{
|
||||
context.SaveChanges();
|
||||
}
|
||||
catch (DbUpdateException e)
|
||||
{
|
||||
Log.Error(e);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
@ -231,7 +231,7 @@ public class MangaDex : MangaConnector
|
||||
string? name = attributes?["title"]?.Value<string>("en") ?? attributes?["title"]?.First?.First?.Value<string>();
|
||||
string? description = attributes?["description"]?.Value<string>("en")??attributes?["description"]?.First?.First?.Value<string>();
|
||||
string? status = attributes?["status"]?.Value<string>();
|
||||
uint? year = attributes?["year"]?.Value<uint>();
|
||||
uint? year = attributes?["year"]?.Value<uint?>();
|
||||
string? originalLanguage = attributes?["originalLanguage"]?.Value<string>();
|
||||
JArray? altTitlesJArray = attributes?["altTitles"] as JArray;
|
||||
JArray? tagsJArray = attributes?["tags"] as JArray;
|
||||
|
@ -117,32 +117,21 @@ public static class Tranga
|
||||
return;
|
||||
}
|
||||
IServiceProvider serviceProvider = (IServiceProvider)serviceProviderObj;
|
||||
using IServiceScope scope = serviceProvider.CreateScope();
|
||||
|
||||
while (true)
|
||||
{
|
||||
Log.Debug("Starting Job-Cycle...");
|
||||
DateTime cycleStart = DateTime.UtcNow;
|
||||
using IServiceScope scope = serviceProvider.CreateScope();
|
||||
PgsqlContext cycleContext = scope.ServiceProvider.GetRequiredService<PgsqlContext>();
|
||||
Log.Debug("Loading Jobs...");
|
||||
DateTime loadStart = DateTime.UtcNow;
|
||||
Log.Debug($"Jobs Loaded! (took {DateTime.UtcNow.Subtract(loadStart).TotalMilliseconds}ms)");
|
||||
//Update finished Jobs to new states
|
||||
IQueryable<Job> completedJobs = cycleContext.Jobs.Where(j => j.state == JobState.Completed);
|
||||
foreach (Job completedJob in completedJobs)
|
||||
if (completedJob.RecurrenceMs <= 0)
|
||||
{
|
||||
cycleContext.Jobs.Remove(completedJob);
|
||||
}
|
||||
|
||||
//Retrieve waiting and due Jobs
|
||||
IQueryable<Job> runningJobs = cycleContext.Jobs.Where(j => j.state == JobState.Running);
|
||||
List<Job> runningJobs = cycleContext.Jobs.Where(j => j.state == JobState.Running).ToList();
|
||||
|
||||
DateTime filterStart = DateTime.UtcNow;
|
||||
Log.Debug("Filtering Jobs...");
|
||||
List<MangaConnector> busyConnectors = GetBusyConnectors(runningJobs);
|
||||
|
||||
IQueryable<Job> waitingJobs = cycleContext.Jobs.Where(j => j.state == JobState.CompletedWaiting || j.state == JobState.FirstExecution);
|
||||
List<Job> waitingJobs = cycleContext.Jobs.Where(j => j.state == JobState.CompletedWaiting || j.state == JobState.FirstExecution).ToList();
|
||||
List<Job> dueJobs = FilterDueJobs(waitingJobs);
|
||||
List<Job> jobsWithoutBusyConnectors = FilterJobWithBusyConnectors(dueJobs, busyConnectors);
|
||||
List<Job> jobsWithoutMissingDependencies = FilterJobDependencies(jobsWithoutBusyConnectors);
|
||||
@ -175,16 +164,21 @@ public static class Tranga
|
||||
//Start Jobs that are allowed to run (preconditions match)
|
||||
foreach (Job job in startJobs)
|
||||
{
|
||||
bool running = false;
|
||||
Thread t = new(() =>
|
||||
{
|
||||
using IServiceScope jobScope = serviceProvider.CreateScope();
|
||||
PgsqlContext jobContext = jobScope.ServiceProvider.GetRequiredService<PgsqlContext>();
|
||||
jobContext.Jobs.Find(job.JobId)?.Run(jobContext); //FIND the job IN THE NEW CONTEXT!!!!!!! SO WE DON'T GET TRACKING PROBLEMS AND AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
if (jobContext.Jobs.Find(job.JobId) is not { } inContext)
|
||||
return;
|
||||
inContext.Run(jobContext, ref running); //FIND the job IN THE NEW CONTEXT!!!!!!! SO WE DON'T GET TRACKING PROBLEMS AND AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
});
|
||||
RunningJobs.Add(t, job);
|
||||
t.Start();
|
||||
while(!running)
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
Log.Debug($"Jobs Completed: {completedJobs.Count()} Running: {runningJobs.Count()}\n" +
|
||||
Log.Debug($"Running: {runningJobs.Count()}\n" +
|
||||
$"Waiting: {waitingJobs.Count()}\n" +
|
||||
$"\tof which Due: {dueJobs.Count()}\n" +
|
||||
$"\t\tof which can be started: {jobsWithoutMissingDependencies.Count()}\n" +
|
||||
@ -211,7 +205,7 @@ public static class Tranga
|
||||
}
|
||||
}
|
||||
|
||||
private static List<MangaConnector> GetBusyConnectors(IQueryable<Job> runningJobs)
|
||||
private static List<MangaConnector> GetBusyConnectors(List<Job> runningJobs)
|
||||
{
|
||||
HashSet<MangaConnector> busyConnectors = new();
|
||||
foreach (Job runningJob in runningJobs)
|
||||
@ -222,7 +216,7 @@ public static class Tranga
|
||||
return busyConnectors.ToList();
|
||||
}
|
||||
|
||||
private static List<Job> FilterDueJobs(IQueryable<Job> jobs) =>
|
||||
private static List<Job> FilterDueJobs(List<Job> jobs) =>
|
||||
jobs.ToList()
|
||||
.Where(j => j.NextExecution < DateTime.UtcNow)
|
||||
.ToList();
|
||||
|
Loading…
x
Reference in New Issue
Block a user