Added manga data and pipeline.
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace MangaReader.Core.Data;
|
||||
namespace MangaReader.Core.Data;
|
||||
|
||||
public class Manga
|
||||
{
|
||||
@@ -23,298 +21,4 @@ public class Manga
|
||||
Genres = new HashSet<MangaGenre>();
|
||||
Chapters = new HashSet<MangaChapter>();
|
||||
}
|
||||
}
|
||||
|
||||
public class MangaCover
|
||||
{
|
||||
public int MangaCoverId { get; set; }
|
||||
|
||||
public int MangaId { get; set; }
|
||||
public required Manga Manga { get; set; }
|
||||
|
||||
public required Guid Guid { get; set; }
|
||||
public required string FileExtension { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsPrimary { get; set; }
|
||||
}
|
||||
|
||||
public class MangaTitle
|
||||
{
|
||||
public int MangaTitleId { get; set; }
|
||||
|
||||
public int MangaId { get; set; }
|
||||
public required Manga Manga { get; set; }
|
||||
|
||||
public required string TitleEntry { get; set; }
|
||||
public TitleType TitleType { get; set; }
|
||||
}
|
||||
|
||||
public enum TitleType
|
||||
{
|
||||
Primary,
|
||||
OfficialTranslation,
|
||||
FanTranslation,
|
||||
Synonym,
|
||||
Abbreviation,
|
||||
Romaji,
|
||||
Japanese
|
||||
}
|
||||
|
||||
public class Source
|
||||
{
|
||||
public int SourceId { get; set; }
|
||||
public required string Name { get; set; }
|
||||
}
|
||||
|
||||
public class MangaSource
|
||||
{
|
||||
public int MangaId { get; set; }
|
||||
public required Manga Manga { get; set; }
|
||||
|
||||
public int SourceId { get; set; }
|
||||
public required Source Source { get; set; }
|
||||
|
||||
public required string Url { get; set; }
|
||||
}
|
||||
|
||||
public class Genre
|
||||
{
|
||||
public int GenreId { get; set; }
|
||||
public required string Name { get; set; }
|
||||
}
|
||||
|
||||
public class MangaGenre
|
||||
{
|
||||
public int MangaId { get; set; }
|
||||
public required Manga Manga { get; set; }
|
||||
|
||||
public int GenreId { get; set; }
|
||||
public required Genre Genre { get; set; }
|
||||
}
|
||||
|
||||
public class MangaChapter
|
||||
{
|
||||
public int MangaChapterId { get; set; }
|
||||
|
||||
public int MangaId { get; set; }
|
||||
public required Manga Manga { get; set; }
|
||||
|
||||
public int? VolumeNumber { get; set; }
|
||||
public int ChapterNumber { get; set; }
|
||||
public string? Title { get; set; }
|
||||
|
||||
public virtual ICollection<ChapterSource> Sources { get; set; } = [];
|
||||
public virtual ICollection<ChapterPage> Pages { get; set; } = [];
|
||||
}
|
||||
|
||||
public class ChapterSource
|
||||
{
|
||||
public int MangaChapterId { get; set; }
|
||||
public required MangaChapter Chapter { get; set; }
|
||||
|
||||
public int SourceId { get; set; }
|
||||
public required Source Source { get; set; }
|
||||
|
||||
public required string Url { get; set; }
|
||||
}
|
||||
|
||||
public class ChapterPage
|
||||
{
|
||||
public int ChapterPageId { get; set; }
|
||||
|
||||
public int MangaChapterId { get; set; }
|
||||
public required MangaChapter MangaChapter { get; set; }
|
||||
|
||||
public int PageNumber { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class MangaContext(DbContextOptions options) : DbContext(options)
|
||||
{
|
||||
public DbSet<Manga> Mangas { get; set; }
|
||||
public DbSet<MangaCover> MangaCovers { get; set; }
|
||||
public DbSet<MangaTitle> MangaTitles { get; set; }
|
||||
public DbSet<Source> Sources { get; set; }
|
||||
public DbSet<MangaSource> MangaSources { get; set; }
|
||||
public DbSet<Genre> Genres { get; set; }
|
||||
public DbSet<MangaGenre> MangaGenres { get; set; }
|
||||
public DbSet<MangaChapter> MangaChapters { get; set; }
|
||||
public DbSet<ChapterSource> ChapterSources { get; set; }
|
||||
public DbSet<ChapterPage> ChapterPages { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
ConfigureManga(modelBuilder);
|
||||
ConfigureMangaCover(modelBuilder);
|
||||
ConfigureMangaTitle(modelBuilder);
|
||||
ConfigureSource(modelBuilder);
|
||||
ConfigureMangaSource(modelBuilder);
|
||||
ConfigureGenre(modelBuilder);
|
||||
ConfigureMangaGenre(modelBuilder);
|
||||
ConfigureMangaChapter(modelBuilder);
|
||||
ConfigureChapterSource(modelBuilder);
|
||||
ConfigureChapterPage(modelBuilder);
|
||||
}
|
||||
|
||||
private static void ConfigureManga(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Entity<Manga>()
|
||||
.HasKey(x => x.MangaId);
|
||||
|
||||
modelBuilder.Entity<Manga>()
|
||||
.HasIndex(x => x.Slug)
|
||||
.IsUnique();
|
||||
}
|
||||
|
||||
private static void ConfigureMangaCover(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Entity<MangaCover>()
|
||||
.HasKey(x => x.MangaCoverId);
|
||||
|
||||
modelBuilder
|
||||
.Entity<MangaCover>()
|
||||
.HasOne(x => x.Manga)
|
||||
.WithMany(x => x.Covers)
|
||||
.HasForeignKey(x => x.MangaId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<MangaCover>()
|
||||
.HasIndex(x => x.Guid)
|
||||
.IsUnique();
|
||||
|
||||
//modelBuilder
|
||||
// .Entity<MangaCover>()
|
||||
// .HasIndex(x => new { x.MangaId, x.IsPrimary })
|
||||
// .IsUnique()
|
||||
// .HasFilter("[IsPrimary] = 1"); // Enforce only one primary cover per manga
|
||||
}
|
||||
|
||||
private static void ConfigureMangaTitle(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Entity<MangaTitle>()
|
||||
.HasKey(mangaTitle => mangaTitle.MangaTitleId);
|
||||
|
||||
modelBuilder.Entity<MangaTitle>()
|
||||
.HasIndex(mangaTitle => new { mangaTitle.MangaId, mangaTitle.TitleEntry })
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder
|
||||
.Entity<MangaTitle>()
|
||||
.HasIndex(mangaTitle => mangaTitle.TitleEntry);
|
||||
|
||||
modelBuilder
|
||||
.Entity<MangaTitle>()
|
||||
.HasOne(x => x.Manga)
|
||||
.WithMany(x => x.Titles)
|
||||
.HasForeignKey(x => x.MangaId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
|
||||
private static void ConfigureSource(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Entity<Source>()
|
||||
.HasKey(x => x.SourceId);
|
||||
|
||||
modelBuilder
|
||||
.Entity<Source>()
|
||||
.HasIndex(x => x.Name)
|
||||
.IsUnique(true);
|
||||
}
|
||||
|
||||
private static void ConfigureMangaSource(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Entity<MangaSource>()
|
||||
.HasKey(mangaSource => new { mangaSource.MangaId, mangaSource.SourceId });
|
||||
|
||||
modelBuilder.Entity<MangaSource>()
|
||||
.HasIndex(x => x.Url)
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder
|
||||
.Entity<MangaSource>()
|
||||
.HasOne(x => x.Manga)
|
||||
.WithMany(x => x.Sources)
|
||||
.HasForeignKey(x => x.MangaId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
|
||||
private static void ConfigureGenre(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Entity<Genre>()
|
||||
.HasKey(x => x.GenreId);
|
||||
|
||||
modelBuilder
|
||||
.Entity<Genre>()
|
||||
.HasIndex(x => x.Name)
|
||||
.IsUnique(true);
|
||||
}
|
||||
|
||||
private static void ConfigureMangaGenre(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Entity<MangaGenre>()
|
||||
.HasKey(mangaGenre => new { mangaGenre.MangaId, mangaGenre.GenreId });
|
||||
|
||||
modelBuilder
|
||||
.Entity<MangaGenre>()
|
||||
.HasOne(x => x.Manga)
|
||||
.WithMany(x => x.Genres)
|
||||
.HasForeignKey(x => x.MangaId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
|
||||
private static void ConfigureMangaChapter(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Entity<MangaChapter>()
|
||||
.HasKey(x => x.MangaChapterId);
|
||||
|
||||
modelBuilder
|
||||
.Entity<MangaChapter>()
|
||||
.HasOne(x => x.Manga)
|
||||
.WithMany(x => x.Chapters)
|
||||
.HasForeignKey(x => x.MangaId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
|
||||
private static void ConfigureChapterSource(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Entity<ChapterSource>()
|
||||
.HasKey(chapterSource => new { chapterSource.MangaChapterId, chapterSource.SourceId });
|
||||
|
||||
modelBuilder
|
||||
.Entity<ChapterSource>()
|
||||
.HasOne(x => x.Chapter)
|
||||
.WithMany(x => x.Sources)
|
||||
.HasForeignKey(x => x.MangaChapterId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
|
||||
private static void ConfigureChapterPage(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Entity<ChapterPage>()
|
||||
.HasKey(chapterPage => chapterPage.ChapterPageId);
|
||||
|
||||
modelBuilder
|
||||
.Entity<ChapterPage>()
|
||||
.HasIndex(chapterPage => new { chapterPage.MangaChapterId, chapterPage.PageNumber })
|
||||
.IsUnique(true);
|
||||
|
||||
modelBuilder
|
||||
.Entity<ChapterPage>()
|
||||
.HasOne(x => x.MangaChapter)
|
||||
.WithMany(x => x.Pages)
|
||||
.HasForeignKey(x => x.MangaChapterId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user