Various updates.
This commit is contained in:
@@ -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; } = [];
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user