From b7c39bc9c9116945b3ee9288351d6be0b1d6a0a1 Mon Sep 17 00:00:00 2001 From: Anders Bjerner Date: Tue, 27 Nov 2018 23:35:18 +0100 Subject: [PATCH] Updated the way an "Issue" is loaded/deserialized - The RepositoryManagementService and Issue now relies on manual parsing the JSON, as this gives us some more control - As a result of above, Issue is now mostly just a wrapper for GitHubIssue from my GitHub package (means less logic for us to handle in this repo) - Comments and Events are now lazy loaded as we may not always need them - Added new PullRequest class, which is currently just an empty class inheriting from the Issue class --- OurUmbraco.Site/Views/Dashboard.cshtml | 2 +- .../Our/Api/IssuesStatisticsController.cs | 9 +-- OurUmbraco/Our/Models/GitHub/Issue.cs | 67 ++++++++++--------- OurUmbraco/Our/Models/GitHub/PullRequest.cs | 22 ++++++ OurUmbraco/Our/Services/ReleasesService.cs | 3 +- .../Services/RepositoryManagementService.cs | 13 ++-- OurUmbraco/OurUmbraco.csproj | 1 + 7 files changed, 74 insertions(+), 43 deletions(-) create mode 100644 OurUmbraco/Our/Models/GitHub/PullRequest.cs diff --git a/OurUmbraco.Site/Views/Dashboard.cshtml b/OurUmbraco.Site/Views/Dashboard.cshtml index 526506e9e8..c20b332e70 100644 --- a/OurUmbraco.Site/Views/Dashboard.cshtml +++ b/OurUmbraco.Site/Views/Dashboard.cshtml @@ -260,7 +260,7 @@ @{ var dateCssClass = string.Empty; - var businessDays = issue.CreateDateTime.ToLocalTime().BusinessDaysSince(); + var businessDays = issue.CreateDateTime.ToLocalTime().DateTime.BusinessDaysSince(); } @if (category.CategoryKey == RepositoryManagementService.CategoryKey.NoReply) { diff --git a/OurUmbraco/Our/Api/IssuesStatisticsController.cs b/OurUmbraco/Our/Api/IssuesStatisticsController.cs index 26729b4da3..77eff2d9aa 100644 --- a/OurUmbraco/Our/Api/IssuesStatisticsController.cs +++ b/OurUmbraco/Our/Api/IssuesStatisticsController.cs @@ -6,6 +6,7 @@ using OurUmbraco.Our.Extensions; using OurUmbraco.Our.Models; using OurUmbraco.Our.Services; +using Skybrud.Social.GitHub.Models.Issues; using Umbraco.Web.WebApi; namespace OurUmbraco.Our.Api @@ -58,24 +59,24 @@ public List GetGroupedIssuesData(int fromDay, int fromMonth, int foreach (var issue in allCommunityIssues) { - if (issue.CreateDateTime <= periodLastDay && issue.State != "closed") + if (issue.CreateDateTime <= periodLastDay && issue.State != GitHubIssueState.Closed) issuesList.NumberOpen = issuesList.NumberOpen + 1; } var allClosingTimesInHours = new List(); foreach (var issue in issuesInPeriod.Value) { - if (issue.State == "closed" && issue.ClosedDateTime.HasValue) + if (issue.State == GitHubIssueState.Closed && issue.ClosedDateTime != null) { var createDateTime = issue.CreateDateTime; - var closedDateTime = issue.ClosedDateTime.Value; + var closedDateTime = issue.ClosedDateTime; if (closedDateTime < periodFirstDay || closedDateTime > periodLastDay) continue; issuesList.NumberClosed = issuesList.NumberClosed + 1; - var hoursOpen = createDateTime.BusinessHoursUntil(closedDateTime); + var hoursOpen = createDateTime.DateTime.BusinessHoursUntil(closedDateTime.DateTime); allClosingTimesInHours.Add(hoursOpen); } } diff --git a/OurUmbraco/Our/Models/GitHub/Issue.cs b/OurUmbraco/Our/Models/GitHub/Issue.cs index 4c76577c5c..5a7c6eceef 100644 --- a/OurUmbraco/Our/Models/GitHub/Issue.cs +++ b/OurUmbraco/Our/Models/GitHub/Issue.cs @@ -1,61 +1,64 @@ using System; -using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Skybrud.Essentials.Time; +using Skybrud.Social.GitHub.Models.Issues; +using Skybrud.Social.GitHub.Models.Labels; +using Skybrud.Social.GitHub.Models.Users; namespace OurUmbraco.Our.Models.GitHub { public class Issue { - [JsonProperty("html_url")] - public string Link { get; set; } - [JsonProperty("number")] - public int Number { get; set; } + private readonly GitHubIssue _issue; + private Comments[] _comments; + private Event[] _events; - [JsonProperty("title")] - public string Title { get; set; } + public string Link => _issue.Urls.HtmlUrl; - [JsonProperty("user")] - public User User { get; set; } + public int Number => _issue.Number; - [JsonProperty("labels")] - public Label[] Labels { get; set; } + public string Title => _issue.Title; - [JsonProperty("state")] - public string State { get; set; } + public GitHubUserItem User => _issue.User; - [JsonProperty("assignees")] - public User[] Assignees { get; set; } + public GitHubLabel[] Labels => _issue.Labels; - [JsonProperty("comments")] - public int CommentCount { get; set; } + public GitHubIssueState State => _issue.State; - [JsonProperty("created_at")] - public DateTime CreateDateTime { get; set; } + public GitHubUserItem[] Assignees => _issue.Assignees; - [JsonProperty("updated_at")] - public DateTime UpdateDateTime { get; set; } + public int CommentCount => _issue.Comments; - [JsonProperty("closed_at")] - public DateTime? ClosedDateTime { get; set; } + public EssentialsDateTime CreateDateTime => _issue.CreatedAt; - [JsonProperty("body")] - public string Description { get; set; } + public EssentialsDateTime UpdateDateTime => _issue.UpdatedAt; - [JsonProperty("_comments")] - public Comments[] Comments { get; set; } + public EssentialsDateTime ClosedDateTime => _issue.ClosedAt; - [JsonProperty("events")] - public Event[] Events { get; set; } + public string Description => _issue.Body; + + public Comments[] Comments => _comments ?? (_comments = _issue.JObject.Value("comments")); + + public Event[] Events => _events ?? (_events = _issue.JObject.Value("events")); // Custom properties - public string RepositoryName { get; set; } + public string RepositoryName => Link.Split('/')[4]; public DateTime? FirstPrTeamOrHqComment { get; set; } public DateTime? InThisCategorySince { get; set; } public bool NeedsTeamUmbracoReply { get; set; } + + protected Issue(JObject obj) { + _issue = GitHubIssue.Parse(obj); + } + + public static Issue Parse(JObject obj) { + return obj == null ? null : new Issue(obj); + } // Note: leaving the other properties commented out in case we need them later @@ -69,5 +72,7 @@ public class Issue //public User assignee { get; set; } //public object milestone { get; set; } //public string author_association { get; set; } + } -} + +} \ No newline at end of file diff --git a/OurUmbraco/Our/Models/GitHub/PullRequest.cs b/OurUmbraco/Our/Models/GitHub/PullRequest.cs new file mode 100644 index 0000000000..d4c3b5b317 --- /dev/null +++ b/OurUmbraco/Our/Models/GitHub/PullRequest.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json.Linq; + +namespace OurUmbraco.Our.Models.GitHub +{ + + public class PullRequest : Issue + { + + public PullRequest(JObject obj) : base(obj) + { + + + } + + public new static PullRequest Parse(JObject obj) + { + return obj == null ? null : new PullRequest(obj); + } + + } + +} \ No newline at end of file diff --git a/OurUmbraco/Our/Services/ReleasesService.cs b/OurUmbraco/Our/Services/ReleasesService.cs index cbff3d244e..3c31a34966 100644 --- a/OurUmbraco/Our/Services/ReleasesService.cs +++ b/OurUmbraco/Our/Services/ReleasesService.cs @@ -13,6 +13,7 @@ using OurUmbraco.Our.Extensions; using OurUmbraco.Our.Models; using OurUmbraco.Our.Models.GitHub; +using Skybrud.Social.GitHub.Models.Issues; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Web; @@ -205,7 +206,7 @@ private static void AddItemsToReleases(PerformContext context, List rel if (stateLabel != null) // if there's a label with a state then use that as the state state = stateLabel.Name.Replace("state/", string.Empty); - else if (item.State == "closed" && item.Labels.Any(x => x.Name.StartsWith("release"))) + else if (item.State == GitHubIssueState.Closed && item.Labels.Any(x => x.Name.StartsWith("release"))) // there is no state label applied // if the item is closed and has a release label on it then we set it to fixed state = "fixed"; diff --git a/OurUmbraco/Our/Services/RepositoryManagementService.cs b/OurUmbraco/Our/Services/RepositoryManagementService.cs index b605f31265..4a4baf2782 100644 --- a/OurUmbraco/Our/Services/RepositoryManagementService.cs +++ b/OurUmbraco/Our/Services/RepositoryManagementService.cs @@ -6,6 +6,9 @@ using Newtonsoft.Json; using OurUmbraco.Community.GitHub; using OurUmbraco.Our.Models.GitHub; +using Skybrud.Essentials.Json; +using Skybrud.Social.GitHub.Models.Issues; +using Skybrud.Social.GitHub.Models.Labels; using Umbraco.Core; namespace OurUmbraco.Our.Services @@ -44,15 +47,13 @@ public List GetAllCommunityIssues(bool pulls) foreach (var file in issueFiles) { - var fileContent = File.ReadAllText(file); - var item = JsonConvert.DeserializeObject(fileContent); + + Issue item = pulls ? JsonUtils.LoadJsonObject(file, PullRequest.Parse) : JsonUtils.LoadJsonObject(file, Issue.Parse); // Exclude issues created by HQ if (hqMembers.Contains(item.User.Login.ToLowerInvariant())) continue; - item.RepositoryName = repositoryName; - foreach (var comment in item.Comments) { var commenter = comment.User.Login.ToLowerInvariant(); @@ -101,7 +102,7 @@ public List GetAllOpenIssues(bool pulls) foreach (var item in allIssues) { - if (item.State == "closed") + if (item.State == GitHubIssueState.Closed) continue; var pullRequestService = new GitHubService(); @@ -223,7 +224,7 @@ public List GetAllOpenIssues(bool pulls) return openIssues.OrderBy(x => x.SortOrder).ToList(); } - private static void AddCategoryCreatedDate(Issue item, Models.GitHub.Label label, string[] labelNames) + private static void AddCategoryCreatedDate(Issue item, GitHubLabel label, string[] labelNames) { if (item.Events != null) { diff --git a/OurUmbraco/OurUmbraco.csproj b/OurUmbraco/OurUmbraco.csproj index b86cff6141..d01af3e5e2 100644 --- a/OurUmbraco/OurUmbraco.csproj +++ b/OurUmbraco/OurUmbraco.csproj @@ -510,6 +510,7 @@ +