diff options
Diffstat (limited to 'src/SMAPI.Web/Startup.cs')
-rw-r--r-- | src/SMAPI.Web/Startup.cs | 90 |
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")); |