class NS1Base(object): # https://trello.com/b/1diHBDGp/ SPRINT_BOARD_ID = '56b0bee08a91f6b079ba6ae9' def __init__(self): self.client = None self._me = None def check_api_key(self): if not os.getenv('TRELLO_API_KEY') or not os.getenv('TRELLO_API_SECRET'): raise Exception("You must define TRELLO_API_KEY and TRELLO_API_SECRET, from these: https://trello.com/app-key") def check_oauth(self): if not os.getenv('TRELLO_OAUTH_KEY') or not os.getenv('TRELLO_OAUTH_SECRET'): self.create_oauth() def create_oauth(self): from trello import util util.create_oauth_token() sys.exit(0) def init_client(self): self.client = TrelloClient(api_key=os.getenv('TRELLO_API_KEY'), api_secret=os.getenv('TRELLO_API_SECRET'), token=os.getenv('TRELLO_OAUTH_KEY'), token_secret=os.getenv('TRELLO_OAUTH_SECRET')) # check for auth try: self.client.list_organizations() except Unauthorized: print "RECEIVED UNAUTHORIZED, RECREATING OAUTH" self.create_oauth() @property def me(self): if self._me: return self._me self._me = Member(self.client, 'me') self._me.fetch() return self._me def boot(self): self.check_api_key() self.check_oauth() self.init_client()
class Trello: def __init__(self): self.client = TrelloClient( api_key=getValueFromJSON('auth.json', 'Properties', 'api_key'), api_secret=getValueFromJSON('auth.json', 'Properties', 'api_secret'), token=getValueFromJSON('auth.json', 'Properties', 'token'), token_secret=getValueFromJSON('auth.json', 'Properties', 'token_secret')) self.list = self.findList() def findList(self): self.teamName = input('Enter team name: ') try: for org in self.client.list_organizations(): if org.name.startswith(self.teamName): print('Found Team') for board in org.all_boards(): if getValueFromJSON('Config.json', 'Properties', 'BoardName') in board.name: print('Found board') for list in board.all_lists(): if getValueFromJSON('Config.json', 'Properties', 'ListName') in list.name: print('Found list') return list print( 'List could not be found. Make sure list name exactly matches config.json' ) break exit() print( 'Board could not be found. Make sure board name contains the correct spelling and case inside config.json' ) break exit() print( 'Team could not be found. Make sure spelling exactly matches what is listed on Trello' ) except Exception as e: print( 'Trello API raised error: {}. Do you have your auth token and api key setup in auth.json?' .format(e)) exit() def addCard(self, cardName, checklistItems, fileAttachment): card = self.list.add_card(cardName) card.attach(file=fileAttachment, mimeType='image/jpeg', name=cardName + '.jpg') card.add_checklist('Checklist', checklistItems)
def getTrelloCards(): client = TrelloClient(api_key=config.api_key, api_secret=config.api_secret, token=config.token, token_secret=config.token_secret) org_name = config.org_name brd_name = config.brd_name list_name = datetime.now().strftime("%Y-%V") orgs = list( filter(lambda x: x.name == org_name, client.list_organizations())) if len(orgs) != 1: print("Error while filtering organzation") exit(1) debug_out("Organization found") brds = list( filter(lambda x: x.name == brd_name, orgs[0].get_boards("open"))) if len(brds) != 1: print("Error while filtering boards") exit(1) debug_out("Board found") lists = list( filter(lambda x: x.name == list_name, brds[0].get_lists("open"))) if len(lists) != 1: print("Error while filtering lists") exit(1) cards = lists[0].list_cards() debug_out("List found, with %s cards" % len(cards)) if len(cards) == 0: print("Not sending empty newsletter") exit(1) return cards
class TrelloHelper(): def __init__(self, api_key, token): self.client = TrelloClient(api_key=api_key, token=token) def create_organization(self, organization_name): post_args = {'displayName': organization_name} obj = self.client.fetch_json( '/organizations', http_method='POST', post_args=post_args ) return self.client.get_organization(obj['id']) def delete_organization(self, organization_id): self.client.fetch_json( '/organizations/{}'.format(organization_id), http_method='DELETE', ) def list_organizations(self): return self.client.list_organizations()
class TrelloBoard(object): def __init__(self, api_key, token): """Creates a TrelloBoard object :param api_key: (str) Your Trello api key https://trello.com/1/appKey/generate :param token: (str) Your Trello token """ self.tc = TrelloClient(api_key=api_key, token=token) self._ab_id_cache = {} self._ab_name_cache = {} self._ab_slack_cache = {} # self._warmup_caches() @property def boards(self): """All the boards that can be accessed :return: (Board) list of Board """ return self.tc.list_boards() @property def addressbook(self): board = self._board("Address Book") ab = {} for l in board.list_lists(list_filter="open"): for card in l.list_cards(): info = yaml.load(card.desc) if info: ab[info["id"]] = { "name": card.name, "slack": info["slack"] } self._ab_id_cache = ab return ab @lru_cache(maxsize=128) def _org_id(self, team_name): """Get the id of a Trello team :param team_name: :return: """ orgs = self.tc.list_organizations() for org in orgs: if org.name == team_name: return org.id @lru_cache(maxsize=128) def _board(self, board_name): logger.debug("Looking up board {}".format(board_name)) board = [b for b in self.boards if b.name == board_name] if board: return board[0] @lru_cache(maxsize=128) def _board_by_url(self, board_url): board = [b for b in self.boards if b.url == board_url] if board: return board[0] @lru_cache(maxsize=128) def _member(self, member_id, board_name): member_id = str(member_id) board = self._board(board_name) if not board: return None for l in board.list_lists(list_filter="open"): for card in l.list_cards(): if card.desc == member_id: return card @lru_cache(maxsize=128) def _label(self, label_name, board_name): board = self._board(board_name) label = [l for l in board.get_labels() if l.name == label_name] if label: return label[0] def _warmup_caches(self): logger.debug("Warming up the caches") ids = self.addressbook try: for meetup_name, slack_name in [(n["name"], n["slack"]) for n in ids.values()]: _ = self.contact_by_name(meetup_name) if slack_name: _ = self.contact_by_slack_name(slack_name) except Exception as e: logger.warning("Exception {} when warming up caches".format(e)) def create_board(self, board_name, team_name=None): logger.debug("Checking for board {} on {} team".format( board_name, team_name)) template = self._board("Meetup Template") board = self._board(board_name) org_id = self._org_id(team_name=team_name) if not board: logger.debug("Adding board {}".format(board_name)) self.tc.add_board(board_name=board_name, source_board=template, organization_id=org_id, permission_level="public") def add_rsvp(self, name, member_id, board_name): logger.debug("Adding rsvp {} to {}".format(name, board_name)) member_id = str(member_id) board = self._board(board_name) if not board: return None if not self._member(member_id, board_name): rsvp_list = board.list_lists(list_filter="open")[0] rsvp_list.add_card(name=name, desc=member_id) def cancel_rsvp(self, member_id, board_name): logger.debug("Cancelling RSVP for members id {} at {}".format( member_id, board_name)) card = self._member(member_id, board_name) logger.debug("Card for member id {} is {}".format(member_id, card)) canceled = self._label("Canceled", board_name) logger.debug("Canceled tag is {}".format(canceled)) if card: card.add_label(canceled) def tables_detail(self, board_name): tables = {} board = self._board(board_name) info_card = None if not board: return None for table in board.list_lists(list_filter="open"): names = [] title = table.name if not table.name.startswith( "RSVP") else "~ without a table ~" for card in table.list_cards(): if card.name != "Info" and not card.labels: names.append(card.name) elif card.name == "Info": info_card = card elif card.labels: for label in card.labels: if label.name == "GM": names.append(card.name + " (GM)") elif label.name == "Canceled": names.append(card.name + " (CANCELED)") else: names.append(card.name) if info_card: full_info = info_card.desc.split("Players: ", 1) blurb = full_info[0] if len(full_info) == 2: players = full_info[1] else: players = "" else: blurb, players = "", "" tables[title] = {"members": names, "blurb": blurb} tables[title]["players"] = players or "Unknown" resp = OrderedDict(sorted(tables.items())) return resp def table(self, board_name, list_name): return self.tables_detail(board_name)[list_name] def contact_by_name(self, member_name): logger.debug("Checking {}".format(member_name)) if self._ab_name_cache.get(member_name): return self._ab_name_cache[member_name] else: board = self._board("Address Book") for l in board.list_lists(list_filter="open"): for card in l.list_cards(): desc = yaml.load(card.desc) if card.name == member_name and desc["slack"]: logger.debug("Desc: {}".format(desc)) self._ab_name_cache[member_name] = yaml.load(card.desc) return self._ab_name_cache[member_name] def contact_by_slack_name(self, slack_name): if self._ab_slack_cache.get(slack_name): return self._ab_slack_cache[slack_name] else: board = self._board("Address Book") try: for l in board.list_lists(list_filter="open"): for card in l.list_cards(): desc = yaml.load(card.desc) if desc["slack"] == slack_name: self._ab_slack_cache[slack_name] = { "name": card.name, "id": desc["id"] } return self._ab_slack_cache[slack_name] except: logger.debug("Nothing found for {}".format(slack_name)) def contact_by_id(self, member_id): if self._ab_id_cache.get(member_id): return self._ab_id_cache[member_id] else: board = self._board("Address Book") for l in board.list_lists(list_filter="open"): for card in l.list_cards(): info = yaml.load(card.desc) if info: if info['id'] == member_id and info["slack"]: self._ab_id_cache[member_id] = { "name": card.name, "slack": info["slack"] } return self._ab_id_cache[member_id] def add_contact(self, member_name, member_id): member_id = str(member_id) if self._ab_id_cache.get(member_id): return True board = self._board("Address Book") ab_list = board.list_lists(list_filter="open")[0] info = yaml.dump({ "id": member_id, "slack": None }, default_flow_style=False) no_slack = self._label("NoSlack", "Address Book") for card in ab_list.list_cards(): desc = yaml.load(card.desc) if desc["id"] == member_id: return True ab_list.add_card(name=member_name, desc=info, labels=[no_slack]) def add_table(self, title, info, board_url): board = self._board_by_url(board_url) table_numbers = [ int(n.name.split(".", 1)[0]) for n in board.list_lists(list_filter="open") if n.name[0].isnumeric() ] ordinal = max(table_numbers) + 1 if table_numbers else 1 title = "{}. {}".format(ordinal, title) table = board.add_list(name=title, pos="bottom") info = "\n\nPlayers:".join(info.split("Players:")) table.add_card("Info", desc=info) return "Table *{}* added to *{}*".format(title, board.name)
class trello: def __init__(self, apiKey, TOKEN): self.apiKey = apiKey self.token = TOKEN self.client = TrelloClient(api_key=apiKey, api_secret='your-secret', token=TOKEN, token_secret='your-oauth-token-secret') def printTrello(self): all_boards = self.client.list_boards() last_board = all_boards[-1] print("Boards ") for board in all_boards: print("Board Name :", board.name, " Board ID", board.id) for list in board.all_lists(): print("\t", "ListName :", list.name, "listID :", list.id) for card in list.list_cards(""): print("\t\t", "cardName :", card.name, "cardID :", card.id) #for card in board.all_cards(): # print("\tCard Name :",card.name," Card ID",card.id) ####### BOARD OPERATIONS def getBoard(self, boardID): self.board = self.client.get_board(board_id=boardID) return self.board def getBoardByName(self, boardName): all_boards = self.client.list_boards() for board in all_boards: if board.name == boardName: self.board = board return board return None # close all boards def clearBoards(self): for board in self.client.list_boards(): board.close() def createBoard(self, boardName, organizationID=None, permission_level="private"): self.board = self.client.add_board(board_name=boardName, source_board=None, organization_id=organizationID, permission_level=permission_level) for list in self.board.get_lists(None): self.board.get_list(list.id).close() self.createList("To Do:", self.board.id, 1) self.createList("Doing:", self.board.id, 2) self.createList("Build:", self.board.id, 3) self.createList("Test:", self.board.id, 4) self.createList("Deploy:", self.board.id, 5) return self.board def closeBoardByName(self, boardName=None): if boardName != None: all_boards = self.client.list_boards() for board in all_boards: if board.name == boardName: return board.close() else: if self.board != None: self.closeBoard(self.board.id) def closeBoard(self, boardId=None): if boardId != None: return self.getBoard(boardID=boardId).close() else: if self.board != None: self.board.close() else: return None def boardList(self): return self.client.list_boards() ####### END BOARD OPERATIONS ####### LIST OPERATIONS def getList(self, listID, boardID): return self.client.get_board(board_id=boardID).get_list(list_id=listID) def getListByName(self, listID, boardID): return self.client.get_board(board_id=boardID).get_list(list_id=listID) def createList(self, listName, boardID, sira=None): board = self.client.get_board(boardID) addedlist = board.add_list(listName, sira) return addedlist def closeList(self, listID, boardID): return self.client.get_board(boardID).get_list(listID).close() def closeJustListID(self, listID): # unsafe url = "https://api.trello.com/1/lists/" + listID + "?closed=true&key=" + self.apiKey + "&token=" + self.token querystring = {} response = requests.request("PUT", url, params=querystring) return response.text ####### END LIST OPERATIONS ####### CARD OPERATIONS def getCard(self, cardID): return self.client.get_card(card_id=cardID) def createCard(self, boardID, listID, cardName): self.getList(boardID=boardID, listID=listID).add_card(name=cardName, labels=None, due="", source=None, position=None) def removeCard(self, cardID): url = "https://api.trello.com/1/cards/" + cardID + "?key=" + self.apiKey + "&token=" + self.token querystring = {} response = requests.request("PUT", url, params=querystring) return response.text def moveCard(self, cardID, desListID): self.getCard(cardID=cardID).change_list(list_id=desListID) ####### END CARD OPERATIONS ####### TEAM MEMBER OPERATIONS def addMemberBoard(self, boardID, memberID): board = self.client.get_board(board_id=boardID) board.add_member(memberID) # ORGANIZATION OPERATIONS def getOrganization(self, organizationID): return self.client.get_organization(organizationID) def getOrganizationByName(self, organizationName): for organization in self.listOrganizations(): if organization.name == "": return organization return None def listOrganizations(self): self.client.list_organizations() return self.client.list_organizations() def createOrganization(self, organizationName): url = "https://api.trello.com/1/organizations?displayName=" + organizationName + "&desc=" + organizationName + "&key=" + self.apiKey + "&token=" + self.token querystring = {} response = requests.request("POST", url, params=querystring) organizationID = str.split(response.text, ",")[0].split("\"")[3] return organizationID def addOrganizationMember(self, organizationID, mail, memberType="normal", fullName="member"): configuredMail = str.replace(mail, "@", "%40") url = "https://api.trello.com/1/organizations/" + organizationID + "/members?email=" + configuredMail + "&fullName=" + fullName + "&type=" + memberType + "&key=" + self.apiKey + "&token=" + self.token querystring = {} response = requests.request("PUT", url, params=querystring) data = (json.loads(response.text)) memberID = (data["memberships"][-1]["idMember"]) return memberID def removeOrganizationMember(self, organizationID, memberID): url = "https://api.trello.com/1/organizations/" + organizationID + "/members/" + memberID + "?key=" + self.apiKey + "&token=" + self.token querystring = {} response = requests.request("DELETE", url, params=querystring) return response.text def removeOrganization(self, organizationID): url = "https://api.trello.com/1/organizations/" + organizationID + "?key=" + self.apiKey + "&token=" + self.token querystring = {} response = requests.request("DELETE", url, params=querystring) return response.text def addCommendToCard(self, cardID, commendText): url = "https://api.trello.com/1/cards/" + cardID + "/actions/comments?text=" + commendText + "&key=" + self.apiKey + "&token=" + self.token querystring = {} response = requests.request("POST", url, params=querystring) return response.text
class TrelloBoard(object): def __init__(self, api_key, token): """Creates a TrelloBoard object :param api_key: (str) Your Trello api key https://trello.com/1/appKey/generate :param token: (str) Your Trello token """ self.tc = TrelloClient(api_key=api_key, token=token) @property def boards(self) -> List[Board]: """All the boards that can be accessed :return: (Board) list of Board """ return self.tc.list_boards() @lru_cache(maxsize=128) def _org_id(self, team_name: str) -> str: """Get the id of a Trello team :param team_name: :return: """ orgs = self.tc.list_organizations() for org in orgs: if org.name == team_name: return org.id @lru_cache(maxsize=128) def _board(self, board_name): logger.debug("Looking up board {}".format(board_name)) board = [b for b in self.boards if b.name == board_name] try: return board[0] except IndexError as e: raise NoBoardError from e @lru_cache(maxsize=128) def _board_by_url(self, board_url): board = [b for b in self.boards if b.url == board_url] if board: return board[0] @lru_cache(maxsize=128) def _member(self, member_id: int, board_name: str) -> Optional[Card]: member_id = str(member_id) try: board = self._board(board_name) except NoBoardError: return for l in board.list_lists(list_filter="open"): for card in l.list_cards(): sleep(0.1) if card.desc == member_id: return card @lru_cache(maxsize=128) def _label(self, label_name, board_name): board = self._board(board_name) label = [l for l in board.get_labels() if l.name == label_name] if label: return label[0] def participants(self, board_name): board = self._board(board_name) members = [] for l in board.list_lists(list_filter="open"): for card in l.list_cards(): sleep(0.1) try: members.append(int(card.desc)) except ValueError: pass return members def create_board(self, board_name, team_name=None): logger.debug("Checking for board {} on {} team".format( board_name, team_name)) template = self._board("Meetup Template") org_id = self._org_id(team_name=team_name) try: self._board(board_name) except NoBoardError: self.tc.add_board(board_name=board_name, source_board=template, organization_id=org_id, permission_level="public") def add_rsvp(self, name, member_id, board_name): logger.debug("Adding rsvp {} to {}".format(name, board_name)) try: board = self._board(board_name) except NoBoardError: logger.debug("Board {} not found".format(board_name)) return if not self._member(member_id, board_name): logger.debug("Member {} does not exist in {}. Adding them.".format( member_id, board_name)) rsvp_list = board.list_lists(list_filter="open")[0] logger.debug("RSVP list for {}: {}".format(board_name, rsvp_list)) rsvp_list.add_card(name=name, desc=str(member_id)) def cancel_rsvp(self, member_id, board_name): logger.debug("Canceling RSVP for members id {} at {}".format( member_id, board_name)) member_card = self._member(member_id, board_name) logger.debug("Card for member id {} is {}".format( member_id, member_card)) canceled = self._label("Canceled", board_name) logger.debug("Canceled tag is {}".format(canceled)) if member_card: member_card.add_label(canceled) def tables_for_event(self, event_name: str) -> Dict[int, GameTable]: tables = {} info_card = None board = self._board(event_name) for board_list in board.list_lists(list_filter="open"): if board_list.name.startswith("RSVP"): title = "Without a table :disappointed:" table_number = 9999 else: table_number, title = board_list.name.split(". ", maxsplit=1) table_number = int(table_number) table = GameTable(number=table_number, title=title) for card in board_list.list_cards(): sleep(0.1) if card.name == "Info": info_card = card elif card.labels: for label in card.labels: if label.name == "GM": table.gm = card.name else: table.add_player(card.name) if info_card: full_info = info_card.desc.split("Players: ", 1) table.blurb = full_info[0] if len(full_info) == 2: try: table.max_players = int(full_info[1]) except ValueError: pass tables[table_number] = table return OrderedDict(sorted(tables.items())) def table(self, board_name: str, table_number: int) -> GameTable: return self.tables_for_event(board_name)[table_number] def add_table(self, title, info, board_url): board = self._board_by_url(board_url) table_numbers = [ int(n.name.split(".", 1)[0]) for n in board.list_lists(list_filter="open") if n.name[0].isnumeric() ] ordinal = max(table_numbers) + 1 if table_numbers else 1 title = "{}. {}".format(ordinal, title) table = board.add_list(name=title, pos="bottom") info = "\n\nPlayers:".join(info.split("Players:")) table.add_card("Info", desc=info) return "Table *{}* added to *{}*".format(title, board.name)
class Handler(BaseHandler): name = 'Trello' prefix = 'trello' patterns = [ ([ '(?P<command>desligar) (?P<users>.*)', '(?P<command>terminate) (?P<users>.*)', '{prefix} (?P<command>terminate) (?P<users>.*)' ], 'Desliga um funcionário'), ] def __init__(self, bot, slack, api_key=None, api_secret=None, oauth_token=None, oauth_secret=None): super().__init__(bot, slack) self.directed = True if not api_key: api_key = os.environ.get('TRELLO_API_KEY') if not api_secret: api_secret = os.environ.get('TRELLO_API_SECRET') if not oauth_token: oauth_token = os.environ.get('TRELLO_OAUTH_TOKEN') if not oauth_secret: oauth_secret = os.environ.get('TRELLO_OAUTH_SECRET') self.client = TrelloClient(api_key=api_key, api_secret=api_secret, token=oauth_token, token_secret=oauth_secret) self.org_name = os.environ.get('TRELLO_ORGANIZATION', 'pagarmeoficial') self.org_id = self.get_org_id(self.org_name) self.org = self.client.get_organization(self.org_id) self.set_job_status('Initialized') def get_org_id(self, name): orgs = self.client.list_organizations() for org in orgs: if org.name == name: return org.id def process(self, channel, user, ts, message, at_bot, command, **kwargs): if at_bot: if command in ['desligar', 'terminate']: user_handle = self.get_user_handle(user) self.log('@{}: {}'.format(user_handle, message)) self.set_job_status('Processing') if not self.authorized(user_handle, 'Terminator'): self.set_job_status('Unauthorized') self.post_message( channel=channel, text='@{} Unauthorized'.format(user_handle)) return False to_remove = [ x for x in kwargs['users'].split() if '@' not in x ] for r in to_remove: try: c = self.bot.get_config('alias_reverse', r) if c: if c not in to_remove: to_remove.append(c) except: continue for r in to_remove: try: c = self.bot.get_config('alias', r).split() for x in c: if x not in to_remove: to_remove.append(x) except: continue print(to_remove) if len(to_remove) == 0: self.log('No valid usernames') self.set_job_status('Finished') return self.post_message(channel=channel, text='@{} Removendo usuários: {}'.format( user_handle, ', '.join(to_remove))) all_boards = self.org.get_boards({'fields': 'id'}) members = { board.id: board.all_members() for board in all_boards } members_username = { board.id: [x.username for x in members[board.id]] for board in all_boards } for username in to_remove: response = '@{} User {} not found at any boards'.format( user_handle, username) removed = False removed_boards = [] m = None for mm in members: if isinstance(members[mm], list): for member in members[mm]: if member.username == username: m = member break else: if members[mm].username == username: m = mm break if m == None: self.log('User {} doesn\'t exists'.format(username)) continue try: self.client.fetch_json( '/organizations/{}/members/{}'.format( self.org_id, m.id), http_method='DELETE') except: traceback.print_exc() for board in all_boards: if username in members_username[board.id]: try: self.log('Found {} at board {}'.format( username, board.name)) removed = True removed_boards.append('"{}"'.format( board.name)) board.remove_member(m) self.log( 'User {} removed from board {}'.format( username, board.name)) except: self.post_message( channel, 'Failed to remove {} from board {}'.format( username, board.name)) self.log(traceback.format_exc()) if removed: response = '@{} User {} removed from boards {}'.format( user_handle, username, ', '.join(removed_boards)) if response: self.post_message(channel, response) else: self.log( 'User {} not found in any boards'.format(username)) self.post_message( channel, '@{} User {} not found in any boards'.format( user_handle, username)) self.set_job_status('Finished') self.set_job_end(datetime.now())
class TrelloPlugin(BotPlugin): ''' I can manage Trello boards for you ''' def __init__(self, dispatcher): self.client = TrelloClient( api_key=os.getenv('TRELLO_API_KEY'), api_secret=os.getenv('TRELLO_API_SECRET'), token=os.getenv('TRELLO_API_TOKEN'), ) self.admins = get_list_from_environment('TRELLO_ADMINS') self.load_orgs() self.__boards = [] self.handlers = [ CommandHandler( 'list', self.list_objects, pass_args=True, ) ] self.add_handlers(dispatcher) self.version = '0.0.1' logger.info(f'Trello plugin v{version} enabled') @property def organization(self): if len(self.__orgs) == 1: return self.__orgs[0] else: return os.getenv('TRELLO_DEFAULT_ORGANIZATION') def load_orgs(self): logger.info('Getting organizations') self.__orgs = self.client.list_organizations() def load_boards(self): logger.info('Getting boards') self.__boards = self.organization.get_boards('open') @property def orgs(self): if len(self.__orgs) == 0: self.load_orgs() return self.__orgs @property def boards(self): if len(self.__boards) == 0: self.load_boards() return self.__boards @property def org_names(self): return [org.name for org in self.orgs] @property def board_names(self): return [board.name for board in self.boards] def get_board(self, board_name): board_found = None for board in self.boards: if board.name == board_name: board_found = board break return board_found def list_orgs(self): msg = '\n'.join([ f'- *{org_name}*' if org_name == self.organization.name else f'- {org_name}' for org_name in self.org_names ]) return msg, ParseMode.MARKDOWN def list_boards(self): msg = '\n'.join([f'- {board_name}' for board_name in self.board_names]) return msg, ParseMode.MARKDOWN def list_column_cards(self, column): msg = '\n'.join([f' + {card.name}' for card in column.list_cards()]) return msg def list_board_columns(self, board_name): msg = f'No such board `{board_name}`' board = self.get_board(board_name) if board is not None: msg = '\n'.join([ f'- {column.name} ({column.cardsCnt()} cards) ' f'\n{self.list_column_cards(column)}'.strip() for column in board.open_lists() ]) return msg, ParseMode.HTML def list_objects(self, bot, update, args): ''' List Trello objects visible to me. Object type depends on first argument: - `orgs`: List organizations. - `boards`: List boards. - `board_name`: List cards in `board_name`. By default it lists organizations. ''' msg = '' parse_mode = None if update.message.from_user.username in self.admins: if len(args) < 1 or args[0] == 'orgs': msg, parse_mode = self.list_orgs() elif args[0] == 'boards': msg, parse_mode = self.list_boards() elif args[0] in self.board_names: msg, parse_mode = self.list_board_columns(args[0]) else: msg = f'No such board `{args[0]}`' parse_mode = ParseMode.MARKDOWN msg += '\n\nYou can specify either one of: `orgs`, `boards`, ' \ 'or use a `board_name` to list its cards' else: msg = 'You must be admin to list Trello objects' bot.send_message( chat_id=update.message.chat_id, text=msg, parse_mode=parse_mode, )