summaryrefslogtreecommitdiff
path: root/src/SMAPI.Web/Startup.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI.Web/Startup.cs')
-rw-r--r--src/SMAPI.Web/Startup.cs90
1 files changed, 72 insertions, 18 deletions
diff --git a/src/SMAPI.Web/Startup.cs b/src/SMAPI.Web/Startup.cs
index a2e47482..8110b696 100644
--- a/src/SMAPI.Web/Startup.cs
+++ b/src/SMAPI.Web/Startup.cs
@@ -1,19 +1,27 @@
using System.Collections.Generic;
+using Hangfire;
+using Hangfire.Mongo;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
+using MongoDB.Bson.Serialization;
+using MongoDB.Driver;
using Newtonsoft.Json;
-using StardewModdingAPI.Toolkit.Serialisation;
+using StardewModdingAPI.Toolkit.Serialization;
using StardewModdingAPI.Web.Framework;
+using StardewModdingAPI.Web.Framework.Caching;
+using StardewModdingAPI.Web.Framework.Caching.Mods;
+using StardewModdingAPI.Web.Framework.Caching.Wiki;
using StardewModdingAPI.Web.Framework.Clients.Chucklefish;
+using StardewModdingAPI.Web.Framework.Clients.CurseForge;
using StardewModdingAPI.Web.Framework.Clients.GitHub;
using StardewModdingAPI.Web.Framework.Clients.ModDrop;
using StardewModdingAPI.Web.Framework.Clients.Nexus;
using StardewModdingAPI.Web.Framework.Clients.Pastebin;
+using StardewModdingAPI.Web.Framework.Compression;
using StardewModdingAPI.Web.Framework.ConfigModels;
using StardewModdingAPI.Web.Framework.RewriteRules;
@@ -48,12 +56,15 @@ namespace StardewModdingAPI.Web
/// <param name="services">The service injection container.</param>
public void ConfigureServices(IServiceCollection services)
{
- // init configuration
+ // init basic services
services
+ .Configure<BackgroundServicesConfig>(this.Configuration.GetSection("BackgroundServices"))
.Configure<ModCompatibilityListConfig>(this.Configuration.GetSection("ModCompatibilityList"))
.Configure<ModUpdateCheckConfig>(this.Configuration.GetSection("ModUpdateCheck"))
+ .Configure<MongoDbConfig>(this.Configuration.GetSection("MongoDB"))
.Configure<SiteConfig>(this.Configuration.GetSection("Site"))
.Configure<RouteOptions>(options => options.ConstraintMap.Add("semanticVersion", typeof(VersionConstraint)))
+ .AddLogging()
.AddMemoryCache()
.AddMvc()
.ConfigureApplicationPartManager(manager => manager.FeatureProviders.Add(new InternalControllerFeatureProvider()))
@@ -65,6 +76,38 @@ namespace StardewModdingAPI.Web
options.SerializerSettings.Formatting = Formatting.Indented;
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});
+ MongoDbConfig mongoConfig = this.Configuration.GetSection("MongoDB").Get<MongoDbConfig>();
+
+ // init background service
+ {
+ BackgroundServicesConfig config = this.Configuration.GetSection("BackgroundServices").Get<BackgroundServicesConfig>();
+ if (config.Enabled)
+ services.AddHostedService<BackgroundService>();
+ }
+
+ // init MongoDB
+ services.AddSingleton<IMongoDatabase>(serv =>
+ {
+ BsonSerializer.RegisterSerializer(new UtcDateTimeOffsetSerializer());
+ return new MongoClient(mongoConfig.GetConnectionString()).GetDatabase(mongoConfig.Database);
+ });
+ services.AddSingleton<IModCacheRepository>(serv => new ModCacheRepository(serv.GetRequiredService<IMongoDatabase>()));
+ services.AddSingleton<IWikiCacheRepository>(serv => new WikiCacheRepository(serv.GetRequiredService<IMongoDatabase>()));
+
+ // init Hangfire
+ services
+ .AddHangfire(config =>
+ {
+ config
+ .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
+ .UseSimpleAssemblyNameTypeSerializer()
+ .UseRecommendedSerializerSettings()
+ .UseMongoStorage(mongoConfig.GetConnectionString(), $"{mongoConfig.Database}-hangfire", new MongoStorageOptions
+ {
+ MigrationOptions = new MongoMigrationOptions(MongoMigrationStrategy.Drop),
+ CheckConnection = false // error on startup takes down entire process
+ });
+ });
// init API clients
{
@@ -77,11 +120,13 @@ namespace StardewModdingAPI.Web
baseUrl: api.ChucklefishBaseUrl,
modPageUrlFormat: api.ChucklefishModPageUrlFormat
));
+ services.AddSingleton<ICurseForgeClient>(new CurseForgeClient(
+ userAgent: userAgent,
+ apiUrl: api.CurseForgeBaseUrl
+ ));
services.AddSingleton<IGitHubClient>(new GitHubClient(
baseUrl: api.GitHubBaseUrl,
- stableReleaseUrlFormat: api.GitHubStableReleaseUrlFormat,
- anyReleaseUrlFormat: api.GitHubAnyReleaseUrlFormat,
userAgent: userAgent,
acceptHeader: api.GitHubAcceptHeader,
username: api.GitHubUsername,
@@ -94,11 +139,13 @@ namespace StardewModdingAPI.Web
modUrlFormat: api.ModDropModPageUrl
));
- services.AddSingleton<INexusClient>(new NexusWebScrapeClient(
- userAgent: userAgent,
- baseUrl: api.NexusBaseUrl,
- modUrlFormat: api.NexusModUrlFormat,
- modScrapeUrlFormat: api.NexusModScrapeUrlFormat
+ services.AddSingleton<INexusClient>(new NexusClient(
+ webUserAgent: userAgent,
+ webBaseUrl: api.NexusBaseUrl,
+ webModUrlFormat: api.NexusModUrlFormat,
+ webModScrapeUrlFormat: api.NexusModScrapeUrlFormat,
+ apiAppVersion: version,
+ apiKey: api.NexusApiKey
));
services.AddSingleton<IPastebinClient>(new PastebinClient(
@@ -108,20 +155,19 @@ namespace StardewModdingAPI.Web
devKey: api.PastebinDevKey
));
}
+
+ // init helpers
+ services.AddSingleton<IGzipHelper>(new GzipHelper());
}
/// <summary>The method called by the runtime to configure the HTTP request pipeline.</summary>
/// <param name="app">The application builder.</param>
/// <param name="env">The hosting environment.</param>
- /// <param name="loggerFactory">The logger factory.</param>
- public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
- loggerFactory.AddConsole(this.Configuration.GetSection("Logging"));
- loggerFactory.AddDebug();
-
+ // basic config
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
-
app
.UseCors(policy => policy
.AllowAnyHeader()
@@ -132,6 +178,13 @@ namespace StardewModdingAPI.Web
.UseRewriter(this.GetRedirectRules())
.UseStaticFiles() // wwwroot folder
.UseMvc();
+
+ // enable Hangfire dashboard
+ app.UseHangfireDashboard("/tasks", new DashboardOptions
+ {
+ IsReadOnlyFunc = context => !JobDashboardAuthorizationFilter.IsLocalRequest(context),
+ Authorization = new[] { new JobDashboardAuthorizationFilter() }
+ });
}
@@ -155,14 +208,15 @@ namespace StardewModdingAPI.Web
redirects.Add(new ConditionalRewriteSubdomainRule(
shouldRewrite: req =>
req.Host.Host != "localhost"
- && (req.Host.Host.StartsWith("api.") || req.Host.Host.StartsWith("log.") || req.Host.Host.StartsWith("mods."))
+ && (req.Host.Host.StartsWith("api.") || req.Host.Host.StartsWith("json.") || req.Host.Host.StartsWith("log.") || req.Host.Host.StartsWith("mods."))
&& !req.Path.StartsWithSegments("/content")
&& !req.Path.StartsWithSegments("/favicon.ico")
));
// shortcut redirects
redirects.Add(new RedirectToUrlRule(@"^/3\.0\.?$", "https://stardewvalleywiki.com/Modding:Migrate_to_SMAPI_3.0"));
- redirects.Add(new RedirectToUrlRule(@"^/buildmsg(?:/?(.*))$", "https://github.com/Pathoschild/SMAPI/blob/develop/docs/mod-build-config.md#$1"));
+ redirects.Add(new RedirectToUrlRule(@"^/(?:buildmsg|package)(?:/?(.*))$", "https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md#$1")); // buildmsg deprecated, remove when SDV 1.4 is released
+ redirects.Add(new RedirectToUrlRule(@"^/community\.?$", "https://stardewvalleywiki.com/Modding:Community"));
redirects.Add(new RedirectToUrlRule(@"^/compat\.?$", "https://mods.smapi.io"));
redirects.Add(new RedirectToUrlRule(@"^/docs\.?$", "https://stardewvalleywiki.com/Modding:Index"));
redirects.Add(new RedirectToUrlRule(@"^/install\.?$", "https://stardewvalleywiki.com/Modding:Player_Guide/Getting_Started#Install_SMAPI"));