mirror of
https://github.com/revenz/FileFlowsPlugins.git
synced 2026-02-13 01:19:15 -06:00
added checksum and collection nodes
This commit is contained in:
Binary file not shown.
@@ -63,6 +63,20 @@
|
||||
"Extensions-Help": "A list of case insensitive file extensions that will be matched against.\nOutput 1 Matches\nOutput 2: Does not match"
|
||||
}
|
||||
},
|
||||
"FileExists": {
|
||||
"Description": "Checks if a file exists\n\nOutput 1: File exists\nOutput 2: File does not exist",
|
||||
"Fields": {
|
||||
"FileName": "File Name",
|
||||
"FileName-Help": "The file to check if exists. This should be used with a variable from a previous node."
|
||||
}
|
||||
},
|
||||
"Delete": {
|
||||
"Description": "Deletes a file",
|
||||
"Fields": {
|
||||
"FileName": "File Name",
|
||||
"FileName-Help": "If left blank the current working file will be deleted, or folder if library is folder based."
|
||||
}
|
||||
},
|
||||
"FileSize": {
|
||||
"Description": "Checks if the file size matches the configured parameters. The values are in megabytes.\n\nOutput 1: Matches\nOutput 2: Does not match",
|
||||
"Fields": {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace FileFlows.BasicNodes.File
|
||||
{
|
||||
using FileFlows.Plugin;
|
||||
using FileFlows.Plugin.Attributes;
|
||||
|
||||
public class Delete : Node
|
||||
{
|
||||
@@ -9,15 +10,22 @@ namespace FileFlows.BasicNodes.File
|
||||
public override FlowElementType Type => FlowElementType.Process;
|
||||
public override string Icon => "far fa-trash-alt";
|
||||
|
||||
[TextVariable(1)]
|
||||
public string FileName { get; set; }
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
string filename = args.ReplaceVariables(this.FileName ?? string.Empty, stripMissing: true);
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
filename = args.WorkingFile;
|
||||
|
||||
if (args.IsDirectory)
|
||||
{
|
||||
try
|
||||
{
|
||||
args.Logger?.ILog("Deleting directory: " + args.WorkingFile);
|
||||
Directory.Delete(args.WorkingFile, true);
|
||||
args.Logger?.ILog("Deleted directory: " + args.WorkingFile);
|
||||
args.Logger?.ILog("Deleting directory: " + filename);
|
||||
Directory.Delete(filename, true);
|
||||
args.Logger?.ILog("Deleted directory: " + filename);
|
||||
return 1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -30,14 +38,14 @@ namespace FileFlows.BasicNodes.File
|
||||
{
|
||||
try
|
||||
{
|
||||
args.Logger?.ILog("Deleting file: " + args.WorkingFile);
|
||||
System.IO.File.Delete(args.WorkingFile);
|
||||
args.Logger?.ILog("Deleted file: " + args.WorkingFile);
|
||||
args.Logger?.ILog("Deleting file: " + filename);
|
||||
System.IO.File.Delete(filename);
|
||||
args.Logger?.ILog("Deleted file: " + filename);
|
||||
return 1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
args.Logger?.ELog($"Failed to delete file: '{args.WorkingFile}' => {ex.Message}");
|
||||
args.Logger?.ELog($"Failed to delete file: '{filename}' => {ex.Message}");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
42
BasicNodes/File/FileExists.cs
Normal file
42
BasicNodes/File/FileExists.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
namespace FileFlows.BasicNodes.File
|
||||
{
|
||||
using FileFlows.Plugin;
|
||||
using FileFlows.Plugin.Attributes;
|
||||
|
||||
public class FileExists: Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 2;
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
public override string Icon => "fas fa-question-circle";
|
||||
|
||||
[TextVariable(1)]
|
||||
public string FileName { get; set; }
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
string file = args.ReplaceVariables(FileName ?? string.Empty, true);
|
||||
if(string.IsNullOrWhiteSpace(file))
|
||||
{
|
||||
args.Logger?.ELog("FileName not set");
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(file);
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
args.Logger?.ILog("File does exist: " + file);
|
||||
return 1;
|
||||
}
|
||||
args.Logger?.ILog("File does NOT exist: " + file);
|
||||
return 2;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
args.Logger?.ELog($"Failed testing if file '{file}' exists: " + ex.Message);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
ChecksumNodes/ChecksumNodes.csproj
Normal file
BIN
ChecksumNodes/ChecksumNodes.csproj
Normal file
Binary file not shown.
15
ChecksumNodes/ChecksumNodes.en.json
Normal file
15
ChecksumNodes/ChecksumNodes.en.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"Flow":{
|
||||
"Parts": {
|
||||
"MD5Checksum": {
|
||||
"Description": "Computes a MD5 checksum of the working file and stores it in the variable \"MD5\" and in \"Checksum\"."
|
||||
},
|
||||
"SHA1Checksum": {
|
||||
"Description": "Computes a SHA1 checksum of the working file and stores it in the variable \"SHA1\" and in \"Checksum\"."
|
||||
},
|
||||
"SHA256Checksum": {
|
||||
"Description": "Computes a SHA256 checksum of the working file and stores it in the variable \"SHA256\" and in \"Checksum\"."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
6
ChecksumNodes/GlobalUsings.cs
Normal file
6
ChecksumNodes/GlobalUsings.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Linq;
|
||||
global using System.Text;
|
||||
global using System.Threading.Tasks;
|
||||
global using FileFlows.Plugin;
|
||||
40
ChecksumNodes/Nodes/MD5.cs
Normal file
40
ChecksumNodes/Nodes/MD5.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace ChecksumNodes
|
||||
{
|
||||
public class MD5:Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 1;
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
public override string Icon => "fas fa-file-contract";
|
||||
|
||||
private Dictionary<string, object> _Variables;
|
||||
public override Dictionary<string, object> Variables => _Variables;
|
||||
public MD5()
|
||||
{
|
||||
_Variables = new Dictionary<string, object>()
|
||||
{
|
||||
{ "Checksum", "4A4566696CC81C6053EC708975767498" },
|
||||
{ "MD5", "4A4566696CC81C6053EC708975767498" }
|
||||
};
|
||||
}
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
using var md5 = System.Security.Cryptography.MD5.Create();
|
||||
DateTime start = DateTime.Now;
|
||||
using var stream = File.OpenRead(args.WorkingFile);
|
||||
var hash = md5.ComputeHash(stream);
|
||||
string hashStr = BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
|
||||
args.Logger?.ILog("MD5 of working file: " + hashStr);
|
||||
args.Logger?.ILog("Time taken to compute hash: " + (DateTime.Now - start));
|
||||
args.UpdateVariables(new Dictionary<string, object>
|
||||
{
|
||||
{ "MD5", hashStr },
|
||||
{ "Checksum", hashStr },
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
ChecksumNodes/Nodes/SHA1.cs
Normal file
41
ChecksumNodes/Nodes/SHA1.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace ChecksumNodes
|
||||
{
|
||||
public class SHA1:Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 1;
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
|
||||
public override string Icon => "fas fa-file-contract";
|
||||
|
||||
private Dictionary<string, object> _Variables;
|
||||
public override Dictionary<string, object> Variables => _Variables;
|
||||
public SHA1()
|
||||
{
|
||||
_Variables = new Dictionary<string, object>()
|
||||
{
|
||||
{ "Checksum", "32B26A271530F105CBC35CB653110E1A49D019B6" },
|
||||
{ "SHA1", "32B26A271530F105CBC35CB653110E1A49D019B6" }
|
||||
};
|
||||
}
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
using var hasher = System.Security.Cryptography.SHA1.Create();
|
||||
DateTime start = DateTime.Now;
|
||||
using var stream = File.OpenRead(args.WorkingFile);
|
||||
var hash = hasher.ComputeHash(stream);
|
||||
string hashStr = BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
|
||||
args.Logger?.ILog("SHA1 of working file: " + hashStr);
|
||||
args.Logger?.ILog("Time taken to compute hash: " + (DateTime.Now - start));
|
||||
args.UpdateVariables(new Dictionary<string, object>
|
||||
{
|
||||
{ "SHA1", hashStr },
|
||||
{ "Checksum", hashStr },
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
ChecksumNodes/Nodes/SHA256.cs
Normal file
41
ChecksumNodes/Nodes/SHA256.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace ChecksumNodes
|
||||
{
|
||||
public class SHA256:Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 1;
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
|
||||
public override string Icon => "fas fa-file-contract";
|
||||
|
||||
private Dictionary<string, object> _Variables;
|
||||
public override Dictionary<string, object> Variables => _Variables;
|
||||
public SHA256()
|
||||
{
|
||||
_Variables = new Dictionary<string, object>()
|
||||
{
|
||||
{ "Checksum", "BD9B74A682CD757611805F86371A5A277B2941FA42345CE4C87A7C9E28244C2C" },
|
||||
{ "SHA256", "BD9B74A682CD757611805F86371A5A277B2941FA42345CE4C87A7C9E28244C2C" }
|
||||
};
|
||||
}
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
using var hasher = System.Security.Cryptography.SHA256.Create();
|
||||
DateTime start = DateTime.Now;
|
||||
using var stream = File.OpenRead(args.WorkingFile);
|
||||
var hash = hasher.ComputeHash(stream);
|
||||
string hashStr = BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
|
||||
args.Logger?.ILog("SHA256 of working file: " + hashStr);
|
||||
args.Logger?.ILog("Time taken to compute hash: " + (DateTime.Now - start));
|
||||
args.UpdateVariables(new Dictionary<string, object>
|
||||
{
|
||||
{ "SHA256", hashStr },
|
||||
{ "Checksum", hashStr },
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
ChecksumNodes/Nodes/SHA512.cs
Normal file
41
ChecksumNodes/Nodes/SHA512.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace ChecksumNodes
|
||||
{
|
||||
public class SHA512:Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 1;
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
|
||||
public override string Icon => "fas fa-file-contract";
|
||||
|
||||
private Dictionary<string, object> _Variables;
|
||||
public override Dictionary<string, object> Variables => _Variables;
|
||||
public SHA512()
|
||||
{
|
||||
_Variables = new Dictionary<string, object>()
|
||||
{
|
||||
{ "Checksum", "267dc7710d5938c6dc362dd24b2f3b13e4a75a1f4338c0d0a39786afd67491f13be0525f46b1bcdb7be934248870210e73166f9103063b9a6a986a94dae77d4e" },
|
||||
{ "SHA512", "267dc7710d5938c6dc362dd24b2f3b13e4a75a1f4338c0d0a39786afd67491f13be0525f46b1bcdb7be934248870210e73166f9103063b9a6a986a94dae77d4e" }
|
||||
};
|
||||
}
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
using var hasher = System.Security.Cryptography.SHA512.Create();
|
||||
DateTime start = DateTime.Now;
|
||||
using var stream = File.OpenRead(args.WorkingFile);
|
||||
var hash = hasher.ComputeHash(stream);
|
||||
string hashStr = BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
|
||||
args.Logger?.ILog("SHA512 of working file: " + hashStr);
|
||||
args.Logger?.ILog("Time taken to compute hash: " + (DateTime.Now - start));
|
||||
args.UpdateVariables(new Dictionary<string, object>
|
||||
{
|
||||
{ "SHA512", hashStr },
|
||||
{ "Checksum", hashStr },
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
ChecksumNodes/Plugin.cs
Normal file
11
ChecksumNodes/Plugin.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace ChecksumNodes
|
||||
{
|
||||
public class Plugin : IPlugin
|
||||
{
|
||||
public string Name => "Checksum Nodes";
|
||||
|
||||
public void Init()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
49
ChecksumNodes/Tests/ChecksumTests.cs
Normal file
49
ChecksumNodes/Tests/ChecksumTests.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
#if(DEBUG)
|
||||
|
||||
namespace ChecksumNodes.Tests
|
||||
{
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
[TestClass]
|
||||
public class ChecksumTests
|
||||
{
|
||||
|
||||
[TestMethod]
|
||||
public void Checksum_MD5_Large()
|
||||
{
|
||||
var args = new NodeParameters(@"D:\videos\Injustice.mkv", new TestLogger(), false, "");
|
||||
var output = new MD5().Execute(args);
|
||||
Assert.IsTrue(args.Variables.ContainsKey("MD5"));
|
||||
Assert.IsFalse(string.IsNullOrWhiteSpace(args.Variables["MD5"] as string));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Checksum_SHA1_Large()
|
||||
{
|
||||
var args = new NodeParameters(@"D:\videos\Injustice.mkv", new TestLogger(), false, "");
|
||||
var output = new SHA1().Execute(args);
|
||||
Assert.IsTrue(args.Variables.ContainsKey("SHA1"));
|
||||
Assert.IsFalse(string.IsNullOrWhiteSpace(args.Variables["SHA1"] as string));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Checksum_SHA256_Large()
|
||||
{
|
||||
var args = new NodeParameters(@"D:\videos\Injustice.mkv", new TestLogger(), false, "");
|
||||
var output = new SHA256().Execute(args);
|
||||
Assert.IsTrue(args.Variables.ContainsKey("SHA256"));
|
||||
Assert.IsFalse(string.IsNullOrWhiteSpace(args.Variables["SHA256"] as string));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Checksum_SHA512_Large()
|
||||
{
|
||||
var args = new NodeParameters(@"D:\videos\Injustice.mkv", new TestLogger(), false, "");
|
||||
var output = new SHA512().Execute(args);
|
||||
Assert.IsTrue(args.Variables.ContainsKey("SHA512"));
|
||||
Assert.IsFalse(string.IsNullOrWhiteSpace(args.Variables["SHA512"] as string));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
45
ChecksumNodes/Tests/TestLogger.cs
Normal file
45
ChecksumNodes/Tests/TestLogger.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
#if(DEBUG)
|
||||
|
||||
namespace ChecksumNodes.Tests
|
||||
{
|
||||
using FileFlows.Plugin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
internal class TestLogger : ILogger
|
||||
{
|
||||
private List<string> Messages = new List<string>();
|
||||
|
||||
public void DLog(params object[] args) => Log("DBUG", args);
|
||||
|
||||
public void ELog(params object[] args) => Log("ERRR", args);
|
||||
|
||||
public void ILog(params object[] args) => Log("INFO", args);
|
||||
|
||||
public void WLog(params object[] args) => Log("WARN", args);
|
||||
|
||||
private void Log(string type, object[] args)
|
||||
{
|
||||
if (args == null || args.Length == 0)
|
||||
return;
|
||||
string message = type + " -> " +
|
||||
string.Join(", ", args.Select(x =>
|
||||
x == null ? "null" :
|
||||
x.GetType().IsPrimitive || x is string ? x.ToString() :
|
||||
System.Text.Json.JsonSerializer.Serialize(x)));
|
||||
Messages.Add(message);
|
||||
}
|
||||
|
||||
public bool Contains(string message)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message))
|
||||
return false;
|
||||
|
||||
string log = string.Join(Environment.NewLine, Messages);
|
||||
return log.Contains(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
BIN
CollectionNodes/CollectionNodes.csproj
Normal file
BIN
CollectionNodes/CollectionNodes.csproj
Normal file
Binary file not shown.
21
CollectionNodes/CollectionNodes.en.json
Normal file
21
CollectionNodes/CollectionNodes.en.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"Flow":{
|
||||
"Parts": {
|
||||
"DataCollection": {
|
||||
"Description": "Checks a database for a key and a matching value. If not in the database, will add it to the database.\n\nOutput 1: Not in database\nOutput 2: In database and the same\nOutput 3: In datbase but value different.",
|
||||
"Fields": {
|
||||
"DatabaseFolder": "Database Folder",
|
||||
"DatabaseFolder-Help": "The location to save the SQLite database file. This folder must be accessible by every processing node.",
|
||||
"DatabaseFile": "Database File",
|
||||
"DatabaseFile-Help": "The SQLite database file. This file must be accessible by every processing node.",
|
||||
"Key": "Key",
|
||||
"Key-Help": "The key value used to index the collection. If left empty the original filename will be used.",
|
||||
"Value": "Value",
|
||||
"Value-Help": "The value to check the collection for. Can be a variable from a previous node.",
|
||||
"UpdateIfDifferent": "Update If Different",
|
||||
"UpdateIfDifferent-Help": "If the value in the collection should be updated if the stored value is different."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
6
CollectionNodes/GlobalUsings.cs
Normal file
6
CollectionNodes/GlobalUsings.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Linq;
|
||||
global using System.Text;
|
||||
global using System.Threading.Tasks;
|
||||
global using FileFlows.Plugin;
|
||||
142
CollectionNodes/Nodes/DataCollection.cs
Normal file
142
CollectionNodes/Nodes/DataCollection.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using FileFlows.Plugin.Attributes;
|
||||
using NPoco;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Data.SQLite;
|
||||
|
||||
namespace CollectionNodes
|
||||
{
|
||||
public class DataCollection : Node
|
||||
{
|
||||
public override int Inputs => 1;
|
||||
public override int Outputs => 3;
|
||||
public override FlowElementType Type => FlowElementType.Logic;
|
||||
public override string Icon => "fas fa-database";
|
||||
private Dictionary<string, object> _Variables;
|
||||
public override Dictionary<string, object> Variables => _Variables;
|
||||
public DataCollection()
|
||||
{
|
||||
_Variables = new Dictionary<string, object>()
|
||||
{
|
||||
{ "dc.Value", "ValueFromDataCollection" }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[Required]
|
||||
[Folder(1)]
|
||||
public string DatabaseFolder { get; set; }
|
||||
|
||||
[Required]
|
||||
[Text(2)]
|
||||
public string DatabaseFile { get; set; }
|
||||
|
||||
[TextVariable(3)]
|
||||
public string Key { get; set; }
|
||||
|
||||
[Required]
|
||||
[TextVariable(4)]
|
||||
public string Value { get; set; }
|
||||
|
||||
[Boolean(5)]
|
||||
public bool UpdateIfDifferent { get; set; }
|
||||
|
||||
public override int Execute(NodeParameters args)
|
||||
{
|
||||
string key = args.ReplaceVariables(Key ?? string.Empty, true);
|
||||
string value = args.ReplaceVariables(Value ?? string.Empty, true);
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
args.Logger?.ELog("Key not set using filename");
|
||||
key = args.FileName;
|
||||
}
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
args.Logger?.ELog("Value not set");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (args.Variables.ContainsKey(value))
|
||||
{
|
||||
value = args.Variables[value]?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
string dbFile = Path.Combine(
|
||||
args.ReplaceVariables(this.DatabaseFolder, stripMissing: true),
|
||||
args.ReplaceVariables(this.DatabaseFile, stripMissing: true)
|
||||
);
|
||||
CreateDatabaseIfNotExists(dbFile);
|
||||
|
||||
|
||||
var db = new Database($"Data Source={dbFile};Version=3;", null, SQLiteFactory.Instance);
|
||||
|
||||
string result = db.ExecuteScalar<string>($"select {nameof(DbObject.Value)} from {nameof(DbObject)} where {nameof(DbObject.Key)} = @0", key);
|
||||
if(result == null)
|
||||
{
|
||||
args.Logger?.ILog("Key not in database");
|
||||
db.Execute($"insert into {nameof(DbObject)} values (@0, @1)", key, value);
|
||||
args.UpdateVariables(new Dictionary<string, object>
|
||||
{
|
||||
{ "dc.Value", value },
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
if (result == value)
|
||||
{
|
||||
args.Logger?.ILog("Value matches what was already in database");
|
||||
args.UpdateVariables(new Dictionary<string, object>
|
||||
{
|
||||
{ "dc.Value", value },
|
||||
});
|
||||
return 2;
|
||||
}
|
||||
args.UpdateVariables(new Dictionary<string, object>
|
||||
{
|
||||
{ "dc.Value", result },
|
||||
});
|
||||
args.Logger?.ILog("Key value did not match what was in database");
|
||||
if (UpdateIfDifferent)
|
||||
{
|
||||
db.Execute($"update {nameof(DbObject)} set {nameof(DbObject.Value)} = @1 where {nameof(DbObject.Key)} = @0", key, value);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
private void CreateDatabaseIfNotExists(string dbFile)
|
||||
{
|
||||
if (System.IO.File.Exists(dbFile) == false)
|
||||
SQLiteConnection.CreateFile(dbFile);
|
||||
else
|
||||
{
|
||||
// create backup
|
||||
File.Copy(dbFile, dbFile + ".backup", true);
|
||||
}
|
||||
|
||||
using (var con = new SQLiteConnection($"Data Source={dbFile};Version=3;"))
|
||||
{
|
||||
con.Open();
|
||||
using (var cmd = new SQLiteCommand($"SELECT name FROM sqlite_master WHERE type='table' AND name='{nameof(DbObject)}'", con))
|
||||
{
|
||||
if (cmd.ExecuteScalar() != null)
|
||||
return;// tables exist, all good
|
||||
}
|
||||
using (var cmd = new SQLiteCommand(CreateDbScript, con))
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
con.Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private const string CreateDbScript = @$"CREATE TABLE {nameof(DbObject)}(
|
||||
Key VARCHAR(1024) NOT NULL PRIMARY KEY,
|
||||
Value TEXT NOT NULL
|
||||
);";
|
||||
|
||||
private class DbObject
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
18
CollectionNodes/Plugin.cs
Normal file
18
CollectionNodes/Plugin.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using FileFlows.Plugin.Attributes;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace CollectionNodes
|
||||
{
|
||||
public class Plugin : IPlugin
|
||||
{
|
||||
public string Name => "Collection Nodes";
|
||||
|
||||
[Folder(1)]
|
||||
[Required]
|
||||
public string DataDirectory { get; set; }
|
||||
|
||||
public void Init()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
68
CollectionNodes/Tests/DataCollectionTests.cs
Normal file
68
CollectionNodes/Tests/DataCollectionTests.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
#if(DEBUG)
|
||||
namespace CollectionNodes.Tests
|
||||
{
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
[TestClass]
|
||||
public class DataCollectionTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void DataCollection_NotIn()
|
||||
{
|
||||
var logger =new TestLogger();
|
||||
var args = new NodeParameters(@"D:\videos\injustice.mkv", logger, false, "");
|
||||
string dbFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".sqlite");
|
||||
var dc = new DataCollection()
|
||||
{
|
||||
Value = "Checksum",
|
||||
DatabaseFile = dbFile,
|
||||
UpdateIfDifferent = true,
|
||||
};
|
||||
args.Variables.Add("Checksum", "batman");
|
||||
var output = dc.Execute(args);
|
||||
Assert.AreEqual(1, output);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DataCollection_InAndSame()
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(@"D:\videos\injustice.mkv", logger, false, "");
|
||||
string dbFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".sqlite");
|
||||
var dc = new DataCollection()
|
||||
{
|
||||
Value = "Checksum",
|
||||
DatabaseFile = dbFile,
|
||||
UpdateIfDifferent = true,
|
||||
};
|
||||
args.Variables.Add("Checksum", "batman");
|
||||
var output = dc.Execute(args);
|
||||
Assert.AreEqual(1, output);
|
||||
|
||||
var output2 = dc.Execute(args);
|
||||
Assert.AreEqual(2, output2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DataCollection_InAndNotSame()
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(@"D:\videos\injustice.mkv", logger, false, "");
|
||||
string dbFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".sqlite");
|
||||
var dc = new DataCollection()
|
||||
{
|
||||
Value = "Checksum",
|
||||
DatabaseFile = dbFile,
|
||||
UpdateIfDifferent = true,
|
||||
};
|
||||
args.Variables.Add("Checksum", "batman");
|
||||
var output = dc.Execute(args);
|
||||
Assert.AreEqual(1, output);
|
||||
|
||||
args.Variables["Checksum"] = "joker";
|
||||
var output3 = dc.Execute(args);
|
||||
Assert.AreEqual(3, output3);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
45
CollectionNodes/Tests/TestLogger.cs
Normal file
45
CollectionNodes/Tests/TestLogger.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
#if(DEBUG)
|
||||
|
||||
namespace CollectionNodes.Tests
|
||||
{
|
||||
using FileFlows.Plugin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
internal class TestLogger : ILogger
|
||||
{
|
||||
private List<string> Messages = new List<string>();
|
||||
|
||||
public void DLog(params object[] args) => Log("DBUG", args);
|
||||
|
||||
public void ELog(params object[] args) => Log("ERRR", args);
|
||||
|
||||
public void ILog(params object[] args) => Log("INFO", args);
|
||||
|
||||
public void WLog(params object[] args) => Log("WARN", args);
|
||||
|
||||
private void Log(string type, object[] args)
|
||||
{
|
||||
if (args == null || args.Length == 0)
|
||||
return;
|
||||
string message = type + " -> " +
|
||||
string.Join(", ", args.Select(x =>
|
||||
x == null ? "null" :
|
||||
x.GetType().IsPrimitive || x is string ? x.ToString() :
|
||||
System.Text.Json.JsonSerializer.Serialize(x)));
|
||||
Messages.Add(message);
|
||||
}
|
||||
|
||||
public bool Contains(string message)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message))
|
||||
return false;
|
||||
|
||||
string log = string.Join(Environment.NewLine, Messages);
|
||||
return log.Contains(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -7,7 +7,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicNodes", "BasicNodes\Ba
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VideoNodes", "VideoNodes\VideoNodes.csproj", "{CF96D3D1-1D8B-47F7-BEA7-BB238F7A566A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetaNodes", "MetaNodes\MetaNodes.csproj", "{E6F8E9F6-31D7-4A89-966D-2690CA7C0528}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MetaNodes", "MetaNodes\MetaNodes.csproj", "{E6F8E9F6-31D7-4A89-966D-2690CA7C0528}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChecksumNodes", "ChecksumNodes\ChecksumNodes.csproj", "{910B0A24-0E5C-4E1D-9C52-D537F896DE02}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CollectionNodes", "CollectionNodes\CollectionNodes.csproj", "{4211AAE9-0764-4626-B0F2-089A466E002A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -27,6 +31,14 @@ Global
|
||||
{E6F8E9F6-31D7-4A89-966D-2690CA7C0528}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E6F8E9F6-31D7-4A89-966D-2690CA7C0528}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E6F8E9F6-31D7-4A89-966D-2690CA7C0528}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{910B0A24-0E5C-4E1D-9C52-D537F896DE02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{910B0A24-0E5C-4E1D-9C52-D537F896DE02}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{910B0A24-0E5C-4E1D-9C52-D537F896DE02}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{910B0A24-0E5C-4E1D-9C52-D537F896DE02}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4211AAE9-0764-4626-B0F2-089A466E002A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4211AAE9-0764-4626-B0F2-089A466E002A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4211AAE9-0764-4626-B0F2-089A466E002A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4211AAE9-0764-4626-B0F2-089A466E002A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -6,15 +6,8 @@ namespace FileFlows.VideoNodes
|
||||
public class Plugin : FileFlows.Plugin.IPlugin
|
||||
{
|
||||
public string Name => "Video Nodes";
|
||||
|
||||
[Required]
|
||||
[File(2, "exe")]
|
||||
public string FFProbeExe { get; set; }
|
||||
|
||||
public void Init()
|
||||
{
|
||||
//var context = new System.Runtime.Loader.AssemblyLoadContext(null, true);
|
||||
//context.LoadFromAssemblyPath(@"C:\Users\john\src\ViWatcher\Plugins\VideoNodes\bin\Debug\net6.0\FFMpegCore.dll");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user