refactor Nexus code into generic vendor, rewrite using fluent HTTP client (#336)
This commit is contained in:
parent
dfae52b1e5
commit
edbc3ef3c0
|
@ -1,9 +1,7 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json;
|
using StardewModdingAPI.Web.Framework;
|
||||||
using StardewModdingAPI.Web.Models;
|
using StardewModdingAPI.Web.Models;
|
||||||
|
|
||||||
namespace StardewModdingAPI.Web.Controllers
|
namespace StardewModdingAPI.Web.Controllers
|
||||||
|
@ -21,45 +19,19 @@ namespace StardewModdingAPI.Web.Controllers
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<ModGenericModel[]> Post([FromBody] ModSearchModel[] mods)
|
public async Task<ModGenericModel[]> Post([FromBody] ModSearchModel[] mods)
|
||||||
{
|
{
|
||||||
using (var client = new HttpClient())
|
using (NexusModsClient client = new NexusModsClient())
|
||||||
{
|
{
|
||||||
// the return array of mods
|
List<ModGenericModel> result = new List<ModGenericModel>();
|
||||||
var modList = new List<ModGenericModel>();
|
|
||||||
|
|
||||||
foreach (var mod in mods)
|
foreach (ModSearchModel mod in mods)
|
||||||
{
|
{
|
||||||
if (!mod.NexusID.HasValue)
|
if (mod.NexusID.HasValue)
|
||||||
continue;
|
result.Add(await client.GetModInfoAsync(mod.NexusID.Value));
|
||||||
|
else
|
||||||
try
|
result.Add(new ModGenericModel(null, mod.NexusID ?? 0));
|
||||||
{
|
|
||||||
// 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 });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return modList.ToArray();
|
return result.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,21 +7,52 @@ namespace StardewModdingAPI.Web.Models
|
||||||
** Accessors
|
** Accessors
|
||||||
*********/
|
*********/
|
||||||
/// <summary>The unique mod ID.</summary>
|
/// <summary>The unique mod ID.</summary>
|
||||||
public int ID { get; set; }
|
public int ID { get; }
|
||||||
|
|
||||||
/// <summary>The mod name.</summary>
|
/// <summary>The mod name.</summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; }
|
||||||
|
|
||||||
/// <summary>The mod's vendor ID.</summary>
|
/// <summary>The mod's vendor ID.</summary>
|
||||||
public string Vendor { get; set; }
|
public string Vendor { get; }
|
||||||
|
|
||||||
/// <summary>The mod's semantic version number.</summary>
|
/// <summary>The mod's semantic version number.</summary>
|
||||||
public string Version { get; set; }
|
public string Version { get; }
|
||||||
|
|
||||||
/// <summary>The mod's web URL.</summary>
|
/// <summary>The mod's web URL.</summary>
|
||||||
public string Url { get; set; }
|
public string Url { get; }
|
||||||
|
|
||||||
/// <summary>Whether the mod is valid.</summary>
|
/// <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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,6 +19,7 @@
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" />
|
<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.BrowserLink" Version="1.1.2" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.1" />
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.1" />
|
||||||
|
<PackageReference Include="Pathoschild.Http.FluentClient" Version="3.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.1" />
|
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.1" />
|
||||||
|
|
Loading…
Reference in New Issue