diff --git a/BasicNodes/BasicNodes.csproj b/BasicNodes/BasicNodes.csproj
index 9d018d1d..e9f7bed4 100644
--- a/BasicNodes/BasicNodes.csproj
+++ b/BasicNodes/BasicNodes.csproj
@@ -29,6 +29,10 @@
+
+
+
+
Always
diff --git a/BasicNodes/BasicNodes.en.json b/BasicNodes/BasicNodes.en.json
index 351f3ca0..2bd59318 100644
--- a/BasicNodes/BasicNodes.en.json
+++ b/BasicNodes/BasicNodes.en.json
@@ -323,6 +323,18 @@
"Body-Help": "The body of the request being sent. Variables can be used in this field."
}
},
+ "Unpack": {
+ "Description": "Allows you to unpack an archive (zip, rar, tar, etc)",
+ "Outputs": {
+ "1": "File Unpacked"
+ },
+ "Fields": {
+ "DestinationPath": "Destination Folder",
+ "DestinationPath-Help": "The destination folder where to unpack the file.",
+ "File": "File",
+ "File-Help": "The name of the file to unpack. Can be left blank and if so the current working file will be used."
+ }
+ },
"Unzip": {
"Description": "Allows you to unzip a file",
"Outputs": {
diff --git a/BasicNodes/Tools/Unpack.cs b/BasicNodes/Tools/Unpack.cs
new file mode 100644
index 00000000..85fe25d0
--- /dev/null
+++ b/BasicNodes/Tools/Unpack.cs
@@ -0,0 +1,122 @@
+using System.Diagnostics;
+using FileFlows.Plugin;
+using FileFlows.Plugin.Attributes;
+using System.IO.Compression;
+using FileFlows.BasicNodes;
+using SharpCompress.Archives;
+
+namespace BasicNodes.Tools;
+
+///
+/// Node used to unpack files from archives
+///
+public class Unpack: Node
+{
+ public override int Inputs => 1;
+ public override int Outputs => 1;
+ public override FlowElementType Type => FlowElementType.Process;
+ public override string Icon => "fas fa-file-archive";
+ ///
+ /// Gets the Help URL for this element
+ ///
+ public override string HelpUrl => "https://fileflows.com/docs/plugins/basic-nodes/unpack";
+
+ private string _DestinationPath = string.Empty;
+ private string _file = string.Empty;
+
+ [Folder(1)]
+ public string DestinationPath
+ {
+ get => _DestinationPath;
+ set { _DestinationPath = value ?? ""; }
+ }
+
+ [TextVariable(2)]
+ public string File
+ {
+ get => _file;
+ set { _file = value ?? ""; }
+ }
+
+ public override int Execute(NodeParameters args)
+ {
+ try
+ {
+ var filename = args.ReplaceVariables(File ?? string.Empty, stripMissing: true)?.EmptyAsNull() ?? args.WorkingFile;
+
+ var fileInfo = new FileInfo(filename);
+
+ if (fileInfo.Exists == false)
+ {
+ args.Logger?.ELog("File does not exist: " + filename);
+ return -1;
+ }
+
+ string destDir = args.ReplaceVariables(DestinationPath, stripMissing: true, cleanSpecialCharacters: true);
+
+ if (fileInfo.Extension.ToLower() == ".zip")
+ ZipFile.ExtractToDirectory(filename, destDir, true);
+ else
+ Extract(args, args.WorkingFile, destDir);
+
+ return 1;
+ }
+ catch (Exception ex)
+ {
+ args.Logger?.ELog("Failed unzip: " + ex.Message + Environment.NewLine + ex.StackTrace);
+ return -1;
+ }
+ }
+
+ ///
+ /// Unpacks a file
+ ///
+ /// the node parameters
+ /// the file to extract
+ /// the location to extract to
+ private void Extract(NodeParameters args, string workingFile, string destinationPath)
+ {
+ bool isRar = workingFile.ToLowerInvariant().EndsWith(".cbr");
+ try
+ {
+ ArchiveFactory.WriteToDirectory(workingFile, destinationPath);
+ }
+ catch (Exception ex) when (isRar && ex.Message.Contains("Unknown Rar Header"))
+ {
+ UnrarCommandLineExtract(args, workingFile, destinationPath);
+ }
+ }
+
+
+ ///
+ /// Unpacks a folder
+ ///
+ /// the node parameters
+ /// the file to extract
+ /// the location to extract to
+ void UnrarCommandLineExtract(NodeParameters args, string workingFile, string destinationPath)
+ {
+ var process = new Process();
+ string unrar = args.GetToolPath("unrar")?.EmptyAsNull() ?? "unrar";
+ process.StartInfo.FileName = unrar;
+ process.StartInfo.ArgumentList.Add("x");
+ process.StartInfo.ArgumentList.Add("-o+");
+ process.StartInfo.ArgumentList.Add(workingFile);
+ process.StartInfo.ArgumentList.Add(destinationPath);
+ process.StartInfo.UseShellExecute = false;
+ process.StartInfo.RedirectStandardOutput = true;
+ process.StartInfo.RedirectStandardError = true;
+ process.StartInfo.CreateNoWindow = true;
+ process.Start();
+ string output = process.StandardError.ReadToEnd();
+ string error = process.StandardError.ReadToEnd();
+ process.WaitForExit();
+
+ args.Logger?.ILog("Unrar output:\n" + output);
+ if (string.IsNullOrWhiteSpace(error) == false)
+ args.Logger?.ELog("Unrar error:\n" + error);
+
+ if (process.ExitCode != 0)
+ throw new Exception(error?.EmptyAsNull() ?? "Failed to extract rar file");
+ }
+}
diff --git a/BasicNodes/Tools/Unzip.cs b/BasicNodes/Tools/Unzip.cs
index 6e5b03f2..1a3d9c5a 100644
--- a/BasicNodes/Tools/Unzip.cs
+++ b/BasicNodes/Tools/Unzip.cs
@@ -1,18 +1,29 @@
-using FileFlows.Plugin;
+using BasicNodes.Tools;
+using FileFlows.Plugin;
using FileFlows.Plugin.Attributes;
-using System.IO.Compression;
namespace FileFlows.BasicNodes.File;
///
/// Node that unzips a file
///
-public class Unzip : Node
+public class Unzip : Node
{
+ ///
+ /// Gets that this node is obsolete
+ ///
+ public override bool Obsolete => true;
+ ///
+ /// Gets the obsolete message
+ ///
+ public override string ObsoleteMessage => "This has been replaced with the Unpack node.\n\nUse that instead.";
public override int Inputs => 1;
public override int Outputs => 1;
public override FlowElementType Type => FlowElementType.Process;
public override string Icon => "fas fa-file-archive";
+ ///
+ /// Gets the Help URL for this element
+ ///
public override string HelpUrl => "https://fileflows.com/docs/plugins/basic-nodes/unzip";
private string _DestinationPath = string.Empty;
@@ -32,27 +43,16 @@ public class Unzip : Node
set { _zip = value ?? ""; }
}
+ ///
+ /// Executes the node
+ ///
+ /// the arguments
+ /// the output
public override int Execute(NodeParameters args)
{
- try
- {
- var zip = args.ReplaceVariables(Zip ?? string.Empty, stripMissing: true)?.EmptyAsNull() ?? args.WorkingFile;
-
- if (System.IO.File.Exists(zip) == false)
- {
- args.Logger?.ELog("File does not exist: " + zip);
- return -1;
- }
-
- string destDir = args.ReplaceVariables(DestinationPath, stripMissing: true, cleanSpecialCharacters: true);
-
- ZipFile.ExtractToDirectory(zip, destDir, true);
- return 1;
- }
- catch (Exception ex)
- {
- args.Logger?.ELog("Failed unzip: " + ex.Message + Environment.NewLine + ex.StackTrace);
- return -1;
- }
+ var unpack = new Unpack();
+ unpack.File = Zip;
+ unpack.DestinationPath = DestinationPath;
+ return unpack.Execute(args);
}
}
diff --git a/ComicNodes/Helpers/GenericExtractor.cs b/ComicNodes/Helpers/GenericExtractor.cs
index a87a129b..b73f62af 100644
--- a/ComicNodes/Helpers/GenericExtractor.cs
+++ b/ComicNodes/Helpers/GenericExtractor.cs
@@ -10,7 +10,7 @@ internal class GenericExtractor
///
/// Uncompresses a folder
///
- /// the node paratemers
+ /// the node parameters
/// the file to extract
/// the location to extract to
/// if the NodeParameter.PartPercentageUpdate should end at 50%