diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/SMAPI.Web/Controllers/ModsController.cs | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/src/SMAPI.Web/Controllers/ModsController.cs b/src/SMAPI.Web/Controllers/ModsController.cs index 99d19f76..f258c745 100644 --- a/src/SMAPI.Web/Controllers/ModsController.cs +++ b/src/SMAPI.Web/Controllers/ModsController.cs @@ -1,9 +1,13 @@ +using System; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Options; using StardewModdingAPI.Toolkit; using StardewModdingAPI.Toolkit.Framework.Clients.Wiki; +using StardewModdingAPI.Web.Framework.ConfigModels; using StardewModdingAPI.Web.ViewModels; namespace StardewModdingAPI.Web.Controllers @@ -12,22 +16,58 @@ namespace StardewModdingAPI.Web.Controllers internal class ModsController : Controller { /********* + ** Properties + *********/ + /// <summary>The cache in which to store mod metadata.</summary> + private readonly IMemoryCache Cache; + + /// <summary>The number of minutes successful update checks should be cached before refetching them.</summary> + private readonly int SuccessCacheMinutes; + + + /********* ** Public methods *********/ + /// <summary>Construct an instance.</summary> + /// <param name="cache">The cache in which to store mod metadata.</param> + /// <param name="configProvider">The config settings for mod update checks.</param> + public ModsController(IMemoryCache cache, IOptions<ModUpdateCheckConfig> configProvider) + { + ModUpdateCheckConfig config = configProvider.Value; + + this.Cache = cache; + this.SuccessCacheMinutes = config.SuccessCacheMinutes; + } + /// <summary>Display information for all mods.</summary> [HttpGet] [Route("mods")] public async Task<ViewResult> Index() { - WikiModEntry[] mods = await new ModToolkit().GetWikiCompatibilityListAsync(); - ModListModel viewModel = new ModListModel( - stableVersion: "1.3.28", - betaVersion: "1.3.31-beta", - mods: mods - .Select(mod => new ModModel(mod)) - .OrderBy(p => Regex.Replace(p.Name.ToLower(), "[^a-z0-9]", "")) // ignore case, spaces, and special characters when sorting - ); - return this.View("Index", viewModel); + return this.View("Index", await this.FetchDataAsync()); + } + + + /********* + ** Private methods + *********/ + /// <summary>Asynchronously fetch mod metadata from the wiki.</summary> + public async Task<ModListModel> FetchDataAsync() + { + return await this.Cache.GetOrCreateAsync($"{nameof(ModsController)}_mod_list", async entry => + { + WikiModEntry[] entries = await new ModToolkit().GetWikiCompatibilityListAsync(); + ModListModel model = new ModListModel( + stableVersion: "1.3.28", + betaVersion: "1.3.31-beta", + mods: entries + .Select(mod => new ModModel(mod)) + .OrderBy(p => Regex.Replace(p.Name.ToLower(), "[^a-z0-9]", "")) // ignore case, spaces, and special characters when sorting + ); + + entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(this.SuccessCacheMinutes); + return model; + }); } } } |