bubbleking
bubbleking

Reputation: 3611

Manatee.Trello Moving Cards

I'm writing a small application to manage Trello Boards in only a few aspects such as sorting Cards on a List, moving/copying Cards based on Due Date and/or Labels, archiving Lists on a regular basis and generating reports based on Labels, etc. As such, I've been putting together a facade around the Manatee.Trello library to simplify the interface for my services.

I've been getting comfortable with the library and things have been relatively smooth. However, I wrote an extension method on the Card class to move Cards within or between Lists, and another method that calls this extension method repeatedly to move all Cards from one List to another.

My issue is that when running the code on a couple of dummy lists with 7 cards in one, it completes without error, but at least one card doesn't actually get moved (though as many as 3 cards have failed to move). I can't tell if this is because I'm moving things too rapidly, or if I need to adjust the TrelloConfiguration.ChangeSubmissionTime, or what. I've tried playing around with delays but it doesn't help.

Here is my calling code:

public void MoveCardsBetweenLists(
    string originListName,
    string destinationListName,
    string originBoardName,
    string destinationBoardName = null)
{
    var fromBoard = GetBoard(originBoardName); // returns a Manatee.Trello.Board

    var toBoard = destinationBoardName == null
                  || destinationBoardName.Equals(originBoardName, StringComparison.OrdinalIgnoreCase)
                      ? fromBoard
                      : GetBoard(destinationBoardName);

    var fromList = GetListFromBoard(originListName, fromBoard); // returns a Manatee.Trello.List from the specified Board
    var toList = GetListFromBoard(destinationListName, toBoard);

    for (int i = 0; i < fromList.Cards.Count(); i++)
    {
        fromList.Cards[i].Move(1, toList);
    }
}

Here is my extension method on Manatee.Trello.Card:

public static void Move(this Card card, int position, List list = null)
{
    if (list != null && list != card.List)
    {
        card.List = list;
    }

    card.Position = position;
}

Upvotes: 2

Views: 1254

Answers (1)

gregsdennis
gregsdennis

Reputation: 8428

I've created a test that replicates the functionality you want. Basically, I create 7 cards on my board, move them to another list, then delete them (just to maintain initial state).

private static void Run(System.Action action)
{
    var serializer = new ManateeSerializer();
    TrelloConfiguration.Serializer = serializer;
    TrelloConfiguration.Deserializer = serializer;
    TrelloConfiguration.JsonFactory = new ManateeFactory();
    TrelloConfiguration.RestClientProvider = new WebApiClientProvider();

    TrelloAuthorization.Default.AppKey = TrelloIds.AppKey;
    TrelloAuthorization.Default.UserToken = TrelloIds.UserToken;

    action();

    TrelloProcessor.Flush();
}

#region http://stackoverflow.com/q/39926431/878701

private static void Move(Card card, int position, List list = null)
{
    if (list != null && list != card.List)
    {
        card.List = list;
    }

    card.Position = position;
}

[TestMethod]
public void MovingCards()
{
    Run(() =>
            {
                var list = new List(TrelloIds.ListId);
                var cards = new List<Card>();
                for (int i = 0; i < 10; i++)
                {
                    cards.Add(list.Cards.Add("test card " + i));
                }

                var otherList = list.Board.Lists.Last();

                for(var i = 0; i < cards.Count; i++)
                {
                    Move(card, i, otherList);
                }

                foreach (var card in cards)
                {
                    card.Delete();
                }
            });
}

#endregion

Quick question: Are you calling TrelloProcessor.Flush() before your execution ends? If you don't, then some changes will likely remain in the request processor queue when the application ends, so they'll never be sent. See my wiki page on processing requests for more information.

Also, I've noticed that you're using 1 as the position for each move. By doing this, you'll end up with an unreliable ordering. The position data that Trello uses is floating point. To position a card between two other cards, it simply takes the average of the other cards. In your case, (if the destination list is empty), I'd suggest sending in the indexer variable for the ordering. If the destination list isn't empty, you'll need to calculate a new position based on the other cards in the list (by the averaging method Trello uses).

Finally, I like the extension code you have. If you have ideas that you think would be useful to add to the library, please feel free to fork the GitHub repo and create a pull request.

Upvotes: 2

Related Questions