2016-09-12 21:27:17 -07:00
using System ;
2016-06-13 20:00:44 -07:00
using System.Collections.Generic ;
using System.IO ;
2016-09-17 18:00:18 -07:00
using System.Linq ;
using System.Threading.Tasks ;
2016-06-13 20:00:44 -07:00
2016-09-12 21:27:17 -07:00
namespace SabreTools.Helper
2016-06-13 20:00:44 -07:00
{
public class SimpleSort
{
// Private instance variables
2016-09-19 20:08:25 -07:00
private DatFile _datdata ;
2016-06-13 20:00:44 -07:00
private List < string > _inputs ;
2016-09-16 16:35:58 -07:00
private string _outDir ;
private string _tempDir ;
2016-06-17 20:03:07 -07:00
private bool _quickScan ;
2016-10-14 16:58:15 -07:00
private bool _date ;
2016-06-21 13:41:18 -07:00
private bool _toFolder ;
2016-09-12 22:00:25 -07:00
private bool _delete ;
2016-10-08 23:28:09 -07:00
private bool _tgz ;
2016-08-25 15:28:35 -07:00
private bool _romba ;
2016-08-29 20:27:19 -07:00
private bool _updateDat ;
2016-10-05 17:23:44 -07:00
private ArchiveScanLevel _archiveScanLevel ;
2016-10-17 14:28:21 -07:00
private string _headerToCheckAgainst ;
2016-06-13 20:00:44 -07:00
private Logger _logger ;
2016-09-17 18:00:18 -07:00
private int _maxDegreeOfParallelism = 4 ; // Hardcoded for now, should be an input later
2016-06-13 20:00:44 -07:00
2016-06-26 22:08:35 -07:00
// Other private variables
private int _cursorTop ;
private int _cursorLeft ;
2016-09-19 20:08:25 -07:00
private DatFile _matched ;
2016-06-26 22:08:35 -07:00
2016-06-13 20:00:44 -07:00
/// <summary>
/// Create a new SimpleSort object
/// </summary>
2016-09-17 18:00:18 -07:00
/// <param name="datdata">DAT to compare against</param>
2016-06-13 20:00:44 -07:00
/// <param name="inputs">List of input files/folders to check</param>
2016-09-16 16:35:58 -07:00
/// <param name="outDir">Output directory to use to build to</param>
/// <param name="tempDir">Temporary directory for archive extraction</param>
2016-06-17 20:03:07 -07:00
/// <param name="quickScan">True to enable external scanning of archives, false otherwise</param>
2016-10-14 16:58:15 -07:00
/// <param name="date">True if the date from the DAT should be used if available, false otherwise</param>
2016-06-21 13:41:18 -07:00
/// <param name="toFolder">True if files should be output to folder, false otherwise</param>
2016-09-12 22:00:25 -07:00
/// <param name="delete">True if input files should be deleted, false otherwise</param>
2016-10-08 23:28:09 -07:00
/// <param name="tgz">True if output files should be written to TorrentGZ instead of TorrentZip</param>
2016-08-25 15:28:35 -07:00
/// <param name="romba">True if files should be output in Romba depot folders, false otherwise</param>
2016-10-05 17:23:44 -07:00
/// <param name="archiveScanLevel">ArchiveScanLevel representing the archive handling levels</param>
2016-08-29 20:27:19 -07:00
/// <param name="updateDat">True if the updated DAT should be output, false otherwise</param>
2016-10-17 14:28:21 -07:00
/// <param name="headerToCheckAgainst">Populated string representing the name of the skipper to use, a blank string to use the first available checker, null otherwise</param>
2016-06-13 20:00:44 -07:00
/// <param name="logger">Logger object for file and console output</param>
2016-09-19 20:08:25 -07:00
public SimpleSort ( DatFile datdata , List < string > inputs , string outDir , string tempDir ,
2016-10-20 17:24:44 -07:00
bool quickScan , bool date , bool toFolder , bool delete , bool tgz , bool romba ,
2016-10-17 14:28:21 -07:00
ArchiveScanLevel archiveScanLevel , bool updateDat , string headerToCheckAgainst , Logger logger )
2016-06-13 20:00:44 -07:00
{
_datdata = datdata ;
_inputs = inputs ;
2016-09-16 16:35:58 -07:00
_outDir = ( outDir = = "" ? "Rebuild" : outDir ) ;
2016-09-16 18:02:56 -07:00
_tempDir = ( String . IsNullOrEmpty ( tempDir ) ? Path . Combine ( Path . GetTempPath ( ) , Path . GetRandomFileName ( ) ) : tempDir ) ;
2016-06-17 20:03:07 -07:00
_quickScan = quickScan ;
2016-10-14 16:58:15 -07:00
_date = date ;
2016-06-21 13:41:18 -07:00
_toFolder = toFolder ;
2016-09-12 22:00:25 -07:00
_delete = delete ;
2016-10-08 23:28:09 -07:00
_tgz = tgz ;
2016-08-25 15:28:35 -07:00
_romba = romba ;
2016-10-05 17:23:44 -07:00
_archiveScanLevel = archiveScanLevel ;
2016-08-29 20:27:19 -07:00
_updateDat = updateDat ;
2016-10-17 14:28:21 -07:00
_headerToCheckAgainst = headerToCheckAgainst ;
2016-06-13 20:00:44 -07:00
_logger = logger ;
2016-06-26 23:25:48 -07:00
_cursorTop = Console . CursorTop ;
_cursorLeft = Console . CursorLeft ;
2016-09-19 20:08:25 -07:00
_matched = new DatFile
2016-06-26 23:25:48 -07:00
{
2016-09-22 18:15:02 -07:00
Files = new SortedDictionary < string , List < DatItem > > ( ) ,
2016-06-26 23:25:48 -07:00
} ;
2016-06-13 20:00:44 -07:00
}
/// <summary>
2016-10-20 17:24:44 -07:00
/// Process the DAT and find all matches in input files and folders
2016-06-13 20:00:44 -07:00
/// </summary>
2016-10-20 17:24:44 -07:00
/// <returns>True if rebuilding was a success, false otherwise</returns>
/// <remarks>
/// This currently processes files as follows:
/// 1) Get all file names from the input files/folders
/// 2) Loop through and process each file individually
/// a) Hash the file
/// b) Check against the DAT for duplicates
/// c) Check for headers
/// d) Check headerless rom for duplicates
///
/// This is actually rather slow and inefficient. See below for more correct implemenation
/// </remarks>
public bool RebuildToOutput ( )
2016-06-13 20:00:44 -07:00
{
// First, check that the output directory exists
2016-09-16 16:35:58 -07:00
if ( ! Directory . Exists ( _outDir ) )
2016-06-13 20:00:44 -07:00
{
2016-09-16 16:35:58 -07:00
Directory . CreateDirectory ( _outDir ) ;
_outDir = Path . GetFullPath ( _outDir ) ;
2016-06-13 20:00:44 -07:00
}
2016-06-14 12:36:25 -07:00
// Then create or clean the temp directory
2016-09-16 16:35:58 -07:00
if ( ! Directory . Exists ( _tempDir ) )
2016-06-14 12:36:25 -07:00
{
2016-09-16 16:35:58 -07:00
Directory . CreateDirectory ( _tempDir ) ;
2016-06-14 12:36:25 -07:00
}
else
{
2016-09-16 16:35:58 -07:00
FileTools . CleanDirectory ( _tempDir ) ;
2016-06-14 12:36:25 -07:00
}
2016-08-24 21:19:05 -07:00
bool success = true ;
2016-10-17 13:54:03 -07:00
_logger . User ( "Retrieving list all files from input" ) ;
DateTime start = DateTime . Now ;
2016-08-24 21:19:05 -07:00
// Create a list of just files from inputs
List < string > files = new List < string > ( ) ;
2016-10-17 15:08:49 -07:00
Parallel . ForEach ( _inputs ,
new ParallelOptions { MaxDegreeOfParallelism = _maxDegreeOfParallelism , } ,
input = > {
if ( File . Exists ( input ) )
2016-08-18 14:34:29 -07:00
{
2016-10-17 15:08:49 -07:00
_logger . Verbose ( "File found: '" + input + "'" ) ;
files . Add ( Path . GetFullPath ( input ) ) ;
2016-08-18 14:34:29 -07:00
}
2016-10-17 15:08:49 -07:00
else if ( Directory . Exists ( input ) )
{
_logger . Verbose ( "Directory found: '" + input + "'" ) ;
Parallel . ForEach ( Directory . EnumerateFiles ( input , "*" , SearchOption . AllDirectories ) ,
new ParallelOptions { MaxDegreeOfParallelism = _maxDegreeOfParallelism , } ,
file = >
{
_logger . Verbose ( "File found: '" + file + "'" ) ;
files . Add ( Path . GetFullPath ( file ) ) ;
} ) ;
}
else
{
_logger . Error ( "'" + input + "' is not a file or directory!" ) ;
}
} ) ;
2016-10-17 13:54:03 -07:00
_logger . User ( "Retrieving complete in: " + DateTime . Now . Subtract ( start ) . ToString ( @"hh\:mm\:ss\.fffff" ) ) ;
2016-08-24 21:19:05 -07:00
// Then, loop through and check each of the inputs
_logger . User ( "Processing files:\n" ) ;
_cursorTop = Console . CursorTop ;
for ( int i = 0 ; i < files . Count ; i + + )
{
success & = RebuildToOutputHelper ( files [ i ] , i , files . Count ) ;
2016-09-16 18:02:56 -07:00
if ( _tempDir ! = Path . GetTempPath ( ) )
{
FileTools . CleanDirectory ( _tempDir ) ;
}
2016-10-12 14:40:21 -07:00
if ( success & & _delete )
{
try
{
File . Delete ( files [ i ] ) ;
}
catch { }
}
2016-08-24 21:19:05 -07:00
}
2016-06-14 12:36:25 -07:00
2016-08-24 21:19:05 -07:00
// Now one final delete of the temp directory
2016-09-16 16:35:58 -07:00
while ( Directory . Exists ( _tempDir ) )
2016-08-24 21:19:05 -07:00
{
try
{
2016-09-16 17:14:36 -07:00
if ( _tempDir ! = Path . GetTempPath ( ) )
{
Directory . Delete ( _tempDir , true ) ;
}
2016-08-24 21:19:05 -07:00
}
catch
{
continue ;
}
2016-08-18 14:34:29 -07:00
}
2016-06-22 21:23:50 -07:00
2016-08-24 21:19:05 -07:00
// Now output the stats for the built files
_logger . ClearBeneath ( Constants . HeaderHeight ) ;
Console . SetCursorPosition ( 0 , Constants . HeaderHeight + 1 ) ;
_logger . User ( "Stats of the matched ROMs:" ) ;
2016-09-26 14:38:05 -07:00
StreamWriter sw = new StreamWriter ( new MemoryStream ( ) ) ;
2016-09-26 17:36:25 -07:00
_matched . OutputStats ( sw , StatOutputFormat . None , _logger , recalculate : true , baddumpCol : true , nodumpCol : true ) ;
2016-09-26 14:38:05 -07:00
sw . Dispose ( ) ;
2016-08-24 21:19:05 -07:00
2016-08-29 20:27:19 -07:00
// Now output the fixdat based on the original input if asked
if ( _updateDat )
{
_datdata . FileName = "fixDat_" + _datdata . FileName ;
_datdata . Name = "fixDat_" + _datdata . Name ;
_datdata . Description = "fixDat_" + _datdata . Description ;
2016-09-30 12:15:36 -07:00
_datdata . OutputFormat = OutputFormat . Logiqx ;
2016-09-22 17:46:21 -07:00
_datdata . WriteToFile ( "" , _logger ) ;
2016-08-29 20:27:19 -07:00
}
2016-08-29 12:23:02 -07:00
2016-06-13 20:00:44 -07:00
return success ;
}
/// <summary>
2016-08-24 21:19:05 -07:00
/// Process an individual file against the DAT for rebuilding
2016-06-13 20:00:44 -07:00
/// </summary>
2016-06-22 21:44:58 -07:00
/// <param name="input">Name of the input file</param>
/// <param name="index">Index of the current file</param>
/// <param name="total">Total number of files</param>
2016-06-13 20:00:44 -07:00
/// <param name="recurse">True if this is in a recurse step and the file should be deleted, false otherwise (default)</param>
/// <returns>True if it was processed properly, false otherwise</returns>
2016-06-22 21:44:58 -07:00
private bool RebuildToOutputHelper ( string input , int index , int total , bool recurse = false )
2016-06-13 20:00:44 -07:00
{
bool success = true ;
// Get the full path of the input for movement purposes
2016-06-28 21:19:12 -07:00
string percentage = ( index = = 0 ? "0.00" : Math . Round ( ( 100 * ( ( double ) index / total ) ) , 2 , MidpointRounding . AwayFromZero ) . ToString ( ) ) ;
2016-06-26 22:08:35 -07:00
string statement = percentage + "% - " + input ;
2016-06-26 23:25:48 -07:00
_logger . ClearBeneath ( _cursorTop + 1 ) ;
2016-09-23 15:09:00 -07:00
_logger . WriteExact ( statement , _cursorTop , 0 ) ;
2016-06-13 20:00:44 -07:00
2016-06-17 20:03:07 -07:00
// Get if the file should be scanned internally and externally
2016-08-29 12:23:02 -07:00
bool shouldExternalScan , shouldInternalScan ;
2016-10-05 17:23:44 -07:00
ArchiveTools . GetInternalExternalProcess ( input , _archiveScanLevel , _logger , out shouldExternalScan , out shouldInternalScan ) ;
2016-06-13 20:52:12 -07:00
2016-06-14 12:36:25 -07:00
// Hash and match the external files
2016-06-17 20:03:07 -07:00
if ( shouldExternalScan )
2016-06-13 20:52:12 -07:00
{
2016-10-03 15:29:40 -07:00
Rom rom = FileTools . GetFileInfo ( input , _logger ) ;
2016-06-14 12:36:25 -07:00
// If we have a blank RomData, it's an error
if ( rom . Name = = null )
{
return false ;
}
// Try to find the matches to the file that was found
2016-09-22 20:30:04 -07:00
List < DatItem > foundroms = rom . GetDuplicates ( _datdata , _logger ) ;
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "File '" + input + "' had " + foundroms . Count + " matches in the DAT!" ) ;
2016-08-29 16:33:07 -07:00
foreach ( Rom found in foundroms )
2016-06-14 12:36:25 -07:00
{
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "Matched name: " + found . Name ) ;
2016-06-21 13:36:44 -07:00
2016-06-26 23:25:48 -07:00
// Add rom to the matched list
2016-09-19 20:36:12 -07:00
string key = found . Size + "-" + found . CRC ;
2016-09-12 21:27:17 -07:00
if ( _matched . Files . ContainsKey ( key ) )
2016-06-26 23:25:48 -07:00
{
2016-08-29 13:52:13 -07:00
_matched . Files [ key ] . Add ( found ) ;
2016-06-26 23:25:48 -07:00
}
else
{
2016-09-19 18:04:24 -07:00
List < DatItem > temp = new List < DatItem > ( ) ;
2016-06-26 23:25:48 -07:00
temp . Add ( found ) ;
2016-08-29 13:52:13 -07:00
_matched . Files . Add ( key , temp ) ;
2016-06-26 23:25:48 -07:00
}
2016-06-21 13:36:44 -07:00
if ( _toFolder )
{
// Copy file to output directory
2016-09-19 18:04:24 -07:00
string gamedir = Path . Combine ( _outDir , found . MachineName ) ;
2016-06-21 13:36:44 -07:00
if ( ! Directory . Exists ( gamedir ) )
{
Directory . CreateDirectory ( gamedir ) ;
}
2016-10-08 23:28:09 -07:00
_logger . Verbose ( "Rebuilding file '" + Path . GetFileName ( rom . Name ) + "' to '" + ( _tgz ? found . SHA1 : found . Name ) + "'" ) ;
2016-06-21 13:36:44 -07:00
try
{
2016-08-29 16:33:07 -07:00
File . Copy ( input , Path . Combine ( gamedir , Path . GetFileName ( found . Name ) ) ) ;
2016-06-21 13:36:44 -07:00
}
catch { }
}
else
{
2016-10-08 23:28:09 -07:00
if ( _tgz )
2016-08-25 15:28:35 -07:00
{
2016-09-22 21:00:18 -07:00
ArchiveTools . WriteTorrentGZ ( input , _outDir , _romba , _logger ) ;
2016-08-25 15:28:35 -07:00
}
else
{
2016-10-14 16:58:15 -07:00
ArchiveTools . WriteToArchive ( input , _outDir , found , _logger , date : _date ) ;
2016-08-25 15:28:35 -07:00
}
2016-06-21 13:36:44 -07:00
}
2016-06-14 12:36:25 -07:00
}
2016-06-17 11:02:38 -07:00
// Now get the transformed file if it exists
2016-10-17 14:28:21 -07:00
SkipperRule rule = Skipper . GetMatchingRule ( input , _headerToCheckAgainst , _logger ) ;
2016-06-17 11:02:38 -07:00
// If we have have a non-empty rule, apply it
if ( rule . Tests ! = null & & rule . Tests . Count ! = 0 )
2016-06-14 12:36:25 -07:00
{
2016-09-09 15:37:15 -07:00
// Otherwise, apply the rule to the file
2016-06-14 12:36:25 -07:00
string newinput = input + ".new" ;
2016-10-03 21:16:59 -07:00
rule . TransformFile ( input , newinput , _logger ) ;
2016-10-03 15:29:40 -07:00
Rom drom = FileTools . GetFileInfo ( newinput , _logger ) ;
2016-06-14 12:36:25 -07:00
// If we have a blank RomData, it's an error
2016-10-14 16:58:15 -07:00
if ( String . IsNullOrEmpty ( drom . Name ) )
2016-06-14 12:36:25 -07:00
{
return false ;
}
// Try to find the matches to the file that was found
2016-09-22 20:30:04 -07:00
List < DatItem > founddroms = drom . GetDuplicates ( _datdata , _logger ) ;
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "File '" + newinput + "' had " + founddroms . Count + " matches in the DAT!" ) ;
2016-08-29 16:33:07 -07:00
foreach ( Rom found in founddroms )
2016-06-14 12:36:25 -07:00
{
2016-06-26 23:25:48 -07:00
// Add rom to the matched list
2016-09-19 20:36:12 -07:00
string key = found . Size + "-" + found . CRC ;
2016-08-29 13:52:13 -07:00
if ( _matched . Files . ContainsKey ( key ) )
2016-06-26 23:25:48 -07:00
{
2016-08-29 13:52:13 -07:00
_matched . Files [ key ] . Add ( found ) ;
2016-06-26 23:25:48 -07:00
}
else
{
2016-09-19 18:04:24 -07:00
List < DatItem > temp = new List < DatItem > ( ) ;
2016-06-26 23:25:48 -07:00
temp . Add ( found ) ;
2016-08-29 13:52:13 -07:00
_matched . Files . Add ( key , temp ) ;
2016-06-26 23:25:48 -07:00
}
2016-06-14 12:36:25 -07:00
// First output the headerless rom
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "Matched name: " + found . Name ) ;
2016-06-21 13:36:44 -07:00
if ( _toFolder )
{
// Copy file to output directory
2016-09-19 18:04:24 -07:00
string gamedir = Path . Combine ( _outDir , found . MachineName ) ;
2016-06-21 13:36:44 -07:00
if ( ! Directory . Exists ( gamedir ) )
{
Directory . CreateDirectory ( gamedir ) ;
}
2016-10-08 23:28:09 -07:00
_logger . Verbose ( "Rebuilding file '" + Path . GetFileName ( rom . Name ) + "' to '" + ( _tgz ? found . SHA1 : found . Name ) + "'" ) ;
2016-06-21 13:36:44 -07:00
try
{
2016-08-29 16:33:07 -07:00
File . Copy ( newinput , Path . Combine ( gamedir , Path . GetFileName ( found . Name ) ) ) ;
2016-06-21 13:36:44 -07:00
}
catch { }
}
else
{
2016-10-08 23:28:09 -07:00
if ( _tgz )
2016-08-25 15:28:35 -07:00
{
2016-09-22 21:00:18 -07:00
ArchiveTools . WriteTorrentGZ ( newinput , _outDir , _romba , _logger ) ;
2016-08-25 15:28:35 -07:00
}
else
{
2016-10-14 16:58:15 -07:00
ArchiveTools . WriteToArchive ( newinput , _outDir , found , _logger , date : _date ) ;
2016-08-25 15:28:35 -07:00
}
2016-06-21 13:36:44 -07:00
}
2016-06-14 12:36:25 -07:00
// Then output the headered rom (renamed)
2016-08-29 16:33:07 -07:00
Rom newfound = found ;
2016-09-19 20:36:12 -07:00
newfound . Name = Path . GetFileNameWithoutExtension ( newfound . Name ) + " (" + rom . CRC + ")" + Path . GetExtension ( newfound . Name ) ;
2016-09-19 22:53:33 -07:00
newfound . Size = rom . Size ;
newfound . CRC = rom . CRC ;
newfound . MD5 = rom . MD5 ;
newfound . SHA1 = rom . SHA1 ;
2016-06-14 12:36:25 -07:00
2016-06-26 23:25:48 -07:00
// Add rom to the matched list
2016-09-19 20:36:12 -07:00
key = newfound . Size + "-" + newfound . CRC ;
2016-08-29 13:52:13 -07:00
if ( _matched . Files . ContainsKey ( key ) )
2016-06-26 23:25:48 -07:00
{
2016-08-29 13:52:13 -07:00
_matched . Files [ key ] . Add ( newfound ) ;
2016-06-26 23:25:48 -07:00
}
else
{
2016-09-19 18:04:24 -07:00
List < DatItem > temp = new List < DatItem > ( ) ;
2016-06-26 23:25:48 -07:00
temp . Add ( newfound ) ;
2016-08-29 13:52:13 -07:00
_matched . Files . Add ( key , temp ) ;
2016-06-26 23:25:48 -07:00
}
2016-06-21 13:36:44 -07:00
if ( _toFolder )
{
// Copy file to output directory
2016-09-19 18:04:24 -07:00
string gamedir = Path . Combine ( _outDir , found . MachineName ) ;
2016-06-21 13:36:44 -07:00
if ( ! Directory . Exists ( gamedir ) )
{
Directory . CreateDirectory ( gamedir ) ;
}
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "Rebuilding file '" + Path . GetFileName ( rom . Name ) + "' to '" + newfound . Name + "'" ) ;
2016-06-21 13:36:44 -07:00
try
{
2016-08-29 16:33:07 -07:00
File . Copy ( input , Path . Combine ( gamedir , Path . GetFileName ( newfound . Name ) ) ) ;
2016-06-21 13:36:44 -07:00
}
catch { }
}
else
{
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "Matched name: " + newfound . Name ) ;
2016-10-08 23:28:09 -07:00
if ( _tgz )
2016-08-25 15:28:35 -07:00
{
2016-09-22 21:00:18 -07:00
ArchiveTools . WriteTorrentGZ ( input , _outDir , _romba , _logger ) ;
2016-08-25 15:28:35 -07:00
}
else
{
2016-10-14 16:58:15 -07:00
ArchiveTools . WriteToArchive ( input , _outDir , newfound , _logger , date : _date ) ;
2016-08-25 15:28:35 -07:00
}
2016-06-21 13:36:44 -07:00
}
2016-06-14 12:36:25 -07:00
}
// Now remove this temporary file
2016-06-15 16:00:40 -07:00
try
{
2016-08-29 16:33:07 -07:00
File . Delete ( newinput ) ;
2016-06-15 16:00:40 -07:00
}
catch
{
// Don't log file deletion errors
}
2016-06-14 12:36:25 -07:00
}
2016-06-13 20:52:12 -07:00
}
2016-06-17 20:03:07 -07:00
// If we should scan the file as an archive
if ( shouldInternalScan )
2016-06-13 20:52:12 -07:00
{
2016-06-17 20:03:07 -07:00
// If external scanning is enabled, use that method instead
if ( _quickScan )
2016-06-15 11:21:39 -07:00
{
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "Beginning quick scan of contents from '" + input + "'" ) ;
2016-09-22 21:00:18 -07:00
List < Rom > internalRomData = ArchiveTools . GetArchiveFileInfo ( input , _logger ) ;
2016-09-23 15:09:00 -07:00
_logger . Verbose ( internalRomData . Count + " entries found in '" + input + "'" ) ;
2016-06-17 20:03:07 -07:00
// If the list is populated, then the file was a filled archive
if ( internalRomData . Count > 0 )
2016-06-15 15:15:51 -07:00
{
2016-08-29 16:33:07 -07:00
foreach ( Rom rom in internalRomData )
2016-06-15 15:15:51 -07:00
{
2016-06-17 20:03:07 -07:00
// Try to find the matches to the file that was found
2016-09-22 20:30:04 -07:00
List < DatItem > foundroms = rom . GetDuplicates ( _datdata , _logger ) ;
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "File '" + rom . Name + "' had " + foundroms . Count + " matches in the DAT!" ) ;
2016-08-29 16:33:07 -07:00
foreach ( Rom found in foundroms )
2016-06-15 15:15:51 -07:00
{
2016-06-26 23:25:48 -07:00
// Add rom to the matched list
2016-09-19 20:36:12 -07:00
string key = found . Size + "-" + found . CRC ;
2016-08-29 13:52:13 -07:00
if ( _matched . Files . ContainsKey ( key ) )
2016-06-26 23:25:48 -07:00
{
2016-08-29 13:52:13 -07:00
_matched . Files [ key ] . Add ( found ) ;
2016-06-26 23:25:48 -07:00
}
else
{
2016-09-19 18:04:24 -07:00
List < DatItem > temp = new List < DatItem > ( ) ;
2016-06-26 23:25:48 -07:00
temp . Add ( found ) ;
2016-08-29 13:52:13 -07:00
_matched . Files . Add ( key , temp ) ;
2016-06-26 23:25:48 -07:00
}
2016-06-21 13:36:44 -07:00
if ( _toFolder )
{
// Copy file to output directory
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "Rebuilding file '" + Path . GetFileName ( rom . Name ) + "' to '" + found . Name + "'" ) ;
2016-09-22 21:00:18 -07:00
string outfile = ArchiveTools . ExtractSingleItemFromArchive ( input , rom . Name , _tempDir , _logger ) ;
2016-08-29 16:33:07 -07:00
if ( File . Exists ( outfile ) )
2016-06-21 13:36:44 -07:00
{
2016-09-19 18:04:24 -07:00
string gamedir = Path . Combine ( _outDir , found . MachineName ) ;
2016-06-21 13:36:44 -07:00
if ( ! Directory . Exists ( gamedir ) )
{
Directory . CreateDirectory ( gamedir ) ;
}
try
{
2016-08-29 16:33:07 -07:00
File . Move ( outfile , Path . Combine ( gamedir , Path . GetFileName ( found . Name ) ) ) ;
2016-06-21 13:36:44 -07:00
}
catch { }
}
}
else
{
// Copy file between archives
2016-10-08 23:28:09 -07:00
_logger . Verbose ( "Rebuilding file '" + Path . GetFileName ( rom . Name ) + "' to '" + ( _tgz ? found . SHA1 : found . Name ) + "'" ) ;
2016-06-22 14:17:27 -07:00
2016-10-08 23:28:09 -07:00
if ( Build . MonoEnvironment | | _tgz )
2016-06-22 14:17:27 -07:00
{
2016-09-22 21:00:18 -07:00
string outfile = ArchiveTools . ExtractSingleItemFromArchive ( input , rom . Name , _tempDir , _logger ) ;
2016-08-29 16:33:07 -07:00
if ( File . Exists ( outfile ) )
2016-06-22 14:17:27 -07:00
{
2016-10-08 23:28:09 -07:00
if ( _tgz )
2016-08-25 15:28:35 -07:00
{
2016-09-22 21:00:18 -07:00
ArchiveTools . WriteTorrentGZ ( outfile , _outDir , _romba , _logger ) ;
2016-08-25 15:28:35 -07:00
}
else
{
2016-10-08 23:28:09 -07:00
ArchiveTools . WriteToArchive ( outfile , _outDir , found , _logger ) ;
2016-08-25 15:28:35 -07:00
}
2016-06-22 14:17:27 -07:00
try
{
2016-08-29 16:33:07 -07:00
File . Delete ( outfile ) ;
2016-06-22 14:17:27 -07:00
}
catch { }
}
}
else
{
2016-09-22 21:00:18 -07:00
ArchiveTools . CopyFileBetweenArchives ( input , _outDir , rom . Name , found , _logger ) ;
2016-06-22 14:17:27 -07:00
}
2016-06-21 13:36:44 -07:00
}
2016-06-15 15:15:51 -07:00
}
}
}
2016-06-15 11:21:39 -07:00
}
2016-06-17 20:03:07 -07:00
else
2016-06-15 15:56:47 -07:00
{
2016-06-17 20:03:07 -07:00
// Now, if the file is a supported archive type, also run on all files within
2016-10-05 17:23:44 -07:00
bool encounteredErrors = ArchiveTools . ExtractArchive ( input , _tempDir , _archiveScanLevel , _logger ) ;
2016-06-17 20:03:07 -07:00
2016-06-15 15:56:47 -07:00
// Remove the current file if we are in recursion so it's not picked up in the next step
if ( recurse )
{
try
{
2016-08-29 16:33:07 -07:00
File . Delete ( input ) ;
2016-06-15 15:56:47 -07:00
}
2016-06-16 10:37:04 -07:00
catch ( Exception )
2016-06-15 15:56:47 -07:00
{
2016-06-15 16:00:40 -07:00
// Don't log file deletion errors
2016-06-15 15:56:47 -07:00
}
}
2016-06-17 20:03:07 -07:00
// If no errors were encountered, we loop through the temp directory
if ( ! encounteredErrors )
2016-06-15 15:15:51 -07:00
{
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "Archive found! Successfully extracted" ) ;
2016-09-16 16:35:58 -07:00
foreach ( string file in Directory . EnumerateFiles ( _tempDir , "*" , SearchOption . AllDirectories ) )
2016-06-17 20:03:07 -07:00
{
2016-06-22 21:44:58 -07:00
success & = RebuildToOutputHelper ( file , index , total , true ) ;
2016-06-17 20:03:07 -07:00
}
2016-06-15 15:15:51 -07:00
}
2016-06-13 20:52:12 -07:00
}
}
return success ;
}
2016-06-16 10:37:04 -07:00
2016-10-05 16:54:52 -07:00
/// <summary>
/// Process the DAT and find all matches in input files and folders
/// </summary>
/// <returns>True if rebuilding was a success, false otherwise</returns>
/// <remarks>
/// This implemenation of the code should do the following:
/// 1) Get all file names from the input files/folders (parallel)
/// 2) Loop through and get the file info from every file (including headerless)
/// 3) Find all duplicate files in the input DAT(s)
/// 4) Order by output game
/// 5) Rebuild all files
/// </remarks>
2016-10-20 17:24:44 -07:00
public bool RebuiltToOutputAlternate ( )
2016-10-05 16:54:52 -07:00
{
2016-10-20 17:24:44 -07:00
// First, check that the output directory exists
if ( ! Directory . Exists ( _outDir ) )
{
Directory . CreateDirectory ( _outDir ) ;
_outDir = Path . GetFullPath ( _outDir ) ;
}
// Then create or clean the temp directory
if ( ! Directory . Exists ( _tempDir ) )
{
Directory . CreateDirectory ( _tempDir ) ;
}
else
{
FileTools . CleanDirectory ( _tempDir ) ;
}
2016-10-05 16:54:52 -07:00
bool success = true ;
#region Find all files
// Create a list of just files from inputs
_logger . User ( "Finding all files..." ) ;
List < string > files = new List < string > ( ) ;
Parallel . ForEach ( _inputs ,
new ParallelOptions { MaxDegreeOfParallelism = _maxDegreeOfParallelism } ,
input = >
{
if ( File . Exists ( input ) )
{
_logger . Verbose ( "File found: '" + input + "'" ) ;
lock ( files )
{
files . Add ( Path . GetFullPath ( input ) ) ;
}
}
else if ( Directory . Exists ( input ) )
{
_logger . Verbose ( "Directory found: '" + input + "'" ) ;
List < string > infiles = Directory . EnumerateFiles ( input , "*" , SearchOption . AllDirectories ) . ToList ( ) ;
Parallel . ForEach ( infiles ,
new ParallelOptions { MaxDegreeOfParallelism = _maxDegreeOfParallelism } ,
file = >
{
_logger . Verbose ( "File found: '" + input + "'" ) ;
lock ( files )
{
files . Add ( Path . GetFullPath ( file ) ) ;
}
} ) ;
}
else
{
_logger . Error ( "'" + input + "' is not a file or directory!" ) ;
}
} ) ;
_logger . User ( "Finding files complete!" ) ;
#endregion
#region Get source file information
// Now loop through all of the files and check them, DFD style
_logger . User ( "Getting source file information..." ) ;
DatFile matchdat = new DatFile
{
Files = new SortedDictionary < string , List < DatItem > > ( ) ,
} ;
foreach ( string file in files )
{
// Get if the file should be scanned internally and externally
bool shouldExternalScan , shouldInternalScan ;
2016-10-05 17:23:44 -07:00
ArchiveTools . GetInternalExternalProcess ( file , _archiveScanLevel , _logger , out shouldExternalScan , out shouldInternalScan ) ;
2016-10-05 16:54:52 -07:00
// Hash and match the external files
if ( shouldExternalScan )
{
RebuildToOutputAlternateParseRomHelper ( file , ref matchdat , _logger ) ;
}
// If we should scan the file as an archive
if ( shouldInternalScan )
{
// If external scanning is enabled, use that method instead
if ( _quickScan )
{
_logger . Verbose ( "Beginning quick scan of contents from '" + file + "'" ) ;
List < Rom > internalRomData = ArchiveTools . GetArchiveFileInfo ( file , _logger ) ;
_logger . Verbose ( internalRomData . Count + " entries found in '" + file + "'" ) ;
// Now add all of the roms to the DAT
for ( int i = 0 ; i < internalRomData . Count ; i + + )
{
RebuildToOutputAlternateParseRomHelper ( file , ref matchdat , _logger ) ;
}
}
// Otherwise, try to extract the file to the temp folder
else
{
// Now, if the file is a supported archive type, also run on all files within
2016-10-05 17:23:44 -07:00
bool encounteredErrors = ArchiveTools . ExtractArchive ( file , _tempDir , _archiveScanLevel , _logger ) ;
2016-10-05 16:54:52 -07:00
// If we succeeded in extracting, loop through the files
if ( ! encounteredErrors )
{
List < string > extractedFiles = Directory . EnumerateFiles ( _tempDir , "*" , SearchOption . AllDirectories ) . ToList ( ) ;
foreach ( string extractedFile in extractedFiles )
{
RebuildToOutputAlternateParseRomHelper ( extractedFile , ref matchdat , _logger ) ;
}
}
// Otherwise, skip extracting and just get information on the file itself (if we didn't already)
else if ( ! shouldExternalScan )
{
RebuildToOutputAlternateParseRomHelper ( file , ref matchdat , _logger ) ;
}
// Clean the temp directory for the next round
if ( Directory . Exists ( _tempDir ) )
{
FileTools . CleanDirectory ( _tempDir ) ;
}
}
}
}
_logger . User ( "Getting source file information complete!" ) ;
#endregion
#region Find all files to rebuild and bucket by game
// Create a dictionary of from/to Rom mappings
Dictionary < DatItem , DatItem > toFromMap = new Dictionary < DatItem , DatItem > ( ) ;
// Now populate it
foreach ( string key in matchdat . Files . Keys )
{
foreach ( DatItem rom in matchdat . Files [ key ] )
{
List < DatItem > matched = rom . GetDuplicates ( _datdata , _logger , true ) ;
foreach ( DatItem match in matched )
{
try
{
toFromMap . Add ( match , rom ) ;
}
catch { }
}
}
}
// Then bucket the keys by game for better output
SortedDictionary < string , List < DatItem > > keysByGame = DatFile . BucketListByGame ( toFromMap . Keys . ToList ( ) , false , true , _logger ) ;
#endregion
#region Rebuild all files
// At this point, we have "toFromMap" which maps output files to input files as well as
// as SortedDictionary called keysByGame which is the output files sorted by game in
// alphabetical order. We should be able to use these to do everything we need =)
// Now write out each game sequentially
foreach ( string key in keysByGame . Keys )
{
}
#endregion
return success ;
}
/// <summary>
/// Wrap adding a file to the dictionary in custom DFD, files that matched a skipper a prefixed with "HEAD::"
/// </summary>
/// <param name="file">Name of the file to attempt to add</param>
/// <param name="matchdat">Reference to the Dat to add to</param>
/// <param name="logger">Logger object for file and console output</param>
/// <returns>True if the file could be added, false otherwise</returns>
2016-10-12 14:40:21 -07:00
private bool RebuildToOutputAlternateParseRomHelper ( string file , ref DatFile matchdat , Logger logger )
2016-10-05 16:54:52 -07:00
{
Rom rom = FileTools . GetFileInfo ( file , logger ) ;
// If we have a blank RomData, it's an error
if ( rom . Name = = null )
{
return false ;
}
// Otherwise, set the machine name as the full path to the file
rom . MachineName = Path . GetDirectoryName ( Path . GetFullPath ( file ) ) ;
// Add the rom information to the Dat
string key = rom . Size + "-" + rom . CRC ;
if ( matchdat . Files . ContainsKey ( key ) )
{
matchdat . Files [ key ] . Add ( rom ) ;
}
else
{
List < DatItem > temp = new List < DatItem > ( ) ;
temp . Add ( rom ) ;
matchdat . Files . Add ( key , temp ) ;
}
// Now attempt to see if the file has a header
FileStream input = File . OpenRead ( file ) ;
2016-10-17 14:28:21 -07:00
SkipperRule rule = Skipper . GetMatchingRule ( input , _headerToCheckAgainst , _logger ) ;
2016-10-05 16:54:52 -07:00
// If there's a match, get the new information from the stream
if ( rule . Tests ! = null & & rule . Tests . Count ! = 0 )
{
// Create the input and output streams
MemoryStream output = new MemoryStream ( ) ;
// Transform the stream and get the information from it
rule . TransformStream ( input , output , _logger , false , true ) ;
Rom romNH = FileTools . GetStreamInfo ( output , output . Length ) ;
romNH . Name = "HEAD::" + rom . Name ;
romNH . MachineName = rom . MachineName ;
// Add the rom information to the Dat
key = romNH . Size + "-" + romNH . CRC ;
if ( matchdat . Files . ContainsKey ( key ) )
{
matchdat . Files [ key ] . Add ( romNH ) ;
}
else
{
List < DatItem > temp = new List < DatItem > ( ) ;
temp . Add ( romNH ) ;
matchdat . Files . Add ( key , temp ) ;
}
// Dispose of the stream
output . Dispose ( ) ;
}
// Dispose of the stream
input . Dispose ( ) ;
return true ;
}
2016-06-16 10:37:04 -07:00
/// <summary>
/// Clean an individual folder based on the DAT
/// </summary>
/// <returns>True if the cleaning succeeded, false otherwise</returns>
2016-06-16 11:03:52 -07:00
/// <remarks>This method is incomplete, it need to be finished before it can be used</remarks>
2016-10-12 14:40:21 -07:00
private bool InplaceRebuild ( )
2016-06-16 10:37:04 -07:00
{
bool success = true ;
/ *
The process of rebuilding inplace is as follows :
0 ) Resort the input roms by Game since that ' s more important in this case
1 ) Scan the current folder according to the level specified ( no recursion )
a - If file is a match in all aspects , set correct flag and pass
+ If the file has a header , skip ?
b - If file is a match in hash but not name , rename , set correct flag and pass
c - If file is not a match , extract it to the output folder and remove from archive , set incorrect flag
2 ) For all files that have been removed , check to see if they could be rebuilt to another location
a - This behaves similarly ( and indeed could call ) "RebuildToFolder"
b - If a file is a match and rebuilt , remove it from the output folder
* /
// Assuming archived sets, move all toplevel folders to temp
2016-09-16 16:35:58 -07:00
foreach ( string directory in Directory . EnumerateDirectories ( _outDir , "*" , SearchOption . TopDirectoryOnly ) )
2016-06-16 10:37:04 -07:00
{
2016-09-16 16:35:58 -07:00
Directory . Move ( directory , Path . Combine ( _tempDir , Path . GetFileNameWithoutExtension ( directory ) ) ) ;
2016-06-16 10:37:04 -07:00
}
// Now process the inputs (assumed that it's archived sets as of right now
2016-09-19 18:04:24 -07:00
Dictionary < string , List < DatItem > > scanned = new Dictionary < string , List < DatItem > > ( ) ;
2016-09-16 16:35:58 -07:00
foreach ( string archive in Directory . EnumerateFiles ( _outDir , "*" , SearchOption . AllDirectories ) )
2016-06-16 10:37:04 -07:00
{
2016-06-21 11:38:33 -07:00
// If we are in quickscan, get the list of roms that way
2016-08-29 16:33:07 -07:00
List < Rom > roms = new List < Rom > ( ) ;
2016-06-21 11:38:33 -07:00
if ( _quickScan )
2016-06-16 10:37:04 -07:00
{
2016-09-22 21:00:18 -07:00
roms = ArchiveTools . GetArchiveFileInfo ( Path . GetFullPath ( archive ) , _logger ) ;
2016-06-16 10:37:04 -07:00
}
2016-06-21 11:38:33 -07:00
// Otherwise, extract it and get info one by one
2016-06-16 10:37:04 -07:00
else
{
2016-09-16 16:35:58 -07:00
string temparcdir = Path . Combine ( _tempDir , Path . GetFileNameWithoutExtension ( archive ) ) ;
2016-09-22 21:00:18 -07:00
ArchiveTools . ExtractArchive ( Path . GetFullPath ( archive ) , temparcdir , _logger ) ;
2016-06-21 11:38:33 -07:00
foreach ( string tempfile in Directory . EnumerateFiles ( temparcdir , "*" , SearchOption . AllDirectories ) )
{
2016-10-03 15:29:40 -07:00
roms . Add ( FileTools . GetFileInfo ( Path . GetFullPath ( tempfile ) , _logger ) ) ;
2016-06-21 11:38:33 -07:00
}
// Clear the temporary archive directory
2016-09-01 20:38:41 -07:00
FileTools . CleanDirectory ( temparcdir ) ;
2016-06-21 11:38:33 -07:00
}
2016-06-16 10:37:04 -07:00
2016-06-21 11:38:33 -07:00
// Then add each of the found files to the new dictionary
2016-08-29 16:33:07 -07:00
foreach ( Rom rom in roms )
2016-06-21 11:38:33 -07:00
{
2016-09-19 20:36:12 -07:00
string key = rom . Size + "-" + rom . CRC ;
2016-06-21 11:38:33 -07:00
if ( scanned . ContainsKey ( key ) )
2016-06-16 10:37:04 -07:00
{
2016-06-21 11:38:33 -07:00
scanned [ key ] . Add ( rom ) ;
2016-06-16 10:37:04 -07:00
}
else
{
2016-09-19 18:04:24 -07:00
List < DatItem > templist = new List < DatItem > ( ) ;
2016-06-21 11:38:33 -07:00
templist . Add ( rom ) ;
scanned . Add ( key , templist ) ;
2016-06-16 10:37:04 -07:00
}
2016-06-21 11:38:33 -07:00
}
}
2016-06-16 10:37:04 -07:00
2016-06-21 11:38:33 -07:00
// If nothing was found, we that it was successful
if ( scanned . Count = = 0 )
{
return success ;
}
// Now that we have all of the from DAT and from folder roms, we try to match them, removing the perfect matches
2016-09-19 18:04:24 -07:00
Dictionary < string , List < DatItem > > remove = new Dictionary < string , List < DatItem > > ( ) ;
2016-06-21 11:38:33 -07:00
foreach ( string key in scanned . Keys )
{
// If the key doesn't even exist in the DAT, then mark the entire key for removal
2016-08-29 13:52:13 -07:00
if ( ! _datdata . Files . ContainsKey ( key ) )
2016-06-21 11:38:33 -07:00
{
if ( remove . ContainsKey ( key ) )
2016-06-16 11:02:33 -07:00
{
2016-06-21 11:38:33 -07:00
remove [ key ] . AddRange ( scanned [ key ] ) ;
}
else
{
remove . Add ( key , scanned [ key ] ) ;
}
}
// Otherwise check each of the values individually
else
{
2016-09-19 18:04:24 -07:00
List < DatItem > romsList = _datdata . Files [ key ] ;
List < DatItem > scannedList = scanned [ key ] ;
2016-08-29 16:33:07 -07:00
foreach ( Rom rom in scannedList )
2016-06-21 11:38:33 -07:00
{
if ( ! romsList . Contains ( rom ) )
2016-06-16 11:02:33 -07:00
{
2016-06-21 11:38:33 -07:00
if ( remove . ContainsKey ( key ) )
{
remove [ key ] . Add ( rom ) ;
}
else
{
2016-09-19 18:04:24 -07:00
List < DatItem > templist = new List < DatItem > ( ) ;
2016-06-21 11:38:33 -07:00
templist . Add ( rom ) ;
remove . Add ( key , templist ) ;
}
2016-06-16 11:02:33 -07:00
}
}
2016-06-16 10:37:04 -07:00
}
}
2016-06-21 11:38:33 -07:00
// At this point, we have the complete list of files from the DAT, a complete
// list of files that were scanned from the archives, and a complete list of
// the files to be removed because they aren't matches. I think at this point,
// we need to see if any of the files in "removed" can be rebuilt to something
// that is missing. But we don't have a list of missings, so how do we get this
// set of roms? Missing would be (_datdata.Roms - matches) I think. So if we
// get this additional set, we then run it against the "removed" set and rebuild
// as we go based on what we can do. Here is where we need some smarts. If the
// game to rebuild from and to are the same, we want to copy within. You
// should create a new helper function that "renames" an entry within the same
// archive to help this along. Everything else rebuilding should be copied from
// archive to archive. Once remove has been traversed, we will extract and remove
// all of the files that have been found and put them in the temporary folder.
2016-06-16 10:37:04 -07:00
return success ;
}
2016-09-12 22:00:25 -07:00
/// <summary>
2016-10-08 23:28:09 -07:00
/// Process inputs and convert to TorrentZip or TorrentGZ, optionally converting to Romba
2016-09-12 22:00:25 -07:00
/// </summary>
/// <returns>True if processing was a success, false otherwise</returns>
public bool Convert ( )
{
bool success = true ;
// First, check that the output directory exists
2016-09-16 16:35:58 -07:00
if ( ! Directory . Exists ( _outDir ) )
2016-09-12 22:00:25 -07:00
{
2016-09-16 16:35:58 -07:00
Directory . CreateDirectory ( _outDir ) ;
_outDir = Path . GetFullPath ( _outDir ) ;
2016-09-12 22:00:25 -07:00
}
// Then create or clean the temp directory
2016-09-16 16:35:58 -07:00
if ( ! Directory . Exists ( _tempDir ) )
2016-09-12 22:00:25 -07:00
{
2016-09-16 16:35:58 -07:00
Directory . CreateDirectory ( _tempDir ) ;
2016-09-12 22:00:25 -07:00
}
else
{
2016-09-16 16:35:58 -07:00
FileTools . CleanDirectory ( _tempDir ) ;
2016-09-12 22:00:25 -07:00
}
// Now process all of the inputs
foreach ( string input in _inputs )
{
_logger . User ( "Examining file " + input ) ;
// Get if the file should be scanned internally and externally
bool shouldExternalProcess , shouldInternalProcess ;
2016-10-05 17:23:44 -07:00
ArchiveTools . GetInternalExternalProcess ( input , _archiveScanLevel , _logger , out shouldExternalProcess , out shouldInternalProcess ) ;
2016-09-12 22:00:25 -07:00
// Do an external scan of the file, if necessary
if ( shouldExternalProcess )
{
2016-10-05 16:54:52 -07:00
// If a DAT is defined, we want to make sure that this file is not in there
2016-10-08 23:28:09 -07:00
Rom rom = FileTools . GetFileInfo ( input , _logger ) ;
2016-10-05 16:54:52 -07:00
if ( _datdata ! = null & & _datdata . Files . Count > 0 )
{
2016-10-06 16:19:09 -07:00
if ( rom . HasDuplicates ( _datdata , _logger ) )
2016-10-05 16:54:52 -07:00
{
_logger . User ( "File '" + input + "' existed in the DAT, skipping..." ) ;
continue ;
}
}
2016-09-12 22:00:25 -07:00
_logger . User ( "Processing file " + input ) ;
2016-10-08 23:28:09 -07:00
if ( _tgz )
{
success & = ArchiveTools . WriteTorrentGZ ( input , _outDir , _romba , _logger ) ;
}
else
{
success & = ArchiveTools . WriteToArchive ( input , _outDir , rom , _logger ) ;
}
2016-09-12 22:00:25 -07:00
}
// Process the file as an archive, if necessary
if ( shouldInternalProcess )
{
// Now, if the file is a supported archive type, also run on all files within
2016-10-05 17:23:44 -07:00
bool encounteredErrors = ArchiveTools . ExtractArchive ( input , _tempDir , _archiveScanLevel , _logger ) ;
2016-09-12 22:00:25 -07:00
// If no errors were encountered, we loop through the temp directory
if ( ! encounteredErrors )
{
2016-09-23 15:09:00 -07:00
_logger . Verbose ( "Archive found! Successfully extracted" ) ;
2016-09-16 16:35:58 -07:00
foreach ( string file in Directory . EnumerateFiles ( _tempDir , "*" , SearchOption . AllDirectories ) )
2016-09-12 22:00:25 -07:00
{
2016-10-05 16:54:52 -07:00
// If a DAT is defined, we want to make sure that this file is not in there
2016-10-08 23:28:09 -07:00
Rom rom = FileTools . GetFileInfo ( file , _logger ) ;
2016-10-05 16:54:52 -07:00
if ( _datdata ! = null & & _datdata . Files . Count > 0 )
{
2016-10-06 16:19:09 -07:00
if ( rom . HasDuplicates ( _datdata , _logger ) )
2016-10-05 16:54:52 -07:00
{
_logger . User ( "File '" + file + "' existed in the DAT, skipping..." ) ;
continue ;
}
}
2016-10-08 23:28:09 -07:00
_logger . User ( "Processing file " + input ) ;
if ( _tgz )
{
2016-10-19 10:47:23 -07:00
success & = ArchiveTools . WriteTorrentGZ ( file , _outDir , _romba , _logger ) ;
2016-10-08 23:28:09 -07:00
}
else
{
2016-10-19 10:47:23 -07:00
success & = ArchiveTools . WriteToArchive ( file , _outDir , rom , _logger ) ;
2016-10-08 23:28:09 -07:00
}
2016-09-12 22:00:25 -07:00
}
2016-09-16 16:35:58 -07:00
FileTools . CleanDirectory ( _tempDir ) ;
2016-09-12 22:00:25 -07:00
}
}
// Delete the source file if we're supposed to
if ( _delete )
{
try
{
_logger . User ( "Attempting to delete " + input ) ;
File . Delete ( input ) ;
}
catch ( Exception ex )
{
_logger . Error ( ex . ToString ( ) ) ;
success & = false ;
}
}
}
// Now one final delete of the temp directory
2016-09-16 16:35:58 -07:00
while ( Directory . Exists ( _tempDir ) )
2016-09-12 22:00:25 -07:00
{
try
{
2016-09-16 16:35:58 -07:00
Directory . Delete ( _tempDir , true ) ;
2016-09-12 22:00:25 -07:00
}
catch
{
continue ;
}
}
// If we're in romba mode and the size file doesn't exist, create it
2016-09-16 16:35:58 -07:00
if ( _romba & & ! File . Exists ( Path . Combine ( _outDir , ".romba_size" ) ) )
2016-09-12 22:00:25 -07:00
{
// Get the size of all of the files in the output folder
long size = 0 ;
2016-09-16 16:35:58 -07:00
foreach ( string file in Directory . EnumerateFiles ( _outDir , "*" , SearchOption . AllDirectories ) )
2016-09-12 22:00:25 -07:00
{
FileInfo tempinfo = new FileInfo ( file ) ;
size + = tempinfo . Length ;
}
// Write out the value to each of the romba depot files
2016-09-22 15:36:02 -07:00
StreamWriter tw = new StreamWriter ( File . Open ( Path . Combine ( _outDir , ".romba_size" ) , FileMode . Create , FileAccess . Write ) ) ;
StreamWriter twb = new StreamWriter ( File . Open ( Path . Combine ( _outDir , ".romba_size.backup" ) , FileMode . Create , FileAccess . Write ) ) ;
tw . Write ( size ) ;
twb . Write ( size ) ;
tw . Dispose ( ) ;
twb . Dispose ( ) ;
2016-09-12 22:00:25 -07:00
}
return success ;
}
2016-06-13 20:00:44 -07:00
}
2016-09-12 21:27:17 -07:00
}