moved variable replacing to Plugin dll.

made renamer replace empty [] and ()s
made renamer use a safe file name from nodeparameters
fixed issue with pattern match returning 0 instead of 2 for no match
added dummy data to variables so UI can preview variable replacements
This commit is contained in:
reven
2021-11-24 22:28:21 +13:00
parent 599ee1700e
commit c59a8ee0e3
16 changed files with 210 additions and 56 deletions

Binary file not shown.

View File

@@ -86,11 +86,12 @@
"Description": "Renames the working file.\nVariables can be used by entering the key '{' inside the Pattern field.",
"Fields": {
"Pattern": "Pattern",
"Pattern-Help": "The pattern to use to rename the folder. Variables can be used, for example '{FileName}.{ext}'.",
"DestinationPath": "Destination Path",
"DestinationPath-Help": "If the file should be moved to a different directory.",
"LogOnly": "Log Only",
"LogOnly-Help": "Turn on if you just want to test this node without it actually renaming the file"
"LogOnly-Help": "Turn on if you just want to test this node without it actually renaming the file",
"CsvFile": "CSV File",
"CsvFile-Help": "Will append to this file the original name and the renamed file. Useful when using ''Log Only'' to test the renamer before changing files."
}
}
}

View File

@@ -1,6 +1,7 @@
namespace FileFlows.BasicNodes.File
{
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Text.RegularExpressions;
using FileFlows.Plugin;
using FileFlows.Plugin.Attributes;
@@ -35,6 +36,9 @@
[Boolean(3)]
public bool LogOnly { get; set; }
[File(4)]
public string CsvFile { get; set; }
public override int Execute(NodeParameters args)
{
if(string.IsNullOrEmpty(Pattern))
@@ -48,35 +52,55 @@
newFile = newFile.Replace('\\', Path.DirectorySeparatorChar);
newFile = newFile.Replace('/', Path.DirectorySeparatorChar);
if (args.Variables?.Any() == true)
{
{
foreach (string variable in args.Variables.Keys)
{
string strValue = args.Variables[variable]?.ToString() ?? "";
newFile = ReplaceVariable(newFile, variable, strValue);
}
}
}
newFile = args.ReplaceVariables(newFile, stripMissing: true);
newFile = Regex.Replace(newFile, @"\.(\.[\w\d]+)$", "$1");
// remove empty [], (), {}
newFile = newFile.Replace("()", "").Replace("{}", "").Replace("[]", "");
// remove double space that may have been introduced by empty [], () removals
while (newFile.IndexOf(" ") >= 0)
newFile = newFile.Replace(" ", " ");
newFile = Regex.Replace(newFile, @"\s(\.[\w\d]+)$", "$1");
newFile = newFile.Replace(" \\", "\\");
string destFolder = DestinationPath;
if (string.IsNullOrEmpty(destFolder))
destFolder = new FileInfo(args.WorkingFile).Directory?.FullName ?? "";
var dest = new FileInfo(Path.Combine(destFolder, newFile));
args.Logger?.ILog("Renaming file to: " + (string.IsNullOrEmpty(DestinationPath) ? "" : DestinationPath + Path.DirectorySeparatorChar) + newFile);
var dest = args.GetSafeName(Path.Combine(destFolder, newFile));
args.Logger?.ILog("Renaming file to: " + dest.FullName.Substring(destFolder.Length+1));
if (string.IsNullOrEmpty(CsvFile) == false)
{
try
{
System.IO.File.AppendAllText(CsvFile, EscapeForCsv(args.FileName) + "," + EscapeForCsv(dest.FullName) + Environment.NewLine);
}
catch (Exception ex)
{
args.Logger?.ELog("Failed to append to CSV file: " + ex.Message);
}
}
if (LogOnly)
return 1;
return args.MoveFile(dest.FullName) ? 1 : -1;
}
private string ReplaceVariable(string input, string variable, string value)
private string EscapeForCsv(string input)
{
return Regex.Replace(input, @"{" + Regex.Escape(variable) + @"}", value, RegexOptions.IgnoreCase);
StringBuilder sb = new StringBuilder();
sb.Append('"');
foreach(char c in input)
{
sb.Append(c);
if(c == '"')
sb.Append('"');
}
sb.Append('"');
return sb.ToString();
}
}
}

