diff --git a/ComicNodes/Comics/ComicConverter.cs b/ComicNodes/Comics/ComicConverter.cs index 1cbf7f07..5c69135b 100644 --- a/ComicNodes/Comics/ComicConverter.cs +++ b/ComicNodes/Comics/ComicConverter.cs @@ -1,4 +1,5 @@ using System.ComponentModel; +using System.Diagnostics; using FileFlows.Plugin.Helpers; namespace FileFlows.ComicNodes.Comics; @@ -154,7 +155,7 @@ public class ComicConverter: Node if (Codec.ToLowerInvariant() is "webp" or "jpeg") { args.Logger?.ILog("Converting images to: " + Codec); - var rgxImages = new Regex(@"\.(jpeg|jpg|jpe|png|bmp|tiff|webp|gif)$", RegexOptions.IgnoreCase); + var rgxImages = new Regex(@"\.(jpeg|jpg|jp2|jpe|png|bmp|tiff|webp|gif)$", RegexOptions.IgnoreCase); var files = Directory.GetFiles(destinationPath, "*.*", SearchOption.AllDirectories); ImageOptions imageOptions = new() { @@ -165,10 +166,13 @@ public class ComicConverter: Node args.Logger?.ILog("Quality: " + Quality); args.Logger?.ILog("MaxWidth: " + MaxWidth); args.Logger?.ILog("MaxHeight: " + MaxHeight); + args.Logger?.ILog("Total Files: " + files.Length); args.PartPercentageUpdate?.Invoke(0); int count = 0; - foreach (string file in files) + + for (int i = 0; i < files.Length; i++) { + var file = files[i]; if (cancellation.IsCancellationRequested) break; try @@ -183,23 +187,47 @@ public class ComicConverter: Node continue; } - if (rgxImages.IsMatch(file)) - { - args.Logger?.ILog("Converting image: " + file); - string dest; - if (Codec.ToLowerInvariant() == "webp") - { - dest = Path.ChangeExtension(file, "webp"); - args.ImageHelper.ConvertToWebp(file, dest, imageOptions); - } - else - { - dest = Path.ChangeExtension(file, "jpg"); - args.ImageHelper.ConvertToJpeg(file, dest, imageOptions); - } + // if (file.ToLowerInvariant().EndsWith(".jp2")) + // { + // // special case + // if (ConvertJp2ToJpeg(args.Logger, ref file) == false) + // { + // args.FailureReason = + // "JPEG 2000 File detected which is only supported if ImageMagick is installed."; + // args.Logger?.ELog(args.FailureReason); + // break; + // } + // } - if (File.Exists(dest) && File.Exists(file) && file != dest) - File.Delete(file); + if (rgxImages.IsMatch(file) == false) + continue; + + DateTime dt = DateTime.UtcNow; + string dest; + if (Codec.ToLowerInvariant() == "webp") + { + dest = Path.ChangeExtension(file, "webp"); + args.ImageHelper.ConvertToWebp(file, dest, imageOptions); + } + else + { + dest = Path.ChangeExtension(file, "jpg"); + args.ImageHelper.ConvertToJpeg(file, dest, imageOptions); + } + + if (File.Exists(dest) == false) + { + args.FailureReason = "Failed to convert image: " + dest; + args.Logger?.ELog(args.FailureReason); + break; + } + + args.Logger?.ILog($"Converted image [{DateTime.UtcNow.Subtract(dt)}]: {dest}"); + + if (File.Exists(file) && file != dest) + { + args.Logger?.ILog("Deleting file: " + file); + File.Delete(file); } } finally @@ -207,6 +235,7 @@ public class ComicConverter: Node float total = files.Length; args.PartPercentageUpdate?.Invoke((count++ / total) * 100); } + } } @@ -219,6 +248,60 @@ public class ComicConverter: Node return 1; } + + + + + /// + /// Tries to use imagemagick to convert an image to JPEG + /// + /// The logger + /// the file to convert + /// true if converted + private bool ConvertJp2ToJpeg(ILogger logger, ref string file) + { + try + { + + string outFile = Path.ChangeExtension(file, "jpg"); + // Start the ImageMagick convert process + ProcessStartInfo startInfo = new ProcessStartInfo + { + FileName = "convert", // ImageMagick's convert command + ArgumentList = { file, outFile }, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + using Process process = Process.Start(startInfo); + // Capture output + string output = process.StandardOutput.ReadToEnd(); + string error = process.StandardError.ReadToEnd(); + process.WaitForExit(); + + // Check for errors + if (string.IsNullOrEmpty(error) == false) + { + logger?.ELog($"Error occurred: {error}"); + return false; + } + logger?.ILog("Converted JPEG 2000 File: " + file); + File.Delete(file); + + file = outFile; + + + // Conversion successful + return true; + } + catch (Exception ex) + { + logger.ELog($"An error occurred converted the JPEG 2000 image: {ex.Message}"); + return false; + } + } /// /// Cancels the conversion diff --git a/ComicNodes/Comics/CreateComicInfo.cs b/ComicNodes/Comics/CreateComicInfo.cs index 85625273..f42f2e3d 100644 --- a/ComicNodes/Comics/CreateComicInfo.cs +++ b/ComicNodes/Comics/CreateComicInfo.cs @@ -1,8 +1,6 @@ using System.Xml; using FileFlows.ComicNodes.Helpers; -using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; using FileHelper = FileFlows.Plugin.Helpers.FileHelper; -using Path = SixLabors.ImageSharp.Drawing.Path; namespace FileFlows.ComicNodes.Comics; @@ -68,6 +66,34 @@ public class CreateComicInfo : Node } args.Logger?.ILog("Got ComicInfo from filename"); + var newMetadata = new Dictionary + { + { nameof(info.Value.Title), info.Value.Title }, + { nameof(info.Value.Series), info.Value.Series }, + { nameof(info.Value.Publisher), info.Value.Publisher }, + { nameof(info.Value.Number), info.Value.Number }, + { nameof(info.Value.Count), info.Value.Count }, + { nameof(info.Value.Volume), info.Value.Volume }, + { nameof(info.Value.AlternateSeries), info.Value.AlternateSeries }, + { nameof(info.Value.AlternateNumber), info.Value.AlternateNumber }, + { nameof(info.Value.AlternateCount), info.Value.AlternateCount }, + { nameof(info.Value.Summary), info.Value.Summary }, + { nameof(info.Value.Notes), info.Value.Notes }, + { nameof(info.Value.ReleaseDate), info.Value.ReleaseDate }, + { nameof(info.Value.Tags), info.Value.Tags?.Any() == true ? string.Join(", ", info.Value.Tags) : null } + }.Where(x => x.Value != null) + .ToDictionary(x => x.Key, x => x.Value); + + if (args.Metadata != null) + { + foreach (var key in args.Metadata.Keys) + { + if (newMetadata.ContainsKey(key)) + continue; + newMetadata[key] = args.Metadata[key]; + } + } + string xml = SerializeToXml(info.Value); if (string.IsNullOrWhiteSpace(xml)) { @@ -199,19 +225,7 @@ public class CreateComicInfo : Node Encoding = Encoding.UTF8 }); writer.WriteStartDocument(); - writer.WriteStartElement("xs", "schema", "http://www.w3.org/2001/XMLSchema"); - writer.WriteAttributeString("elementFormDefault", "qualified"); - - writer.WriteStartElement("xs", "element", null); - writer.WriteAttributeString("name", "ComicInfo"); - writer.WriteAttributeString("nillable", "true"); - writer.WriteAttributeString("type", "ComicInfo"); - writer.WriteEndElement(); - - writer.WriteStartElement("xs", "complexType", null); - writer.WriteAttributeString("name", "ComicInfo"); - - writer.WriteStartElement("xs", "sequence", null); + writer.WriteStartElement("ComicInfo", "http://www.w3.org/2001/XMLSchema"); WriteXmlElement(writer, "Title", comicInfo.Title); WriteXmlElement(writer, "Series", comicInfo.Series); @@ -233,9 +247,7 @@ public class CreateComicInfo : Node WriteXmlElement(writer, "Day", comicInfo.ReleaseDate.Value.Day.ToString()); } - writer.WriteEndElement(); // Close sequence - writer.WriteEndElement(); // Close complexType - writer.WriteEndElement(); // Close schema + writer.WriteEndElement(); // Close ComicInfo writer.WriteEndDocument(); writer.Flush(); @@ -253,23 +265,8 @@ public class CreateComicInfo : Node if (value == null) return; - writer.WriteStartElement("xs", "element", null); - writer.WriteAttributeString("minOccurs", "0"); - writer.WriteAttributeString("maxOccurs", "1"); - writer.WriteAttributeString("name", name); - if (value is string) - { - writer.WriteAttributeString("default", ""); - writer.WriteAttributeString("type", "xs:string"); - } - else if (value is int || value is int?) - { - writer.WriteAttributeString("default", "-1"); - writer.WriteAttributeString("type", "xs:int"); - } - + writer.WriteStartElement(name); writer.WriteValue(value); - writer.WriteEndElement(); } } \ No newline at end of file diff --git a/FileFlows.Plugin.dll b/FileFlows.Plugin.dll index 4baf1628..62684758 100644 Binary files a/FileFlows.Plugin.dll and b/FileFlows.Plugin.dll differ diff --git a/FileFlows.Plugin.pdb b/FileFlows.Plugin.pdb index c9e023a8..f704460d 100644 Binary files a/FileFlows.Plugin.pdb and b/FileFlows.Plugin.pdb differ