diff --git a/SabreTools.Helper/Tools/ArchiveTools.cs b/SabreTools.Helper/Tools/ArchiveTools.cs index 4a5036a4..8a33a75a 100644 --- a/SabreTools.Helper/Tools/ArchiveTools.cs +++ b/SabreTools.Helper/Tools/ArchiveTools.cs @@ -44,11 +44,11 @@ namespace SabreTools.Helper.Tools /// Attempt to extract a file as an archive /// /// Name of the file to be extracted - /// Temporary directory for archive extraction + /// Output directory for archive extraction /// ArchiveScanLevel representing the archive handling levels /// Logger object for file and console output /// True if the extraction was a success, false otherwise - public static bool ExtractArchive(string input, string tempDir, ArchiveScanLevel archiveScanLevel, Logger logger) + public static bool ExtractArchive(string input, string outDir, ArchiveScanLevel archiveScanLevel, Logger logger) { bool encounteredErrors = true; @@ -69,13 +69,13 @@ namespace SabreTools.Helper.Tools logger.Verbose("Found archive of type: " + at); // Create the temp directory - Directory.CreateDirectory(tempDir); + Directory.CreateDirectory(outDir); // Extract all files to the temp directory SevenZipArchive sza = SevenZipArchive.Open(File.OpenRead(input)); foreach (SevenZipArchiveEntry entry in sza.Entries) { - entry.WriteToDirectory(tempDir, new ExtractionOptions{ PreserveFileTime = true, ExtractFullPath = true, Overwrite = true }); + entry.WriteToDirectory(outDir, new ExtractionOptions{ PreserveFileTime = true, ExtractFullPath = true, Overwrite = true }); } encounteredErrors = false; sza.Dispose(); @@ -87,10 +87,10 @@ namespace SabreTools.Helper.Tools logger.Verbose("Found archive of type: " + at); // Create the temp directory - Directory.CreateDirectory(tempDir); + Directory.CreateDirectory(outDir); // Decompress the input stream - FileStream outstream = File.Create(Path.Combine(tempDir, Path.GetFileNameWithoutExtension(input))); + FileStream outstream = File.Create(Path.Combine(outDir, Path.GetFileNameWithoutExtension(input))); GZipStream gzstream = new GZipStream(File.OpenRead(input), CompressionMode.Decompress); gzstream.CopyTo(outstream); @@ -107,13 +107,13 @@ namespace SabreTools.Helper.Tools logger.Verbose("Found archive of type: " + at); // Create the temp directory - Directory.CreateDirectory(tempDir); + Directory.CreateDirectory(outDir); // Extract all files to the temp directory RarArchive ra = RarArchive.Open(input); foreach (RarArchiveEntry entry in ra.Entries) { - entry.WriteToDirectory(tempDir, new ExtractionOptions { PreserveFileTime = true, ExtractFullPath = true, Overwrite = true }); + entry.WriteToDirectory(outDir, new ExtractionOptions { PreserveFileTime = true, ExtractFullPath = true, Overwrite = true }); } encounteredErrors = false; ra.Dispose(); @@ -125,13 +125,13 @@ namespace SabreTools.Helper.Tools logger.Verbose("Found archive of type: " + at); // Create the temp directory - Directory.CreateDirectory(tempDir); + Directory.CreateDirectory(outDir); // Extract all files to the temp directory TarArchive ta = TarArchive.Open(input); foreach (TarArchiveEntry entry in ta.Entries) { - entry.WriteToDirectory(tempDir, new ExtractionOptions { PreserveFileTime = true, ExtractFullPath = true, Overwrite = true }); + entry.WriteToDirectory(outDir, new ExtractionOptions { PreserveFileTime = true, ExtractFullPath = true, Overwrite = true }); } encounteredErrors = false; ta.Dispose(); @@ -143,7 +143,7 @@ namespace SabreTools.Helper.Tools logger.Verbose("Found archive of type: " + at); // Create the temp directory - Directory.CreateDirectory(tempDir); + Directory.CreateDirectory(outDir); // Extract all files to the temp directory ZipFile zf = new ZipFile(); @@ -166,7 +166,7 @@ namespace SabreTools.Helper.Tools // Create the rest of the path, if needed if (!String.IsNullOrEmpty(Path.GetDirectoryName(zf.Entries[i].FileName))) { - Directory.CreateDirectory(Path.Combine(tempDir, Path.GetDirectoryName(zf.Entries[i].FileName))); + Directory.CreateDirectory(Path.Combine(outDir, Path.GetDirectoryName(zf.Entries[i].FileName))); } // If the entry ends with a directory separator, continue to the next item, if any @@ -177,7 +177,7 @@ namespace SabreTools.Helper.Tools continue; } - FileStream writeStream = File.OpenWrite(Path.Combine(tempDir, zf.Entries[i].FileName)); + FileStream writeStream = File.OpenWrite(Path.Combine(outDir, zf.Entries[i].FileName)); byte[] ibuffer = new byte[_bufferSize]; int ilen; @@ -971,7 +971,7 @@ namespace SabreTools.Helper.Tools } /// - /// Write a set of input files to a torrent7z archive (assuming the same output archive name) + /// (UNIMPLEMENTED) Write a set of input files to a torrent7z archive (assuming the same output archive name) /// /// Input filenames to be moved /// Output directory to build to @@ -1060,7 +1060,7 @@ namespace SabreTools.Helper.Tools // If we're in romba mode, create the subfolder and move the file if (romba) { - MoveToRombaFolder(rom, outDir, outfile, logger); + FileTools.MoveToRombaFolder(rom, outDir, outfile, logger); } return true; @@ -1087,7 +1087,7 @@ namespace SabreTools.Helper.Tools } /// - /// Write a set of input files to a torrentlrzip archive (assuming the same output archive name) + /// (UNIMPLEMENTED) Write a set of input files to a torrentlrzip archive (assuming the same output archive name) /// /// Input filenames to be moved /// Output directory to build to @@ -1121,7 +1121,7 @@ namespace SabreTools.Helper.Tools } /// - /// Write a set of input files to a torrentrar archive (assuming the same output archive name) + /// (UNIMPLEMENTED) Write a set of input files to a torrentrar archive (assuming the same output archive name) /// /// Input filenames to be moved /// Output directory to build to @@ -1155,7 +1155,7 @@ namespace SabreTools.Helper.Tools } /// - /// Write a set of input files to a torrentxz archive (assuming the same output archive name) + /// (UNIMPLEMENTED) Write a set of input files to a torrentxz archive (assuming the same output archive name) /// /// Input filenames to be moved /// Output directory to build to @@ -1418,44 +1418,6 @@ namespace SabreTools.Helper.Tools return true; } - /// - /// Get the romba path for a file based on the rom's SHA-1 - /// - /// Rom to get the sha1 from - /// Base output folder - /// Formatted path string to use - public static string GetRombaPath(Rom rom, string baseOutDir) - { - string subfolder = Path.Combine(rom.SHA1.Substring(0, 2), rom.SHA1.Substring(2, 2), rom.SHA1.Substring(4, 2), rom.SHA1.Substring(6, 2)); - return Path.Combine(baseOutDir, subfolder); - } - - /// - /// Move a file to a named, Romba-style subdirectory - /// - /// Rom to get the sha1 from - /// Base output folder - /// Name of the file to be moved - /// Logger object for file and console output - public static void MoveToRombaFolder(Rom rom, string baseOutDir, string filename, Logger logger) - { - string outDir = GetRombaPath(rom, baseOutDir); - if (!Directory.Exists(outDir)) - { - Directory.CreateDirectory(outDir); - } - - try - { - File.Move(filename, Path.Combine(outDir, Path.GetFileName(filename))); - } - catch (Exception ex) - { - logger.Warning(ex.ToString()); - File.Delete(filename); - } - } - #endregion } } diff --git a/SabreTools.Helper/Tools/DatabaseTools.cs b/SabreTools.Helper/Tools/DatabaseTools.cs index 1adb6210..5e9da2bd 100644 --- a/SabreTools.Helper/Tools/DatabaseTools.cs +++ b/SabreTools.Helper/Tools/DatabaseTools.cs @@ -1,5 +1,6 @@ using Mono.Data.Sqlite; using System; +using System.Collections.Generic; using SabreTools.Helper.Data; @@ -27,6 +28,9 @@ namespace SabreTools.Helper.Tools { bool exists = false; + // Ensure the database exists + EnsureDatabase(Constants.HeadererDbSchema, Constants.HeadererFileName, Constants.HeadererConnectionString); + // Open the database connection SqliteConnection dbc = new SqliteConnection(Constants.HeadererConnectionString); dbc.Open(); @@ -153,5 +157,48 @@ CREATE TABLE IF NOT EXISTS data ( dbc.Dispose(); } } + + /// + /// Retrieve headers from the database + /// + /// SHA-1 of the deheadered file + /// Logger object for console and file output + /// List of strings representing the headers to add + public static List RetrieveHeadersFromDatabase(string SHA1, Logger logger) + { + // Ensure the database exists + EnsureDatabase(Constants.HeadererDbSchema, Constants.HeadererFileName, Constants.HeadererConnectionString); + + // Open the database connection + SqliteConnection dbc = new SqliteConnection(Constants.HeadererConnectionString); + dbc.Open(); + + // Create the output list of headers + List headers = new List(); + + string query = @"SELECT header, type FROM data WHERE sha1='" + SHA1 + "'"; + SqliteCommand slc = new SqliteCommand(query, dbc); + SqliteDataReader sldr = slc.ExecuteReader(); + + if (sldr.HasRows) + { + while (sldr.Read()) + { + logger.Verbose("Found match with rom type " + sldr.GetString(1)); + headers.Add(sldr.GetString(0)); + } + } + else + { + logger.Warning("No matching header could be found!"); + } + + // Dispose of database objects + slc.Dispose(); + sldr.Dispose(); + dbc.Dispose(); + + return headers; + } } } diff --git a/SabreTools.Helper/Tools/FileTools.cs b/SabreTools.Helper/Tools/FileTools.cs index d9cacb79..a025098d 100644 --- a/SabreTools.Helper/Tools/FileTools.cs +++ b/SabreTools.Helper/Tools/FileTools.cs @@ -231,34 +231,6 @@ namespace SabreTools.Helper.Tools #region File Manipulation - /// - /// Get the XmlTextReader associated with a file, if possible - /// - /// Name of the file to be parsed - /// Logger object for console and file output - /// The XmlTextReader representing the (possibly converted) file, null otherwise - public static XmlReader GetXmlTextReader(string filename, Logger logger) - { - logger.Verbose("Attempting to read file: \"" + filename + "\""); - - // Check if file exists - if (!File.Exists(filename)) - { - logger.Warning("File '" + filename + "' could not read from!"); - return null; - } - - XmlReader xtr = XmlReader.Create(filename, new XmlReaderSettings { - CheckCharacters = false, - DtdProcessing = DtdProcessing.Ignore, - IgnoreComments = true, - IgnoreWhitespace = true, - ValidationFlags = XmlSchemaValidationFlags.None, - ValidationType = ValidationType.None, - }); - return xtr; - } - /// /// Add an aribtrary number of bytes to the inputted file /// @@ -307,6 +279,30 @@ namespace SabreTools.Helper.Tools fsw.Dispose(); } + /// + /// Cleans out the temporary directory + /// + /// Name of the directory to clean out + public static void CleanDirectory(string dirname) + { + foreach (string file in Directory.EnumerateFiles(dirname, "*", SearchOption.TopDirectoryOnly)) + { + try + { + File.Delete(file); + } + catch { } + } + foreach (string dir in Directory.EnumerateDirectories(dirname, "*", SearchOption.TopDirectoryOnly)) + { + try + { + Directory.Delete(dir, true); + } + catch { } + } + } + /// /// Detect header skipper compliance and create an output file /// @@ -364,6 +360,133 @@ namespace SabreTools.Helper.Tools return true; } + /// + /// Retrieve a list of just files from inputs + /// + /// List of strings representing directories and files + /// Integer representing the maximum amount of parallelization to be used + /// Logger object for file and console output + /// True if the parent name should be appended after the special character "¬", false otherwise + /// List of strings representing just files from the inputs + public static List GetOnlyFilesFromInputs(List inputs, int maxDegreeOfParallelism, Logger logger, bool appendparent = false) + { + List outputs = new List(); + Parallel.ForEach(inputs, + new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism, }, + input => + { + if (Directory.Exists(input)) + { + List files = FileTools.RetrieveFiles(input, new List()); + foreach (string file in files) + { + try + { + lock (outputs) + { + outputs.Add(Path.GetFullPath(file) + (appendparent ? "¬" + Path.GetFullPath(input) : "")); + } + } + catch (PathTooLongException) + { + logger.Warning("The path for " + file + " was too long"); + } + catch (Exception ex) + { + logger.Error(ex.ToString()); + } + } + } + else if (File.Exists(input)) + { + try + { + lock (outputs) + { + outputs.Add(Path.GetFullPath(input) + (appendparent ? "¬" + Path.GetFullPath(input) : "")); + } + } + catch (PathTooLongException) + { + logger.Warning("The path for " + input + " was too long"); + } + catch (Exception ex) + { + logger.Error(ex.ToString()); + } + } + }); + + return outputs; + } + + /// + /// Get the romba path for a file based on the rom's SHA-1 + /// + /// Rom to get the sha1 from + /// Base output folder + /// Formatted path string to use + public static string GetRombaPath(Rom rom, string baseOutDir) + { + string subfolder = Path.Combine(rom.SHA1.Substring(0, 2), rom.SHA1.Substring(2, 2), rom.SHA1.Substring(4, 2), rom.SHA1.Substring(6, 2)); + return Path.Combine(baseOutDir, subfolder); + } + + /// + /// Get the XmlTextReader associated with a file, if possible + /// + /// Name of the file to be parsed + /// Logger object for console and file output + /// The XmlTextReader representing the (possibly converted) file, null otherwise + public static XmlReader GetXmlTextReader(string filename, Logger logger) + { + logger.Verbose("Attempting to read file: \"" + filename + "\""); + + // Check if file exists + if (!File.Exists(filename)) + { + logger.Warning("File '" + filename + "' could not read from!"); + return null; + } + + XmlReader xtr = XmlReader.Create(filename, new XmlReaderSettings + { + CheckCharacters = false, + DtdProcessing = DtdProcessing.Ignore, + IgnoreComments = true, + IgnoreWhitespace = true, + ValidationFlags = XmlSchemaValidationFlags.None, + ValidationType = ValidationType.None, + }); + return xtr; + } + + /// + /// Move a file to a named, Romba-style subdirectory + /// + /// Rom to get the sha1 from + /// Base output folder + /// Name of the file to be moved + /// Logger object for file and console output + public static void MoveToRombaFolder(Rom rom, string baseOutDir, string filename, Logger logger) + { + string outDir = GetRombaPath(rom, baseOutDir); + if (!Directory.Exists(outDir)) + { + Directory.CreateDirectory(outDir); + } + + try + { + File.Move(filename, Path.Combine(outDir, Path.GetFileName(filename))); + } + catch (Exception ex) + { + logger.Warning(ex.ToString()); + File.Delete(filename); + } + } + /// /// Detect and replace header(s) to the given file /// @@ -379,133 +502,29 @@ namespace SabreTools.Helper.Tools Directory.CreateDirectory(outDir); } - bool success = true; - // First, get the SHA-1 hash of the file Rom rom = GetFileInfo(file, logger); - // Then try to pull the corresponding headers from the database - string header = ""; + // Retrieve a list of all related headers from the database + List headers = DatabaseTools.RetrieveHeadersFromDatabase(rom.SHA1, logger); - // Open the database connection - SqliteConnection dbc = new SqliteConnection(Constants.HeadererConnectionString); - dbc.Open(); - - string query = @"SELECT header, type FROM data WHERE sha1='" + rom.SHA1 + "'"; - SqliteCommand slc = new SqliteCommand(query, dbc); - SqliteDataReader sldr = slc.ExecuteReader(); - - if (sldr.HasRows) + // If we have nothing retrieved, we return false + if (headers.Count == 0) { - int sub = 0; - while (sldr.Read()) - { - logger.Verbose("Found match with rom type " + sldr.GetString(1)); - header = sldr.GetString(0); - - logger.User("Creating reheadered file: " + - (outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file))) + sub); - AppendBytesToFile(file, - (outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file))) + sub, header, string.Empty); - logger.User("Reheadered file created!"); - } - } - else - { - logger.Warning("No matching header could be found!"); - success = false; + return false; } - // Dispose of database objects - slc.Dispose(); - sldr.Dispose(); - dbc.Dispose(); - - return success; - } - - /// - /// Cleans out the temporary directory - /// - /// Name of the directory to clean out - public static void CleanDirectory(string dirname) - { - foreach (string file in Directory.EnumerateFiles(dirname, "*", SearchOption.TopDirectoryOnly)) + // Now loop through and create the reheadered files, if possible + for (int i = 0; i < headers.Count; i++) { - try - { - File.Delete(file); - } - catch { } + logger.User("Creating reheadered file: " + + (outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file))) + i); + AppendBytesToFile(file, + (outDir == "" ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file))) + i, headers[i], string.Empty); + logger.User("Reheadered file created!"); } - foreach (string dir in Directory.EnumerateDirectories(dirname, "*", SearchOption.TopDirectoryOnly)) - { - try - { - Directory.Delete(dir, true); - } - catch { } - } - } - /// - /// Retrieve a list of just files from inputs - /// - /// List of strings representing directories and files - /// Integer representing the maximum amount of parallelization to be used - /// Logger object for file and console output - /// True if the parent name should be appended after the special character "¬", false otherwise - /// List of strings representing just files from the inputs - public static List GetOnlyFilesFromInputs(List inputs, int maxDegreeOfParallelism, Logger logger, bool appendparent = false) - { - List outputs = new List(); - Parallel.ForEach(inputs, - new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism, }, - input => - { - if (Directory.Exists(input)) - { - List files = FileTools.RetrieveFiles(input, new List()); - foreach (string file in files) - { - try - { - lock (outputs) - { - outputs.Add(Path.GetFullPath(file) + (appendparent ? "¬" + Path.GetFullPath(input) : "")); - } - } - catch (PathTooLongException) - { - logger.Warning("The path for " + file + " was too long"); - } - catch (Exception ex) - { - logger.Error(ex.ToString()); - } - } - } - else if (File.Exists(input)) - { - try - { - lock (outputs) - { - outputs.Add(Path.GetFullPath(input) + (appendparent ? "¬" + Path.GetFullPath(input) : "")); - } - } - catch (PathTooLongException) - { - logger.Warning("The path for " + input + " was too long"); - } - catch (Exception ex) - { - logger.Error(ex.ToString()); - } - } - }); - - return outputs; + return true; } #endregion diff --git a/SabreTools/SabreTools.cs b/SabreTools/SabreTools.cs index f49643de..1c612479 100644 --- a/SabreTools/SabreTools.cs +++ b/SabreTools/SabreTools.cs @@ -36,7 +36,6 @@ namespace SabreTools Console.Clear(); } Build.Start("SabreTools"); - DatabaseTools.EnsureDatabase(Constants.HeadererDbSchema, Constants.HeadererFileName, Constants.HeadererConnectionString); // Credits take precidence over all if ((new List(args)).Contains("--credits"))