diff --git a/.github/README.md b/.github/README.md index d6d215d..63197d8 100644 --- a/.github/README.md +++ b/.github/README.md @@ -49,6 +49,20 @@ Add the package to an existing Umbraco website from nuget: Once added, a new Content App will be available alongside your Umbraco pages allowing you to trigger a sustainability report. +## Configuration + +Example configuration that can be added for this package. + + ``` + "UmbracoCommunitySustainability": { + "Enabled": true, + "MediaOptimisation": { + "ShowWarnings": true, + "FileTypes": { "Image": "2000000" } + } + } + ``` + ## Contributing Contributions to this package are most welcome! Please read the [Contributing Guidelines](CONTRIBUTING.md) for how to get involved. diff --git a/docs/README_nuget.md b/docs/README_nuget.md index 27b5924..97ac44c 100644 --- a/docs/README_nuget.md +++ b/docs/README_nuget.md @@ -33,6 +33,21 @@ Add the package to an existing Umbraco website from NuGet: Once added, a new Content App will be available alongside your Umbraco pages allowing you to trigger a sustainability report. +## Configuration + +Example configuration that can be added for this package. + + ``` + "UmbracoCommunitySustainability": { + "Enabled": true, + "MediaOptimisation": { + "ShowWarnings": true, + "FileTypes": { "Image": "2000000" } + } + } + ``` + + ## License Copyright © [Rick Butterfield](https://github.com/rickbutterfield), [Thomas Morris](https://github.com/tcmorris) and other contributors. diff --git a/src/Umbraco.Community.Sustainability.TestSite.13.x/appsettings.json b/src/Umbraco.Community.Sustainability.TestSite.13.x/appsettings.json index 1bf5dbc..47dc540 100644 --- a/src/Umbraco.Community.Sustainability.TestSite.13.x/appsettings.json +++ b/src/Umbraco.Community.Sustainability.TestSite.13.x/appsettings.json @@ -34,5 +34,12 @@ "UpgradeUnattended": true } } + }, + "UmbracoCommunitySustainability": { + "Enabled": true, + "MediaOptimisation": { + "ShowWarnings": true, + "FileTypes": { "Image": "2000000" } + } } } diff --git a/src/Umbraco.Community.Sustainability/Configuration/MediaOptimisationConfiguration.cs b/src/Umbraco.Community.Sustainability/Configuration/MediaOptimisationConfiguration.cs new file mode 100644 index 0000000..aa0c61e --- /dev/null +++ b/src/Umbraco.Community.Sustainability/Configuration/MediaOptimisationConfiguration.cs @@ -0,0 +1,9 @@ +namespace Umbraco.Community.Sustainability.Configuration +{ + public class MediaOptimisationConfiguration + { + public bool ShowWarnings { get; set; } = false; + + public Dictionary FileTypes { get; set; } + } +} diff --git a/src/Umbraco.Community.Sustainability/Configuration/SustainabilityConfiguration.cs b/src/Umbraco.Community.Sustainability/Configuration/SustainabilityConfiguration.cs new file mode 100644 index 0000000..634c1ca --- /dev/null +++ b/src/Umbraco.Community.Sustainability/Configuration/SustainabilityConfiguration.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Community.Sustainability.Configuration +{ + public class SustainabilityConfiguration + { + public const string SectionAlias = "UmbracoCommunitySustainability"; + + public bool Enabled { get; set; } = true; + public MediaOptimisationConfiguration MediaOptimisation { get; set; } + } +} diff --git a/src/Umbraco.Community.Sustainability/Notifications/MediaTreeNodeRenderingNotificationHandler.cs b/src/Umbraco.Community.Sustainability/Notifications/MediaTreeNodeRenderingNotificationHandler.cs new file mode 100644 index 0000000..07351bb --- /dev/null +++ b/src/Umbraco.Community.Sustainability/Notifications/MediaTreeNodeRenderingNotificationHandler.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Community.Sustainability.Configuration; +using Umbraco.Community.Sustainability.Services; + +namespace Umbraco.Community.Sustainability.Notifications +{ + public class MediaTreeNodeRenderingNotificationHandler : INotificationHandler + { + private readonly IMediaOptimisationService _mediaOptimisationService; + private readonly SustainabilityConfiguration _configuration; + + public MediaTreeNodeRenderingNotificationHandler( + IMediaOptimisationService mediaOptimisationService, + IOptions configuration) + { + _mediaOptimisationService = mediaOptimisationService; + _configuration = configuration.Value; + } + + public void Handle(TreeNodesRenderingNotification notification) + { + if (_configuration.Enabled + && _configuration.MediaOptimisation.ShowWarnings + && notification.TreeAlias == Cms.Core.Constants.Trees.Media) + { + foreach (var node in notification.Nodes) + { + int.TryParse(node.Id.ToString(), out int nodeId); + + if (_mediaOptimisationService.ShowMediaWarning(nodeId)) + { + node.Icon = "icon-alert-alt color-red"; + } + } + } + } + } +} diff --git a/src/Umbraco.Community.Sustainability/Services/MediaOptimisationService.cs b/src/Umbraco.Community.Sustainability/Services/MediaOptimisationService.cs new file mode 100644 index 0000000..54148cc --- /dev/null +++ b/src/Umbraco.Community.Sustainability/Services/MediaOptimisationService.cs @@ -0,0 +1,56 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Web; +using Umbraco.Community.Sustainability.Configuration; +using Umbraco.Extensions; + +namespace Umbraco.Community.Sustainability.Services +{ + public interface IMediaOptimisationService + { + bool ShowMediaWarning(int nodeId); + } + + public class MediaOptimisationService : IMediaOptimisationService + { + private readonly IUmbracoContextFactory _umbracoContextFactory; + private readonly SustainabilityConfiguration _configuration; + + public MediaOptimisationService( + IUmbracoContextFactory umbracoContextFactory, + IOptions configuration) + { + _umbracoContextFactory = umbracoContextFactory; + _configuration = configuration.Value; + } + + public bool ShowMediaWarning(int nodeId) + { + var mediaItem = GetMediaFile(nodeId); + if (mediaItem == null) + { + return false; + } + + var fileTypes = _configuration.MediaOptimisation.FileTypes; + if (!fileTypes.Any(x => x.Key.InvariantEquals(mediaItem.ContentType.Alias))) + { + return false; + } + + var imageSize = mediaItem.Value("umbracoBytes"); + var acceptedFileSize = fileTypes.FirstOrDefault(x => x.Key.InvariantEquals(mediaItem.ContentType.Alias)); + + long maxAcceptedFileSize = (long)Convert.ToDouble(acceptedFileSize.Value); + + return imageSize > maxAcceptedFileSize; + } + + private IPublishedContent? GetMediaFile(int nodeId) + { + using var umbracoContextReference = _umbracoContextFactory.EnsureUmbracoContext(); + + return umbracoContextReference.UmbracoContext.Media?.GetById(nodeId); + } + } +} diff --git a/src/Umbraco.Community.Sustainability/SustainabilityComposer.cs b/src/Umbraco.Community.Sustainability/SustainabilityComposer.cs index ff6cf62..187bf3f 100644 --- a/src/Umbraco.Community.Sustainability/SustainabilityComposer.cs +++ b/src/Umbraco.Community.Sustainability/SustainabilityComposer.cs @@ -2,6 +2,7 @@ using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Notifications; +using Umbraco.Community.Sustainability.Configuration; using Umbraco.Community.Sustainability.ContentApps; using Umbraco.Community.Sustainability.Notifications; using Umbraco.Community.Sustainability.Sections; @@ -22,14 +23,22 @@ public void Compose(IUmbracoBuilder builder) throw new Exception($"Playwright exited with code {exitCode}"); } + // startup builder.AddNotificationHandler(); builder.ManifestFilters().Append(); - builder.ContentApps().Append(); + // ui + builder.ContentApps().Append(); builder.Sections().Append(); + // services builder.Services.AddScoped(); builder.Services.AddSingleton(); + builder.Services.AddSingleton(); + builder.Services.AddOptions().Bind(builder.Config.GetSection(SustainabilityConfiguration.SectionAlias)); + + // notifications + builder.AddNotificationHandler(); } } } diff --git a/src/Umbraco.Community.Sustainability/SustainabilityManifestFilter.cs b/src/Umbraco.Community.Sustainability/SustainabilityManifestFilter.cs index 391436f..f5fe5fd 100644 --- a/src/Umbraco.Community.Sustainability/SustainabilityManifestFilter.cs +++ b/src/Umbraco.Community.Sustainability/SustainabilityManifestFilter.cs @@ -25,7 +25,6 @@ public void Filter(List manifests) { // List any Stylesheet files // Urls should start '/App_Plugins/UmbracoCommunitySustainability/' not '/wwwroot/Umbraco.Community.Sustainability/', e.g. - // "/App_Plugins/UmbracoCommunitySustainability/Styles/styles.css" } }); } diff --git a/src/Umbraco.Community.Sustainability/Umbraco.Community.Sustainability.csproj b/src/Umbraco.Community.Sustainability/Umbraco.Community.Sustainability.csproj index 544c15e..d802de6 100644 --- a/src/Umbraco.Community.Sustainability/Umbraco.Community.Sustainability.csproj +++ b/src/Umbraco.Community.Sustainability/Umbraco.Community.Sustainability.csproj @@ -57,6 +57,5 @@ True \ - - +