summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs')
-rw-r--r--src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs161
1 files changed, 0 insertions, 161 deletions
diff --git a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs b/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs
deleted file mode 100644
index d0da42df..00000000
--- a/src/StardewModdingAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityClient.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Threading.Tasks;
-using HtmlAgilityPack;
-using Pathoschild.Http.Client;
-
-namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
-{
- /// <summary>An HTTP client for fetching mod metadata from the wiki compatibility list.</summary>
- public class WikiCompatibilityClient : IDisposable
- {
- /*********
- ** Properties
- *********/
- /// <summary>The underlying HTTP client.</summary>
- private readonly IClient Client;
-
-
- /*********
- ** Public methods
- *********/
- /// <summary>Construct an instance.</summary>
- /// <param name="userAgent">The user agent for the wiki API.</param>
- /// <param name="baseUrl">The base URL for the wiki API.</param>
- public WikiCompatibilityClient(string userAgent, string baseUrl = "https://stardewvalleywiki.com/mediawiki/api.php")
- {
- this.Client = new FluentClient(baseUrl).SetUserAgent(userAgent);
- }
-
- /// <summary>Fetch mod compatibility entries.</summary>
- public async Task<WikiCompatibilityEntry[]> FetchAsync()
- {
- // fetch HTML
- ResponseModel response = await this.Client
- .GetAsync("")
- .WithArguments(new
- {
- action = "parse",
- page = "Modding:SMAPI_compatibility",
- format = "json"
- })
- .As<ResponseModel>();
- string html = response.Parse.Text["*"];
-
- // parse HTML
- var doc = new HtmlDocument();
- doc.LoadHtml(html);
-
- // find mod entries
- HtmlNodeCollection modNodes = doc.DocumentNode.SelectNodes("table[@id='mod-list']//tr[@class='mod']");
- if (modNodes == null)
- throw new InvalidOperationException("Can't parse wiki compatibility list, no mods found.");
-
- // parse
- return this.ParseEntries(modNodes).ToArray();
- }
-
- /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
- public void Dispose()
- {
- this.Client?.Dispose();
- }
-
-
- /*********
- ** Private methods
- *********/
- /// <summary>Parse valid mod compatibility entries.</summary>
- /// <param name="nodes">The HTML compatibility entries.</param>
- private IEnumerable<WikiCompatibilityEntry> ParseEntries(IEnumerable<HtmlNode> nodes)
- {
- foreach (HtmlNode node in nodes)
- {
- // parse status
- WikiCompatibilityStatus status;
- {
- string rawStatus = node.GetAttributeValue("data-status", null);
- if (rawStatus == null)
- continue; // not a mod node?
- if (!Enum.TryParse(rawStatus, true, out status))
- throw new InvalidOperationException($"Unknown status '{rawStatus}' when parsing compatibility list.");
- }
-
- // parse unofficial version
- ISemanticVersion unofficialVersion = null;
- {
- string rawUnofficialVersion = node.GetAttributeValue("data-unofficial-version", null);
- SemanticVersion.TryParse(rawUnofficialVersion, out unofficialVersion);
- }
-
- // parse other fields
- string name = node.Descendants("td").FirstOrDefault()?.InnerText?.Trim();
- string summary = node.Descendants("td").FirstOrDefault(p => p.GetAttributeValue("class", null) == "summary")?.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");
-
- // yield model
- yield return new WikiCompatibilityEntry
- {
- ID = ids,
- Name = name,
- Status = status,
- NexusID = nexusID,
- ChucklefishID = chucklefishID,
- GitHubRepo = githubRepo,
- CustomSourceUrl = customSourceUrl,
- CustomUrl = customUrl,
- UnofficialVersion = unofficialVersion,
- Summary = summary
- };
- }
- }
-
- /// <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)
- {
- string raw = this.GetAttribute(node, attributeName);
- 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")]
- private class ResponseModel
- {
- /// <summary>The parse API results.</summary>
- public ResponseParseModel Parse { get; set; }
- }
-
- /// <summary>The inner response model for the MediaWiki parse API.</summary>
- [SuppressMessage("ReSharper", "ClassNeverInstantiated.Local")]
- [SuppressMessage("ReSharper", "CollectionNeverUpdated.Local")]
- [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")]
- private class ResponseParseModel
- {
- /// <summary>The parsed text.</summary>
- public IDictionary<string, string> Text { get; set; }
- }
- }
-}