diff --git a/BasicNodes/File/WriteText.cs b/BasicNodes/File/WriteText.cs new file mode 100644 index 00000000..4e0f4b65 --- /dev/null +++ b/BasicNodes/File/WriteText.cs @@ -0,0 +1,102 @@ +using System.ComponentModel.DataAnnotations; +using FileFlows.BasicNodes; +using FileFlows.Plugin; +using FileFlows.Plugin.Attributes; + +namespace BasicNodes.File; + +/// +/// A flow element that writes text to a file +/// +public class WriteText : Node +{ + /// + public override int Inputs => 1; + + /// + public override int Outputs => 1; + + /// + public override FlowElementType Type => FlowElementType.Process; + + /// + public override string Icon => "fas fa-file-signature"; + + /// + public override string Group => "File"; + + /// + public override string HelpUrl => "https://fileflows.com/docs/plugins/basic-nodes/write-text"; + + /// + /// Gets or sets the output text location + /// + [TextVariable(1)] + [Required] + public string File { get; set; } + + /// + /// Gets or sets the text to write, if blank writes the current file + /// + [TextVariable(2)] + public string Text { get; set; } + + /// + public override int Execute(NodeParameters args) + { + string file = args.ReplaceVariables(File, stripMissing: true); + if (string.IsNullOrWhiteSpace(file)) + { + args.FailureReason = "No file set"; + args.Logger?.ELog(args.FailureReason); + return -1; + } + + string text = GetText(args, Text, file); + + args.Logger?.ILog($"Text: {text}"); + args.Logger?.ILog($"File: {file}"); + + var result = args.FileService.FileAppendAllText(file, text); + if (result.Failed(out var error)) + { + args.FailureReason = "File writing file: " + error; + args.Logger.ELog(args.FailureReason); + return -1; + } + + args.Logger?.ILog($"Text written to file"); + return 1; + } + + /// + /// Gets the text to write + /// + /// the node parameters + /// the original text + /// the file to write to + /// the text to write + public static string GetText(NodeParameters args, string text, string outputFile) + { + if (outputFile?.ToLowerInvariant().EndsWith(".csv") == true) + { + var parts = text?.Split([";", ","], StringSplitOptions.RemoveEmptyEntries) ?? []; + if (parts.Length == 0) + { + return CsvEncode(args.WorkingFile); + } + + return string.Join(",", parts.Select(x => CsvEncode(args.ReplaceVariables(x, stripMissing: true)))); + } + + return args.ReplaceVariables(text, stripMissing: true)?.EmptyAsNull() ?? args.WorkingFile; + } + + /// + /// CSV encodes a string + /// + /// the text to encode + /// the CSV encoded string + private static string CsvEncode(string text) + => $"\"{text.Replace("\"", "\"\"")}\""; +} \ No newline at end of file diff --git a/BasicNodes/Tests/WriteTextTests.cs b/BasicNodes/Tests/WriteTextTests.cs new file mode 100644 index 00000000..48c97465 --- /dev/null +++ b/BasicNodes/Tests/WriteTextTests.cs @@ -0,0 +1,52 @@ +#if(DEBUG) + +using BasicNodes.File; + +namespace BasicNodes.Tests; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class WriteTextTests : TestBase +{ + [TestMethod] + public void WorkingFile_Csv() + { + var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, new LocalFileService()); + + var output = WriteText.GetText(args, "", "file.csv"); + Assert.AreEqual("\"/test/file.mkv\"", output); + } + + [TestMethod] + public void WorkingFile_Text() + { + var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, new LocalFileService()); + + var output = WriteText.GetText(args, "", "file.txt"); + Assert.AreEqual("/test/file.mkv", output); + } + + [TestMethod] + public void CsvArgs() + { + var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, new LocalFileService()); + args.Variables["file.Name"] = "file.mkv"; + args.Variables["ext"] = "mkv"; + + var output = WriteText.GetText(args, "{file.Name};{ext}", "file.csv"); + Assert.AreEqual("\"file.mkv\",\"mkv\"", output); + } + + [TestMethod] + public void CsvArg() + { + var args = new FileFlows.Plugin.NodeParameters(@"/test/file.mkv", new TestLogger(), false, string.Empty, new LocalFileService()); + args.Variables["file.Name"] = "file.mkv"; + + var output = WriteText.GetText(args, "{file.Name}", "file.csv"); + Assert.AreEqual("\"file.mkv\"", output); + } +} + +#endif \ No newline at end of file diff --git a/BasicNodes/i18n/en.json b/BasicNodes/i18n/en.json index 35b9ccb7..cfbab138 100644 --- a/BasicNodes/i18n/en.json +++ b/BasicNodes/i18n/en.json @@ -501,6 +501,18 @@ "Options": "Options", "Options-Help": "The string to match against." } + }, + "WriteText": { + "Description": "Writes text to a file", + "Outputs": { + "1": "Text written to file" + }, + "Fields": { + "File": "File", + "File-Help": "The file to write the text to.", + "Text": "Text", + "Text-Help": "The text to write to the file. If left blank the current working file full path will be written." + } } } }