mirror of
https://github.com/revenz/FileFlowsPlugins.git
synced 2026-02-05 05:59:20 -06:00
FF-254 - added comic book nodes
This commit is contained in:
48
ComicNodes/ComicNodes.csproj
Normal file
48
ComicNodes/ComicNodes.csproj
Normal file
@@ -0,0 +1,48 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>FileFlows.$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
|
||||
<FileVersion>0.9.4.168</FileVersion>
|
||||
<ProductVersion>0.9.4.168</ProductVersion>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<PublishTrimmed>true</PublishTrimmed>
|
||||
<Company>FileFlows</Company>
|
||||
<Authors>John Andrews</Authors>
|
||||
<Product>Comic Nodes</Product>
|
||||
<PackageProjectUrl>https://fileflows.com/</PackageProjectUrl>
|
||||
<Description>Nodes for processing comic books (cbr, cbz, pdf etc)</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="ComicNodes.en.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="ComicNodes.en.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(Configuration)' == 'Debug'">
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Docnet.Core" Version="2.3.1" />
|
||||
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta15" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="FileFlows.Plugin">
|
||||
<HintPath>..\FileFlows.Plugin.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
27
ComicNodes/ComicNodes.en.json
Normal file
27
ComicNodes/ComicNodes.en.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"Flow": {
|
||||
"Parts": {
|
||||
"ComicConverter": {
|
||||
"Outputs": {
|
||||
"1": "Comic was converted and saved as temporary file",
|
||||
"2": "Comic was already in desired format"
|
||||
},
|
||||
"Description": "Converts a comic to a different comic book format",
|
||||
"Fields": {
|
||||
"Format": "Format",
|
||||
"Format-Help": "The format to convert the comic into"
|
||||
}
|
||||
},
|
||||
"ComicExtractor": {
|
||||
"Outputs": {
|
||||
"1": "Comic was extracted"
|
||||
},
|
||||
"Description": "Extracts all files from a comic book format and saves them to them to a specific folder",
|
||||
"Fields": {
|
||||
"DestinationPath": "Destination Path",
|
||||
"DestinationPath-Help": "The folder to save the extract comic book files to"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
83
ComicNodes/Comics/ComicConverter.cs
Normal file
83
ComicNodes/Comics/ComicConverter.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace FileFlows.ComicNodes.Comics;
|
||||
|
||||
public class ComicConverter: Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 2;
|
||||
public override FlowElementType Type => FlowElementType.Process;
|
||||
public override string Icon => "fas fa-book";
|
||||
public override bool FailureNode => true;
|
||||
|
||||
|
||||
[DefaultValue("cbz")]
|
||||
[Select(nameof(FormatOptions), 1)]
|
||||
public string Format { get; set; } = string.Empty;
|
||||
|
||||
private static List<ListOption> _FormatOptions;
|
||||
public static List<ListOption> FormatOptions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_FormatOptions == null)
|
||||
{
|
||||
_FormatOptions = new List<ListOption>
|
||||
{
|
||||
new ListOption { Label = "CBZ", Value = "cbz"},
|
||||
//new ListOption { Label = "CB7", Value = "cb7"},
|
||||
new ListOption { Label = "PDF", Value = "pdf" }
|
||||
};
|
||||
}
|
||||
return _FormatOptions;
|
||||
}
|
||||
}
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
string currentFormat = new FileInfo(args.WorkingFile).Extension;
|
||||
if (string.IsNullOrEmpty(currentFormat))
|
||||
{
|
||||
args.Logger?.ELog("Could not detect format for: " + args.WorkingFile);
|
||||
return -1;
|
||||
}
|
||||
if(currentFormat[0] == '.')
|
||||
currentFormat = currentFormat[1..]; // remove the dot
|
||||
currentFormat = currentFormat.ToLower();
|
||||
|
||||
if(currentFormat == Format)
|
||||
{
|
||||
args.Logger?.ILog($"Already in the target format of '{Format}'");
|
||||
return 2;
|
||||
}
|
||||
|
||||
string destinationPath = Path.Combine(args.TempPath, Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(destinationPath);
|
||||
if (Helpers.ComicExtractor.Extract(args, args.WorkingFile, destinationPath, halfProgress: true) == false)
|
||||
return -1;
|
||||
|
||||
string newFile = CreateComic(args, destinationPath, this.Format);
|
||||
|
||||
args.SetWorkingFile(newFile);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private string CreateComic(NodeParameters args, string directory, string format)
|
||||
{
|
||||
string file = Path.Combine(args.TempPath, Guid.NewGuid().ToString() + "." + format);
|
||||
args.Logger?.ILog("Creating comic: " + file);
|
||||
if (format == "cbz")
|
||||
Helpers.ZipHelper.Compress(args, directory, file);
|
||||
//else if (format == "cb7")
|
||||
// Helpers.SevenZipHelper.Compress(args, directory, file + ".7z");
|
||||
else if (format == "pdf")
|
||||
Helpers.PdfHelper.Create(args, directory, file);
|
||||
else
|
||||
throw new Exception("Unknown format:" + format);
|
||||
Directory.Delete(directory, true);
|
||||
args.Logger?.ILog("Created comic: " + file);
|
||||
args.Logger?.ILog("Deleted temporary extraction directory: " + directory);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
29
ComicNodes/Comics/ComicExtractor.cs
Normal file
29
ComicNodes/Comics/ComicExtractor.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace FileFlows.ComicNodes.Comics;
|
||||
|
||||
public class ComicExtractor : Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 1;
|
||||
public override FlowElementType Type => FlowElementType.Process;
|
||||
public override string Icon => "fas fa-file-pdf";
|
||||
|
||||
[Required]
|
||||
[Folder(1)]
|
||||
public string DestinationPath { get; set; }
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
string dest = args.ReplaceVariables(DestinationPath, true);
|
||||
dest = dest.Replace("\\", Path.DirectorySeparatorChar.ToString());
|
||||
dest = dest.Replace("/", Path.DirectorySeparatorChar.ToString());
|
||||
if (string.IsNullOrEmpty(dest))
|
||||
{
|
||||
args.Logger?.ELog("No destination specified");
|
||||
args.Result = NodeResult.Failure;
|
||||
return -1;
|
||||
}
|
||||
Helpers.ComicExtractor.Extract(args, args.WorkingFile, dest, halfProgress: false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
6
ComicNodes/ExtensionMethods.cs
Normal file
6
ComicNodes/ExtensionMethods.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace FileFlows.Comic;
|
||||
|
||||
internal static class ExtensionMethods
|
||||
{
|
||||
public static string? EmptyAsNull(this string str) => str == string.Empty ? null : str;
|
||||
}
|
||||
5
ComicNodes/GlobalUsings.cs
Normal file
5
ComicNodes/GlobalUsings.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
global using System;
|
||||
global using System.Text;
|
||||
global using System.ComponentModel.DataAnnotations;
|
||||
global using FileFlows.Plugin;
|
||||
global using FileFlows.Plugin.Attributes;
|
||||
39
ComicNodes/Helpers/ComicExtractor.cs
Normal file
39
ComicNodes/Helpers/ComicExtractor.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FileFlows.ComicNodes.Helpers
|
||||
{
|
||||
internal class ComicExtractor
|
||||
{
|
||||
internal static bool Extract(NodeParameters args, string file, string destinationPath, bool halfProgress)
|
||||
{
|
||||
|
||||
string currentFormat = new FileInfo(args.WorkingFile).Extension;
|
||||
if (string.IsNullOrEmpty(currentFormat))
|
||||
{
|
||||
args.Logger?.ELog("Could not detect format for: " + args.WorkingFile);
|
||||
return false;
|
||||
}
|
||||
if (currentFormat[0] == '.')
|
||||
currentFormat = currentFormat[1..]; // remove the dot
|
||||
currentFormat = currentFormat.ToLower();
|
||||
|
||||
Directory.CreateDirectory(destinationPath);
|
||||
args.Logger?.ILog("Extracting comic pages to: " + destinationPath);
|
||||
|
||||
if (currentFormat == "pdf")
|
||||
PdfHelper.Extract(args, args.WorkingFile, destinationPath, "page", halfProgress: halfProgress);
|
||||
else if (currentFormat == "cbz")
|
||||
ZipHelper.Extract(args, args.WorkingFile, destinationPath, halfProgress: halfProgress);
|
||||
else if (currentFormat == "cb7" || currentFormat == "cbr" || currentFormat == "gz" || currentFormat == "bz2")
|
||||
GenericExtractor.Extract(args, args.WorkingFile, destinationPath, halfProgress: halfProgress);
|
||||
else
|
||||
throw new Exception("Unknown format:" + currentFormat);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
ComicNodes/Helpers/GenericExtractor.cs
Normal file
28
ComicNodes/Helpers/GenericExtractor.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using SharpCompress.Archives;
|
||||
using System;
|
||||
using System.IO.Compression;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace FileFlows.ComicNodes.Helpers;
|
||||
|
||||
internal class GenericExtractor
|
||||
{
|
||||
/// <summary>
|
||||
/// Uncompresses a folder
|
||||
/// </summary>
|
||||
/// <param name="args">the node paratemers</param>
|
||||
/// <param name="workingFile">the file to extract</param>
|
||||
/// <param name="destinationPath">the location to extract to</param>
|
||||
/// <param name="halfProgress">if the NodeParameter.PartPercentageUpdate should end at 50%</param>
|
||||
internal static void Extract(NodeParameters args, string workingFile, string destinationPath, bool halfProgress = true)
|
||||
{
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
args?.PartPercentageUpdate(halfProgress ? 50 : 0);
|
||||
|
||||
ArchiveFactory.WriteToDirectory(workingFile, destinationPath);
|
||||
PageNameHelper.FixPageNames(destinationPath);
|
||||
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
args?.PartPercentageUpdate(halfProgress ? 50 : 100);
|
||||
}
|
||||
}
|
||||
20
ComicNodes/Helpers/PageNameHelper.cs
Normal file
20
ComicNodes/Helpers/PageNameHelper.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace FileFlows.ComicNodes.Helpers;
|
||||
|
||||
internal class PageNameHelper
|
||||
{
|
||||
internal static void FixPageNames(string directory)
|
||||
{
|
||||
|
||||
var files = new DirectoryInfo(directory).GetFiles();
|
||||
foreach (var file in files)
|
||||
{
|
||||
var numMatch = Regex.Match(file.Name, @"[\d]+");
|
||||
if (numMatch.Success == false)
|
||||
continue;
|
||||
// ensure any file that is stupidly name eg page1.jpg, page2.jpg, page10.jpg, page11.jpg etc is ordered correctly
|
||||
file.MoveTo(Path.Combine(directory, file.Name.Replace(numMatch.Value, int.Parse(numMatch.Value).ToString(new string('0', files.Length.ToString().Length)))));
|
||||
}
|
||||
}
|
||||
}
|
||||
118
ComicNodes/Helpers/PdfHelper.cs
Normal file
118
ComicNodes/Helpers/PdfHelper.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using Docnet.Core;
|
||||
using Docnet.Core.Editors;
|
||||
using Docnet.Core.Models;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace FileFlows.ComicNodes.Helpers;
|
||||
|
||||
internal class PdfHelper
|
||||
{
|
||||
public static void Extract(NodeParameters args, string pdfFile, string destinationDirectory, string filePrefix, bool halfProgress = true)
|
||||
{
|
||||
using var library = DocLib.Instance;
|
||||
using var docReader = library.GetDocReader(pdfFile, new PageDimensions(1080, 1920));
|
||||
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
args?.PartPercentageUpdate(halfProgress ? 50 : 0);
|
||||
|
||||
int pageCount = docReader.GetPageCount();
|
||||
for (int i = 1; i < pageCount; i++)
|
||||
{
|
||||
using var pageReader = docReader.GetPageReader(i);
|
||||
var rawBytes = pageReader.GetImage();
|
||||
|
||||
var width = pageReader.GetPageWidth();
|
||||
var height = pageReader.GetPageHeight();
|
||||
|
||||
using var image = Image.LoadPixelData<Bgra32>(rawBytes, width, height);
|
||||
string file = Path.Combine(destinationDirectory, filePrefix + "-" + i.ToString(new String('0', pageCount.ToString().Length)) + ".png");
|
||||
image.SaveAsPng(file);
|
||||
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
{
|
||||
float percent = (i / pageCount) * 100f;
|
||||
if (halfProgress)
|
||||
percent = (percent / 2);
|
||||
args?.PartPercentageUpdate(percent);
|
||||
}
|
||||
}
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
args?.PartPercentageUpdate(halfProgress ? 50 : 0);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a PDF from images
|
||||
/// </summary>
|
||||
/// <param name="args">the NodeParameters</param>
|
||||
/// <param name="directory">the directory to of images</param>
|
||||
/// <param name="output">the output file of the pdf</param>
|
||||
/// <param name="halfProgress">if the NodePArameter.PartPercentageUpdate should start at 50%</param>
|
||||
internal static void Create(NodeParameters args, string directory, string output, bool halfProgress = true)
|
||||
{
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
args?.PartPercentageUpdate(halfProgress ? 50 : 0);
|
||||
var rgxImages = new Regex(@"\.(jpeg|jpg|jpe|png|webp)$");
|
||||
var files = Directory.GetFiles(directory).Where(x => rgxImages.IsMatch(x)).ToArray();
|
||||
|
||||
List<JpegImage> images = new List<JpegImage>();
|
||||
for(int i = 0; i < files.Length; i++)
|
||||
{
|
||||
var file = files[i];
|
||||
var format = Image.DetectFormat(file);
|
||||
var info = Image.Identify(file);
|
||||
if (file.ToLower().EndsWith(".png"))
|
||||
{
|
||||
var img = Image.Load(file);
|
||||
using var memoryStream = new MemoryStream();
|
||||
img.SaveAsJpeg(memoryStream);
|
||||
var jpeg = new JpegImage
|
||||
{
|
||||
Bytes = memoryStream.ToArray(),
|
||||
Width = info.Width,
|
||||
Height = info.Height
|
||||
};
|
||||
images.Add(jpeg);
|
||||
}
|
||||
else if(file.ToLower().EndsWith(".webp"))
|
||||
{
|
||||
var img = Image.Load(file);
|
||||
using var memoryStream = new MemoryStream();
|
||||
img.SaveAsJpeg(memoryStream);
|
||||
var jpeg = new JpegImage
|
||||
{
|
||||
Bytes = memoryStream.ToArray(),
|
||||
Width = info.Width,
|
||||
Height = info.Height
|
||||
};
|
||||
images.Add(jpeg);
|
||||
}
|
||||
else // jpeg
|
||||
{
|
||||
var jpeg = new JpegImage
|
||||
{
|
||||
Bytes = File.ReadAllBytes(file),
|
||||
Width = info.Width,
|
||||
Height = info.Height
|
||||
};
|
||||
images.Add(jpeg);
|
||||
|
||||
}
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
{
|
||||
float percent = (i / ((float)files.Length)) * 100f;
|
||||
if (halfProgress)
|
||||
percent = 50 + (percent / 2);
|
||||
args?.PartPercentageUpdate(percent);
|
||||
}
|
||||
}
|
||||
|
||||
var bytes = DocLib.Instance.JpegToPdf(images);
|
||||
File.WriteAllBytes(output, bytes);
|
||||
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
args?.PartPercentageUpdate(100);
|
||||
}
|
||||
}
|
||||
63
ComicNodes/Helpers/ZipHelper.cs
Normal file
63
ComicNodes/Helpers/ZipHelper.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace FileFlows.ComicNodes.Helpers;
|
||||
|
||||
internal class ZipHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Zips a folder to a file
|
||||
/// </summary>
|
||||
/// <param name="args">the NodeParameters</param>
|
||||
/// <param name="directory">the directory to zip</param>
|
||||
/// <param name="output">the output file of the zip</param>
|
||||
/// <param name="pattern">the file pattern to include in the zip</param>
|
||||
/// <param name="allDirectories">If all directories should be included or just the top most</param>
|
||||
/// <param name="halfProgress">if the NodePArameter.PartPercentageUpdate should start at 50%</param>
|
||||
internal static void Compress(NodeParameters args, string directory, string output, string pattern = "*.*", bool allDirectories = false, bool halfProgress = true)
|
||||
{
|
||||
|
||||
var dir = new DirectoryInfo(directory);
|
||||
var files = dir.GetFiles(pattern, allDirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
|
||||
using FileStream fs = new FileStream(output, FileMode.Create);
|
||||
using ZipArchive arch = new ZipArchive(fs, ZipArchiveMode.Create);
|
||||
if(args?.PartPercentageUpdate != null)
|
||||
args?.PartPercentageUpdate(halfProgress ? 50 : 0);
|
||||
float current = 0;
|
||||
float count = files.Length;
|
||||
foreach (var file in files)
|
||||
{
|
||||
++count;
|
||||
string relative = file.FullName.Substring(dir.FullName.Length + 1);
|
||||
try
|
||||
{
|
||||
arch.CreateEntryFromFile(file.FullName, relative, CompressionLevel.SmallestSize);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
args.Logger?.WLog("Failed to add file to zip: " + file.FullName + " => " + ex.Message);
|
||||
}
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
{
|
||||
float percent = (current / count) * 100f;
|
||||
if (halfProgress)
|
||||
percent = 50 + (percent / 2);
|
||||
args?.PartPercentageUpdate(percent);
|
||||
}
|
||||
}
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
args?.PartPercentageUpdate(100);
|
||||
}
|
||||
|
||||
internal static void Extract(NodeParameters args, string workingFile, string destinationPath, bool halfProgress = true)
|
||||
{
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
args?.PartPercentageUpdate(halfProgress ? 50 : 0);
|
||||
|
||||
ZipFile.ExtractToDirectory(workingFile, destinationPath);
|
||||
PageNameHelper.FixPageNames(destinationPath);
|
||||
|
||||
if (args?.PartPercentageUpdate != null)
|
||||
args?.PartPercentageUpdate(halfProgress ? 50 : 100);
|
||||
}
|
||||
}
|
||||
12
ComicNodes/Plugin.cs
Normal file
12
ComicNodes/Plugin.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace FileFlows.Comic;
|
||||
|
||||
public class Plugin : FileFlows.Plugin.IPlugin
|
||||
{
|
||||
public Guid Uid => new Guid("3664da0a-b531-47b9-bdc8-e8368d9746ce");
|
||||
public string Name => "Comic Nodes";
|
||||
public string MinimumVersion => "0.9.0.1487";
|
||||
|
||||
public void Init()
|
||||
{
|
||||
}
|
||||
}
|
||||
72
ComicNodes/Tests/ComicTests.cs
Normal file
72
ComicNodes/Tests/ComicTests.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
#if(DEBUG)
|
||||
|
||||
using FileFlows.ComicNodes.Comics;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace FileFlows.Comic.Tests;
|
||||
|
||||
[TestClass]
|
||||
public class ComicTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void Comic_Pdf_To_Cbz()
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(@"D:\comics\testfiles\fp1.pdf", logger, false, string.Empty);
|
||||
args.TempPath = @"D:\comics\temp";
|
||||
|
||||
var node = new ComicConverter();
|
||||
node.Format = "cbz";
|
||||
int result = node.Execute(args);
|
||||
|
||||
string log = logger.ToString();
|
||||
Assert.AreEqual(1, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Comic_Cbz_To_Pdf()
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(@"D:\comics\testfiles\mb.cbz", logger, false, string.Empty);
|
||||
args.TempPath = @"D:\comics\temp";
|
||||
|
||||
var node = new ComicConverter();
|
||||
node.Format = "pdf";
|
||||
int result = node.Execute(args);
|
||||
|
||||
string log = logger.ToString();
|
||||
Assert.AreEqual(1, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Comic_Cb7_To_Cbz()
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(@"D:\comics\testfiles\cb7.cb7", logger, false, string.Empty);
|
||||
args.TempPath = @"D:\comics\temp";
|
||||
|
||||
var node = new ComicConverter();
|
||||
node.Format = "cbz";
|
||||
int result = node.Execute(args);
|
||||
|
||||
string log = logger.ToString();
|
||||
Assert.AreEqual(1, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Comic_Cbr_To_Cbz()
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(@"D:\comics\testfiles\bm001.cbr", logger, false, string.Empty);
|
||||
args.TempPath = @"D:\comics\temp";
|
||||
|
||||
var node = new ComicConverter();
|
||||
node.Format = "cbz";
|
||||
int result = node.Execute(args);
|
||||
|
||||
string log = logger.ToString();
|
||||
Assert.AreEqual(1, result);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
80
ComicNodes/Tests/ExtractTests.cs
Normal file
80
ComicNodes/Tests/ExtractTests.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
#if(DEBUG)
|
||||
|
||||
using FileFlows.ComicNodes.Comics;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace FileFlows.Comic.Tests;
|
||||
|
||||
[TestClass]
|
||||
public class ExtractTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void Extract_Pdf()
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(@"D:\comics\testfiles\fp1.pdf", logger, false, string.Empty);
|
||||
|
||||
var node = new ComicExtractor();
|
||||
node.DestinationPath = @"D:\comics\converted\pdf";
|
||||
if (Directory.Exists(node.DestinationPath))
|
||||
Directory.Delete(node.DestinationPath, true);
|
||||
Directory.CreateDirectory(node.DestinationPath);
|
||||
int result = node.Execute(args);
|
||||
|
||||
string log = logger.ToString();
|
||||
Assert.AreEqual(1, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Extract_Cbr()
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(@"D:\comics\testfiles\bm001.cbr", logger, false, string.Empty);
|
||||
|
||||
var node = new ComicExtractor();
|
||||
node.DestinationPath = @"D:\comics\converted\cbr";
|
||||
if (Directory.Exists(node.DestinationPath))
|
||||
Directory.Delete(node.DestinationPath, true);
|
||||
Directory.CreateDirectory(node.DestinationPath);
|
||||
int result = node.Execute(args);
|
||||
|
||||
string log = logger.ToString();
|
||||
Assert.AreEqual(1, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Extract_Cbz()
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(@"D:\comics\testfiles\mb.cbz", logger, false, string.Empty);
|
||||
|
||||
var node = new ComicExtractor();
|
||||
node.DestinationPath = @"D:\comics\converted\cbz";
|
||||
if (Directory.Exists(node.DestinationPath))
|
||||
Directory.Delete(node.DestinationPath, true);
|
||||
Directory.CreateDirectory(node.DestinationPath);
|
||||
int result = node.Execute(args);
|
||||
|
||||
string log = logger.ToString();
|
||||
Assert.AreEqual(1, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Extract_Cb7()
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(@"D:\comics\testfiles\cb7.cb7", logger, false, string.Empty);
|
||||
|
||||
var node = new ComicExtractor();
|
||||
node.DestinationPath = @"D:\comics\converted\cb7";
|
||||
if(Directory.Exists(node.DestinationPath))
|
||||
Directory.Delete(node.DestinationPath, true);
|
||||
Directory.CreateDirectory(node.DestinationPath);
|
||||
int result = node.Execute(args);
|
||||
|
||||
string log = logger.ToString();
|
||||
Assert.AreEqual(1, result);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
59
ComicNodes/Tests/TestLogger.cs
Normal file
59
ComicNodes/Tests/TestLogger.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
#if(DEBUG)
|
||||
|
||||
namespace FileFlows.Comic.Tests;
|
||||
|
||||
using FileFlows.Plugin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class TestLogger : ILogger
|
||||
{
|
||||
private List<string> Messages = new List<string>();
|
||||
|
||||
public void DLog(params object[] args) => Log("DBUG", args);
|
||||
|
||||
public void ELog(params object[] args) => Log("ERRR", args);
|
||||
|
||||
public void ILog(params object[] args) => Log("INFO", args);
|
||||
|
||||
public void WLog(params object[] args) => Log("WARN", args);
|
||||
private void Log(string type, object[] args)
|
||||
{
|
||||
if (args == null || args.Length == 0)
|
||||
return;
|
||||
string message = type + " -> " +
|
||||
string.Join(", ", args.Select(x =>
|
||||
x == null ? "null" :
|
||||
x.GetType().IsPrimitive || x is string ? x.ToString() :
|
||||
System.Text.Json.JsonSerializer.Serialize(x)));
|
||||
Messages.Add(message);
|
||||
}
|
||||
|
||||
public bool Contains(string message)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message))
|
||||
return false;
|
||||
|
||||
string log = string.Join(Environment.NewLine, Messages);
|
||||
return log.Contains(message);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Join(Environment.NewLine, this.Messages.ToArray());
|
||||
}
|
||||
|
||||
public string GetTail(int length = 50)
|
||||
{
|
||||
if (length <= 0)
|
||||
length = 50;
|
||||
if (Messages.Count <= length)
|
||||
return string.Join(Environment.NewLine, Messages);
|
||||
return string.Join(Environment.NewLine, Messages.TakeLast(length));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -33,6 +33,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VideoLegacyNodes", "VideoLe
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AudioNodes", "AudioNodes\AudioNodes.csproj", "{600204C7-94F1-4793-9D02-D836A1B15B60}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComicNodes", "ComicNodes\ComicNodes.csproj", "{45568FCB-00FF-4AEA-AA43-DC569D667B04}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -99,6 +101,10 @@ Global
|
||||
{600204C7-94F1-4793-9D02-D836A1B15B60}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{600204C7-94F1-4793-9D02-D836A1B15B60}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{600204C7-94F1-4793-9D02-D836A1B15B60}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{45568FCB-00FF-4AEA-AA43-DC569D667B04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{45568FCB-00FF-4AEA-AA43-DC569D667B04}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{45568FCB-00FF-4AEA-AA43-DC569D667B04}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{45568FCB-00FF-4AEA-AA43-DC569D667B04}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Reference in New Issue
Block a user