[DatFile] Add basic HTML output for stats

This commit is contained in:
Matt Nadareski
2016-09-23 16:32:24 -07:00
parent 95193effbe
commit 2e1ca1f251
5 changed files with 171 additions and 9 deletions

View File

@@ -143,6 +143,7 @@ namespace SabreTools.Helper
helptext.Add(" -out= Output directory");
helptext.Add(" -hs, --hash-split Split a DAT or folder by best-available hashes");
helptext.Add(" -out= Output directory");
helptext.Add(" -html, --html Write statistics on all input DATs to HTML");
helptext.Add(" -st, --stats Get statistics on all input DATs");
helptext.Add(" -si, --single Show individual statistics");
helptext.Add(" -ts, --type-split Split a DAT or folder by file types (rom/disk)");

View File

@@ -4361,6 +4361,38 @@ namespace SabreTools.Helper
", false);
}
/// <summary>
/// Output the stats for the Dat in a human-readable HTML format
/// </summary>
/// <param name="sw">StreamWriter representing the output file or stream for the statistics</param>
/// <param name="logger">Logger object for file and console writing</param>
/// <param name="recalculate">True if numbers should be recalculated for the DAT, false otherwise (default)</param>
/// <param name="game">Number of games to use, -1 means recalculate games (default)</param>
public void OutputHTMLStats(StreamWriter sw, Logger logger, bool recalculate = false, long game = -1)
{
// If we're supposed to recalculate the statistics, do so
if (recalculate)
{
RecalculateStats();
}
BucketByGame(false, true, logger, false);
if (TotalSize < 0)
{
TotalSize = Int64.MaxValue + TotalSize;
}
sw.Write("\t\t\t<tr><td>" + FileName + "</td>"
+ "<td>" + Style.GetBytesReadable(TotalSize) + "</td>"
+ "<td>" + (game == -1 ? Files.Count : game) + "</td>"
+ "<td>" + RomCount + "</td>"
+ "<td>" + DiskCount + "</td>"
+ "<td>" + CRCCount + "</td>"
+ "<td>" + MD5Count + "</td>"
+ "<td>" + SHA1Count + "</td>"
+ "<td>" + NodumpCount + "</td>"
+ "</tr>\n");
}
#endregion
#endregion // Instance Methods
@@ -5106,6 +5138,104 @@ namespace SabreTools.Helper
Please check the log folder if the stats scrolled offscreen", false);
}
/// <summary>
/// Output the stats for a list of input dats as files in a human-readable HTML format
/// </summary>
/// <param name="inputs">List of input files and folders</param>
/// <param name="single">True if single DAT stats are output, false otherwise</param>
/// <param name="logger">Logger object for file and console output</param>
/// <param name="statLogger">Logger object for file and console output (statistics)</param>
public static void OutputHTMLStats(List<string> inputs, Logger logger)
{
StreamWriter sw = new StreamWriter(File.OpenWrite("report.html"));
// Make sure we have all files
List<string> newinputs = new List<string>();
foreach (string input in inputs)
{
if (File.Exists(input))
{
newinputs.Add(input);
}
if (Directory.Exists(input))
{
foreach (string file in Directory.GetFiles(input, "*", SearchOption.AllDirectories))
{
newinputs.Add(file);
}
}
}
// Write the HTML header
sw.Write(@"<!DOCTYPE html>
<html>
<header>
<title>DAT Statistics Report</title>
</header>
<body>
<table border=""1"" cellpadding=""0"" cellspacing=""0"">
<tr><th>File Name</th><th>Total Size</th><th>Games</th><th>Roms</th><th>Disks</th><th>&#35; with CRC</th>"
+ "<th>&#35; with MD5</th><th>&#35; with SHA-1</th><th>Nodumps</th></tr>\n");
// Init all total variables
long totalSize = 0;
long totalGame = 0;
long totalRom = 0;
long totalDisk = 0;
long totalCRC = 0;
long totalMD5 = 0;
long totalSHA1 = 0;
long totalNodump = 0;
/// Now process each of the input files
foreach (string filename in newinputs)
{
logger.Verbose("Beginning stat collection for '" + filename + "'", false);
List<string> games = new List<string>();
DatFile datdata = new DatFile();
datdata.Parse(filename, 0, 0, logger);
datdata.BucketByGame(false, true, logger, false);
// Output single DAT stats (if asked)
logger.User("Adding stats for file '" + filename + "'\n", false);
datdata.OutputHTMLStats(sw, logger);
// Add single DAT stats to totals
totalSize += datdata.TotalSize;
totalGame += datdata.Files.Count;
totalRom += datdata.RomCount;
totalDisk += datdata.DiskCount;
totalCRC += datdata.CRCCount;
totalMD5 += datdata.MD5Count;
totalSHA1 += datdata.SHA1Count;
totalNodump += datdata.NodumpCount;
}
sw.Write("<tr><td colspan=\"9\"></td></tr>");
// Output total DAT stats
DatFile totaldata = new DatFile
{
FileName = "Totals",
TotalSize = totalSize,
RomCount = totalRom,
DiskCount = totalDisk,
CRCCount = totalCRC,
MD5Count = totalMD5,
SHA1Count = totalSHA1,
NodumpCount = totalNodump,
};
totaldata.OutputHTMLStats(sw, logger, game: totalGame);
// Write HTML footer
sw.Write(@" </table>
</body>
</html>
");
sw.Flush();
sw.Dispose();
}
#endregion
#endregion // Static Methods

View File

@@ -310,6 +310,18 @@ Options:
This should only be used if one of the inputs starts with a flag or another already
defined input.
-html, --html Get statistics on all input DATs written to HTML
This will output by default the combined statistics for all input DAT files. The stats
that are outputted are as follows:
- Total uncompressed size
- Number of games found
- Number of roms found
- Number of disks found
- Roms that include a CRC
- Roms that include a MD5
- Roms that include a SHA-1
- Roms with Nodump status
-st, --stats Get statistics on all input DATs
This will output by default the combined statistics for all input DAT files. The stats
that are outputted are as follows:

View File

@@ -213,8 +213,7 @@ namespace SabreTools
/// <param name="inputs">Input file or folder names</param>
/// <param name="restore">False if we're extracting headers (default), true if we're restoring them</param>
/// <param name="outDir">Output directory to write new files to, blank defaults to rom folder</param>
/// <param name="logger">Logger object for file and console output</param>
private static void InitHeaderer(List<string> inputs, bool restore, string outDir, Logger logger)
private static void InitHeaderer(List<string> inputs, bool restore, string outDir)
{
foreach (string input in inputs)
{
@@ -222,11 +221,11 @@ namespace SabreTools
{
if (restore)
{
FileTools.RestoreHeader(input, outDir, logger);
FileTools.RestoreHeader(input, outDir, _logger);
}
else
{
FileTools.DetectSkipperAndTransform(input, outDir, logger);
FileTools.DetectSkipperAndTransform(input, outDir, _logger);
}
}
else if (Directory.Exists(input))
@@ -235,17 +234,26 @@ namespace SabreTools
{
if (restore)
{
FileTools.RestoreHeader(sub, outDir, logger);
FileTools.RestoreHeader(sub, outDir, _logger);
}
else
{
FileTools.DetectSkipperAndTransform(sub, outDir, logger);
FileTools.DetectSkipperAndTransform(sub, outDir, _logger);
}
}
}
}
}
/// <summary>
/// Wrap getting statistics on a DAT or folder of DATs to HTML
/// </summary>
/// <param name="inputs">List of inputs to be used</param>
private static void InitHTMLStats(List<string> inputs)
{
DatFile.OutputHTMLStats(inputs, _logger);
}
/// <summary>
/// Wrap sorting files using an input DAT
/// </summary>

