mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-23 04:43:35 +08:00
Updating Warmup UI
--HG-- branch : 1.x
This commit is contained in:
@@ -6,6 +6,7 @@ using System.Xml;
|
|||||||
using Autofac;
|
using Autofac;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using Orchard.Environment.Configuration;
|
||||||
using Orchard.Environment.Warmup;
|
using Orchard.Environment.Warmup;
|
||||||
using Orchard.FileSystems.AppData;
|
using Orchard.FileSystems.AppData;
|
||||||
using Orchard.FileSystems.LockFile;
|
using Orchard.FileSystems.LockFile;
|
||||||
@@ -26,11 +27,13 @@ namespace Orchard.Tests.Modules.Warmup {
|
|||||||
private Mock<IWebDownloader> _webDownloader;
|
private Mock<IWebDownloader> _webDownloader;
|
||||||
private IOrchardServices _orchardServices;
|
private IOrchardServices _orchardServices;
|
||||||
private WarmupSettingsPart _settings;
|
private WarmupSettingsPart _settings;
|
||||||
|
private IWarmupReportManager _reportManager;
|
||||||
|
|
||||||
private readonly string _basePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
private readonly string _basePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||||
|
|
||||||
private string _warmupFilename, _lockFilename;
|
private string _warmupFilename, _lockFilename;
|
||||||
private const string WarmupFolder = "Warmup";
|
private const string WarmupFolder = "Warmup";
|
||||||
|
private const string TenantFolder = "Sites/Default";
|
||||||
|
|
||||||
[TestFixtureTearDown]
|
[TestFixtureTearDown]
|
||||||
public void Clean() {
|
public void Clean() {
|
||||||
@@ -60,15 +63,18 @@ namespace Orchard.Tests.Modules.Warmup {
|
|||||||
builder.RegisterType<DefaultLockFileManager>().As<ILockFileManager>();
|
builder.RegisterType<DefaultLockFileManager>().As<ILockFileManager>();
|
||||||
builder.RegisterType<WarmupUpdater>().As<IWarmupUpdater>();
|
builder.RegisterType<WarmupUpdater>().As<IWarmupUpdater>();
|
||||||
builder.RegisterType<StubClock>().As<IClock>();
|
builder.RegisterType<StubClock>().As<IClock>();
|
||||||
|
builder.RegisterType<WarmupReportManager>().As<IWarmupReportManager>();
|
||||||
|
builder.RegisterInstance(new ShellSettings { Name = "Default" }).As<ShellSettings>();
|
||||||
builder.RegisterInstance(_clock = new StubClock()).As<IClock>();
|
builder.RegisterInstance(_clock = new StubClock()).As<IClock>();
|
||||||
builder.RegisterInstance(_webDownloader.Object).As<IWebDownloader>();
|
builder.RegisterInstance(_webDownloader.Object).As<IWebDownloader>();
|
||||||
_container = builder.Build();
|
_container = builder.Build();
|
||||||
|
|
||||||
_lockFileManager = _container.Resolve<ILockFileManager>();
|
_lockFileManager = _container.Resolve<ILockFileManager>();
|
||||||
_warmupUpdater = _container.Resolve<IWarmupUpdater>();
|
_warmupUpdater = _container.Resolve<IWarmupUpdater>();
|
||||||
|
_reportManager = _container.Resolve<IWarmupReportManager>();
|
||||||
|
|
||||||
_warmupFilename = _appDataFolder.Combine(WarmupFolder, "warmup.txt");
|
_warmupFilename = _appDataFolder.Combine(TenantFolder, "warmup.txt");
|
||||||
_lockFilename = _appDataFolder.Combine(WarmupFolder, "warmup.txt.lock");
|
_lockFilename = _appDataFolder.Combine(TenantFolder, "warmup.txt.lock");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -91,8 +97,7 @@ namespace Orchard.Tests.Modules.Warmup {
|
|||||||
_lockFileManager.TryAcquireLock(_lockFilename, ref lockFile);
|
_lockFileManager.TryAcquireLock(_lockFilename, ref lockFile);
|
||||||
using(lockFile) {
|
using(lockFile) {
|
||||||
_warmupUpdater.Generate();
|
_warmupUpdater.Generate();
|
||||||
// warmup file + lock file
|
Assert.That(_appDataFolder.ListFiles(WarmupFolder).Count(), Is.EqualTo(0));
|
||||||
Assert.That(_appDataFolder.ListFiles(WarmupFolder).Count(), Is.EqualTo(2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_warmupUpdater.Generate();
|
_warmupUpdater.Generate();
|
||||||
@@ -114,11 +119,14 @@ namespace Orchard.Tests.Modules.Warmup {
|
|||||||
_warmupUpdater.Generate();
|
_warmupUpdater.Generate();
|
||||||
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
||||||
|
|
||||||
// warmup + content files
|
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, "warmup.txt")));
|
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net/About"))));
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net/About"))));
|
||||||
|
|
||||||
|
files = _appDataFolder.ListFiles(TenantFolder).ToList();
|
||||||
|
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(TenantFolder, "warmup.txt")));
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(TenantFolder, "warmup.xml")));
|
||||||
|
|
||||||
var homepageContent = _appDataFolder.ReadFile(_appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net")));
|
var homepageContent = _appDataFolder.ReadFile(_appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net")));
|
||||||
var aboutcontent = _appDataFolder.ReadFile(_appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net/About")));
|
var aboutcontent = _appDataFolder.ReadFile(_appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net/About")));
|
||||||
|
|
||||||
@@ -141,8 +149,6 @@ namespace Orchard.Tests.Modules.Warmup {
|
|||||||
_warmupUpdater.Generate();
|
_warmupUpdater.Generate();
|
||||||
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
||||||
|
|
||||||
// warmup + content file
|
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, "warmup.txt")));
|
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
||||||
Assert.That(files, Has.None.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net/About"))));
|
Assert.That(files, Has.None.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net/About"))));
|
||||||
}
|
}
|
||||||
@@ -158,9 +164,7 @@ namespace Orchard.Tests.Modules.Warmup {
|
|||||||
_warmupUpdater.Generate();
|
_warmupUpdater.Generate();
|
||||||
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
||||||
|
|
||||||
// warmup + content file
|
Assert.That(files.Count, Is.EqualTo(1));
|
||||||
Assert.That(files.Count, Is.EqualTo(2));
|
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, "warmup.txt")));
|
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,8 +262,6 @@ namespace Orchard.Tests.Modules.Warmup {
|
|||||||
_warmupUpdater.Generate();
|
_warmupUpdater.Generate();
|
||||||
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
||||||
|
|
||||||
// warmup + content files
|
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, "warmup.txt")));
|
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://www.orchardproject.net"))));
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://www.orchardproject.net"))));
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://www.orchardproject.net/About"))));
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://www.orchardproject.net/About"))));
|
||||||
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
||||||
@@ -276,6 +278,96 @@ namespace Orchard.Tests.Modules.Warmup {
|
|||||||
Assert.That(aboutcontent, Is.EqualTo("Bar"));
|
Assert.That(aboutcontent, Is.EqualTo("Bar"));
|
||||||
Assert.That(wwwaboutcontent, Is.EqualTo("Bar"));
|
Assert.That(wwwaboutcontent, Is.EqualTo("Bar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ReportIsCreated() {
|
||||||
|
_settings.Urls = @" /
|
||||||
|
/About";
|
||||||
|
|
||||||
|
((StubWorkContextAccessor.WorkContextImpl.StubSite)_orchardServices.WorkContext.CurrentSite).BaseUrl = "http://www.orchardproject.net/";
|
||||||
|
|
||||||
|
_webDownloader
|
||||||
|
.Setup(w => w.Download("http://www.orchardproject.net/"))
|
||||||
|
.Returns(new DownloadResult { Content = "Foo", StatusCode = HttpStatusCode.OK });
|
||||||
|
|
||||||
|
_webDownloader
|
||||||
|
.Setup(w => w.Download("http://www.orchardproject.net/About"))
|
||||||
|
.Returns(new DownloadResult { Content = "Bar", StatusCode = HttpStatusCode.OK });
|
||||||
|
|
||||||
|
_warmupUpdater.Generate();
|
||||||
|
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
||||||
|
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://www.orchardproject.net"))));
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://www.orchardproject.net/About"))));
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net/About"))));
|
||||||
|
|
||||||
|
var report = _reportManager.Read().ToList();
|
||||||
|
|
||||||
|
Assert.That(report.Count(), Is.EqualTo(2));
|
||||||
|
Assert.That(report, Has.Some.Matches<ReportEntry>(x => x.RelativeUrl == "/"));
|
||||||
|
Assert.That(report, Has.Some.Matches<ReportEntry>(x => x.RelativeUrl == "/About"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ShouldNotDeleteOtherFiles() {
|
||||||
|
_settings.Urls = @" /
|
||||||
|
/About";
|
||||||
|
|
||||||
|
((StubWorkContextAccessor.WorkContextImpl.StubSite)_orchardServices.WorkContext.CurrentSite).BaseUrl = "http://www.orchardproject.net/";
|
||||||
|
|
||||||
|
_webDownloader
|
||||||
|
.Setup(w => w.Download("http://www.orchardproject.net/"))
|
||||||
|
.Returns(new DownloadResult { Content = "Foo", StatusCode = HttpStatusCode.OK });
|
||||||
|
|
||||||
|
_webDownloader
|
||||||
|
.Setup(w => w.Download("http://www.orchardproject.net/About"))
|
||||||
|
.Returns(new DownloadResult { Content = "Bar", StatusCode = HttpStatusCode.OK });
|
||||||
|
|
||||||
|
// Create a static file in the warmup folder
|
||||||
|
_appDataFolder.CreateFile(_appDataFolder.Combine(WarmupFolder, "foo.txt"), "Foo");
|
||||||
|
|
||||||
|
_warmupUpdater.Generate();
|
||||||
|
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
||||||
|
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, "foo.txt")));
|
||||||
|
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://www.orchardproject.net"))));
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://www.orchardproject.net/About"))));
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net/About"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ClearingUrlsShouldDeleteContent() {
|
||||||
|
_settings.Urls = @" /
|
||||||
|
/About";
|
||||||
|
|
||||||
|
((StubWorkContextAccessor.WorkContextImpl.StubSite)_orchardServices.WorkContext.CurrentSite).BaseUrl = "http://www.orchardproject.net/";
|
||||||
|
|
||||||
|
_webDownloader
|
||||||
|
.Setup(w => w.Download("http://www.orchardproject.net/"))
|
||||||
|
.Returns(new DownloadResult { Content = "Foo", StatusCode = HttpStatusCode.OK });
|
||||||
|
|
||||||
|
_webDownloader
|
||||||
|
.Setup(w => w.Download("http://www.orchardproject.net/About"))
|
||||||
|
.Returns(new DownloadResult { Content = "Bar", StatusCode = HttpStatusCode.OK });
|
||||||
|
|
||||||
|
_warmupUpdater.Generate();
|
||||||
|
var files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
||||||
|
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://www.orchardproject.net"))));
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://www.orchardproject.net/About"))));
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net"))));
|
||||||
|
Assert.That(files, Has.Some.Matches<string>(x => x == _appDataFolder.Combine(WarmupFolder, WarmupUtility.EncodeUrl("http://orchardproject.net/About"))));
|
||||||
|
|
||||||
|
_settings.Urls = @"";
|
||||||
|
|
||||||
|
_warmupUpdater.Generate();
|
||||||
|
files = _appDataFolder.ListFiles(WarmupFolder).ToList();
|
||||||
|
|
||||||
|
Assert.That(files.Count, Is.EqualTo(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,12 @@
|
|||||||
@Html.EditorFor(m => m.SiteName)
|
@Html.EditorFor(m => m.SiteName)
|
||||||
@Html.ValidationMessage("SiteName", "*")
|
@Html.ValidationMessage("SiteName", "*")
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.BaseUrl)">@T("Base url ")</label>
|
||||||
|
@Html.TextBoxFor(m => m.BaseUrl, new { @class = "textMedium" })
|
||||||
|
<span class="hint">@T("Enter the fully qualified base url of your website.")</span>
|
||||||
|
<span class="hint">@T("e.g., http://localhost:30320/orchardlocal, http://www.yourdomain.com")</span>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="SiteCulture">@T("Default Site Culture")</label>
|
<label for="SiteCulture">@T("Default Site Culture")</label>
|
||||||
@Html.DropDownList("SiteCulture", new SelectList(Model.SiteCultures, Model.SiteCulture))
|
@Html.DropDownList("SiteCulture", new SelectList(Model.SiteCultures, Model.SiteCulture))
|
||||||
@@ -41,10 +47,4 @@
|
|||||||
@Html.TextBoxFor(m => m.PageSize, new { @class = "text-small" })
|
@Html.TextBoxFor(m => m.PageSize, new { @class = "text-small" })
|
||||||
<span class="hint">@T("Determines the default number of items that are shown per page.")</span>
|
<span class="hint">@T("Determines the default number of items that are shown per page.")</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<label for="@Html.FieldIdFor(m => m.BaseUrl)">@T("Base url ")</label>
|
|
||||||
@Html.TextBoxFor(m => m.BaseUrl, new { @class = "textMedium" })
|
|
||||||
<span class="hint">@T("Enter the fully qualified base url of your website.")</span>
|
|
||||||
<span class="hint">@T("e.g., http://localhost:30320/orchardlocal, http://www.yourdomain.com")</span>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
</fieldset>
|
@@ -10,8 +10,9 @@ namespace Orchard.Warmup {
|
|||||||
public void GetNavigation(NavigationBuilder builder) {
|
public void GetNavigation(NavigationBuilder builder) {
|
||||||
builder
|
builder
|
||||||
.Add(T("Settings"), menu => menu
|
.Add(T("Settings"), menu => menu
|
||||||
.Add(T("Warmup" ), "10.0", item => item.Action("Index", "Admin", new { area = "Orchard.Warmup" }).Permission(StandardPermissions.SiteOwner))
|
.Add(T("Performance"), "10.0", subMenu => subMenu.Action("Index", "Admin", new { area = "Orchard.Warmup" }).Permission(StandardPermissions.SiteOwner)
|
||||||
);
|
.Add(T("Warmup"), "10.0", item => item.Action("Index", "Admin", new { area = "Orchard.Warmup" }).Permission(StandardPermissions.SiteOwner).LocalNav())
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 293 B |
Binary file not shown.
After Width: | Height: | Size: 405 B |
21
src/Orchard.Web/Modules/Orchard.Warmup/Content/Web.config
Normal file
21
src/Orchard.Web/Modules/Orchard.Warmup/Content/Web.config
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appSettings>
|
||||||
|
<add key="webpages:Enabled" value="false" />
|
||||||
|
</appSettings>
|
||||||
|
<system.web>
|
||||||
|
<httpHandlers>
|
||||||
|
<!-- iis6 - for any request in this location, return via managed static file handler -->
|
||||||
|
<add path="*" verb="*" type="System.Web.StaticFileHandler" />
|
||||||
|
</httpHandlers>
|
||||||
|
</system.web>
|
||||||
|
<system.webServer>
|
||||||
|
<handlers accessPolicy="Script,Read">
|
||||||
|
<!--
|
||||||
|
iis7 - for any request to a file exists on disk, return it via native http module.
|
||||||
|
accessPolicy 'Script' is to allow for a managed 404 page.
|
||||||
|
-->
|
||||||
|
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
|
||||||
|
</handlers>
|
||||||
|
</system.webServer>
|
||||||
|
</configuration>
|
@@ -1,25 +1,28 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.Core.Contents.Controllers;
|
using Orchard.Core.Contents.Controllers;
|
||||||
using Orchard.FileSystems.AppData;
|
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Security;
|
using Orchard.Security;
|
||||||
using Orchard.Warmup.Models;
|
using Orchard.Warmup.Models;
|
||||||
using Orchard.UI.Notify;
|
using Orchard.UI.Notify;
|
||||||
using Orchard.Warmup.Services;
|
using Orchard.Warmup.Services;
|
||||||
|
using Orchard.Warmup.ViewModels;
|
||||||
|
|
||||||
namespace Orchard.Warmup.Controllers {
|
namespace Orchard.Warmup.Controllers {
|
||||||
[ValidateInput(false)]
|
[ValidateInput(false)]
|
||||||
public class AdminController : Controller, IUpdateModel {
|
public class AdminController : Controller, IUpdateModel {
|
||||||
private readonly IWarmupScheduler _warmupScheduler;
|
private readonly IWarmupUpdater _warmupUpdater;
|
||||||
|
private readonly IWarmupReportManager _reportManager;
|
||||||
|
|
||||||
public AdminController(
|
public AdminController(
|
||||||
IOrchardServices services,
|
IOrchardServices services,
|
||||||
IWarmupScheduler warmupScheduler,
|
IWarmupUpdater warmupUpdater,
|
||||||
IAppDataFolder appDataFolder) {
|
IWarmupReportManager reportManager) {
|
||||||
_warmupScheduler = warmupScheduler;
|
_warmupUpdater = warmupUpdater;
|
||||||
|
_reportManager = reportManager;
|
||||||
Services = services;
|
Services = services;
|
||||||
|
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
@@ -33,7 +36,13 @@ namespace Orchard.Warmup.Controllers {
|
|||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
var warmupPart = Services.WorkContext.CurrentSite.As<WarmupSettingsPart>();
|
var warmupPart = Services.WorkContext.CurrentSite.As<WarmupSettingsPart>();
|
||||||
return View(warmupPart);
|
|
||||||
|
var viewModel = new WarmupViewModel {
|
||||||
|
Settings = warmupPart,
|
||||||
|
ReportEntries = _reportManager.Read()
|
||||||
|
};
|
||||||
|
|
||||||
|
return View(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
[FormValueRequired("submit")]
|
[FormValueRequired("submit")]
|
||||||
@@ -42,11 +51,14 @@ namespace Orchard.Warmup.Controllers {
|
|||||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage settings")))
|
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage settings")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
var warmupPart = Services.WorkContext.CurrentSite.As<WarmupSettingsPart>();
|
var viewModel = new WarmupViewModel {
|
||||||
|
Settings = Services.WorkContext.CurrentSite.As<WarmupSettingsPart>(),
|
||||||
|
ReportEntries = Enumerable.Empty<ReportEntry>()
|
||||||
|
};
|
||||||
|
|
||||||
if(TryUpdateModel(warmupPart)) {
|
if (TryUpdateModel(viewModel)) {
|
||||||
if (!String.IsNullOrEmpty(warmupPart.Urls)) {
|
if (!String.IsNullOrEmpty(viewModel.Settings.Urls)) {
|
||||||
using (var urlReader = new StringReader(warmupPart.Urls)) {
|
using (var urlReader = new StringReader(viewModel.Settings.Urls)) {
|
||||||
string relativeUrl;
|
string relativeUrl;
|
||||||
while (null != (relativeUrl = urlReader.ReadLine())) {
|
while (null != (relativeUrl = urlReader.ReadLine())) {
|
||||||
if (!Uri.IsWellFormedUriString(relativeUrl, UriKind.Relative) || !(relativeUrl.StartsWith("/"))) {
|
if (!Uri.IsWellFormedUriString(relativeUrl, UriKind.Relative) || !(relativeUrl.StartsWith("/"))) {
|
||||||
@@ -57,30 +69,20 @@ namespace Orchard.Warmup.Controllers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (warmupPart.Scheduled) {
|
if (viewModel.Settings.Scheduled) {
|
||||||
if (warmupPart.Delay <= 0) {
|
if (viewModel.Settings.Delay <= 0) {
|
||||||
AddModelError("Delay", T("Delay must be greater than zero."));
|
AddModelError("Delay", T("Delay must be greater than zero."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ModelState.IsValid) {
|
if (ModelState.IsValid) {
|
||||||
Services.Notifier.Information(T("Warmup updated successfully."));
|
Services.Notifier.Information(T("Warmup updated successfully."));
|
||||||
}
|
}
|
||||||
|
|
||||||
return View(warmupPart);
|
|
||||||
}
|
|
||||||
|
|
||||||
[FormValueRequired("submit.Generate")]
|
|
||||||
[HttpPost, ActionName("Index")]
|
|
||||||
public ActionResult IndexPostGenerate() {
|
|
||||||
var result = IndexPost();
|
|
||||||
|
|
||||||
if (ModelState.IsValid) {
|
if (ModelState.IsValid) {
|
||||||
_warmupScheduler.Schedule(true);
|
_warmupUpdater.Generate();
|
||||||
Services.Notifier.Information(T("Static pages are currently being generated."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
||||||
|
10
src/Orchard.Web/Modules/Orchard.Warmup/Models/ReportEntry.cs
Normal file
10
src/Orchard.Web/Modules/Orchard.Warmup/Models/ReportEntry.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Orchard.Warmup.Models {
|
||||||
|
public class ReportEntry {
|
||||||
|
public string RelativeUrl { get; set; }
|
||||||
|
public string Filename { get; set; }
|
||||||
|
public int StatusCode { get; set; }
|
||||||
|
public DateTime CreatedUtc { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -59,6 +59,9 @@
|
|||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Content Include="Content\Admin\images\offline.gif" />
|
||||||
|
<Content Include="Content\Admin\images\online.gif" />
|
||||||
|
<Content Include="Styles\orchard-warmup-admin.css" />
|
||||||
<Content Include="web.config" />
|
<Content Include="web.config" />
|
||||||
<Content Include="Views\Web.config" />
|
<Content Include="Views\Web.config" />
|
||||||
<Content Include="Scripts\Web.config" />
|
<Content Include="Scripts\Web.config" />
|
||||||
@@ -83,8 +86,11 @@
|
|||||||
<Compile Include="Handlers\WarmupContentHandler.cs" />
|
<Compile Include="Handlers\WarmupContentHandler.cs" />
|
||||||
<Compile Include="Handlers\WarmupSettingsPartHandler.cs" />
|
<Compile Include="Handlers\WarmupSettingsPartHandler.cs" />
|
||||||
<Compile Include="Migrations.cs" />
|
<Compile Include="Migrations.cs" />
|
||||||
|
<Compile Include="Models\ReportEntry.cs" />
|
||||||
<Compile Include="Models\WarmupSettingsPart.cs" />
|
<Compile Include="Models\WarmupSettingsPart.cs" />
|
||||||
<Compile Include="Models\WarmupSettingsPartRecord.cs" />
|
<Compile Include="Models\WarmupSettingsPartRecord.cs" />
|
||||||
|
<Compile Include="Services\WarmupReportManager.cs" />
|
||||||
|
<Compile Include="Services\IWarmupReportManager.cs" />
|
||||||
<Compile Include="Services\IWarmupScheduler.cs" />
|
<Compile Include="Services\IWarmupScheduler.cs" />
|
||||||
<Compile Include="Services\WarmupScheduler.cs" />
|
<Compile Include="Services\WarmupScheduler.cs" />
|
||||||
<Compile Include="Services\WebDownloader.cs" />
|
<Compile Include="Services\WebDownloader.cs" />
|
||||||
@@ -93,10 +99,12 @@
|
|||||||
<Compile Include="Services\SettingsBanner.cs" />
|
<Compile Include="Services\SettingsBanner.cs" />
|
||||||
<Compile Include="Services\WarmupTask.cs" />
|
<Compile Include="Services\WarmupTask.cs" />
|
||||||
<Compile Include="Services\WarmupUpdater.cs" />
|
<Compile Include="Services\WarmupUpdater.cs" />
|
||||||
|
<Compile Include="ViewModels\WarmupViewModel.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Views\EditorTemplates\Parts.Warmup.SiteSettings.cshtml" />
|
<Content Include="Content\Web.config">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Placement.info" />
|
<Content Include="Placement.info" />
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.Warmup.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Warmup.Services {
|
||||||
|
public interface IWarmupReportManager : IDependency {
|
||||||
|
IEnumerable<ReportEntry> Read();
|
||||||
|
void Create(IEnumerable<ReportEntry> reportEntries);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,58 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Orchard.Environment.Configuration;
|
||||||
|
using Orchard.FileSystems.AppData;
|
||||||
|
using Orchard.Warmup.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Warmup.Services {
|
||||||
|
public class WarmupReportManager : IWarmupReportManager {
|
||||||
|
private readonly IAppDataFolder _appDataFolder;
|
||||||
|
private const string WarmupReportFilename = "warmup.xml";
|
||||||
|
private readonly string _warmupReportPath;
|
||||||
|
|
||||||
|
public WarmupReportManager(
|
||||||
|
ShellSettings shellSettings,
|
||||||
|
IAppDataFolder appDataFolder) {
|
||||||
|
_appDataFolder = appDataFolder;
|
||||||
|
|
||||||
|
_warmupReportPath = _appDataFolder.Combine("Sites", _appDataFolder.Combine(shellSettings.Name, WarmupReportFilename));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<ReportEntry> Read() {
|
||||||
|
if(!_appDataFolder.FileExists(_warmupReportPath)) {
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var warmupReportContent = _appDataFolder.ReadFile(_warmupReportPath);
|
||||||
|
|
||||||
|
var doc = XDocument.Parse(warmupReportContent);
|
||||||
|
foreach (var entryNode in doc.Root.Descendants("ReportEntry")) {
|
||||||
|
yield return new ReportEntry {
|
||||||
|
CreatedUtc = XmlConvert.ToDateTime(entryNode.Attribute("CreatedUtc").Value, XmlDateTimeSerializationMode.Utc),
|
||||||
|
Filename = entryNode.Attribute("Filename").Value,
|
||||||
|
RelativeUrl = entryNode.Attribute("RelativeUrl").Value,
|
||||||
|
StatusCode = Int32.Parse(entryNode.Attribute("StatusCode").Value)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Create(IEnumerable<ReportEntry> reportEntries) {
|
||||||
|
var report = new XDocument(new XElement("WarmupReport"));
|
||||||
|
|
||||||
|
foreach (var reportEntry in reportEntries) {
|
||||||
|
report.Root.Add(
|
||||||
|
new XElement("ReportEntry",
|
||||||
|
new XAttribute("RelativeUrl", reportEntry.RelativeUrl),
|
||||||
|
new XAttribute("Filename", reportEntry.Filename),
|
||||||
|
new XAttribute("StatusCode", reportEntry.StatusCode),
|
||||||
|
new XAttribute("CreatedUtc", XmlConvert.ToString(reportEntry.CreatedUtc, XmlDateTimeSerializationMode.Utc))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_appDataFolder.CreateFile(_warmupReportPath, report.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Environment.Configuration;
|
||||||
using Orchard.Environment.Warmup;
|
using Orchard.Environment.Warmup;
|
||||||
using Orchard.FileSystems.AppData;
|
using Orchard.FileSystems.AppData;
|
||||||
using Orchard.FileSystems.LockFile;
|
using Orchard.FileSystems.LockFile;
|
||||||
@@ -18,8 +20,11 @@ namespace Orchard.Warmup.Services {
|
|||||||
private readonly IClock _clock;
|
private readonly IClock _clock;
|
||||||
private readonly IAppDataFolder _appDataFolder;
|
private readonly IAppDataFolder _appDataFolder;
|
||||||
private readonly IWebDownloader _webDownloader;
|
private readonly IWebDownloader _webDownloader;
|
||||||
|
private readonly IWarmupReportManager _reportManager;
|
||||||
private const string BaseFolder = "Warmup";
|
private const string BaseFolder = "Warmup";
|
||||||
private const string WarmupFilename = "warmup.txt";
|
private const string WarmupFilename = "warmup.txt";
|
||||||
|
|
||||||
|
private readonly string _warmupPath;
|
||||||
private readonly string _lockFilename;
|
private readonly string _lockFilename;
|
||||||
|
|
||||||
public WarmupUpdater(
|
public WarmupUpdater(
|
||||||
@@ -27,13 +32,18 @@ namespace Orchard.Warmup.Services {
|
|||||||
ILockFileManager lockFileManager,
|
ILockFileManager lockFileManager,
|
||||||
IClock clock,
|
IClock clock,
|
||||||
IAppDataFolder appDataFolder,
|
IAppDataFolder appDataFolder,
|
||||||
IWebDownloader webDownloader) {
|
IWebDownloader webDownloader,
|
||||||
|
IWarmupReportManager reportManager,
|
||||||
|
ShellSettings shellSettings) {
|
||||||
_orchardServices = orchardServices;
|
_orchardServices = orchardServices;
|
||||||
_lockFileManager = lockFileManager;
|
_lockFileManager = lockFileManager;
|
||||||
_clock = clock;
|
_clock = clock;
|
||||||
_appDataFolder = appDataFolder;
|
_appDataFolder = appDataFolder;
|
||||||
_webDownloader = webDownloader;
|
_webDownloader = webDownloader;
|
||||||
_lockFilename = _appDataFolder.Combine(BaseFolder, WarmupFilename + ".lock");
|
_reportManager = reportManager;
|
||||||
|
|
||||||
|
_lockFilename = _appDataFolder.Combine("Sites", _appDataFolder.Combine(shellSettings.Name, WarmupFilename + ".lock"));
|
||||||
|
_warmupPath = _appDataFolder.Combine("Sites", _appDataFolder.Combine(shellSettings.Name, WarmupFilename));
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
@@ -44,8 +54,8 @@ namespace Orchard.Warmup.Services {
|
|||||||
var baseUrl = _orchardServices.WorkContext.CurrentSite.BaseUrl;
|
var baseUrl = _orchardServices.WorkContext.CurrentSite.BaseUrl;
|
||||||
var part = _orchardServices.WorkContext.CurrentSite.As<WarmupSettingsPart>();
|
var part = _orchardServices.WorkContext.CurrentSite.As<WarmupSettingsPart>();
|
||||||
|
|
||||||
// do nothing while the base url setting is not defined, or if there is no page defined
|
// do nothing while the base url setting is not defined
|
||||||
if (String.IsNullOrWhiteSpace(baseUrl) || String.IsNullOrWhiteSpace(part.Urls)) {
|
if (String.IsNullOrWhiteSpace(baseUrl)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,10 +70,9 @@ namespace Orchard.Warmup.Services {
|
|||||||
// check if we need to regenerate the pages by reading the last time it has been done
|
// check if we need to regenerate the pages by reading the last time it has been done
|
||||||
// 1- if the warmup file doesn't exists, generate the pages
|
// 1- if the warmup file doesn't exists, generate the pages
|
||||||
// 2- otherwise, if the scheduled generation option is on, check if the delay is over
|
// 2- otherwise, if the scheduled generation option is on, check if the delay is over
|
||||||
var warmupPath = _appDataFolder.Combine(BaseFolder, WarmupFilename);
|
if (_appDataFolder.FileExists(_warmupPath)) {
|
||||||
if(_appDataFolder.FileExists(warmupPath)) {
|
|
||||||
try {
|
try {
|
||||||
var warmupContent = _appDataFolder.ReadFile(warmupPath);
|
var warmupContent = _appDataFolder.ReadFile(_warmupPath);
|
||||||
var expired = XmlConvert.ToDateTimeOffset(warmupContent).AddMinutes(part.Delay);
|
var expired = XmlConvert.ToDateTimeOffset(warmupContent).AddMinutes(part.Delay);
|
||||||
if (expired > _clock.UtcNow) {
|
if (expired > _clock.UtcNow) {
|
||||||
return;
|
return;
|
||||||
@@ -71,63 +80,104 @@ namespace Orchard.Warmup.Services {
|
|||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
// invalid file, delete continue processing
|
// invalid file, delete continue processing
|
||||||
_appDataFolder.DeleteFile(warmupPath);
|
_appDataFolder.DeleteFile(_warmupPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete existing static page files
|
// delete peviously generated pages, by reading the Warmup Report file
|
||||||
foreach (var filename in _appDataFolder.ListFiles(BaseFolder)) {
|
try {
|
||||||
var prefix = _appDataFolder.Combine(BaseFolder, "http");
|
var encodedPrefix = WarmupUtility.EncodeUrl("http://www.");
|
||||||
|
|
||||||
// delete only static page files
|
|
||||||
if (!filename.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
_appDataFolder.DeleteFile(filename);
|
|
||||||
}
|
|
||||||
catch(Exception e) {
|
|
||||||
// ignore files which could not be deleted
|
|
||||||
Logger.Error(e, "Could not delete file {0}", filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop over every relative url to generate the contents
|
|
||||||
using (var urlReader = new StringReader(part.Urls)) {
|
|
||||||
string relativeUrl;
|
|
||||||
while (null != (relativeUrl = urlReader.ReadLine())) {
|
|
||||||
string url = null;
|
|
||||||
relativeUrl = relativeUrl.Trim();
|
|
||||||
|
|
||||||
|
foreach (var reportEntry in _reportManager.Read()) {
|
||||||
try {
|
try {
|
||||||
url = VirtualPathUtility.RemoveTrailingSlash(baseUrl) + relativeUrl;
|
// use FileName as the SiteBaseUrl could have changed in the meantime
|
||||||
var download = _webDownloader.Download(url);
|
var path = _appDataFolder.Combine(BaseFolder, reportEntry.Filename);
|
||||||
|
_appDataFolder.DeleteFile(path);
|
||||||
if (download != null && download.StatusCode == HttpStatusCode.OK) {
|
|
||||||
var filename = WarmupUtility.EncodeUrl(url.TrimEnd('/'));
|
|
||||||
var path = _appDataFolder.Combine(BaseFolder, filename);
|
|
||||||
_appDataFolder.CreateFile(path, download.Content);
|
|
||||||
|
|
||||||
// if the base url contains http://www, then also render the www-less one
|
|
||||||
|
|
||||||
if (url.StartsWith("http://www.", StringComparison.OrdinalIgnoreCase)) {
|
|
||||||
url = "http://" + url.Substring("http://www.".Length);
|
|
||||||
filename = WarmupUtility.EncodeUrl(url.TrimEnd('/'));
|
|
||||||
path = _appDataFolder.Combine(BaseFolder, filename);
|
|
||||||
_appDataFolder.CreateFile(path, download.Content);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// delete the www-less version too if it's available
|
||||||
|
if (reportEntry.Filename.StartsWith(encodedPrefix, StringComparison.OrdinalIgnoreCase)) {
|
||||||
|
var filename = WarmupUtility.EncodeUrl("http://") + reportEntry.Filename.Substring(encodedPrefix.Length);
|
||||||
|
path = _appDataFolder.Combine(BaseFolder, filename);
|
||||||
|
_appDataFolder.DeleteFile(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
Logger.Error(e, "Could not extract warmup page content for: ", url);
|
Logger.Error(e, "Could not delete specific warmup file: ", reportEntry.Filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
Logger.Error(e, "Could not read warmup report file");
|
||||||
|
}
|
||||||
|
|
||||||
|
var reportEntries = new List<ReportEntry>();
|
||||||
|
|
||||||
|
if (!String.IsNullOrEmpty(part.Urls)) {
|
||||||
|
// loop over every relative url to generate the contents
|
||||||
|
using (var urlReader = new StringReader(part.Urls)) {
|
||||||
|
string relativeUrl;
|
||||||
|
while (null != (relativeUrl = urlReader.ReadLine())) {
|
||||||
|
string url = null;
|
||||||
|
relativeUrl = relativeUrl.Trim();
|
||||||
|
|
||||||
|
try {
|
||||||
|
url = VirtualPathUtility.RemoveTrailingSlash(baseUrl) + relativeUrl;
|
||||||
|
var filename = WarmupUtility.EncodeUrl(url.TrimEnd('/'));
|
||||||
|
var path = _appDataFolder.Combine(BaseFolder, filename);
|
||||||
|
|
||||||
|
var download = _webDownloader.Download(url);
|
||||||
|
|
||||||
|
if (download != null) {
|
||||||
|
if (download.StatusCode == HttpStatusCode.OK) {
|
||||||
|
// success
|
||||||
|
_appDataFolder.CreateFile(path, download.Content);
|
||||||
|
|
||||||
|
reportEntries.Add(new ReportEntry {
|
||||||
|
RelativeUrl = relativeUrl,
|
||||||
|
Filename = filename,
|
||||||
|
StatusCode = (int) download.StatusCode,
|
||||||
|
CreatedUtc = _clock.UtcNow
|
||||||
|
});
|
||||||
|
|
||||||
|
// if the base url contains http://www, then also render the www-less one);
|
||||||
|
|
||||||
|
if (url.StartsWith("http://www.", StringComparison.OrdinalIgnoreCase)) {
|
||||||
|
url = "http://" + url.Substring("http://www.".Length);
|
||||||
|
filename = WarmupUtility.EncodeUrl(url.TrimEnd('/'));
|
||||||
|
path = _appDataFolder.Combine(BaseFolder, filename);
|
||||||
|
_appDataFolder.CreateFile(path, download.Content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reportEntries.Add(new ReportEntry {
|
||||||
|
RelativeUrl = relativeUrl,
|
||||||
|
Filename = filename,
|
||||||
|
StatusCode = (int) download.StatusCode,
|
||||||
|
CreatedUtc = _clock.UtcNow
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// download failed
|
||||||
|
reportEntries.Add(new ReportEntry {
|
||||||
|
RelativeUrl = relativeUrl,
|
||||||
|
Filename = filename,
|
||||||
|
StatusCode = 0,
|
||||||
|
CreatedUtc = _clock.UtcNow
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Logger.Error(e, "Could not extract warmup page content for: ", url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_reportManager.Create(reportEntries);
|
||||||
|
|
||||||
// finally write the time the generation has been executed
|
// finally write the time the generation has been executed
|
||||||
_appDataFolder.CreateFile(warmupPath, XmlConvert.ToString(_clock.UtcNow, XmlDateTimeSerializationMode.Utc));
|
_appDataFolder.CreateFile(_warmupPath, XmlConvert.ToString(_clock.UtcNow, XmlDateTimeSerializationMode.Utc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,9 +189,8 @@ namespace Orchard.Warmup.Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
using (lockFile) {
|
using (lockFile) {
|
||||||
var warmupPath = _appDataFolder.Combine(BaseFolder, WarmupFilename);
|
if (_appDataFolder.FileExists(_warmupPath)) {
|
||||||
if (_appDataFolder.FileExists(warmupPath)) {
|
_appDataFolder.DeleteFile(_warmupPath);
|
||||||
_appDataFolder.DeleteFile(warmupPath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
td.status-error {
|
||||||
|
background: transparent url(../Content/Admin/images/offline.gif) no-repeat right;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.status-ok {
|
||||||
|
background: transparent url(../Content/Admin/images/online.gif) no-repeat right;
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.Warmup.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Warmup.ViewModels {
|
||||||
|
public class WarmupViewModel {
|
||||||
|
public WarmupSettingsPart Settings { get; set; }
|
||||||
|
public IEnumerable<ReportEntry> ReportEntries { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -1,38 +1,72 @@
|
|||||||
@model Orchard.Warmup.Models.WarmupSettingsPart
|
@model Orchard.Warmup.ViewModels.WarmupViewModel
|
||||||
@using Orchard.Utility.Extensions;
|
@using Orchard.Utility.Extensions;
|
||||||
@using Orchard.Warmup.Models;
|
@using Orchard.Warmup.Models;
|
||||||
|
|
||||||
@{ Layout.Title = T("Settings").ToString(); }
|
@{
|
||||||
|
Style.Include("orchard-warmup-admin.css");
|
||||||
|
Layout.Title = T("Performance").ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
<p>The urls below will be requested using @Html.Link(WorkContext.CurrentSite.BaseUrl, WorkContext.CurrentSite.BaseUrl) as a base url. You can change it on the @Html.ActionLink(T("General Settings page").Text, "Index", new { controller = "Admin", area = "Settings" }).</p>
|
||||||
|
|
||||||
@using (Html.BeginFormAntiForgeryPost()) {
|
@using (Html.BeginFormAntiForgeryPost()) {
|
||||||
@Html.ValidationSummary()
|
@Html.ValidationSummary()
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>@T("Warmup")</legend>
|
|
||||||
<div>
|
<div>
|
||||||
<label for="@Html.FieldIdFor(m => m.Urls)">@T("Urls for which static warmup pages will be generated")</label>
|
@Html.TextAreaFor(m => m.Settings.Urls, new { @class = "textMedium" })
|
||||||
@Html.TextAreaFor(m => m.Urls, new { @class = "textMedium" })
|
|
||||||
<span class="hint">@T("This must be a set of relative paths, e.g., /, /About")</span>
|
<span class="hint">@T("This must be a set of relative paths, e.g., /, /About")</span>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div>
|
<div>
|
||||||
@Html.EditorFor(m => m.Scheduled)
|
@Html.EditorFor(m => m.Settings.Scheduled)
|
||||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Scheduled)">@T("Generate warmup pages periodically")</label>
|
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Settings.Scheduled)">@T("Generate warmup pages periodically")</label>
|
||||||
</div>
|
</div>
|
||||||
<div data-controllerid="@Html.FieldIdFor(m => m.Scheduled)">
|
<div data-controllerid="@Html.FieldIdFor(m => m.Settings.Scheduled)">
|
||||||
@T("Every")
|
@T("Every")
|
||||||
@Html.TextBoxFor(m => m.Delay, new { @class = "text-small" })
|
@Html.TextBoxFor(m => m.Settings.Delay, new { @class = "text-small" })
|
||||||
@T("minutes")
|
@T("minutes")
|
||||||
@Html.ValidationMessage("Delay", "*")
|
@Html.ValidationMessage("Delay", "*")
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@Html.EditorFor(m => m.OnPublish)
|
@Html.EditorFor(m => m.Settings.OnPublish)
|
||||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.OnPublish)">@T("Generate warmup pages each time some content is published")</label>
|
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Settings.OnPublish)">@T("Generate warmup pages any time some content is published")</label>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<button class="primaryAction" name="submit" value="@T("Save")" type="submit">@T("Save")</button>
|
<button class="primaryAction" name="submit" value="@T("Save")" type="submit">@T("Save")</button>
|
||||||
<button class="primaryAction" name="submit.Generate" value="@T("Save and generate")" type="submit">@T("Save and generate")</button>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label>@T("Report")</label>
|
||||||
|
<table class="items" summary="@T("This is a table of the reports in your application")">
|
||||||
|
<colgroup>
|
||||||
|
<col id="Col1" />
|
||||||
|
<col id="Col2" />
|
||||||
|
<col id="Col3" />
|
||||||
|
<col id="Col4" />
|
||||||
|
</colgroup>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">@T("Url")</th>
|
||||||
|
<th scope="col">@T("Status")</th>
|
||||||
|
<th scope="col">@T("Date")</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
@foreach (var reportEntry in Model.ReportEntries) {
|
||||||
|
<tr>
|
||||||
|
<td class="status-@(reportEntry.StatusCode != 200 ? "error" : "ok")" >
|
||||||
|
@Html.Link(Html.Encode(reportEntry.RelativeUrl), reportEntry.RelativeUrl, new { target = "_blank" })
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@reportEntry.StatusCode
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@Display.DateTimeRelative(dateTimeUtc: reportEntry.CreatedUtc).ToString()
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
|
@@ -1,28 +0,0 @@
|
|||||||
@model Orchard.Warmup.Models.WarmupSettingsPartRecord
|
|
||||||
@using Orchard.Utility.Extensions;
|
|
||||||
@using Orchard.Warmup.Models;
|
|
||||||
|
|
||||||
<fieldset>
|
|
||||||
<legend>@T("Warmup")</legend>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="@Html.FieldIdFor(m => m.Urls)">@T("Urls for which static warm up pages will be generated")</label>
|
|
||||||
@Html.TextAreaFor(m => m.Urls, new { @class = "textMedium" })
|
|
||||||
@Html.ValidationMessage("Urls", "*")
|
|
||||||
<span class="hint">@T("This must be a set of virtual paths, e.g., ~/, ~/About")</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
@Html.EditorFor(m => m.Scheduled)
|
|
||||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Scheduled)">@T("Generate warmup pages periodically")</label>
|
|
||||||
</div>
|
|
||||||
<div data-controllerid="@Html.FieldIdFor(m => m.Scheduled)>
|
|
||||||
<label for="@Html.FieldIdFor(m => m.Urls)">@T("Delay to generate pages")</label>
|
|
||||||
@Html.TextBoxFor(m => m.Delay, new { @class = "" }) @T("minutes")
|
|
||||||
@Html.ValidationMessage("Delay", "*")
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
@Html.EditorFor(m => m.OnPublish)
|
|
||||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.OnPublish)">@T("Generate warmup pages each time some content is published")</label>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
Reference in New Issue
Block a user