add GitHub update check support (#336)

This commit is contained in:
Jesse Plamondon-Willard 2017-09-22 22:42:04 -04:00
parent 71d85a0c22
commit 0d6f6a9ace
4 changed files with 126 additions and 0 deletions

View File

@ -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);

View File

@ -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; }

View File

@ -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; }
}
}
}

View File

@ -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",