mirror of
https://github.com/revenz/FileFlowsPlugins.git
synced 2026-01-06 09:50:14 -06:00
creating repo for plugins
This commit is contained in:
25
BasicNodes/BasicNodes.csproj
Normal file
25
BasicNodes/BasicNodes.csproj
Normal file
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Plugin">
|
||||
<HintPath>..\Plugin.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jint" Version="3.0.0-beta-2035" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="BasicNodes.en.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
87
BasicNodes/BasicNodes.en.json
Normal file
87
BasicNodes/BasicNodes.en.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"Enums":{
|
||||
"LogType":{
|
||||
"Info":"Information",
|
||||
"Debug":"Debug",
|
||||
"Warning":"Warning",
|
||||
"Error":"Error"
|
||||
}
|
||||
},
|
||||
"Flow":{
|
||||
"Parts":{
|
||||
"InputFile":{
|
||||
"Description":"An input node for a library file. This is required and is the starting point of a flow. Any input node can be used, just one is required."
|
||||
},
|
||||
"CopyFile":{
|
||||
"Description":"Copies a file to the destination path",
|
||||
"Fields":{
|
||||
"DestinationPath":"Destination Path",
|
||||
"DestinationPath-Help":"The path where the file will be copied too",
|
||||
"CopyFolder":"Copy Folder",
|
||||
"CopyFolder-Help" :"If the relative library folder structure should be copied too"
|
||||
}
|
||||
},
|
||||
"Log":{
|
||||
"Description":"Logs a message to the flow log",
|
||||
"Fields":{
|
||||
"LogType":"Type",
|
||||
"Message":"Message"
|
||||
}
|
||||
},
|
||||
"FileExtension":{
|
||||
"Description":"Checks if the file has one of the configured extensions.\n\nOutput 1: Matches\nOutput 2: Does not match",
|
||||
"Fields":{
|
||||
"Extensions":"Extensions",
|
||||
"Extensions-Help":"A list of case insensitive file extensions that will be matched against.\nOuput 1 Matches\nOutput 2: Does not match"
|
||||
}
|
||||
},
|
||||
"FileSize":{
|
||||
"Description":"Checks if the file size matches the configured parameters.\n\nOutput 1: Matches\nOutput 2: Does not match",
|
||||
"Fields":{
|
||||
"Comparison":"Comparison",
|
||||
"Lower":"Lower",
|
||||
"Lower-Suffix":"MB",
|
||||
"Lower-Help":"The value it must bet greater than",
|
||||
"Upper":"Upper",
|
||||
"Upper-Suffix":"MB",
|
||||
"Upper-Help":"The value it must be less than. Leave as 0 to not test the upper limit."
|
||||
}
|
||||
},
|
||||
"MoveFile":{
|
||||
"Description":"Moves a file to the destination path",
|
||||
"Fields":{
|
||||
"DestinationPath":"Destination Path",
|
||||
"DestinationPath-Help":"The path where the file will be moved too",
|
||||
"MoveFolder":"Copy Folder",
|
||||
"MoveFolder-Help" :"If the relative library folder structure should be copied too",
|
||||
"DeleteOriginal":"Delete Original",
|
||||
"DeleteOriginal-Help":"If the original file should be deleted, this will only happen if the working file is different to the original file"
|
||||
}
|
||||
},
|
||||
"RenameFile":{
|
||||
"Description":"Renames the working file",
|
||||
"Fields":{
|
||||
"FileName":"File Name",
|
||||
"FileName-Help":"The new filename"
|
||||
}
|
||||
},
|
||||
"DeleteSourceDirectory":{
|
||||
"Description":"Deletes the source directory of the original library file",
|
||||
"Fields":{
|
||||
"IfEmpty":"If Empty",
|
||||
"IfEmpty-Help":"Only delete the source directory if the it is empty",
|
||||
"IncludePatterns":"Include Patterns",
|
||||
"IncludePatterns-Help":"Optional, if set only files matching these patterns will be counted to see if the folder is empty. Any of these patterns can match."
|
||||
}
|
||||
},
|
||||
"Function":{
|
||||
"Fields":{
|
||||
"Outputs":"Outputs",
|
||||
"Outputs-Help":"The number of outputs this node can have.",
|
||||
"Code":"Code",
|
||||
"Code-Help":"return -1 for error and flow to stop\nreturn 0 for flow to complete\nreturn 1 or more for the desired output to be called"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
107
BasicNodes/File/CopyFile.cs
Normal file
107
BasicNodes/File/CopyFile.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
namespace FileFlows.BasicNodes.File
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using FileFlows.Plugin;
|
||||
using FileFlows.Plugin.Attributes;
|
||||
|
||||
public class CopyFile : Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 1;
|
||||
public override FlowElementType Type => FlowElementType.Process;
|
||||
public override string Icon => "far fa-copy";
|
||||
|
||||
private string _DestinationPath = string.Empty;
|
||||
|
||||
[Folder(1)]
|
||||
public string DestinationPath
|
||||
{
|
||||
get => _DestinationPath;
|
||||
set { _DestinationPath = value ?? ""; }
|
||||
}
|
||||
|
||||
[Boolean(2)]
|
||||
public bool CopyFolder { get; set; }
|
||||
|
||||
private bool Canceled;
|
||||
|
||||
public override Task Cancel()
|
||||
{
|
||||
Canceled = true;
|
||||
return base.Cancel();
|
||||
}
|
||||
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
Canceled = false;
|
||||
string dest = DestinationPath;
|
||||
if (string.IsNullOrEmpty(dest))
|
||||
{
|
||||
args.Logger.ELog("No destination specified");
|
||||
args.Result = NodeResult.Failure;
|
||||
return -1;
|
||||
}
|
||||
args.Result = NodeResult.Failure;
|
||||
|
||||
if (CopyFolder)
|
||||
dest = Path.Combine(dest, args.RelativeFile);
|
||||
else
|
||||
dest = Path.Combine(dest, new FileInfo(args.FileName).Name);
|
||||
|
||||
var destDir = new FileInfo(dest).DirectoryName;
|
||||
if (Directory.Exists(destDir) == false)
|
||||
Directory.CreateDirectory(destDir);
|
||||
|
||||
// have to use file streams so we can report progress
|
||||
int bufferSize = 1024 * 1024;
|
||||
|
||||
using (FileStream fsOut = new FileStream(dest, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
|
||||
{
|
||||
using (FileStream fsIn = new FileStream(args.WorkingFile, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
try
|
||||
{
|
||||
long fileSize = fsIn.Length;
|
||||
fsOut.SetLength(fileSize);
|
||||
int bytesRead = -1;
|
||||
byte[] bytes = new byte[bufferSize];
|
||||
|
||||
while ((bytesRead = fsIn.Read(bytes, 0, bufferSize)) > 0 && Canceled == false)
|
||||
{
|
||||
fsOut.Write(bytes, 0, bytesRead);
|
||||
float percent = fsOut.Position / fileSize * 100;
|
||||
if (percent > 100)
|
||||
percent = 100;
|
||||
args.PartPercentageUpdate(percent);
|
||||
}
|
||||
if (Canceled == false)
|
||||
args.PartPercentageUpdate(100);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
args.Logger.ELog("Failed to move file: " + ex.Message + Environment.NewLine + ex.StackTrace);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Canceled)
|
||||
{
|
||||
try
|
||||
{
|
||||
System.IO.File.Delete(dest);
|
||||
}
|
||||
catch (Exception) { }
|
||||
args.Logger.ELog("Action was canceled.");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.SetWorkingFile(dest);
|
||||
|
||||
return base.Execute(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
BasicNodes/File/DeleteSourceDirectory.cs
Normal file
82
BasicNodes/File/DeleteSourceDirectory.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
namespace FileFlows.BasicNodes.File
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using FileFlows.Plugin;
|
||||
using FileFlows.Plugin.Attributes;
|
||||
|
||||
public class DeleteSourceDirectory : Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 2;
|
||||
public override FlowElementType Type => FlowElementType.Process;
|
||||
public override string Icon => "far fa-trash-alt";
|
||||
|
||||
[Boolean(1)]
|
||||
public bool IfEmpty { get; set; }
|
||||
|
||||
[StringArray(2)]
|
||||
public string[] IncludePatterns { get; set; }
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
string path = args.FileName.Substring(0, args.FileName.Length - args.RelativeFile.Length);
|
||||
args.Logger.ILog("Library path: " + path);
|
||||
int pathIndex = args.RelativeFile.IndexOf(System.IO.Path.DirectorySeparatorChar);
|
||||
if (pathIndex < 0)
|
||||
{
|
||||
args.Logger.ILog("File is in library root, will not delete");
|
||||
return base.Execute(args);
|
||||
}
|
||||
|
||||
string topdir = args.RelativeFile.Substring(0, pathIndex);
|
||||
string pathToDelete = Path.Combine(path, topdir);
|
||||
|
||||
if (IfEmpty)
|
||||
{
|
||||
var files = new System.IO.DirectoryInfo(pathToDelete).GetFiles("*.*", SearchOption.AllDirectories);
|
||||
if (IncludePatterns?.Any() == true)
|
||||
{
|
||||
var count = files.Where(x =>
|
||||
{
|
||||
foreach (var pattern in IncludePatterns)
|
||||
{
|
||||
if (x.FullName.Contains(pattern))
|
||||
return true;
|
||||
try
|
||||
{
|
||||
if (System.Text.RegularExpressions.Regex.IsMatch(x.FullName, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase))
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
return false;
|
||||
}).Count();
|
||||
if (count > 0)
|
||||
{
|
||||
args.Logger.ILog("Directory is not empty, cannot delete: " + pathToDelete);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else if (files.Length == 0)
|
||||
{
|
||||
args.Logger.ILog("Directory is not empty, cannot delete: " + pathToDelete);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
args.Logger.ILog("Deleting directory: " + pathToDelete);
|
||||
try
|
||||
{
|
||||
System.IO.Directory.Delete(pathToDelete, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
args.Logger.ELog("Failed to delete directory: " + ex.Message);
|
||||
return -1;
|
||||
}
|
||||
return base.Execute(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
17
BasicNodes/File/FileExtension.cs
Normal file
17
BasicNodes/File/FileExtension.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace FileFlows.BasicNodes.File
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using FileFlows.Plugin;
|
||||
using FileFlows.Plugin.Attributes;
|
||||
|
||||
public class FileExtension : Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 2;
|
||||
public override string Icon => "far fa-file-excel";
|
||||
|
||||
[StringArray(1)]
|
||||
public string[] Extensions { get; set; }
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
}
|
||||
}
|
||||
31
BasicNodes/File/FileSize.cs
Normal file
31
BasicNodes/File/FileSize.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace FileFlows.BasicNodes.File
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using FileFlows.Plugin;
|
||||
using FileFlows.Plugin.Attributes;
|
||||
|
||||
public class FileSize : Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 2;
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
public override string Icon => "fas fa-balance-scale-right";
|
||||
|
||||
|
||||
[NumberInt(1)]
|
||||
public int Lower { get; set; }
|
||||
|
||||
[NumberInt(2)]
|
||||
public int Upper { get; set; }
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
long size = new FileInfo(args.WorkingFile).Length;
|
||||
if (size < (Lower * 1024 * 1024))
|
||||
return 2;
|
||||
if (Upper > 0 && size > (Upper * 1024 * 1024))
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
BasicNodes/File/InputFile.cs
Normal file
13
BasicNodes/File/InputFile.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace FileFlows.BasicNodes.File
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using FileFlows.Plugin;
|
||||
using FileFlows.Plugin.Attributes;
|
||||
|
||||
public class InputFile : Node
|
||||
{
|
||||
public override int Outputs => 1;
|
||||
public override FlowElementType Type => FlowElementType.Input;
|
||||
public override string Icon => "far fa-file";
|
||||
}
|
||||
}
|
||||
89
BasicNodes/File/MoveFile.cs
Normal file
89
BasicNodes/File/MoveFile.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
namespace FileFlows.BasicNodes.File
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using FileFlows.Plugin;
|
||||
using FileFlows.Plugin.Attributes;
|
||||
|
||||
public class MoveFile : Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 1;
|
||||
public override FlowElementType Type => FlowElementType.Process;
|
||||
public override string Icon => "fas fa-file-export";
|
||||
|
||||
[Folder(1)]
|
||||
public string DestinationPath { get; set; }
|
||||
|
||||
[Boolean(2)]
|
||||
public bool MoveFolder { get; set; }
|
||||
|
||||
[Boolean(3)]
|
||||
public bool DeleteOriginal { get; set; }
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
string dest = DestinationPath;
|
||||
if (string.IsNullOrEmpty(dest))
|
||||
{
|
||||
args.Logger.ELog("No destination specified");
|
||||
args.Result = NodeResult.Failure;
|
||||
return -1;
|
||||
}
|
||||
args.Result = NodeResult.Failure;
|
||||
|
||||
if (MoveFolder)
|
||||
dest = Path.Combine(dest, args.RelativeFile);
|
||||
else
|
||||
dest = Path.Combine(dest, new FileInfo(args.FileName).Name);
|
||||
|
||||
var destDir = new FileInfo(dest).DirectoryName;
|
||||
if (Directory.Exists(destDir) == false)
|
||||
Directory.CreateDirectory(destDir);
|
||||
|
||||
long fileSize = new FileInfo(args.WorkingFile).Length;
|
||||
|
||||
bool moved = false;
|
||||
Task task = Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (System.IO.File.Exists(dest))
|
||||
System.IO.File.Delete(dest);
|
||||
System.IO.File.Move(args.WorkingFile, dest, true);
|
||||
|
||||
if (DeleteOriginal && args.WorkingFile != args.FileName)
|
||||
{
|
||||
System.IO.File.Delete(args.FileName);
|
||||
}
|
||||
args.SetWorkingFile(dest);
|
||||
|
||||
moved = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
args.Logger.ELog("Failed to move file: " + ex.Message);
|
||||
}
|
||||
});
|
||||
|
||||
while (task.IsCompleted == false)
|
||||
{
|
||||
|
||||
long currentSize = 0;
|
||||
var destFileInfo = new FileInfo(dest);
|
||||
if (destFileInfo.Exists)
|
||||
currentSize = destFileInfo.Length;
|
||||
|
||||
args.PartPercentageUpdate(currentSize / fileSize * 100);
|
||||
System.Threading.Thread.Sleep(50);
|
||||
}
|
||||
|
||||
if (moved == false)
|
||||
return -1;
|
||||
|
||||
args.PartPercentageUpdate(100);
|
||||
|
||||
return base.Execute(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
BasicNodes/Functions/Function.cs
Normal file
57
BasicNodes/Functions/Function.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
namespace FileFlows.BasicNodes.Functions
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using FileFlows.Plugin;
|
||||
using FileFlows.Plugin.Attributes;
|
||||
using Jint.Runtime;
|
||||
using Jint.Native.Object;
|
||||
using Jint;
|
||||
using System.Text;
|
||||
|
||||
public class Function : Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
public override string Icon => "fas fa-code";
|
||||
|
||||
[DefaultValue(1)]
|
||||
[NumberIntAttribute(1)]
|
||||
public new int Outputs { get; set; }
|
||||
|
||||
[DefaultValue("// VideoFile object contains info about the video file\n\n// return 0 to complete the flow.\n// return -1 to signal an error in the flow\n// return 1+ to indicate which output to process next\n\n return 0;")]
|
||||
[Code(2)]
|
||||
public string Code { get; set; }
|
||||
|
||||
delegate void LogDelegate(params object[] values);
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
args.Logger.DLog("Code: ", Environment.NewLine + new string('=', 40) + Environment.NewLine + Code + Environment.NewLine + new string('=', 40));
|
||||
if (string.IsNullOrEmpty(Code))
|
||||
return base.Execute(args); // no code, means will run fine... i think... maybe... depends what i do
|
||||
|
||||
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(100);
|
||||
})
|
||||
.SetValue("Logger", args.Logger)
|
||||
.SetValue("FileSize", new FileInfo(args.WorkingFile).Length)
|
||||
//.SetValue("ILog", log.ILog)
|
||||
;
|
||||
|
||||
var result = engine.Evaluate(Code).ToObject();
|
||||
if (result as bool? != true)
|
||||
args.Result = NodeResult.Failure;
|
||||
|
||||
return base.Execute(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
BasicNodes/Functions/Log.cs
Normal file
36
BasicNodes/Functions/Log.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace FileFlows.BasicNodes.Functions
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using FileFlows.Plugin;
|
||||
using FileFlows.Plugin.Attributes;
|
||||
using Jint.Runtime;
|
||||
using Jint.Native.Object;
|
||||
using Jint;
|
||||
using System.Text;
|
||||
|
||||
public class Log : Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 1;
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
public override string Icon => "far fa-file-alt";
|
||||
|
||||
[Enum(1, LogType.Info, LogType.Debug, LogType.Warning, LogType.Error)]
|
||||
public LogType LogType { get; set; }
|
||||
|
||||
[TextArea(2)]
|
||||
public string Message { get; set; }
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
switch (LogType)
|
||||
{
|
||||
case LogType.Error: args.Logger.ELog(Message); break;
|
||||
case LogType.Warning: args.Logger.WLog(Message); break;
|
||||
case LogType.Debug: args.Logger.DLog(Message); break;
|
||||
case LogType.Info: args.Logger.ILog(Message); break;
|
||||
}
|
||||
|
||||
return base.Execute(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
BasicNodes/Plugin.cs
Normal file
11
BasicNodes/Plugin.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace FileFlows.BasicNodes
|
||||
{
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
public class Plugin : FileFlows.Plugin.IPlugin
|
||||
{
|
||||
public string Name => "Basic Nodes";
|
||||
|
||||
public void Init() { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user