diff --git a/Processor.cs b/Processor.cs new file mode 100644 index 0000000..67ac137 --- /dev/null +++ b/Processor.cs @@ -0,0 +1,155 @@ +using System; +using System.IO; +using System.Linq; + +namespace TwoFour +{ + /// + /// Depth changing processor + /// + public class Processor + { + /// + /// Directory to process + /// + private string directory; + + /// + /// Number of bytes deep the folder should be rebuilt to + /// + private int depth; + + /// + /// Create a new processor + /// + /// Directory to process + /// Byte depth + public Processor(string directory, int depth) + { + this.directory = directory; + this.depth = depth; + } + + /// + /// Process a given directory in the requested way + /// + /// True if the folder was processed, false on unrecoverable error + public bool ProcessFolder() + { + try + { + // Get the full path for processing + directory = Path.GetFullPath(directory); + if (!Directory.Exists(directory)) + throw new DirectoryNotFoundException(); + + // Make sure it ends with a directory separator + if (!directory.EndsWith("\\")) + directory += "\\"; + } + catch + { + Console.WriteLine($"{directory} is not a valid directory"); + return false; + } + + Console.WriteLine($"Traversing {directory} and rebuilding to {depth}-deep folders"); + foreach (string file in Directory.EnumerateFiles(directory, "*", SearchOption.AllDirectories)) + { + Console.WriteLine($"Processing {file}"); + + // Get relevant parts of the path + string oldDir = Path.GetDirectoryName(file); + string current = oldDir.Substring(directory.Length); + string filename = Path.GetFileName(file); + + // Make sure subdirectory ends with a directory separator + if (!current.EndsWith("\\")) + current += "\\"; + + // Get the expected new subdirectory + string expected = GetSubdirectory(filename); + + // If we have a match between current and expected, don't do anything + if (string.Equals(current, expected, StringComparison.OrdinalIgnoreCase)) + { + Console.WriteLine($"{file} already in the right directory!"); + continue; + } + + // Get the new full path to the output directory + string subdirectory = Path.Combine(directory, expected); + + // Make sure subdirectory ends with a directory separator + if (!subdirectory.EndsWith("\\")) + subdirectory += "\\"; + + // If the directory doesn't exist, create it + if (!Directory.Exists(subdirectory)) + { + try + { + Console.WriteLine($"Creating {subdirectory}"); + Directory.CreateDirectory(subdirectory); + } + catch (Exception ex) + { + Console.WriteLine($"An exception occurred while creating {subdirectory}: {ex}"); + continue; + } + + } + + // Now move the file accordingly + try + { + Console.WriteLine($"Moving {filename}"); + File.Move(file, Path.Combine(subdirectory, filename)); + } + catch (Exception ex) + { + Console.WriteLine($"An exception occurred while moving {filename}: {ex}"); + continue; + } + + // If the old path is a subset of the new path and it's empty, remove it + if (current.Contains(expected) && Directory.EnumerateFiles(oldDir, "*", SearchOption.AllDirectories).Any()) + { + try + { + Console.WriteLine($"Removing {oldDir}"); + Directory.Delete(oldDir); + } + catch (Exception ex) + { + Console.WriteLine($"An exception occurred while removing {oldDir}: {ex}"); + continue; + } + } + } + + return true; + } + + /// + /// Get the expected subdirectory path for a given file path + /// + /// Filename to get subdirectory for + /// String representing the subdirectory, null on error + private string GetSubdirectory(string filename) + { + // If we don't have a long enough filename, return null + if (filename.Length < 2 * depth) + return null; + + // Otherwise, get the proper value + string path = string.Empty; + for (int i = 0; i < depth; i++) + { + path += $"{filename.Substring(i * 2, 2)}\\"; + } + + return path; + } + } +} diff --git a/Program.cs b/Program.cs index a179134..05b654d 100644 --- a/Program.cs +++ b/Program.cs @@ -1,6 +1,4 @@ using System; -using System.IO; -using System.Linq; namespace TwoFour { @@ -8,7 +6,7 @@ namespace TwoFour { public static void Main(string[] args) { - // If we don't have the right inputs, show help and exit + // If we don't have the right number of inputs, show help and exit if (args.Length < 2) { Console.WriteLine("At least 2 arguments are required"); @@ -16,45 +14,32 @@ namespace TwoFour return; } - // Get rebuild mode from first arg - bool? fourdeep = null; - if (args[0] == "2" || args[0] == "two" || args[0] == "rvx" || args[0] == "romvaultx" || args[0] == "romroot") - fourdeep = false; - else if (args[0] == "4" || args[0] == "four" || args[0] == "romba" || args[0] == "depot") - fourdeep = true; + // Get rebuild depth from first arg + int depth; + if (args[0] == "rvx" || args[0] == "romvaultx" || args[0] == "romroot") + depth = 2; + else if (args[0] == "romba" || args[0] == "depot") + depth = 4; + else if (!int.TryParse(args[0], out depth)) + depth = -1; // If neither matched, show help and exit - if (fourdeep == null) + if (depth < 0) { - Console.WriteLine($"{args[0]} is not a valid flag"); + Console.WriteLine($"{args[0]} is not a valid depth"); DisplayHelp(); return; } - // Get processing folders from remaining args + // Process each directory from remaining args for (int i = 1; i < args.Length; i++) { - string directory = args[i]; - try + Processor processor = new Processor(args[i], depth); + if (!processor.ProcessFolder()) { - // Get the full path for processing - directory = Path.GetFullPath(directory); - if (!Directory.Exists(directory)) - throw new DirectoryNotFoundException(); - - // Make sure it ends with a directory separator - if (!directory.EndsWith("\\")) - directory += "\\"; - } - catch - { - Console.WriteLine($"{directory} is not a valid directory"); DisplayHelp(); return; } - - // Now that we have both, run the processing accordingly - ProcessFolder(fourdeep.Value, directory); } } @@ -65,112 +50,9 @@ namespace TwoFour { Console.WriteLine("Usage: TwoFour.exe [mode] [path\\to\\folder] ..."); Console.WriteLine(); - Console.WriteLine("Valid modes for 2-deep: 2, two, rvx, romvaultx, romroot"); - Console.WriteLine("Valid modes for 4-deep: 4, four, romba, depot"); - } - - /// - /// Process a given directory in the requested way - /// - /// True to get the 4-deep path, false to get the 2-deep path - /// Directory to process - private static void ProcessFolder(bool fourdeep, string directory) - { - Console.WriteLine($"Traversing {directory} and rebuilding as {(fourdeep ? "Romba depot" : "RVX RomRoot")}"); - foreach (string file in Directory.EnumerateFiles(directory, "*", SearchOption.AllDirectories)) - { - Console.WriteLine($"Processing {file}"); - - // Get relevant parts of the path - string oldDir = Path.GetDirectoryName(file); - string current = oldDir.Substring(directory.Length); - string filename = Path.GetFileName(file); - - // Make sure subdirectory ends with a directory separator - if (!current.EndsWith("\\")) - current += "\\"; - - // Get the expected new subdirectory - string expected = GetSubdirectory(filename, fourdeep); - - // If we have a match between current and expected, don't do anything - if (string.Equals(current, expected, StringComparison.OrdinalIgnoreCase)) - { - Console.WriteLine($"{file} already in the right directory!"); - continue; - } - - // Get the new full path to the output directory - string subdirectory = Path.Combine(directory, expected); - - // Make sure subdirectory ends with a directory separator - if (!subdirectory.EndsWith("\\")) - subdirectory += "\\"; - - // If the directory doesn't exist, create it - if (!Directory.Exists(subdirectory)) - { - try - { - Console.WriteLine($"Creating {subdirectory}"); - Directory.CreateDirectory(subdirectory); - } - catch (Exception ex) - { - Console.WriteLine($"An exception occurred while creating {subdirectory}: {ex}"); - continue; - } - - } - - // Now move the file accordingly - try - { - Console.WriteLine($"Moving {filename}"); - File.Move(file, Path.Combine(subdirectory, filename)); - } - catch (Exception ex) - { - Console.WriteLine($"An exception occurred while moving {filename}: {ex}"); - continue; - } - - // If the old path is a subset of the new path and it's empty, remove it - if (current.Contains(expected) && Directory.EnumerateFiles(oldDir, "*", SearchOption.AllDirectories).Any()) - { - try - { - Console.WriteLine($"Removing {oldDir}"); - Directory.Delete(oldDir); - } - catch (Exception ex) - { - Console.WriteLine($"An exception occurred while removing {oldDir}: {ex}"); - continue; - } - } - } - } - - /// - /// Get the expected subdirectory path for a given file path - /// - /// Filename to get subdirectory for - /// True to get the 4-deep path, false to get the 2-deep path - /// String representing the subdirectory, null on error - private static string GetSubdirectory(string filename, bool fourdeep) - { - // If we don't have a long enough filename, return null - if (fourdeep && filename.Length < 8) - return null; - else if (!fourdeep && filename.Length < 4) - return null; - - // Otherwise, get the proper value - if (fourdeep) - return $"{filename.Substring(0, 2)}\\{filename.Substring(2, 2)}\\{filename.Substring(4, 2)}\\{filename.Substring(6, 2)}\\"; - else - return $"{filename.Substring(0, 2)}\\{filename.Substring(2, 2)}\\"; + Console.WriteLine("Special modes for 2-deep: rvx, romvaultx, romroot"); + Console.WriteLine("Special modes for 4-deep: romba, depot"); + Console.WriteLine("All other positive numbers are allowed"); } } } diff --git a/TwoFour.csproj b/TwoFour.csproj index 89729bc..0b1ca60 100644 --- a/TwoFour.csproj +++ b/TwoFour.csproj @@ -43,6 +43,7 @@ +