View File

@@ -62,6 +62,7 @@ namespace SabreTools
forceunpack = false,
hashsplit = false,
headerer = false,
html = false,
inplace = false,
merge = false,
noMD5 = false,
@@ -212,6 +213,10 @@ namespace SabreTools
case "--hash-split":
hashsplit = true;
break;
case "-html":
case "--html":
html = true;
break;
case "-ip":
case "--inplace":
inplace = true;
@@ -518,7 +523,7 @@ namespace SabreTools
}
// If more than one switch is enabled, show the help screen
if (!(extsplit ^ hashsplit ^ headerer ^ (datfromdir || merge || diffMode != 0 || update
if (!(extsplit ^ hashsplit ^ headerer ^ html ^ (datfromdir || merge || diffMode != 0 || update
|| outputFormat != 0 || tsv != null|| trim) ^ rem ^ stats ^ typesplit))
{
_logger.Error("Only one feature switch is allowed at a time");
@@ -528,7 +533,7 @@ namespace SabreTools
}
// If a switch that requires a filename is set and no file is, show the help screen
if (inputs.Count == 0 && (datfromdir || extsplit || hashsplit || headerer
if (inputs.Count == 0 && (datfromdir || extsplit || hashsplit || headerer || html
|| (merge || diffMode != 0 || update || outputFormat != 0 || tsv != null) || stats || trim || typesplit))
{
_logger.Error("This feature requires at least one input");
@@ -561,7 +566,13 @@ namespace SabreTools
// If we're in headerer mode
else if (headerer)
{
InitHeaderer(inputs, restore, outDir, _logger);
InitHeaderer(inputs, restore, outDir);
}
// Get statistics on input files to HTML
else if (html)
{
InitHTMLStats(inputs);
}
// Get statistics on input files