diff --git a/src/jcdcdev.Umbraco.ReadingTime/Core/IReadingTimeService.cs b/src/jcdcdev.Umbraco.ReadingTime/Core/IReadingTimeService.cs index cd76f7e..d920fd9 100644 --- a/src/jcdcdev.Umbraco.ReadingTime/Core/IReadingTimeService.cs +++ b/src/jcdcdev.Umbraco.ReadingTime/Core/IReadingTimeService.cs @@ -6,6 +6,7 @@ namespace jcdcdev.Umbraco.ReadingTime.Core; public interface IReadingTimeService { Task ScanTree(int homeId); + Task ScanAll(); Task Process(IContent item); Task DeleteAsync(Guid key); Task GetAsync(Guid key, Guid dataTypeKey); diff --git a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.1.0/InitialMigration.cs b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.1.0/InitialMigration.cs new file mode 100644 index 0000000..2711ce5 --- /dev/null +++ b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.1.0/InitialMigration.cs @@ -0,0 +1,10 @@ +using Umbraco.Cms.Infrastructure.Migrations; + +namespace jcdcdev.Umbraco.ReadingTime.Infrastructure.Migrations; + +public class InitialMigration : NoopMigration +{ + public InitialMigration(IMigrationContext context) : base(context) + { + } +} diff --git a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.2.0/MultiplePropertyEditorSupport.cs b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.2.0/MultiplePropertyEditorSupport.cs deleted file mode 100644 index a8d3165..0000000 --- a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.2.0/MultiplePropertyEditorSupport.cs +++ /dev/null @@ -1,34 +0,0 @@ -using jcdcdev.Umbraco.ReadingTime.Core; -using Umbraco.Cms.Infrastructure.Migrations; - -namespace jcdcdev.Umbraco.ReadingTime.Infrastructure.Migrations; - -public class MultiplePropertyEditorSupport : MigrationBase -{ - public MultiplePropertyEditorSupport(IMigrationContext context) : base(context) - { - } - - protected override void Migrate() - { - if (!ColumnExists(Constants.TableName, "dataTypeId")) - { - Alter.Table(Constants.TableName) - .AddColumn("dataTypeId") - .AsInt32() - .ForeignKey(global::Umbraco.Cms.Core.Constants.DatabaseSchema.Tables.Node, "id") - .NotNullable() - .Do(); - } - - if (!ColumnExists(Constants.TableName, "dataTypeKey")) - { - Alter.Table(Constants.TableName) - .AddColumn("dataTypeKey") - .AsInt32() - .ForeignKey(global::Umbraco.Cms.Core.Constants.DatabaseSchema.Tables.Node, "uniqueId") - .NotNullable() - .Do(); - } - } -} diff --git a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.3.0/MultiplePropertyEditorSupport.cs b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.3.0/MultiplePropertyEditorSupport.cs new file mode 100644 index 0000000..3728ec4 --- /dev/null +++ b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.3.0/MultiplePropertyEditorSupport.cs @@ -0,0 +1,10 @@ +using Umbraco.Cms.Infrastructure.Migrations; + +namespace jcdcdev.Umbraco.ReadingTime.Infrastructure.Migrations; + +public class MultiplePropertyEditorSupport : NoopMigration +{ + public MultiplePropertyEditorSupport(IMigrationContext context) : base(context) + { + } +} diff --git a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.3.1/RebuildDatabase.cs b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.3.1/RebuildDatabase.cs new file mode 100644 index 0000000..0a2823d --- /dev/null +++ b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/0.3.1/RebuildDatabase.cs @@ -0,0 +1,30 @@ +using jcdcdev.Umbraco.ReadingTime.Core; +using jcdcdev.Umbraco.ReadingTime.Infrastructure.Persistence; +using Microsoft.Extensions.Logging; +using Umbraco.Cms.Infrastructure.Migrations; + +namespace jcdcdev.Umbraco.ReadingTime.Infrastructure.Migrations; + +public class RebuildDatabase : MigrationBase +{ + private readonly IReadingTimeService _readingTimeService; + + public RebuildDatabase(IMigrationContext context, IReadingTimeService readingTimeService) : base(context) + { + _readingTimeService = readingTimeService; + } + + protected override void Migrate() + { + Logger.LogInformation("Rebuilding ReadingTime database"); + if (TableExists(Constants.TableName)) + { + Delete.ForeignKey("FK_jcdcdevReadingTime_umbracoNode_uniqueId").OnTable(Constants.TableName).Do(); + Delete.Table(Constants.TableName).Do(); + } + + Create.Table().Do(); + + _readingTimeService.ScanAll(); + } +} diff --git a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/InitialMigration.cs b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/InitialMigration.cs deleted file mode 100644 index 51ed8ba..0000000 --- a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/InitialMigration.cs +++ /dev/null @@ -1,22 +0,0 @@ -using jcdcdev.Umbraco.ReadingTime.Core; -using jcdcdev.Umbraco.ReadingTime.Infrastructure.Persistence; -using Umbraco.Cms.Infrastructure.Migrations; - -namespace jcdcdev.Umbraco.ReadingTime.Infrastructure.Migrations; - -public class InitialMigration : MigrationBase -{ - public InitialMigration(IMigrationContext context) : base(context) - { - } - - protected override void Migrate() - { - if (TableExists(Constants.TableName)) - { - Delete.Table(Constants.TableName).Do(); - } - - Create.Table().Do(); - } -} diff --git a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/MigrationPlan.cs b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/MigrationPlan.cs index d4e0d1d..bba9752 100644 --- a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/MigrationPlan.cs +++ b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Migrations/MigrationPlan.cs @@ -1,5 +1,6 @@ using jcdcdev.Umbraco.ReadingTime.Core; using Umbraco.Cms.Core.Packaging; +using Umbraco.Cms.Infrastructure.Migrations; namespace jcdcdev.Umbraco.ReadingTime.Infrastructure.Migrations; @@ -12,7 +13,13 @@ public MigrationPlan() : base(Constants.Package.Name) protected override void DefinePlan() { From(string.Empty); - To(nameof(InitialMigration)); - To(nameof(MultiplePropertyEditorSupport)); + To(); + To(); + To(); + } + + private void To() where T : MigrationBase + { + To(typeof(T).Name); } } diff --git a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Persistence/ReadingTimePoco.cs b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Persistence/ReadingTimePoco.cs index 8970621..8a40cf5 100644 --- a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Persistence/ReadingTimePoco.cs +++ b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/Persistence/ReadingTimePoco.cs @@ -15,12 +15,12 @@ public class ReadingTimePoco public int Id { get; set; } [Column(Name = "key")] - [ForeignKey(typeof(NodeDto), Column = "uniqueId")] + [ForeignKey(typeof(NodeDto), Column = "uniqueId", Name = "FK_jcdcdevReadingTime_content_umbracoNode_uniqueId")] [NullSetting(NullSetting = NullSettings.NotNull)] public Guid Key { get; set; } [Column(Name = "dataTypeKey")] - [ForeignKey(typeof(NodeDto), Column = "uniqueId")] + [ForeignKey(typeof(NodeDto), Column = "uniqueId", Name = "FK_jcdcdevReadingTime_dataTypeKey_umbracoNode_uniqueId")] [NullSetting(NullSetting = NullSettings.NotNull)] public Guid DataTypeKey { get; set; } @@ -30,7 +30,7 @@ public class ReadingTimePoco public string? TextData { get; set; } [Column(Name = "dataTypeId")] - [ForeignKey(typeof(NodeDto), Column = "id")] + [ForeignKey(typeof(NodeDto), Column = "id", Name = "FK_jcdcdevReadingTime_dataTypeId_umbracoNode_uniqueId")] [NullSetting(NullSetting = NullSettings.NotNull)] public int DataTypeId { get; set; } } diff --git a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/ReadingTimeService.cs b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/ReadingTimeService.cs index cf04b32..890596c 100644 --- a/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/ReadingTimeService.cs +++ b/src/jcdcdev.Umbraco.ReadingTime/Infrastructure/ReadingTimeService.cs @@ -3,6 +3,7 @@ using jcdcdev.Umbraco.ReadingTime.Core.Models; using jcdcdev.Umbraco.ReadingTime.Core.PropertyEditors; using jcdcdev.Umbraco.ReadingTime.Infrastructure.Persistence; +using Microsoft.Extensions.Logging; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services; using Umbraco.Extensions; @@ -15,29 +16,38 @@ public class ReadingTimeService : IReadingTimeService private readonly ReadingTimeValueProviderCollection _convertors; private readonly IDataTypeService _dataTypeService; private readonly IReadingTimeRepository _readingTimeRepository; + private readonly ILogger _logger; public ReadingTimeService( IContentService contentService, ReadingTimeValueProviderCollection convertors, IReadingTimeRepository readingTimeRepository, - IDataTypeService dataTypeService) + IDataTypeService dataTypeService, + ILogger logger) { _contentService = contentService; _convertors = convertors; _readingTimeRepository = readingTimeRepository; _dataTypeService = dataTypeService; + _logger = logger; } public async Task GetAsync(Guid key, Guid dataTypeKey) => await _readingTimeRepository.Get(key, dataTypeKey); + public async Task GetAsync(Guid key, int dataTypeId) => await _readingTimeRepository.Get(key, dataTypeId); - public async Task DeleteAsync(Guid key) => await _readingTimeRepository.DeleteAsync(key); + public async Task DeleteAsync(Guid key) + { + _logger.LogDebug("Deleting reading time for {Key}", key); + return await _readingTimeRepository.DeleteAsync(key); + } public async Task ScanTree(int homeId) { var content = _contentService.GetById(homeId); if (content == null) { + _logger.LogWarning("Content with id {HomeId} not found", homeId); return; } @@ -63,7 +73,20 @@ public async Task ScanTree(int homeId) moreRecords = (page + 1) * 100 <= totalRecords; } - await Process(current); + if (current.Published) + { + await Process(current); + } + } + } + + public async Task ScanAll() + { + var root = _contentService.GetRootContent().ToList(); + _logger.LogInformation("Scanning {Count} root content items", root.Count); + foreach (var content in root) + { + await ScanTree(content.Id); } } @@ -75,6 +98,7 @@ public async Task Process(IContent item) return; } + _logger.LogDebug("Processing {Id}:{Item}", item.Id, item.Name); foreach (var property in props) { await ProcessPropertyEditor(item, property); @@ -86,12 +110,14 @@ private async Task ProcessPropertyEditor(IContent item, IProperty readingTimePro var dataType = _dataTypeService.GetDataType(readingTimeProperty.PropertyType.DataTypeId); if (dataType == null) { + _logger.LogWarning("DataType not found for property {PropertyId}", readingTimeProperty.Id); return; } var config = dataType.ConfigurationAs(); if (config == null) { + _logger.LogWarning("Configuration not found for property {PropertyId}", readingTimeProperty.Id); return; } @@ -100,13 +126,16 @@ private async Task ProcessPropertyEditor(IContent item, IProperty readingTimePro var propertyType = readingTimeProperty.PropertyType; if (propertyType.VariesByCulture()) { + _logger.LogDebug("Processing culture variants for {Id}:{Item}", item.Id, item.Name); foreach (var culture in item.AvailableCultures) { + _logger.LogDebug("Processing culture {Culture}", culture); var model = GetModel(item, culture, null, config); models.Add(model); } } + _logger.LogDebug("Processing invariant variant for {Id}:{Item}", item.Id, item.Name); var invariant = GetModel(item, null, null, config); models.Add(invariant); @@ -134,14 +163,24 @@ private ReadingTimeVariantDto GetModel(IContent item, string? culture, string? s foreach (var property in item.Properties) { var convertor = _convertors.FirstOrDefault(x => x.CanConvert(property.PropertyType)); + if (convertor == null) + { + _logger.LogDebug("No convertor found for {PropertyId}:{PropertyEditorAlias}", property.Id, property.PropertyType.PropertyEditorAlias); + continue; + } + + _logger.LogDebug("Processing property {PropertyId}:{PropertyEditorAlias}", property.Id, property.PropertyType.PropertyEditorAlias); + var cCulture = property.PropertyType.VariesByCulture() ? culture : null; var cSegment = property.PropertyType.VariesBySegment() ? segment : null; var readingTime = convertor?.GetReadingTime(property, cCulture, cSegment, item.AvailableCultures, config); if (!readingTime.HasValue) { + _logger.LogDebug("No reading time found for {PropertyId}:{PropertyEditorAlias}", property.Id, property.PropertyType.PropertyEditorAlias); continue; } + _logger.LogDebug("Reading time found for {PropertyId}:{PropertyEditorAlias} ({Time})", property.Id, property.PropertyType.PropertyEditorAlias, readingTime.Value); time += readingTime.Value; } diff --git a/src/jcdcdev.Umbraco.ReadingTime/ManifestFilter.cs b/src/jcdcdev.Umbraco.ReadingTime/ManifestFilter.cs index cdbe999..8555715 100644 --- a/src/jcdcdev.Umbraco.ReadingTime/ManifestFilter.cs +++ b/src/jcdcdev.Umbraco.ReadingTime/ManifestFilter.cs @@ -1,3 +1,4 @@ +using jcdcdev.Umbraco.ReadingTime.Core; using Umbraco.Cms.Core.Manifest; namespace jcdcdev.Umbraco.ReadingTime; @@ -8,7 +9,7 @@ public void Filter(List manifests) { manifests.Add(new PackageManifest { - PackageName = "jcdcdev.Umbraco.ReadingTime", + PackageName = Constants.Package.Name, Version = GetType().Assembly.GetName().Version?.ToString(3) ?? "0.1.0", AllowPackageTelemetry = true });