Skip to content

Commit

Permalink
Merge pull request #43 from kennethzfeng/develop
Browse files Browse the repository at this point in the history
Fixed Attribute Access Issue on Card
  • Loading branch information
sarumont committed Jul 9, 2014
2 parents 37d800c + 39f9084 commit 81f93a2
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 53 deletions.
32 changes: 32 additions & 0 deletions test/test_trello.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from trello import TrelloClient
import unittest
import os
import datetime

class TrelloClientTestCase(unittest.TestCase):

Expand Down Expand Up @@ -126,6 +127,37 @@ def test51_add_card(self):
if not card:
self.fail("No card created")

def test52_add_card_set_due(self):
boards = self._trello.list_boards()
board_id = None
for b in boards:
if b.name != os.environ['TRELLO_TEST_BOARD_NAME']:
continue

for l in b.open_lists():
try:
name = "Testing from Python"
description = "Description goes here"
card = l.add_card(name, description)
except Exception as e:
print str(e)
self.fail("Caught Exception adding card")

# Set the due date to be 3 days from now
today = datetime.datetime.today()
day_detla = datetime.timedelta(3)
due_date = today + day_detla #
card.set_due(due_date)
expected_due_date = card.due
# Refresh the due date from cloud
card.fetch()
actual_due_date = card.due[:10]
self.assertEquals(expected_due_date, actual_due_date)
break
break
if not card:
self.fail("No card created")

def suite():
tests = ['test01_list_boards', 'test10_board_attrs', 'test20_add_card']
return unittest.TestSuite(map(TrelloClientTestCase, tests))
Expand Down
114 changes: 61 additions & 53 deletions trello/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,29 +122,20 @@ def list_boards(self):
- url: URL to the board
"""
json_obj = self.fetch_json('/members/me/boards')
boards = list()
for obj in json_obj:
boards.append(self._board_from_json(obj))

return boards
return [Board.from_json(self, obj) for obj in json_obj]

def get_board(self, board_id):
obj = self.fetch_json('/boards/' + board_id)
return self._board_from_json(obj)
return Board.from_json(self, obj)

def add_board(self, board_name):
obj = self.fetch_json('/boards', http_method='POST',
post_args={'name': board_name})
board = Board(self, obj['id'], name=obj['name'].encode('utf-8'))
board.closed = obj['closed']
return board
return Board.from_json(self, obj)

def get_list(self, list_id):
obj = self.fetch_json('/lists/' + list_id)
list = List(self.get_board(obj['idBoard']), obj['id'],
name=obj['name'].encode('utf-8'))
list.closed = obj['closed']
return list
return List.from_json(board=self, json_obj=obj)

def get_member(self, member_id):
return Member(self, member_id).fetch()
Expand Down Expand Up @@ -176,13 +167,6 @@ def fetch_json(
raise ResourceUnavailable(url, response)
return json.loads(content)

def _board_from_json(self, json):
board = Board(self, json['id'], name=json['name'].encode('utf-8'))
board.description = json.get('desc', '').encode('utf-8')
board.closed = json['closed']
board.url = json['url']
return board

def list_hooks(self, token=None):
"""
Returns a list of all hooks associated with a specific token. If you don't pass in a token,
Expand Down Expand Up @@ -257,6 +241,20 @@ def __init__(self, client, board_id, name=''):
self.id = board_id
self.name = name

@classmethod
def from_json(cls, trello_client, json_obj):
"""
Deserialize the board json object to a Board object
:trello_client: the trello client
:json_obj: the board json object
"""
board = Board(trello_client, json_obj['id'], name=json_obj['name'].encode('utf-8'))
board.description = json_obj.get('desc', '').encode('utf-8')
board.closed = json_obj['closed']
board.url = json_obj['url']
return board

def __repr__(self):
return '<Board %s>' % self.name

Expand Down Expand Up @@ -296,13 +294,7 @@ def get_lists(self, list_filter):
json_obj = self.client.fetch_json(
'/boards/' + self.id + '/lists',
query_params={'cards': 'none', 'filter': list_filter})
lists = list()
for obj in json_obj:
l = List(self, obj['id'], name=obj['name'].encode('utf-8'))
l.closed = obj['closed']
lists.append(l)

