diff options
Diffstat (limited to 'src/StardewModdingAPI.Web')
7 files changed, 139 insertions, 96 deletions
diff --git a/src/StardewModdingAPI.Web/Controllers/CheckController.cs b/src/StardewModdingAPI.Web/Controllers/CheckController.cs index a7582edd..9ec068cb 100644 --- a/src/StardewModdingAPI.Web/Controllers/CheckController.cs +++ b/src/StardewModdingAPI.Web/Controllers/CheckController.cs @@ -1,9 +1,7 @@ -using System; using System.Collections.Generic; -using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json; +using StardewModdingAPI.Web.Framework; using StardewModdingAPI.Web.Models; namespace StardewModdingAPI.Web.Controllers @@ -21,45 +19,19 @@ namespace StardewModdingAPI.Web.Controllers [HttpPost] public async Task<ModGenericModel[]> Post([FromBody] ModSearchModel[] mods) { - using (var client = new HttpClient()) + using (NexusModsClient client = new NexusModsClient()) { - // the return array of mods - var modList = new List<ModGenericModel>(); + List<ModGenericModel> result = new List<ModGenericModel>(); - foreach (var mod in mods) + foreach (ModSearchModel mod in mods) { - if (!mod.NexusID.HasValue) - continue; - - try - { - // create request with HttpRequestMessage - var request = new HttpRequestMessage(HttpMethod.Get, new Uri($"http://www.nexusmods.com/stardewvalley/mods/{mod.NexusID}")); - - // add the Nexus Client useragent to get JSON response from the site - request.Headers.UserAgent.ParseAdd("Nexus Client v0.63.15"); - - // send the request out - var response = await client.SendAsync(request); - // ensure the response is valid (throws exception) - response.EnsureSuccessStatusCode(); - - // get the JSON string of the response - string stringResponse = await response.Content.ReadAsStringAsync(); - - // create the mod data from the JSON string - var modData = JsonConvert.DeserializeObject<NexusResponseModel>(stringResponse); - - // add to the list of mods - modList.Add(modData.ModInfo()); - } - catch (Exception) - { - modList.Add(new ModGenericModel { ID = mod.NexusID.Value, Vendor = "Nexus", Valid = false }); - } + if (mod.NexusID.HasValue) + result.Add(await client.GetModInfoAsync(mod.NexusID.Value)); + else + result.Add(new ModGenericModel(null, mod.NexusID ?? 0)); } - return modList.ToArray(); + return result.ToArray(); } } } diff --git a/src/StardewModdingAPI.Web/Framework/IModRepository.cs b/src/StardewModdingAPI.Web/Framework/IModRepository.cs new file mode 100644 index 00000000..ebf9850f --- /dev/null +++ b/src/StardewModdingAPI.Web/Framework/IModRepository.cs @@ -0,0 +1,17 @@ +using System; +using System.Threading.Tasks; +using StardewModdingAPI.Web.Models; + +namespace StardewModdingAPI.Web.Framework +{ + /// <summary>A repository which provides mod metadata.</summary> + internal interface IModRepository : IDisposable + { + /********* + ** Public methods + *********/ + /// <summary>Get metadata about a mod in the repository.</summary> + /// <param name="id">The mod ID in this repository.</param> + Task<ModGenericModel> GetModInfoAsync(int id); + } +} diff --git a/src/StardewModdingAPI.Web/Framework/NexusModsClient.cs b/src/StardewModdingAPI.Web/Framework/NexusModsClient.cs new file mode 100644 index 00000000..8f010d56 --- /dev/null +++ b/src/StardewModdingAPI.Web/Framework/NexusModsClient.cs @@ -0,0 +1,75 @@ +using System; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Pathoschild.Http.Client; +using StardewModdingAPI.Web.Models; + +namespace StardewModdingAPI.Web.Framework +{ + /// <summary>An HTTP client for fetching mod metadata from Nexus Mods.</summary> + internal class NexusModsClient : IModRepository + { + /********* + ** Properties + *********/ + /// <summary>The underlying HTTP client.</summary> + private readonly IClient Client; + + /********* + ** Public methods + *********/ + /// <summary>Construct an instance.</summary> + public NexusModsClient() + { + this.Client = new FluentClient("http://www.nexusmods.com/stardewvalley") + .SetUserAgent("Nexus Client v0.63.15"); + } + + /// <summary>Get metadata about a mod in the repository.</summary> + /// <param name="id">The mod ID in this repository.</param> + public async Task<ModGenericModel> GetModInfoAsync(int id) + { + try + { + NexusResponseModel response = await this.Client + .GetAsync($"mods/{id}") + .As<NexusResponseModel>(); + return new ModGenericModel("Nexus", id, response.Name, response.Version, response.Url); + } + catch (Exception) + { + return new ModGenericModel("Nexus", id); + } + } + + /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary> + public void Dispose() + { + this.Client.Dispose(); + } + + + /********* + ** Private models + *********/ + /// <summary>A mod metadata response from Nexus Mods.</summary> + private class NexusResponseModel + { + /********* + ** Accessors + *********/ + /// <summary>The unique mod ID.</summary> + public int ID { get; set; } + + /// <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/StardewModdingAPI.Web/Models/IModModel.cs b/src/StardewModdingAPI.Web/Models/IModModel.cs deleted file mode 100644 index 2eadcaec..00000000 --- a/src/StardewModdingAPI.Web/Models/IModModel.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace StardewModdingAPI.Web.Models -{ - /// <summary>A mod metadata response which provides a method to extract generic info.</summary> - internal interface IModModel - { - /********* - ** Public methods - *********/ - /// <summary>Get basic mod metadata.</summary> - ModGenericModel ModInfo(); - } -} diff --git a/src/StardewModdingAPI.Web/Models/ModGenericModel.cs b/src/StardewModdingAPI.Web/Models/ModGenericModel.cs index 208af416..dc36c7f4 100644 --- a/src/StardewModdingAPI.Web/Models/ModGenericModel.cs +++ b/src/StardewModdingAPI.Web/Models/ModGenericModel.cs @@ -7,21 +7,52 @@ namespace StardewModdingAPI.Web.Models ** Accessors *********/ /// <summary>The unique mod ID.</summary> - public int ID { get; set; } + public int ID { get; } /// <summary>The mod name.</summary> - public string Name { get; set; } + public string Name { get; } /// <summary>The mod's vendor ID.</summary> - public string Vendor { get; set; } + public string Vendor { get; } /// <summary>The mod's semantic version number.</summary> - public string Version { get; set; } + public string Version { get; } /// <summary>The mod's web URL.</summary> - public string Url { get; set; } + public string Url { get; } /// <summary>Whether the mod is valid.</summary> - public bool Valid { get; set; } = true; + public bool Valid { get; } + + + /********* + ** Public methods + *********/ + /// <summary>Construct a valid instance.</summary> + /// <param name="vendor">The mod's vendor ID.</param> + /// <param name="id">The unique mod ID.</param> + /// <param name="name">The mod name.</param> + /// <param name="version">The mod's semantic version number.</param> + /// <param name="url">The mod's web URL.</param> + /// <param name="valid">Whether the mod is valid.</param> + public ModGenericModel(string vendor, int id, string name, string version, string url, bool valid = true) + { + this.Vendor = vendor; + this.ID = id; + this.Name = name; + this.Version = version; + this.Url = url; + this.Valid = valid; + } + + /// <summary>Construct an valid instance.</summary> + /// <param name="vendor">The mod's vendor ID.</param> + /// <param name="id">The unique mod ID.</param> + public ModGenericModel(string vendor, int id) + { + this.Vendor = vendor; + this.ID = id; + this.Valid = false; + } } } diff --git a/src/StardewModdingAPI.Web/Models/NexusResponseModel.cs b/src/StardewModdingAPI.Web/Models/NexusResponseModel.cs deleted file mode 100644 index ae5c691c..00000000 --- a/src/StardewModdingAPI.Web/Models/NexusResponseModel.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Newtonsoft.Json; - -namespace StardewModdingAPI.Web.Models -{ - /// <summary>A mod metadata response from Nexus Mods.</summary> - public class NexusResponseModel : IModModel - { - /********* - ** Accessors - *********/ - /// <summary>The unique mod ID.</summary> - public int ID { get; set; } - - /// <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; } - - - /********* - ** Public methods - *********/ - /// <summary>Get basic mod metadata.</summary> - public ModGenericModel ModInfo() - { - return new ModGenericModel - { - ID = this.ID, - Version = this.Version, - Name = this.Name, - Url = this.Url, - Vendor = "Nexus" - }; - } - } -} diff --git a/src/StardewModdingAPI.Web/StardewModdingAPI.Web.csproj b/src/StardewModdingAPI.Web/StardewModdingAPI.Web.csproj index fa1d88eb..eee0f3f3 100644 --- a/src/StardewModdingAPI.Web/StardewModdingAPI.Web.csproj +++ b/src/StardewModdingAPI.Web/StardewModdingAPI.Web.csproj @@ -19,6 +19,7 @@ <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" /> <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.2" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.1" /> + <PackageReference Include="Pathoschild.Http.FluentClient" Version="3.1.0" /> </ItemGroup> <ItemGroup> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.1" /> |