Compare commits

..

4 Commits
1.5.0 ... 1.5.2

Author SHA1 Message Date
Matt Nadareski
415b488005 Bump version 2024-11-14 22:23:20 -05:00
Matt Nadareski
5d300c9975 Make download helpers public for ease 2024-11-14 22:22:52 -05:00
Matt Nadareski
304236774f Bump version 2024-11-13 01:54:40 -05:00
Matt Nadareski
9924289c48 Fix casting issues 2024-11-13 01:54:24 -05:00
5 changed files with 301 additions and 189 deletions

View File

@@ -15,8 +15,8 @@ namespace SabreTools.RedumpLib.Test
/// <summary>
/// DiscType values that map to MediaType
/// </summary>
private static readonly DiscType?[] _mappableDiscTypes = new DiscType?[]
{
private static readonly DiscType?[] _mappableDiscTypes =
[
DiscType.BD25,
DiscType.BD33,
DiscType.BD50,
@@ -35,13 +35,13 @@ namespace SabreTools.RedumpLib.Test
DiscType.NintendoWiiUOpticalDiscSL,
DiscType.UMDSL,
DiscType.UMDDL,
};
];
/// <summary>
/// MediaType values that map to DiscType
/// </summary>
private static readonly MediaType?[] _mappableMediaTypes = new MediaType?[]
{
private static readonly MediaType?[] _mappableMediaTypes =
[
MediaType.BluRay,
MediaType.CDROM,
MediaType.DVD,
@@ -51,7 +51,7 @@ namespace SabreTools.RedumpLib.Test
MediaType.NintendoWiiOpticalDisc,
MediaType.NintendoWiiUOpticalDisc,
MediaType.UMD,
};
];
/// <summary>
/// Check that every supported system has some set of MediaTypes supported
@@ -101,9 +101,9 @@ namespace SabreTools.RedumpLib.Test
foreach (DiscType? discType in Enum.GetValues(typeof(DiscType)))
{
if (_mappableDiscTypes.Contains(discType))
testData.Add(new object?[] { discType, false });
testData.Add([discType, false]);
else
testData.Add(new object?[] { discType, true });
testData.Add([discType, true]);
}
return testData;
@@ -118,7 +118,7 @@ namespace SabreTools.RedumpLib.Test
var testData = new List<object?[]>() { new object?[] { null } };
foreach (RedumpSystem? redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
{
testData.Add(new object?[] { redumpSystem });
testData.Add([redumpSystem]);
}
return testData;
@@ -135,9 +135,9 @@ namespace SabreTools.RedumpLib.Test
foreach (MediaType? mediaType in Enum.GetValues(typeof(MediaType)))
{
if (_mappableMediaTypes.Contains(mediaType))
testData.Add(new object?[] { mediaType, false });
testData.Add([mediaType, false]);
else
testData.Add(new object?[] { mediaType, true });
testData.Add([mediaType, true]);
}
return testData;
@@ -173,7 +173,7 @@ namespace SabreTools.RedumpLib.Test
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (DiscCategory? discCategory in Enum.GetValues(typeof(DiscCategory)))
{
testData.Add(new object?[] { discCategory, false });
testData.Add([discCategory, false]);
}
return testData;
@@ -210,9 +210,9 @@ namespace SabreTools.RedumpLib.Test
foreach (DiscType? discType in Enum.GetValues(typeof(DiscType)))
{
if (discType == DiscType.NONE)
testData.Add(new object?[] { discType, true });
testData.Add([discType, true]);
else
testData.Add(new object?[] { discType, false });
testData.Add([discType, false]);
}
return testData;
@@ -346,7 +346,7 @@ namespace SabreTools.RedumpLib.Test
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (Language? language in Enum.GetValues(typeof(Language)))
{
testData.Add(new object?[] { language, false });
testData.Add([language, false]);
}
return testData;
@@ -382,7 +382,7 @@ namespace SabreTools.RedumpLib.Test
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (LanguageSelection? languageSelection in Enum.GetValues(typeof(LanguageSelection)))
{
testData.Add(new object?[] { languageSelection, false });
testData.Add([languageSelection, false]);
}
return testData;
@@ -435,7 +435,7 @@ namespace SabreTools.RedumpLib.Test
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (MediaType? mediaType in Enum.GetValues(typeof(MediaType)))
{
testData.Add(new object?[] { mediaType, false });
testData.Add([mediaType, false]);
}
return testData;
@@ -515,7 +515,7 @@ namespace SabreTools.RedumpLib.Test
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (Region? region in Enum.GetValues(typeof(Region)))
{
testData.Add(new object?[] { region, false });
testData.Add([region, false]);
}
return testData;
@@ -568,7 +568,7 @@ namespace SabreTools.RedumpLib.Test
var testData = new List<object?[]>() { new object?[] { null, true } };
foreach (SiteCode? siteCode in Enum.GetValues(typeof(SiteCode)))
{
testData.Add(new object?[] { siteCode, false });
testData.Add([siteCode, false]);
}
return testData;
@@ -631,7 +631,7 @@ namespace SabreTools.RedumpLib.Test
if (redumpSystem.IsMarker())
continue;
testData.Add(new object?[] { redumpSystem, false });
testData.Add([redumpSystem, false]);
}
return testData;
@@ -668,9 +668,9 @@ namespace SabreTools.RedumpLib.Test
foreach (SystemCategory? systemCategory in Enum.GetValues(typeof(SystemCategory)))
{
if (systemCategory == SystemCategory.NONE)
testData.Add(new object?[] { systemCategory, true });
testData.Add([systemCategory, true]);
else
testData.Add(new object?[] { systemCategory, false });
testData.Add([systemCategory, false]);
}
return testData;
@@ -706,7 +706,7 @@ namespace SabreTools.RedumpLib.Test
var testData = new List<object?[]>() { new object?[] { null, false } };
foreach (YesNo? yesNo in Enum.GetValues(typeof(YesNo)))
{
testData.Add(new object?[] { yesNo, false });
testData.Add([yesNo, false]);
}
return testData;