View File

@@ -27,7 +27,7 @@ namespace FileFlows.BasicNodes.Functions
var rgx = new Regex(Pattern);
if (rgx.IsMatch(args.WorkingFile) || rgx.IsMatch(args.FileName))
return 1;
return 0;
return 2;
}
catch (Exception ex)
{

View File

@@ -29,7 +29,7 @@ namespace BasicNodes.Tests
args.SetWorkingFile($@"c:\temp\{Guid.NewGuid().ToString()}.avi", dontDelete: true);
var result = pm.Execute(args);
Assert.AreEqual(0, result);
Assert.AreEqual(2, result);
}
[TestMethod]
@@ -43,6 +43,17 @@ namespace BasicNodes.Tests
var result = pm.Execute(args);
Assert.AreEqual(-1, result);
}
[TestMethod]
public void PatternMatch_Trailer()
{
PatternMatch pm = new PatternMatch();
pm.Pattern = @"\-trailer";
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\testfile-TRAILER.avi");
args.SetWorkingFile($@"c:\temp\{Guid.NewGuid().ToString()}.avi", dontDelete: true);
var result = pm.Execute(args);
Assert.AreEqual(2, result);
}
}
}

View File

@@ -23,6 +23,31 @@ namespace BasicNodes.Tests
args.SetWorkingFile($@"c:\temp\{Guid.NewGuid()}.mkv", dontDelete: true);
Renamer node = new Renamer();
node.Pattern = @"{mi.Title} ({mi.Year})\{mi.Title} [{vi.Resolution}]{ext}";
node.LogOnly = true;
var result = node.Execute(args);
Assert.AreEqual(1, result);
string expectedShort = $"Ghostbusters (1984){Path.DirectorySeparatorChar}Ghostbusters [1080P].mkv";
Assert.IsTrue(logger.Contains($"Renaming file to: " + expectedShort));
}
[TestMethod]
public void Renamer_Extension_DoubleDot()
{
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\testfile.mkv");
var logger = new TestLogger();
args.Logger = logger;
args.Variables = new Dictionary<string, object>
{
{ "mi.Title", "Ghostbusters" },
{ "mi.Year", 1984 },
{ "vi.Resolution", "1080P" }
};
args.SetWorkingFile($@"c:\temp\{Guid.NewGuid()}.mkv", dontDelete: true);
Renamer node = new Renamer();
node.Pattern = @"{mi.Title} ({mi.Year})\{mi.Title} [{vi.Resolution}].{ext}";
node.LogOnly = true;
@@ -34,6 +59,105 @@ namespace BasicNodes.Tests
Assert.IsTrue(logger.Contains($"Renaming file to: " + expectedShort));
}
[TestMethod]
public void Renamer_Empty_SquareBrackets()
{
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\testfile.mkv");
var logger = new TestLogger();
args.Logger = logger;
args.Variables = new Dictionary<string, object>
{
{ "mi.Title", "Ghostbusters" },
{ "mi.Year", 1984 }
};
args.SetWorkingFile($@"c:\temp\{Guid.NewGuid()}.mkv", dontDelete: true);
Renamer node = new Renamer();
node.Pattern = @"{mi.Title} ({mi.Year})\{mi.Title} [{vi.Resolution}] {mi.Year}.{ext}";
node.LogOnly = true;
var result = node.Execute(args);
Assert.AreEqual(1, result);
string expectedShort = $"Ghostbusters (1984){Path.DirectorySeparatorChar}Ghostbusters 1984.mkv";
Assert.IsTrue(logger.Contains($"Renaming file to: " + expectedShort));
}
[TestMethod]
public void Renamer_Empty_RoundBrackets()
{
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\testfile.mkv");
var logger = new TestLogger();
args.Logger = logger;
args.Variables = new Dictionary<string, object>
{
{ "mi.Title", "Ghostbusters" },
{ "vi.Resolution", "1080p" }
};
args.SetWorkingFile($@"c:\temp\{Guid.NewGuid()}.mkv", dontDelete: true);
Renamer node = new Renamer();
node.Pattern = @"{mi.Title} ({mi.Year})\{mi.Title} ({mi.Year}) {vi.Resolution!}.{ext}";
node.LogOnly = true;
var result = node.Execute(args);
Assert.AreEqual(1, result);
string expectedShort = $"Ghostbusters{Path.DirectorySeparatorChar}Ghostbusters 1080P.mkv";
Assert.IsTrue(logger.Contains($"Renaming file to: " + expectedShort));
}
[TestMethod]
public void Renamer_Empty_SquareBrackets_Extension()
{
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\testfile.mkv");
var logger = new TestLogger();
args.Logger = logger;
args.Variables = new Dictionary<string, object>
{
{ "mi.Title", "Ghostbusters" },
{ "mi.Year", 1984 }
};
args.SetWorkingFile($@"c:\temp\{Guid.NewGuid()}.mkv", dontDelete: true);
Renamer node = new Renamer();
node.Pattern = @"{mi.Title} ({mi.Year})\{mi.Title} [{vi.Resolution}].{ext}";
node.LogOnly = true;
var result = node.Execute(args);
Assert.AreEqual(1, result);
string expectedShort = $"Ghostbusters (1984){Path.DirectorySeparatorChar}Ghostbusters.mkv";
Assert.IsTrue(logger.Contains($"Renaming file to: " + expectedShort));
}
[TestMethod]
public void Renamer_Colon()
{
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\testfile.mkv");
var logger = new TestLogger();
args.Logger = logger;
args.Variables = new Dictionary<string, object>
{
{ "mi.Title", "Batman Unlimited: Mech vs Mutants" },
{ "mi.Year", 2016 }
};
args.SetWorkingFile($@"c:\temp\{Guid.NewGuid()}.mkv", dontDelete: true);
Renamer node = new Renamer();
node.Pattern = @"{mi.Title} ({mi.Year})\{mi.Title}.{ext}";
node.LogOnly = true;
var result = node.Execute(args);
Assert.AreEqual(1, result);
string expectedShort = $"Batman Unlimited - Mech vs Mutants (2016){Path.DirectorySeparatorChar}Batman Unlimited - Mech vs Mutants.mkv";
Assert.IsTrue(logger.Contains($"Renaming file to: " + expectedShort));
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -125,6 +125,21 @@ namespace MetaNodes.Tests.TheMovieDb
Assert.AreEqual("Back to the Future Part II", args.Variables["mi.Title"]);
Assert.AreEqual("1989", args.Variables["mi.Year"]);
}
[TestMethod]
public void MovieLookupTests_NoMatchNoVariables()
{
var args = new FileFlows.Plugin.NodeParameters(@"c:\test\sdfsdfdsvfdcxdsf.mkv");
args.Logger = new TestLogger();
MovieLookup ml = new MovieLookup();
ml.UseFolderName = false;
var result = ml.Execute(args);
Assert.AreEqual(2, result);
Assert.IsFalse(args.Variables.ContainsKey("mi.Title"));
Assert.IsFalse(args.Variables.ContainsKey("mi.Year"));
}
}
}

