From c1997c11dbf4b006a3865162cb576653bc666d6f Mon Sep 17 00:00:00 2001 From: JasonMulligan Date: Fri, 6 Mar 2020 17:11:58 -0500 Subject: [PATCH] Fix: Trello limit constraints --- Constants/SolutionConstants.cs | 1 + Models/TrelloActionDto.cs | 13 +++ Models/TrelloCardDto.cs | 14 ++++ Services/TrelloService.cs | 148 +++++++++++++++++++++++++++------ 4 files changed, 151 insertions(+), 25 deletions(-) diff --git a/Constants/SolutionConstants.cs b/Constants/SolutionConstants.cs index 31cb9b0..91cdc47 100644 --- a/Constants/SolutionConstants.cs +++ b/Constants/SolutionConstants.cs @@ -67,6 +67,7 @@ public static class TrelloListIndexMap public const string kTrelloUserSecret = "861101898508498761cd2952b258926b568326994f44ef23fd85ca3685667525"; public const string kTrelloUserToken = "9a4b5cc8411e7380cf8fc392341f118e2f32869ac50a134fb9bd81f43fb0fe62"; public const string kTrelloBoardId = "5cdf08913ae8753993cfdd9c"; + public const int kTrelloLimitMax = 1000; public const string kLabelSeperator = ":"; diff --git a/Models/TrelloActionDto.cs b/Models/TrelloActionDto.cs index ddc790f..2ea32c6 100644 --- a/Models/TrelloActionDto.cs +++ b/Models/TrelloActionDto.cs @@ -10,6 +10,19 @@ public class TrelloActionDto public TrelloActionDataDto data { get; set; } + public DateTime DateFromId + { + get + { + var timestamp = int.Parse(this.id.Substring(0, 8), System.Globalization.NumberStyles.HexNumber); + + var dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(timestamp); + + return dateTimeOffset.UtcDateTime; + } + } + + public TrelloActionDto() { data = new TrelloActionDataDto(); diff --git a/Models/TrelloCardDto.cs b/Models/TrelloCardDto.cs index 4aebbc7..d8c79d6 100644 --- a/Models/TrelloCardDto.cs +++ b/Models/TrelloCardDto.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace esdc_sa_appdev_reporting_api.Models @@ -13,6 +14,19 @@ public class TrelloCardDto public List idMembers { get; set; } + public DateTime DateFromId + { + get + { + var timestamp = int.Parse(this.id.Substring(0, 8), System.Globalization.NumberStyles.HexNumber); + + var dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(timestamp); + + return dateTimeOffset.UtcDateTime; + } + } + + public TrelloCardDto() { idLabels = new List(); diff --git a/Services/TrelloService.cs b/Services/TrelloService.cs index 0cfbf6e..6533fa6 100644 --- a/Services/TrelloService.cs +++ b/Services/TrelloService.cs @@ -144,9 +144,9 @@ public async Task> GetGeneralReportResults() var trelloLists = await this.GetTrelloLists(); var trelloLabels = await this.GetTrelloLabels(); var trelloMembers = await this.GetTrelloMembers(); - var trelloCards = await this.GetTrelloCards(); - var trelloCardMoveActions = await this.GetTrelloCardMoveActions(); - var trelloCardCreatedActions = await this.GetTrelloCardCreateActions(); + var trelloCards = await this.GetAllTrelloCards(); + var trelloCardMoveActions = await this.GetAllTrelloCardMoveActions(); + var trelloCardCreatedActions = await this.GetAllTrelloCardCreateActions(); // Pre-sort trelloCardMoveActions @@ -264,7 +264,7 @@ public async Task> GetTrelloLists() Console.WriteLine($"Error in GetTrelloLists: {httpRequestException.Message}"); } - return null; + return new List(); } } @@ -293,7 +293,7 @@ public async Task> GetTrelloLabels() Console.WriteLine($"Error in GetTrelloLabels: {httpRequestException.Message}"); } - return null; + return new List(); } } @@ -321,12 +321,45 @@ public async Task> GetTrelloMembers() Console.WriteLine($"Error in GetTrelloMembers: {httpRequestException.Message}"); } - return null; + return new List(); } } - public async Task> GetTrelloCards() + public async Task> GetAllTrelloCards() + { + var trelloCards = new List(); + var beforeDate = DateTime.Now; + var isBreak = false; + + while (isBreak == false) + { + var results = await this.GetTrelloCards(beforeDate); + + if (results.Count < SolutionConstants.kTrelloLimitMax) + { + isBreak = true; + } + else + { + // Grab the earliest date of the results. + var dateMin = results.Min(x => x.DateFromId); + + // Because the earliest timestamp record may not necessarily be the last record within a given day, the target date is the last date + 1. + beforeDate = dateMin.AddDays(1).Date; + + // Only keep the results of the last known full day. + results = results.Where(x => x.DateFromId >= beforeDate).ToList(); + } + + trelloCards.AddRange(results); + } + + return trelloCards; + } + + + public async Task> GetTrelloCards(DateTime beforeDate) { using (var http = new HttpClient()) { @@ -334,7 +367,9 @@ public async Task> GetTrelloCards() { var url = "https://api.trello.com/1/boards/" + SolutionConstants.kTrelloBoardId + "/cards/" + "?key=" + SolutionConstants.kTrelloAppKey - + "&token=" + SolutionConstants.kTrelloUserToken; + + "&token=" + SolutionConstants.kTrelloUserToken + + "&before=" + beforeDate.ToString(CoreConstants.Formats.DtmZuluIso) + + "&limit=" + SolutionConstants.kTrelloLimitMax.ToString(); var response = await http.GetAsync(url); @@ -349,15 +384,47 @@ public async Task> GetTrelloCards() Console.WriteLine($"Error in GetTrelloCards: {httpRequestException.Message}"); } - return null; + return new List(); } } - public async Task> GetTrelloCardCreateActions() + public async Task> GetAllTrelloCardMoveActions() { - // Reference: https://stackoverflow.com/questions/51777063/how-can-i-get-all-actions-for-a-board-using-trellos-rest-api + var trelloActions = new List(); + var beforeDate = DateTime.Now; + var isBreak = false; + while (isBreak == false) + { + var results = await this.GetTrelloCardMoveActions(beforeDate); + + if (results.Count < SolutionConstants.kTrelloLimitMax) + { + isBreak = true; + } + else + { + // Grab the earliest date of the results. + var dateMin = results.Min(x => x.DateFromId); + + // Because the earliest timestamp record may not necessarily be the last record within a given day, the target date is the last date + 1. + beforeDate = dateMin.AddDays(1).Date; + + // Only keep the results of the last known full day. + results = results.Where(x => x.DateFromId >= beforeDate).ToList(); + } + + trelloActions.AddRange(results); + } + + // Only keep the records that where list transfers. + return trelloActions.Where(x => (x.IsListTransfer() == true)).ToList(); + } + + + public async Task> GetTrelloCardMoveActions(DateTime beforeDate) + { using (var http = new HttpClient()) { try @@ -365,10 +432,10 @@ public async Task> GetTrelloCardCreateActions() var url = "https://api.trello.com/1/boards/" + SolutionConstants.kTrelloBoardId + "/actions/" + "?key=" + SolutionConstants.kTrelloAppKey + "&token=" + SolutionConstants.kTrelloUserToken - //+ "&before=2019-07-01" + + "&filter=updateCard" //+ "&since=2019-06-01" - + "&filter=createCard" - + "&limit=1000"; + + "&before=" + beforeDate.ToString(CoreConstants.Formats.DtmZuluIso) + + "&limit=" + SolutionConstants.kTrelloLimitMax.ToString(); var response = await http.GetAsync(url); @@ -383,13 +450,48 @@ public async Task> GetTrelloCardCreateActions() Console.WriteLine($"Error in GetTrelloCardMoveActions: {httpRequestException.Message}"); } - return null; + return new List(); + } + } + + + public async Task> GetAllTrelloCardCreateActions() + { + var trelloActions = new List(); + var beforeDate = DateTime.Now; + var isBreak = false; + + while (isBreak == false) + { + var results = await this.GetTrelloCardCreateActions(beforeDate); + + if (results.Count < SolutionConstants.kTrelloLimitMax) + { + isBreak = true; + } + else + { + // Grab the earliest date of the results. + var dateMin = results.Min(x => x.DateFromId); + + // Because the earliest timestamp record may not necessarily be the last record within a given day, the target date is the last date + 1. + beforeDate = dateMin.AddDays(1).Date; + + // Only keep the results of the last known full day. + results = results.Where(x => x.DateFromId >= beforeDate).ToList(); + } + + trelloActions.AddRange(results); } + + return trelloActions; } - public async Task> GetTrelloCardMoveActions() + public async Task> GetTrelloCardCreateActions(DateTime beforeDate) { + // Reference: https://stackoverflow.com/questions/51777063/how-can-i-get-all-actions-for-a-board-using-trellos-rest-api + using (var http = new HttpClient()) { try @@ -397,10 +499,9 @@ public async Task> GetTrelloCardMoveActions() var url = "https://api.trello.com/1/boards/" + SolutionConstants.kTrelloBoardId + "/actions/" + "?key=" + SolutionConstants.kTrelloAppKey + "&token=" + SolutionConstants.kTrelloUserToken - //+ "&before=2019-07-01" - //+ "&since=2019-06-01" - + "&filter=updateCard" - + "&limit=1000"; + + "&filter=createCard" + + "&before=" + beforeDate.ToString(CoreConstants.Formats.DtmZuluIso) + + "&limit=" + SolutionConstants.kTrelloLimitMax.ToString(); var response = await http.GetAsync(url); @@ -408,19 +509,16 @@ public async Task> GetTrelloCardMoveActions() var jsonResult = await response.Content.ReadAsStringAsync(); - var list = JsonConvert.DeserializeObject>(jsonResult); - - return list.Where(x => (x.IsListTransfer() == true)).ToList(); + return JsonConvert.DeserializeObject>(jsonResult); } catch (HttpRequestException httpRequestException) { Console.WriteLine($"Error in GetTrelloCardMoveActions: {httpRequestException.Message}"); } - return null; + return new List(); } } - #region --- Private -------------------------------------------------------