Files
SabreTools/RombaSharp/Features/Archive.cs

202 lines
8.2 KiB
C#
Raw Normal View History

2020-08-01 13:25:32 -07:00
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SabreTools.DatFiles;
2020-12-08 15:15:41 -08:00
using SabreTools.DatItems;
2020-12-10 23:24:09 -08:00
using SabreTools.DatTools;
using SabreTools.FileTypes;
2020-12-07 13:57:26 -08:00
using SabreTools.Help;
2020-08-01 13:25:32 -07:00
using Microsoft.Data.Sqlite;
namespace RombaSharp.Features
{
internal class Archive : BaseFeature
{
public const string Value = "Archive";
public Archive()
{
Name = Value;
Flags = new List<string>() { "archive" };
Description = "Adds ROM files from the specified directories to the ROM archive.";
2020-12-07 13:57:26 -08:00
_featureType = ParameterType.Flag;
2020-08-01 13:25:32 -07:00
LongDescription = @"Adds ROM files from the specified directories to the ROM archive.
Traverses the specified directory trees looking for zip files and normal files.
Unpacked files will be stored as individual entries. Prior to unpacking a zip
file, the external SHA1 is checked against the DAT index.
If -only-needed is set, only those files are put in the ROM archive that
have a current entry in the DAT index.";
2020-12-07 13:57:26 -08:00
Features = new Dictionary<string, SabreTools.Help.Feature>();
2020-08-01 13:25:32 -07:00
AddFeature(OnlyNeededFlag);
AddFeature(ResumeStringInput);
AddFeature(IncludeZipsInt32Input); // Defaults to 0
AddFeature(WorkersInt32Input);
AddFeature(IncludeGZipsInt32Input); // Defaults to 0
AddFeature(Include7ZipsInt32Input); // Defaults to 0
AddFeature(SkipInitialScanFlag);
AddFeature(UseGolangZipFlag);
AddFeature(NoDbFlag);
}
2020-12-07 13:57:26 -08:00
public override void ProcessFeatures(Dictionary<string, SabreTools.Help.Feature> features)
2020-08-01 13:25:32 -07:00
{
base.ProcessFeatures(features);
// Get the archive scanning level
// TODO: Remove usage
int sevenzip = GetInt32(features, Include7ZipsInt32Value);
int gz = GetInt32(features, IncludeGZipsInt32Value);
int zip = GetInt32(features, IncludeZipsInt32Value);
// Get feature flags
bool noDb = GetBoolean(features, NoDbValue);
bool onlyNeeded = GetBoolean(features, OnlyNeededValue);
// First we want to get just all directories from the inputs
List<string> onlyDirs = new List<string>();
foreach (string input in Inputs)
{
if (Directory.Exists(input))
onlyDirs.Add(Path.GetFullPath(input));
}
// Then process all of the input directories into an internal DAT
DatFile df = DatFile.Create();
foreach (string dir in onlyDirs)
{
2020-12-10 15:42:39 -08:00
DatFromDir.PopulateFromDir(df, dir, asFiles: TreatAsFile.NonArchive);
DatFromDir.PopulateFromDir(df, dir, asFiles: TreatAsFile.All);
2020-08-01 13:25:32 -07:00
}
// Create an empty Dat for files that need to be rebuilt
DatFile need = DatFile.Create();
// Open the database connection
SqliteConnection dbc = new SqliteConnection(_connectionString);
dbc.Open();
// Now that we have the Dats, add the files to the database
string crcquery = "INSERT OR IGNORE INTO crc (crc) VALUES";
string md5query = "INSERT OR IGNORE INTO md5 (md5) VALUES";
string sha1query = "INSERT OR IGNORE INTO sha1 (sha1, depot) VALUES";
string crcsha1query = "INSERT OR IGNORE INTO crcsha1 (crc, sha1) VALUES";
string md5sha1query = "INSERT OR IGNORE INTO md5sha1 (md5, sha1) VALUES";
foreach (string key in df.Items.Keys)
{
List<DatItem> datItems = df.Items[key];
foreach (Rom rom in datItems)
{
// If we care about if the file exists, check the databse first
if (onlyNeeded && !noDb)
{
string query = "SELECT * FROM crcsha1 JOIN md5sha1 ON crcsha1.sha1=md5sha1.sha1"
+ $" WHERE crcsha1.crc=\"{rom.CRC}\""
+ $" OR md5sha1.md5=\"{rom.MD5}\""
+ $" OR md5sha1.sha1=\"{rom.SHA1}\"";
SqliteCommand slc = new SqliteCommand(query, dbc);
SqliteDataReader sldr = slc.ExecuteReader();
if (sldr.HasRows)
{
// Add to the queries
if (!string.IsNullOrWhiteSpace(rom.CRC))
crcquery += $" (\"{rom.CRC}\"),";
if (!string.IsNullOrWhiteSpace(rom.MD5))
md5query += $" (\"{rom.MD5}\"),";
if (!string.IsNullOrWhiteSpace(rom.SHA1))
{
sha1query += $" (\"{rom.SHA1}\", \"{_depots.Keys.ToList()[0]}\"),";
if (!string.IsNullOrWhiteSpace(rom.CRC))
crcsha1query += $" (\"{rom.CRC}\", \"{rom.SHA1}\"),";
if (!string.IsNullOrWhiteSpace(rom.MD5))
md5sha1query += $" (\"{rom.MD5}\", \"{rom.SHA1}\"),";
}
// Add to the Dat
need.Items.Add(key, rom);
}
}
// Otherwise, just add the file to the list
else
{
// Add to the queries
if (!noDb)
{
if (!string.IsNullOrWhiteSpace(rom.CRC))
crcquery += $" (\"{rom.CRC}\"),";
if (!string.IsNullOrWhiteSpace(rom.MD5))
md5query += $" (\"{rom.MD5}\"),";
if (!string.IsNullOrWhiteSpace(rom.SHA1))
{
sha1query += $" (\"{rom.SHA1}\", \"{_depots.Keys.ToList()[0]}\"),";
if (!string.IsNullOrWhiteSpace(rom.CRC))
crcsha1query += $" (\"{rom.CRC}\", \"{rom.SHA1}\"),";
if (!string.IsNullOrWhiteSpace(rom.MD5))
md5sha1query += $" (\"{rom.MD5}\", \"{rom.SHA1}\"),";
}
}
// Add to the Dat
need.Items.Add(key, rom);
}
}
}
// Now run the queries, if they're populated
if (crcquery != "INSERT OR IGNORE INTO crc (crc) VALUES")
{
SqliteCommand slc = new SqliteCommand(crcquery.TrimEnd(','), dbc);
slc.ExecuteNonQuery();
slc.Dispose();
}
if (md5query != "INSERT OR IGNORE INTO md5 (md5) VALUES")
{
SqliteCommand slc = new SqliteCommand(md5query.TrimEnd(','), dbc);
slc.ExecuteNonQuery();
slc.Dispose();
}
if (sha1query != "INSERT OR IGNORE INTO sha1 (sha1, depot) VALUES")
{
SqliteCommand slc = new SqliteCommand(sha1query.TrimEnd(','), dbc);
slc.ExecuteNonQuery();
slc.Dispose();
}
if (crcsha1query != "INSERT OR IGNORE INTO crcsha1 (crc, sha1) VALUES")
{
SqliteCommand slc = new SqliteCommand(crcsha1query.TrimEnd(','), dbc);
slc.ExecuteNonQuery();
slc.Dispose();
}
if (md5sha1query != "INSERT OR IGNORE INTO md5sha1 (md5, sha1) VALUES")
{
SqliteCommand slc = new SqliteCommand(md5sha1query.TrimEnd(','), dbc);
slc.ExecuteNonQuery();
slc.Dispose();
}
// Create the sorting object to use and rebuild the needed files
2020-12-10 14:31:00 -08:00
Rebuilder.RebuildGeneric(
2020-12-10 11:07:36 -08:00
need,
2020-08-02 13:44:45 -07:00
onlyDirs,
outDir: _depots.Keys.ToList()[0],
outputFormat: OutputFormat.TorrentGzipRomba,
asFiles: TreatAsFile.NonArchive);
2020-08-01 13:25:32 -07:00
}
}
}