return lists
return [List.from_json(board=self, json_obj=obj) for obj in json_obj]

def add_list(self, name):
"""Add a list to this board
Expand All @@ -314,9 +306,7 @@ def add_list(self, name):
'/lists',
http_method='POST',
post_args={'name': name, 'idBoard': self.id}, )
list = List(self, obj['id'], name=obj['name'].encode('utf-8'))
list.closed = obj['closed']
return list
return List.from_json(board=self, json_obj=obj)

def all_cards(self):
"""Returns all cards on this board"""
Expand Down Expand Up @@ -444,6 +434,18 @@ def __init__(self, board, list_id, name=''):
self.id = list_id
self.name = name

@classmethod
def from_json(cls, board, json_obj):
"""
Deserialize the list json object to a List object
:board: the board object that the list belongs to
:json_obj: the json list object
"""
list = List(board, json_obj['id'], name=json_obj['name'].encode('utf-8'))
list.closed = json_obj['closed']
return list

def __repr__(self):
return '<List %s>' % self.name

Expand All @@ -456,15 +458,7 @@ def fetch(self):
def list_cards(self):
"""Lists all cards in this list"""
json_obj = self.client.fetch_json('/lists/' + self.id + '/cards')
cards = list()
for c in json_obj:
card = Card(self, c['id'], name=c['name'].encode('utf-8'))
card.description = c.get('desc', '').encode('utf-8')
card.closed = c['closed']
card.url = c['url']
card.member_ids = c['idMembers']
cards.append(card)
return cards
return [Card.from_json(self, c) for c in json_obj]

def add_card(self, name, desc=None):
"""Add a card to this list
Expand All @@ -476,13 +470,7 @@ def add_card(self, name, desc=None):
'/lists/' + self.id + '/cards',
http_method='POST',
post_args={'name': name, 'idList': self.id, 'desc': desc}, )
card = Card(self, json_obj['id'])
card.name = json_obj['name']
card.description = json_obj.get('desc', '')
card.closed = json_obj['closed']
card.url = json_obj['url']
card.member_ids = json_obj['idMembers']
return card
return Card.from_json(self, json_obj)

def fetch_actions(self, action_filter):
"""
Expand Down Expand Up @@ -548,6 +536,25 @@ def __init__(self, trello_list, card_id, name=''):
self.id = card_id
self.name = name

@classmethod
def from_json(cls, trello_list, json_obj):
"""
Deserialize the card json object to a Card object
:trello_list: the list object that the card belongs to
:json_obj: json object
"""
if 'id' not in json_obj:
raise Exception("key 'id' is not in json_obj")
card = cls(trello_list,
json_obj['id'],
name=json_obj['name'].encode('utf-8'))
card.desc = json_obj.get('desc', '')
card.closed = json_obj['closed']
card.url = json_obj['url']
card.member_ids = json_obj['idMembers']
return card

def __repr__(self):
return '<Card %s>' % self.name

Expand All @@ -557,16 +564,17 @@ def fetch(self):
'/cards/' + self.id,
query_params={'badges': False})
self.name = json_obj['name'].encode('utf-8')
self.description = json_obj.get('desc', '')
self.desc = json_obj.get('desc', '')
self.closed = json_obj['closed']
self.url = json_obj['url']
self.member_ids = json_obj['idMembers']
self.short_id = json_obj['idShort']
self.list_id = json_obj['idList']
self.board_id = json_obj['idBoard']
self.idMembers = json_obj['idMembers']
self.idShort = json_obj['idShort']
self.idList = json_obj['idList']
self.idBoard = json_obj['idBoard']
self.labels = json_obj['labels']
self.badges = json_obj['badges']
self.due = json_obj['due']
# For consistency, due date is in YYYY-MM-DD format
self.due = json_obj.get('due', '')[:10]
self.checked = json_obj['checkItemStates']

self.checklists = []
Expand Down Expand Up @@ -601,7 +609,7 @@ def create_date(self):

def set_description(self, description):
self._set_remote_attribute('desc', description)
self.description = description
self.desc = description

def set_due(self, due):
"""Set the due time for the card
Expand Down

0 comments on commit 81f93a2

Please sign in to comment.