def collect_cards(requester, db_board, board_name, board_members, all_lists): trello_client = init_trello_client(requester) # make an instance of py-trello's Board object to have access to relevant api calls board = Board(client=trello_client, board_id=db_board.trello_board_id) board.name = board_name # load all checklists checklists = defaultdict(list) for cl in board.get_checklists(): checklists[cl.card_id].append(cl) open_cards = collect_cards_internal(requester, board, board_members, checklists, all_lists, card_status='open') # request closed cards separately to have a better chance to index all open cards # (thus avoiding hitting rate limits already in open cards indexing) collect_cards_internal(requester, board, board_members, checklists, all_lists, card_status='closed') # update board lists with a list of cards lists_with_cards = defaultdict(list) for ac in open_cards: lists_with_cards[ac.idList].append({ 'id': ac.id, 'name': ac.name, 'pos': ac.pos, 'url': ac.url }) board_lists = db_board.trello_content.get('lists', []) for bl in board_lists: bl.update({ 'cards': sorted(lists_with_cards[bl['id']], key=itemgetter('pos')) }) db_board.trello_content = { 'description': db_board.trello_content.get('description'), 'lists': board_lists } db_board.save() algolia_engine.sync(db_board, add=False)
def setup(trello_key, trello_secret, board_id, out, delimiter, card_extractors, filters): # validate inputs if not trello_key or not trello_secret: raise click.BadParameter('trello_secret and trello_key are required') if not board_id: raise click.BadParameter('board_id is required') trello_client = TrelloClient( api_key=trello_key, api_secret=trello_secret, ) data_provider = DataProvider(Board( trello_client, board_id=board_id, )) print(data_provider.board.name) # TODO: add logging database = DataBase(delimiter=delimiter) runner = Runner(data_provider, database, card_extractors_parameter=[ Parameter(x.strip()) for x in card_extractors.split(',') ], filters=[Parameter(x.strip()) for x in filters.split(',')] if filters else []) runner.run() database.export(out)
def show(self): board = Board(self.client, board_id=self.SPRINT_BOARD_ID) lists = board.open_lists() list_map = {} for l in lists: cards = l.list_cards() list_map[l.name] = [c.name for c in cards] print list_map
def make_trello_card(*args, **kwargs): """Generate a new Trello card""" # Generate our card board and list # DEV: board is never used... # TODO: This is very backwards with needing a board to get a client... # Might move to another lib # https://github.com/sarumont/py-trello/blob/0.4.3/trello/trellolist.py#L11-L20 # https://github.com/sarumont/py-trello/blob/0.4.3/trello/trellolist.py#L48-L63 board = Board(client=trello_client, board_id=TRELLO_BOARD_ID) card_list = List(board=board, list_id=TRELLO_LIST_ID) return card_list.add_card(*args, **kwargs)
def main(api_key, token, board_id): """List out the board lists for our client""" trello_client = TrelloClient( api_key=api_key, token=token, ) board = Board(client=trello_client, board_id=board_id) print('Lists') print('-----') print('Name: Id') for card_list in board.all_lists(): print('{card_list.name}: {card_list.id}'.format(card_list=card_list))
def list_tix(self): board = Board(self.client, board_id=self.SPRINT_BOARD_ID) cards = board.open_cards() lists = board.open_lists() list_names = {l.id: l.name for l in lists} for c in cards: c.fetch(True) if self.me.id in c.member_ids: feature_id = c.shortUrl[-8:] print "%s | %s: %s | %s | %s" % ( feature_id, c.name, c.desc[0:30], list_names[c.list_id], c.shortUrl)
def capture_sprint(self, sprint_id, snapshot_phase): board = Board(self.client, board_id=self.SPRINT_BOARD_ID) cards = board.open_cards() c = self._db.cursor() # make sure cards exist for card in cards: self.write_card(card) # write them to state c.execute( '''insert or ignore into sprint_state values (?, ?, ?, ?, ?)''', (sprint_id, card.list_id, card.id, snapshot_phase, 0)) c.close()
def getRecruitmentBoard(configurationFileName='api.json'): api = {} # In[1]: with open(configurationFileName) as json_file: api = json.load(json_file) # In[2]: client = TrelloClient(api_key=api["api_key"], api_secret=api["api_secret"], token=api["token"]) all_boards = client.list_boards() last_board = all_boards[-1] recruitment = Board() for board in all_boards: if board.name == api["recruitment_board_name"]: recruitment = board print(recruitment.name) return recruitment
def archive_cards(board_name="Private", list_name="Done", days=1): """ archive cards """ username, key, token = util.get_credential() client = TrelloClient(key, token) # Get board boards = get_boards(username, client) board_id = boards[board_name] board = Board(board_id, client) # Get board lists = board.get_lists() list_done = [x for x in lists if x.name == list_name][0] cards = list_done.get_cards() target = datetime.datetime.now(pytz.utc) - datetime.timedelta(days=days) for card in _filter_cards(cards, target): card.set_closed("true") logger.debug(card)
def finish_sprint(self): print "Finishing Sprint %s" % self.last_sprint_id self.ensure('prepared', self.last_sprint_id) self.ensure('started', self.last_sprint_id) self.ensure_not('finished', self.last_sprint_id) # outgoing sprint: snapshot_phase=2 (finish) try: self.capture_sprint(self.last_sprint_id, snapshot_phase=FINISH) except Exception as e: print "ROLLING BACK" self._db.rollback() raise e self.set_sprint_flag('finished', self.last_sprint_id) self._db.commit() # archive all cards in Done column board = Board(self.client, board_id=self.SPRINT_BOARD_ID) done_list = board.get_list(self.list_ids['Done']) done_list.archive_all_cards()
def populate_tables(self): c = self._db.cursor() # version the db c.execute('insert or replace into version values (1)') # ensure we have all the lists board = Board(self.client, board_id=self.SPRINT_BOARD_ID) lists = board.open_lists() for l in lists: c.execute('''insert or replace into lists values (?, ?)''', (l.id, l.name)) self.list_ids[l.name] = l.id self.list_names_by_id[l.id] = l.name # make sure this and next sprint are in sprints table c.execute( '''insert or ignore into sprints values (?, ?, ?, 0, 0, 0)''', (self.cur_sprint_id, self.cur_sprint_start, self.next_sprint_start - datetime.timedelta(days=1))) c.execute( '''insert or ignore into sprints values (?, ?, ?, 0, 0, 0)''', (self.next_sprint_id, self.next_sprint_start, self.next_sprint_end)) self._db.commit() c.close()
def get_counts(client, board_id, monitor_lists, done_list, start_day): """ Get List data :param client: Trello client Object :param board_id: Trello Board ID :param monitor_lists: Trello monitor lists from PowerUp Data :param start_day: Start day of the Sprint. Eg: Monday :return: returns count of User Stories/Defects remaining and completed """ stories_defects_remaining = 0 stories_defects_done = 0 tasks_remaining = 0 ideal_tasks_remaining = 0 board_object = Board(client, board_id=board_id) board_cards = board_object.get_cards() for monitor_list in monitor_lists: for board_card in board_cards: if board_card.idList == monitor_list: if board_card.name[:2] in 'T ': tasks_remaining += 1 elif board_card.name[:2] in ('U ', 'D ', 'C '): stories_defects_remaining += 1 else: for board_card in board_cards: if board_card.idList == done_list: if board_card.name[:2] in ('U ', 'D ', 'C '): stories_defects_done += 1 if current_day == start_day: if board_card.name[:2] in 'T ': ideal_tasks_remaining += 1 if current_day == start_day: ideal_tasks_remaining += tasks_remaining return stories_defects_remaining, stories_defects_done, tasks_remaining, ideal_tasks_remaining
#!/usr/bin/env PYTHONIOENCODING=UTF-8 python # -*- coding: utf-8 -*- from trello import TrelloClient, get_boards from trello import Board import util CONFIG = "./config.cfg" if __name__ == u"__main__": username, key, token = util.get_credential() client = TrelloClient(key, token) # Get "Private" board boards = get_boards(username, client) board_id = boards["Private"] board = Board(board_id, client) # Get "Doing" board lists = board.get_lists() # Get current card cards = lists[1].get_cards() try: print(cards[0].name) except: print("nothing :)")
def prep_sprint(self): # incoming sprint: snapshot_phase=1 (start), from_roadmap=1 print "Preparing Sprint %s" % self.cur_sprint_id self.ensure_not('prepared', self.cur_sprint_id) ## change title to todays date board = Board(self.client, board_id=self.SPRINT_BOARD_ID) # no method for setting name, use client directly board.client.fetch_json( '/boards/' + board.id + '/name', http_method='PUT', post_args={ 'value': 'Engineering: Current Sprint %s' % self.cur_sprint_id, }, ) ## right shift sprint roadmap, bring into current sprint rm_board = Board(self.client, board_id=self.SPRINT_RM_BOARD_ID) rm_lists = rm_board.open_lists() rm_list_map = {l.name: l.id for l in rm_lists} from_rm_cards = [] for l in reversed(rm_lists): # leave any non S + N lists alone if not l.name.startswith('S +'): continue if l.name == 'S + 1': # capture this card list so we can mark from_roadmap correctly from_rm_cards = l.list_cards() # send to sprint board_id = self.SPRINT_BOARD_ID list_id = self.list_ids['New'] else: # send to next col board_id = self.SPRINT_RM_BOARD_ID n_id = int(l.name[-1:]) list_id = rm_list_map['S + %s' % str(n_id - 1)] l.client.fetch_json('/lists/' + l.id + '/moveAllCards', post_args={ 'idBoard': board_id, 'idList': list_id }, http_method='POST') ## capture tickets coming in from roadmap (so we can figure out which were added ad hoc after sprint start) c = self._db.cursor() try: for card in from_rm_cards: card.fetch(True) # if we are doing default due dates, add now if it doesn't exist if card.due is None and DEFAULT_DUE_DATE: card.set_due(self.cur_sprint_start + DEFAULT_DUE_DATE) self.write_card(card) # write them to state c.execute( '''insert into sprint_state values (?, ?, ?, ?, ?)''', (self.cur_sprint_id, card.list_id, card.id, 1, 1)) except Exception as e: print "ROLLING BACK" self._db.rollback() raise e c.close() self.set_sprint_flag('prepared', self.cur_sprint_id) self._db.commit()