summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2017-09-22 22:42:04 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2017-09-22 22:42:04 -0400
commit0d6f6a9acef175fd9ea0df6790111d8d58d7f368 (patch)
tree28cb29eb86b8189a5f87ba2a2f05ce988ccded9f
parent71d85a0c22a9295a08acdf433ef67d8b1b47e57b (diff)
downloadSMAPI-0d6f6a9acef175fd9ea0df6790111d8d58d7f368.tar.gz
SMAPI-0d6f6a9acef175fd9ea0df6790111d8d58d7f368.tar.bz2
SMAPI-0d6f6a9acef175fd9ea0df6790111d8d58d7f368.zip
add GitHub update check support (#336)
-rw-r--r--src/StardewModdingAPI.Web/Controllers/ModsController.cs1
-rw-r--r--src/StardewModdingAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs27
-rw-r--r--src/StardewModdingAPI.Web/Framework/ModRepositories/GitHubRepository.cs91
-rw-r--r--src/StardewModdingAPI.Web/appsettings.json7
4 files changed, 126 insertions, 0 deletions
diff --git a/src/StardewModdingAPI.Web/Controllers/ModsController.cs b/src/StardewModdingAPI.Web/Controllers/ModsController.cs
index a3f5001a..4b1abde4 100644
--- a/src/StardewModdingAPI.Web/Controllers/ModsController.cs
+++ b/src/StardewModdingAPI.Web/Controllers/ModsController.cs
@@ -44,6 +44,7 @@ namespace StardewModdingAPI.Web.Controllers
this.Repositories =
new IModRepository[]
{
+ new GitHubRepository(config.GitHubKey, config.GitHubBaseUrl, config.GitHubReleaseUrlFormat, config.GitHubUserAgent, config.GitHubAcceptHeader),
new NexusRepository(config.NexusKey, config.NexusUserAgent, config.NexusBaseUrl, config.NexusModUrlFormat)
}
.ToDictionary(p => p.VendorKey, StringComparer.CurrentCultureIgnoreCase);
diff --git a/src/StardewModdingAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs b/src/StardewModdingAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs
index c8763800..4dbad506 100644
--- a/src/StardewModdingAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs
+++ b/src/StardewModdingAPI.Web/Framework/ConfigModels/ModUpdateCheckConfig.cs
@@ -3,9 +3,36 @@ namespace StardewModdingAPI.Web.Framework.ConfigModels
/// <summary>The config settings for mod update checks.</summary>
public class ModUpdateCheckConfig
{
+ /*********
+ ** Accessors
+ *********/
+ /****
+ ** General
+ ****/
/// <summary>The number of minutes update checks should be cached before refetching them.</summary>
public int CacheMinutes { 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.</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; }
+
+ /****
+ ** Nexus Mods
+ ****/
/// <summary>The repository key for Nexus Mods.</summary>
public string NexusKey { get; set; }
diff --git a/src/StardewModdingAPI.Web/Framework/ModRepositories/GitHubRepository.cs b/src/StardewModdingAPI.Web/Framework/ModRepositories/GitHubRepository.cs
new file mode 100644
index 00000000..c5772ad9
--- /dev/null
+++ b/src/StardewModdingAPI.Web/Framework/ModRepositories/GitHubRepository.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Pathoschild.Http.Client;
+using StardewModdingAPI.Web.Models;
+
+namespace StardewModdingAPI.Web.Framework.ModRepositories
+{
+ /// <summary>An HTTP client for fetching mod metadata from GitHub project releases.</summary>
+ internal class GitHubRepository : IModRepository
+ {
+ /*********
+ ** Properties
+ *********/
+ /// <summary>The underlying HTTP client.</summary>
+ private readonly IClient Client;
+
+
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The unique key for this vendor.</summary>
+ public string VendorKey { get; }
+
+ /// <summary>The URL for a Nexus Mods API query excluding the base URL, where {0} is the mod ID.</summary>
+ public string ReleaseUrlFormat { get; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="vendorKey">The unique key for this vendor.</param>
+ /// <param name="baseUrl">The base URL for the Nexus Mods API.</param>
+ /// <param name="releaseUrlFormat">The URL for a Nexus Mods API query excluding the <paramref name="baseUrl"/>, where {0} is the mod ID.</param>
+ /// <param name="userAgent">The user agent for the GitHub API client.</param>
+ /// <param name="acceptHeader">The Accept header value expected by the GitHub API.</param>
+ public GitHubRepository(string vendorKey, string baseUrl, string releaseUrlFormat, string userAgent, string acceptHeader)
+ {
+ this.VendorKey = vendorKey;
+ this.ReleaseUrlFormat = releaseUrlFormat;
+
+ this.Client = new FluentClient(baseUrl)
+ .SetUserAgent(string.Format(userAgent, this.GetType().Assembly.GetName().Version))
+ .AddDefault(req => req.WithHeader("Accept", acceptHeader));
+ }
+
+ /// <summary>Get metadata about a mod in the repository.</summary>
+ /// <param name="id">The mod ID in this repository.</param>
+ public async Task<ModInfoModel> GetModInfoAsync(string id)
+ {
+ try
+ {
+ GitRelease release = await this.Client
+ .GetAsync(string.Format(this.ReleaseUrlFormat, id))
+ .As<GitRelease>();
+
+ return new ModInfoModel(id, release.Tag, $"https://github.com/{id}/releases");
+ }
+ catch (Exception ex)
+ {
+ return new ModInfoModel(ex.ToString());
+ }
+ }
+
+ /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
+ public void Dispose()
+ {
+ this.Client.Dispose();
+ }
+
+
+ /*********
+ ** Private models
+ *********/
+ /// <summary>Metadata about a GitHub release tag.</summary>
+ private 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; }
+ }
+ }
+}
diff --git a/src/StardewModdingAPI.Web/appsettings.json b/src/StardewModdingAPI.Web/appsettings.json
index 1e624055..f996157c 100644
--- a/src/StardewModdingAPI.Web/appsettings.json
+++ b/src/StardewModdingAPI.Web/appsettings.json
@@ -7,6 +7,13 @@
},
"ModUpdateCheck": {
"CacheMinutes": 60,
+
+ "GitHubKey": "GitHub",
+ "GitHubUserAgent": "SMAPI/{0} (+https://github.com/Pathoschild/SMAPI)",
+ "GitHubBaseUrl": "https://api.github.com",
+ "GitHubReleaseUrlFormat": "repos/{0}/releases/latest",
+ "GitHubAcceptHeader": "application/vnd.github.v3+json",
+
"NexusKey": "Nexus",
"NexusUserAgent": "Nexus Client v0.63.15",
"NexusBaseUrl": "http://www.nexusmods.com/stardewvalley",