Beispiel #1
0
        public override bool ProcessFeatures(Dictionary <string, SabreTools.Help.Feature> features)
        {
            // If the base fails, just fail out
            if (!base.ProcessFeatures(features))
            {
                return(false);
            }

            // Get the archive scanning level
            // TODO: Remove usage
            int sevenzip = GetInt32(features, Include7ZipsInt32Value);
            int gz       = GetInt32(features, IncludeGZipsInt32Value);
            int zip      = GetInt32(features, IncludeZipsInt32Value);

            // Get feature flags
            bool noDb       = GetBoolean(features, NoDbValue);
            bool onlyNeeded = GetBoolean(features, OnlyNeededValue);

            // First we want to get just all directories from the inputs
            List <string> onlyDirs = new List <string>();

            foreach (string input in Inputs)
            {
                if (Directory.Exists(input))
                {
                    onlyDirs.Add(Path.GetFullPath(input));
                }
            }

            // Then process all of the input directories into an internal DAT
            DatFile df = DatFile.Create();

            foreach (string dir in onlyDirs)
            {
                DatFromDir.PopulateFromDir(df, dir, asFiles: TreatAsFile.NonArchive, hashes: Hash.Standard);
                DatFromDir.PopulateFromDir(df, dir, asFiles: TreatAsFile.All, hashes: Hash.Standard);
            }

            // Create an empty Dat for files that need to be rebuilt
            DatFile need = DatFile.Create();

            // Open the database connection
            SqliteConnection dbc = new SqliteConnection(_connectionString);

            dbc.Open();

            // Now that we have the Dats, add the files to the database
            string crcquery     = "INSERT OR IGNORE INTO crc (crc) VALUES";
            string md5query     = "INSERT OR IGNORE INTO md5 (md5) VALUES";
            string sha1query    = "INSERT OR IGNORE INTO sha1 (sha1, depot) VALUES";
            string crcsha1query = "INSERT OR IGNORE INTO crcsha1 (crc, sha1) VALUES";
            string md5sha1query = "INSERT OR IGNORE INTO md5sha1 (md5, sha1) VALUES";

            foreach (string key in df.Items.Keys)
            {
                ConcurrentList <DatItem> datItems = df.Items[key];
                foreach (Rom rom in datItems)
                {
                    // If we care about if the file exists, check the databse first
                    if (onlyNeeded && !noDb)
                    {
                        string query = "SELECT * FROM crcsha1 JOIN md5sha1 ON crcsha1.sha1=md5sha1.sha1"
                                       + $" WHERE crcsha1.crc=\"{rom.CRC}\""
                                       + $" OR md5sha1.md5=\"{rom.MD5}\""
                                       + $" OR md5sha1.sha1=\"{rom.SHA1}\"";
                        SqliteCommand    slc  = new SqliteCommand(query, dbc);
                        SqliteDataReader sldr = slc.ExecuteReader();

                        if (sldr.HasRows)
                        {
                            // Add to the queries
                            if (!string.IsNullOrWhiteSpace(rom.CRC))
                            {
                                crcquery += $" (\"{rom.CRC}\"),";
                            }

                            if (!string.IsNullOrWhiteSpace(rom.MD5))
                            {
                                md5query += $" (\"{rom.MD5}\"),";
                            }

                            if (!string.IsNullOrWhiteSpace(rom.SHA1))
                            {
                                sha1query += $" (\"{rom.SHA1}\", \"{_depots.Keys.ToList()[0]}\"),";

                                if (!string.IsNullOrWhiteSpace(rom.CRC))
                                {
                                    crcsha1query += $" (\"{rom.CRC}\", \"{rom.SHA1}\"),";
                                }

                                if (!string.IsNullOrWhiteSpace(rom.MD5))
                                {
                                    md5sha1query += $" (\"{rom.MD5}\", \"{rom.SHA1}\"),";
                                }
                            }

                            // Add to the Dat
                            need.Items.Add(key, rom);
                        }
                    }
                    // Otherwise, just add the file to the list
                    else
                    {
                        // Add to the queries
                        if (!noDb)
                        {
                            if (!string.IsNullOrWhiteSpace(rom.CRC))
                            {
                                crcquery += $" (\"{rom.CRC}\"),";
                            }

                            if (!string.IsNullOrWhiteSpace(rom.MD5))
                            {
                                md5query += $" (\"{rom.MD5}\"),";
                            }

                            if (!string.IsNullOrWhiteSpace(rom.SHA1))
                            {
                                sha1query += $" (\"{rom.SHA1}\", \"{_depots.Keys.ToList()[0]}\"),";

                                if (!string.IsNullOrWhiteSpace(rom.CRC))
                                {
                                    crcsha1query += $" (\"{rom.CRC}\", \"{rom.SHA1}\"),";
                                }

                                if (!string.IsNullOrWhiteSpace(rom.MD5))
                                {
                                    md5sha1query += $" (\"{rom.MD5}\", \"{rom.SHA1}\"),";
                                }
                            }
                        }

                        // Add to the Dat
                        need.Items.Add(key, rom);
                    }
                }
            }

            // Now run the queries, if they're populated
            if (crcquery != "INSERT OR IGNORE INTO crc (crc) VALUES")
            {
                SqliteCommand slc = new SqliteCommand(crcquery.TrimEnd(','), dbc);
                slc.ExecuteNonQuery();
                slc.Dispose();
            }

            if (md5query != "INSERT OR IGNORE INTO md5 (md5) VALUES")
            {
                SqliteCommand slc = new SqliteCommand(md5query.TrimEnd(','), dbc);
                slc.ExecuteNonQuery();
                slc.Dispose();
            }

            if (sha1query != "INSERT OR IGNORE INTO sha1 (sha1, depot) VALUES")
            {
                SqliteCommand slc = new SqliteCommand(sha1query.TrimEnd(','), dbc);
                slc.ExecuteNonQuery();
                slc.Dispose();
            }

            if (crcsha1query != "INSERT OR IGNORE INTO crcsha1 (crc, sha1) VALUES")
            {
                SqliteCommand slc = new SqliteCommand(crcsha1query.TrimEnd(','), dbc);
                slc.ExecuteNonQuery();
                slc.Dispose();
            }

            if (md5sha1query != "INSERT OR IGNORE INTO md5sha1 (md5, sha1) VALUES")
            {
                SqliteCommand slc = new SqliteCommand(md5sha1query.TrimEnd(','), dbc);
                slc.ExecuteNonQuery();
                slc.Dispose();
            }

            // Create the sorting object to use and rebuild the needed files
            Rebuilder.RebuildGeneric(
                need,
                onlyDirs,
                outDir: _depots.Keys.ToList()[0],
                outputFormat: OutputFormat.TorrentGzipRomba,
                asFiles: TreatAsFile.NonArchive);

            return(true);
        }
