summaryrefslogtreecommitdiff
path: root/src/SMAPI.Web/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI.Web/Framework')
-rw-r--r--src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishClient.cs83
-rw-r--r--src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishMod.cs18
-rw-r--r--src/SMAPI.Web/Framework/Clients/Chucklefish/IChucklefishClient.cs17
-rw-r--r--src/SMAPI.Web/Framework/Clients/GitHub/GitAsset.cs20
-rw-r--r--src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs70
-rw-r--r--src/SMAPI.Web/Framework/Clients/GitHub/GitRelease.cs25
-rw-r--r--src/SMAPI.Web/Framework/Clients/GitHub/IGitHubClient.cs17
-rw-r--r--src/SMAPI.Web/Framework/Clients/Nexus/INexusClient.cs17
-rw-r--r--src/SMAPI.Web/Framework/Clients/Nexus/NexusClient.cs48
-rw-r--r--src/SMAPI.Web/Framework/Clients/Nexus/NexusMod.cs21
-rw-r--r--src/SMAPI.Web/Framework/Clients/Pastebin/IPastebinClient.cs17
-rw-r--r--src/SMAPI.Web/Framework/Clients/Pastebin/PasteInfo.cs (renamed from src/SMAPI.Web/Framework/LogParser/GetPasteResponse.cs)4
-rw-r--r--src/SMAPI.Web/Framework/Clients/Pastebin/PastebinClient.cs (renamed from src/SMAPI.Web/Framework/LogParser/PastebinClient.cs)30
-rw-r--r--src/SMAPI.Web/Framework/Clients/Pastebin/SavePasteResult.cs (renamed from src/SMAPI.Web/Framework/LogParser/SavePasteResponse.cs)4
-rw-r--r--src/SMAPI.Web/Framework/ConfigModels/ApiClientsConfig.cs72
-rw-r--r--src/SMAPI.Web/Framework/ConfigModels/ContextConfig.cs15
-rw-r--r--src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs24
-rw-r--r--src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs49
-rw-r--r--src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs50
-rw-r--r--src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs59
-rw-r--r--src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs51
21 files changed, 488 insertions, 223 deletions
diff --git a/src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishClient.cs b/src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishClient.cs
new file mode 100644
index 00000000..6772672c
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishClient.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Net;
+using System.Threading.Tasks;
+using HtmlAgilityPack;
+using Pathoschild.Http.Client;
+
+namespace StardewModdingAPI.Web.Framework.Clients.Chucklefish
+{
+ /// <summary>An HTTP client for fetching mod metadata from the Chucklefish mod site.</summary>
+ internal class ChucklefishClient : IChucklefishClient
+ {
+ /*********
+ ** Properties
+ *********/
+ /// <summary>The base URL for the Chucklefish mod site.</summary>
+ private readonly string BaseUrl;
+
+ /// <summary>The URL for a mod page excluding the base URL, where {0} is the mod ID.</summary>
+ private readonly string ModPageUrlFormat;
+
+ /// <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 API client.</param>
+ /// <param name="baseUrl">The base URL for the Chucklefish mod site.</param>
+ /// <param name="modPageUrlFormat">The URL for a mod page excluding the <paramref name="baseUrl"/>, where {0} is the mod ID.</param>
+ public ChucklefishClient(string userAgent, string baseUrl, string modPageUrlFormat)
+ {
+ this.BaseUrl = baseUrl;
+ this.ModPageUrlFormat = modPageUrlFormat;
+ this.Client = new FluentClient(baseUrl).SetUserAgent(userAgent);
+ }
+
+ /// <summary>Get metadata about a mod.</summary>
+ /// <param name="id">The Chucklefish mod ID.</param>
+ /// <returns>Returns the mod info if found, else <c>null</c>.</returns>
+ public async Task<ChucklefishMod> GetModAsync(uint id)
+ {
+ // fetch HTML
+ string html;
+ try
+ {
+ html = await this.Client
+ .GetAsync(string.Format(this.ModPageUrlFormat, id))
+ .AsString();
+ }
+ catch (ApiException ex) when (ex.Status == HttpStatusCode.NotFound)
+ {
+ return null;
+ }
+
+ // parse HTML
+ var doc = new HtmlDocument();
+ doc.LoadHtml(html);
+
+ // extract mod info
+ string url = new UriBuilder(new Uri(this.BaseUrl)) { Path = string.Format(this.ModPageUrlFormat, id) }.Uri.ToString();
+ string name = doc.DocumentNode.SelectSingleNode("//meta[@name='twitter:title']").Attributes["content"].Value;
+ if (name.StartsWith("[SMAPI] "))
+ name = name.Substring("[SMAPI] ".Length);
+ string version = doc.DocumentNode.SelectSingleNode("//h1/span").InnerText;
+
+ // create model
+ return new ChucklefishMod
+ {
+ Name = name,
+ Version = version,
+ Url = url
+ };
+ }
+
+ /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
+ public void Dispose()
+ {
+ this.Client?.Dispose();
+ }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishMod.cs b/src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishMod.cs
new file mode 100644
index 00000000..fd0101d4
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishMod.cs
@@ -0,0 +1,18 @@
+namespace StardewModdingAPI.Web.Framework.Clients.Chucklefish
+{
+ /// <summary>Mod metadata from the Chucklefish mod site.</summary>
+ internal class ChucklefishMod
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The mod name.</summary>
+ public string Name { get; set; }
+
+ /// <summary>The mod's semantic version number.</summary>
+ public string Version { get; set; }
+
+ /// <summary>The mod's web URL.</summary>
+ public string Url { get; set; }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/Chucklefish/IChucklefishClient.cs b/src/SMAPI.Web/Framework/Clients/Chucklefish/IChucklefishClient.cs
new file mode 100644
index 00000000..1d8b256e
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/Chucklefish/IChucklefishClient.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Threading.Tasks;
+
+namespace StardewModdingAPI.Web.Framework.Clients.Chucklefish
+{
+ /// <summary>An HTTP client for fetching mod metadata from the Chucklefish mod site.</summary>
+ internal interface IChucklefishClient : IDisposable
+ {
+ /*********
+ ** Methods
+ *********/
+ /// <summary>Get metadata about a mod.</summary>
+ /// <param name="id">The Chucklefish mod ID.</param>
+ /// <returns>Returns the mod info if found, else <c>null</c>.</returns>
+ Task<ChucklefishMod> GetModAsync(uint id);
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/GitHub/GitAsset.cs b/src/SMAPI.Web/Framework/Clients/GitHub/GitAsset.cs
new file mode 100644
index 00000000..73ce4025
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/GitHub/GitAsset.cs
@@ -0,0 +1,20 @@
+using Newtonsoft.Json;
+
+namespace StardewModdingAPI.Web.Framework.Clients.GitHub
+{
+ /// <summary>A GitHub download attached to a release.</summary>
+ internal class GitAsset
+ {
+ /// <summary>The file name.</summary>
+ [JsonProperty("name")]
+ public string FileName { get; set; }
+
+ /// <summary>The file content type.</summary>
+ [JsonProperty("content_type")]
+ public string ContentType { get; set; }
+
+ /// <summary>The download URL.</summary>
+ [JsonProperty("browser_download_url")]
+ public string DownloadUrl { get; set; }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs b/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs
new file mode 100644
index 00000000..0b205660
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Net;
+using System.Threading.Tasks;
+using Pathoschild.Http.Client;
+
+namespace StardewModdingAPI.Web.Framework.Clients.GitHub
+{
+ /// <summary>An HTTP client for fetching metadata from GitHub.</summary>
+ internal class GitHubClient : IGitHubClient
+ {
+ /*********
+ ** Properties
+ *********/
+ /// <summary>The URL for a GitHub releases API query excluding the base URL, where {0} is the repository owner and name.</summary>
+ private readonly string ReleaseUrlFormat;
+
+ /// <summary>The underlying HTTP client.</summary>
+ private readonly IClient Client;
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="baseUrl">The base URL for the GitHub API.</param>
+ /// <param name="releaseUrlFormat">The URL for a GitHub releases API query excluding the <paramref name="baseUrl"/>, where {0} is the repository owner and name.</param>
+ /// <param name="userAgent">The user agent for the API client.</param>
+ /// <param name="acceptHeader">The Accept header value expected by the GitHub API.</param>
+ /// <param name="username">The username with which to authenticate to the GitHub API.</param>
+ /// <param name="password">The password with which to authenticate to the GitHub API.</param>
+ public GitHubClient(string baseUrl, string releaseUrlFormat, string userAgent, string acceptHeader, string username, string password)
+ {
+ this.ReleaseUrlFormat = releaseUrlFormat;
+
+ this.Client = new FluentClient(baseUrl)
+ .SetUserAgent(userAgent)
+ .AddDefault(req => req.WithHeader("Accept", acceptHeader));
+ if (!string.IsNullOrWhiteSpace(username))
+ this.Client = this.Client.SetBasicAuthentication(username, password);
+ }
+
+ /// <summary>Get the latest release for a GitHub repository.</summary>
+ /// <param name="repo">The repository key (like <c>Pathoschild/SMAPI</c>).</param>
+ /// <returns>Returns the latest release if found, else <c>null</c>.</returns>
+ public async Task<GitRelease> GetLatestReleaseAsync(string repo)
+ {
+ // validate key format
+ if (!repo.Contains("/") || repo.IndexOf("/", StringComparison.InvariantCultureIgnoreCase) != repo.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase))
+ throw new ArgumentException($"The value '{repo}' isn't a valid GitHub repository key, must be a username and project name like 'Pathoschild/SMAPI'.", nameof(repo));
+
+ // fetch info
+ try
+ {
+ return await this.Client
+ .GetAsync(string.Format(this.ReleaseUrlFormat, repo))
+ .As<GitRelease>();
+ }
+ catch (ApiException ex) when (ex.Status == HttpStatusCode.NotFound)
+ {
+ return null;
+ }
+ }
+
+ /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
+ public void Dispose()
+ {
+ this.Client?.Dispose();
+ }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/GitHub/GitRelease.cs b/src/SMAPI.Web/Framework/Clients/GitHub/GitRelease.cs
new file mode 100644
index 00000000..b944088d
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/GitHub/GitRelease.cs
@@ -0,0 +1,25 @@
+using Newtonsoft.Json;
+
+namespace StardewModdingAPI.Web.Framework.Clients.GitHub
+{
+ /// <summary>A GitHub project release.</summary>
+ internal class GitRelease
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The display name.</summary>
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ /// <summary>The semantic version string.</summary>
+ [JsonProperty("tag_name")]
+ public string Tag { get; set; }
+
+ /// <summary>The Markdown description for the release.</summary>
+ public string Body { get; set; }
+
+ /// <summary>The attached files.</summary>
+ public GitAsset[] Assets { get; set; }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/GitHub/IGitHubClient.cs b/src/SMAPI.Web/Framework/Clients/GitHub/IGitHubClient.cs
new file mode 100644
index 00000000..6e8eadff
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/GitHub/IGitHubClient.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Threading.Tasks;
+
+namespace StardewModdingAPI.Web.Framework.Clients.GitHub
+{
+ /// <summary>An HTTP client for fetching metadata from GitHub.</summary>
+ internal interface IGitHubClient : IDisposable
+ {
+ /*********
+ ** Methods
+ *********/
+ /// <summary>Get the latest release for a GitHub repository.</summary>
+ /// <param name="repo">The repository key (like <c>Pathoschild/SMAPI</c>).</param>
+ /// <returns>Returns the latest release if found, else <c>null</c>.</returns>
+ Task<GitRelease> GetLatestReleaseAsync(string repo);
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/Nexus/INexusClient.cs b/src/SMAPI.Web/Framework/Clients/Nexus/INexusClient.cs
new file mode 100644
index 00000000..e56e7af4
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/Nexus/INexusClient.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Threading.Tasks;
+
+namespace StardewModdingAPI.Web.Framework.Clients.Nexus
+{
+ /// <summary>An HTTP client for fetching mod metadata from Nexus Mods.</summary>
+ internal interface INexusClient : IDisposable
+ {
+ /*********
+ ** Methods
+ *********/
+ /// <summary>Get metadata about a mod.</summary>
+ /// <param name="id">The Nexus mod ID.</param>
+ /// <returns>Returns the mod info if found, else <c>null</c>.</returns>
+ Task<NexusMod> GetModAsync(uint id);
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/Nexus/NexusClient.cs b/src/SMAPI.Web/Framework/Clients/Nexus/NexusClient.cs
new file mode 100644
index 00000000..1a7011e2
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/Nexus/NexusClient.cs
@@ -0,0 +1,48 @@
+using System.Threading.Tasks;
+using Pathoschild.Http.Client;
+
+namespace StardewModdingAPI.Web.Framework.Clients.Nexus
+{
+ /// <summary>An HTTP client for fetching mod metadata from Nexus Mods.</summary>
+ internal class NexusClient : INexusClient
+ {
+ /*********
+ ** Properties
+ *********/
+ /// <summary>The URL for a Nexus Mods API query excluding the base URL, where {0} is the mod ID.</summary>
+ private readonly string ModUrlFormat;
+
+ /// <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 Nexus Mods API client.</param>
+ /// <param name="baseUrl">The base URL for the Nexus Mods API.</param>
+ /// <param name="modUrlFormat">The URL for a Nexus Mods API query excluding the <paramref name="baseUrl"/>, where {0} is the mod ID.</param>
+ public NexusClient(string userAgent, string baseUrl, string modUrlFormat)
+ {
+ this.ModUrlFormat = modUrlFormat;
+ this.Client = new FluentClient(baseUrl).SetUserAgent(userAgent);
+ }
+
+ /// <summary>Get metadata about a mod.</summary>
+ /// <param name="id">The Nexus mod ID.</param>
+ /// <returns>Returns the mod info if found, else <c>null</c>.</returns>
+ public async Task<NexusMod> GetModAsync(uint id)
+ {
+ return await this.Client
+ .GetAsync(string.Format(this.ModUrlFormat, id))
+ .As<NexusMod>();
+ }
+
+ /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
+ public void Dispose()
+ {
+ this.Client?.Dispose();
+ }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/Nexus/NexusMod.cs b/src/SMAPI.Web/Framework/Clients/Nexus/NexusMod.cs
new file mode 100644
index 00000000..2b04104f
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/Nexus/NexusMod.cs
@@ -0,0 +1,21 @@
+using Newtonsoft.Json;
+
+namespace StardewModdingAPI.Web.Framework.Clients.Nexus
+{
+ /// <summary>Mod metadata from Nexus Mods.</summary>
+ internal class NexusMod
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The mod name.</summary>
+ public string Name { get; set; }
+
+ /// <summary>The mod's semantic version number.</summary>
+ public string Version { get; set; }
+
+ /// <summary>The mod's web URL.</summary>
+ [JsonProperty("mod_page_uri")]
+ public string Url { get; set; }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/Clients/Pastebin/IPastebinClient.cs b/src/SMAPI.Web/Framework/Clients/Pastebin/IPastebinClient.cs
new file mode 100644
index 00000000..630dfb76
--- /dev/null
+++ b/src/SMAPI.Web/Framework/Clients/Pastebin/IPastebinClient.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Threading.Tasks;
+
+namespace StardewModdingAPI.Web.Framework.Clients.Pastebin
+{
+ /// <summary>An API client for Pastebin.</summary>
+ internal interface IPastebinClient : IDisposable
+ {
+ /// <summary>Fetch a saved paste.</summary>
+ /// <param name="id">The paste ID.</param>
+ Task<PasteInfo> GetAsync(string id);
+
+ /// <summary>Save a paste to Pastebin.</summary>
+ /// <param name="content">The paste content.</param>
+ Task<SavePasteResult> PostAsync(string content);
+ }
+}
diff --git a/src/SMAPI.Web/Framework/LogParser/GetPasteResponse.cs b/src/SMAPI.Web/Framework/Clients/Pastebin/PasteInfo.cs
index 4f8794db..955156eb 100644
--- a/src/SMAPI.Web/Framework/LogParser/GetPasteResponse.cs
+++ b/src/SMAPI.Web/Framework/Clients/Pastebin/PasteInfo.cs
@@ -1,7 +1,7 @@
-namespace StardewModdingAPI.Web.Framework.LogParser
+namespace StardewModdingAPI.Web.Framework.Clients.Pastebin
{
/// <summary>The response for a get-paste request.</summary>
- internal class GetPasteResponse
+ internal class PasteInfo
{
/// <summary>Whether the log was successfully fetched.</summary>
public bool Success { get; set; }
diff --git a/src/SMAPI.Web/Framework/LogParser/PastebinClient.cs b/src/SMAPI.Web/Framework/Clients/Pastebin/PastebinClient.cs
index 1cfaed17..ef83a91e 100644
--- a/src/SMAPI.Web/Framework/LogParser/PastebinClient.cs
+++ b/src/SMAPI.Web/Framework/Clients/Pastebin/PastebinClient.cs
@@ -8,10 +8,10 @@ using System.Threading.Tasks;
using System.Web;
using Pathoschild.Http.Client;
-namespace StardewModdingAPI.Web.Framework.LogParser
+namespace StardewModdingAPI.Web.Framework.Clients.Pastebin
{
/// <summary>An API client for Pastebin.</summary>
- internal class PastebinClient : IDisposable
+ internal class PastebinClient : IPastebinClient
{
/*********
** Properties
@@ -43,7 +43,7 @@ namespace StardewModdingAPI.Web.Framework.LogParser
/// <summary>Fetch a saved paste.</summary>
/// <param name="id">The paste ID.</param>
- public async Task<GetPasteResponse> GetAsync(string id)
+ public async Task<PasteInfo> GetAsync(string id)
{
try
{
@@ -54,30 +54,30 @@ namespace StardewModdingAPI.Web.Framework.LogParser
// handle Pastebin errors
if (string.IsNullOrWhiteSpace(content))
- return new GetPasteResponse { Error = "Received an empty response from Pastebin." };
+ return new PasteInfo { Error = "Received an empty response from Pastebin." };
if (content.StartsWith("<!DOCTYPE"))
- return new GetPasteResponse { Error = $"Received a captcha challenge from Pastebin. Please visit https://pastebin.com/{id} in a new window to solve it." };
- return new GetPasteResponse { Success = true, Content = content };
+ return new PasteInfo { Error = $"Received a captcha challenge from Pastebin. Please visit https://pastebin.com/{id} in a new window to solve it." };
+ return new PasteInfo { Success = true, Content = content };
}
catch (ApiException ex) when (ex.Status == HttpStatusCode.NotFound)
{
- return new GetPasteResponse { Error = "There's no log with that ID." };
+ return new PasteInfo { Error = "There's no log with that ID." };
}
catch (Exception ex)
{
- return new GetPasteResponse { Error = ex.ToString() };
+ return new PasteInfo { Error = ex.ToString() };
}
}
/// <summary>Save a paste to Pastebin.</summary>
/// <param name="content">The paste content.</param>
- public async Task<SavePasteResponse> PostAsync(string content)
+ public async Task<SavePasteResult> PostAsync(string content)
{
try
{
// validate
if (string.IsNullOrWhiteSpace(content))
- return new SavePasteResponse { Error = "The log content can't be empty." };
+ return new SavePasteResult { Error = "The log content can't be empty." };
// post to API
string response = await this.Client
@@ -96,19 +96,19 @@ namespace StardewModdingAPI.Web.Framework.LogParser
// handle Pastebin errors
if (string.IsNullOrWhiteSpace(response))
- return new SavePasteResponse { Error = "Received an empty response from Pastebin." };
+ return new SavePasteResult { Error = "Received an empty response from Pastebin." };
if (response.StartsWith("Bad API request"))
- return new SavePasteResponse { Error = response };
+ return new SavePasteResult { Error = response };
if (!response.Contains("/"))
- return new SavePasteResponse { Error = $"Received an unknown response: {response}" };
+ return new SavePasteResult { Error = $"Received an unknown response: {response}" };
// return paste ID
string pastebinID = response.Split("/").Last();
- return new SavePasteResponse { Success = true, ID = pastebinID };
+ return new SavePasteResult { Success = true, ID = pastebinID };
}
catch (Exception ex)
{
- return new SavePasteResponse { Success = false, Error = ex.ToString() };
+ return new SavePasteResult { Success = false, Error = ex.ToString() };
}
}
diff --git a/src/SMAPI.Web/Framework/LogParser/SavePasteResponse.cs b/src/SMAPI.Web/Framework/Clients/Pastebin/SavePasteResult.cs
index 1c0960a4..89dab697 100644
--- a/src/SMAPI.Web/Framework/LogParser/SavePasteResponse.cs
+++ b/src/SMAPI.Web/Framework/Clients/Pastebin/SavePasteResult.cs
@@ -1,7 +1,7 @@
-namespace StardewModdingAPI.Web.Framework.LogParser
+namespace StardewModdingAPI.Web.Framework.Clients.Pastebin
{
/// <summary>The response for a save-log request.</summary>
- internal class SavePasteResponse
+ internal class SavePasteResult
{
/// <summary>Whether the log was successfully saved.</summary>
public bool Success { get; set; }
diff --git a/src/SMAPI.Web/Framework/ConfigModels/ApiClientsConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/ApiClientsConfig.cs
new file mode 100644
index 00000000..61219414
--- /dev/null
+++ b/src/SMAPI.Web/Framework/ConfigModels/ApiClientsConfig.cs
@@ -0,0 +1,72 @@
+namespace StardewModdingAPI.Web.Framework.ConfigModels
+{
+ /// <summary>The config settings for the API clients.</summary>
+ internal class ApiClientsConfig
+ {
+ /*********
+ ** Accessors
+ *********/
+ /****
+ ** Generic
+ ****/
+ /// <summary>The user agent for API clients, where {0} is the SMAPI version.</summary>
+ public string UserAgent { get; set; }
+
+
+ /****
+ ** Chucklefish
+ ****/
+ /// <summary>The base URL for the Chucklefish mod site.</summary>
+ public string ChucklefishBaseUrl { get; set; }
+
+ /// <summary>The URL for a mod page on the Chucklefish mod site excluding the <see cref="GitHubBaseUrl"/>, where {0} is the mod ID.</summary>
+ public string ChucklefishModPageUrlFormat { get; set; }
+
+
+ /****
+ ** GitHub
+ ****/
+ /// <summary>The base URL for the GitHub API.</summary>
+ public string GitHubBaseUrl { get; set; }
+
+ /// <summary>The URL for a GitHub API latest-release query excluding the <see cref="GitHubBaseUrl"/>, where {0} is the organisation and project name.</summary>
+ public string GitHubReleaseUrlFormat { get; set; }
+
+ /// <summary>The Accept header value expected by the GitHub API.</summary>
+ public string GitHubAcceptHeader { get; set; }
+
+ /// <summary>The username with which to authenticate to the GitHub API (if any).</summary>
+ public string GitHubUsername { get; set; }
+
+ /// <summary>The password with which to authenticate to the GitHub API (if any).</summary>
+ public string GitHubPassword { get; set; }
+
+ /****
+ ** Nexus Mods
+ ****/
+ /// <summary>The user agent for the Nexus Mods API client.</summary>
+ public string NexusUserAgent { get; set; }
+
+ /// <summary>The base URL for the Nexus Mods API.</summary>
+ public string NexusBaseUrl { get; set; }
+
+ /// <summary>The URL for a Nexus Mods API query excluding the <see cref="NexusBaseUrl"/>, where {0} is the mod ID.</summary>
+ public string NexusModUrlFormat { get; set; }
+
+ /****
+ ** Pastebin
+ ****/
+ /// <summary>The base URL for the Pastebin API.</summary>
+ public string PastebinBaseUrl { get; set; }
+
+ /// <summary>The user agent for the Pastebin API client, where {0} is the SMAPI version.</summary>
+ public string PastebinUserAgent { get; set; }
+
+ /// <summary>The user key used to authenticate with the Pastebin API.</summary>
+ public string PastebinUserKey { get; set; }
+
+ /// <summary>The developer key used to authenticate with the Pastebin API.</summary>
+ public string PastebinDevKey { get; set; }
+
+ }
+}
diff --git a/src/SMAPI.Web/Framework/ConfigModels/ContextConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/ContextConfig.cs
new file mode 100644
index 00000000..117462f4
--- /dev/null
+++ b/src/SMAPI.Web/Framework/ConfigModels/ContextConfig.cs
@@ -0,0 +1,15 @@
+namespace StardewModdingAPI.Web.Framework.ConfigModels
+{
+ /// <summary>The config settings for the app context.</summary>
+ public class ContextConfig // must be public to pass into views
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The root URL for the app.</summary>
+ public string RootUrl { get; set; }
+
+ /// <summary>The root URL for the log parser.</summary>
+ public string LogParserUrl { get; set; }
+ }
+}
diff --git a/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs
deleted file mode 100644
index df5d605d..00000000
--- a/src/SMAPI.Web/Framework/ConfigModels/LogParserConfig.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-namespace StardewModdingAPI.Web.Framework.ConfigModels
-{
- /// <summary>The config settings for the log parser.</summary>
- internal class LogParserConfig
- {
- /*********
- ** Accessors
- *********/
- /// <summary>The root URL for the log parser controller.</summary>
- public string SectionUrl { get; set; }
-
- /// <summary>The base URL for the Pastebin API.</summary>
- public string PastebinBaseUrl { get; set; }
-
- /// <summary>The user agent for the Pastebin API client, where {0} is the SMAPI version.</summary>
- public string PastebinUserAgent { get; set; }
-
- /// <summary>The user key used to authenticate with the Pastebin API.</summary>
- public string PastebinUserKey { get; set; }
-
- /// <summary>The developer key used to authenticate with the Pastebin API.</summary>
- public string PastebinDevKey { get; set; }
- }
-}
diff --git a/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs b/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs
index 2fb5b97e..58c3a100 100644
--- a/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs
+++ b/src/SMAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs
@@ -6,9 +6,6 @@ namespace StardewModdingAPI.Web.Framework.ConfigModels
/*********
** Accessors
*********/
- /****
- ** General
- ****/
/// <summary>The number of minutes update checks should be cached before refetching them.</summary>
public int CacheMinutes { get; set; }
@@ -16,59 +13,13 @@ namespace StardewModdingAPI.Web.Framework.ConfigModels
/// <remarks>Derived from SMAPI's SemanticVersion implementation.</remarks>
public string SemanticVersionRegex { get; set; }
- /****
- ** Chucklefish mod site
- ****/
/// <summary>The repository key for the Chucklefish mod site.</summary>
public string ChucklefishKey { get; set; }
- /// <summary>The user agent for the Chucklefish API client, where {0} is the SMAPI version.</summary>
- public string ChucklefishUserAgent { get; set; }
-
- /// <summary>The base URL for the Chucklefish mod site.</summary>
- public string ChucklefishBaseUrl { get; set; }
-
- /// <summary>The URL for a mod page on the Chucklefish mod site excluding the <see cref="GitHubBaseUrl"/>, where {0} is the mod ID.</summary>
- public string ChucklefishModPageUrlFormat { get; set; }
-
-
- /****
- ** GitHub
- ****/
/// <summary>The repository key for Nexus Mods.</summary>
public string GitHubKey { get; set; }
- /// <summary>The user agent for the GitHub API client, where {0} is the SMAPI version.</summary>
- public string GitHubUserAgent { get; set; }
-
- /// <summary>The base URL for the GitHub API.</summary>
- public string GitHubBaseUrl { get; set; }
-
- /// <summary>The URL for a GitHub API latest-release query excluding the <see cref="GitHubBaseUrl"/>, where {0} is the organisation and project name.</summary>
- public string GitHubReleaseUrlFormat { get; set; }
-
- /// <summary>The Accept header value expected by the GitHub API.</summary>
- public string GitHubAcceptHeader { get; set; }
-
- /// <summary>The username with which to authenticate to the GitHub API (if any).</summary>
- public string GitHubUsername { get; set; }
-
- /// <summary>The password with which to authenticate to the GitHub API (if any).</summary>
- public string GitHubPassword { get; set; }
-
- /****
- ** Nexus Mods
- ****/
/// <summary>The repository key for Nexus Mods.</summary>
public string NexusKey { get; set; }
-
- /// <summary>The user agent for the Nexus Mods API client.</summary>
- public string NexusUserAgent { get; set; }
-
- /// <summary>The base URL for the Nexus Mods API.</summary>
- public string NexusBaseUrl { get; set; }
-
- /// <summary>The URL for a Nexus Mods API query excluding the <see cref="NexusBaseUrl"/>, where {0} is the mod ID.</summary>
- public string NexusModUrlFormat { get; set; }
}
}
diff --git a/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs
index