mirror of
https://github.com/SabreTools/SabreTools.RedumpLib.git
synced 2026-02-09 05:35:38 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
304236774f | ||
|
|
9924289c48 | ||
|
|
240eb74ead | ||
|
|
a64b109d2c | ||
|
|
3e0f9b5410 | ||
|
|
668be418ac | ||
|
|
7d184a634e | ||
|
|
67aed0899d | ||
|
|
9fbaf1a187 | ||
|
|
fe8686a2bb |
8
.github/workflows/build_nupkg.yml
vendored
8
.github/workflows/build_nupkg.yml
vendored
@@ -16,10 +16,16 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Build library
|
||||
run: dotnet build
|
||||
|
||||
- name: Run tests
|
||||
run: dotnet test
|
||||
|
||||
- name: Pack
|
||||
run: dotnet pack
|
||||
|
||||
7
.github/workflows/check_pr.yml
vendored
7
.github/workflows/check_pr.yml
vendored
@@ -11,7 +11,10 @@ jobs:
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 8.0.x
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Build
|
||||
run: dotnet build
|
||||
run: dotnet build
|
||||
|
||||
- name: Run tests
|
||||
run: dotnet test
|
||||
@@ -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;
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<TargetFrameworks>net6.0;net8.0;net9.0</TargetFrameworks>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SabreTools.RedumpLib\SabreTools.RedumpLib.csproj" />
|
||||
<ProjectReference Include="..\SabreTools.RedumpLib\SabreTools.RedumpLib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="TestData\*" />
|
||||
<None Remove="TestData\*" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="TestData\*">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\*">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeCoverage" Version="17.11.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
|
||||
<PackageReference Include="xunit.analyzers" Version="1.16.0" />
|
||||
<PackageReference Include="xunit.assert" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.core" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.extensibility.core" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.extensibility.execution" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.runner.console" Version="2.9.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeCoverage" Version="17.11.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
|
||||
<PackageReference Include="xunit.analyzers" Version="1.17.0" />
|
||||
<PackageReference Include="xunit.assert" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.core" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.extensibility.core" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.extensibility.execution" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.runner.console" Version="2.9.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
|
||||
namespace SabreTools.RedumpLib.Attributes
|
||||
{
|
||||
@@ -34,19 +31,7 @@ namespace SabreTools.RedumpLib.Attributes
|
||||
return null;
|
||||
|
||||
// Get the enum value info from the array, if possible
|
||||
#if NET20 || NET35
|
||||
System.Reflection.MemberInfo? enumValueMemberInfo = null;
|
||||
foreach (var m in memberInfos)
|
||||
{
|
||||
if (m.DeclaringType != enumType)
|
||||
continue;
|
||||
|
||||
enumValueMemberInfo = m;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
var enumValueMemberInfo = memberInfos.FirstOrDefault(m => m.DeclaringType == enumType);
|
||||
#endif
|
||||
var enumValueMemberInfo = Array.Find(memberInfos, m => m.DeclaringType == enumType);
|
||||
if (enumValueMemberInfo == null)
|
||||
return null;
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Net;
|
||||
#endif
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -272,12 +271,11 @@ namespace SabreTools.RedumpLib
|
||||
{
|
||||
info.CommonDiscInfo!.Title = title.Substring(0, firstParenLocation);
|
||||
var submatches = Constants.DiscNumberLetterRegex.Matches(title);
|
||||
#if NET20 || NET35
|
||||
foreach (Match submatch in submatches)
|
||||
#else
|
||||
foreach (Match submatch in submatches.Cast<Match>())
|
||||
#endif
|
||||
foreach (Match? submatch in submatches)
|
||||
{
|
||||
if (submatch == null)
|
||||
continue;
|
||||
|
||||
var submatchValue = submatch.Groups[1].Value;
|
||||
|
||||
// Disc number or letter
|
||||
@@ -285,11 +283,7 @@ namespace SabreTools.RedumpLib
|
||||
info.CommonDiscInfo.DiscNumberLetter = submatchValue.Remove(0, "Disc ".Length);
|
||||
|
||||
// Issue number
|
||||
#if NET20 || NET35
|
||||
else if (long.TryParse(submatchValue, out _))
|
||||
#else
|
||||
else if (submatchValue.All(c => char.IsNumber(c)))
|
||||
#endif
|
||||
else if (ulong.TryParse(submatchValue, out _))
|
||||
info.CommonDiscInfo.Title += $" ({submatchValue})";
|
||||
|
||||
// Disc title
|
||||
@@ -308,15 +302,13 @@ namespace SabreTools.RedumpLib
|
||||
match = Constants.ForeignTitleRegex.Match(discData);
|
||||
if (match.Success)
|
||||
info.CommonDiscInfo!.ForeignTitleNonLatin = WebUtility.HtmlDecode(match.Groups[1].Value);
|
||||
else
|
||||
info.CommonDiscInfo!.ForeignTitleNonLatin = null;
|
||||
|
||||
// Category
|
||||
match = Constants.CategoryRegex.Match(discData);
|
||||
if (match.Success)
|
||||
info.CommonDiscInfo.Category = Extensions.ToDiscCategory(match.Groups[1].Value);
|
||||
info.CommonDiscInfo!.Category = Extensions.ToDiscCategory(match.Groups[1].Value);
|
||||
else
|
||||
info.CommonDiscInfo.Category = DiscCategory.Games;
|
||||
info.CommonDiscInfo!.Category = DiscCategory.Games;
|
||||
|
||||
// Region
|
||||
if (info.CommonDiscInfo.Region == null)
|
||||
@@ -331,12 +323,11 @@ namespace SabreTools.RedumpLib
|
||||
if (matches.Count > 0)
|
||||
{
|
||||
var tempLanguages = new List<Language?>();
|
||||
#if NET20 || NET35
|
||||
foreach (Match submatch in matches)
|
||||
#else
|
||||
foreach (Match submatch in matches.Cast<Match>())
|
||||
#endif
|
||||
foreach (Match? submatch in matches)
|
||||
{
|
||||
if (submatch == null)
|
||||
continue;
|
||||
|
||||
var language = Extensions.ToLanguage(submatch.Groups[1].Value);
|
||||
if (language != null)
|
||||
tempLanguages.Add(language);
|
||||
@@ -382,12 +373,11 @@ namespace SabreTools.RedumpLib
|
||||
tempDumpers.Add(dumper);
|
||||
}
|
||||
|
||||
#if NET20 || NET35
|
||||
foreach (Match submatch in matches)
|
||||
#else
|
||||
foreach (Match submatch in matches.Cast<Match>())
|
||||
#endif
|
||||
foreach (Match? submatch in matches)
|
||||
{
|
||||
if (submatch == null)
|
||||
continue;
|
||||
|
||||
string? dumper = WebUtility.HtmlDecode(submatch.Groups[1].Value);
|
||||
if (dumper != null)
|
||||
tempDumpers.Add(dumper);
|
||||
|
||||
@@ -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
|
||||
@@ -793,7 +790,8 @@ namespace SabreTools.RedumpLib.Data
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
/// <returns></returns>
|
||||
public static string? LongName(this DiscCategory? category) => AttributeHelper<DiscCategory?>.GetAttribute(category)?.LongName;
|
||||
public static string? LongName(this DiscCategory? category)
|
||||
=> AttributeHelper<DiscCategory?>.GetAttribute(category)?.LongName;
|
||||
|
||||
/// <summary>
|
||||
/// Get the Category enum value for a given string
|
||||
@@ -830,7 +828,8 @@ namespace SabreTools.RedumpLib.Data
|
||||
/// </summary>
|
||||
/// <param name="discType"></param>
|
||||
/// <returns></returns>
|
||||
public static string? LongName(this DiscType? discType) => AttributeHelper<DiscType?>.GetAttribute(discType)?.LongName;
|
||||
public static string? LongName(this DiscType? discType)
|
||||
=> AttributeHelper<DiscType?>.GetAttribute(discType)?.LongName;
|
||||
|
||||
/// <summary>
|
||||
/// Get the DiscType enum value for a given string
|
||||
@@ -896,7 +895,8 @@ namespace SabreTools.RedumpLib.Data
|
||||
/// </summary>
|
||||
/// <param name="language"></param>
|
||||
/// <returns></returns>
|
||||
public static string? LongName(this Language? language) => AttributeHelper<Language?>.GetAttribute(language)?.LongName;
|
||||
public static string? LongName(this Language? language)
|
||||
=> AttributeHelper<Language?>.GetAttribute(language)?.LongName;
|
||||
|
||||
/// <summary>
|
||||
/// Get the Redump shortnames for each known language
|
||||
@@ -925,74 +925,23 @@ namespace SabreTools.RedumpLib.Data
|
||||
/// <returns>Language represented by the string, if possible</returns>
|
||||
public static Language? ToLanguage(string lang)
|
||||
{
|
||||
#if NET20 || NET35
|
||||
var languages = new List<Language?>();
|
||||
foreach (Language l in Enum.GetValues(typeof(Language)))
|
||||
{
|
||||
languages.Add(new Nullable<Language>(l));
|
||||
}
|
||||
#else
|
||||
var languages = Enum.GetValues(typeof(Language))
|
||||
.Cast<Language?>()
|
||||
.ToList();
|
||||
#endif
|
||||
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 = languages
|
||||
.Where(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 = languages
|
||||
.Where(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 = languages
|
||||
.Where(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;
|
||||
}
|
||||
@@ -1002,21 +951,48 @@ namespace SabreTools.RedumpLib.Data
|
||||
/// </summary>
|
||||
/// <param name="language"></param>
|
||||
/// <returns></returns>
|
||||
public static string? ThreeLetterCode(this Language? language) => (AttributeHelper<Language?>.GetAttribute(language) as LanguageAttribute)?.ThreeLetterCode;
|
||||
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>
|
||||
/// <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 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;
|
||||
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>
|
||||
/// <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-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;
|
||||
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>
|
||||
/// <param name="language"></param>
|
||||
/// <returns></returns>
|
||||
public static string? TwoLetterCode(this Language? language)
|
||||
=> (AttributeHelper<Language?>.GetAttribute(language) as LanguageAttribute)?.TwoLetterCode;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1097,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
|
||||
@@ -1114,36 +1108,15 @@ namespace SabreTools.RedumpLib.Data
|
||||
public static Region? ToRegion(string region)
|
||||
{
|
||||
region = region.ToLowerInvariant();
|
||||
#if NET20 || NET35
|
||||
var regions = new List<Region?>();
|
||||
foreach (Region r in Enum.GetValues(typeof(Region)))
|
||||
{
|
||||
regions.Add(new Nullable<Region>(r));
|
||||
}
|
||||
#else
|
||||
var regions = Enum.GetValues(typeof(Region))
|
||||
.Cast<Region?>()
|
||||
.ToList();
|
||||
#endif
|
||||
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 = regions
|
||||
.Where(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;
|
||||
}
|
||||
@@ -1449,31 +1422,10 @@ namespace SabreTools.RedumpLib.Data
|
||||
/// </summary>
|
||||
public static List<string> ListSystems()
|
||||
{
|
||||
var systems = new List<string>();
|
||||
|
||||
#if NET20 || NET35
|
||||
var knownSystems = new List<RedumpSystem?>();
|
||||
foreach (RedumpSystem s in Enum.GetValues(typeof(RedumpSystem)))
|
||||
{
|
||||
var ns = new Nullable<RedumpSystem>(s);
|
||||
if (ns != null && !ns.IsMarker() && ns.GetCategory() != SystemCategory.NONE)
|
||||
knownSystems.Add(ns);
|
||||
}
|
||||
|
||||
knownSystems.Sort((x, y) => (x.LongName() ?? string.Empty).CompareTo(y.LongName() ?? string.Empty));
|
||||
#else
|
||||
var knownSystems = Enum.GetValues(typeof(RedumpSystem))
|
||||
.OfType<RedumpSystem?>()
|
||||
.Where(s => s != null && !s.IsMarker() && s.GetCategory() != SystemCategory.NONE)
|
||||
.OrderBy(s => s.LongName() ?? string.Empty);
|
||||
#endif
|
||||
|
||||
foreach (var val in knownSystems)
|
||||
{
|
||||
systems.Add($"{val.ShortName()} - {val.LongName()}");
|
||||
}
|
||||
|
||||
return systems;
|
||||
var systems = (RedumpSystem?[])Enum.GetValues(typeof(RedumpSystem));
|
||||
var knownSystems = Array.FindAll(systems, s => s != null && !s.IsMarker() && s.GetCategory() != SystemCategory.NONE);
|
||||
Array.Sort(knownSystems, (x, y) => (x.LongName() ?? string.Empty).CompareTo(y.LongName() ?? string.Empty));
|
||||
return [.. Array.ConvertAll(knownSystems, val => $"{val.ShortName()} - {val.LongName()}")];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1481,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
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
using SabreTools.RedumpLib.Web;
|
||||
|
||||
@@ -51,6 +52,11 @@ namespace SabreTools.RedumpLib
|
||||
/// </summary>
|
||||
public bool OnlyList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Don't replace forward slashes with `-` in queries
|
||||
/// </summary>
|
||||
public bool NoSlash { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Force continuing downloads until user cancels or pages run out
|
||||
/// </summary>
|
||||
@@ -97,49 +103,85 @@ namespace SabreTools.RedumpLib
|
||||
/// <summary>
|
||||
/// Run the downloads that should go
|
||||
/// </summary>
|
||||
/// <returns>True if there was a valid download type, false otherwise</returns>
|
||||
public async Task<bool> Download()
|
||||
/// <returns>List of IDs that were processed on success, empty on error</returns>
|
||||
/// <remarks>Packs will never return anything other than empty</remarks>
|
||||
public async Task<List<int>> Download()
|
||||
{
|
||||
// Login to Redump, if possible
|
||||
if (!_client.LoggedIn)
|
||||
await _client.Login(Username ?? string.Empty, Password ?? string.Empty);
|
||||
|
||||
// Create output list
|
||||
List<int> processedIds = [];
|
||||
|
||||
switch (Feature)
|
||||
{
|
||||
case Feature.Site:
|
||||
if (OnlyNew)
|
||||
await Discs.DownloadLastModified(_client, OutDir, Force);
|
||||
else
|
||||
await Discs.DownloadSiteRange(_client, OutDir, MinimumId, MaximumId);
|
||||
break;
|
||||
case Feature.WIP:
|
||||
if (OnlyNew)
|
||||
await WIP.DownloadLastSubmitted(_client, OutDir);
|
||||
else
|
||||
await WIP.DownloadWIPRange(_client, OutDir, MinimumId, MaximumId);
|
||||
break;
|
||||
case Feature.Packs:
|
||||
await Packs.DownloadPacks(_client, OutDir, UseSubfolders);
|
||||
break;
|
||||
case Feature.User:
|
||||
if (OnlyList)
|
||||
await User.ListUser(_client, Username);
|
||||
else if (OnlyNew)
|
||||
await User.DownloadUserLastModified(_client, Username, OutDir);
|
||||
else
|
||||
await User.DownloadUser(_client, Username, OutDir);
|
||||
break;
|
||||
case Feature.Quicksearch:
|
||||
if (OnlyList)
|
||||
await Search.ListSearchResults(_client, QueryString);
|
||||
else
|
||||
await Search.DownloadSearchResults(_client, QueryString, OutDir);
|
||||
processedIds = await ProcessQuicksearch();
|
||||
break;
|
||||
case Feature.Site:
|
||||
processedIds = await ProcessSite();
|
||||
break;
|
||||
case Feature.User:
|
||||
processedIds = await ProcessUser();
|
||||
break;
|
||||
case Feature.WIP:
|
||||
processedIds = await ProcessWIP();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
return [];
|
||||
}
|
||||
|
||||
return true;
|
||||
return processedIds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process the Quicksearch feature
|
||||
/// </summary>
|
||||
private async Task<List<int>> ProcessQuicksearch()
|
||||
{
|
||||
if (OnlyList)
|
||||
return await Search.ListSearchResults(_client, QueryString, NoSlash);
|
||||
else
|
||||
return await Search.DownloadSearchResults(_client, QueryString, OutDir, NoSlash);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process the Site feature
|
||||
/// </summary>
|
||||
private async Task<List<int>> ProcessSite()
|
||||
{
|
||||
if (OnlyNew)
|
||||
return await Discs.DownloadLastModified(_client, OutDir, Force);
|
||||
else
|
||||
return await Discs.DownloadSiteRange(_client, OutDir, MinimumId, MaximumId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process the User feature
|
||||
/// </summary>
|
||||
private async Task<List<int>> ProcessUser()
|
||||
{
|
||||
if (OnlyList)
|
||||
return await User.ListUser(_client, Username);
|
||||
else if (OnlyNew)
|
||||
return await User.DownloadUserLastModified(_client, Username, OutDir);
|
||||
else
|
||||
return await User.DownloadUser(_client, Username, OutDir);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process the WIP feature
|
||||
/// </summary>
|
||||
private async Task<List<int>> ProcessWIP()
|
||||
{
|
||||
if (OnlyNew)
|
||||
return await WIP.DownloadLastSubmitted(_client, OutDir);
|
||||
else
|
||||
return await WIP.DownloadWIPRange(_client, OutDir, MinimumId, MaximumId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Text.RegularExpressions;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
|
||||
@@ -60,28 +57,10 @@ namespace SabreTools.RedumpLib
|
||||
AddIfExists(output, Template.FullyMatchingIDField, info.FullyMatchedID?.ToString(), 1);
|
||||
AddIfExists(output, Template.PartiallyMatchingIDsField, info.PartiallyMatchedIDs, 1);
|
||||
AddIfExists(output, Template.RegionField, info.CommonDiscInfo?.Region.LongName() ?? "SPACE! (CHANGE THIS)", 1);
|
||||
#if NET20 || NET35
|
||||
var languages = info.CommonDiscInfo?.Languages ?? [null];
|
||||
var languageStrings = new List<string>();
|
||||
foreach (var l in languages)
|
||||
{
|
||||
languageStrings.Add(l.LongName() ?? "SILENCE! (CHANGE THIS)");
|
||||
}
|
||||
|
||||
AddIfExists(output, Template.LanguagesField, languageStrings.ToArray(), 1);
|
||||
|
||||
var langaugeSelections = info.CommonDiscInfo?.LanguageSelection ?? [];
|
||||
var languageSelectionStrings = new List<string?>();
|
||||
foreach (var l in langaugeSelections)
|
||||
{
|
||||
languageSelectionStrings.Add(l.LongName());
|
||||
}
|
||||
|
||||
AddIfExists(output, Template.PlaystationLanguageSelectionViaField, languageSelectionStrings.ToArray(), 1);
|
||||
#else
|
||||
AddIfExists(output, Template.LanguagesField, (info.CommonDiscInfo?.Languages ?? [null]).Select(l => l.LongName() ?? "SILENCE! (CHANGE THIS)").ToArray(), 1);
|
||||
AddIfExists(output, Template.PlaystationLanguageSelectionViaField, (info.CommonDiscInfo?.LanguageSelection ?? []).Select(l => l.LongName()).ToArray(), 1);
|
||||
#endif
|
||||
AddIfExists(output, Template.LanguagesField,
|
||||
Array.ConvertAll(info.CommonDiscInfo?.Languages ?? [null], l => l.LongName() ?? "SILENCE! (CHANGE THIS)"), 1);
|
||||
AddIfExists(output, Template.PlaystationLanguageSelectionViaField,
|
||||
Array.ConvertAll(info.CommonDiscInfo?.LanguageSelection ?? [], l => l.LongName()), 1);
|
||||
AddIfExists(output, Template.DiscSerialField, info.CommonDiscInfo?.Serial, 1);
|
||||
|
||||
// All ringcode information goes in an indented area
|
||||
@@ -307,32 +286,13 @@ namespace SabreTools.RedumpLib
|
||||
info.CommonDiscInfo.Comments = string.Empty;
|
||||
|
||||
// Add all special fields before any comments
|
||||
#if NET20 || NET35
|
||||
var orderedCommentTags = OrderCommentTags(info.CommonDiscInfo.CommentsSpecialFields);
|
||||
var commentTagStrings = new List<string>();
|
||||
foreach (var kvp in orderedCommentTags)
|
||||
{
|
||||
if (string.IsNullOrEmpty(kvp.Value))
|
||||
continue;
|
||||
|
||||
string? formatted = FormatSiteTag(kvp);
|
||||
if (formatted == null)
|
||||
continue;
|
||||
|
||||
commentTagStrings.Add(formatted);
|
||||
}
|
||||
|
||||
info.CommonDiscInfo.Comments = string.Join("\n", commentTagStrings.ToArray())
|
||||
+ "\n" + info.CommonDiscInfo.Comments;
|
||||
#else
|
||||
info.CommonDiscInfo.Comments = string.Join(
|
||||
"\n", OrderCommentTags(info.CommonDiscInfo.CommentsSpecialFields)
|
||||
.Where(kvp => !string.IsNullOrEmpty(kvp.Value))
|
||||
.Select(FormatSiteTag)
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.FindAll(kvp => !string.IsNullOrEmpty(kvp.Value))
|
||||
.ConvertAll(FormatSiteTag)
|
||||
.FindAll(s => !string.IsNullOrEmpty(s))
|
||||
.ToArray()
|
||||
) + "\n" + info.CommonDiscInfo.Comments;
|
||||
#endif
|
||||
|
||||
// Normalize newlines
|
||||
info.CommonDiscInfo.Comments = info.CommonDiscInfo.Comments.Replace("\r\n", "\n");
|
||||
@@ -352,32 +312,13 @@ namespace SabreTools.RedumpLib
|
||||
info.CommonDiscInfo.Contents = string.Empty;
|
||||
|
||||
// Add all special fields before any contents
|
||||
#if NET20 || NET35
|
||||
var orderedContentTags = OrderContentTags(info.CommonDiscInfo.ContentsSpecialFields);
|
||||
var contentTagStrings = new List<string>();
|
||||
foreach (var kvp in orderedContentTags)
|
||||
{
|
||||
if (string.IsNullOrEmpty(kvp.Value))
|
||||
continue;
|
||||
|
||||
string? formatted = FormatSiteTag(kvp);
|
||||
if (formatted == null)
|
||||
continue;
|
||||
|
||||
contentTagStrings.Add(formatted);
|
||||
}
|
||||
|
||||
info.CommonDiscInfo.Contents = string.Join("\n", contentTagStrings.ToArray())
|
||||
+ "\n" + info.CommonDiscInfo.Contents;
|
||||
#else
|
||||
info.CommonDiscInfo.Contents = string.Join(
|
||||
"\n", OrderContentTags(info.CommonDiscInfo.ContentsSpecialFields)
|
||||
.Where(kvp => !string.IsNullOrEmpty(kvp.Value))
|
||||
.Select(FormatSiteTag)
|
||||
.Where(s => !string.IsNullOrEmpty(s))
|
||||
.FindAll(kvp => !string.IsNullOrEmpty(kvp.Value))
|
||||
.ConvertAll(FormatSiteTag)
|
||||
.FindAll(s => !string.IsNullOrEmpty(s))
|
||||
.ToArray()
|
||||
) + "\n" + info.CommonDiscInfo.Contents;
|
||||
#endif
|
||||
|
||||
// Normalize newlines
|
||||
info.CommonDiscInfo.Contents = info.CommonDiscInfo.Contents.Replace("\r\n", "\n");
|
||||
@@ -425,11 +366,7 @@ namespace SabreTools.RedumpLib
|
||||
|
||||
// If the value contains a newline
|
||||
value = value.Replace("\r\n", "\n");
|
||||
#if NET20 || NET35
|
||||
if (value.Contains("\n"))
|
||||
#else
|
||||
if (value.Contains('\n'))
|
||||
#endif
|
||||
{
|
||||
output.Add(prefix + key + ":"); output.Add("");
|
||||
string[] values = value.Split('\n');
|
||||
@@ -495,17 +432,7 @@ namespace SabreTools.RedumpLib
|
||||
if (value == null || value.Count == 0)
|
||||
return;
|
||||
|
||||
#if NET20 || NET35
|
||||
var valueStrings = new List<string>();
|
||||
foreach (int o in value)
|
||||
{
|
||||
valueStrings.Add(o.ToString());
|
||||
}
|
||||
|
||||
AddIfExists(output, key, string.Join(", ", valueStrings.ToArray()), indent);
|
||||
#else
|
||||
AddIfExists(output, key, string.Join(", ", value.Select(o => o.ToString()).ToArray()), indent);
|
||||
#endif
|
||||
AddIfExists(output, key, string.Join(", ", [.. value.ConvertAll(o => o.ToString())]), indent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,41 +1,54 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Assembly Properties -->
|
||||
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.4.2</Version>
|
||||
<PropertyGroup>
|
||||
<!-- Assembly Properties -->
|
||||
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.5.1</Version>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Description>Code to interact with redump.org</Description>
|
||||
<Copyright>Copyright (c) Matt Nadareski 2020-2024</Copyright>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<RepositoryUrl>https://github.com/SabreTools/SabreTools.RedumpLib</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>web client redump</PackageTags>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Description>Code to interact with redump.org</Description>
|
||||
<Copyright>Copyright (c) Matt Nadareski 2020-2024</Copyright>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<RepositoryUrl>https://github.com/SabreTools/SabreTools.RedumpLib</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>web client redump</PackageTags>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="../README.md" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
<!-- Support All Frameworks -->
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`))">
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
|
||||
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Support for old .NET versions -->
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`))">
|
||||
<PackageReference Include="Net30.LinqBridge" Version="1.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))">
|
||||
<PackageReference Include="MinAsyncBridge" Version="0.12.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="../README.md" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.4.10" />
|
||||
</ItemGroup>
|
||||
<!-- Support for old .NET versions -->
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`))">
|
||||
<PackageReference Include="Net30.LinqBridge" Version="1.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net40`))">
|
||||
<PackageReference Include="MinAsyncBridge" Version="0.12.4" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Threading.Tasks;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
using SabreTools.RedumpLib.Web;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
|
||||
@@ -15,17 +16,22 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// <param name="rc">RedumpClient for connectivity</param>
|
||||
/// <param name="outDir">Output directory to save data to</param>
|
||||
/// <param name="force">Force continuation of download</param>
|
||||
public static async Task<bool> DownloadLastModified(RedumpClient rc, string? outDir, bool force)
|
||||
/// <returns>All disc IDs in last modified range, empty on error</returns>
|
||||
public static async Task<List<int>> DownloadLastModified(RedumpClient rc, string? outDir, bool force)
|
||||
{
|
||||
List<int> ids = [];
|
||||
|
||||
// Keep getting last modified pages until there are none left
|
||||
int pageNumber = 1;
|
||||
while (true)
|
||||
{
|
||||
if (!await rc.CheckSingleSitePage(string.Format(Constants.LastModifiedUrl, pageNumber++), outDir, !force))
|
||||
var pageIds = await rc.CheckSingleSitePage(string.Format(Constants.LastModifiedUrl, pageNumber++), outDir, !force);
|
||||
ids.AddRange(pageIds);
|
||||
if (pageIds.Count == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ids;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -35,21 +41,25 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// <param name="outDir">Output directory to save data to</param>
|
||||
/// <param name="minId">Starting ID for the range</param>
|
||||
/// <param name="maxId">Ending ID for the range (inclusive)</param>
|
||||
public static async Task<bool> DownloadSiteRange(RedumpClient rc, string? outDir, int minId = 0, int maxId = 0)
|
||||
/// <returns>All disc IDs in last modified range, empty on error</returns>
|
||||
public static async Task<List<int>> DownloadSiteRange(RedumpClient rc, string? outDir, int minId = 0, int maxId = 0)
|
||||
{
|
||||
List<int> ids = [];
|
||||
|
||||
if (!rc.LoggedIn)
|
||||
{
|
||||
Console.WriteLine("Site download functionality is only available to Redump members");
|
||||
return false;
|
||||
return ids;
|
||||
}
|
||||
|
||||
for (int id = minId; id <= maxId; id++)
|
||||
{
|
||||
ids.Add(id);
|
||||
if (await rc.DownloadSingleSiteID(id, outDir, true))
|
||||
DelayHelper.DelayRandom(); // Intentional sleep here so we don't flood the server
|
||||
}
|
||||
|
||||
return true;
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
#if NET20 || NET35
|
||||
using System.Collections.Generic;
|
||||
#endif
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Threading.Tasks;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
|
||||
@@ -23,92 +17,15 @@ 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)
|
||||
{
|
||||
#if NET20 || NET35
|
||||
var systems = new List<RedumpSystem?>();
|
||||
foreach (RedumpSystem s in Enum.GetValues(typeof(RedumpSystem)))
|
||||
{
|
||||
systems.Add(new Nullable<RedumpSystem>(s));
|
||||
}
|
||||
#elif NET40_OR_GREATER || NETCOREAPP3_1
|
||||
var systems = Enum.GetValues(typeof(RedumpSystem))
|
||||
.OfType<RedumpSystem>()
|
||||
.Select(s => new Nullable<RedumpSystem>(s));
|
||||
#else
|
||||
var systems = Enum.GetValues<RedumpSystem>().Select(s => new RedumpSystem?(s));
|
||||
#endif
|
||||
var systems = (RedumpSystem[])Enum.GetValues(typeof(RedumpSystem));
|
||||
|
||||
#if NET20 || NET35
|
||||
var filtered = new List<RedumpSystem?>();
|
||||
foreach (var s in systems)
|
||||
{
|
||||
if (s.HasCues())
|
||||
filtered.Add(s);
|
||||
}
|
||||
await rc.DownloadPacks(Constants.PackCuesUrl, filtered.ToArray(), "CUEs", outDir, useSubfolders ? "cue" : null);
|
||||
|
||||
filtered = new List<RedumpSystem?>();
|
||||
foreach (var s in systems)
|
||||
{
|
||||
if (s.HasDat())
|
||||
filtered.Add(s);
|
||||
}
|
||||
await rc.DownloadPacks(Constants.PackDatfileUrl, filtered.ToArray(), "DATs", outDir, useSubfolders ? "dat" : null);
|
||||
|
||||
filtered = new List<RedumpSystem?>();
|
||||
foreach (var s in systems)
|
||||
{
|
||||
if (s.HasCues())
|
||||
filtered.Add(s);
|
||||
}
|
||||
|
||||
filtered = new List<RedumpSystem?>();
|
||||
foreach (var s in systems)
|
||||
{
|
||||
if (s.HasDkeys())
|
||||
filtered.Add(s);
|
||||
}
|
||||
await rc.DownloadPacks(Constants.PackDkeysUrl, filtered.ToArray(), "Decrypted KEYS", outDir, useSubfolders ? "dkey" : null);
|
||||
|
||||
filtered = new List<RedumpSystem?>();
|
||||
foreach (var s in systems)
|
||||
{
|
||||
if (s.HasGdi())
|
||||
filtered.Add(s);
|
||||
}
|
||||
await rc.DownloadPacks(Constants.PackGdiUrl, filtered.ToArray(), "GDIs", outDir, useSubfolders ? "gdi" : null);
|
||||
|
||||
filtered = new List<RedumpSystem?>();
|
||||
foreach (var s in systems)
|
||||
{
|
||||
if (s.HasKeys())
|
||||
filtered.Add(s);
|
||||
}
|
||||
await rc.DownloadPacks(Constants.PackKeysUrl, filtered.ToArray(), "KEYS", outDir, useSubfolders ? "keys" : null);
|
||||
|
||||
filtered = new List<RedumpSystem?>();
|
||||
foreach (var s in systems)
|
||||
{
|
||||
if (s.HasLsd())
|
||||
filtered.Add(s);
|
||||
}
|
||||
await rc.DownloadPacks(Constants.PackLsdUrl, filtered.ToArray(), "LSD", outDir, useSubfolders ? "lsd" : null);
|
||||
|
||||
filtered = new List<RedumpSystem?>();
|
||||
foreach (var s in systems)
|
||||
{
|
||||
if (s.HasSbi())
|
||||
filtered.Add(s);
|
||||
}
|
||||
await rc.DownloadPacks(Constants.PackSbiUrl, filtered.ToArray(), "SBIs", outDir, useSubfolders ? "sbi" : null);
|
||||
#else
|
||||
await rc.DownloadPacks(Constants.PackCuesUrl, systems.Where(s => s.HasCues()).ToArray(), "CUEs", outDir, useSubfolders ? "cue" : null);
|
||||
await rc.DownloadPacks(Constants.PackDatfileUrl, systems.Where(s => s.HasDat()).ToArray(), "DATs", outDir, useSubfolders ? "dat" : null);
|
||||
await rc.DownloadPacks(Constants.PackDkeysUrl, systems.Where(s => s.HasDkeys()).ToArray(), "Decrypted KEYS", outDir, useSubfolders ? "dkey" : null);
|
||||
await rc.DownloadPacks(Constants.PackGdiUrl, systems.Where(s => s.HasGdi()).ToArray(), "GDIs", outDir, useSubfolders ? "gdi" : null);
|
||||
await rc.DownloadPacks(Constants.PackKeysUrl, systems.Where(s => s.HasKeys()).ToArray(), "KEYS", outDir, useSubfolders ? "keys" : null);
|
||||
await rc.DownloadPacks(Constants.PackLsdUrl, systems.Where(s => s.HasLsd()).ToArray(), "LSD", outDir, useSubfolders ? "lsd" : null);
|
||||
await rc.DownloadPacks(Constants.PackSbiUrl, systems.Where(s => s.HasSbi()).ToArray(), "SBIs", outDir, useSubfolders ? "sbi" : null);
|
||||
#endif
|
||||
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);
|
||||
await rc.DownloadPacks(Constants.PackDkeysUrl, Array.FindAll(systems, s => s.HasDkeys()), "Decrypted KEYS", outDir, useSubfolders ? "dkey" : null);
|
||||
await rc.DownloadPacks(Constants.PackGdiUrl, Array.FindAll(systems, s => s.HasGdi()), "GDIs", outDir, useSubfolders ? "gdi" : null);
|
||||
await rc.DownloadPacks(Constants.PackKeysUrl, Array.FindAll(systems, s => s.HasKeys()), "KEYS", outDir, useSubfolders ? "keys" : null);
|
||||
await rc.DownloadPacks(Constants.PackLsdUrl, Array.FindAll(systems, s => s.HasLsd()), "LSD", outDir, useSubfolders ? "lsd" : null);
|
||||
await rc.DownloadPacks(Constants.PackSbiUrl, Array.FindAll(systems, s => s.HasSbi()), "SBIs", outDir, useSubfolders ? "sbi" : null);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -122,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);
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Net;
|
||||
#if NETCOREAPP
|
||||
using System.Net.Http;
|
||||
@@ -219,11 +216,7 @@ namespace SabreTools.RedumpLib.Web
|
||||
|
||||
// Otherwise, traverse each dump on the page
|
||||
var matches = Constants.DiscRegex.Matches(dumpsPage);
|
||||
#if NET20 || NET35
|
||||
foreach (Match? match in matches)
|
||||
#else
|
||||
foreach (Match? match in matches.Cast<Match?>())
|
||||
#endif
|
||||
{
|
||||
if (match == null)
|
||||
continue;
|
||||
@@ -249,15 +242,17 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// <param name="url">Base URL to download using</param>
|
||||
/// <param name="outDir">Output directory to save data to</param>
|
||||
/// <param name="failOnSingle">True to return on first error, false otherwise</param>
|
||||
/// <returns>True if the page could be downloaded, false otherwise</returns>
|
||||
public async Task<bool> CheckSingleSitePage(string url, string? outDir, bool failOnSingle)
|
||||
/// <returns>List of IDs that were found on success, empty on error</returns>
|
||||
public async Task<List<int>> CheckSingleSitePage(string url, string? outDir, bool failOnSingle)
|
||||
{
|
||||
List<int> ids = [];
|
||||
|
||||
// Try to retrieve the data
|
||||
string? dumpsPage = await DownloadStringWithRetries(url);
|
||||
|
||||
// If we have no dumps left
|
||||
if (dumpsPage == null || dumpsPage.Contains("No discs found."))
|
||||
return false;
|
||||
return ids;
|
||||
|
||||
// If we have a single disc page already
|
||||
if (dumpsPage.Contains("<b>Download:</b>"))
|
||||
@@ -265,21 +260,18 @@ namespace SabreTools.RedumpLib.Web
|
||||
var value = Regex.Match(dumpsPage, @"/disc/(\d+)/sfv/").Groups[1].Value;
|
||||
if (int.TryParse(value, out int id))
|
||||
{
|
||||
ids.Add(id);
|
||||
bool downloaded = await DownloadSingleSiteID(id, outDir, false);
|
||||
if (!downloaded && failOnSingle)
|
||||
return false;
|
||||
return ids;
|
||||
}
|
||||
|
||||
return false;
|
||||
return ids;
|
||||
}
|
||||
|
||||
// Otherwise, traverse each dump on the page
|
||||
var matches = Constants.DiscRegex.Matches(dumpsPage);
|
||||
#if NET20 || NET35
|
||||
foreach (Match? match in matches)
|
||||
#else
|
||||
foreach (Match? match in matches.Cast<Match?>())
|
||||
#endif
|
||||
{
|
||||
if (match == null)
|
||||
continue;
|
||||
@@ -288,9 +280,10 @@ namespace SabreTools.RedumpLib.Web
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int value))
|
||||
{
|
||||
ids.Add(value);
|
||||
bool downloaded = await DownloadSingleSiteID(value, outDir, false);
|
||||
if (!downloaded && failOnSingle)
|
||||
return false;
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -300,7 +293,7 @@ namespace SabreTools.RedumpLib.Web
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return ids;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -321,11 +314,7 @@ namespace SabreTools.RedumpLib.Web
|
||||
|
||||
// Otherwise, traverse each dump on the page
|
||||
var matches = Constants.NewDiscRegex.Matches(dumpsPage);
|
||||
#if NET20 || NET35
|
||||
foreach (Match? match in matches)
|
||||
#else
|
||||
foreach (Match? match in matches.Cast<Match?>())
|
||||
#endif
|
||||
{
|
||||
if (match == null)
|
||||
continue;
|
||||
@@ -351,23 +340,21 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// <param name="wc">RedumpWebClient to access the packs</param>
|
||||
/// <param name="outDir">Output directory to save data to</param>
|
||||
/// <param name="failOnSingle">True to return on first error, false otherwise</param>
|
||||
/// <returns>True if the page could be downloaded, false otherwise</returns>
|
||||
public async Task<bool> CheckSingleWIPPage(string url, string? outDir, bool failOnSingle)
|
||||
/// <returns>List of IDs that were found on success, empty on error</returns>
|
||||
public async Task<List<int>> CheckSingleWIPPage(string url, string? outDir, bool failOnSingle)
|
||||
{
|
||||
List<int> ids = [];
|
||||
|
||||
// Try to retrieve the data
|
||||
string? dumpsPage = await DownloadStringWithRetries(url);
|
||||
|
||||
// If we have no dumps left
|
||||
if (dumpsPage == null || dumpsPage.Contains("No discs found."))
|
||||
return false;
|
||||
return ids;
|
||||
|
||||
// Otherwise, traverse each dump on the page
|
||||
var matches = Constants.NewDiscRegex.Matches(dumpsPage);
|
||||
#if NET20 || NET35
|
||||
foreach (Match? match in matches)
|
||||
#else
|
||||
foreach (Match? match in matches.Cast<Match?>())
|
||||
#endif
|
||||
{
|
||||
if (match == null)
|
||||
continue;
|
||||
@@ -376,9 +363,10 @@ namespace SabreTools.RedumpLib.Web
|
||||
{
|
||||
if (int.TryParse(match.Groups[2].Value, out int value))
|
||||
{
|
||||
ids.Add(value);
|
||||
bool downloaded = await DownloadSingleWIPID(value, outDir, false);
|
||||
if (!downloaded && failOnSingle)
|
||||
return false;
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -388,7 +376,7 @@ namespace SabreTools.RedumpLib.Web
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return ids;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -737,7 +725,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[]>();
|
||||
|
||||
@@ -745,7 +733,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
|
||||
@@ -760,7 +748,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)}");
|
||||
@@ -777,13 +765,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
|
||||
|
||||
@@ -15,12 +15,13 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// </summary>
|
||||
/// <param name="rc">RedumpClient for connectivity</param>
|
||||
/// <param name="query">Query string to attempt to search for</param>
|
||||
/// <returns>All disc IDs for the given query, null on error</returns>
|
||||
public static async Task<List<int>?> ListSearchResults(RedumpClient rc, string? query)
|
||||
/// <param name="noSlash">Don't replace slashes with `-` in queries</param>
|
||||
/// <returns>All disc IDs for the given query, empty on error</returns>
|
||||
public static async Task<List<int>> ListSearchResults(RedumpClient rc, string? query, bool noSlash)
|
||||
{
|
||||
// If the query is invalid
|
||||
if (string.IsNullOrEmpty(query))
|
||||
return null;
|
||||
return [];
|
||||
|
||||
List<int> ids = [];
|
||||
|
||||
@@ -29,8 +30,9 @@ namespace SabreTools.RedumpLib.Web
|
||||
|
||||
// Special characters become dashes
|
||||
query = query.Replace(' ', '-');
|
||||
query = query.Replace('/', '-');
|
||||
query = query.Replace('\\', '/');
|
||||
query = query.Replace('\\', '-');
|
||||
if (!noSlash)
|
||||
query = query.Replace('/', '-');
|
||||
|
||||
// Lowercase is defined per language
|
||||
query = query.ToLowerInvariant();
|
||||
@@ -50,7 +52,7 @@ namespace SabreTools.RedumpLib.Web
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"An exception occurred while trying to log in: {ex}");
|
||||
return null;
|
||||
return [];
|
||||
}
|
||||
|
||||
return ids;
|
||||
@@ -62,19 +64,24 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// <param name="rc">RedumpClient for connectivity</param>
|
||||
/// <param name="query">Query string to attempt to search for</param>
|
||||
/// <param name="outDir">Output directory to save data to</param>
|
||||
public static async Task<bool> DownloadSearchResults(RedumpClient rc, string? query, string? outDir)
|
||||
/// <param name="noSlash">Don't replace slashes with `-` in queries</param>
|
||||
/// <returns>All disc IDs for the given query, empty on error</returns>
|
||||
public static async Task<List<int>> DownloadSearchResults(RedumpClient rc, string? query, string? outDir, bool noSlash)
|
||||
{
|
||||
List<int> ids = [];
|
||||
|
||||
// If the query is invalid
|
||||
if (string.IsNullOrEmpty(query))
|
||||
return false;
|
||||
return ids;
|
||||
|
||||
// Strip quotes
|
||||
query = query!.Trim('"', '\'');
|
||||
|
||||
// Special characters become dashes
|
||||
query = query.Replace(' ', '-');
|
||||
query = query.Replace('/', '-');
|
||||
query = query.Replace('\\', '/');
|
||||
query = query.Replace('\\', '-');
|
||||
if (!noSlash)
|
||||
query = query.Replace('/', '-');
|
||||
|
||||
// Lowercase is defined per language
|
||||
query = query.ToLowerInvariant();
|
||||
@@ -83,11 +90,13 @@ namespace SabreTools.RedumpLib.Web
|
||||
int pageNumber = 1;
|
||||
while (true)
|
||||
{
|
||||
if (!await rc.CheckSingleSitePage(string.Format(Constants.QuickSearchUrl, query, pageNumber++), outDir, false))
|
||||
var pageIds = await rc.CheckSingleSitePage(string.Format(Constants.QuickSearchUrl, query, pageNumber++), outDir, false);
|
||||
ids.AddRange(pageIds);
|
||||
if (pageIds.Count == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,23 +16,28 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// <param name="rc">RedumpClient for connectivity</param>
|
||||
/// <param name="username">Username to check discs for</param>
|
||||
/// <param name="outDir">Output directory to save data to</param>
|
||||
public static async Task<bool> DownloadUser(RedumpClient rc, string? username, string? outDir)
|
||||
/// <returns>All disc IDs for the given user, empty on error</returns>
|
||||
public static async Task<List<int>> DownloadUser(RedumpClient rc, string? username, string? outDir)
|
||||
{
|
||||
List<int> ids = [];
|
||||
|
||||
if (!rc.LoggedIn || string.IsNullOrEmpty(username))
|
||||
{
|
||||
Console.WriteLine("User download functionality is only available to Redump members");
|
||||
return false;
|
||||
return ids;
|
||||
}
|
||||
|
||||
// Keep getting user pages until there are none left
|
||||
int pageNumber = 1;
|
||||
while (true)
|
||||
{
|
||||
if (!await rc.CheckSingleSitePage(string.Format(Constants.UserDumpsUrl, username, pageNumber++), outDir, false))
|
||||
var pageIds = await rc.CheckSingleSitePage(string.Format(Constants.UserDumpsUrl, username, pageNumber++), outDir, false);
|
||||
ids.AddRange(pageIds);
|
||||
if (pageIds.Count == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ids;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -41,23 +46,28 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// <param name="rc">RedumpClient for connectivity</param>
|
||||
/// <param name="username">Username to check discs for</param>
|
||||
/// <param name="outDir">Output directory to save data to</param>
|
||||
public static async Task<bool> DownloadUserLastModified(RedumpClient rc, string? username, string? outDir)
|
||||
/// <returns>All disc IDs for the given user, empty on error</returns>
|
||||
public static async Task<List<int>> DownloadUserLastModified(RedumpClient rc, string? username, string? outDir)
|
||||
{
|
||||
List<int> ids = [];
|
||||
|
||||
if (!rc.LoggedIn || string.IsNullOrEmpty(username))
|
||||
{
|
||||
Console.WriteLine("User download functionality is only available to Redump members");
|
||||
return false;
|
||||
return ids;
|
||||
}
|
||||
|
||||
// Keep getting last modified user pages until there are none left
|
||||
int pageNumber = 1;
|
||||
while (true)
|
||||
{
|
||||
if (!await rc.CheckSingleSitePage(string.Format(Constants.UserDumpsLastModifiedUrl, username, pageNumber++), outDir, true))
|
||||
var pageIds = await rc.CheckSingleSitePage(string.Format(Constants.UserDumpsLastModifiedUrl, username, pageNumber++), outDir, true);
|
||||
ids.AddRange(pageIds);
|
||||
if (pageIds.Count == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ids;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -65,8 +75,8 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// </summary>
|
||||
/// <param name="rc">RedumpClient for connectivity</param>
|
||||
/// <param name="username">Username to check discs for</param>
|
||||
/// <returns>All disc IDs for the given user, null on error</returns>
|
||||
public static async Task<List<int>?> ListUser(RedumpClient rc, string? username)
|
||||
/// <returns>All disc IDs for the given user, empty on error</returns>
|
||||
public static async Task<List<int>> ListUser(RedumpClient rc, string? username)
|
||||
{
|
||||
List<int> ids = [];
|
||||
|
||||
@@ -82,7 +92,7 @@ namespace SabreTools.RedumpLib.Web
|
||||
int pageNumber = 1;
|
||||
while (true)
|
||||
{
|
||||
List<int> pageIds = await rc.CheckSingleSitePage(string.Format(Constants.UserDumpsUrl, username, pageNumber++));
|
||||
var pageIds = await rc.CheckSingleSitePage(string.Format(Constants.UserDumpsUrl, username, pageNumber++));
|
||||
ids.AddRange(pageIds);
|
||||
if (pageIds.Count <= 1)
|
||||
break;
|
||||
@@ -91,7 +101,7 @@ namespace SabreTools.RedumpLib.Web
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"An exception occurred while trying to log in: {ex}");
|
||||
return null;
|
||||
return [];
|
||||
}
|
||||
|
||||
return ids;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
|
||||
@@ -14,7 +15,8 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// </summary>
|
||||
/// <param name="rc">RedumpClient for connectivity</param>
|
||||
/// <param name="outDir">Output directory to save data to</param>
|
||||
public static async Task<bool> DownloadLastSubmitted(RedumpClient rc, string? outDir)
|
||||
/// <returns>All disc IDs in last submitted range, empty on error</returns>
|
||||
public static async Task<List<int>> DownloadLastSubmitted(RedumpClient rc, string? outDir)
|
||||
{
|
||||
return await rc.CheckSingleWIPPage(Constants.WipDumpsUrl, outDir, false);
|
||||
}
|
||||
@@ -26,21 +28,25 @@ namespace SabreTools.RedumpLib.Web
|
||||
/// <param name="outDir">Output directory to save data to</param>
|
||||
/// <param name="minId">Starting ID for the range</param>
|
||||
/// <param name="maxId">Ending ID for the range (inclusive)</param>
|
||||
public static async Task<bool> DownloadWIPRange(RedumpClient rc, string? outDir, int minId = 0, int maxId = 0)
|
||||
/// <returns>All disc IDs in last submitted range, empty on error</returns>
|
||||
public static async Task<List<int>> DownloadWIPRange(RedumpClient rc, string? outDir, int minId = 0, int maxId = 0)
|
||||
{
|
||||
List<int> ids = [];
|
||||
|
||||
if (!rc.LoggedIn || !rc.IsStaff)
|
||||
{
|
||||
Console.WriteLine("WIP download functionality is only available to Redump moderators");
|
||||
return false;
|
||||
return ids;
|
||||
}
|
||||
|
||||
for (int id = minId; id <= maxId; id++)
|
||||
{
|
||||
ids.Add(id);
|
||||
if (await rc.DownloadSingleWIPID(id, outDir, true))
|
||||
DelayHelper.DelayRandom(); // Intentional sleep here so we don't flood the server
|
||||
}
|
||||
|
||||
return true;
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#! /bin/bash
|
||||
|
||||
# This batch file assumes the following:
|
||||
# - .NET 8.0 (or newer) SDK is installed and in PATH
|
||||
# - .NET 9.0 (or newer) SDK is installed and in PATH
|
||||
#
|
||||
# If any of these are not satisfied, the operation may fail
|
||||
# in an unpredictable way and result in an incomplete output.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This batch file assumes the following:
|
||||
# - .NET 8.0 (or newer) SDK is installed and in PATH
|
||||
# - .NET 9.0 (or newer) SDK is installed and in PATH
|
||||
#
|
||||
# If any of these are not satisfied, the operation may fail
|
||||
# in an unpredictable way and result in an incomplete output.
|
||||
|
||||
Reference in New Issue
Block a user