add GitHub update check support (#336)
This commit is contained in:
parent
71d85a0c22
commit
0d6f6a9ace
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue