Exemplo n.º 1
0
 private static void removeFrom(TrelloCard card, params HashSet <TrelloCard>[] sets)
 {
     foreach (var hashSet in sets)
     {
         if (hashSet.Contains(card))
         {
             hashSet.Remove(card);
         }
     }
 }
Exemplo n.º 2
0
        public void Set(TrelloCard card, CardStatus status, bool propagateToNext = false)
        {
            if (!BoardAnalysis.Cards.Contains(card))
            {
                BoardAnalysis.Cards.Add(card);
            }
            switch (status)
            {
            case CardStatus.Other:
                if (Other.Contains(card))
                {
                    break;
                }

                Other.Add(card);
                removeFrom(card, Doing, Done);
                break;

            case CardStatus.Doing:
                if (Doing.Contains(card))
                {
                    break;
                }

                Doing.Add(card);
                removeFrom(card, Done, Other);
                break;

            case CardStatus.Done:
                if (Done.Contains(card))
                {
                    break;
                }

                Done.Add(card);
                removeFrom(card, Other, Doing);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(status), status, null);
            }
            if (propagateToNext)
            {
                ((PeriodCardsStatus)Next(false))?.Set(card, status);
            }
        }
Exemplo n.º 3
0
        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();
            }
        }