I can't believe it's more fixes! (#863)

* Send stack trace to the UI on prod mode

* Pdfs will now generate cover images. I missed something a few releases ago.

* Ignore @Recently-Snapshot directories for QNAP.

* Refactored Bitmap code to use ImageSharp so it's truly cross platform.

* Updated pdf extraction to use a multi-threaded approach to greatly speed up pdf image extraction

* Hooked in Characters tag from ComicInfo.xml
This commit is contained in:
Joseph Milazzo 2021-12-20 11:50:47 -06:00 committed by GitHub
parent 6127f20bb2
commit bbdfe17247
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 28 additions and 28 deletions

View File

@ -171,6 +171,8 @@ namespace API.Tests.Parser
[InlineData("TEST/Love Hina - Special.jpg", false)]
[InlineData("__macosx/Love Hina/", false)]
[InlineData("MACOSX/Love Hina/", false)]
[InlineData("._Love Hina/Love Hina/", true)]
[InlineData("@Recently-Snapshot/Love Hina/", true)]
public void HasBlacklistedFolderInPathTest(string inputPath, bool expected)
{
Assert.Equal(expected, HasBlacklistedFolderInPath(inputPath));

View File

@ -62,6 +62,7 @@
<PackageReference Include="NetVips.Native" Version="8.12.1" />
<PackageReference Include="NReco.Logging.File" Version="1.1.2" />
<PackageReference Include="SharpCompress" Version="0.30.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.33.0.40503">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@ -76,6 +76,7 @@ namespace API.Data.Metadata
public string CoverArtist { get; set; } = string.Empty;
public string Editor { get; set; } = string.Empty;
public string Publisher { get; set; } = string.Empty;
public string Characters { get; set; } = string.Empty;
public static AgeRating ConvertAgeRatingToEnum(string value)
{

View File

@ -1097,7 +1097,7 @@ namespace API.Parser
public static bool HasBlacklistedFolderInPath(string path)
{
return path.Contains("__MACOSX");
return path.Contains("__MACOSX") || path.StartsWith("@Recently-Snapshot");
}

View File

@ -346,6 +346,7 @@ namespace API.Services
info.Letterer = Parser.Parser.CleanAuthor(info.Letterer);
info.Penciller = Parser.Parser.CleanAuthor(info.Penciller);
info.Publisher = Parser.Parser.CleanAuthor(info.Publisher);
info.Characters = Parser.Parser.CleanAuthor(info.Characters);
if (!string.IsNullOrEmpty(info.Web))
{

View File

@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@ -20,7 +17,10 @@ using ExCSS;
using HtmlAgilityPack;
using Microsoft.Extensions.Logging;
using Microsoft.IO;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using VersOne.Epub;
using Image = SixLabors.ImageSharp.Image;
namespace API.Services
{
@ -445,31 +445,25 @@ namespace API.Services
return null;
}
private static void AddBytesToBitmap(Bitmap bmp, byte[] rawBytes)
{
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
var bmpData = bmp.LockBits(rect, ImageLockMode.WriteOnly, bmp.PixelFormat);
var pNative = bmpData.Scan0;
Marshal.Copy(rawBytes, 0, pNative, rawBytes.Length);
bmp.UnlockBits(bmpData);
}
/// <summary>
/// Extracts a pdf into images to a target directory. Uses multi-threaded implementation since docnet is slow normally.
/// </summary>
/// <param name="fileFilePath"></param>
/// <param name="targetDirectory"></param>
public void ExtractPdfImages(string fileFilePath, string targetDirectory)
{
_directoryService.ExistOrCreate(targetDirectory);
using var docReader = DocLib.Instance.GetDocReader(fileFilePath, new PageDimensions(1080, 1920));
var pages = docReader.GetPageCount();
using var stream = StreamManager.GetStream("BookService.GetPdfPage");
for (var pageNumber = 0; pageNumber < pages; pageNumber++)
Parallel.For(0, pages, pageNumber =>
{
using var stream = StreamManager.GetStream("BookService.GetPdfPage");
GetPdfPage(docReader, pageNumber, stream);
using var fileStream = File.Create(Path.Combine(targetDirectory, "Page-" + pageNumber + ".png"));
stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(fileStream);
}
});
}
/// <summary>
@ -536,20 +530,14 @@ namespace API.Services
private static void GetPdfPage(IDocReader docReader, int pageNumber, Stream stream)
{
// TODO: BUG: Most of this Bitmap code is only supported on Windows. Refactor.
using var pageReader = docReader.GetPageReader(pageNumber);
var rawBytes = pageReader.GetImage(new NaiveTransparencyRemover());
var width = pageReader.GetPageWidth();
var height = pageReader.GetPageHeight();
using var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
AddBytesToBitmap(bmp, rawBytes);
// Removes 1px margin on left/right side after bitmap is copied out
for (var y = 0; y < bmp.Height; y++)
{
bmp.SetPixel(bmp.Width - 1, y, bmp.GetPixel(bmp.Width - 2, y));
}
var image = Image.LoadPixelData<Bgra32>(rawBytes, width, height);
stream.Seek(0, SeekOrigin.Begin);
bmp.Save(stream, ImageFormat.Jpeg);
image.SaveAsPng(stream);
stream.Seek(0, SeekOrigin.Begin);
}

View File

@ -113,6 +113,14 @@ public class MetadataService : IMetadataService
person => PersonHelper.AddPersonIfNotExists(chapter.People, person));
}
if (!string.IsNullOrEmpty(comicInfo.Characters))
{
var people = comicInfo.Characters.Split(",");
PersonHelper.RemovePeople(chapter.People, people, PersonRole.Character);
PersonHelper.UpdatePeople(allPeople, people, PersonRole.Character,
person => PersonHelper.AddPersonIfNotExists(chapter.People, person));
}
if (!string.IsNullOrEmpty(comicInfo.Translator))
{
var people = comicInfo.Translator.Split(",");
@ -220,7 +228,6 @@ public class MetadataService : IMetadataService
{
if (series == null) return;
//var firstFile = series.Volumes.FirstWithChapters().Chapters.Fir
if (!_cacheHelper.ShouldUpdateCoverImage(_directoryService.FileSystem.Path.Join(_directoryService.CoverImageDirectory, series.CoverImage),
null, series.Created, forceUpdate, series.CoverImageLocked))
return;