diff --git a/SabreTools.RedumpLib/Web/Client.cs b/SabreTools.RedumpLib/Web/Client.cs index 00b4db0..ddd3877 100644 --- a/SabreTools.RedumpLib/Web/Client.cs +++ b/SabreTools.RedumpLib/Web/Client.cs @@ -635,21 +635,21 @@ namespace SabreTools.RedumpLib.Web // If the web client failed, return null if (dumpsPage is null) { - if (Debug) ReportDebug($"CheckSingleDiscsPage(\"{url}\") - Client failure"); + if (Debug) ReportDebug($"CheckSingleDiscsEndpoint(\"{url}\") - Client failure"); return null; } // If we have no dumps left if (dumpsPage.Contains("No discs found.")) { - if (Debug) ReportDebug($"CheckSingleDiscsPage(\"{url}\") - No discs found"); + if (Debug) ReportDebug($"CheckSingleDiscsEndpoint(\"{url}\") - No discs found"); return ids; } // If we have a single disc page already if (dumpsPage.Contains("

Disc

")) { - if (Debug) ReportDebug($"CheckSingleDiscsPage(\"{url}\") - Single disc page"); + if (Debug) ReportDebug($"CheckSingleDiscsEndpoint(\"{url}\") - Single disc page"); string? lastUrl = await GetResolvedURL(url); if (lastUrl is not null) { @@ -699,7 +699,88 @@ namespace SabreTools.RedumpLib.Web List? ids = await CheckSingleDiscsEndpoint(endpoint); if (ids is null) { - if (Debug) ReportDebug($"CheckSingleDiscsPage(\"{outDir}\") - Client failure"); + if (Debug) ReportDebug($"CheckSingleDiscsEndpoint(\"{outDir}\") - Client failure"); + return null; + } + + // Try to download all IDs + List processed = []; + foreach (int id in ids) + { + try + { + var discEndpoint = new Endpoints.Disc { Id = id }; + bool downloaded = await DownloadSingleDiscEndpoint(discEndpoint, outDir, rename: false, discSubpaths); + if (!downloaded && !IgnoreErrors) + return processed; + + processed.Add(id); + } + catch (Exception ex) + { + ReportError(ex); + continue; + } + } + + return processed; + } + + /// + /// Process a Redump API discs endpoint as a list of possible IDs or disc page + /// + /// API discs endpoint to process + /// List of IDs from the endpoint, empty on none, null on error + public async Task?> CheckSingleDiscsApiEndpoint(Endpoints.Api endpoint) + { + // Ensure that the endpoint is for discs + if (endpoint.Subpath != ApiSubpath.Discs) + { + ReportError("Only a discs API query is allowed!"); + return null; + } + + string url = endpoint.BuildUrl(); + + // Try to retrieve the data + string? dumpsPage = await DownloadString(url); + + // If the web client failed, return null + if (dumpsPage is null) + { + if (Debug) ReportDebug($"CheckSingleDiscsApiEndpoint(\"{url}\") - Client failure"); + return null; + } + + // Try to deserialize the data into a list of IDs + try + { + return JsonConvert.DeserializeObject?>(dumpsPage); + } + catch (Exception ex) + { + ReportError(ex); + return null; + } + } + + /// + /// Process a Redump API discs endpoint as a list of possible IDs or disc page + /// + /// Output directory to save data to + /// API discs endpoint to process + /// Set of subpaths to download if available, null for all + /// List of IDs from the endpoint, empty on none, null on error + public async Task?> CheckSingleDiscsApiEndpoint( + string? outDir, + Endpoints.Api endpoint, + DiscSubpath[]? discSubpaths = null) + { + // Get all IDs from the page + List? ids = await CheckSingleDiscsApiEndpoint(endpoint); + if (ids is null) + { + if (Debug) ReportDebug($"CheckSingleDiscsApiEndpoint(\"{outDir}\") - Client failure"); return null; } diff --git a/SabreTools.RedumpLib/Web/Discs.cs b/SabreTools.RedumpLib/Web/Discs.cs index d19a0cc..1d46c2a 100644 --- a/SabreTools.RedumpLib/Web/Discs.cs +++ b/SabreTools.RedumpLib/Web/Discs.cs @@ -408,5 +408,40 @@ namespace SabreTools.RedumpLib.Web return ids; } + + /// + /// List the disc IDs associated with a given discs API query + /// + /// RedumpClient for connectivity + /// Use CRC-32 value for searching; incomplatible with and + /// Use MD5 value for searching; incomplatible with and + /// Use CRC-32 value for searching; incomplatible with and + /// All disc IDs for the given query, empty on error + public static async Task> ListDiscsApiResults( + this Client client, + string? crc32 = null, + string? md5 = null, + string? sha1 = null) + { + // If there is an invalid combination of hashes + if (crc32 is null && md5 is null && sha1 is null) + return []; + else if (crc32 is not null && (md5 is not null || sha1 is not null)) + return []; + else if (md5 is not null && (crc32 is not null || sha1 is not null)) + return []; + else if (sha1 is not null && (crc32 is not null || md5 is not null)) + return []; + + var endpoint = new Endpoints.Api + { + Subpath = ApiSubpath.Discs, + Crc32 = crc32, + Md5 = md5, + Sha1 = sha1, + }; + + return await client.CheckSingleDiscsApiEndpoint(endpoint) ?? []; + } } }