summaryrefslogtreecommitdiff
path: root/src/SMAPI.Web
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2019-07-24 18:29:50 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2019-09-14 18:54:11 -0400
commite856d5efebe12b3aa65d5868ea7baa59cc54863d (patch)
treee678510fb04ab409d1ec91e6d54761c7357264ff /src/SMAPI.Web
parent4fb16abfe9f300b0d841a98b462967b7ca1dcbe5 (diff)
downloadSMAPI-e856d5efebe12b3aa65d5868ea7baa59cc54863d.tar.gz
SMAPI-e856d5efebe12b3aa65d5868ea7baa59cc54863d.tar.bz2
SMAPI-e856d5efebe12b3aa65d5868ea7baa59cc54863d.zip
add remote mod status to update check info (#651)
Diffstat (limited to 'src/SMAPI.Web')
-rw-r--r--src/SMAPI.Web/Controllers/ModsApiController.cs10
-rw-r--r--src/SMAPI.Web/Framework/Clients/ModDrop/ModDropMod.cs3
-rw-r--r--src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs6
-rw-r--r--src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs6
-rw-r--r--src/SMAPI.Web/Framework/ModRepositories/ModDropRepository.cs8
-rw-r--r--src/SMAPI.Web/Framework/ModRepositories/ModInfoModel.cs26
-rw-r--r--src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs8
-rw-r--r--src/SMAPI.Web/Framework/ModRepositories/RemoteModStatus.cs18
8 files changed, 50 insertions, 35 deletions
diff --git a/src/SMAPI.Web/Controllers/ModsApiController.cs b/src/SMAPI.Web/Controllers/ModsApiController.cs
index 9cffd3b3..a74d0d8a 100644
--- a/src/SMAPI.Web/Controllers/ModsApiController.cs
+++ b/src/SMAPI.Web/Controllers/ModsApiController.cs
@@ -245,11 +245,11 @@ namespace StardewModdingAPI.Web.Controllers
// parse update key
UpdateKey parsed = UpdateKey.Parse(updateKey);
if (!parsed.LooksValid)
- return new ModInfoModel($"The update key '{updateKey}' isn't in a valid format. It should contain the site key and mod ID like 'Nexus:541'.");
+ return new ModInfoModel().WithError(RemoteModStatus.DoesNotExist, $"The update key '{updateKey}' isn't in a valid format. It should contain the site key and mod ID like 'Nexus:541'.");
// get matching repository
if (!this.Repositories.TryGetValue(parsed.Repository, out IModRepository repository))
- return new ModInfoModel($"There's no mod site with key '{parsed.Repository}'. Expected one of [{string.Join(", ", this.Repositories.Keys)}].");
+ return new ModInfoModel().WithError(RemoteModStatus.DoesNotExist, $"There's no mod site with key '{parsed.Repository}'. Expected one of [{string.Join(", ", this.Repositories.Keys)}].");
// fetch mod info
return await this.Cache.GetOrCreateAsync($"{repository.VendorKey}:{parsed.ID}".ToLower(), async entry =>
@@ -258,11 +258,11 @@ namespace StardewModdingAPI.Web.Controllers
if (result.Error == null)
{
if (result.Version == null)
- result.Error = $"The update key '{updateKey}' matches a mod with no version number.";
+ result.WithError(RemoteModStatus.InvalidData, $"The update key '{updateKey}' matches a mod with no version number.");
else if (!Regex.IsMatch(result.Version, this.VersionRegex, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase))
- result.Error = $"The update key '{updateKey}' matches a mod with invalid semantic version '{result.Version}'.";
+ result.WithError(RemoteModStatus.InvalidData, $"The update key '{updateKey}' matches a mod with invalid semantic version '{result.Version}'.");
}
- entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(result.Error == null ? this.SuccessCacheMinutes : this.ErrorCacheMinutes);
+ entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(result.Status == RemoteModStatus.TemporaryError ? this.ErrorCacheMinutes : this.SuccessCacheMinutes);
return result;
});
}
diff --git a/src/SMAPI.Web/Framework/Clients/ModDrop/ModDropMod.cs b/src/SMAPI.Web/Framework/Clients/ModDrop/ModDropMod.cs
index 291fb353..def79106 100644
--- a/src/SMAPI.Web/Framework/Clients/ModDrop/ModDropMod.cs
+++ b/src/SMAPI.Web/Framework/Clients/ModDrop/ModDropMod.cs
@@ -17,8 +17,5 @@ namespace StardewModdingAPI.Web.Framework.Clients.ModDrop
/// <summary>The mod's web URL.</summary>
public string Url { get; set; }
-
- /// <summary>A user-friendly error which indicates why fetching the mod info failed (if applicable).</summary>
- public string Error { get; set; }
}
}
diff --git a/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs
index 87e29a2f..04c80dd2 100644
--- a/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs
+++ b/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs
@@ -32,21 +32,21 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
{
// validate ID format
if (!uint.TryParse(id, out uint realID))
- return new ModInfoModel($"The value '{id}' isn't a valid Chucklefish mod ID, must be an integer ID.");
+ return new ModInfoModel().WithError(RemoteModStatus.DoesNotExist, $"The value '{id}' isn't a valid Chucklefish mod ID, must be an integer ID.");
// fetch info
try
{
var mod = await this.Client.GetModAsync(realID);
if (mod == null)
- return new ModInfoModel("Found no mod with this ID.");
+ return new ModInfoModel().WithError(RemoteModStatus.DoesNotExist, "Found no Chucklefish mod with this ID.");
// create model
return new ModInfoModel(name: mod.Name, version: this.NormaliseVersion(mod.Version), url: mod.Url);
}
catch (Exception ex)
{
- return new ModInfoModel(ex.ToString());
+ return new ModInfoModel().WithError(RemoteModStatus.TemporaryError, ex.ToString());
}
}
diff --git a/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs
index 14f44dc0..614e00c2 100644
--- a/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs
+++ b/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs
@@ -32,7 +32,7 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
{
// validate ID format
if (!id.Contains("/") || id.IndexOf("/", StringComparison.InvariantCultureIgnoreCase) != id.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase))
- return new ModInfoModel($"The value '{id}' isn't a valid GitHub mod ID, must be a username and project name like 'Pathoschild/LookupAnything'.");
+ return new ModInfoModel().WithError(RemoteModStatus.DoesNotExist, $"The value '{id}' isn't a valid GitHub mod ID, must be a username and project name like 'Pathoschild/LookupAnything'.");
// fetch info
try
@@ -40,7 +40,7 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
// get latest release (whether preview or stable)
GitRelease latest = await this.Client.GetLatestReleaseAsync(id, includePrerelease: true);
if (latest == null)
- return new ModInfoModel("Found no mod with this ID.");
+ return new ModInfoModel().WithError(RemoteModStatus.DoesNotExist, "Found no GitHub release for this ID.");
// split stable/prerelease if applicable
GitRelease preview = null;
@@ -59,7 +59,7 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
}
catch (Exception ex)
{
- return new ModInfoModel(ex.ToString());
+ return new ModInfoModel().WithError(RemoteModStatus.TemporaryError, ex.ToString());
}
}
diff --git a/src/SMAPI.Web/Framework/ModRepositories/ModDropRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/ModDropRepository.cs
index 1994f515..5703b34e 100644
--- a/src/SMAPI.Web/Framework/ModRepositories/ModDropRepository.cs
+++ b/src/SMAPI.Web/Framework/ModRepositories/ModDropRepository.cs
@@ -32,21 +32,19 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
{
// validate ID format
if (!long.TryParse(id, out long modDropID))
- return new ModInfoModel($"The value '{id}' isn't a valid ModDrop mod ID, must be an integer ID.");
+ return new ModInfoModel().WithError(RemoteModStatus.DoesNotExist, $"The value '{id}' isn't a valid ModDrop mod ID, must be an integer ID.");
// fetch info
try
{
ModDropMod mod = await this.Client.GetModAsync(modDropID);
if (mod == null)
- return new ModInfoModel("Found no mod with this ID.");
- if (mod.Error != null)
- return new ModInfoModel(mod.Error);
+ return new ModInfoModel().WithError(RemoteModStatus.DoesNotExist, "Found no ModDrop mod with this ID.");
return new ModInfoModel(name: mod.Name, version: mod.LatestDefaultVersion?.ToString(), previewVersion: mod.LatestOptionalVersion?.ToString(), url: mod.Url);
}
catch (Exception ex)
{
- return new ModInfoModel(ex.ToString());
+ return new ModInfoModel().WithError(RemoteModStatus.TemporaryError, ex.ToString());
}
}
diff --git a/src/SMAPI.Web/Framework/ModRepositories/ModInfoModel.cs b/src/SMAPI.Web/Framework/ModRepositories/ModInfoModel.cs
index 18252298..16885bfd 100644
--- a/src/SMAPI.Web/Framework/ModRepositories/ModInfoModel.cs
+++ b/src/SMAPI.Web/Framework/ModRepositories/ModInfoModel.cs
@@ -9,15 +9,18 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
/// <summary>The mod name.</summary>
public string Name { get; set; }
- /// <summary>The mod's latest release number.</summary>
+ /// <summary>The mod's latest version.</summary>
public string Version { get; set; }
- /// <summary>The mod's latest optional release, if newer than <see cref="Version"/>.</summary>
+ /// <summary>The mod's latest optional or prerelease version, if newer than <see cref="Version"/>.</summary>
public string PreviewVersion { get; set; }
/// <summary>The mod's web URL.</summary>
public string Url { get; set; }
+ /// <summary>The mod availability status.</summary>
+ public RemoteModStatus Status { get; set; } = RemoteModStatus.Ok;
+
/// <summary>The error message indicating why the mod is invalid (if applicable).</summary>
public string Error { get; set; }
@@ -26,31 +29,30 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
** Public methods
*********/
/// <summary>Construct an empty instance.</summary>
- public ModInfoModel()
- {
- // needed for JSON deserialising
- }
+ public ModInfoModel() { }
/// <summary>Construct an instance.</summary>
/// <param name="name">The mod name.</param>
/// <param name="version">The semantic version for the mod's latest release.</param>
/// <param name="previewVersion">The semantic version for the mod's latest preview release, if available and different from <see cref="Version"/>.</param>
/// <param name="url">The mod's web URL.</param>
- /// <param name="error">The error message indicating why the mod is invalid (if applicable).</param>
- public ModInfoModel(string name, string version, string url, string previewVersion = null, string error = null)
+ public ModInfoModel(string name, string version, string url, string previewVersion = null)
{
this.Name = name;
this.Version = version;
this.PreviewVersion = previewVersion;
this.Url = url;
- this.Error = error;
}
- /// <summary>Construct an instance.</summary>
- /// <param name="error">The error message indicating why the mod is invalid.</param>
- public ModInfoModel(string error)
+ /// <summary>Set a mod error.</summary>
+ /// <param name="status">The mod availability status.</param>
+ /// <param name="error">The error message indicating why the mod is invalid (if applicable).</param>
+ public ModInfoModel WithError(RemoteModStatus status, string error)
{
+ this.Status = status;
this.Error = error;
+
+ return this;
}
}
}
diff --git a/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs
index 4c5fe9bf..9679f93e 100644
--- a/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs
+++ b/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs
@@ -32,21 +32,21 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
{
// validate ID format
if (!uint.TryParse(id, out uint nexusID))
- return new ModInfoModel($"The value '{id}' isn't a valid Nexus mod ID, must be an integer ID.");
+ return new ModInfoModel().WithError(RemoteModStatus.DoesNotExist, $"The value '{id}' isn't a valid Nexus mod ID, must be an integer ID.");
// fetch info
try
{
NexusMod mod = await this.Client.GetModAsync(nexusID);
if (mod == null)
- return new ModInfoModel("Found no mod with this ID.");
+ return new ModInfoModel().WithError(RemoteModStatus.DoesNotExist, "Found no Nexus mod with this ID.");
if (mod.Error != null)
- return new ModInfoModel(mod.Error);
+ return new ModInfoModel().WithError(RemoteModStatus.TemporaryError, mod.Error);
return new ModInfoModel(name: mod.Name, version: this.NormaliseVersion(mod.Version), previewVersion: mod.LatestFileVersion?.ToString(), url: mod.Url);
}
catch (Exception ex)
{
- return new ModInfoModel(ex.ToString());
+ return new ModInfoModel().WithError(RemoteModStatus.TemporaryError, ex.ToString());
}
}
diff --git a/src/SMAPI.Web/Framework/ModRepositories/RemoteModStatus.cs b/src/SMAPI.Web/Framework/ModRepositories/RemoteModStatus.cs
new file mode 100644
index 00000000..02876556
--- /dev/null
+++ b/src/SMAPI.Web/Framework/ModRepositories/RemoteModStatus.cs
@@ -0,0 +1,18 @@
+namespace StardewModdingAPI.Web.Framework.ModRepositories
+{
+ /// <summary>The mod availability status on a remote site.</summary>
+ internal enum RemoteModStatus
+ {
+ /// <summary>The mod is valid.</summary>
+ Ok,
+
+ /// <summary>The mod data was fetched, but the data is not valid (e.g. version isn't semantic).</summary>
+ InvalidData,
+
+ /// <summary>The mod does not exist.</summary>
+ DoesNotExist,
+
+ /// <summary>The mod was temporarily unavailable (e.g. the site could not be reached or an unknown error occurred).</summary>
+ TemporaryError
+ }
+}