View File

@@ -24,8 +24,8 @@
{
_Variables = new Dictionary<string, object>()
{
{ "mi.Title", string.Empty },
{"mi.Year", string.Empty }
{ "mi.Title", "Batman Begins" },
{ "mi.Year", 2005 }
};
}

View File

@@ -15,12 +15,12 @@ namespace FileFlows.VideoNodes
{
_Variables = new Dictionary<string, object>()
{
{ "vi.VideoCodec", string.Empty },
{ "vi.AudioCodec", string.Empty },
{ "vi.AudioCodecs", string.Empty },
{ "vi.AudioLanguage", string.Empty },
{ "vi.AudioLanguages", string.Empty },
{ "vi.Resolution", string.Empty },
{ "vi.VideoCodec", "hevc" },
{ "vi.AudioCodec", "ac3" },
{ "vi.AudioCodecs", "ac3,aac"},
{ "vi.AudioLanguage", "eng" },
{ "vi.AudioLanguages", "eng, mao" },
{ "vi.Resolution", "1080p" },
};
}
@@ -53,29 +53,6 @@ namespace FileFlows.VideoNodes
SetVideoInfo(args, videoInfo, Variables);
Variables["vi.VideoCodec"] = videoInfo.VideoStreams[0].Codec;
if (videoInfo.AudioStreams?.Any() == true)
{
;
if (string.IsNullOrEmpty(videoInfo.AudioStreams[0].Codec))
Variables["vi.AudioCodec"] = videoInfo.AudioStreams[0].Codec;
if(string.IsNullOrEmpty(videoInfo.AudioStreams[0].Language))
Variables["vi.AudioLanguage"] = videoInfo.AudioStreams[0].Language;
Variables["vi.AudioCodecs"] = string.Join(", ", videoInfo.AudioStreams.Select(x => x.Codec).Where(x => string.IsNullOrEmpty(x) == false));
Variables["vi.AudioLanguages"] = string.Join(", ", videoInfo.AudioStreams.Select(x => x.Language).Where(x => string.IsNullOrEmpty(x) == false));
}
if (videoInfo.VideoStreams[0].Width == 1920)
Variables["vi.Resolution"] = "1080P";
else if (videoInfo.VideoStreams[0].Width == 3840)
Variables["vi.Resolution"] = "4k";
else if (videoInfo.VideoStreams[0].Width == 1280)
Variables["vi.Resolution"] = "720p";
else if (videoInfo.VideoStreams[0].Width < 1280)
Variables["vi.Resolution"] = "SD";
else
Variables["vi.Resolution"] = videoInfo.VideoStreams[0].Width + "x" + videoInfo.VideoStreams[0].Height;
return 1;
}
catch (Exception ex)

