From e3482c1d9b7092d214170a7c59f596ab40b2fb57 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 18 Aug 2020 12:58:41 -0700 Subject: [PATCH] Complete rewrite after 3 years --- Program.cs | 221 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 158 insertions(+), 63 deletions(-) diff --git a/Program.cs b/Program.cs index 9429907..2cfbe7f 100644 --- a/Program.cs +++ b/Program.cs @@ -1,78 +1,173 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; namespace TwoFour { - class Program - { - static void Main(string[] args) - { - Console.WriteLine("Getting list of all files"); - List files = Directory.EnumerateFiles(Environment.CurrentDirectory, "*", SearchOption.AllDirectories).ToList(); + public class Program + { + public static void Main(string[] args) + { + // If we don't have the right inputs, show help and exit + if (args.Length != 2) + { + Console.WriteLine("Exactly 2 arguments are required"); + DisplayHelp(); + return; + } - Console.WriteLine("Moving all files to main folder"); - foreach (string file in files) - { - try - { - File.Move(file, Path.GetFileName(file)); - } - catch { } - } + // 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; - Console.WriteLine("Clean up all old directories"); - List olddirs = Directory.EnumerateDirectories(Environment.CurrentDirectory, "*", SearchOption.TopDirectoryOnly).ToList(); - foreach (string dir in olddirs) - { - try - { - Directory.Delete(dir, true); - } - catch { } - } + // If neither matched, show help and exit + if (fourdeep == null) + { + Console.WriteLine($"{args[0]} is not a valid flag"); + DisplayHelp(); + return; + } - Console.WriteLine("Get the new list of files from the current directory"); - files = Directory.EnumerateFiles(Environment.CurrentDirectory, "*", SearchOption.TopDirectoryOnly).ToList(); - Console.WriteLine("files.Count: " + files.Count); + // Get processing folder from second arg + string directory = args[1]; + try + { + // Get the full path for processing + directory = Path.GetFullPath(directory); + if (!Directory.Exists(directory)) + throw new DirectoryNotFoundException(); - Console.WriteLine("Now naively sort based on the current asked type: " + (args.Length > 0 ? args[0] : "4")); - foreach (string file in files) - { - string newdir = ""; - string filename = Path.GetFileName(file); + // Make sure it ends with a directory separator + if (!directory.EndsWith("\\")) + directory += "\\"; + } + catch + { + Console.WriteLine($"{directory} is not a valid directory"); + DisplayHelp(); + return; + } - Console.WriteLine("file: " + filename); - if (filename == "TwoFour.exe" || filename.Contains(".romba")) - { - continue; - } + // Now that we have both, run the processing accordingly + ProcessFolder(fourdeep.Value, directory); + } - if (args.Length > 0 && args[0] == "2") - { - newdir = Path.Combine(filename.Substring(0, 2), filename.Substring(2, 2)); - } - else - { - newdir = Path.Combine(filename.Substring(0, 2), filename.Substring(2, 2), filename.Substring(4, 2), filename.Substring(6, 2)); - } + /// + /// Display the help text + /// + private static void DisplayHelp() + { + 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"); + } - Console.WriteLine("newdir: " + newdir); + /// + /// 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}"); - if (newdir != "") - { - try - { - if (!Directory.Exists(newdir)) - { - Directory.CreateDirectory(newdir); - } - File.Move(file, Path.Combine(newdir, filename)); - } - catch { } - } - } - } - } + // 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)}\\"; + } + } }