add optional extended metadata to mods API (#532)

This commit is contained in:
Jesse Plamondon-Willard 2018-06-29 01:01:57 -04:00
parent c9fedebaf3
commit a0888e0ad1
5 changed files with 100 additions and 15 deletions

View File

@ -132,10 +132,7 @@ namespace StardewModdingAPI.Web.Controllers
}
if (this.IsNewer(version, result.Main?.Version))
{
result.Name = data.Name;
result.Main = new ModEntryVersionModel(version, data.Url);
}
}
// handle optional version
@ -148,19 +145,14 @@ namespace StardewModdingAPI.Web.Controllers
}
if (this.IsNewer(version, result.Optional?.Version))
{
result.Name = result.Name ?? data.Name;
result.Optional = new ModEntryVersionModel(version, data.Url);
}
}
}
// get unofficial version
{
WikiCompatibilityEntry wikiEntry = wikiData.FirstOrDefault(entry => entry.ID.Contains(result.ID.Trim(), StringComparer.InvariantCultureIgnoreCase));
if (wikiEntry?.UnofficialVersion != null && this.IsNewer(wikiEntry.UnofficialVersion, result.Main?.Version) && this.IsNewer(wikiEntry.UnofficialVersion, result.Optional?.Version))
result.Unofficial = new ModEntryVersionModel(wikiEntry.UnofficialVersion, this.WikiCompatibilityPageUrl);
}
WikiCompatibilityEntry wikiEntry = wikiData.FirstOrDefault(entry => entry.ID.Contains(result.ID.Trim(), StringComparer.InvariantCultureIgnoreCase));
if (wikiEntry?.UnofficialVersion != null && this.IsNewer(wikiEntry.UnofficialVersion, result.Main?.Version) && this.IsNewer(wikiEntry.UnofficialVersion, result.Optional?.Version))
result.Unofficial = new ModEntryVersionModel(wikiEntry.UnofficialVersion, this.WikiCompatibilityPageUrl);
// fallback to preview if latest is invalid
if (result.Main == null && result.Optional != null)
@ -172,13 +164,16 @@ namespace StardewModdingAPI.Web.Controllers
// special cases
if (mod.ID == "Pathoschild.SMAPI")
{
result.Name = "SMAPI";
if (result.Main != null)
result.Main.Url = "https://smapi.io/";
if (result.Optional != null)
result.Optional.Url = "https://smapi.io/";
}
// add extended metadata
if (model.IncludeExtendedMetadata && (wikiEntry != null || record != null))
result.Metadata = new ModExtendedMetadataModel(wikiEntry, record);
// add result
result.Errors = errors.ToArray();
result.SetBackwardsCompatibility(apiVersion);

View File

@ -11,9 +11,6 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
/// <summary>The mod's unique ID (if known).</summary>
public string ID { get; set; }
/// <summary>The mod name.</summary>
public string Name { get; set; }
/// <summary>The main version.</summary>
public ModEntryVersionModel Main { get; set; }
@ -23,6 +20,9 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
/// <summary>The latest unofficial version, if newer than <see cref="Main"/> and <see cref="Optional"/>.</summary>
public ModEntryVersionModel Unofficial { get; set; }
/// <summary>Optional extended data which isn't needed for update checks.</summary>
public ModExtendedMetadataModel Metadata { get; set; }
/// <summary>The errors that occurred while fetching update data.</summary>
public string[] Errors { get; set; } = new string[0];

View File

@ -0,0 +1,77 @@
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using StardewModdingAPI.Toolkit.Framework.Clients.Wiki;
using StardewModdingAPI.Toolkit.Framework.ModData;
namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
{
/// <summary>Extended metadata about a mod.</summary>
public class ModExtendedMetadataModel
{
/*********
** Accessors
*********/
/// <summary>The mod's unique ID. A mod may have multiple current IDs in rare cases (e.g. due to parallel releases or unofficial updates).</summary>
public string[] ID { get; set; } = new string[0];
/// <summary>The mod's display name.</summary>
public string Name { get; set; }
/// <summary>The mod ID on Nexus.</summary>
public int? NexusID { get; set; }
/// <summary>The mod ID in the Chucklefish mod repo.</summary>
public int? ChucklefishID { get; set; }
/// <summary>The GitHub repository in the form 'owner/repo'.</summary>
public string GitHubRepo { get; set; }
/// <summary>The URL to a non-GitHub source repo.</summary>
public string CustomSourceUrl { get; set; }
/// <summary>The custom mod page URL (if applicable).</summary>
public string CustomUrl { get; set; }
/// <summary>The compatibility status.</summary>
[JsonConverter(typeof(StringEnumConverter))]
public WikiCompatibilityStatus? CompatibilityStatus { get; set; }
/// <summary>The human-readable summary of the compatibility status or workaround, without HTML formatitng.</summary>
public string CompatibilitySummary { get; set; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
public ModExtendedMetadataModel() { }
/// <summary>Construct an instance.</summary>
/// <param name="wiki">The mod metadata from the wiki (if available).</param>
/// <param name="db">The mod metadata from SMAPI's internal DB (if available).</param>
public ModExtendedMetadataModel(WikiCompatibilityEntry wiki, ModDataRecord db)
{
// wiki data
if (wiki != null)
{
this.ID = wiki.ID;
this.Name = wiki.Name;
this.NexusID = wiki.NexusID;
this.ChucklefishID = wiki.ChucklefishID;
this.GitHubRepo = wiki.GitHubRepo;
this.CustomSourceUrl = wiki.CustomSourceUrl;
this.CustomUrl = wiki.CustomUrl;
this.CompatibilityStatus = wiki.Status;
this.CompatibilitySummary = wiki.Summary;
}
// internal DB data
if (db != null)
{
this.ID = this.ID.Union(db.FormerIDs).ToArray();
this.Name = this.Name ?? db.DisplayName;
}
}
}
}

View File

@ -16,6 +16,9 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
/// <summary>The mods for which to find data.</summary>
public ModSearchEntryModel[] Mods { get; set; }
/// <summary>Whether to include extended metadata for each mod.</summary>
public bool IncludeExtendedMetadata { get; set; }
/*********
** Public methods

View File

@ -86,6 +86,16 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
: version;
}
/// <summary>Get the possible mod IDs.</summary>
public IEnumerable<string> GetIDs()
{
return this.FormerIDs
.Concat(new[] { this.ID })
.Where(p => !string.IsNullOrWhiteSpace(p))
.Select(p => p.Trim())
.Distinct();
}
/// <summary>Get a parsed representation of the <see cref="ModDataRecord.Fields"/> which match a given manifest.</summary>
/// <param name="manifest">The manifest to match.</param>
public ModDataRecordVersionedFields GetVersionedFields(IManifest manifest)