From 8cdd19b934b34810967576992a771f657748a8fe Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 10 Mar 2020 17:22:28 +0300 Subject: [PATCH] Docs Update label improvements --- .../Volo/Docs/Documents/DocumentAppService.cs | 16 +++-- .../Volo/Docs/Documents/DocumentUpdateInfo.cs | 4 ++ .../Volo/Docs/Documents/NavigationNode.cs | 2 + .../Volo/Docs/Documents/Document.cs | 6 +- .../Volo/Docs/Documents/IDocumentSource.cs | 3 +- .../Documents/FileSystemDocumentSource.cs | 2 +- .../GitHub/Documents/GithubDocumentSource.cs | 33 +++++++-- .../GitHub/Documents/GithubPatchAnalyzer.cs | 68 +++++++++++++++++++ .../GitHub/Documents/IGithubPatchAnalyzer.cs | 12 ++++ .../Projects/ProjectGithubExtensions.cs | 6 ++ .../Documents/TagHelpers/TreeTagHelper.cs | 12 ++-- 11 files changed, 146 insertions(+), 18 deletions(-) create mode 100644 modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubPatchAnalyzer.cs create mode 100644 modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/IGithubPatchAnalyzer.cs diff --git a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs index 342130d530..7c8ee03997 100644 --- a/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs +++ b/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs @@ -96,6 +96,7 @@ namespace Volo.Docs.Documents { leaf.CreationTime = documentUpdateInfo.CreationTime; leaf.LastUpdatedTime = documentUpdateInfo.LastUpdatedTime; + leaf.LastSignificantUpdateTime = documentUpdateInfo.LastSignificantUpdateTime; } } @@ -189,12 +190,12 @@ namespace Volo.Docs.Documents { version = string.IsNullOrWhiteSpace(version) ? project.LatestVersionBranchName : version; - async Task GetDocumentAsync() + async Task GetDocumentAsync(Document oldDocument = null) { Logger.LogInformation($"Not found in the cache. Requesting {documentName} from the source..."); var source = _documentStoreFactory.Create(project.DocumentStoreType); - var sourceDocument = await source.GetDocumentAsync(project, documentName, languageCode, version); + var sourceDocument = await source.GetDocumentAsync(project, documentName, languageCode, version, oldDocument?.LastSignificantUpdateTime); await _documentRepository.DeleteAsync(project.Id, sourceDocument.Name, sourceDocument.LanguageCode, sourceDocument.Version); await _documentRepository.InsertAsync(sourceDocument, true); @@ -206,7 +207,8 @@ namespace Volo.Docs.Documents { Name = sourceDocument.Name, CreationTime = sourceDocument.CreationTime, - LastUpdatedTime = sourceDocument.LastUpdatedTime + LastUpdatedTime = sourceDocument.LastUpdatedTime, + LastSignificantUpdateTime = sourceDocument.LastSignificantUpdateTime }); return CreateDocumentWithDetailsDto(project, sourceDocument); @@ -229,7 +231,7 @@ namespace Volo.Docs.Documents //TODO: Configurable cache time? document.LastCachedTime + TimeSpan.FromHours(2) < DateTime.Now) { - return await GetDocumentAsync(); + return await GetDocumentAsync(document); } var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}"; @@ -238,11 +240,17 @@ namespace Volo.Docs.Documents Name = document.Name, CreationTime = document.CreationTime, LastUpdatedTime = document.LastUpdatedTime, + LastSignificantUpdateTime = document.LastSignificantUpdateTime }); return CreateDocumentWithDetailsDto(project, document); } + private bool DoesDocuemntHasSignificantUpdates(Document sourceDocument, Document oldDocument) + { + throw new NotImplementedException(); + } + protected virtual DocumentWithDetailsDto CreateDocumentWithDetailsDto(Project project, Document document) { var documentDto = ObjectMapper.Map(document); diff --git a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/DocumentUpdateInfo.cs b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/DocumentUpdateInfo.cs index fcabe91549..fd330d9b45 100644 --- a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/DocumentUpdateInfo.cs +++ b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/DocumentUpdateInfo.cs @@ -10,5 +10,9 @@ namespace Volo.Docs.Documents public virtual DateTime CreationTime { get; set; } public virtual DateTime LastUpdatedTime { get; set; } + + public virtual bool HasSignificantUpdates { get; set; } + + public DateTime? LastSignificantUpdateTime { get; set; } } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs index b5c2704eb8..9e54e72be5 100644 --- a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs +++ b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs @@ -26,6 +26,8 @@ namespace Volo.Docs.Documents public virtual DateTime? LastUpdatedTime { get; set; } + public DateTime? LastSignificantUpdateTime { get; set; } + public bool IsSelected(string documentName) { if (documentName == null) diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/Document.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/Document.cs index ecbc3aa617..ee8710bff3 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/Document.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/Document.cs @@ -34,6 +34,8 @@ namespace Volo.Docs.Documents public virtual DateTime CreationTime { get; set; } public virtual DateTime LastUpdatedTime { get; set; } + + public virtual DateTime? LastSignificantUpdateTime { get; set; } public virtual DateTime LastCachedTime { get; set; } @@ -60,7 +62,8 @@ namespace Volo.Docs.Documents [NotNull] string localDirectory, DateTime creationTime, DateTime lastUpdatedTime, - DateTime lastCachedTime + DateTime lastCachedTime, + DateTime? lastSignificantUpdateTime = null ) { Id = id; @@ -80,6 +83,7 @@ namespace Volo.Docs.Documents CreationTime = creationTime; LastUpdatedTime = lastUpdatedTime; LastCachedTime = lastCachedTime; + LastSignificantUpdateTime = lastSignificantUpdateTime; Contributors = new List(); ExtraProperties = new Dictionary(); diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentSource.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentSource.cs index e9d2779bd3..4afe789d37 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentSource.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentSource.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Domain.Services; @@ -8,7 +9,7 @@ namespace Volo.Docs.Documents { public interface IDocumentSource : IDomainService { - Task GetDocumentAsync(Project project, string documentName, string languageCode, string version); + Task GetDocumentAsync(Project project, string documentName, string languageCode, string version, DateTime? lastKnownSignificantUpdateTime = null); Task> GetVersionsAsync(Project project); diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentSource.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentSource.cs index d93b378dcd..3fa341a848 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentSource.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentSource.cs @@ -16,7 +16,7 @@ namespace Volo.Docs.FileSystem.Documents { public const string Type = "FileSystem"; - public async Task GetDocumentAsync(Project project, string documentName, string languageCode, string version) + public async Task GetDocumentAsync(Project project, string documentName, string languageCode, string version, DateTime? lastKnownSignificantUpdateTime = null) { var projectFolder = project.GetFileSystemPath(); var path = Path.Combine(projectFolder, languageCode, documentName); diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs index 0c837991d1..ea5dc776a4 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs @@ -21,13 +21,15 @@ namespace Volo.Docs.GitHub.Documents public const string Type = "GitHub"; private readonly IGithubRepositoryManager _githubRepositoryManager; + private readonly IGithubPatchAnalyzer _githubPatchAnalyzer; - public GithubDocumentSource(IGithubRepositoryManager githubRepositoryManager) + public GithubDocumentSource(IGithubRepositoryManager githubRepositoryManager, IGithubPatchAnalyzer githubPatchAnalyzer) { _githubRepositoryManager = githubRepositoryManager; + _githubPatchAnalyzer = githubPatchAnalyzer; } - public virtual async Task GetDocumentAsync(Project project, string documentName, string languageCode, string version) + public virtual async Task GetDocumentAsync(Project project, string documentName, string languageCode, string version, DateTime? lastKnownSignificantUpdateTime = null) { var token = project.GetGitHubAccessTokenOrNull(); var rootUrl = project.GetGitHubUrl(version); @@ -46,7 +48,9 @@ namespace Volo.Docs.GitHub.Documents fileName = documentName.Substring(documentName.LastIndexOf('/') + 1); } - var fileCommits = await GetFileCommitsAsync(project, version, $"docs/{languageCode}/{documentName}"); + var fileCommits = await GetFileCommitsAsync(project, version, project.GetGitHubInnerUrl(languageCode, documentName)); + + var documentCreationTime = fileCommits.LastOrDefault()?.Commit.Author.Date.DateTime ?? DateTime.MinValue; var document= new Document(GuidGenerator.Create(), project.Id, @@ -60,9 +64,10 @@ namespace Volo.Docs.GitHub.Documents rootUrl, rawRootUrl, localDirectory, - fileCommits.LastOrDefault()?.Commit.Author.Date.DateTime ?? DateTime.MinValue, + documentCreationTime, fileCommits.FirstOrDefault()?.Commit.Author.Date.DateTime ?? DateTime.MinValue, - DateTime.Now); + DateTime.Now, + GetLastSignificantUpdateTime(fileCommits, project.GetGitHubInnerUrl(languageCode, documentName), lastKnownSignificantUpdateTime, documentCreationTime) ?? lastKnownSignificantUpdateTime); var authors = fileCommits .Where(x => x.Author != null) @@ -82,6 +87,24 @@ namespace Volo.Docs.GitHub.Documents return document; } + private DateTime? GetLastSignificantUpdateTime(IReadOnlyList fileCommits, string fileName, + DateTime? lastKnownSignificantUpdateTime, DateTime documentCreationTime) + { + var commitsToEvaluate = (lastKnownSignificantUpdateTime != null + ? fileCommits.Where(c => c.Commit.Author.Date.DateTime > lastKnownSignificantUpdateTime) + :fileCommits).Where(c=>c.Commit.Author.Date.DateTime > DateTime.Now.AddDays(-14) && c.Commit.Author.Date.DateTime > documentCreationTime); + + foreach (var gitHubCommit in commitsToEvaluate) + { + if (_githubPatchAnalyzer.HasPatchSignificantChanges(gitHubCommit.Files.First(f=>f.Filename == fileName).Patch)) + { + return gitHubCommit.Commit.Author.Date.DateTime; + } + } + + return null; + } + public async Task> GetVersionsAsync(Project project) { List versions; diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubPatchAnalyzer.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubPatchAnalyzer.cs new file mode 100644 index 0000000000..8ed8dff0e6 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubPatchAnalyzer.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Volo.Abp.Domain.Services; + +namespace Volo.Docs.GitHub.Documents +{ + public class GithubPatchAnalyzer : DomainService, IGithubPatchAnalyzer + { + private const string OldChangeStart = "\\n-"; + private const string NewChangeStart = "\\n+"; + + public bool HasPatchSignificantChanges(string patch) + { + var changes = GetChanges(patch); + + foreach (var change in changes) + { + var isSignificant = IsChangeSignificant(change); + + if (isSignificant) + { + return true; + } + } + + return false; + } + + private bool IsChangeSignificant(CommitChanges change) + { + throw new NotImplementedException(); + } + + private List GetChanges(string patch) + { + var changes = new List(); + var changeList = patch.Split("@@").Where(s => !string.IsNullOrWhiteSpace(s)).Where((c, i) => i % 2 == 0).ToList(); + + foreach (var change in changeList) + { + var commitChange = new CommitChanges(); + var lines = change.Split("\\n"); + + commitChange.OldLines.AddRange(lines.Where(l => l.StartsWith("-")).Select(l => l.Substring(1)).Where(l => !string.IsNullOrWhiteSpace(l))); + commitChange.NewLines.AddRange(lines.Where(l => l.StartsWith("+")).Select(l => l.Substring(1)).Where(l=>!string.IsNullOrWhiteSpace(l))); + + changes.Add(commitChange); + } + + return changes; + } + + private class CommitChanges + { + public List OldLines { get; set; } + + public List NewLines { get; set; } + + public CommitChanges() + { + OldLines = new List(); + NewLines= new List(); + } + } + } +} diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/IGithubPatchAnalyzer.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/IGithubPatchAnalyzer.cs new file mode 100644 index 0000000000..da57fe4c9f --- /dev/null +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/IGithubPatchAnalyzer.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.Domain.Services; + +namespace Volo.Docs.GitHub.Documents +{ + public interface IGithubPatchAnalyzer : IDomainService + { + bool HasPatchSignificantChanges(string patch); + } +} diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Projects/ProjectGithubExtensions.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Projects/ProjectGithubExtensions.cs index d518132950..4810f94ac4 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Projects/ProjectGithubExtensions.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Projects/ProjectGithubExtensions.cs @@ -14,6 +14,12 @@ namespace Volo.Docs.GitHub.Projects return project.ExtraProperties["GitHubRootUrl"] as string; } + public static string GetGitHubInnerUrl([NotNull] this Project project, string languageCode, string documentName) + { + return project + .GetGitHubUrl().Split("{version}")[1].EnsureEndsWith('/').TrimStart('/') + languageCode + '/' + documentName; + } + public static string GetGitHubUrl([NotNull] this Project project, string version) { return project diff --git a/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs b/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs index 1c57191d0a..5f7ae8e7a7 100644 --- a/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs +++ b/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs @@ -127,16 +127,16 @@ namespace Volo.Docs.Areas.Documents.TagHelpers if (!node.Path.IsNullOrWhiteSpace() && node.CreationTime.HasValue && node.LastUpdatedTime.HasValue) { - var newBadge = "" + _localizer["New"] + ""; - var updBadge = "" + _localizer["Upd"] + ""; - if(node.CreationTime + TimeSpan.FromDays(14) > DateTime.Now) { - badge = newBadge; + var newBadge = "" + _localizer["New"] + ""; + badge += newBadge; } - else if (node.LastUpdatedTime + TimeSpan.FromDays(14) > DateTime.Now) + + if (node.LastSignificantUpdateTime != null && node.LastSignificantUpdateTime + TimeSpan.FromDays(14) > DateTime.Now) { - badge = updBadge; + var updBadge = "" + _localizer["Upd"] + ""; + badge += updBadge; } }