View File

@@ -85,15 +85,17 @@ namespace FileFlows.VideoNodes
}
if (videoInfo.VideoStreams[0].Width == 1920)
Variables.AddOrUpdate("vi.Resolution", "1080P");
Variables.AddOrUpdate("vi.Resolution", "1080");
else if (videoInfo.VideoStreams[0].Width == 3840)
Variables.AddOrUpdate("vi.Resolution", "4k");
Variables.AddOrUpdate("vi.Resolution", "4l");
else if (videoInfo.VideoStreams[0].Width == 1280)
Variables.AddOrUpdate("vi.Resolution", "720P");
Variables.AddOrUpdate("vi.Resolution", "720p");
else if (videoInfo.VideoStreams[0].Width < 1280)
Variables.AddOrUpdate("vi.Resolution", "SD");
else
Variables.AddOrUpdate("vi.Resolution", videoInfo.VideoStreams[0].Width + "x" + videoInfo.VideoStreams[0].Height);
args.UpdateVariables(variables);
}
protected VideoInfo GetVideoInfo(NodeParameters args)

Binary file not shown.

View File

@@ -1,17 +1,17 @@
[
{
"Name": "BasicNodes",
"Version": "0.0.1.11",
"Version": "0.0.1.12",
"Package": "https://github.com/revenz/FileFlowsPlugins/blob/master/Builds/BasicNodes.zip?raw=true"
},
{
"Name": "MetaNodes",
"Version": "0.0.1.11",
"Version": "0.0.1.12",
"Package": "https://github.com/revenz/FileFlowsPlugins/blob/master/Builds/MetaNodes.zip?raw=true"
},
{
"Name": "VideoNodes",
"Version": "0.0.1.11",
"Version": "0.0.1.12",
"Package": "https://github.com/revenz/FileFlowsPlugins/blob/master/Builds/VideoNodes.zip?raw=true"
}
]