2020-07-31 23:17:12 -07:00
using System.Collections.Generic ;
using System.IO ;
2020-12-07 13:57:26 -08:00
using SabreTools.Help ;
2020-12-07 15:08:57 -08:00
using SabreTools.IO ;
2020-07-31 23:17:12 -07:00
using SabreTools.Library.DatFiles ;
2020-08-01 22:13:56 -07:00
using SabreTools.Library.FileTypes ;
2020-07-31 23:17:12 -07:00
using SabreTools.Library.Tools ;
namespace SabreTools.Features
{
internal class Sort : BaseFeature
{
public const string Value = "Sort" ;
public Sort ( )
{
Name = Value ;
Flags = new List < string > ( ) { "-ss" , "--sort" } ;
Description = "Sort inputs by a set of DATs" ;
2020-12-07 13:57:26 -08:00
_featureType = ParameterType . Flag ;
2020-07-31 23:17:12 -07:00
LongDescription = "This feature allows the user to quickly rebuild based on a supplied DAT file(s). By default all files will be rebuilt to uncompressed folders in the output directory." ;
Features = new Dictionary < string , Feature > ( ) ;
AddFeature ( DatListInput ) ;
AddFeature ( OutputDirStringInput ) ;
AddFeature ( DepotFlag ) ;
2020-08-18 23:39:13 -07:00
this [ DepotFlag ] . AddFeature ( DepotDepthInt32Input ) ;
2020-07-31 23:17:12 -07:00
AddFeature ( DeleteFlag ) ;
AddFeature ( InverseFlag ) ;
AddFeature ( QuickFlag ) ;
2020-08-27 16:57:22 -07:00
AddFeature ( AaruFormatsAsFilesFlag ) ;
2020-07-31 23:17:12 -07:00
AddFeature ( ChdsAsFilesFlag ) ;
AddFeature ( AddDateFlag ) ;
AddFeature ( IndividualFlag ) ;
// Output Formats
AddFeature ( Torrent7zipFlag ) ;
AddFeature ( TarFlag ) ;
AddFeature ( TorrentGzipFlag ) ;
this [ TorrentGzipFlag ] . AddFeature ( RombaFlag ) ;
2020-08-18 23:39:13 -07:00
this [ TorrentGzipFlag ] [ RombaFlag ] . AddFeature ( RombaDepthInt32Input ) ;
2020-07-31 23:17:12 -07:00
//AddFeature(SharedInputs.TorrentLrzipFlag);
//AddFeature(SharedInputs.TorrentLz4Flag);
//AddFeature(SharedInputs.TorrentRarFlag);
//AddFeature(SharedInputs.TorrentXzFlag);
//this[SharedInputs.TorrentXzFlag].AddFeature(SharedInputs.RombaFlag);
AddFeature ( TorrentZipFlag ) ;
//AddFeature(SharedInputs.TorrentZpaqFlag);
//AddFeature(SharedInputs.TorrentZstdFlag);
AddFeature ( HeaderStringInput ) ;
AddInternalSplitFeatures ( ) ;
AddFeature ( UpdateDatFlag ) ;
AddFeature ( ThreadsInt32Input ) ;
}
public override void ProcessFeatures ( Dictionary < string , Feature > features )
{
base . ProcessFeatures ( features ) ;
// Get feature flags
2020-09-18 00:45:08 -07:00
TreatAsFile asFiles = GetTreatAsFiles ( features ) ;
2020-07-31 23:17:12 -07:00
bool date = GetBoolean ( features , AddDateValue ) ;
bool delete = GetBoolean ( features , DeleteValue ) ;
bool inverse = GetBoolean ( features , InverseValue ) ;
bool quickScan = GetBoolean ( features , QuickValue ) ;
bool updateDat = GetBoolean ( features , UpdateDatValue ) ;
var outputFormat = GetOutputFormat ( features ) ;
2020-08-28 01:13:55 -07:00
// If we have the romba flag
if ( Header . OutputDepot ? . IsActive = = true )
{
// Update TorrentGzip output
if ( outputFormat = = OutputFormat . TorrentGzip )
outputFormat = OutputFormat . TorrentGzipRomba ;
2020-07-31 23:17:12 -07:00
2020-08-28 01:13:55 -07:00
// Update TorrentXz output
else if ( outputFormat = = OutputFormat . TorrentXZ )
outputFormat = OutputFormat . TorrentXZRomba ;
}
2020-07-31 23:17:12 -07:00
// Get a list of files from the input datfiles
var datfiles = GetList ( features , DatListValue ) ;
var datfilePaths = DirectoryExtensions . GetFilesOnly ( datfiles ) ;
// If we are in individual mode, process each DAT on their own, appending the DAT name to the output dir
if ( GetBoolean ( features , IndividualValue ) )
{
foreach ( ParentablePath datfile in datfilePaths )
{
DatFile datdata = DatFile . Create ( ) ;
2020-09-18 11:40:21 -07:00
datdata . Parse ( datfile , int . MaxValue , keep : true ) ;
2020-08-02 12:55:39 -07:00
2020-08-20 11:23:48 -07:00
// Set depot information
datdata . Header . InputDepot = Header . InputDepot . Clone ( ) as DepotInformation ;
datdata . Header . OutputDepot = Header . OutputDepot . Clone ( ) as DepotInformation ;
2020-08-02 12:55:39 -07:00
// If we have overridden the header skipper, set it now
2020-08-02 12:54:27 -07:00
if ( ! string . IsNullOrEmpty ( Header . HeaderSkipper ) )
datdata . Header . HeaderSkipper = Header . HeaderSkipper ;
2020-07-31 23:17:12 -07:00
// If we have the depot flag, respect it
2020-08-28 22:38:10 -07:00
bool success ;
2020-08-24 11:56:49 -07:00
if ( Header . InputDepot ? . IsActive ? ? false )
2020-08-28 22:38:10 -07:00
success = datdata . RebuildDepot ( Inputs , Path . Combine ( OutputDir , datdata . Header . FileName ) , date , delete , inverse , outputFormat ) ;
2020-07-31 23:17:12 -07:00
else
2020-08-28 22:38:10 -07:00
success = datdata . RebuildGeneric ( Inputs , Path . Combine ( OutputDir , datdata . Header . FileName ) , quickScan , date , delete , inverse , outputFormat , asFiles ) ;
// If we have a success and we're updating the DAT, write it out
if ( success & & updateDat )
{
datdata . Header . FileName = $"fixDAT_{Header.FileName}" ;
datdata . Header . Name = $"fixDAT_{Header.Name}" ;
datdata . Header . Description = $"fixDAT_{Header.Description}" ;
datdata . Items . ClearMarked ( ) ;
datdata . Write ( OutputDir ) ;
}
2020-07-31 23:17:12 -07:00
}
}
// Otherwise, process all DATs into the same output
else
{
InternalStopwatch watch = new InternalStopwatch ( "Populating internal DAT" ) ;
// Add all of the input DATs into one huge internal DAT
DatFile datdata = DatFile . Create ( ) ;
foreach ( ParentablePath datfile in datfilePaths )
{
2020-09-18 11:40:21 -07:00
datdata . Parse ( datfile , int . MaxValue , keep : true ) ;
2020-07-31 23:17:12 -07:00
}
2020-08-20 11:23:48 -07:00
// Set depot information
datdata . Header . InputDepot = Header . InputDepot . Clone ( ) as DepotInformation ;
datdata . Header . OutputDepot = Header . OutputDepot . Clone ( ) as DepotInformation ;
2020-08-02 12:55:39 -07:00
// If we have overridden the header skipper, set it now
if ( ! string . IsNullOrEmpty ( Header . HeaderSkipper ) )
datdata . Header . HeaderSkipper = Header . HeaderSkipper ;
2020-07-31 23:17:12 -07:00
watch . Stop ( ) ;
// If we have the depot flag, respect it
2020-08-28 22:38:10 -07:00
bool success ;
2020-08-24 11:56:49 -07:00
if ( Header . InputDepot ? . IsActive ? ? false )
2020-08-28 22:38:10 -07:00
success = datdata . RebuildDepot ( Inputs , OutputDir , date , delete , inverse , outputFormat ) ;
2020-07-31 23:17:12 -07:00
else
2020-08-28 22:38:10 -07:00
success = datdata . RebuildGeneric ( Inputs , OutputDir , quickScan , date , delete , inverse , outputFormat , asFiles ) ;
// If we have a success and we're updating the DAT, write it out
if ( success & & updateDat )
{
datdata . Header . FileName = $"fixDAT_{Header.FileName}" ;
datdata . Header . Name = $"fixDAT_{Header.Name}" ;
datdata . Header . Description = $"fixDAT_{Header.Description}" ;
datdata . Items . ClearMarked ( ) ;
datdata . Write ( OutputDir ) ;
}
2020-07-31 23:17:12 -07:00
}
}
}
}