mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Remove .NET Framework 4.6.2/4.7.2 (#24)
* Remove < .NET 4.8, general cleanup * Abstract * Tango * Banner * Scan no more * Common * Application * Access * Filter-feeder * Graffiti * Paint-over * Law and Order * XOR-o * Unused staircase * Maybe * Maybe not * Delete this * The word is "no" * Emit * Improper * Aye aye * Fence * Barrier * Monkey * Pail * Lines
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
using SabreTools.Library.Data;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
using SabreTools.Library.Data;
|
||||
using SabreTools.Library.DatItems;
|
||||
using SabreTools.Library.Reports;
|
||||
using SabreTools.Library.Tools;
|
||||
|
||||
namespace SabreTools.Library.DatFiles
|
||||
{
|
||||
@@ -24,6 +31,11 @@ namespace SabreTools.Library.DatFiles
|
||||
/// </summary>
|
||||
public StatReportFormat ReportFormat { get; set; } = StatReportFormat.None;
|
||||
|
||||
/// <summary>
|
||||
/// Statistics output file name
|
||||
/// </summary>
|
||||
public string ReportName { get; set; } = "report";
|
||||
|
||||
/// <summary>
|
||||
/// Overall item count
|
||||
/// </summary>
|
||||
@@ -80,10 +92,12 @@ namespace SabreTools.Library.DatFiles
|
||||
/// </summary>
|
||||
public long MD5Count { get; set; } = 0;
|
||||
|
||||
#if NET_FRAMEWORK
|
||||
/// <summary>
|
||||
/// Number of items with a RIPEMD160 hash
|
||||
/// </summary>
|
||||
public long RIPEMD160Count { get; set; } = 0;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Number of items with a SHA-1 hash
|
||||
@@ -129,6 +143,8 @@ namespace SabreTools.Library.DatFiles
|
||||
|
||||
#region Instance Methods
|
||||
|
||||
#region Updates
|
||||
|
||||
/// <summary>
|
||||
/// Add to the statistics given a DatItem
|
||||
/// </summary>
|
||||
@@ -155,7 +171,9 @@ namespace SabreTools.Library.DatFiles
|
||||
if (((Disk)item).ItemStatus != ItemStatus.Nodump)
|
||||
{
|
||||
this.MD5Count += (string.IsNullOrWhiteSpace(((Disk)item).MD5) ? 0 : 1);
|
||||
#if NET_FRAMEWORK
|
||||
this.RIPEMD160Count += (string.IsNullOrWhiteSpace(((Disk)item).RIPEMD160) ? 0 : 1);
|
||||
#endif
|
||||
this.SHA1Count += (string.IsNullOrWhiteSpace(((Disk)item).SHA1) ? 0 : 1);
|
||||
this.SHA256Count += (string.IsNullOrWhiteSpace(((Disk)item).SHA256) ? 0 : 1);
|
||||
this.SHA384Count += (string.IsNullOrWhiteSpace(((Disk)item).SHA384) ? 0 : 1);
|
||||
@@ -177,7 +195,9 @@ namespace SabreTools.Library.DatFiles
|
||||
this.TotalSize += ((Rom)item).Size;
|
||||
this.CRCCount += (string.IsNullOrWhiteSpace(((Rom)item).CRC) ? 0 : 1);
|
||||
this.MD5Count += (string.IsNullOrWhiteSpace(((Rom)item).MD5) ? 0 : 1);
|
||||
#if NET_FRAMEWORK
|
||||
this.RIPEMD160Count += (string.IsNullOrWhiteSpace(((Rom)item).RIPEMD160) ? 0 : 1);
|
||||
#endif
|
||||
this.SHA1Count += (string.IsNullOrWhiteSpace(((Rom)item).SHA1) ? 0 : 1);
|
||||
this.SHA256Count += (string.IsNullOrWhiteSpace(((Rom)item).SHA256) ? 0 : 1);
|
||||
this.SHA384Count += (string.IsNullOrWhiteSpace(((Rom)item).SHA384) ? 0 : 1);
|
||||
@@ -218,7 +238,9 @@ namespace SabreTools.Library.DatFiles
|
||||
// Individual hash counts
|
||||
this.CRCCount += stats.CRCCount;
|
||||
this.MD5Count += stats.MD5Count;
|
||||
#if NET_FRAMEWORK
|
||||
this.RIPEMD160Count += stats.RIPEMD160Count;
|
||||
#endif
|
||||
this.SHA1Count += stats.SHA1Count;
|
||||
this.SHA256Count += stats.SHA256Count;
|
||||
this.SHA384Count += stats.SHA384Count;
|
||||
@@ -229,7 +251,43 @@ namespace SabreTools.Library.DatFiles
|
||||
this.GoodCount += stats.GoodCount;
|
||||
this.NodumpCount += stats.NodumpCount;
|
||||
this.VerifiedCount += stats.VerifiedCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the highest-order BucketedBy value that represents the statistics
|
||||
/// </summary>
|
||||
public BucketedBy GetBestAvailable()
|
||||
{
|
||||
// If all items are supposed to have a SHA-512, we sort by that
|
||||
if (RomCount + DiskCount - NodumpCount == SHA512Count)
|
||||
return BucketedBy.SHA512;
|
||||
|
||||
// If all items are supposed to have a SHA-384, we sort by that
|
||||
else if (RomCount + DiskCount - NodumpCount == SHA384Count)
|
||||
return BucketedBy.SHA384;
|
||||
|
||||
// If all items are supposed to have a SHA-256, we sort by that
|
||||
else if (RomCount + DiskCount - NodumpCount == SHA256Count)
|
||||
return BucketedBy.SHA256;
|
||||
|
||||
// If all items are supposed to have a SHA-1, we sort by that
|
||||
else if (RomCount + DiskCount - NodumpCount == SHA1Count)
|
||||
return BucketedBy.SHA1;
|
||||
|
||||
#if NET_FRAMEWORK
|
||||
// If all items are supposed to have a RIPEMD160, we sort by that
|
||||
else if (RomCount + DiskCount - NodumpCount == RIPEMD160Count)
|
||||
return BucketedBy.RIPEMD160;
|
||||
#endif
|
||||
|
||||
// If all items are supposed to have a MD5, we sort by that
|
||||
else if (RomCount + DiskCount - NodumpCount == MD5Count)
|
||||
return BucketedBy.MD5;
|
||||
|
||||
// Otherwise, we sort by CRC
|
||||
else
|
||||
return BucketedBy.CRC;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove from the statistics given a DatItem
|
||||
@@ -257,7 +315,9 @@ namespace SabreTools.Library.DatFiles
|
||||
if (((Disk)item).ItemStatus != ItemStatus.Nodump)
|
||||
{
|
||||
this.MD5Count -= (string.IsNullOrWhiteSpace(((Disk)item).MD5) ? 0 : 1);
|
||||
#if NET_FRAMEWORK
|
||||
this.RIPEMD160Count -= (string.IsNullOrWhiteSpace(((Disk)item).RIPEMD160) ? 0 : 1);
|
||||
#endif
|
||||
this.SHA1Count -= (string.IsNullOrWhiteSpace(((Disk)item).SHA1) ? 0 : 1);
|
||||
this.SHA256Count -= (string.IsNullOrWhiteSpace(((Disk)item).SHA256) ? 0 : 1);
|
||||
this.SHA384Count -= (string.IsNullOrWhiteSpace(((Disk)item).SHA384) ? 0 : 1);
|
||||
@@ -279,7 +339,9 @@ namespace SabreTools.Library.DatFiles
|
||||
this.TotalSize -= ((Rom)item).Size;
|
||||
this.CRCCount -= (string.IsNullOrWhiteSpace(((Rom)item).CRC) ? 0 : 1);
|
||||
this.MD5Count -= (string.IsNullOrWhiteSpace(((Rom)item).MD5) ? 0 : 1);
|
||||
#if NET_FRAMEWORK
|
||||
this.RIPEMD160Count -= (string.IsNullOrWhiteSpace(((Rom)item).RIPEMD160) ? 0 : 1);
|
||||
#endif
|
||||
this.SHA1Count -= (string.IsNullOrWhiteSpace(((Rom)item).SHA1) ? 0 : 1);
|
||||
this.SHA256Count -= (string.IsNullOrWhiteSpace(((Rom)item).SHA256) ? 0 : 1);
|
||||
this.SHA384Count -= (string.IsNullOrWhiteSpace(((Rom)item).SHA384) ? 0 : 1);
|
||||
@@ -318,7 +380,9 @@ namespace SabreTools.Library.DatFiles
|
||||
|
||||
this.CRCCount = 0;
|
||||
this.MD5Count = 0;
|
||||
#if NET_FRAMEWORK
|
||||
this.RIPEMD160Count = 0;
|
||||
#endif
|
||||
this.SHA1Count = 0;
|
||||
this.SHA256Count = 0;
|
||||
this.SHA384Count = 0;
|
||||
@@ -330,6 +394,210 @@ namespace SabreTools.Library.DatFiles
|
||||
this.VerifiedCount = 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Writing
|
||||
|
||||
/// <summary>
|
||||
/// Output the stats for a list of input dats as files in a human-readable format
|
||||
/// </summary>
|
||||
/// <param name="inputs">List of input files and folders</param>
|
||||
/// <param name="reportName">Name of the output file</param>
|
||||
/// <param name="single">True if single DAT stats are output, false otherwise</param>
|
||||
/// <param name="baddumpCol">True if baddumps should be included in output, false otherwise</param>
|
||||
/// <param name="nodumpCol">True if nodumps should be included in output, false otherwise</param>
|
||||
/// <param name="statDatFormat" > Set the statistics output format to use</param>
|
||||
public static void OutputStats(List<string> inputs, string reportName, string outDir, bool single,
|
||||
bool baddumpCol, bool nodumpCol, StatReportFormat statDatFormat)
|
||||
{
|
||||
// If there's no output format, set the default
|
||||
if (statDatFormat == StatReportFormat.None)
|
||||
statDatFormat = StatReportFormat.Textfile;
|
||||
|
||||
// Get the proper output file name
|
||||
if (string.IsNullOrWhiteSpace(reportName))
|
||||
reportName = "report";
|
||||
|
||||
// Get the proper output directory name
|
||||
outDir = DirectoryExtensions.Ensure(outDir);
|
||||
|
||||
// Get the dictionary of desired output report names
|
||||
Dictionary<StatReportFormat, string> outputs = DatStats.CreateOutStatsNames(outDir, statDatFormat, reportName);
|
||||
|
||||
// Make sure we have all files and then order them
|
||||
List<string> files = DirectoryExtensions.GetFilesOnly(inputs);
|
||||
files = files
|
||||
.OrderBy(i => Path.GetDirectoryName(i))
|
||||
.ThenBy(i => Path.GetFileName(i))
|
||||
.ToList();
|
||||
|
||||
// Get all of the writers that we need
|
||||
List<BaseReport> reports = outputs.Select(kvp => BaseReport.Create(kvp.Key, kvp.Value, baddumpCol, nodumpCol)).ToList();
|
||||
|
||||
// Write the header, if any
|
||||
reports.ForEach(report => report.WriteHeader());
|
||||
|
||||
// Init all total variables
|
||||
DatStats totalStats = new DatStats();
|
||||
|
||||
// Init directory-level variables
|
||||
string lastdir = null;
|
||||
string basepath = null;
|
||||
DatStats dirStats = new DatStats();
|
||||
|
||||
// Now process each of the input files
|
||||
foreach (string file in files)
|
||||
{
|
||||
// Get the directory for the current file
|
||||
string thisdir = Path.GetDirectoryName(file);
|
||||
basepath = Path.GetDirectoryName(Path.GetDirectoryName(file));
|
||||
|
||||
// If we don't have the first file and the directory has changed, show the previous directory stats and reset
|
||||
if (lastdir != null && thisdir != lastdir)
|
||||
{
|
||||
// Output separator if needed
|
||||
reports.ForEach(report => report.WriteMidSeparator());
|
||||
|
||||
DatFile lastdirdat = DatFile.Create();
|
||||
|
||||
reports.ForEach(report => report.ReplaceStatistics($"DIR: {WebUtility.HtmlEncode(lastdir)}", dirStats.GameCount, dirStats));
|
||||
reports.ForEach(report => report.Write());
|
||||
|
||||
// Write the mid-footer, if any
|
||||
reports.ForEach(report => report.WriteFooterSeparator());
|
||||
|
||||
// Write the header, if any
|
||||
reports.ForEach(report => report.WriteMidHeader());
|
||||
|
||||
// Reset the directory stats
|
||||
dirStats.Reset();
|
||||
}
|
||||
|
||||
Globals.Logger.Verbose($"Beginning stat collection for '{file}'", false);
|
||||
List<string> games = new List<string>();
|
||||
DatFile datdata = DatFile.CreateAndParse(file);
|
||||
datdata.BucketBy(BucketedBy.Game, DedupeType.None, norename: true);
|
||||
|
||||
// Output single DAT stats (if asked)
|
||||
Globals.Logger.User($"Adding stats for file '{file}'\n", false);
|
||||
if (single)
|
||||
{
|
||||
reports.ForEach(report => report.ReplaceStatistics(datdata.DatHeader.FileName, datdata.Keys.Count, datdata.DatStats));
|
||||
reports.ForEach(report => report.Write());
|
||||
}
|
||||
|
||||
// Add single DAT stats to dir
|
||||
dirStats.AddStats(datdata.DatStats);
|
||||
dirStats.GameCount += datdata.Keys.Count();
|
||||
|
||||
// Add single DAT stats to totals
|
||||
totalStats.AddStats(datdata.DatStats);
|
||||
totalStats.GameCount += datdata.Keys.Count();
|
||||
|
||||
// Make sure to assign the new directory
|
||||
lastdir = thisdir;
|
||||
}
|
||||
|
||||
// Output the directory stats one last time
|
||||
reports.ForEach(report => report.WriteMidSeparator());
|
||||
|
||||
if (single)
|
||||
{
|
||||
reports.ForEach(report => report.ReplaceStatistics($"DIR: {WebUtility.HtmlEncode(lastdir)}", dirStats.GameCount, dirStats));
|
||||
reports.ForEach(report => report.Write());
|
||||
}
|
||||
|
||||
// Write the mid-footer, if any
|
||||
reports.ForEach(report => report.WriteFooterSeparator());
|
||||
|
||||
// Write the header, if any
|
||||
reports.ForEach(report => report.WriteMidHeader());
|
||||
|
||||
// Reset the directory stats
|
||||
dirStats.Reset();
|
||||
|
||||
// Output total DAT stats
|
||||
reports.ForEach(report => report.ReplaceStatistics("DIR: All DATs", totalStats.GameCount, totalStats));
|
||||
reports.ForEach(report => report.Write());
|
||||
|
||||
// Output footer if needed
|
||||
reports.ForEach(report => report.WriteFooter());
|
||||
|
||||
Globals.Logger.User(@"
|
||||
Please check the log folder if the stats scrolled offscreen", false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the proper extension for the stat output format
|
||||
/// </summary>
|
||||
/// <param name="outDir">Output path to use</param>
|
||||
/// <param name="statDatFormat">StatDatFormat to get the extension for</param>
|
||||
/// <param name="reportName">Name of the input file to use</param>
|
||||
/// <returns>Dictionary of output formats mapped to file names</returns>
|
||||
private static Dictionary<StatReportFormat, string> CreateOutStatsNames(string outDir, StatReportFormat statDatFormat, string reportName, bool overwrite = true)
|
||||
{
|
||||
Dictionary<StatReportFormat, string> output = new Dictionary<StatReportFormat, string>();
|
||||
|
||||
// First try to create the output directory if we need to
|
||||
if (!Directory.Exists(outDir))
|
||||
Directory.CreateDirectory(outDir);
|
||||
|
||||
// Double check the outDir for the end delim
|
||||
if (!outDir.EndsWith(Path.DirectorySeparatorChar.ToString()))
|
||||
outDir += Path.DirectorySeparatorChar;
|
||||
|
||||
// For each output format, get the appropriate stream writer
|
||||
if (statDatFormat.HasFlag(StatReportFormat.None))
|
||||
output.Add(StatReportFormat.None, CreateOutStatsNamesHelper(outDir, ".null", reportName, overwrite));
|
||||
|
||||
if (statDatFormat.HasFlag(StatReportFormat.Textfile))
|
||||
output.Add(StatReportFormat.Textfile, CreateOutStatsNamesHelper(outDir, ".txt", reportName, overwrite));
|
||||
|
||||
if (statDatFormat.HasFlag(StatReportFormat.CSV))
|
||||
output.Add(StatReportFormat.CSV, CreateOutStatsNamesHelper(outDir, ".csv", reportName, overwrite));
|
||||
|
||||
if (statDatFormat.HasFlag(StatReportFormat.HTML))
|
||||
output.Add(StatReportFormat.HTML, CreateOutStatsNamesHelper(outDir, ".html", reportName, overwrite));
|
||||
|
||||
if (statDatFormat.HasFlag(StatReportFormat.SSV))
|
||||
output.Add(StatReportFormat.SSV, CreateOutStatsNamesHelper(outDir, ".ssv", reportName, overwrite));
|
||||
|
||||
if (statDatFormat.HasFlag(StatReportFormat.TSV))
|
||||
output.Add(StatReportFormat.TSV, CreateOutStatsNamesHelper(outDir, ".tsv", reportName, overwrite));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Help generating the outstats name
|
||||
/// </summary>
|
||||
/// <param name="outDir">Output directory</param>
|
||||
/// <param name="extension">Extension to use for the file</param>
|
||||
/// <param name="reportName">Name of the input file to use</param>
|
||||
/// <param name="overwrite">True if we ignore existing files, false otherwise</param>
|
||||
/// <returns>String containing the new filename</returns>
|
||||
private static string CreateOutStatsNamesHelper(string outDir, string extension, string reportName, bool overwrite)
|
||||
{
|
||||
string outfile = outDir + reportName + extension;
|
||||
outfile = outfile.Replace($"{Path.DirectorySeparatorChar}{Path.DirectorySeparatorChar}", Path.DirectorySeparatorChar.ToString());
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
int i = 1;
|
||||
while (File.Exists(outfile))
|
||||
{
|
||||
outfile = $"{outDir}{reportName}_{i}{extension}";
|
||||
outfile = outfile.Replace($"{Path.DirectorySeparatorChar}{Path.DirectorySeparatorChar}", Path.DirectorySeparatorChar.ToString());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return outfile;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion // Instance Methods
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user