diff --git a/Apprise/Apprise.csproj b/Apprise/Apprise.csproj index 3b05cfba..4b6064e8 100644 Binary files a/Apprise/Apprise.csproj and b/Apprise/Apprise.csproj differ diff --git a/Apprise/Plugin.cs b/Apprise/Plugin.cs index ac9f3450..174dcaa6 100644 --- a/Apprise/Plugin.cs +++ b/Apprise/Plugin.cs @@ -3,7 +3,7 @@ namespace FileFlows.Apprise; public class Plugin : FileFlows.Plugin.IPlugin { public string Name => "Apprise Nodes"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { diff --git a/BasicNodes/BasicNodes.csproj b/BasicNodes/BasicNodes.csproj index e8f34834..5813cec4 100644 Binary files a/BasicNodes/BasicNodes.csproj and b/BasicNodes/BasicNodes.csproj differ diff --git a/BasicNodes/JavascriptExecutor.cs b/BasicNodes/JavascriptExecutor.cs new file mode 100644 index 00000000..474773d7 --- /dev/null +++ b/BasicNodes/JavascriptExecutor.cs @@ -0,0 +1,109 @@ +using FileFlows.Plugin; +using Jint; +using System.Text; +using System.Text.Json; +using System.Text.RegularExpressions; + +namespace BasicNodes; + +/// +/// A Javascript code executor +/// +internal class JavascriptExecutor +{ + /// + /// Delegate used by the executor so log messages can be passed from the javascript code into the flow runner + /// + /// the parameters for the logger + delegate void LogDelegate(params object[] values); + + /// + /// Executes javascript + /// + /// the execution arguments + /// the output to be called next + public static int Execute(JavascriptExecutionArgs execArgs) + { + if (string.IsNullOrEmpty(execArgs?.Code)) + return -1; // no code, flow cannot continue doesnt know what to do + var args = execArgs.Args; + try + { + long fileSize = 0; + var fileInfo = new FileInfo(args.WorkingFile); + if (fileInfo.Exists) + fileSize = fileInfo.Length; + + // replace Variables. with dictionary notation + string tcode = execArgs.Code; + foreach (string k in args.Variables.Keys.OrderByDescending(x => x.Length)) + { + // replace Variables.Key or Variables?.Key?.Subkey etc to just the variable + // so Variables.file?.Orig.Name, will be replaced to Variables["file.Orig.Name"] + // since its just a dictionary key value + string keyRegex = @"Variables(\?)?\." + k.Replace(".", @"(\?)?\."); + + + object? value = args.Variables[k]; + if (value is JsonElement jElement) + { + if (jElement.ValueKind == JsonValueKind.String) + value = jElement.GetString(); + if (jElement.ValueKind == JsonValueKind.Number) + value = jElement.GetInt64(); + } + + tcode = Regex.Replace(tcode, keyRegex, "Variables['" + k + "']"); + } + + var sb = new StringBuilder(); + var log = new + { + ILog = new LogDelegate(args.Logger.ILog), + DLog = new LogDelegate(args.Logger.DLog), + WLog = new LogDelegate(args.Logger.WLog), + ELog = new LogDelegate(args.Logger.ELog), + }; + var engine = new Engine(options => + { + options.LimitMemory(4_000_000); + options.MaxStatements(500); + }) + .SetValue("Logger", args.Logger) + .SetValue("Variables", args.Variables) + .SetValue("Flow", args); + foreach (var arg in execArgs.AdditionalArguments) + engine.SetValue(arg.Key, arg.Value); + + var result = int.Parse(engine.Evaluate(tcode).ToObject().ToString()); + return result; + } + catch (Exception ex) + { + args.Logger?.ELog("Failed executing function: " + ex.Message + Environment.NewLine + ex.StackTrace); + return -1; + } + } +} + + +/// +/// The arguments to pass to the javascript executor +/// +public class JavascriptExecutionArgs +{ + /// + /// Gets or sets the code to execute + /// + public string Code { get; set; } + + /// + /// Gets or sets teh NodeParameters + /// + public NodeParameters Args { get; set; } + + /// + /// Gets a collection of additional arguments to be passed to the javascript executor + /// + public Dictionary AdditionalArguments { get; private set; } = new Dictionary(); +} \ No newline at end of file diff --git a/BasicNodes/Plugin.cs b/BasicNodes/Plugin.cs index 9aa56529..3f71c8c5 100644 --- a/BasicNodes/Plugin.cs +++ b/BasicNodes/Plugin.cs @@ -5,7 +5,7 @@ namespace FileFlows.BasicNodes public class Plugin : FileFlows.Plugin.IPlugin { public string Name => "Basic Nodes"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { } } diff --git a/BasicNodes/ScriptNode.cs b/BasicNodes/ScriptNode.cs new file mode 100644 index 00000000..35ef98fd --- /dev/null +++ b/BasicNodes/ScriptNode.cs @@ -0,0 +1,63 @@ +using BasicNodes; +using FileFlows.Plugin; +using System.Dynamic; + +namespace FileFlows.BasicNodes; + +/// +/// A special node that is not shown in the UI and only created +/// by the Flow Runner to execute a script. +/// This Node exists in this plugin to make use of the Javascript executor +/// +public class ScriptNode:Node +{ + /// + /// Gets the number of inputs of this node + /// + public override int Inputs => 1; + + /// + /// Gets or sets the model to pass to the node + /// + public ExpandoObject Model { get; set; } + + /// + /// Gets or sets the code to execute + /// + public string Code { get; set; } + + + /// + /// Executes the script node + /// + /// the NodeParameters passed into this from the flow runner + /// the output node to call next + public override int Execute(NodeParameters args) + { + // will throw exception if invalid + var script = new ScriptParser().Parse("ScriptNode", Code); + + // build up the entry point + string epParams = string.Join(", ", script.Parameters?.Select(x => x.Name).ToArray()); + // all scripts must contain the "Script" method we then add this to call that + string entryPoint = $"Script({epParams});"; + + var execArgs = new JavascriptExecutionArgs + { + Args = args, + Code = Code + "\n\n" + entryPoint + }; + + if (script.Parameters?.Any() == true) + { + var dictModel = Model as IDictionary; + foreach (var p in script.Parameters) + { + var value = dictModel?.ContainsKey(p.Name) == true ? dictModel[p.Name] : null; + execArgs.AdditionalArguments.Add(p.Name, value); + } + } + + return JavascriptExecutor.Execute(execArgs); + } +} diff --git a/ChecksumNodes/ChecksumNodes.csproj b/ChecksumNodes/ChecksumNodes.csproj index 42307a3b..cb8ea1a9 100644 Binary files a/ChecksumNodes/ChecksumNodes.csproj and b/ChecksumNodes/ChecksumNodes.csproj differ diff --git a/ChecksumNodes/Plugin.cs b/ChecksumNodes/Plugin.cs index 23ca459f..3c3bb2fa 100644 --- a/ChecksumNodes/Plugin.cs +++ b/ChecksumNodes/Plugin.cs @@ -3,7 +3,7 @@ namespace ChecksumNodes public class Plugin : IPlugin { public string Name => "Checksum Nodes"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { diff --git a/CollectionNodes/CollectionNodes.csproj b/CollectionNodes/CollectionNodes.csproj index 6171b600..43ea1685 100644 Binary files a/CollectionNodes/CollectionNodes.csproj and b/CollectionNodes/CollectionNodes.csproj differ diff --git a/CollectionNodes/Plugin.cs b/CollectionNodes/Plugin.cs index 627e6b4c..2fc5066f 100644 --- a/CollectionNodes/Plugin.cs +++ b/CollectionNodes/Plugin.cs @@ -6,7 +6,7 @@ namespace CollectionNodes public class Plugin : IPlugin { public string Name => "Collection Nodes"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; [Folder(1)] [Required] diff --git a/DiscordNodes/DiscordNodes.csproj b/DiscordNodes/DiscordNodes.csproj index 9fd96615..c1bdccc4 100644 Binary files a/DiscordNodes/DiscordNodes.csproj and b/DiscordNodes/DiscordNodes.csproj differ diff --git a/DiscordNodes/Plugin.cs b/DiscordNodes/Plugin.cs index 2827a322..c0cdd589 100644 --- a/DiscordNodes/Plugin.cs +++ b/DiscordNodes/Plugin.cs @@ -3,7 +3,7 @@ namespace FileFlows.DiscordNodes; public class Plugin : FileFlows.Plugin.IPlugin { public string Name => "Discord"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { diff --git a/EmailNodes/EmailNodes.csproj b/EmailNodes/EmailNodes.csproj index d777e690..512a51ef 100644 Binary files a/EmailNodes/EmailNodes.csproj and b/EmailNodes/EmailNodes.csproj differ diff --git a/EmailNodes/Plugin.cs b/EmailNodes/Plugin.cs index b945fe77..2d4438b8 100644 --- a/EmailNodes/Plugin.cs +++ b/EmailNodes/Plugin.cs @@ -3,7 +3,7 @@ public class Plugin : IPlugin { public string Name => "Email"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { diff --git a/Emby/Emby.csproj b/Emby/Emby.csproj index 976bf3b6..dc732e38 100644 Binary files a/Emby/Emby.csproj and b/Emby/Emby.csproj differ diff --git a/Emby/Plugin.cs b/Emby/Plugin.cs index b8206ac4..0e6c4966 100644 --- a/Emby/Plugin.cs +++ b/Emby/Plugin.cs @@ -3,7 +3,7 @@ namespace FileFlows.Emby; public class Plugin : FileFlows.Plugin.IPlugin { public string Name => "Emby"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { diff --git a/FileFlows.Plugin.dll b/FileFlows.Plugin.dll index ea43043c..cefd757e 100644 Binary files a/FileFlows.Plugin.dll and b/FileFlows.Plugin.dll differ diff --git a/FileFlows.Plugin.pdb b/FileFlows.Plugin.pdb index 9a831ec6..bb30c076 100644 Binary files a/FileFlows.Plugin.pdb and b/FileFlows.Plugin.pdb differ diff --git a/Gotify/Gotify.csproj b/Gotify/Gotify.csproj index aabeb41f..fb4255a6 100644 Binary files a/Gotify/Gotify.csproj and b/Gotify/Gotify.csproj differ diff --git a/Gotify/Plugin.cs b/Gotify/Plugin.cs index 9e331ba6..6bc0bc09 100644 --- a/Gotify/Plugin.cs +++ b/Gotify/Plugin.cs @@ -3,7 +3,7 @@ namespace FileFlows.Gotify; public class Plugin : FileFlows.Plugin.IPlugin { public string Name => "Gotify Nodes"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { diff --git a/ImageNodes/ImageNodes.csproj b/ImageNodes/ImageNodes.csproj index 5be7728d..d854cc03 100644 Binary files a/ImageNodes/ImageNodes.csproj and b/ImageNodes/ImageNodes.csproj differ diff --git a/ImageNodes/Plugin.cs b/ImageNodes/Plugin.cs index 9efe5bee..e8b83199 100644 --- a/ImageNodes/Plugin.cs +++ b/ImageNodes/Plugin.cs @@ -3,7 +3,7 @@ namespace FileFlows.ImageNodes; public class Plugin : FileFlows.Plugin.IPlugin { public string Name => "Image Nodes"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { diff --git a/MetaNodes/MetaNodes.csproj b/MetaNodes/MetaNodes.csproj index 1e74cf2c..ce4c259d 100644 Binary files a/MetaNodes/MetaNodes.csproj and b/MetaNodes/MetaNodes.csproj differ diff --git a/MetaNodes/Plugin.cs b/MetaNodes/Plugin.cs index 41cf1cde..4d51473f 100644 --- a/MetaNodes/Plugin.cs +++ b/MetaNodes/Plugin.cs @@ -5,7 +5,7 @@ namespace MetaNodes public class Plugin : FileFlows.Plugin.IPlugin { public string Name => "Meta Nodes"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { } } diff --git a/MusicNodes/MusicNodes.csproj b/MusicNodes/MusicNodes.csproj index 7b86ba67..543948fc 100644 Binary files a/MusicNodes/MusicNodes.csproj and b/MusicNodes/MusicNodes.csproj differ diff --git a/MusicNodes/Plugin.cs b/MusicNodes/Plugin.cs index 581c743d..ba8d097d 100644 --- a/MusicNodes/Plugin.cs +++ b/MusicNodes/Plugin.cs @@ -6,7 +6,7 @@ namespace FileFlows.MusicNodes public class Plugin : FileFlows.Plugin.IPlugin { public string Name => "Music Nodes"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { diff --git a/Plex/Plex.csproj b/Plex/Plex.csproj index f952c008..7a4c7019 100644 Binary files a/Plex/Plex.csproj and b/Plex/Plex.csproj differ diff --git a/Plex/Plugin.cs b/Plex/Plugin.cs index a7ff5372..16c241fd 100644 --- a/Plex/Plugin.cs +++ b/Plex/Plugin.cs @@ -3,7 +3,7 @@ namespace FileFlows.Plex; public class Plugin : FileFlows.Plugin.IPlugin { public string Name => "Plex"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { diff --git a/VideoNodes/Plugin.cs b/VideoNodes/Plugin.cs index 37df9f0a..a11a96d4 100644 --- a/VideoNodes/Plugin.cs +++ b/VideoNodes/Plugin.cs @@ -6,7 +6,7 @@ namespace FileFlows.VideoNodes public class Plugin : FileFlows.Plugin.IPlugin { public string Name => "Video Nodes"; - public string MinimumVersion => "0.6.1.900"; + public string MinimumVersion => "0.6.3.1000"; public void Init() { diff --git a/VideoNodes/VideoNodes.csproj b/VideoNodes/VideoNodes.csproj index 5ae78006..020aa236 100644 Binary files a/VideoNodes/VideoNodes.csproj and b/VideoNodes/VideoNodes.csproj differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.Plugin.dll b/build/utils/PluginInfoGenerator/FileFlows.Plugin.dll index 5d71cabf..5f5e3654 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.Plugin.dll and b/build/utils/PluginInfoGenerator/FileFlows.Plugin.dll differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.Plugin.pdb b/build/utils/PluginInfoGenerator/FileFlows.Plugin.pdb index 61fead5c..d4378d9f 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.Plugin.pdb and b/build/utils/PluginInfoGenerator/FileFlows.Plugin.pdb differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.ServerShared.dll b/build/utils/PluginInfoGenerator/FileFlows.ServerShared.dll index b378903a..65e99194 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.ServerShared.dll and b/build/utils/PluginInfoGenerator/FileFlows.ServerShared.dll differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.ServerShared.pdb b/build/utils/PluginInfoGenerator/FileFlows.ServerShared.pdb index fdfc54c9..e0dec801 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.ServerShared.pdb and b/build/utils/PluginInfoGenerator/FileFlows.ServerShared.pdb differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.ServerShared.xml b/build/utils/PluginInfoGenerator/FileFlows.ServerShared.xml index d20c0252..fc1a7bbd 100644 --- a/build/utils/PluginInfoGenerator/FileFlows.ServerShared.xml +++ b/build/utils/PluginInfoGenerator/FileFlows.ServerShared.xml @@ -203,6 +203,17 @@ Gets the location of the node configuration file + + + Gets the location of the server configuration file + + + + + Deletes all files and folders from a directory + + the path of the directory + A helper for interacting with files @@ -800,6 +811,41 @@ the updated plugininfo This not yet implemented + + + Script Service interface + + + + + Get the code for a script + + The UID identifying the script + the code for the script + + + + A service used to get script data from the FileFlows server + + + + + Gets or sets a function used to load new instances of the service + + + + + Loads an instance of the script service + + an instance of the script service + + + + Get the code for a script + + The UID identifying the script + the code for the script + A service lets you communicate with the FileFLows server @@ -953,14 +999,6 @@ if auto updates are enabled - - - Downloads a file and saves it - - The url of the file to download - the location to save the file - throws if the file fails to download - A worker that will run at a set schedule diff --git a/build/utils/PluginInfoGenerator/FileFlows.Shared.dll b/build/utils/PluginInfoGenerator/FileFlows.Shared.dll index c494fa1d..f3b0e385 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.Shared.dll and b/build/utils/PluginInfoGenerator/FileFlows.Shared.dll differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.Shared.pdb b/build/utils/PluginInfoGenerator/FileFlows.Shared.pdb index c40049a3..2cfa0a4e 100644 Binary files a/build/utils/PluginInfoGenerator/FileFlows.Shared.pdb and b/build/utils/PluginInfoGenerator/FileFlows.Shared.pdb differ diff --git a/build/utils/PluginInfoGenerator/FileFlows.Shared.xml b/build/utils/PluginInfoGenerator/FileFlows.Shared.xml index 8a19a934..85a817f6 100644 --- a/build/utils/PluginInfoGenerator/FileFlows.Shared.xml +++ b/build/utils/PluginInfoGenerator/FileFlows.Shared.xml @@ -256,11 +256,20 @@ any data to send with the request the request result - + + + Downloads a file from a URL + + the URL of the download + where the download should be saved + throws if the file fails to download + + Logs a message to the log the message to log + if the message is an error message or info @@ -502,6 +511,12 @@ Gets or sets optional place holder text, this can be a translation key + + + Gets or sets the description of the element, if this is set, this will be used instead of the HelpHint + Note: this is used by the Script which the user defines the description for + + Gets or sets the input type of this field @@ -924,6 +939,11 @@ Gets or sets the name of the element + + + Gets or sets a description for this element, only used by scripts where the description is user defined + + Gets or sets the display name of the element @@ -1638,6 +1658,21 @@ Gets or sets the output from this node + + + Model class for the Library Files page + + + + + Gets or sets a list of library files to show in the UI + + + + + Gets or sets the status data for the libraries + + Library status @@ -1935,6 +1970,16 @@ Gets or sets the parsed response object + + + A script is a special function node that lets you reuse them + + + + + Gets or sets the javascript code of the script + + Settings for FileFlows @@ -2054,6 +2099,21 @@ Gets or sets the processing time of the executed node + + + Gets the system information about FileFlows + + + + + Gets the amount of memory used by FileFlows + + + + + Gets the how much CPU is used by FileFlows + + A tool in FileFlows, e.g. an external application @@ -2196,6 +2256,18 @@ The value to validate true if the value has a propre value + + + Validator that checks a Script object is valid + + + + + Validates a Script + + the Script code to validate + true if valid, otherwise false + A validator used to validate a value diff --git a/build/utils/PluginInfoGenerator/PluginInfoGenerator.dll b/build/utils/PluginInfoGenerator/PluginInfoGenerator.dll index 2b1d69bd..1e94d65b 100644 Binary files a/build/utils/PluginInfoGenerator/PluginInfoGenerator.dll and b/build/utils/PluginInfoGenerator/PluginInfoGenerator.dll differ diff --git a/build/utils/PluginInfoGenerator/PluginInfoGenerator.pdb b/build/utils/PluginInfoGenerator/PluginInfoGenerator.pdb index cad67c5c..f6ef8869 100644 Binary files a/build/utils/PluginInfoGenerator/PluginInfoGenerator.pdb and b/build/utils/PluginInfoGenerator/PluginInfoGenerator.pdb differ