Beispiel #2
0
        public override bool ProcessFeatures(Dictionary <string, Feature> features)
        {
            // If the base fails, just fail out
            if (!base.ProcessFeatures(features))
            {
                return(false);
            }

            // Get feature flags
            TreatAsFile asFiles      = GetTreatAsFiles(features);
            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);

            // If we have the romba flag
            if (Header.OutputDepot?.IsActive == true)
            {
                // Update TorrentGzip output
                if (outputFormat == OutputFormat.TorrentGzip)
                {
                    outputFormat = OutputFormat.TorrentGzipRomba;
                }

                // Update TorrentXz output
                else if (outputFormat == OutputFormat.TorrentXZ)
                {
                    outputFormat = OutputFormat.TorrentXZRomba;
                }
            }

            // Get a list of files from the input datfiles
            var datfiles     = GetList(features, DatListValue);
            var datfilePaths = PathTool.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();
                    Parser.ParseInto(datdata, datfile, int.MaxValue, keep: true);

                    // Set depot information
                    datdata.Header.InputDepot  = Header.InputDepot?.Clone() as DepotInformation;
                    datdata.Header.OutputDepot = Header.OutputDepot?.Clone() as DepotInformation;

                    // If we have overridden the header skipper, set it now
                    if (!string.IsNullOrEmpty(Header.HeaderSkipper))
                    {
                        datdata.Header.HeaderSkipper = Header.HeaderSkipper;
                    }

                    // If we have the depot flag, respect it
                    bool success;
                    if (Header.InputDepot?.IsActive ?? false)
                    {
                        success = Rebuilder.RebuildDepot(datdata, Inputs, Path.Combine(OutputDir, datdata.Header.FileName), date, delete, inverse, outputFormat);
                    }
                    else
                    {
                        success = Rebuilder.RebuildGeneric(datdata, 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();
                        Writer.Write(datdata, OutputDir);
                    }
                }
            }

            // 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)
                {
                    Parser.ParseInto(datdata, datfile, int.MaxValue, keep: true);
                }

                // Set depot information
                datdata.Header.InputDepot  = Header.InputDepot?.Clone() as DepotInformation;
                datdata.Header.OutputDepot = Header.OutputDepot?.Clone() as DepotInformation;

                // If we have overridden the header skipper, set it now
                if (!string.IsNullOrEmpty(Header.HeaderSkipper))
                {
                    datdata.Header.HeaderSkipper = Header.HeaderSkipper;
                }

                watch.Stop();

                // If we have the depot flag, respect it
                bool success;
                if (Header.InputDepot?.IsActive ?? false)
                {
                    success = Rebuilder.RebuildDepot(datdata, Inputs, OutputDir, date, delete, inverse, outputFormat);
                }
                else
                {
                    success = Rebuilder.RebuildGeneric(datdata, 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();
                    Writer.Write(datdata, OutputDir);
                }
            }

            return(true);
        }