summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki
diff options
context:
space:
mode:
Diffstat (limited to 'src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki')
-rw-r--r--src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs123
-rw-r--r--src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs60
-rw-r--r--src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityInfo.cs21
-rw-r--r--src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs54
4 files changed, 143 insertions, 115 deletions
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs
index 4060ed36..569e820b 100644
--- a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs
+++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs
@@ -30,7 +30,7 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
}
/// <summary>Fetch mod compatibility entries.</summary>
- public async Task<WikiCompatibilityEntry[]> FetchAsync()
+ public async Task<WikiModEntry[]> FetchAsync()
{
// fetch HTML
ResponseModel response = await this.Client
@@ -69,100 +69,113 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
*********/
/// <summary>Parse valid mod compatibility entries.</summary>
/// <param name="nodes">The HTML compatibility entries.</param>
- private IEnumerable<WikiCompatibilityEntry> ParseEntries(IEnumerable<HtmlNode> nodes)
+ private IEnumerable<WikiModEntry> ParseEntries(IEnumerable<HtmlNode> nodes)
{
foreach (HtmlNode node in nodes)
{
- // parse mod info
- string name = node.Descendants("td").FirstOrDefault()?.Descendants("a")?.FirstOrDefault()?.InnerText?.Trim();
- string[] ids = this.GetAttribute(node, "data-id")?.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToArray() ?? new string[0];
- int? nexusID = this.GetNullableIntAttribute(node, "data-nexus-id");
- int? chucklefishID = this.GetNullableIntAttribute(node, "data-chucklefish-id");
- string githubRepo = this.GetAttribute(node, "data-github");
- string customSourceUrl = this.GetAttribute(node, "data-custom-source");
- string customUrl = this.GetAttribute(node, "data-custom-url");
+ // extract fields
+ string name = this.GetMetadataField(node, "mod-name");
+ string alternateNames = this.GetMetadataField(node, "mod-name2");
+ string author = this.GetMetadataField(node, "mod-author");
+ string alternateAuthors = this.GetMetadataField(node, "mod-author2");
+ string[] ids = this.GetMetadataField(node, "mod-id")?.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToArray() ?? new string[0];
+ int? nexusID = this.GetNullableIntField(node, "mod-nexus-id");
+ int? chucklefishID = this.GetNullableIntField(node, "mod-chucklefish-id");
+ string githubRepo = this.GetMetadataField(node, "mod-github");
+ string customSourceUrl = this.GetMetadataField(node, "mod-custom-source");
+ string customUrl = this.GetMetadataField(node, "mod-url");
+ string brokeIn = this.GetMetadataField(node, "mod-broke-in");
+ string anchor = this.GetMetadataField(node, "mod-anchor");
// parse stable compatibility
- WikiCompatibilityStatus status = this.GetStatusAttribute(node, "data-status") ?? WikiCompatibilityStatus.Ok;
- ISemanticVersion unofficialVersion = this.GetSemanticVersionAttribute(node, "data-unofficial-version");
- string summary = node.Descendants().FirstOrDefault(p => p.HasClass("data-summary"))?.InnerText.Trim();
+ WikiCompatibilityInfo compatibility = new WikiCompatibilityInfo
+ {
+ Status = this.GetStatusField(node, "mod-status") ?? WikiCompatibilityStatus.Ok,
+ UnofficialVersion = this.GetSemanticVersionField(node, "mod-unofficial-version"),
+ UnofficialUrl = this.GetMetadataField(node, "mod-unofficial-url"),
+ Summary = this.GetMetadataField(node, "mod-summary")?.Trim()
+ };
// parse beta compatibility
- WikiCompatibilityStatus? betaStatus = this.GetStatusAttribute(node, "data-beta-status");
- ISemanticVersion betaUnofficialVersion = betaStatus.HasValue ? this.GetSemanticVersionAttribute(node, "data-beta-unofficial-version") : null;
- string betaSummary = betaStatus.HasValue ? node.Descendants().FirstOrDefault(p => p.HasClass("data-beta-summary"))?.InnerText.Trim() : null;
+ WikiCompatibilityInfo betaCompatibility = null;
+ {
+ WikiCompatibilityStatus? betaStatus = this.GetStatusField(node, "mod-beta-status");
+ if (betaStatus.HasValue)
+ {
+ betaCompatibility = new WikiCompatibilityInfo
+ {
+ Status = betaStatus.Value,
+ UnofficialVersion = this.GetSemanticVersionField(node, "mod-beta-unofficial-version"),
+ UnofficialUrl = this.GetMetadataField(node, "mod-beta-unofficial-url"),
+ Summary = this.GetMetadataField(node, "mod-beta-summary")
+ };
+ }
+ }
// yield model
- yield return new WikiCompatibilityEntry
+ yield return new WikiModEntry
{
- // mod info
ID = ids,
Name = name,
+ AlternateNames = alternateNames,
+ Author = author,
+ AlternateAuthors = alternateAuthors,
NexusID = nexusID,
ChucklefishID = chucklefishID,
GitHubRepo = githubRepo,
CustomSourceUrl = customSourceUrl,
CustomUrl = customUrl,
-
- // stable compatibility
- Status = status,
- Summary = summary,
- UnofficialVersion = unofficialVersion,
-
- // beta compatibility
- BetaStatus = betaStatus,
- BetaSummary = betaSummary,
- BetaUnofficialVersion = betaUnofficialVersion
+ BrokeIn = brokeIn,
+ Compatibility = compatibility,
+ BetaCompatibility = betaCompatibility,
+ Anchor = anchor
};
}
}
- /// <summary>Get a compatibility status attribute value.</summary>
- /// <param name="node">The HTML node.</param>
- /// <param name="attributeName">The attribute name.</param>
- private WikiCompatibilityStatus? GetStatusAttribute(HtmlNode node, string attributeName)
+ /// <summary>Get the value of a metadata field.</summary>
+ /// <param name="container">The metadata container.</param>
+ /// <param name="name">The field name.</param>
+ private string GetMetadataField(HtmlNode container, string name)
{
- string raw = node.GetAttributeValue(attributeName, null);
+ return container.Descendants().FirstOrDefault(p => p.HasClass(name))?.InnerHtml;
+ }
+
+ /// <summary>Get the value of a metadata field as a compatibility status.</summary>
+ /// <param name="container">The metadata container.</param>
+ /// <param name="name">The field name.</param>
+ private WikiCompatibilityStatus? GetStatusField(HtmlNode container, string name)
+ {
+ string raw = this.GetMetadataField(container, name);
if (raw == null)
- return null; // not a mod node?
+ return null;
if (!Enum.TryParse(raw, true, out WikiCompatibilityStatus status))
throw new InvalidOperationException($"Unknown status '{raw}' when parsing compatibility list.");
return status;
}
- /// <summary>Get a semantic version attribute value.</summary>
- /// <param name="node">The HTML node.</param>
- /// <param name="attributeName">The attribute name.</param>
- private ISemanticVersion GetSemanticVersionAttribute(HtmlNode node, string attributeName)
+ /// <summary>Get the value of a metadata field as a semantic version.</summary>
+ /// <param name="container">The metadata container.</param>
+ /// <param name="name">The field name.</param>
+ private ISemanticVersion GetSemanticVersionField(HtmlNode container, string name)
{
- string raw = node.GetAttributeValue(attributeName, null);
+ string raw = this.GetMetadataField(container, name);
return SemanticVersion.TryParse(raw, out ISemanticVersion version)
? version
: null;
}
- /// <summary>Get a nullable integer attribute value.</summary>
- /// <param name="node">The HTML node.</param>
- /// <param name="attributeName">The attribute name.</param>
- private int? GetNullableIntAttribute(HtmlNode node, string attributeName)
+ /// <summary>Get the value of a metadata field as a nullable integer.</summary>
+ /// <param name="container">The metadata container.</param>
+ /// <param name="name">The field name.</param>
+ private int? GetNullableIntField(HtmlNode container, string name)
{
- string raw = this.GetAttribute(node, attributeName);
+ string raw = this.GetMetadataField(container, name);
if (raw != null && int.TryParse(raw, out int value))
return value;
return null;
}
- /// <summary>Get a strings attribute value.</summary>
- /// <param name="node">The HTML node.</param>
- /// <param name="attributeName">The attribute name.</param>
- private string GetAttribute(HtmlNode node, string attributeName)
- {
- string raw = node.GetAttributeValue(attributeName, null);
- if (raw != null)
- raw = HtmlEntity.DeEntitize(raw);
- return raw;
- }
-
/// <summary>The response model for the MediaWiki parse API.</summary>
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Local")]
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")]
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs
deleted file mode 100644
index 3cb9c97c..00000000
--- a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityEntry.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
-{
- /// <summary>An entry in the mod compatibility list.</summary>
- public class WikiCompatibilityEntry
- {
- /*********
- ** Accessors
- *********/
- /****
- ** Mod info
- ****/
- /// <summary>The mod's unique ID. A mod may have multiple current IDs in rare cases (e.g. due to parallel releases or unofficial updates).</summary>
- public string[] ID { get; set; }
-
- /// <summary>The mod's display name.</summary>
- public string Name { get; set; }
-
- /// <summary>The mod ID on Nexus.</summary>
- public int? NexusID { get; set; }
-
- /// <summary>The mod ID in the Chucklefish mod repo.</summary>
- public int? ChucklefishID { get; set; }
-
- /// <summary>The GitHub repository in the form 'owner/repo'.</summary>
- public string GitHubRepo { get; set; }
-
- /// <summary>The URL to a non-GitHub source repo.</summary>
- public string CustomSourceUrl { get; set; }
-
- /// <summary>The custom mod page URL (if applicable).</summary>
- public string CustomUrl { get; set; }
-
- /****
- ** Stable compatibility
- ****/
- /// <summary>The compatibility status.</summary>
- public WikiCompatibilityStatus Status { get; set; }
-
- /// <summary>The human-readable summary of the compatibility status or workaround, without HTML formatting.</summary>
- public string Summary { get; set; }
-
- /// <summary>The version of the latest unofficial update, if applicable.</summary>
- public ISemanticVersion UnofficialVersion { get; set; }
-
- /****
- ** Beta compatibility
- ****/
- /// <summary>Whether a Stardew Valley or SMAPI beta which affects mod compatibility is in progress. If this is true, <see cref="BetaUnofficialVersion"/> should be used for beta versions of SMAPI instead of <see cref="UnofficialVersion"/>.</summary>
- public bool HasBetaInfo => this.BetaStatus != null;
-
- /// <summary>The compatibility status for the Stardew Valley beta, if a beta is in progress.</summary>
- public WikiCompatibilityStatus? BetaStatus { get; set; }
-
- /// <summary>The human-readable summary of the compatibility status or workaround for the Stardew Valley beta (if any), without HTML formatting.</summary>
- public string BetaSummary { get; set; }
-
- /// <summary>The version of the latest unofficial update for the Stardew Valley beta (if any), if applicable.</summary>
- public ISemanticVersion BetaUnofficialVersion { get; set; }
- }
-}
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityInfo.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityInfo.cs
new file mode 100644
index 00000000..2725df1a
--- /dev/null
+++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityInfo.cs
@@ -0,0 +1,21 @@
+namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
+{
+ /// <summary>Compatibility info for a mod.</summary>
+ public class WikiCompatibilityInfo
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The compatibility status.</summary>
+ public WikiCompatibilityStatus Status { get; set; }
+
+ /// <summary>The human-readable summary of the compatibility status or workaround, without HTML formatting.</summary>
+ public string Summary { get; set; }
+
+ /// <summary>The version of the latest unofficial update, if applicable.</summary>
+ public ISemanticVersion UnofficialVersion { get; set; }
+
+ /// <summary>The URL to the latest unofficial update, if applicable.</summary>
+ public string UnofficialUrl { get; set; }
+ }
+}
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs
new file mode 100644
index 00000000..752b526c
--- /dev/null
+++ b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiModEntry.cs
@@ -0,0 +1,54 @@
+namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
+{
+ /// <summary>A mod entry in the wiki list.</summary>
+ public class WikiModEntry
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The mod's unique ID. A mod may have multiple current IDs in rare cases (e.g. due to parallel releases or unofficial updates).</summary>
+ public string[] ID { get; set; }
+
+ /// <summary>The mod's display name.</summary>
+ public string Name { get; set; }
+
+ /// <summary>The mod's alternative names, if any.</summary>
+ public string AlternateNames { get; set; }
+
+ /// <summary>The mod's author name.</summary>
+ public string Author { get; set; }
+
+ /// <summary>The mod's alternative author names, if any.</summary>
+ public string AlternateAuthors { get; set; }
+
+ /// <summary>The mod ID on Nexus.</summary>
+ public int? NexusID { get; set; }
+
+ /// <summary>The mod ID in the Chucklefish mod repo.</summary>
+ public int? ChucklefishID { get; set; }
+
+ /// <summary>The GitHub repository in the form 'owner/repo'.</summary>
+ public string GitHubRepo { get; set; }
+
+ /// <summary>The URL to a non-GitHub source repo.</summary>
+ public string CustomSourceUrl { get; set; }
+
+ /// <summary>The custom mod page URL (if applicable).</summary>
+ public string CustomUrl { get; set; }
+
+ /// <summary>The game or SMAPI version which broke this mod (if applicable).</summary>
+ public string BrokeIn { get; set; }
+
+ /// <summary>The mod's compatibility with the latest stable version of the game.</summary>
+ public WikiCompatibilityInfo Compatibility { get; set; }
+
+ /// <summary>The mod's compatibility with the latest beta version of the game (if any).</summary>
+ public WikiCompatibilityInfo BetaCompatibility { get; set; }
+
+ /// <summary>Whether a Stardew Valley or SMAPI beta which affects mod compatibility is in progress. If this is true, <see cref="BetaCompatibility"/> should be used for beta versions of SMAPI instead of <see cref="Compatibility"/>.</summary>
+ public bool HasBetaInfo => this.BetaCompatibility != null;
+
+ /// <summary>The link anchor for the mod entry in the wiki compatibility list.</summary>
+ public string Anchor { get; set; }
+ }
+}