private bool tryQuickAnalyzePeriodThroughActions(out ICardActionsProvider cardActionsProvider) { try { var since = new SinceDate(_boardAnalysis.Timestamp); var allActions = _trello.Actions.AutoPaged().ForBoard(Board, since: since).ToList(); var dictActions = new Dictionary <CardName, List <Action> >(); foreach (var action in allActions) { List <Action> cardActions; var createAction = action as CreateCardAction; if (createAction != null) { if (!dictActions.TryGetValue(createAction.Data.Card, out cardActions)) { dictActions.Add(createAction.Data.Card, cardActions = new List <Action>()); } cardActions.Add(action); continue; } var moveAction = action as UpdateCardMoveAction; if (moveAction == null) { continue; } if (!dictActions.TryGetValue(moveAction.Data.Card, out cardActions)) { dictActions.Add(moveAction.Data.Card, cardActions = new List <Action>()); } cardActions.Add(action); } cardActionsProvider = new CardActionsProvider(dictActions); return(true); } catch { cardActionsProvider = null; return(false); } }
public BoardAnalysisResult AnalyzePeriod(DateTime?start = null, DateTime?end = null, TimeGranularity granularity = TimeGranularity.Week) { const string DataFolder = ".\\data"; ensureBoardIsSelected(); ensureProgressListsAreSpecified(); var startDate = start.HasValue && start.Value != default(DateTime) ? start.Value : projectStartTime(); var endDate = end.HasValue && end.Value != default(DateTime) ? end.Value : DateTime.Today.AddDays(1).Subtract(TimeSpan.FromSeconds(1)); if (_boardAnalysis?.Equals(startDate, endDate, granularity) ?? false) { return(_boardAnalysis); } var db = new ApiDatastore(DataFolder); BoardAnalysisResult boardAnalysis; var analysisExists = false; ISince since = new SinceDate(startDate); if (db.TryLoadBoardAnalysis(Board.Id, startDate, endDate, granularity, out boardAnalysis)) { _boardAnalysis = boardAnalysis; since = new SinceDate(boardAnalysis.Timestamp); analysisExists = true; } UI?.Write("Reads cards from Trello ... "); var allCards = _trello.Cards.ForBoard(Board).ToList(); UI?.WriteLine($"DONE (board '{Board.Name}' contains {allCards.Count} cards)"); UI?.WriteLine("Analysing card actions ..."); UI?.ShowBusy(maxValue: allCards.Count); try { Func <CreateCardAction, CardStatus> createStatus = action => { if (_doingListsIds.Any(id => id == action.Data.List.Id)) { return(CardStatus.Doing); } return(_doneListsIds.Any(id => id == action.Data.List.Id) ? CardStatus.Done : CardStatus.Other); }; Func <MoveCardAction, CardStatus> moveStatus = action => { if (_doingListsIds.Any(id => id == action.ListAfter.Id)) { return(CardStatus.Doing); } return(_doneListsIds.Any(id => id == action.ListAfter.Id) ? CardStatus.Done : CardStatus.Other); }; if (!analysisExists) { _boardAnalysis = new BoardAnalysisResult(Board.Id, startDate, endDate, granularity); } // generate all periods ... PeriodCardsStatus lastPeriod; Dictionary <DateTime, PeriodCardsStatus> result; var firstPeriod = generatePeriods(startDate, ref endDate, granularity, analysisExists, out lastPeriod, out result); var progress = 0; ICardActionsProvider cardActionsProvider; if (!analysisExists || !tryQuickAnalyzePeriodThroughActions(out cardActionsProvider)) { cardActionsProvider = new CardActionsReader(_trello, since, endDate); } var analysisWasUpdated = false; foreach (var card in allCards) { UI?.UpdateBusy(progress, $" | Card: '{card.Name}'"); var allActions = cardActionsProvider.GetCardActions(card); if (allActions.Count == 0) { UI?.UpdateBusy(++progress); continue; } var createActions = allActions.OfType <CreateCardAction>().Where(a => a.Date <= endDate).ToList(); var trelloCard = _boardAnalysis.Cards.FirstOrDefault(c => c.Id == card.Id); PeriodCardsStatus period; foreach (var createAction in createActions) { #if DEBUG if (trelloCard != null) { throw new Exception("Huh?"); } #endif analysisWasUpdated = true; var date = createAction.Date; if (date < firstPeriod.Start) { period = firstPeriod; } else if (date > lastPeriod.End) { period = lastPeriod; } else { period = result[new Period(date, granularity).Start]; } var cardStatus = createStatus(createAction); trelloCard = new TrelloCard { Id = card.Id, Name = card.Name }; if (cardStatus == CardStatus.Doing) { trelloCard.DateCommitted = createAction.Date; } period.Set(trelloCard, cardStatus, true); } var moveActions = allActions.OfType <UpdateCardMoveAction>() .Where(a => a.Date <= endDate) .Select(a => new MoveCardAction(a)) .ToList(); moveActions.Sort((a1, a2) => a1.Date <a2.Date ? -1 : a1.Date> a2.Date ? 1 : 0); foreach (var moveAction in moveActions) { analysisWasUpdated = true; var date = moveAction.Date; if (date < firstPeriod.Start) { period = firstPeriod; } else if (date > lastPeriod.End) { period = lastPeriod; } else { period = result[new Period(moveAction.Date, granularity).Start]; } var cardStatus = moveStatus(moveAction); trelloCard = trelloCard ?? new TrelloCard(moveAction.MoveAction.Data.Card); switch (cardStatus) { case CardStatus.Doing: if (!trelloCard.IsCommitted) { trelloCard.DateCommitted = moveAction.Date; } break; case CardStatus.Done: if (!trelloCard.IsDone) { trelloCard.DateDone = moveAction.Date; } break; } period.Set(trelloCard, cardStatus, true); } UI?.UpdateBusy(++progress); } if (!analysisExists || analysisWasUpdated) { db.SaveBoardAnalysis(_boardAnalysis); } return(_boardAnalysis); } finally { UI?.HideBusy(); } }