View File

@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
#if NET40_OR_GREATER || NETCOREAPP
using System.Linq;
#endif
using SabreTools.RedumpLib.Attributes;
namespace SabreTools.RedumpLib.Data
@@ -928,65 +925,35 @@ namespace SabreTools.RedumpLib.Data
/// <returns>Language represented by the string, if possible</returns>
public static Language? ToLanguage(string lang)
{
var languages = (Language?[])Enum.GetValues(typeof(Language));
lang = lang.ToLowerInvariant();
var languages = (Language[])Enum.GetValues(typeof(Language));
// Check ISO 639-1 codes
#if NET20 || NET35
var languageMapping = new Dictionary<string, Language?>();
foreach (var l in languages)
{
if (l.TwoLetterCode() == null)
continue;
languageMapping[l.TwoLetterCode() ?? string.Empty] = l;
}
#else
Dictionary<string, Language?> languageMapping = Array.FindAll(languages, l => l.TwoLetterCode() != null)
.ToDictionary(l => l.TwoLetterCode() ?? string.Empty, l => l);
#endif
if (languageMapping.ContainsKey(lang))
return languageMapping[lang];
int index = Array.FindIndex(languages, l => lang == l.TwoLetterCode());
if (index > -1)
return languages[index];
// Check standard ISO 639-2 codes
#if NET20 || NET35
languageMapping = new Dictionary<string, Language?>();
foreach (var l in languages)
{
if (l.ThreeLetterCode() == null)
continue;
languageMapping[l.ThreeLetterCode() ?? string.Empty] = l;
}
#else
languageMapping = Array.FindAll(languages, l => l.ThreeLetterCode() != null)
.ToDictionary(l => l.ThreeLetterCode() ?? string.Empty, l => l);
#endif
if (languageMapping.ContainsKey(lang))
return languageMapping[lang];
index = Array.FindIndex(languages, r => lang == r.ThreeLetterCode());
if (index > -1)
return languages[index];
// Check alternate ISO 639-2 codes
#if NET20 || NET35
languageMapping = new Dictionary<string, Language?>();
foreach (var l in languages)
{
if (l.ThreeLetterCodeAlt() == null)
continue;
languageMapping[l.ThreeLetterCodeAlt() ?? string.Empty] = l;
}
#else
languageMapping = Array.FindAll(languages, l => l.ThreeLetterCodeAlt() != null)
.ToDictionary(l => l.ThreeLetterCodeAlt() ?? string.Empty, l => l);
#endif
if (languageMapping.ContainsKey(lang))
return languageMapping[lang];
index = Array.FindIndex(languages, r => lang == r.ThreeLetterCodeAlt());
if (index > -1)
return languages[index];
return null;
}
/// <summary>
/// Get the ISO 639-2 code for each known language
/// </summary>
/// <param name="language"></param>
/// <returns></returns>
public static string? ThreeLetterCode(this Language language)
=> (AttributeHelper<Language>.GetAttribute(language) as LanguageAttribute)?.ThreeLetterCode;
/// <summary>
/// Get the ISO 639-2 code for each known language
/// </summary>
@@ -995,6 +962,14 @@ namespace SabreTools.RedumpLib.Data
public static string? ThreeLetterCode(this Language? language)
=> (AttributeHelper<Language?>.GetAttribute(language) as LanguageAttribute)?.ThreeLetterCode;
/// <summary>
/// Get the ISO 639-2 alternate code for each known language
/// </summary>
/// <param name="language"></param>
/// <returns></returns>
public static string? ThreeLetterCodeAlt(this Language language)
=> (AttributeHelper<Language>.GetAttribute(language) as LanguageAttribute)?.ThreeLetterCodeAlt;
/// <summary>
/// Get the ISO 639-2 alternate code for each known language
/// </summary>
@@ -1003,6 +978,14 @@ namespace SabreTools.RedumpLib.Data
public static string? ThreeLetterCodeAlt(this Language? language)
=> (AttributeHelper<Language?>.GetAttribute(language) as LanguageAttribute)?.ThreeLetterCodeAlt;
/// <summary>
/// Get the ISO 639-1 code for each known language
/// </summary>
/// <param name="language"></param>
/// <returns></returns>
public static string? TwoLetterCode(this Language language)
=> (AttributeHelper<Language>.GetAttribute(language) as LanguageAttribute)?.TwoLetterCode;
/// <summary>
/// Get the ISO 639-1 code for each known language
/// </summary>
@@ -1090,14 +1073,32 @@ namespace SabreTools.RedumpLib.Data
/// </summary>
/// <param name="region"></param>
/// <returns></returns>
public static string? LongName(this Region? region) => AttributeHelper<Region?>.GetAttribute(region)?.LongName;
public static string? LongName(this Region region)
=> AttributeHelper<Region>.GetAttribute(region)?.LongName;
/// <summary>
/// Get the Redump longnames for each known region
/// </summary>
/// <param name="region"></param>
/// <returns></returns>
public static string? LongName(this Region? region)
=> AttributeHelper<Region?>.GetAttribute(region)?.LongName;
/// <summary>
/// Get the Redump shortnames for each known region
/// </summary>
/// <param name="region"></param>
/// <returns></returns>
public static string? ShortName(this Region? region) => AttributeHelper<Region?>.GetAttribute(region)?.ShortName;
public static string? ShortName(this Region region)
=> AttributeHelper<Region>.GetAttribute(region)?.ShortName;
/// <summary>
/// Get the Redump shortnames for each known region
/// </summary>
/// <param name="region"></param>
/// <returns></returns>
public static string? ShortName(this Region? region)
=> AttributeHelper<Region?>.GetAttribute(region)?.ShortName;
/// <summary>
/// Get the Region enum value for a given string
@@ -1107,25 +1108,15 @@ namespace SabreTools.RedumpLib.Data
public static Region? ToRegion(string region)
{
region = region.ToLowerInvariant();
var regions = (Region?[])Enum.GetValues(typeof(Region));
var regions = (Region[])Enum.GetValues(typeof(Region));
// Check ISO 3166-1 alpha-2 codes
#if NET20 || NET35
var regionMapping = new Dictionary<string, Region?>();
foreach (var r in regions)
{
if (r.ShortName() == null)
continue;
int index = Array.FindIndex(regions, r => region == r.ShortName());
if (index > -1)
return regions[index];
regionMapping[r.ShortName()?.ToLowerInvariant() ?? string.Empty] = r;
}
#else
Dictionary<string, Region?> regionMapping = Array.FindAll(regions, r => r.ShortName() != null)
.ToDictionary(r => r.ShortName()?.ToLowerInvariant() ?? string.Empty, r => r);
#endif
if (regionMapping.ContainsKey(region))
return regionMapping[region];
index = Array.FindIndex(regions, r => region == r.LongName());
if (index > -1)
return regions[index];
return null;
}
@@ -1442,64 +1433,146 @@ namespace SabreTools.RedumpLib.Data
/// </summary>
/// <param name="system"></param>
/// <returns></returns>
public static string? LongName(this RedumpSystem? system) => AttributeHelper<RedumpSystem?>.GetAttribute(system)?.LongName;
public static string? LongName(this RedumpSystem system)
=> AttributeHelper<RedumpSystem>.GetAttribute(system)?.LongName;
/// <summary>
/// Get the Redump longnames for each known system
/// </summary>
/// <param name="system"></param>
/// <returns></returns>
public static string? LongName(this RedumpSystem? system)
=> AttributeHelper<RedumpSystem?>.GetAttribute(system)?.LongName;
/// <summary>
/// Get the Redump shortnames for each known system
/// </summary>
/// <param name="system"></param>
/// <returns></returns>
public static string? ShortName(this RedumpSystem? system) => AttributeHelper<RedumpSystem?>.GetAttribute(system)?.ShortName;
public static string? ShortName(this RedumpSystem system)
=> AttributeHelper<RedumpSystem>.GetAttribute(system)?.ShortName;
/// <summary>
/// Get the Redump shortnames for each known system
/// </summary>
/// <param name="system"></param>
/// <returns></returns>
public static string? ShortName(this RedumpSystem? system)
=> AttributeHelper<RedumpSystem?>.GetAttribute(system)?.ShortName;
/// <summary>
/// Determine the category of a system
/// </summary>
public static SystemCategory GetCategory(this RedumpSystem? system) => (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.Category ?? SystemCategory.NONE;
public static SystemCategory GetCategory(this RedumpSystem? system)
=> (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.Category ?? SystemCategory.NONE;
/// <summary>
/// Determine if a system is available in Redump yet
/// </summary>
public static bool IsAvailable(this RedumpSystem? system) => (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.Available ?? false;
public static bool IsAvailable(this RedumpSystem system)
=> (AttributeHelper<RedumpSystem>.GetAttribute(system) as SystemAttribute)?.Available ?? false;
/// <summary>
/// Determine if a system is available in Redump yet
/// </summary>
public static bool IsAvailable(this RedumpSystem? system)
=> (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.Available ?? false;
/// <summary>
/// Determine if a system is restricted to dumpers
/// </summary>
public static bool IsBanned(this RedumpSystem? system) => (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.IsBanned ?? false;
public static bool IsBanned(this RedumpSystem system)
=> (AttributeHelper<RedumpSystem>.GetAttribute(system) as SystemAttribute)?.IsBanned ?? false;
/// <summary>
/// Determine if a system is restricted to dumpers
/// </summary>
public static bool IsBanned(this RedumpSystem? system)
=> (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.IsBanned ?? false;
/// <summary>
/// Determine if a system has a CUE pack
/// </summary>
public static bool HasCues(this RedumpSystem? system) => (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasCues ?? false;
public static bool HasCues(this RedumpSystem system)
=> (AttributeHelper<RedumpSystem>.GetAttribute(system) as SystemAttribute)?.HasCues ?? false;
/// <summary>
/// Determine if a system has a CUE pack
/// </summary>
public static bool HasCues(this RedumpSystem? system)
=> (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasCues ?? false;
/// <summary>
/// Determine if a system has a DAT
/// </summary>
public static bool HasDat(this RedumpSystem? system) => (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasDat ?? false;
public static bool HasDat(this RedumpSystem system)
=> (AttributeHelper<RedumpSystem>.GetAttribute(system) as SystemAttribute)?.HasDat ?? false;
/// <summary>
/// Determine if a system has a DAT
/// </summary>
public static bool HasDat(this RedumpSystem? system)
=> (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasDat ?? false;
/// <summary>
/// Determine if a system has a decrypted keys pack
/// </summary>
public static bool HasDkeys(this RedumpSystem? system) => (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasDkeys ?? false;
public static bool HasDkeys(this RedumpSystem system)
=> (AttributeHelper<RedumpSystem>.GetAttribute(system) as SystemAttribute)?.HasDkeys ?? false;
/// <summary>
/// Determine if a system has a decrypted keys pack
/// </summary>
public static bool HasDkeys(this RedumpSystem? system)
=> (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasDkeys ?? false;
/// <summary>
/// Determine if a system has a GDI pack
/// </summary>
public static bool HasGdi(this RedumpSystem? system) => (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasGdi ?? false;
public static bool HasGdi(this RedumpSystem system)
=> (AttributeHelper<RedumpSystem>.GetAttribute(system) as SystemAttribute)?.HasGdi ?? false;
/// <summary>
/// Determine if a system has a GDI pack
/// </summary>
public static bool HasGdi(this RedumpSystem? system)
=> (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasGdi ?? false;
/// <summary>
/// Determine if a system has a keys pack
/// </summary>
public static bool HasKeys(this RedumpSystem? system) => (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasKeys ?? false;
public static bool HasKeys(this RedumpSystem system)
=> (AttributeHelper<RedumpSystem>.GetAttribute(system) as SystemAttribute)?.HasKeys ?? false;
/// <summary>
/// Determine if a system has a keys pack
/// </summary>
public static bool HasKeys(this RedumpSystem? system)
=> (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasKeys ?? false;
/// <summary>
/// Determine if a system has an LSD pack
/// </summary>
public static bool HasLsd(this RedumpSystem? system) => (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasLsd ?? false;
public static bool HasLsd(this RedumpSystem system)
=> (AttributeHelper<RedumpSystem>.GetAttribute(system) as SystemAttribute)?.HasLsd ?? false;
/// <summary>
/// Determine if a system has an LSD pack
/// </summary>
public static bool HasLsd(this RedumpSystem? system)
=> (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasLsd ?? false;
/// <summary>
/// Determine if a system has an SBI pack
/// </summary>
public static bool HasSbi(this RedumpSystem? system) => (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasSbi ?? false;
public static bool HasSbi(this RedumpSystem system)
=> (AttributeHelper<RedumpSystem>.GetAttribute(system) as SystemAttribute)?.HasSbi ?? false;
/// <summary>
/// Determine if a system has an SBI pack
/// </summary>
public static bool HasSbi(this RedumpSystem? system)
=> (AttributeHelper<RedumpSystem?>.GetAttribute(system) as SystemAttribute)?.HasSbi ?? false;
/// <summary>
/// Get the RedumpSystem enum value for a given string

View File

@@ -6,7 +6,7 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.5.0</Version>
<Version>1.5.2</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>

View File

@@ -17,7 +17,7 @@ namespace SabreTools.RedumpLib.Web
/// <param name="useSubfolders">True to use named subfolders to store downloads, false to store directly in the output directory</param>
public static async Task<bool> DownloadPacks(RedumpClient rc, string? outDir, bool useSubfolders)
{
var systems = (RedumpSystem?[])Enum.GetValues(typeof(RedumpSystem));
var systems = (RedumpSystem[])Enum.GetValues(typeof(RedumpSystem));
await rc.DownloadPacks(Constants.PackCuesUrl, Array.FindAll(systems, s => s.HasCues()), "CUEs", outDir, useSubfolders ? "cue" : null);
await rc.DownloadPacks(Constants.PackDatfileUrl, Array.FindAll(systems, s => s.HasDat()), "DATs", outDir, useSubfolders ? "dat" : null);
@@ -39,7 +39,10 @@ namespace SabreTools.RedumpLib.Web
/// <param name="useSubfolders">True to use named subfolders to store downloads, false to store directly in the output directory</param>
public static async Task<bool> DownloadPacksForSystem(RedumpClient rc, RedumpSystem? system, string? outDir, bool useSubfolders)
{
var systemAsArray = new RedumpSystem?[] { system };
if (system == null)
return false;
var systemAsArray = new RedumpSystem[] { system.Value };
if (system.HasCues())
await rc.DownloadPacks(Constants.PackCuesUrl, systemAsArray, "CUEs", outDir, useSubfolders ? "cue" : null);

View File

@@ -128,7 +128,7 @@ namespace SabreTools.RedumpLib.Web
try
{
// Get the current token from the login page
var loginPage = await DownloadStringWithRetries(Constants.LoginUrl);
var loginPage = await DownloadString(Constants.LoginUrl);
string token = Constants.TokenRegex.Match(loginPage ?? string.Empty).Groups[1].Value;
#if NETFRAMEWORK
@@ -186,6 +186,108 @@ namespace SabreTools.RedumpLib.Web
#endregion
#region Generic Helpers
/// <summary>
/// Download from a URI to a byte array
/// </summary>
/// <param name="uri">Remote URI to retrieve</param>
/// <returns>Byte array from the URI, null on error</returns>
public async Task<byte[]?> DownloadData(string uri)
{
// Only retry a positive number of times
if (RetryCount <= 0)
return null;
for (int i = 0; i < RetryCount; i++)
{
try
{
#if NET40
return await Task.Factory.StartNew(() => _internalClient.DownloadData(uri));
#elif NETFRAMEWORK
return await Task.Run(() => _internalClient.DownloadData(uri));
#else
return await _internalClient.GetByteArrayAsync(uri);
#endif
}
catch { }
// Sleep for 100ms if the last attempt failed
Thread.Sleep(100);
}
return null;
}
/// <summary>
/// Download from a URI to a local file
/// </summary>
/// <param name="uri">Remote URI to retrieve</param>
/// <param name="fileName">Filename to write to</param>
/// <returns>The remote filename from the URI, null on error</returns>
public async Task<string?> DownloadFile(string uri, string fileName)
{
#if NET40
await Task.Factory.StartNew(() => { _internalClient.DownloadFile(uri, fileName); return true; });
return _internalClient.GetLastFilename();
#elif NETFRAMEWORK
await Task.Run(() => _internalClient.DownloadFile(uri, fileName));
return _internalClient.GetLastFilename();
#else
// Make the call to get the file
var response = await _internalClient.GetAsync(uri);
if (response?.Content?.Headers == null || !response.IsSuccessStatusCode)
{
Console.WriteLine($"Could not download {uri}");
return null;
}
// Copy the data to a local temp file
using (var responseStream = await response.Content.ReadAsStreamAsync())
using (var tempFileStream = File.OpenWrite(fileName))
{
responseStream.CopyTo(tempFileStream);
}
return response.Content.Headers.ContentDisposition?.FileName?.Replace("\"", "");
#endif
}
/// <summary>
/// Download from a URI to a string
/// </summary>
/// <param name="uri">Remote URI to retrieve</param>
/// <returns>String from the URI, null on error</returns>
public async Task<string?> DownloadString(string uri)
{
// Only retry a positive number of times
if (RetryCount <= 0)
return null;
for (int i = 0; i < RetryCount; i++)
{
try
{
#if NET40
return await Task.Factory.StartNew(() => _internalClient.DownloadString(uri));
#elif NETFRAMEWORK
return await Task.Run(() => _internalClient.DownloadString(uri));
#else
return await _internalClient.GetStringAsync(uri);
#endif
}
catch { }
// Sleep for 100ms if the last attempt failed
Thread.Sleep(100);
}
return null;
}
#endregion
#region Single Page Helpers
/// <summary>
@@ -198,7 +300,7 @@ namespace SabreTools.RedumpLib.Web
List<int> ids = [];
// Try to retrieve the data
string? dumpsPage = await DownloadStringWithRetries(url);
string? dumpsPage = await DownloadString(url);
// If we have no dumps left
if (dumpsPage == null || dumpsPage.Contains("No discs found."))
@@ -248,7 +350,7 @@ namespace SabreTools.RedumpLib.Web
List<int> ids = [];
// Try to retrieve the data
string? dumpsPage = await DownloadStringWithRetries(url);
string? dumpsPage = await DownloadString(url);
// If we have no dumps left
if (dumpsPage == null || dumpsPage.Contains("No discs found."))
@@ -306,7 +408,7 @@ namespace SabreTools.RedumpLib.Web
List<int> ids = [];
// Try to retrieve the data
string? dumpsPage = await DownloadStringWithRetries(url);
string? dumpsPage = await DownloadString(url);
// If we have no dumps left
if (dumpsPage == null || dumpsPage.Contains("No discs found."))
@@ -346,7 +448,7 @@ namespace SabreTools.RedumpLib.Web
List<int> ids = [];
// Try to retrieve the data
string? dumpsPage = await DownloadStringWithRetries(url);
string? dumpsPage = await DownloadString(url);
// If we have no dumps left
if (dumpsPage == null || dumpsPage.Contains("No discs found."))
@@ -451,7 +553,7 @@ namespace SabreTools.RedumpLib.Web
{
// Try to retrieve the data
string discPageUri = string.Format(Constants.DiscPageUrl, +id);
string? discPage = await DownloadStringWithRetries(discPageUri);
string? discPage = await DownloadString(discPageUri);
if (discPage == null || discPage.Contains($"Disc with ID \"{id}\" doesn't exist"))
{
@@ -489,7 +591,7 @@ namespace SabreTools.RedumpLib.Web
{
// Try to retrieve the data
string discPageUri = string.Format(Constants.DiscPageUrl, +id);
string? discPage = await DownloadStringWithRetries(discPageUri);
string? discPage = await DownloadString(discPageUri);
if (discPage == null || discPage.Contains($"Disc with ID \"{id}\" doesn't exist"))
{
@@ -613,7 +715,7 @@ namespace SabreTools.RedumpLib.Web
{
// Try to retrieve the data
string discPageUri = string.Format(Constants.WipDiscPageUrl, +id);
string? discPage = await DownloadStringWithRetries(discPageUri);
string? discPage = await DownloadString(discPageUri);
if (discPage == null || discPage.Contains($"WIP disc with ID \"{id}\" doesn't exist"))
{
@@ -651,7 +753,7 @@ namespace SabreTools.RedumpLib.Web
{
// Try to retrieve the data
string discPageUri = string.Format(Constants.WipDiscPageUrl, +id);
string? discPage = await DownloadStringWithRetries(discPageUri);
string? discPage = await DownloadString(discPageUri);
if (discPage == null || discPage.Contains($"WIP disc with ID \"{id}\" doesn't exist"))
{
@@ -725,7 +827,7 @@ namespace SabreTools.RedumpLib.Web
/// <param name="url">Base URL to download using</param>
/// <param name="system">Systems to download packs for</param>
/// <param name="title">Name of the pack that is downloading</param>
public async Task<Dictionary<RedumpSystem, byte[]>> DownloadPacks(string url, RedumpSystem?[] systems, string title)
public async Task<Dictionary<RedumpSystem, byte[]>> DownloadPacks(string url, RedumpSystem[] systems, string title)
{
var packsDictionary = new Dictionary<RedumpSystem, byte[]>();
@@ -733,7 +835,7 @@ namespace SabreTools.RedumpLib.Web
foreach (var system in systems)
{
// If the system is invalid, we can't do anything
if (system == null || !system.IsAvailable())
if (!system.IsAvailable())
continue;
// If we didn't have credentials
@@ -748,7 +850,7 @@ namespace SabreTools.RedumpLib.Web
Console.Write($"\r{longName}{new string(' ', Console.BufferWidth - longName!.Length - 1)}");
byte[]? pack = await DownloadSinglePack(url, system);
if (pack != null)
packsDictionary.Add(system.Value, pack);
packsDictionary.Add(system, pack);
}
Console.Write($"\rComplete!{new string(' ', Console.BufferWidth - 10)}");
@@ -765,13 +867,13 @@ namespace SabreTools.RedumpLib.Web
/// <param name="title">Name of the pack that is downloading</param>
/// <param name="outDir">Output directory to save data to</param>
/// <param name="subfolder">Named subfolder for the pack, used optionally</param>
public async Task<bool> DownloadPacks(string url, RedumpSystem?[] systems, string title, string? outDir, string? subfolder)
public async Task<bool> DownloadPacks(string url, RedumpSystem[] systems, string title, string? outDir, string? subfolder)
{
Console.WriteLine($"Downloading {title}");
foreach (var system in systems)
{
// If the system is invalid, we can't do anything
if (system == null || !system.IsAvailable())
if (!system.IsAvailable())
continue;
// If we didn't have credentials
@@ -792,72 +894,6 @@ namespace SabreTools.RedumpLib.Web
return true;
}
/// <summary>
/// Download from a URI to a local file
/// </summary>
/// <param name="uri">Remote URI to retrieve</param>
/// <param name="fileName">Filename to write to</param>
/// <returns>The remote filename from the URI, null on error</returns>
private async Task<string?> DownloadFile(string uri, string fileName)
{
#if NET40
await Task.Factory.StartNew(() => { _internalClient.DownloadFile(uri, fileName); return true; });
return _internalClient.GetLastFilename();
#elif NETFRAMEWORK
await Task.Run(() => _internalClient.DownloadFile(uri, fileName));
return _internalClient.GetLastFilename();
#else
// Make the call to get the file
var response = await _internalClient.GetAsync(uri);
if (response?.Content?.Headers == null || !response.IsSuccessStatusCode)
{
Console.WriteLine($"Could not download {uri}");
return null;
}
// Copy the data to a local temp file
using (var responseStream = await response.Content.ReadAsStreamAsync())
using (var tempFileStream = File.OpenWrite(fileName))
{
responseStream.CopyTo(tempFileStream);
}
return response.Content.Headers.ContentDisposition?.FileName?.Replace("\"", "");
#endif
}
/// <summary>
/// Download from a URI to a string
/// </summary>
/// <param name="uri">Remote URI to retrieve</param>
/// <returns>String from the URI, null on error</returns>
private async Task<string?> DownloadStringWithRetries(string uri)
{
// Only retry a positive number of times
if (RetryCount <= 0)
return null;
for (int i = 0; i < RetryCount; i++)
{
try
{
#if NET40
return await Task.Factory.StartNew(() => _internalClient.DownloadString(uri));
#elif NETFRAMEWORK
return await Task.Run(() => _internalClient.DownloadString(uri));
#else
return await _internalClient.GetStringAsync(uri);
#endif
}
catch { }
// Sleep for 100ms if the last attempt failed
Thread.Sleep(100);
}
return null;
}
/// <summary>
/// Move a tempfile to a new name unless it aleady exists, in which case, delete the tempfile
/// </summary>