From 21244b993e99dd7e2b42e762f04836f88a4defdd Mon Sep 17 00:00:00 2001 From: John Andrews Date: Wed, 8 May 2024 07:37:05 +1200 Subject: [PATCH] FF-1524: Added more comic options --- ComicNodes/Comics/CreateComicInfo.cs | 59 ++++++++++++++----- ComicNodes/Tests/ComicInfoTests.cs | 83 +++++++++++++++++++++++++++ FileFlows.Plugin.dll | Bin 139264 -> 139264 bytes FileFlows.Plugin.pdb | Bin 33912 -> 33916 bytes 4 files changed, 128 insertions(+), 14 deletions(-) diff --git a/ComicNodes/Comics/CreateComicInfo.cs b/ComicNodes/Comics/CreateComicInfo.cs index 6ad07377..7d3fca78 100644 --- a/ComicNodes/Comics/CreateComicInfo.cs +++ b/ComicNodes/Comics/CreateComicInfo.cs @@ -183,16 +183,23 @@ public class CreateComicInfo : Node { if (issueDigits > 0) { - // Pad the number with leading zeros based on the specified number of digits - string paddedNumber = info.Number.Value.ToString().PadLeft(issueDigits, '0'); - - // Add the padded number to the name - name += $" - #{paddedNumber}"; - - // Optionally add information about the count - if (info.Count > 0) + if (info.Volume == "Annual") { - name += $" (of {info.Count})"; + name += " - Annual " + info.Number; + } + else + { + // Pad the number with leading zeros based on the specified number of digits + string paddedNumber = info.Number.Value.ToString().PadLeft(issueDigits, '0'); + + // Add the padded number to the name + name += $" - #{paddedNumber}"; + + // Optionally add information about the count + if (info.Count > 0) + { + name += $" (of {info.Count})"; + } } } else @@ -226,10 +233,12 @@ public class CreateComicInfo : Node info.Series = FileHelper.GetDirectoryName(libraryFile); var yearMatch = Regex.Match(info.Series, @"\((?(19|20)\d{2})\)"); + int? year = null; if (yearMatch.Success) { - info.Volume = yearMatch.Groups["year"].Value; + year = int.Parse(yearMatch.Groups["year"].Value); + info.Volume = year.ToString(); // info.Series = Regex.Replace(info.Series, @"\((19|20)\d{2}\)", "").Trim(); } @@ -239,7 +248,8 @@ public class CreateComicInfo : Node string shortname = FileHelper.GetShortFileName(libraryFile); info.Tags = GetTags(ref shortname); shortname = shortname[..shortname.LastIndexOf('.')]; - (shortname, _) = ExtractYear(shortname); + (shortname, int? year2) = ExtractYear(shortname); + year ??= year2; // Title - #number (of #) - Issue Title var parts = shortname.Split(" - "); if (parts.Length < 2) @@ -255,6 +265,13 @@ public class CreateComicInfo : Node info.Number = int.Parse(lastChanceMatch.Value); return info; } + + if (shortname.ToLowerInvariant().Contains("annual") && year != null) + { + info.Volume = "Annual"; + info.Number = year.Value; + return info; + } return Result.Fail("Invalid filename: " + shortname); } @@ -296,9 +313,9 @@ public class CreateComicInfo : Node /// /// the name of the file /// the new name and the year if found - private static (string Name, string? Year) ExtractYear(string shortname) + private static (string Name, int? Year) ExtractYear(string shortname) { - string? year = null; + int? year = null; // Regular expression to match the year in the specified formats Match match = Regex.Match(shortname, @"(?:(?:19|20)\d{2})|\((?:19|20)\d{2}\)|-(?:\s)?(?:19|20)\d{2}(?:\s)?-"); @@ -306,11 +323,25 @@ public class CreateComicInfo : Node if (match.Success) { // Extract the matched year - year = match.Value.Trim('(', ')', '-', ' '); + year = int.Parse(match.Value.Trim('(', ')', '-', ' ')); // Remove the matched year from the input string shortname = shortname.Remove(match.Index, match.Length).Trim(); } + else + { + match = Regex.Match(shortname, @"'(\d{2})\b"); + + if (match.Success) + { + // Extract the matched year + int number = int.Parse(match.Groups[1].Value); + // Determine the year + year = number > 50 ? 1900 + number : 2000 + number; + // Remove the matched year from the input string + shortname = shortname.Remove(match.Index, match.Length).Trim(); + } + } return (shortname, year); } diff --git a/ComicNodes/Tests/ComicInfoTests.cs b/ComicNodes/Tests/ComicInfoTests.cs index 4fade6b7..0e3c60f0 100644 --- a/ComicNodes/Tests/ComicInfoTests.cs +++ b/ComicNodes/Tests/ComicInfoTests.cs @@ -146,7 +146,90 @@ public class ComicInfoTests : TestBase Assert.AreEqual("X-Man - #005.cbz", name.Value); } + [TestMethod] + public void Annual1900s() + { + var result = CreateComicInfo.GetInfo(Logger, + "/home/john/Comics/Marvel/X-Men/X-Man/X-Man Annual '97.cbz", + "/home/john/Comics", + true); + + TestContext.WriteLine(Logger.ToString()); + + Assert.IsFalse(result.IsFailed); + var info = result.Value; + Assert.IsNotNull(info); + Assert.AreEqual("Marvel", info.Publisher); + Assert.AreEqual("X-Man", info.Series); + Assert.AreEqual("Annual", info.Volume); + Assert.AreEqual(1997, info.Number); + + var xml = CreateComicInfo.SerializeToXml(info); + Assert.IsFalse(string.IsNullOrWhiteSpace(xml)); + TestContext.WriteLine(new string('-', 70)); + TestContext.WriteLine(xml); + + var name = CreateComicInfo.GetNewName(info, "cbz", 3); + Assert.AreEqual("X-Man - Annual 1997.cbz", name.Value); + } + + [TestMethod] + public void Annual2000s() + { + var result = CreateComicInfo.GetInfo(Logger, + "/home/john/Comics/Marvel/X-Men/X-Man/X-Man Annual '04.cbz", + "/home/john/Comics", + true); + + TestContext.WriteLine(Logger.ToString()); + + Assert.IsFalse(result.IsFailed); + var info = result.Value; + Assert.IsNotNull(info); + Assert.AreEqual("Marvel", info.Publisher); + Assert.AreEqual("X-Man", info.Series); + Assert.AreEqual("Annual", info.Volume); + Assert.AreEqual(2004, info.Number); + + var xml = CreateComicInfo.SerializeToXml(info); + Assert.IsFalse(string.IsNullOrWhiteSpace(xml)); + TestContext.WriteLine(new string('-', 70)); + TestContext.WriteLine(xml); + + var name = CreateComicInfo.GetNewName(info, "cbz", 3); + Assert.AreEqual("X-Man - Annual 2004.cbz", name.Value); + } + + + [TestMethod] + public void AnnualFullYear() + { + var result = CreateComicInfo.GetInfo(Logger, + "/home/john/Comics/Marvel/X-Men/X-Man/X-Man Annual 2004.cbz", + "/home/john/Comics", + true); + + TestContext.WriteLine(Logger.ToString()); + + Assert.IsFalse(result.IsFailed); + var info = result.Value; + Assert.IsNotNull(info); + Assert.AreEqual("Marvel", info.Publisher); + Assert.AreEqual("X-Man", info.Series); + Assert.AreEqual("Annual", info.Volume); + Assert.AreEqual(2004, info.Number); + + var xml = CreateComicInfo.SerializeToXml(info); + Assert.IsFalse(string.IsNullOrWhiteSpace(xml)); + TestContext.WriteLine(new string('-', 70)); + TestContext.WriteLine(xml); + + var name = CreateComicInfo.GetNewName(info, "cbz", 3); + Assert.AreEqual("X-Man - Annual 2004.cbz", name.Value); + } + + // [TestMethod] public void PhysicalFileTest() { const string FILE = diff --git a/FileFlows.Plugin.dll b/FileFlows.Plugin.dll index 5809523077a50538c7f271669b958d11add41fac..0076af7fa11a6f4e257fa3f9c41daaf13008b7c4 100644 GIT binary patch delta 250 zcmZoTz|nAkV?qbZheyvAHTJajFmCN((qI<2uafxUX!u``g>P0K_v7q+wfzV)(`-Qv z6U$ViRD)zo^At;yB+C>7gA^l!L`xInq-0C8pRq7|a=x7z}`H0|rBeWFXs!Aq~h&Wk>|d7y)ThAS;<61*`(3+LXZ( VjLm@R48U^9Kvl`x>t&f5nE=+-P5}S_ diff --git a/FileFlows.Plugin.pdb b/FileFlows.Plugin.pdb index 284f805a46d95a56c3a0a52b92ef89f41afe1693..41f9dad2a903149a2ac8ff6d341f2f7885d9c41f 100644 GIT binary patch delta 2755 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 N?WFTEP8r_g{SQAF=D7d>