ISBN Support (#1985)

* Fixed a bug where weblinks would always show

* Started to try and support ico -> png conversion by manually grabbing image data out, but it's hard as hell.

* Implemented ability to parse out ISBN codes for books and ISBN-13 codes for ComicInfo. I can't figure out ISBN-10.

* Fixed Favicon not working on anything but windows

* Implemented ISBN support into Kavita

* Don't round so much when transforming bytes
This commit is contained in:
Joe Milazzo 2023-05-11 20:13:58 -05:00 committed by GitHub
parent a293500f42
commit 6be9ee39f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 2083 additions and 15 deletions

View file

@ -11,6 +11,7 @@ using API.Data.Metadata;
using API.DTOs.Reader;
using API.Entities;
using API.Entities.Enums;
using API.Helpers;
using API.Services.Tasks.Scanner.Parser;
using Docnet.Core;
using Docnet.Core.Converters;
@ -21,6 +22,7 @@ using HtmlAgilityPack;
using Kavita.Common;
using Microsoft.Extensions.Logging;
using Microsoft.IO;
using Nager.ArticleNumber;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using VersOne.Epub;
@ -433,6 +435,14 @@ public class BookService : IBookService
};
ComicInfo.CleanComicInfo(info);
foreach (var identifier in epubBook.Schema.Package.Metadata.Identifiers.Where(id => id.Scheme.Equals("ISBN")))
{
var isbn = identifier.Identifier.Replace("urn:isbn:", string.Empty);
if (!ArticleNumberHelper.IsValidIsbn10(isbn) && !ArticleNumberHelper.IsValidIsbn13(isbn)) continue;
info.Isbn = isbn;
break;
}
// Parse tags not exposed via Library
foreach (var metadataItem in epubBook.Schema.Package.Metadata.MetaItems)
{

View file

@ -1,18 +1,15 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Flurl;
using Flurl.Http;
using HtmlAgilityPack;
using Kavita.Common;
using Microsoft.Extensions.Logging;
using NetVips;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using Image = NetVips.Image;
using Size = SixLabors.ImageSharp.Size;
namespace API.Services;
@ -194,17 +191,46 @@ public class ImageService : IImageService
var baseUrl = uri.Scheme + "://" + uri.Host;
try
{
var validIconRelations = new[]
{
"icon",
"apple-touch-icon",
};
var htmlContent = url.GetStringAsync().Result;
var htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(htmlContent);
var pngLinks = htmlDocument.DocumentNode.Descendants("link")
.Where(link => validIconRelations.Contains(link.GetAttributeValue("rel", string.Empty)))
.Select(link => link.GetAttributeValue("href", string.Empty))
.Where(href => href.EndsWith(".png") || href.EndsWith(".PNG"))
.ToList();
if (pngLinks == null)
{
throw new KavitaException($"Could not grab favicon from {baseUrl}");
}
var correctSizeLink = pngLinks.FirstOrDefault(pngLink => pngLink.Contains("32")) ?? pngLinks.FirstOrDefault();
if (string.IsNullOrEmpty(correctSizeLink))
{
throw new KavitaException($"Could not grab favicon from {baseUrl}");
}
var finalUrl = correctSizeLink;
if (!correctSizeLink.StartsWith(uri.Scheme))
{
finalUrl = Url.Combine(baseUrl, correctSizeLink);
}
_logger.LogTrace("Fetching favicon from {Url}", finalUrl);
// Download the favicon.ico file using Flurl
var faviconStream = await baseUrl
.AppendPathSegment("favicon.ico")
.AllowHttpStatus("2xx")
var faviconStream = await finalUrl
.AllowHttpStatus("2xx,304")
.GetStreamAsync();
// Create the destination file path
var filename = $"{domain}.png";
using var icon = new Icon(faviconStream);
using var bitmap = icon.ToBitmap();
bitmap.Save(Path.Combine(_directoryService.FaviconDirectory, filename), ImageFormat.Png);
using var image = Image.PngloadStream(faviconStream);
image.Pngsave(Path.Combine(_directoryService.FaviconDirectory, filename));
_logger.LogDebug("Favicon.png for {Domain} downloaded and saved successfully", domain);
return filename;

View file

@ -36,7 +36,7 @@ public interface IProcessSeries
void UpdateVolumes(Series series, IList<ParserInfo> parsedInfos, bool forceUpdate = false);
void UpdateChapters(Series series, Volume volume, IList<ParserInfo> parsedInfos, bool forceUpdate = false);
void AddOrUpdateFileForChapter(Chapter chapter, ParserInfo info, bool forceUpdate = false);
void UpdateChapterFromComicInfo(Chapter chapter, ComicInfo? info);
void UpdateChapterFromComicInfo(Chapter chapter, ComicInfo? comicInfo);
}
/// <summary>
@ -722,6 +722,11 @@ public class ProcessSeries : IProcessSeries
);
}
if (!string.IsNullOrEmpty(comicInfo.Isbn))
{
chapter.ISBN = comicInfo.Isbn;
}
if (comicInfo.Count > 0)
{
chapter.TotalCount = comicInfo.Count;