2016-11-04 11:57:32 -07:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
2017-03-18 21:26:50 -07:00
using System.Threading.Tasks ;
2016-11-04 11:57:32 -07:00
using System.Web ;
using SabreTools.Helper.Data ;
using SabreTools.Helper.Tools ;
#if MONO
using System.IO ;
#else
using Alphaleonis.Win32.Filesystem ;
using SearchOption = System . IO . SearchOption ;
using StreamWriter = System . IO . StreamWriter ;
#endif
namespace SabreTools.Helper.Dats
{
2017-02-27 23:00:57 -08:00
/ *
* TODO : Make output standard width ( HTML , without making the entire thing a table )
* TODO : Multithreading ? Either StringBuilder or locking
* TODO : Fix alignment for stats output ( text )
* /
2016-11-04 11:57:32 -07:00
public partial class DatFile
{
#region Instance Methods
2017-03-18 00:04:59 -07:00
#region Statistics
2016-11-04 11:57:32 -07:00
/// <summary>
/// Recalculate the statistics for the Dat
/// </summary>
public void RecalculateStats ( )
{
// Wipe out any stats already there
RomCount = 0 ;
DiskCount = 0 ;
TotalSize = 0 ;
CRCCount = 0 ;
MD5Count = 0 ;
SHA1Count = 0 ;
2017-02-23 14:23:41 -08:00
SHA256Count = 0 ;
2016-11-04 11:57:32 -07:00
BaddumpCount = 0 ;
NodumpCount = 0 ;
// If we have a blank Dat in any way, return
2016-11-08 15:50:27 -08:00
if ( this = = null | | Count = = 0 )
2016-11-04 11:57:32 -07:00
{
return ;
}
// Loop through and add
2017-03-18 21:26:50 -07:00
List < string > keys = Keys . ToList ( ) ;
Parallel . ForEach ( keys , Globals . ParallelOptions , key = >
2016-11-04 11:57:32 -07:00
{
2017-01-26 20:59:11 -08:00
List < DatItem > items = this [ key ] ;
2017-03-18 21:26:50 -07:00
Parallel . ForEach ( items , Globals . ParallelOptions , item = >
2016-11-04 11:57:32 -07:00
{
2017-01-26 20:59:11 -08:00
switch ( item . Type )
{
case ItemType . Archive :
break ;
case ItemType . BiosSet :
break ;
case ItemType . Disk :
Disk disk = ( Disk ) item ;
DiskCount + = 1 ;
MD5Count + = ( String . IsNullOrEmpty ( disk . MD5 ) ? 0 : 1 ) ;
SHA1Count + = ( String . IsNullOrEmpty ( disk . SHA1 ) ? 0 : 1 ) ;
2017-02-23 14:23:41 -08:00
SHA256Count + = ( String . IsNullOrEmpty ( disk . SHA256 ) ? 0 : 1 ) ;
2017-03-18 21:26:50 -07:00
SHA384Count + = ( String . IsNullOrEmpty ( disk . SHA384 ) ? 0 : 1 ) ;
SHA512Count + = ( String . IsNullOrEmpty ( disk . SHA512 ) ? 0 : 1 ) ;
2017-01-26 20:59:11 -08:00
BaddumpCount + = ( disk . ItemStatus = = ItemStatus . BadDump ? 1 : 0 ) ;
NodumpCount + = ( disk . ItemStatus = = ItemStatus . Nodump ? 1 : 0 ) ;
break ;
case ItemType . Release :
break ;
case ItemType . Rom :
Rom rom = ( Rom ) item ;
RomCount + = 1 ;
TotalSize + = ( rom . ItemStatus = = ItemStatus . Nodump ? 0 : rom . Size ) ;
CRCCount + = ( String . IsNullOrEmpty ( rom . CRC ) ? 0 : 1 ) ;
MD5Count + = ( String . IsNullOrEmpty ( rom . MD5 ) ? 0 : 1 ) ;
SHA1Count + = ( String . IsNullOrEmpty ( rom . SHA1 ) ? 0 : 1 ) ;
2017-02-23 14:23:41 -08:00
SHA256Count + = ( String . IsNullOrEmpty ( rom . SHA256 ) ? 0 : 1 ) ;
2017-03-18 21:26:50 -07:00
SHA384Count + = ( String . IsNullOrEmpty ( rom . SHA384 ) ? 0 : 1 ) ;
SHA512Count + = ( String . IsNullOrEmpty ( rom . SHA512 ) ? 0 : 1 ) ;
2017-01-26 20:59:11 -08:00
BaddumpCount + = ( rom . ItemStatus = = ItemStatus . BadDump ? 1 : 0 ) ;
NodumpCount + = ( rom . ItemStatus = = ItemStatus . Nodump ? 1 : 0 ) ;
break ;
case ItemType . Sample :
break ;
}
2017-03-18 21:26:50 -07:00
} ) ;
} ) ;
2016-11-04 11:57:32 -07:00
}
/// <summary>
/// Output the stats for the Dat in a human-readable format
/// </summary>
2016-12-05 11:43:48 -08:00
/// <param name="outputs">Dictionary representing the outputs</param>
2016-11-04 11:57:32 -07:00
/// <param name="statDatFormat">Set the statistics output format to use</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>
/// <param name="baddumpCol">True if baddumps should be included in output, false otherwise (default)</param>
/// <param name="nodumpCol">True if nodumps should be included in output, false otherwise (default)</param>
2017-03-01 21:26:27 -08:00
public void OutputStats ( Dictionary < StatDatFormat , StreamWriter > outputs , StatDatFormat statDatFormat ,
2017-03-01 20:36:22 -08:00
bool recalculate = false , long game = - 1 , bool baddumpCol = false , bool nodumpCol = false )
2016-11-04 11:57:32 -07:00
{
// If we're supposed to recalculate the statistics, do so
if ( recalculate )
{
RecalculateStats ( ) ;
}
2017-03-01 21:26:27 -08:00
BucketBy ( SortedBy . Game , false /* mergeroms */ , norename : true ) ;
2016-11-04 11:57:32 -07:00
if ( TotalSize < 0 )
{
TotalSize = Int64 . MaxValue + TotalSize ;
}
// Log the results to screen
string results = @"For '" + FileName + @ "':
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2016-11-04 17:17:43 -07:00
Uncompressed size : " + Style.GetBytesReadable(TotalSize) + @"
2016-11-08 15:50:27 -08:00
Games found : " + (game == -1 ? Count : game) + @"
2016-11-04 17:17:43 -07:00
Roms found : " + RomCount + @"
Disks found : " + DiskCount + @"
Roms with CRC : " + CRCCount + @"
2017-02-23 14:23:41 -08:00
Roms with MD5 : " + MD5Count + @"
Roms with SHA - 1 : " + SHA1Count + @"
Roms with SHA - 256 : " + SHA256Count + " \ n ";
2016-11-04 11:57:32 -07:00
if ( baddumpCol )
{
results + = " Roms with BadDump status: " + BaddumpCount + "\n" ;
}
if ( nodumpCol )
{
results + = " Roms with Nodump status: " + NodumpCount + "\n" ;
}
2017-03-01 21:26:27 -08:00
Globals . Logger . User ( results ) ;
2016-11-04 11:57:32 -07:00
// Now write it out to file as well
2017-01-27 16:53:29 -08:00
string line = "" ;
2016-12-05 11:43:48 -08:00
if ( outputs . ContainsKey ( StatDatFormat . None ) )
2016-11-04 11:57:32 -07:00
{
2016-12-05 11:43:48 -08:00
line = @"'" + FileName + @ "':
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Uncompressed size : " + Style.GetBytesReadable(TotalSize) + @"
Games found : " + (game == -1 ? Count : game) + @"
Roms found : " + RomCount + @"
Disks found : " + DiskCount + @"
Roms with CRC : " + CRCCount + @"
2017-02-23 14:23:41 -08:00
Roms with SHA - 1 : " + SHA1Count + @"
Roms with SHA - 256 : " + SHA256Count + " \ n ";
2016-12-05 11:43:48 -08:00
if ( baddumpCol )
{
line + = " Roms with BadDump status: " + BaddumpCount + "\n" ;
}
if ( nodumpCol )
{
line + = " Roms with Nodump status: " + NodumpCount + "\n" ;
}
outputs [ StatDatFormat . None ] . Write ( line ) ;
}
if ( outputs . ContainsKey ( StatDatFormat . CSV ) )
{
2017-01-27 16:53:29 -08:00
line = "\"" + FileName + "\","
+ "\"" + TotalSize + "\","
+ "\"" + ( game = = - 1 ? Count : game ) + "\","
+ "\"" + RomCount + "\","
+ "\"" + DiskCount + "\","
+ "\"" + CRCCount + "\","
+ "\"" + MD5Count + "\","
2017-02-23 14:23:41 -08:00
+ "\"" + SHA1Count + "\","
+ "\"" + SHA256Count + "\"" ;
2016-11-04 11:57:32 -07:00
2016-12-05 11:43:48 -08:00
if ( baddumpCol )
{
2017-01-27 16:53:29 -08:00
line + = ",\"" + BaddumpCount + "\"" ;
2016-12-05 11:43:48 -08:00
}
if ( nodumpCol )
{
2017-01-27 16:53:29 -08:00
line + = ",\"" + NodumpCount + "\"" ;
2016-12-05 11:43:48 -08:00
}
2016-11-04 11:57:32 -07:00
2016-12-05 11:43:48 -08:00
line + = "\n" ;
outputs [ StatDatFormat . CSV ] . Write ( line ) ;
}
if ( outputs . ContainsKey ( StatDatFormat . HTML ) )
{
line = "\t\t\t<tr" + ( FileName . StartsWith ( "DIR: " )
2016-11-04 11:57:32 -07:00
? " class=\"dir\"><td>" + HttpUtility . HtmlEncode ( FileName . Remove ( 0 , 5 ) )
: "><td>" + HttpUtility . HtmlEncode ( FileName ) ) + "</td>"
+ "<td align=\"right\">" + Style . GetBytesReadable ( TotalSize ) + "</td>"
2016-11-08 15:50:27 -08:00
+ "<td align=\"right\">" + ( game = = - 1 ? Count : game ) + "</td>"
2016-11-04 11:57:32 -07:00
+ "<td align=\"right\">" + RomCount + "</td>"
+ "<td align=\"right\">" + DiskCount + "</td>"
+ "<td align=\"right\">" + CRCCount + "</td>"
+ "<td align=\"right\">" + MD5Count + "</td>"
2017-02-23 14:23:41 -08:00
+ "<td align=\"right\">" + SHA1Count + "</td>"
+ "<td align=\"right\">" + SHA256Count + "</td>" ;
2016-11-04 11:57:32 -07:00
2016-12-05 11:43:48 -08:00
if ( baddumpCol )
{
line + = "<td align=\"right\">" + BaddumpCount + "</td>" ;
}
if ( nodumpCol )
{
line + = "<td align=\"right\">" + NodumpCount + "</td>" ;
}
2016-11-04 11:57:32 -07:00
2016-12-05 11:43:48 -08:00
line + = "</tr>\n" ;
outputs [ StatDatFormat . HTML ] . Write ( line ) ;
}
if ( outputs . ContainsKey ( StatDatFormat . TSV ) )
{
2017-01-27 16:53:29 -08:00
line = "\"" + FileName + "\"\t"
+ "\"" + TotalSize + "\"\t"
+ "\"" + ( game = = - 1 ? Count : game ) + "\"\t"
+ "\"" + RomCount + "\"\t"
+ "\"" + DiskCount + "\"\t"
+ "\"" + CRCCount + "\"\t"
+ "\"" + MD5Count + "\"\t"
2017-02-23 14:23:41 -08:00
+ "\"" + SHA1Count + "\"\t"
+ "\"" + SHA256Count + "\"" ;
2016-11-04 11:57:32 -07:00
2016-12-05 11:43:48 -08:00
if ( baddumpCol )
{
2017-01-27 16:53:29 -08:00
line + = "\t\"" + BaddumpCount + "\"" ;
2016-12-05 11:43:48 -08:00
}
if ( nodumpCol )
{
2017-01-27 16:53:29 -08:00
line + = "\t\"" + NodumpCount + "\"" ;
2016-12-05 11:43:48 -08:00
}
2016-11-04 11:57:32 -07:00
2016-12-05 11:43:48 -08:00
line + = "\n" ;
outputs [ StatDatFormat . TSV ] . Write ( line ) ;
2016-11-04 11:57:32 -07:00
}
}
#endregion
#endregion // Instance Methods
#region Static Methods
2017-03-18 00:04:59 -07:00
#region Statistics
2016-11-04 11:57:32 -07:00
/// <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>
2016-11-10 10:42:51 -08:00
public static void OutputStats ( List < string > inputs , string reportName , string outDir , bool single ,
2017-03-01 21:26:27 -08:00
bool baddumpCol , bool nodumpCol , StatDatFormat statDatFormat )
2016-11-04 11:57:32 -07:00
{
2016-12-05 11:43:48 -08:00
// If there's no output format, set the default
if ( statDatFormat = = 0x0 )
{
statDatFormat = StatDatFormat . None ;
}
2016-11-10 10:42:51 -08:00
// Get the proper output file name
if ( String . IsNullOrEmpty ( outDir ) )
{
outDir = Environment . CurrentDirectory ;
}
if ( String . IsNullOrEmpty ( reportName ) )
{
reportName = "report" ;
}
outDir = Path . GetFullPath ( outDir ) ;
2016-12-05 11:43:48 -08:00
// Get the dictionary of desired outputs
Dictionary < StatDatFormat , StreamWriter > outputs = OutputStatsGetOutputWriters ( statDatFormat , reportName , outDir ) ;
2016-11-04 11:57:32 -07:00
// Make sure we have all files
List < Tuple < string , string > > newinputs = new List < Tuple < string , string > > ( ) ; // item, basepath
foreach ( string input in inputs )
{
if ( File . Exists ( input ) )
{
newinputs . Add ( Tuple . Create ( Path . GetFullPath ( input ) , Path . GetDirectoryName ( Path . GetFullPath ( input ) ) ) ) ;
}
if ( Directory . Exists ( input ) )
{
foreach ( string file in Directory . GetFiles ( input , "*" , SearchOption . AllDirectories ) )
{
newinputs . Add ( Tuple . Create ( Path . GetFullPath ( file ) , Path . GetFullPath ( input ) ) ) ;
}
}
}
newinputs = newinputs
. OrderBy ( i = > Path . GetDirectoryName ( i . Item1 ) )
. ThenBy ( i = > Path . GetFileName ( i . Item1 ) )
. ToList ( ) ;
// Write the header, if any
2016-12-05 11:43:48 -08:00
OutputStatsWriteHeader ( outputs , statDatFormat , baddumpCol , nodumpCol ) ;
2016-11-04 11:57:32 -07:00
// 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 ;
2017-02-23 14:23:41 -08:00
long totalSHA256 = 0 ;
2016-11-04 11:57:32 -07:00
long totalBaddump = 0 ;
long totalNodump = 0 ;
// Init directory-level variables
string lastdir = null ;
string basepath = null ;
long dirSize = 0 ;
long dirGame = 0 ;
long dirRom = 0 ;
long dirDisk = 0 ;
long dirCRC = 0 ;
long dirMD5 = 0 ;
long dirSHA1 = 0 ;
2017-02-23 14:23:41 -08:00
long dirSHA256 = 0 ;
2016-11-04 11:57:32 -07:00
long dirBaddump = 0 ;
long dirNodump = 0 ;
// Now process each of the input files
foreach ( Tuple < string , string > filename in newinputs )
{
// Get the directory for the current file
string thisdir = Path . GetDirectoryName ( filename . Item1 ) ;
basepath = Path . GetDirectoryName ( filename . Item2 ) ;
// 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
2016-12-05 11:43:48 -08:00
OutputStatsWriteMidSeparator ( outputs , statDatFormat , baddumpCol , nodumpCol ) ;
2016-11-04 11:57:32 -07:00
DatFile lastdirdat = new DatFile
{
FileName = "DIR: " + HttpUtility . HtmlEncode ( lastdir . Remove ( 0 , basepath . Length + ( basepath . Length = = 0 ? 0 : 1 ) ) ) ,
TotalSize = dirSize ,
RomCount = dirRom ,
DiskCount = dirDisk ,
CRCCount = dirCRC ,
MD5Count = dirMD5 ,
SHA1Count = dirSHA1 ,
2017-02-23 14:23:41 -08:00
SHA256Count = dirSHA256 ,
2016-11-04 11:57:32 -07:00
BaddumpCount = dirBaddump ,
NodumpCount = dirNodump ,
} ;
2017-03-01 21:26:27 -08:00
lastdirdat . OutputStats ( outputs , statDatFormat ,
2017-03-01 20:36:22 -08:00
game : dirGame , baddumpCol : baddumpCol , nodumpCol : nodumpCol ) ;
2016-11-04 11:57:32 -07:00
// Write the mid-footer, if any
2016-12-05 11:43:48 -08:00
OutputStatsWriteMidFooter ( outputs , statDatFormat , baddumpCol , nodumpCol ) ;
2016-11-04 11:57:32 -07:00
// Write the header, if any
2016-12-05 11:43:48 -08:00
OutputStatsWriteMidHeader ( outputs , statDatFormat , baddumpCol , nodumpCol ) ;
2016-11-04 11:57:32 -07:00
// Reset the directory stats
dirSize = 0 ;
dirGame = 0 ;
dirRom = 0 ;
dirDisk = 0 ;
dirCRC = 0 ;
dirMD5 = 0 ;
dirSHA1 = 0 ;
2017-02-23 14:23:41 -08:00
dirSHA256 = 0 ;
2016-11-04 11:57:32 -07:00
dirBaddump = 0 ;
dirNodump = 0 ;
}
2017-03-01 21:26:27 -08:00
Globals . Logger . Verbose ( "Beginning stat collection for '" + filename . Item1 + "'" , false ) ;
2016-11-04 11:57:32 -07:00
List < string > games = new List < string > ( ) ;
DatFile datdata = new DatFile ( ) ;
2017-03-01 21:26:27 -08:00
datdata . Parse ( filename . Item1 , 0 , 0 ) ;
datdata . BucketBy ( SortedBy . Game , false /* mergeroms */ , norename : true ) ;
2016-11-04 11:57:32 -07:00
// Output single DAT stats (if asked)
2017-03-01 21:26:27 -08:00
Globals . Logger . User ( "Adding stats for file '" + filename . Item1 + "'\n" , false ) ;
2016-11-04 11:57:32 -07:00
if ( single )
{
2017-03-01 21:26:27 -08:00
datdata . OutputStats ( outputs , statDatFormat ,
2017-03-01 20:36:22 -08:00
baddumpCol : baddumpCol , nodumpCol : nodumpCol ) ;
2016-11-04 11:57:32 -07:00
}
// Add single DAT stats to dir
dirSize + = datdata . TotalSize ;
2016-11-08 15:50:27 -08:00
dirGame + = datdata . Count ;
2016-11-04 11:57:32 -07:00
dirRom + = datdata . RomCount ;
dirDisk + = datdata . DiskCount ;
dirCRC + = datdata . CRCCount ;
dirMD5 + = datdata . MD5Count ;
dirSHA1 + = datdata . SHA1Count ;
2017-02-23 14:23:41 -08:00
dirSHA256 + = datdata . SHA256Count ;
2016-11-04 11:57:32 -07:00
dirBaddump + = datdata . BaddumpCount ;
dirNodump + = datdata . NodumpCount ;
// Add single DAT stats to totals
totalSize + = datdata . TotalSize ;
2016-11-08 15:50:27 -08:00
totalGame + = datdata . Count ;
2016-11-04 11:57:32 -07:00
totalRom + = datdata . RomCount ;
totalDisk + = datdata . DiskCount ;
totalCRC + = datdata . CRCCount ;
totalMD5 + = datdata . MD5Count ;
totalSHA1 + = datdata . SHA1Count ;
2017-02-23 14:23:41 -08:00
totalSHA256 + = datdata . SHA256Count ;
2016-11-04 11:57:32 -07:00
totalBaddump + = datdata . BaddumpCount ;
totalNodump + = datdata . NodumpCount ;
// Make sure to assign the new directory
lastdir = thisdir ;
}
// Output the directory stats one last time
2016-12-05 11:43:48 -08:00
OutputStatsWriteMidSeparator ( outputs , statDatFormat , baddumpCol , nodumpCol ) ;
2016-11-04 11:57:32 -07:00
if ( single )
{
DatFile dirdat = new DatFile
{
FileName = "DIR: " + HttpUtility . HtmlEncode ( lastdir . Remove ( 0 , basepath . Length + ( basepath . Length = = 0 ? 0 : 1 ) ) ) ,
TotalSize = dirSize ,
RomCount = dirRom ,
DiskCount = dirDisk ,
CRCCount = dirCRC ,
MD5Count = dirMD5 ,
SHA1Count = dirSHA1 ,
2017-02-23 14:23:41 -08:00
SHA256Count = dirSHA256 ,
2016-11-04 11:57:32 -07:00
BaddumpCount = dirBaddump ,
NodumpCount = dirNodump ,
} ;
2017-03-01 21:26:27 -08:00
dirdat . OutputStats ( outputs , statDatFormat ,
2017-03-01 20:36:22 -08:00
game : dirGame , baddumpCol : baddumpCol , nodumpCol : nodumpCol ) ;
2016-11-04 11:57:32 -07:00
}
// Write the mid-footer, if any
2016-12-05 11:43:48 -08:00
OutputStatsWriteMidFooter ( outputs , statDatFormat , baddumpCol , nodumpCol ) ;
2016-11-04 11:57:32 -07:00
// Write the header, if any
2016-12-05 11:43:48 -08:00
OutputStatsWriteMidHeader ( outputs , statDatFormat , baddumpCol , nodumpCol ) ;
2016-11-04 11:57:32 -07:00
// Reset the directory stats
dirSize = 0 ;
dirGame = 0 ;
dirRom = 0 ;
dirDisk = 0 ;
dirCRC = 0 ;
dirMD5 = 0 ;
dirSHA1 = 0 ;
2017-02-23 14:23:41 -08:00
dirSHA256 = 0 ;
2016-11-04 11:57:32 -07:00
dirNodump = 0 ;
// Output total DAT stats
DatFile totaldata = new DatFile
{
FileName = "DIR: All DATs" ,
TotalSize = totalSize ,
RomCount = totalRom ,
DiskCount = totalDisk ,
CRCCount = totalCRC ,
MD5Count = totalMD5 ,
SHA1Count = totalSHA1 ,
2017-02-23 14:23:41 -08:00
SHA256Count = totalSHA256 ,
2016-11-04 11:57:32 -07:00
BaddumpCount = totalBaddump ,
NodumpCount = totalNodump ,
} ;
2017-03-01 21:26:27 -08:00
totaldata . OutputStats ( outputs , statDatFormat ,
2017-03-01 20:36:22 -08:00
game : totalGame , baddumpCol : baddumpCol , nodumpCol : nodumpCol ) ;
2016-11-04 11:57:32 -07:00
// Output footer if needed
2016-12-05 11:43:48 -08:00
OutputStatsWriteFooter ( outputs , statDatFormat ) ;
2016-11-04 11:57:32 -07:00
2016-12-05 11:43:48 -08:00
// Flush and dispose of the stream writers
foreach ( StatDatFormat format in outputs . Keys )
{
outputs [ format ] . Flush ( ) ;
outputs [ format ] . Dispose ( ) ;
}
2016-11-04 11:57:32 -07:00
2017-03-01 21:26:27 -08:00
Globals . Logger . User ( @ "
2016-11-04 11:57:32 -07:00
Please check the log folder if the stats scrolled offscreen ", false);
}
/// <summary>
/// Get the proper extension for the stat output format
/// </summary>
/// <param name="statDatFormat">StatDatFormat to get the extension for</param>
2016-12-05 11:43:48 -08:00
/// <param name="reportName">Name of the input file to use</param>
/// <param name="outDir">Output path to use</param>
/// <returns>Dictionary of file types to StreamWriters</returns>
private static Dictionary < StatDatFormat , StreamWriter > OutputStatsGetOutputWriters ( StatDatFormat statDatFormat , string reportName , string outDir )
2016-11-04 11:57:32 -07:00
{
2016-12-05 11:43:48 -08:00
Dictionary < StatDatFormat , StreamWriter > output = new Dictionary < StatDatFormat , System . IO . StreamWriter > ( ) ;
// For each output format, get the appropriate stream writer
if ( ( statDatFormat & StatDatFormat . None ) ! = 0 )
{
reportName = Style . GetFileNameWithoutExtension ( reportName ) + ".txt" ;
Path . Combine ( outDir , reportName ) ;
// Create the StreamWriter for this file
2017-03-15 20:07:28 -07:00
output . Add ( StatDatFormat . None , new StreamWriter ( FileTools . TryCreate ( reportName ) ) ) ;
2016-12-05 11:43:48 -08:00
}
if ( ( statDatFormat & StatDatFormat . CSV ) ! = 0 )
{
reportName = Style . GetFileNameWithoutExtension ( reportName ) + ".csv" ;
Path . Combine ( outDir , reportName ) ;
// Create the StreamWriter for this file
2017-03-15 20:07:28 -07:00
output . Add ( StatDatFormat . CSV , new StreamWriter ( FileTools . TryCreate ( reportName ) ) ) ;
2016-12-05 11:43:48 -08:00
}
if ( ( statDatFormat & StatDatFormat . HTML ) ! = 0 )
{
reportName = Style . GetFileNameWithoutExtension ( reportName ) + ".html" ;
Path . Combine ( outDir , reportName ) ;
// Create the StreamWriter for this file
2017-03-15 20:07:28 -07:00
output . Add ( StatDatFormat . HTML , new StreamWriter ( FileTools . TryCreate ( reportName ) ) ) ;
2016-12-05 11:43:48 -08:00
}
if ( ( statDatFormat & StatDatFormat . TSV ) ! = 0 )
{
reportName = Style . GetFileNameWithoutExtension ( reportName ) + ".csv" ;
Path . Combine ( outDir , reportName ) ;
// Create the StreamWriter for this file
2017-03-15 20:07:28 -07:00
output . Add ( StatDatFormat . TSV , new StreamWriter ( FileTools . TryCreate ( reportName ) ) ) ;
2016-12-05 11:43:48 -08:00
}
return output ;
2016-11-04 11:57:32 -07:00
}
/// <summary>
/// Write out the header to the stream, if any exists
/// </summary>
2016-12-05 11:43:48 -08:00
/// <param name="outputs">Dictionary representing the outputs</param>
2016-11-04 11:57:32 -07:00
/// <param name="statDatFormat">StatDatFormat representing output format</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>
2016-12-05 11:43:48 -08:00
private static void OutputStatsWriteHeader ( Dictionary < StatDatFormat , StreamWriter > outputs , StatDatFormat statDatFormat , bool baddumpCol , bool nodumpCol )
2016-11-04 11:57:32 -07:00
{
2016-12-05 11:43:48 -08:00
if ( outputs . ContainsKey ( StatDatFormat . None ) )
{
// Nothing
}
if ( outputs . ContainsKey ( StatDatFormat . CSV ) )
{
2017-02-23 14:23:41 -08:00
outputs [ StatDatFormat . CSV ] . Write ( "\"File Name\",\"Total Size\",\"Games\",\"Roms\",\"Disks\",\"# with CRC\",\"# with MD5\",\"# with SHA-1\",\"# with SHA-256\""
2017-01-27 16:53:29 -08:00
+ ( baddumpCol ? ",\"BadDumps\"" : "" ) + ( nodumpCol ? ",\"Nodumps\"" : "" ) + "\n" ) ;
2016-12-05 11:43:48 -08:00
}
if ( outputs . ContainsKey ( StatDatFormat . HTML ) )
{
outputs [ StatDatFormat . HTML ] . Write ( @ "<!DOCTYPE html>
2016-11-04 11:57:32 -07:00
< html >
< header >
< title > DAT Statistics Report < / title >
< style >
body {
background - color : lightgray ;
}
. dir {
color : # 0088F F ;
}
. right {
align : right ;
}
< / style >
< / header >
< body >
< h2 > DAT Statistics Report ( " + DateTime.Now.ToShortDateString() + @" ) < / h2 >
2017-01-27 16:53:29 -08:00
< table border = "" 1 "" cellpadding = "" 5 "" cellspacing = "" 0 "" >
2016-12-05 11:43:48 -08:00
");
}
if ( outputs . ContainsKey ( StatDatFormat . TSV ) )
{
2017-02-23 14:23:41 -08:00
outputs [ StatDatFormat . TSV ] . Write ( "\"File Name\"\t\"Total Size\"\t\"Games\"\t\"Roms\"\t\"Disks\"\t\"# with CRC\"\t\"# with MD5\"\t\"# with SHA-1\"\t\"# with SHA-256\""
2017-01-27 16:53:29 -08:00
+ ( baddumpCol ? "\t\"BadDumps\"" : "" ) + ( nodumpCol ? "\t\"Nodumps\"" : "" ) + "\n" ) ;
2016-12-05 11:43:48 -08:00
}
2016-11-04 11:57:32 -07:00
// Now write the mid header for those who need it
2016-12-05 11:43:48 -08:00
OutputStatsWriteMidHeader ( outputs , statDatFormat , baddumpCol , nodumpCol ) ;
2016-11-04 11:57:32 -07:00
}
/// <summary>
/// Write out the mid-header to the stream, if any exists
/// </summary>
2016-12-05 11:43:48 -08:00
/// <param name="outputs">Dictionary representing the outputs</param>
2016-11-04 11:57:32 -07:00
/// <param name="statDatFormat">StatDatFormat representing output format</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>
2016-12-05 11:43:48 -08:00
private static void OutputStatsWriteMidHeader ( Dictionary < StatDatFormat , StreamWriter > outputs , StatDatFormat statDatFormat , bool baddumpCol , bool nodumpCol )
2016-11-04 11:57:32 -07:00
{
2016-12-05 11:43:48 -08:00
if ( outputs . ContainsKey ( StatDatFormat . None ) )
{
// Nothing
}
if ( outputs . ContainsKey ( StatDatFormat . CSV ) )
{
// Nothing
}
if ( outputs . ContainsKey ( StatDatFormat . HTML ) )
2016-11-04 11:57:32 -07:00
{
2017-01-27 16:53:29 -08:00
outputs [ StatDatFormat . HTML ] . Write ( @" <tr bgcolor=""gray""><th>File Name</th><th align=""right"">Total Size</th><th align=""right"">Games</th><th align=""right"">Roms</th>"
2017-02-23 14:23:41 -08:00
+ @"<th align=""right"">Disks</th><th align=""right""># with CRC</th><th align=""right""># with MD5</th><th align=""right""># with SHA-1</th><th align=""right""># with SHA-256</th>"
2017-01-27 16:53:29 -08:00
+ ( baddumpCol ? "<th class=\".right\">Baddumps</th>" : "" ) + ( nodumpCol ? "<th class=\".right\">Nodumps</th>" : "" ) + "</tr>\n" ) ;
2016-12-05 11:43:48 -08:00
}
if ( outputs . ContainsKey ( StatDatFormat . TSV ) )
{
// Nothing
}
2016-11-04 11:57:32 -07:00
}
/// <summary>
/// Write out the separator to the stream, if any exists
/// </summary>
2016-12-05 11:43:48 -08:00
/// <param name="outputs">Dictionary representing the outputs</param>
2016-11-04 11:57:32 -07:00
/// <param name="statDatFormat">StatDatFormat representing output format</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>
2016-12-05 11:43:48 -08:00
private static void OutputStatsWriteMidSeparator ( Dictionary < StatDatFormat , StreamWriter > outputs , StatDatFormat statDatFormat , bool baddumpCol , bool nodumpCol )
2016-11-04 11:57:32 -07:00
{
2016-12-05 11:43:48 -08:00
if ( outputs . ContainsKey ( StatDatFormat . None ) )
2016-11-04 11:57:32 -07:00
{
2016-12-05 11:43:48 -08:00
// Nothing
}
if ( outputs . ContainsKey ( StatDatFormat . CSV ) )
{
// Nothing
}
if ( outputs . ContainsKey ( StatDatFormat . HTML ) )
{
2017-01-27 16:53:29 -08:00
outputs [ StatDatFormat . HTML ] . Write ( "<tr><td colspan=\""
2016-11-04 11:57:32 -07:00
+ ( baddumpCol & & nodumpCol
2017-02-23 14:23:41 -08:00
? "12"
2016-11-04 11:57:32 -07:00
: ( baddumpCol ^ nodumpCol
2017-02-23 14:23:41 -08:00
? "11"
: "10" )
2016-11-04 11:57:32 -07:00
)
2016-12-05 11:43:48 -08:00
+ "\"></td></tr>\n" ) ;
}
if ( outputs . ContainsKey ( StatDatFormat . TSV ) )
{
// Nothing
2016-11-04 11:57:32 -07:00
}
}
/// <summary>
/// Write out the footer-separator to the stream, if any exists
/// </summary>
2016-12-05 11:43:48 -08:00
/// <param name="outputs">Dictionary representing the outputs</param>
2016-11-04 11:57:32 -07:00
/// <param name="statDatFormat">StatDatFormat representing output format</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>
2016-12-05 11:43:48 -08:00
private static void OutputStatsWriteMidFooter ( Dictionary < StatDatFormat , StreamWriter > outputs , StatDatFormat statDatFormat , bool baddumpCol , bool nodumpCol )
2016-11-04 11:57:32 -07:00
{
2016-12-05 11:43:48 -08:00
if ( outputs . ContainsKey ( StatDatFormat . None ) )
{
outputs [ StatDatFormat . None ] . Write ( "\n" ) ;
}
if ( outputs . ContainsKey ( StatDatFormat . CSV ) )
{
outputs [ StatDatFormat . CSV ] . Write ( "\n" ) ;
}
if ( outputs . ContainsKey ( StatDatFormat . HTML ) )
{
2017-01-27 16:53:29 -08:00
outputs [ StatDatFormat . HTML ] . Write ( "<tr border=\"0\"><td colspan=\""
2016-11-04 11:57:32 -07:00
+ ( baddumpCol & & nodumpCol
2017-02-23 14:23:41 -08:00
? "12"
2016-11-04 11:57:32 -07:00
: ( baddumpCol ^ nodumpCol
2017-02-23 14:23:41 -08:00
? "11"
: "10" )
2016-11-04 11:57:32 -07:00
)
2016-12-05 11:43:48 -08:00
+ "\"></td></tr>\n" ) ;
}
if ( outputs . ContainsKey ( StatDatFormat . TSV ) )
{
outputs [ StatDatFormat . TSV ] . Write ( "\n" ) ;
}
2016-11-04 11:57:32 -07:00
}
/// <summary>
/// Write out the footer to the stream, if any exists
/// </summary>
/// <param name="sw">StreamWriter representing the output</param>
/// <param name="statDatFormat">StatDatFormat representing output format</param>
2016-12-05 11:43:48 -08:00
private static void OutputStatsWriteFooter ( Dictionary < StatDatFormat , StreamWriter > outputs , StatDatFormat statDatFormat )
2016-11-04 11:57:32 -07:00
{
2016-12-05 11:43:48 -08:00
if ( outputs . ContainsKey ( StatDatFormat . None ) )
2016-11-04 11:57:32 -07:00
{
2016-12-05 11:43:48 -08:00
// Nothing
}
if ( outputs . ContainsKey ( StatDatFormat . CSV ) )
{
// Nothing
}
if ( outputs . ContainsKey ( StatDatFormat . HTML ) )
{
outputs [ StatDatFormat . HTML ] . Write ( @ " </table>
2016-11-04 11:57:32 -07:00
< / body >
< / html >
2016-12-05 11:43:48 -08:00
");
}
if ( outputs . ContainsKey ( StatDatFormat . TSV ) )
{
// Nothing
}
2016-11-04 11:57:32 -07:00
}
#endregion
#endregion // Static Methods
}
}