Various updates.

This commit is contained in:
2026-01-25 18:33:32 -05:00
parent 4797d3c559
commit d747f68df8
11 changed files with 286 additions and 27 deletions

View File

@@ -4,6 +4,7 @@ public class Manga
{
public int MangaId { get; set; }
public required string Slug { get; set; }
public int? Year { get; set; }
public virtual ICollection<MangaCover> Covers { get; set; } = [];
public virtual ICollection<MangaTitle> Titles { get; set; } = [];

View File

@@ -8,9 +8,14 @@
<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.12.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.10" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
</ItemGroup>
<ItemGroup>

View File

@@ -14,4 +14,5 @@ public class SourceManga
public int? Votes { get; set; }
public SourceMangaChapter[] Chapters { get; set; } = [];
public string[] CoverArtUrls { get; set; } = [];
public int? Year { get; set; }
}

View File

@@ -1,6 +1,10 @@
using MangaReader.Core.Data;
using MangaReader.Core.Metadata;
using Microsoft.EntityFrameworkCore;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
namespace MangaReader.Core.Pipeline;
@@ -29,7 +33,7 @@ public partial class MangaPipeline(MangaContext context) : IMangaPipeline
foreach (SourceMangaDescription description in sourceManga.Descriptions)
{
await AddSourceDescriptionAsync(mangaSource, description);
//await AddDescriptionAsync(mangaSource, description);
await AddDescriptionAsync(manga, description);
}
foreach (SourceMangaTitle alternateTitle in sourceManga.AlternateTitles)
@@ -87,7 +91,10 @@ public partial class MangaPipeline(MangaContext context) : IMangaPipeline
manga.Sources.Any(mangaSource => mangaSource.Url == sourceUrl));
if (manga != null)
{
manga.Year = sourceManga.Year ?? manga.Year;
return manga;
}
manga = new()
{
@@ -353,6 +360,101 @@ public partial class MangaPipeline(MangaContext context) : IMangaPipeline
}
}
//public async Task RunCoversAsync(MangaPagePipelineRequest request, CancellationToken cancellationToken)
//{
// SourceCover[] sourceCovers = await context.SourceCovers
// .Where(x => x.MangaCoverId == null)
// .ToArrayAsync(cancellationToken);
// foreach (SourceCover sourceCover in sourceCovers)
// {
// await AddOrUpdateCoverAsync(sourceCover, cancellationToken);
// }
//}
//private async Task AddOrUpdateCoverAsync(SourceCover sourceCover, CancellationToken cancellationToken)
//{
// HttpClient client = httpClientFactory.CreateClient();
// client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0");
// using HttpResponseMessage responseMessage = await client.GetAsync(sourceCover.Url, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
// responseMessage.EnsureSuccessStatusCode();
// await using Stream networkStream = await responseMessage.Content.ReadAsStreamAsync(cancellationToken);
// Image image = await Image.LoadAsync(networkStream, cancellationToken);
// networkStream.Position = 0;
// IImageFormat imageFormat = await Image.DetectFormatAsync(networkStream, cancellationToken);
// // Normalize output extension (you can keep WEBP if your viewer supports it; WinUI often prefers JPEG/PNG)
// string extension = (imageFormat.Name?.ToLowerInvariant()) switch
// {
// "png" => "png",
// _ => "jpg"
// };
// // Save to memory to hash & maybe convert formats
// await using MemoryStream memoryStream = new();
// if (extension == "png")
// await image.SaveAsPngAsync(memoryStream, cancellationToken);
// else
// await image.SaveAsJpegAsync(memoryStream, cancellationToken);
// memoryStream.Position = 0;
// // Compute hash for dedupe
// string sha256;
// using (var sha = SHA256.Create())
// sha256 = Convert.ToHexString(sha.ComputeHash(memoryStream)).ToLowerInvariant();
// memoryStream.Position = 0;
// // Check if we already have this exact file
// var existing = await context.MangaCovers.FirstOrDefaultAsync(c => c.Sha256 == sha256 && c.MangaId == sc.MangaSource.MangaId, ct);
// var existing2 = await context.MangaCovers.FirstOrDefaultAsync(c => c. == sha256 && c.MangaId == sc.MangaSource.MangaId, ct);
// MangaCover cover;
// if (existing is not null)
// {
// cover = existing;
// }
// else
// {
// // Choose file path
// var folder = _paths.GetMangaCoverFolder(sc.MangaSource.MangaId);
// var guid = Guid.NewGuid();
// var fileName = $"{guid}.{ext}";
// var fullPath = Path.Combine(folder, fileName);
// // Write to disk
// await using (var fs = File.Create(fullPath))
// await ms.CopyToAsync(fs, ct);
// // Create DB record
// cover = new MangaCover
// {
// Manga = sc.MangaSource.Manga,
// Guid = guid,
// FileExtension = ext,
// Sha256 = sha256,
// Width = image.Width,
// Height = image.Height,
// IsPrimary = false
// };
// context.MangaCovers.Add(cover);
// }
// // Link and mark done
// sourceCover.MangaCover = cover;
// //sc.Status = CoverDownloadStatus.Done;
// //sc.Error = null;
// await context.SaveChangesAsync(cancellationToken);
//}
public async Task RunPagesAsync(MangaPagePipelineRequest request, CancellationToken cancellationToken)
{
SourceChapter? sourceChapter = await context.SourceChapters.FirstOrDefaultAsync(x => x.SourceChapterId == request.SourceChapterId, cancellationToken);

View File

@@ -6,4 +6,5 @@ public class MangaAttributes
public List<Dictionary<string, string>> AltTitles { get; set; } = [];
public Dictionary<string, string> Description { get; set; } = [];
public List<TagEntity> Tags { get; set; } = [];
public int? Year { get; set; }
}