Example #1
2
 def __init__(self):
     # API = "9cc1470c039f9f1bf8fe3ce35689a127"
     # TOKEN = "2093b976115e83e07b33321b359aa53a74d612aeec6373218d15796bd78a45b1"
     API = get_credentials()["api"]
     TOKEN = get_credentials()["token"]
     client = TrelloClient(api_key=API,
                           token=TOKEN)
     self.boards = client.list_boards()
    def post(self):
        """ Collect data from the HTML form to fill in a Trello card.

        That card will be uploaded to Suggestion Box board, on the corresponding
        list, determined by the "System" attribute given in the form.
        """
        # Get form data
        date = datetime.now()
        title = self.get_argument('title')
        area = self.get_argument('area')
        system = self.get_argument('system')
        importance = self.get_argument('importance')
        difficulty = self.get_argument('difficulty')
        user = self.get_current_user_name()
        description = self.get_argument('description')
        suggestion = self.get_argument('suggestion')

        client = TrelloClient(api_key = self.application.trello_api_key,
                              api_secret = self.application.trello_api_secret,
                              token = self.application.trello_token)

        # Get Suggestion Box board
        boards = client.list_boards()
        suggestion_box = None
        for b in boards:
            if b.name == 'Suggestion Box':
                suggestion_box = client.get_board(b.id)
                break

        # Get the board lists (which correspond to System in the form data) and
        # concretely get the list where the card will go
        lists = b.all_lists()
        card_list = None
        for l in lists:
            if l.name == system:
                card_list = l
                break

        # Create new card using the info from the form
        new_card = card_list.add_card(TITLE_TEMPLATE.format(title=title, area=area))
        new_card.set_description(DESCRIPTION_TEMPLATE.format(date = date.ctime(),
                                                             area=area,
                                                             system=system,
                                                             importance=importance,
                                                             difficulty=difficulty,
                                                             user=user,
                                                             description=description,
                                                             suggestion=suggestion))

        # Save the information of the card in the database
        self.application.suggestions_db.create({'date': date.isoformat(),
                                                'card_id': new_card.id,
                                                'description': new_card.description,
                                                'name': new_card.name,
                                                'url': new_card.url,
                                                'archived': False})

        self.set_status(200)
    def save_to_trello(self):
        # print clean_form_data
        api_key = settings.TRELLO_KEY
        secret = settings.TRELLO_SECRET
        token = settings.TRELLO_TOKEN
        board = settings.TRELLO_REQUEST_BOARD

        c = TrelloClient(api_key, secret, token)
        b = c.get_board(board)

        # Currently we default to adding card to first list
        l = b.all_lists()[0]
        label_list = b.get_labels()

        ds_name = "%s - %s" % (self.dataset_name, self.dataset_source)

        ds_description = "%s\n%s\nRequested by: %s %s, %s" % \
            (self.dataset_name,
            self.dataset_description,
            self.user_first_name,
            self.user_last_name,
            self.user_email)

        try:
            label_to_add = next(x for x in label_list if x.name == 'Request')
        except StopIteration:
            label_to_add = b.add_label('Request', "lime")

        try:
            card = l.add_card(ds_name, ds_description, [label_to_add])
            self.trello_id = card.id
        except Exception:
            pass
    def sync_trello_cards(self):
        if not self.trello_id:
            logger.exception("Trello board id for %s not set", self.name)
            raise NotSetTrelloBoardID

        client = TrelloClient(**TRELLO_KEYS)
        tasks = client.fetch_json("boards/{}/cards".format(self.trello_id))

        for task_dict in tasks:
            last_activity = task_dict.get('dateLastActivity')
            task, created = Task.objects.get_or_create(
                trello_id=task_dict['id'],
                project=self
            )
            if created or last_activity != task.trello_last_activity:
                task.name = task_dict['name']
                task.description = task_dict['desc']
                task.trello_url = task_dict['shortUrl']
                task.trello_last_activity = last_activity
                task.save()

                logger.info(
                    "Trello card with id %s and name %s has ben %s",
                    task_dict['id'],
                    task_dict['name'],
                    'created' if created else 'updated'
                )
Example #5
0
def create_trello_board(board_name):
    """
    Create Trello board and returns it

    :board_name: the board name
    """
    trello_client = TrelloClient(api_key=trello_api_key, api_secret=trello_api_secret, token=trello_token, token_secret=trello_token_secret)
    return trello_client.add_board(board_name)
Example #6
0
def get_trello_boards():
    """ Get all Trello boards """
    logger.info('Fetching Trello boards ...')
    trello_client = TrelloClient(
        api_key=trello_api_key,
        api_secret=trello_api_secret,
        token=trello_token,
        token_secret=trello_token_secret)
    logger.info('... done')
    return trello_client.list_boards()
 def delete_from_trello(self):
     api_key = settings.TRELLO_KEY
     secret = settings.TRELLO_SECRET
     token = settings.TRELLO_TOKEN
     id = self.trello_id
     c = TrelloClient(api_key, secret, token)
     card = c.get_card(id)
     try:
         card.set_closed(True)
     except Exception:
         pass
def main(api_key, token):
    """List out the boards for our client"""
    trello_client = TrelloClient(
        api_key=api_key,
        token=token,
    )
    print('Boards')
    print('-----')
    print('Name: Id')
    for board in trello_client.list_boards():
        print('{board.name}: {board.id}'.format(board=board))
Example #9
0
def delete_trello_card(trello_card_id):
    """
    Delete (forever) a Trello Card by ID

    :trello_card_id: Trello card ID
    """
    trello_client = TrelloClient(api_key=trello_api_key, api_secret=trello_api_secret, token=trello_token, token_secret=trello_token_secret)
    try:
        trello_card = trello_client.get_card(trello_card_id)
        trello_card.delete()
    except Exception:
        print('Cannot find Trello card with ID {0} deleted in Task Warrior. Maybe you deleted it in Trello too.'.format(trello_card_id))
    def get_client(self):
        client = None
        while client is None:
            self._set_creds()
            client = TrelloClient(api_key=self._api_key, token=self._token)
            try:
                client.list_hooks(self._token)
            except Unauthorized:
                print('Trello client is not authorized.')
                client = None
                self._write_config()

        print('Trello client successfully authorized.')
        return client
Example #11
0
class connectionJASON():
    
    def setUp(self):
        self._trello = TrelloClient(api_key='f8fd231446c1fd27f49e0d8f933252f3',
                                api_secret='338b8eef2cc489ce5cfc9f2252c73f5cf51b44a41cc6cb790be20feb9ed19f2d',
                                token='8004f00bc94627ac6eb98333492a76315821ed06e9d04eec4b6480d1f575758b',
                                token_secret='a528cdd05a0dd7314f45995fdf457c45')
                                
    def getCards(self):
        boards = [board for board in self._trello.list_boards() if 'Proy Industria' in str(board.name) ]
        board = boards[0]
        cards = board.get_cards()
        return cards


    def arrangeCards(self,cards):
        resultTree = AVLTree();
        for i in cards:
            if resultTree.rootNode == None:
                resultTree.insert(i,0)
            else:
                #resultTree.rootNode.text
                currentNode = resultTree.rootNode
                done = True
                while(done):
                    moreImportant = (input(str(i)+" is more important than "+str(currentNode.text)+" y/n "))
                    if moreImportant == "y":
                        if(currentNode.rightChild == None):
                            resultTree.add_as_child2(i,currentNode,1)
                            done = False
                        else:
                            currentNode = currentNode.rightChild
                    else:
                        if(currentNode.leftChild == None):
                            resultTree.add_as_child2(i,currentNode,0)
                            done = False
                        else:
                            currentNode = currentNode.leftChild
                print(resultTree.as_list(1))
                #print(resultTree.rebalance_count)
                #print (resultTree.out())
        return resultTree

    def sendCards(self,cards):
        boards = [board for board in self._trello.list_boards() if 'Proy Industria' in str(board.name) ]
        board = boards[0]
        cards = board.get_cards()
        return cards
Example #12
0
class TrelloWrapper():
    def __init__(self, api_key, api_token):
        self.tc = TrelloClient(api_key, api_token)


    def add_card(self, list_target, card_name, card_due, desc=None):
        """
            Add card to list with a due date
            card_due: time.stuct_time object,
            use time.localtime()
        """
        try:
            # Convert to UTC datetime object
            card_due_utc = time.gmtime(time.mktime(card_due))
            due_str = time.strftime("%Y-%m-%dT%H:%M", card_due_utc)
            json_obj = list_target.client.fetch_json(
                '/lists/' + list_target.id + '/cards',
                http_method='POST',
                post_args={'name': card_name, 'due': due_str,
                    'idList': list_target.id, 'desc': desc}, )
        except Exception as e:
            print(str(e))


    def smart_add_card(self, sentence):
        """Check date keywords in the sentence,
        and use as card's due date."""
        # TODO Life/Inbox as default, move to config
        target_default = ("Life", "Inbox")
        t_curr = time.time()
        p = parser.Parser(t_curr)

        target = p.parse_list(sentence)
        if target is None:
            target = target_default
        due = p.parse_due_time(sentence)

        list_target = self.find_list(target[0],
                target[1])

        if list_target is None:
            return False

        self.add_card(list_target, sentence, due.timetuple())
        return True


    def find_list(self, board_name, list_name):
        """ Return list specified by board_name/list_name"""
        for b in self.tc.list_boards():
            if b.name != board_name:
                continue

            for l in b.open_lists():
                if l.name != list_name:
                    continue

                return l

        return None
    def __init__(self, board_id, list_id, api_key, token=None, **kwargs):
        """
        Validate inputs and connect to Trello API.
        Exception is thrown if input details are not correct.

        :param board_id: Trello board ID where the List is located
        :type board_id: ``str``

        :param list_id: Trello List ID itself
        :type list_id: ``str``

        :param api_key: Trello API key
        :type api_key: ``str``

        :param token: Trello API token
        :type token: ``str``
        """
        self.board_id = board_id
        self.list_id = list_id
        self.api_key = api_key
        # assume empty string '' as None
        self.token = token or None

        self.validate()

        self._client = TrelloClient(api_key=self.api_key, token=self.token)
        self._list = self._client.get_board(self.board_id).get_list(self.list_id)
def get_trello_list():
    # connect to trello
    trello_api_key = 'xxxx'
    trello_api_secret = 'xxxx'
    # this oauth token and secret are fetched using trello_oauth_util.py
    trello_oauth_token = "xxxx"
    trello_oauth_token_secret = "xxxx"
    trello_client = TrelloClient(api_key=trello_api_key, api_secret=trello_api_secret, token=trello_oauth_token,
                                 token_secret=trello_oauth_token_secret)
    # fetch the desired board
    # noinspection PyTypeChecker
    for board in trello_client.list_boards():
        if TRELLO_BOARD_NAME == board.name:
            for board_list in board.all_lists():
                if TRELLO_LIST_NAME == board_list.name:
                    return board_list
Example #15
0
    def __init__(self, token=None, **kwargs):
        super(ServiceTrello, self).__init__(token, **kwargs)
        # app name
        self.app_name = DjangoThConfig.verbose_name
        # expiration
        self.expiry = "30days"
        # scope define the rights access
        self.scope = 'read,write'
        self.oauth = 'oauth1'
        self.service = 'ServiceTrello'

        base = 'https://www.trello.com'
        self.AUTH_URL = '{}/1/OAuthAuthorizeToken'.format(base)
        self.REQ_TOKEN = '{}/1/OAuthGetRequestToken'.format(base)
        self.ACC_TOKEN = '{}/1/OAuthGetAccessToken'.format(base)
        self.consumer_key = settings.TH_TRELLO_KEY['consumer_key']
        self.consumer_secret = settings.TH_TRELLO_KEY['consumer_secret']
        if token:
            token_key, token_secret = token.split('#TH#')
            try:
                self.trello_instance = TrelloClient(self.consumer_key,
                                                    self.consumer_secret,
                                                    token_key,
                                                    token_secret)
            except ResourceUnavailable as e:
                us = UserService.objects.get(token=token)
                logger.error(e.msg, e.error_code)
                update_result(us.trigger_id, msg=e.msg, status=False)
Example #16
0
    def __init__(self, credentials, boards=None):
        self.trello_client = TrelloClient(
            api_key=credentials['public_key'],
            token=credentials['member_token'],
        )

        self.boards = boards
Example #17
0
    def __init__(self):
        self.logger = logging.getLogger("sysengreporting")
        self.client = TrelloClient(api_key = os.environ['TRELLO_API_KEY'],
                                   api_secret = os.environ['TRELLO_API_SECRET'],
                                   token = os.environ['TRELLO_TOKEN'],
                                   token_secret = os.environ['TRELLO_TOKEN_SECRET'])

        for board in self.client.list_boards():
            if board.name == 'Systems Engineering Assignments'.encode('utf-8'):
                self.logger.debug('found Systems Engineering Assignments: %s' % (board.id))
                self.syseng_assignments = board
            elif board.name == 'Private e2e Product Integration'.encode('utf-8'):
                self.logger.debug('found e2e Assignments: %s' % (board.id))
                self.e2e_board = board
            elif board.name == 'Systems Design and Engineering Projects'.encode('utf-8'):
                self.logger.debug('found Systems Design and Engineering Projects: %s' % (board.id))
                self.sysdeseng_projects = board

        self.syseng_members = self.syseng_assignments.all_members()
        self.e2e_members = self.e2e_board.all_members()

        for list in self.sysdeseng_projects.all_lists():
            if list.name == 'In Progress'.encode('utf-8'):
                self.sysdeseng_projects_cards = self.sysdeseng_projects.get_list(list.id).list_cards()

        self.projects = dict()
        self.assignments = dict()
def get_trello_cards():
    """
    Makes an API call to Trello to get all of the cards from Weird Canada's
    New Canadiana board. Requires an OAuth key.
    :return: list of trello cards
    """
    trello_client = TrelloClient(
        api_key=os.environ.get('TRELLO_API_KEY'),
        api_secret=os.environ.get('TRELLO_API_SECRET'),
        token=os.environ.get('TRELLO_OAUTH_KEY'),
        token_secret=os.environ.get('TRELLO_OAUTH_SECRET')
    )

    new_canadiana_board_id = os.environ.get('BOARD_ID')
    new_canadiana_board = trello_client.get_board(new_canadiana_board_id)

    return new_canadiana_board.open_cards()
Example #19
0
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()
Example #20
0
class CardListDatasource(object):
    '''

    '''
    METHODS = {
        'title': 'get_card_title',
        'members': 'get_card_members',
        'duration': 'get_card_duration'
    }

    def __init__(self, api_key, api_secret, token_key, token_secret):
        self.client = TrelloClient(api_key, api_secret, token_key, token_secret)

    def get_board(self, board_name):
        '''
            Return board by name
        '''
        boards = self.client.list_boards()
        for board in boards:
            if board.name == board_name:
                return board
        return None

    def get_cards(self, board):
        return board.all_cards()

    def parse_key(self, key):
        key = key[1:-1] # remove {}
        method = key.split('[')[0]
        try:
            param = re.match(r"[^[]*\[([^]]*)\]", key).groups()[0]
        except AttributeError:
            param = None
        return (method, param)

    def get_row(self, card, keys):
        row = {}
        for key in keys:
            parsed_key = self.parse_key(key)
            method = parsed_key[0]
            column = parsed_key[1]
            kwargs = {
                'card' : card
            }
            if column:
                kwargs['column'] = column
            value = getattr(self, self.METHODS[method])(**kwargs)
            row[key] = value
        return row
        
    def get_card_duration(self, card, column=None):
        '''
            Return card duration, with called column arg
            return card duration inside column
        '''
        history = card.listCardMove_date()
        pass
Example #21
0
    def __init__(self):
        trello_config = Config.open_api.trello

        self.client = TrelloClient(
            api_key=trello_config.API_KEY,
            api_secret=trello_config.API_SECRET,
            token=trello_config.TOKEN,
        )
        self.board = self.client.get_board(trello_config.BOARD)
def sync(events, token):
    trello = TrelloClient(api_key=TRELLO_KEY, token=token)
    board = trello.get_board('55f7167c46760fcb5d68b385')

    far_away, less_2_months, less_1_month, less_1_week, today, past = board.all_lists()

    all_cards = {card_id(c): c for c in board.all_cards()}

    date_today = datetime.date.today()

    for e in events:
        card = all_cards.get(e.id)

        if not card:
            card = create_card(e, far_away)
            create_checklist(card)

        #fetch card to get due date
        try:
            card.fetch()
        except ResourceUnavailable:
            print("Oopsie: too many requests! Let's wait 10 seconds!")
            time.sleep(10)
            card.fetch()

        if e.date != card.due_date.date():
            print('Changing due date of {} to {}'.format(e.city, e.date))
            card.set_due(e.date)

        distance = (e.date - date_today).days
        if distance < 0:
            right_list = past
        elif distance == 0:
            right_list = today
        elif distance < 7:
            right_list = less_1_week
        elif distance < 30:
            right_list = less_1_month
        elif distance < 60:
            right_list = less_2_months
        else:
            right_list = far_away

        ensure_card_in_list(card, right_list)
Example #23
0
 def setUp(self):
     self._trello = TrelloClient(os.environ['TRELLO_API_KEY'],
                                 token=os.environ['TRELLO_TOKEN'])
     for b in self._trello.list_boards():
         if b.name == os.environ['TRELLO_TEST_BOARD_NAME']:
             self._board = b
             break
     try:
         self._list = self._board.open_lists()[0]
     except IndexError:
         self._list = self._board.add_list('List')
Example #24
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()
Example #25
0
    def __init__(self, processed_report, trello_secret):
        self.logger = logging.getLogger(__name__)
        self.client = TrelloClient(api_key = trello_secret[':consumer_key'],
                                   api_secret = trello_secret[':consumer_secret'],
                                   token = trello_secret[':oauth_token'],
                                   token_secret = trello_secret[':oauth_token_secret'])

        #Extract report configuration parameters
        self.projects = processed_report[':collected_content'][':projects'];
        self.epics = processed_report[':collected_content'][':epics'];
        self.assignments = processed_report[':collected_content'][':assignments'];
Example #26
0
 def __init__(self, file='config.yml'):
     """ Load Trello api keys from yaml file"""
     with open(file, 'r') as stream:
         try:
             config = yaml.safe_load(stream)
             self.__client = TrelloClient(
                 api_key = config['key'],
                 api_secret = config['token']
             )
         except yaml.YAMLError as exc:
                 print(exc)
    def __init__(self):
        self.config = load_config("config/trello-config.yaml")
        self.cards_with_external_ids = []
        self.labels = {}

        app_key = self.config['app_key']
        token = self.config['token']
        board_id = self.config['board_id']

        self.board = TrelloClient(api_key=app_key, token=token).get_board(board_id)
        self.classify_board()
        self.log.debug("Connecting to Trello board {0}".format(board_id))
Example #28
0
    def take_action(self, parsed_args):
        logging.getLogger("requests").setLevel(logging.WARNING)
        self.tr = TrelloClient(
            api_key=parsed_args.trello_key,
            api_secret=parsed_args.trello_secret,
            token=parsed_args.trello_token,
            token_secret=parsed_args.trello_token_secret)
        self.log.debug(self.tr.list_boards())
        try:
            self.board = [
                board for board in self.tr.list_boards()
                if board.name == parsed_args.board
            ][0]
        except IndexError:
            raise Exception(
                "Board {0} doesn't exist".format(parsed_args.board))
        self.log.debug(self.board)

        def get_card_type(card):
            l_names = [l.name for l in card.labels]
            if 'tech-debt' in l_names:
                return 'tech-debt'
            return 'bug'

        def get_list_type(list):
            if (
                'New' in list.name or
                'Inbox' in list.name or
                'Assigned' in list.name or
                'Triaged' in list.name or
                'Blocked' in list.name
            ):
                return 'open'
            if (
                'In Progress' in list.name
            ):
                return 'in progress'
            if 'Fix Committed' in list.name:
                return 'done'
            if (
                'Incomplete' in list.name or
                'Won\'t Fix' in list.name or
                'Trash' in list.name
            ):
                return 'rejected'
            return 'unknown'

        stats = [
            get_card_type(c) + ":" + get_list_type(c.get_list())
            for c in self.board.open_cards()
        ]
        for s in sorted(set(stats)):
            self.log.info("{0}: {1}".format(s, stats.count(s)))
def sync(events, token):
    trello = TrelloClient(api_key=TRELLO_KEY, token=token)
    board = trello.get_board("55f7167c46760fcb5d68b385")

    far_away, less_2_months, less_1_month, less_1_week, today, past = board.all_lists()

    all_cards = {card_id(c): c for c in board.all_cards()}

    date_today = datetime.date.today()

    for e in events:
        card = all_cards.get(e.id)

        if not card:
            card = create_card(e, far_away)
            create_checklist(card)

        # fetch card to get due date
        card.fetch()

        if e.date != card.due_date.date():
            print("Changing due date of {} to {}".format(e.city, e.date))
            card.set_due(e.date)

        distance = (e.date - date_today).days
        if distance < 0:
            right_list = past
        elif distance == 0:
            right_list = today
        elif distance < 7:
            right_list = less_1_week
        elif distance < 30:
            right_list = less_1_month
        elif distance < 60:
            right_list = less_2_months
        else:
            right_list = far_away

        ensure_card_in_list(card, right_list)
Example #30
0
    def make_trello_board(self):
        client = TrelloClient(
            api_key=self.auth["trello"]["api_key"],
            api_secret=self.auth["trello"]["api_secret"],
            token=self.auth["trello"]["token"],
            token_secret=self.auth["trello"]["token_secret"],
        )

        boards = client.list_boards()
        template = None

        for board in boards:
            if board.name == self.trello_template:
                template = board

        new_board = client.add_board(
            "DP: " + self.params["title"],
            source_board=template,
            permission_level="private"
        )
        self.params["trello_url"] = new_board.url
        print("Created Trello board - " + new_board.url)
Example #31
0
# Set up Trello environment variables, if failed here, please see the README.md
trelloKey = os.environ.get("TRELLO_API_KEY")
trelloSecret = os.environ.get("TRELLO_API_SECRET")
trelloToken = os.environ.get("TRELLO_TOKEN")
TeamName= os.environ.get("TEAM_NAME")
print TeamName
BoardName=os.environ.get("BOARD_NAME")

#TODO: Usecase3 only asks a person about progress. No matter how many cards are due. Later we'll refine it



client = TrelloClient(
    api_key = trelloKey,
    api_secret=trelloSecret,
    token=trelloToken,
    token_secret=None
)


def get_all_cards():
    opencards = testboard.open_cards()
    all_card_info=[]
    for c in opencards:
        card_info = []
        usernames = []
        # for userid in c.member_ids:
        #     user_name = members_dict[userid]
        # 'sheikhnasifimtiaz' is a slack name
        due_date = c.due
        card_id = c.id
Example #32
0
class TrelloClientTestCase(unittest.TestCase):

    """
    Tests for TrelloClient API. Note these test are in order to preserve dependencies, as an API
    integration cannot be tested independently.
    """

    def setUp(self):
        self._trello = TrelloClient(os.environ['TRELLO_API_KEY'], os.environ['TRELLO_TOKEN'])

    def tearDown(self):
        #self._trello.logout()
        pass

    def test01_list_boards(self):
        self.assertEquals(
                len(self._trello.list_boards()),
                int(os.environ['TRELLO_TEST_BOARD_COUNT']))

    def test10_board_attrs(self):
        boards = self._trello.list_boards()
        for b in boards:
            self.assertIsNotNone(b.id, msg="id not provided")
            self.assertIsNotNone(b.name, msg="name not provided")
            self.assertIsNotNone(b.description, msg="description not provided")
            self.assertIsNotNone(b.closed, msg="closed not provided")
            self.assertIsNotNone(b.url, msg="url not provided")

    def test20_board_all_lists(self):
        boards = self._trello.list_boards()
        for b in boards:
            try:
                b.all_lists()
            except Exception as e:
                self.fail("Caught Exception getting lists")

    def test21_board_open_lists(self):
        boards = self._trello.list_boards()
        for b in boards:
            try:
                b.open_lists()
            except Exception as e:
                self.fail("Caught Exception getting open lists")

    def test22_board_closed_lists(self):
        boards = self._trello.list_boards()
        for b in boards:
            try:
                b.closed_lists()
            except Exception as e:
                self.fail("Caught Exception getting closed lists")

    def test30_list_attrs(self):
        boards = self._trello.list_boards()
        for b in boards:
            for l in b.all_lists():
                self.assertIsNotNone(l.id, msg="id not provided")
                self.assertIsNotNone(l.name, msg="name not provided")
                self.assertIsNotNone(l.closed, msg="closed not provided")
            break # only need to test one board's lists

    def test40_list_cards(self):
        boards = self._trello.list_boards()
        for b in boards:
            for l in b.all_lists():
                for c in l.list_cards():
                    self.assertIsNotNone(c.id, msg="id not provided")
                    self.assertIsNotNone(c.name, msg="name not provided")
                    self.assertIsNotNone(c.description, msg="description not provided")
                    self.assertIsNotNone(c.closed, msg="closed not provided")
                    self.assertIsNotNone(c.url, msg="url not provided")
                break
            break
        pass

    def test50_add_card(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 - no desc"
                    card = l.add_card(name)
                except Exception as e:
                    print(str(e))
                    self.fail("Caught Exception adding card")

                self.assertIsNotNone(card, msg="card is None")
                self.assertIsNotNone(card.id, msg="id not provided")
                self.assertEquals(card.name, name)
                self.assertIsNotNone(card.closed, msg="closed not provided")
                self.assertIsNotNone(card.url, msg="url not provided")
                break
            break
        if not card:
            self.fail("No card created")

    def test51_add_card(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")

                self.assertIsNotNone(card, msg="card is None")
                self.assertIsNotNone(card.id, msg="id not provided")
                self.assertEquals(card.name, name)
                self.assertEquals(card.description, description)
                self.assertIsNotNone(card.closed, msg="closed not provided")
                self.assertIsNotNone(card.url, msg="url not provided")
                break
            break
        if not card:
            self.fail("No card created")
Example #33
0
# -*- coding: utf-8 -*-
"""
Created on Fri Jan 12 11:03:28 2018

@author: louie.wong
"""
import Trello_credentials
from trello import TrelloClient
import pandas as pd
import numpy as np
DDBoard = TrelloClient(
    api_key=Trello_credentials.api_key).get_board('lr4kcjux')

pingpong = []

for i in DDBoard.get_cards():
    pingpong.append(str(i))

pingpong = pd.DataFrame(data=np.array(pingpong).T)
pingpong = pingpong[0].str.split('<Card').str[1].str.split(
    '>').str[0].str.lstrip()
#
#pingpong[0] = str(DDBoard.get_cards()[1:26]).split(' ,')
#pingpong[1] = str(DDBoard.get_cards()[27:]).split(' ,')

#pingpong = pd.DataFrame(np.array(pingpong))
Example #34
0
def main():
    parser = OptionParser(usage='Usage: %prog [options]')

    # look for the config file in ~/.trello.creds JSON
    # Should contain two keys
    #       api-key
    #       token
    default_config = os.path.expanduser('~')

    # TODO only shows Cards with a given Labels
    # TODO save current preferences into a config file (prefered board)
    # TODO build unit testing

    parser.add_option('-c',
                      dest='credentials',
                      help='location of the trello credential '
                      'json file (default ~/.trello.creds    ',
                      default="{}/.trello.creds".format(default_config))
    parser.add_option('-b',
                      '--list-boards',
                      dest='show_boards',
                      help='List all Boards available"',
                      action='store_true')
    parser.add_option('-B', dest='board', help='Active Board')
    parser.add_option('-l',
                      '--list-lanes',
                      dest='show_lanes',
                      help='List all Lanes available"',
                      action='store_true')
    parser.add_option('-L',
                      dest='lanes',
                      help='show only cards in lanes "Lane1,Lane2,Lane3"')
    parser.add_option('-m',
                      '--list-members',
                      dest='show_members',
                      help='List all members available',
                      action='store_true')
    parser.add_option('-s',
                      dest='show_labels',
                      help='show labels with cards',
                      action='store_true')
    parser.add_option('-M',
                      dest='members',
                      help='filter with a specific team member '
                      '(Names: coma separated list of names bob,sam,Luk all:'
                      'display everyone, none: display unassigned cards)')

    opts, args = parser.parse_args()

    try:
        with open(opts.credentials) as f:
            config = json.load(f)
            trello_api_key = config['api_key']
            trello_token = config['token']
    except (FileNotFoundError, json.JSONDecodeError):
        print('Trello Token information file {} '
              'could not be found or parsed.'.format(opts.credentials))
        print('')
        gather_token = input(
            "Do you want to entre your Trello token information now "
            "(see https://trello.com/app-key/) ? (Y/n) ")
        if gather_token == 'n':
            return 1
        trello_api_key = input('Please enter your Trello api key : ')
        trello_token = input('Please enter your Trello api token : ')
        save_token = input("Do you want to save those credentials for future "
                           "use of trello-cli? (Y/n) ")
        if save_token != 'n':
            try:
                data = {}
                data['api_key'] = trello_api_key
                data['token'] = trello_token
                with open(opts.credentials, 'w+') as f:
                    json.dump(data, (f))
            except (FileNotFoundError, json.JSONDecodeError):
                # TODO: Probably better error handling can be done here
                print("Something went wrong saving credentials")
                return 1

    the_boards = {}
    the_board_lanes = {}
    the_board_members = {}
    the_board_cards = []

    # TODO Catch error opening Trello here
    client = TrelloClient(api_key=trello_api_key, token=trello_token)

    # Get the list of boards available to current user
    for board in client.list_boards():
        the_boards[board.name] = board.id
        if opts.show_boards:
            print(board.name)

    # Exit after returning the board list
    if opts.show_boards:
        return 1

    # Pick the Active Board
    if opts.board:
        the_board = client.get_board(the_boards[opts.board])
    else:
        print("Active board missing, use -B \"Board Name\"")
        parser.print_help()
        return 0

    # Capture the board members in a dictionary
    for member in the_board.get_members():
        the_board_members[member.full_name] = member.id

    if opts.show_members:
        for name in the_board_members.keys():
            print(name)
        return 1

    if not opts.show_lanes and not opts.lanes:
        print("Missing lanes information")
        parser.print_help()
        return 1

    # Pick The Board Open Lanes
    for lane in the_board.get_lists('open'):
        if opts.show_lanes:
            print(lane.name)
        else:
            if opts.lanes:
                if lane.name in opts.lanes.split(","):
                    the_board_lanes[lane.name] = lane.id
            else:
                the_board_lanes[lane.name] = lane.id

    if opts.show_lanes:
        return 1

    # Capture all the cards from active lane into a dictionary
    for card in the_board.open_cards():
        if card.list_id in the_board_lanes.values():
            the_board_cards.append(card)

    # Simply show all the cards from said Lanes if no member selected
    if not opts.members:
        for lane in the_board_lanes:
            if the_board_cards:
                print("  {}".format(lane))
            drawCards(the_board_cards, opts.show_labels)
    elif opts.members.split(",")[0] == "none":
        for lane in the_board_lanes:
            card_list = []
            # Show the card only if nobody assigned to it
            # and the lane is in the list
            for card in list(
                    filter(
                        lambda x: len(x.member_id) == 0 and x.list_id ==
                        the_board_lanes[lane], the_board_cards)):
                card_list.append(card)
            if card_list:
                print("  {}".format(lane))
            drawCards(card_list, opts.show_labels)
    else:
        # Print active cards per member/lane
        for member in the_board_members:
            if opts.members.split(",")[0] == "all" or listInString(
                    opts.members, member):
                if list(
                        filter(
                            lambda x: the_board_members[member] in x.member_id,
                            the_board_cards)):
                    print(member)
                    for lane in the_board_lanes:
                        card_list = []
                        for card in list(
                                filter(
                                    lambda x: the_board_members[member] in x.
                                    member_id and x.list_id == the_board_lanes[
                                        lane], the_board_cards)):
                            card_list.append(card)
                        if card_list:
                            print("  {}".format(lane))
                        drawCards(card_list, opts.show_labels)
    return 0
Example #35
0
from dbEngine import db

client = commands.Bot(command_prefix='+')

with open(r'jiselConf.yaml') as file:
    # The FullLoader parameter handles the conversion from YAML
    # scalar values to Python the dictionary format
    jiselConf = yaml.load(file, Loader=yaml.FullLoader)

    print(jiselConf)

gyazo_client = Api(access_token=jiselConf['gyazo_token'])

trello_client = TrelloClient(
    api_key=jiselConf['trello']['api_key'],
    api_secret=jiselConf['trello']['api_secret'],
    token=jiselConf['trello']['token'],
)

scope = [
    'https://spreadsheets.google.com/feeds',
    'https://www.googleapis.com/auth/drive'
]

credentials = ServiceAccountCredentials.from_json_keyfile_name(
    jiselConf['goog'], scope)  # Your json file here
r = redis.Redis(host='localhost', port=6379, db=0)

gc = gspread.authorize(credentials)
curr_minute = datetime.datetime.now().minute
random_minute = random.randint(0, 30)
Example #36
0
 def setUp(self):
     self._trello = TrelloClient(os.environ['TRELLO_API_KEY'],
                                 token=os.environ['TRELLO_TOKEN'])
Example #37
0
class TrelloClientTestCase(unittest.TestCase):
    """

    Tests for TrelloClient API. Note these test are in order to
    preserve dependencies, as an API integration cannot be tested
    independently.

    """
    def setUp(self):
        self._trello = TrelloClient(os.environ['TRELLO_API_KEY'],
                                    token=os.environ['TRELLO_TOKEN'])

    def test01_list_boards(self):
        self.assertEquals(len(self._trello.list_boards()),
                          int(os.environ['TRELLO_TEST_BOARD_COUNT']))

    def test10_board_attrs(self):
        boards = self._trello.list_boards()
        for b in boards:
            self.assertIsNotNone(b.id, msg="id not provided")
            self.assertIsNotNone(b.name, msg="name not provided")
            self.assertIsNotNone(b.description, msg="description not provided")
            self.assertIsNotNone(b.closed, msg="closed not provided")
            self.assertIsNotNone(b.url, msg="url not provided")

    def test20_board_all_lists(self):
        boards = self._trello.list_boards()
        for b in boards:
            try:
                b.all_lists()
            except Exception:
                self.fail("Caught Exception getting lists")

    def test21_board_open_lists(self):
        boards = self._trello.list_boards()
        for b in boards:
            try:
                b.open_lists()
            except Exception:
                self.fail("Caught Exception getting open lists")

    def test22_board_closed_lists(self):
        boards = self._trello.list_boards()
        for b in boards:
            try:
                b.closed_lists()
            except Exception:
                self.fail("Caught Exception getting closed lists")

    def test30_list_attrs(self):
        boards = self._trello.list_boards()
        for b in boards:
            for l in b.all_lists():
                self.assertIsNotNone(l.id, msg="id not provided")
                self.assertIsNotNone(l.name, msg="name not provided")
                self.assertIsNotNone(l.closed, msg="closed not provided")
            break  # only need to test one board's lists

    def test50_list_cards(self):
        boards = self._trello.list_boards()
        for b in boards:
            for l in b.all_lists():
                for c in l.list_cards():
                    self.assertIsNotNone(c.id, msg="id not provided")
                    self.assertIsNotNone(c.name, msg="name not provided")
                    self.assertIsNotNone(c.description,
                                         msg="description not provided")
                    self.assertIsNotNone(c.closed, msg="closed not provided")
                    self.assertIsNotNone(c.url, msg="url not provided")
                break
            break
        pass

    def test51_fetch_cards(self):
        """
        Tests fetching all attributes for all cards
        """
        boards = self._trello.list_boards()
        for b in boards:
            for l in b.all_lists():
                for c in l.list_cards():
                    c.fetch()

                    self.assertIsInstance(c.date_last_activity,
                                          datetime,
                                          msg='date not provided')
                    self.assertTrue(len(c.board_id) > 0,
                                    msg='board id not provided')
                break
            break
        pass

    def test52_list_hooks(self):
        self.assertIsInstance(self._trello.list_hooks(), list)
class Trellist(object):
    """The main object - initialize and use run()

    :param apikey: Your api-key.
    :param apisecret: Your api secret token. Get it from a protected file that you don't commit. Keep it secret!
    :param boardname: Name of the board to work on.
    :param done_list_name: The name of the done list on your board. Only one.
    :param releases_list_name: The name of the list to put release cards on.
    :param create_comments: True by default. Create a comment on the release card for each done card
    :param create_release_if_zero_done: If nothing is done, should you make a sad empty release card?
    """
    def __init__(
        self,
        apikey,
        apisecret,
        boardname,
        done_list_name="done",
        releases_list_name="releases",
        create_release_if_zero_done=False,
        create_comments=True,
    ):
        self.client = TrelloClient(api_key=apikey, api_secret=apisecret)
        self.board = self.get_board(boardname)
        self.done = self.get_list_by_name(done_list_name)
        self.releases = self.get_list_by_name(releases_list_name)
        self.release_template = "{date} release: {count} done"
        self.card_summary_template = "- {card.name} {card.members_initials}"
        self.create_release_if_zero_done = create_release_if_zero_done
        self.create_comment_per_item = create_comments

    def run(self):
        """Runs through all the methods to perform the work"""
        logger.info(f"get all cards in the done board: {self.done.name}")
        cards = self.get_done_cards()
        logger.info(f"got {len(cards)} cards")
        if cards or self.create_release_if_zero_done:
            release_card = self.create_release_card(cards,
                                                    self.release_template,
                                                    self.card_summary_template)
            for card in cards:
                if self.create_comment_per_item:
                    self.add_comment_to_release(release_card, card)
                card.set_closed(True)
        logger.info("finished run")

    def get_board(self, board_name):
        """Gets the open board object by a name, otherwise raises an Error to
        let you know we don't have that board

        :param board_name: actual name of a board you have access to
        """
        board = self.first(self.client.list_boards(),
                           lambda b: b.name == board_name and not b.closed)
        if board:
            return board
        raise ValueError(
            ("Couldn't find an open board named '{}'. Check the name in your"
             " trello - are there extra quote marks in this message?"
             ).format(board_name))

    def get_list_by_name(self, name):
        """Iterate lists and get the first one matching the name passed in

        :param name: Name of a list on the board you've passed in
        """
        trello_list = self.first(self.board.list_lists(),
                                 lambda l: l.name == name)
        if trello_list:
            return trello_list
        raise ValueError(
            ("Couldn't find a list named '{}'. Check the name in your trello"
             " - are there extra quote marks in this message?").format(name))

    def get_card_members(self, card):
        """Return an array of Trello.Member objects of this card

        :param card:
        """
        return [self.get_member(member_id) for member_id in card.member_id]

    @lru_cache()
    def get_member(self, member_id):
        """Get a member. We only use our own function so that we can cache calls

        :param member_id:
        """
        return self.client.get_member(member_id)

    def first(self, iterable, condition):
        """Iterates an iterable and returns the first item that meets a condition or None

        :param iterable: An iterable to fetch the first itemm that meets condition
        :param condition: The condition to evaluate per item
        """
        return next((i for i in iterable if condition(i)), None)

    def get_done_cards(self):
        """Get every card from the done list"""
        return self.done.list_cards()

    def prep_card(self, card):
        """Take the card and add arrays of all member initials, full_names and usernames for use in templates

        :param card: a card to modify with extra information
        """

        card.members = self.get_card_members(card)
        card.members_initials = ""
        card.members_full_names = ""
        card.members_usernames = ""
        if len(card.members):
            card.members_initials = [
                member.initials for member in card.members
            ]
            card.members_full_names = [
                member.full_name for member in card.members
            ]
            card.members_usernames = [
                member.username for member in card.members
            ]
        return card

    def summarize_these(self, cards, template, prep_function):
        """Run a list of cards through a template and return those joined by newlines
        The template can reference any part of a Trello.card as well as 3 handy arrays
        - members_initials
        - members_full_names
        - members_usernames
        These will either have an empty string or an array of strings that show up nicely
        in string.format

        :param cards: Card objects to summarize
        :param template: A template for each card. We pass the full card to format
        :param prep_function: A function that will add make the card more friendly to format
        """
        summary = "\n".join([
            self.summarize_this(card, template, prep_function)
            for card in cards
        ])
        return summary

    def summarize_this(self, card, template, prep_function):
        """Summarize a card by passing it to a template after prepping it with values from a prep_function

        :param card: a Card to summarize
        :param template: a string template. We'll call format and pass in a prepped Card
        :param prep_function: use this to add extra information to the card 
        """
        card = prep_function(self, card)
        summary = template.format(card=card)
        return summary

    def create_release_card(self, cards, release_template,
                            card_summary_template):
        """Returns a new release card, with a title from template and description based on a summary of the cards

        :param cards: Cards in this release
        :param release_template: A format string for release card name that we pass in date and length of cards
        :param card_summary_template: A string we format with per each card
        """
        release_card_name = release_template.format(date=date.today(),
                                                    count=len(cards))
        # turn list of names of cards into a summary
        summary = self.summarize_these(cards,
                                       template=card_summary_template,
                                       prep_function=self.prep_card)
        logger.info(f"{summary}")
        release_card = self.releases.add_card(release_card_name, summary)
        return release_card

    def add_comment_to_release(
        self,
        release_card,
        card,
        comment_format="{card.name}\n{card.url}\n{card.description}",
    ):
        """add_comment_to_release

        :param release_card: A card to comment on
        :param card: A card to summarize in a comment
        :param comment_format: The template, passed in the card.
        """
        comment_text = comment_format.format(card=card)
        release_card.comment(comment_text)
Example #39
0
		"url": "Play Store URL goes here",
		"count": 0 (number of times requested)
	}, ...
]
"""
import sys
from ratelimit import limits
from trello import TrelloClient, Card
import json

# Load file and parse json
new_apps = json.load(open(sys.argv[1]))
new_apps = sorted(new_apps, key=lambda x: x["count"], reverse=True)

# connect to Trello API
client = TrelloClient(api_key=sys.argv[2], token=sys.argv[3])

# The ToDO list
todo = client.get_list('5f7f8dd1238edd7ceea5f81d')


# Method to create card (rate limited as to specification)
@limits(calls=100, period=10)
def sendCardCreationCall(trellist, name, appfilter):
    trellist.add_card(name=name, desc=appfilter, position="bottom")


# loop over apps to add
for app in new_apps:
    sendCardCreationCall(
        todo, app["name"],
Example #40
0
    def take_action(self, parsed_args):
        err_count = 0
        logging.getLogger("requests").setLevel(logging.WARNING)
        self.log.info('Connecting to Launchpad')
        self.lp = Launchpad.login_with('lp-report-bot',
                                       'production',
                                       version='devel')
        self.tr = TrelloClient(api_key=parsed_args.trello_key,
                               api_secret=parsed_args.trello_secret,
                               token=parsed_args.trello_token,
                               token_secret=parsed_args.trello_token_secret)
        try:
            self.board = [
                board for board in self.tr.list_boards()
                if board.name == parsed_args.board
            ][0]
        except IndexError:
            if parsed_args.create_board:
                self.board = self.tr.add_board(parsed_args.board)
                # for label in self.board.all_lists():
                #    #label.delete()
                #    #                    self.client.fetch_json(
                #    #            '/cards/' + self.id,
                #    #            http_method='DELETE')
                for list in self.board.open_lists():
                    list.close()
            else:
                raise Exception(
                    "Board {0} doesn't exist. Use --create-board argument" +
                    " in order to create it".format(parsed_args.board))
        self.log.info("Working with board {0}".format(self.board))
        self.tag_labels = parsed_args.use_labels
        self.cards = dict()
        self.untouched_cards = dict()
        for card in self.board.open_cards():
            groups = re.search('(\d+)', card.name)
            if not (groups is None):
                bug_id = groups.group(0)
                if bug_id not in self.cards:
                    self.untouched_cards[bug_id] = card
                    self.log.debug(
                        "Found existing card for bug {0}".format(bug_id))
                    self.cards[bug_id] = card
                else:
                    self.log.info(
                        "Killing duplicate card for bug {0}".format(bug_id))
                    card.delete()
        self.log.info("Found {0} existing cards".format(
            len(self.untouched_cards)))

        for prj_name in parsed_args.project:
            prj = self.lp.projects[prj_name]
            for f in parsed_args.filter:
                self.log.debug(f)
                filt = json.loads(f)
                if filt['milestone']:
                    filt['milestone'] = prj.getMilestone(
                        name=filt['milestone'])
                if 'assignee' in filt:
                    filt['assignee'] = self.lp.people[filt['assignee']]
                if 'status' not in filt:
                    filt['status'] = [
                        'New', 'Incomplete', 'Opinion', 'Invalid',
                        'Won\'t Fix', 'Expired', 'Confirmed', 'Triaged',
                        'In Progress', 'Fix Committed', 'Fix Released'
                    ]
                self.log.debug(filt)
                self.log.info("Searching for tasks in project %s" % prj_name)
                for task in prj.searchTasks(**filt):
                    self.log.info("Proceeding task %s" % task)
                    retries = 3
                    for i in range(retries):
                        try:
                            self.proceed_task(task)
                        except Exception as e:
                            if i < retries:
                                self.log.exception(e)
                                self.log.warning(
                                    "Got an exception for task %s, retrying" %
                                    task)
                                continue
                            else:
                                self.log.exception(e)
                                self.log.warning("Failed to proceed task %s" %
                                                 task)
                                err_count += 1
                        break
                for series in prj.series:
                    self.log.info("Searching for tasks in {0}:{1}".format(
                        str(prj.name), str(series.name)))
                    for task in series.searchTasks(**filt):
                        self.log.info("Proceeding task %s" % task)
                        retries = 3
                        for i in range(retries):
                            try:
                                self.proceed_task(task)
                            except Exception as e:
                                if i < retries:
                                    continue
                                else:
                                    self.log.exception(e)
                                    self.log.warning(
                                        "Failed to proceed task %s" % task)
                                    err_count += 1
                            break

        if self.untouched_cards:
            self.log.info("%d cards are out of scope" %
                          len(self.untouched_cards))
            try:
                out_of_scope_list = [
                    list for list in self.board.open_lists()
                    if list.name == 'Trash/Out of scope'
                ][0]
            except IndexError:
                out_of_scope_list = self.board.add_list('Trash/Out of scope')
            for card in self.untouched_cards.values():
                card.change_list(out_of_scope_list.id)

        self.log.info("Finished with %d errors" % err_count)
        if err_count > 0:
            return 1
        return 0
Example #41
0
class TrelloManager:
    """Manage Trello connection and data."""
    def __init__(self, api_key, api_secret, token):
        """Create a new TrelloManager using provided keys."""
        self._cl = TrelloClient(
            api_key=api_key,
            api_secret=api_secret,
            token=token,
        )

        # Start whitelisting no organization
        self._wl_org = set()
        # Start whitelisting no board
        self._wl_brd = set()

    def whitelist_org(self, oid):
        """Add an organization to whitelist, by ID."""
        self._wl_org.add(oid)

    def blacklist_org(self, oid):
        """Remove an organization from whitelist, by ID."""
        self._wl_org.discard(oid)

    def whitelist_brd(self, bid):
        """Whitelist a board by id."""
        self._wl_brd.add(bid)

    def blacklist_brd(self, bid):
        """Blacklist a board by id."""
        self._wl_brd.discard(bid)

    def org_names(self):
        """Fetch and return organization names."""
        return {o.name for o in self.fetch_orgs()}

    def fetch_orgs(self):
        """Generate organizations and their blacklistedness."""
        for o in self._cl.fetch_json('/members/me/organizations/'):
            yield Organization(o['id'], o['name'], o['id'] not in self._wl_org,
                               o['url'])

    def fetch_boards(self, org=None):
        """Generate boards (in given org) and their blacklistedness."""
        if org is None:
            for b in self._cl.fetch_json('/members/me/boards/'):
                # If board has not an organization, it is blacklisted iff
                # it's not in the whitelist
                bbl = b['id'] not in self._wl_brd

                # If board has an organization, it is blacklisted iff
                # both board or organization are not in whitelist
                # if b['idOrganization'] is not None:
                #    bbl = bbl or b['idOrganization'] not in self._wl_org

                yield Board(b['id'], b['name'], bbl, b['url'])
        else:
            orgs = list(self.fetch_orgs())
            id2na = {o.id: o.name for o in orgs}
            na2id = {o.name: o.id for o in orgs}

            # Convert names to id
            if org in na2id:
                org = na2id[org]

            # Cannot find ID
            if org not in id2na:
                return

            for b in self._cl.fetch_json(f'/organizations/{org}/boards/'):
                bl = b['id'] not in self._wl_brd
                yield Board(b['id'], b['name'], bl, b['url'])

    def fetch_lists(self, board):
        """Generate lists in given board."""
        raise NotImplemented
        # for l in board.list_lists():
        #    yield l

    def fetch_cards(self, lid=None, bid=None):
        """Generate cards from list, board or everything."""
        if bid is not None:
            seq = self._cl.fetch_json(f'/boards/{bid}/cards')
        elif lid is not None:
            seq = self._cl.fetch_json(f'/lists/{lid}/cards')
        else:
            seq = self._cl.fetch_json(f'/members/me/cards')

        for c in seq:
            if c['due'] is not None:
                c['due'] = parse_date(c['due'])
            yield Card(c['id'], c['name'], c['url'], c['due'],
                       c['dueComplete'])

    def deprecated_fetch_data(self):
        """Fetch all the data from the server, updating cache."""
        logging.info('TrelloManager: fetching_data list_organizations')
        self._orgs = []
        self._boards = []
        self._lists = []
        self._cards = []
        for o in self.fetch_orgs():
            # Skip blacklisted boards
            if o.blacklisted:
                continue
            self._orgs.append(o)
            for b, bbl in self.fetch_boards(o):
                # Skip blacklisted boards
                if bbl:
                    continue
                self._boards.append(b)
                for l in self.fetch_lists(b):
                    self._lists.append(l)
                    for c in self.fetch_cards(l):
                        self._cards.append(c)
                        yield (o, b, l, c)
Example #42
0
class TrelloCmd(Command):
    "Update trello board from launchpad filters"

    log = logging.getLogger(__name__)

    def get_parser(self, prog_name):
        parser = super(TrelloCmd, self).get_parser(prog_name)
        parser.add_argument(
            '--filter',
            type=str,
            action='append',
            required=True,
            help="List of params for searchTasks",
        )
        parser.add_argument('--project',
                            type=str,
                            action='append',
                            required=True,
                            help="Project")
        parser.add_argument('--board',
                            type=str,
                            required=True,
                            help="Trello board name")
        parser.add_argument(
            '--trello-key',
            type=str,
            required=False,
            help="You can get one at https://trello.com/app-key")
        parser.add_argument(
            '--trello-secret',
            type=str,
            required=False,
            help="You can get one at https://trello.com/app-key")
        parser.add_argument(
            '--trello-token',
            type=str,
            required=False,
            help="You can get one at https://trello.com/1/connect?" +
            "key=YOUR_TRELLO_KEY&name=bugfix-app&response_type=token&" +
            "scope=read,write&expiration=never")
        parser.add_argument(
            '--trello-token-secret',
            type=str,
            required=False,
        )
        parser.add_argument('--create-board',
                            action='store_true',
                            help='Create Trello board if not exists')
        parser.add_argument(
            '--use-labels',
            nargs='+',
            help='Labels for cards',
            default=['tricky', 'low-hanging-fruit', 'tech-debt'])
        return parser

    def take_action(self, parsed_args):
        err_count = 0
        logging.getLogger("requests").setLevel(logging.WARNING)
        self.log.info('Connecting to Launchpad')
        self.lp = Launchpad.login_with('lp-report-bot',
                                       'production',
                                       version='devel')
        self.tr = TrelloClient(api_key=parsed_args.trello_key,
                               api_secret=parsed_args.trello_secret,
                               token=parsed_args.trello_token,
                               token_secret=parsed_args.trello_token_secret)
        try:
            self.board = [
                board for board in self.tr.list_boards()
                if board.name == parsed_args.board
            ][0]
        except IndexError:
            if parsed_args.create_board:
                self.board = self.tr.add_board(parsed_args.board)
                # for label in self.board.all_lists():
                #    #label.delete()
                #    #                    self.client.fetch_json(
                #    #            '/cards/' + self.id,
                #    #            http_method='DELETE')
                for list in self.board.open_lists():
                    list.close()
            else:
                raise Exception(
                    "Board {0} doesn't exist. Use --create-board argument" +
                    " in order to create it".format(parsed_args.board))
        self.log.info("Working with board {0}".format(self.board))
        self.tag_labels = parsed_args.use_labels
        self.cards = dict()
        self.untouched_cards = dict()
        for card in self.board.open_cards():
            groups = re.search('(\d+)', card.name)
            if not (groups is None):
                bug_id = groups.group(0)
                if bug_id not in self.cards:
                    self.untouched_cards[bug_id] = card
                    self.log.debug(
                        "Found existing card for bug {0}".format(bug_id))
                    self.cards[bug_id] = card
                else:
                    self.log.info(
                        "Killing duplicate card for bug {0}".format(bug_id))
                    card.delete()
        self.log.info("Found {0} existing cards".format(
            len(self.untouched_cards)))

        for prj_name in parsed_args.project:
            prj = self.lp.projects[prj_name]
            for f in parsed_args.filter:
                self.log.debug(f)
                filt = json.loads(f)
                if filt['milestone']:
                    filt['milestone'] = prj.getMilestone(
                        name=filt['milestone'])
                if 'assignee' in filt:
                    filt['assignee'] = self.lp.people[filt['assignee']]
                if 'status' not in filt:
                    filt['status'] = [
                        'New', 'Incomplete', 'Opinion', 'Invalid',
                        'Won\'t Fix', 'Expired', 'Confirmed', 'Triaged',
                        'In Progress', 'Fix Committed', 'Fix Released'
                    ]
                self.log.debug(filt)
                self.log.info("Searching for tasks in project %s" % prj_name)
                for task in prj.searchTasks(**filt):
                    self.log.info("Proceeding task %s" % task)
                    retries = 3
                    for i in range(retries):
                        try:
                            self.proceed_task(task)
                        except Exception as e:
                            if i < retries:
                                self.log.exception(e)
                                self.log.warning(
                                    "Got an exception for task %s, retrying" %
                                    task)
                                continue
                            else:
                                self.log.exception(e)
                                self.log.warning("Failed to proceed task %s" %
                                                 task)
                                err_count += 1
                        break
                for series in prj.series:
                    self.log.info("Searching for tasks in {0}:{1}".format(
                        str(prj.name), str(series.name)))
                    for task in series.searchTasks(**filt):
                        self.log.info("Proceeding task %s" % task)
                        retries = 3
                        for i in range(retries):
                            try:
                                self.proceed_task(task)
                            except Exception as e:
                                if i < retries:
                                    continue
                                else:
                                    self.log.exception(e)
                                    self.log.warning(
                                        "Failed to proceed task %s" % task)
                                    err_count += 1
                            break

        if self.untouched_cards:
            self.log.info("%d cards are out of scope" %
                          len(self.untouched_cards))
            try:
                out_of_scope_list = [
                    list for list in self.board.open_lists()
                    if list.name == 'Trash/Out of scope'
                ][0]
            except IndexError:
                out_of_scope_list = self.board.add_list('Trash/Out of scope')
            for card in self.untouched_cards.values():
                card.change_list(out_of_scope_list.id)

        self.log.info("Finished with %d errors" % err_count)
        if err_count > 0:
            return 1
        return 0

    def get_task_reviews(self, task):
        self.log.debug("Searching for reviews for task {0}".format(task))
        bug = task.bug
        gerrits = [
            'https://review.openstack.org/', 'https://review.fuel-infra.org/'
        ]
        reviews = []
        # Message number 0 is description
        is_description = True
        for msg in bug.messages:
            if is_description:
                is_description = False
                continue
            for g in gerrits:
                reviews += re.findall(g + '\d+', msg.content)
                long_reviews = re.findall(g + '#/c/\d+', msg.content)
                for u in long_reviews:
                    reviews += [u.replace('#/c/', '')]
        open_reviews = []
        for rev_url in set(reviews):
            [base_url, id] = rev_url.rsplit('/', 1)
            rest = GerritRestAPI(base_url)
            try:
                review = rest.get('/changes/{0}/detail'.format(id))
                if review['status'] == 'NEW':
                    status = []
                    if 'rejected' in review['labels']['Workflow']:
                        status.append('WIP')
                    if 'disliked' in review['labels']['Verified']:
                        status.append('FAIL')
                    open_reviews.append({'url': rev_url, 'status': status})
                    self.log.debug("Found open review {0}".format(rev_url))
            except Exception:
                pass

        return open_reviews

    def get_task_list(self, task):
        list_name = 'Bad Status'
        try:
            if task.status in ['Confirmed']:
                if task.assignee is None or task.assignee.is_team:
                    list_name = 'Inbox/Need triage'
                else:
                    list_name = 'Assigned/Investigating'
            if task.status in ['Incomplete']:
                list_name = 'Incomplete/Need more info'
            if task.status in ['Triaged']:
                list_name = 'Triaged/Ready to be fixed'
            if task.status in ['In Progress']:
                if self.get_task_reviews(task):
                    list_name = 'In Progress/Need review'
                else:
                    list_name = 'In Progress/Working on fix'
            if task.status in ['Fix Committed', 'Fix Released']:
                list_name = 'Fix Committed/Done'
            if task.status in ['Invalid', 'Opinion', 'Won\'t Fix']:
                list_name = 'Won\'t Fix/Done'
            if task.status in ['New']:
                list_name = 'New/Need confirmation'
            # if (
            #     not filter(lambda x: x.startswith('team-'), task.bug.tags)
            #     and 'tech-debt' not in task.bug.tags and
            #     task.status in [
            #         'New', 'Confirmed', 'Triaged', 'In Progress',
            #         'Incomplete']
            #     ):
            #     list_name = 'New/Need confirmation'
            if 'blocked' in task.bug.tags:
                list_name = 'Blocked/On hold'
            return [
                list for list in self.board.open_lists()
                if list.name == list_name
            ][0]
        except IndexError:
            return self.board.add_list(list_name)

    def get_task_labels(self, task):
        bug = task.bug
        tags = list(set(bug.tags).intersection(self.tag_labels))
        # Each bug should have either team tag or no-team tag or tech-debt tag
        team_tags = filter(lambda x: x.startswith('team-'), bug.tags)
        if team_tags:
            tags += team_tags
        else:
            if 'tech-debt' not in bug.tags:
                tags += ['no-team']
        if not filter(lambda x: x.startswith('area-'), task.bug.tags):
            tags += ['no-area']
        # if task.importance in ['Critical', 'High']:
        #     tags.append('high-priority')
        return tags

    def get_card_title(self, task):
        bug = task.bug
        assignee_id = "unassigned"
        if task.assignee_link is not None:
            assignee_id = task.assignee_link.split('~')[-1]
        return u'Bug {0} ({1}): {2}'.format(bug.id, assignee_id,
                                            bug.title)[:200]

    def get_card_description(self, task, card_list):
        bug = task.bug
        desc = "Created by {0}\n".format(bug.owner_link.split('~')[-1])
        desc += bug.web_link + "\n"
        if card_list.name == 'In Progress/Need review':
            desc += "Reviews:\n" + "\n".join(
                map(
                    lambda x: u"{0} {1}".format(x['url'], ':'.join(x[
                        'status'])), self.get_task_reviews(task))) + "\n"
        desc += "\n----------\n" + bug.description
        return desc[:1000]

    def proceed_task(self, task):
        self.log.debug("Processing task {0}".format(task))
        bug = task.bug
        card_list = self.get_task_list(task)
        if str(bug.id) not in self.cards:
            self.log.debug("Creating card for bug {0}".format(bug.id))
            card = card_list.add_card(
                self.get_card_title(task),
                self.get_card_description(task, card_list))
            self.cards[bug.id] = card
        else:
            self.log.debug("Getting card for task {0}".format(task))
            card = self.cards[str(bug.id)]
            try:
                del self.untouched_cards[str(bug.id)]
            except KeyError:
                pass
            self.log.debug(
                ("Updating existing card for bug {0}, moving to {1} list"
                 ).format(bug.id, card_list))
            card.change_list(card_list.id)
            new_name = self.get_card_title(task)
            if new_name != card.name.decode('utf-8'):
                card.set_name(new_name)
            new_desc = self.get_card_description(task, card_list)
            if new_desc != card.description:
                card.set_description(new_desc)
        tags = self.get_task_labels(task)
        for label in card.labels:
            if label.name not in tags:
                # delete_label is not published on pypi yet
                # card.delete_label(label)
                card.client.fetch_json('/cards/' + card.id + '/idLabels/' +
                                       label.id,
                                       http_method='DELETE')
        for label_name in tags:
            try:
                label = [
                    l for l in self.board.get_labels() if l.name == label_name
                ][0]
            except IndexError:
                label = self.board.add_label(label_name, 'green')
            try:
                card.add_label(label)
            except Exception:
                pass
        self.log.debug(task)
Example #43
0
import discord
from discord.ext import commands
from trello import TrelloClient

client = commands.Bot(command_prefix='>')
tclient = TrelloClient(
    api_key='',
    token='')

@client.command()
@commands.has_permissions(manage_channels=True)
async def project(ctx, command, *name: str):
    if command == "create":
        board = tclient.add_board(' '.join(name))
        mainm = await ctx.send('Creating Project Structure for '+' '.join(name))
        cate = await ctx.guild.create_category(" ".join(name))
        info = await ctx.guild.create_text_channel("info", category=cate)
        await info.set_permissions(ctx.guild.default_role, send_messages=False)
        await info.send(f"`Title:` {' '.join(name)}\n`Status:` In Development")
        await ctx.guild.create_text_channel("general-discussion", category=cate)
        await ctx.guild.create_text_channel("artwork", category=cate)
        await ctx.guild.create_text_channel("code", category=cate)
        await ctx.guild.create_text_channel("models", category=cate)
        await ctx.guild.create_voice_channel("Discussion", category=cate)

        await mainm.edit(content=f"Created Project Structure for{' '.join(name)}")

    elif command == "delete":
        cate = None
        for project in ctx.guild.categories:
            if project.name.lower() == ' '.join(name).lower():
from trello import TrelloClient
import requests
import re
import os
import timeit

start = timeit.default_timer()

client = TrelloClient(
    api_key='f0f3c926292bcce056db551471e95247',
    api_secret='3aa90a9a950fec265b7629381e4f9f5d9e432f8a79365ea93f2e027a6b5fb1e5',
    token='c6c08bb22bf251ecf4c978ac63a41e896b4c6cde75f48b4b8a36cfb2e83637f1'
)

board = client.list_boards()[13]
# print(board)
# for list in 
# print(board.open_lists())


list_id = board.open_lists()[0].id
my_list = board.get_list(list_id)

cards = my_list.list_cards()

print(cards)
attachments = []
for card in cards:
    # print(card.name)
    for i in range(1,4):
        attachment_name = card.get_attachments()[i].name
Example #45
0
 def __init__(self, api_key, token):
     self.client = TrelloClient(api_key=api_key, token=token)
import telegram
from dateutil.relativedelta import relativedelta
from trello import TrelloClient

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler('./result.log')

formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)

client = TrelloClient(
    api_key='trello_apikey',
    api_secret='api_api_secret',
    token='trello_auth_token',
)
result = "=24hour================================================\n"
overresult = "=over due================================================\n"
all_boards = client.list_boards()

n = 1  # board_id_sequence
for temp_card in all_boards[n].open_cards():
    # if (temp_card.list_id == '534b2b07ba315558427390eb'):
    #     continue

    card_due = temp_card.due_date

    if (card_due):
        temp_delta = relativedelta(card_due.replace(tzinfo=None),
Example #47
0
class TrelloBoardTestCase(unittest.TestCase):
    """
    Tests for TrelloClient API. Note these test are in order to
    preserve dependencies, as an API integration cannot be tested
    independently.
    """
    def setUp(self):
        self._trello = TrelloClient(os.environ['TRELLO_API_KEY'],
                                    token=os.environ['TRELLO_TOKEN'])
        for b in self._trello.list_boards():
            if b.name == os.environ['TRELLO_TEST_BOARD_NAME']:
                self._board = b
                break
        try:
            self._list = self._board.open_lists()[0]
        except IndexError:
            self._list = self._board.add_list('List')

    def _add_card(self, name, description=None):
        try:
            card = self._list.add_card(name, description)
            self.assertIsNotNone(card, msg="card is None")
            self.assertIsNotNone(card.id, msg="id not provided")
            self.assertEquals(card.name, name)
            return card
        except Exception as e:
            print(str(e))
            self.fail("Caught Exception adding card")

    def test40_add_card(self):
        name = "Testing from Python - no desc"
        card = self._add_card(name)

        self.assertIsNotNone(card.closed, msg="closed not provided")
        self.assertIsNotNone(card.url, msg="url not provided")

        card2 = self._trello.get_card(card.id)
        self.assertEqual(card.name, card2.name)

    def test41_add_card(self):
        name = "Testing from Python"
        description = "Description goes here"
        card = self._add_card(name, description)

        self.assertEquals(card.description, description)
        self.assertIsNotNone(card.closed, msg="closed not provided")
        self.assertIsNotNone(card.url, msg="url not provided")
        card.fetch()
        self.assertIsNotNone(card.member_id)
        self.assertIsNotNone(card.short_id)
        self.assertIsNotNone(card.list_id)
        self.assertIsNotNone(card.comments)
        self.assertIsNotNone(card.checklists)
        self.assertIsInstance(card.create_date, datetime)

    def test42_add_card_with_comments(self):
        name = "Card with comments"
        comment = "Hello World!"
        card = self._add_card(name)
        card.comment(comment)
        card.fetch(True)

        self.assertEquals(card.description, '')
        self.assertIsNotNone(card.closed, msg="closed not provided")
        self.assertIsNotNone(card.url, msg="url not provided")
        self.assertEquals(len(card.comments), 1)
        self.assertEquals(card.comments[0]['data']['text'], comment)

    def test43_delete_checklist(self):
        name = "Card with comments"
        card = self._list.add_card(name)
        card.fetch(True)

        name = 'Checklists'
        checklist = card.add_checklist(name, ['item1', 'item2'])
        self.assertIsNotNone(checklist, msg="checklist is None")
        self.assertIsNotNone(checklist.id, msg="id not provided")
        self.assertEquals(checklist.name, name)
        checklist.delete()
        card.delete()

    def test44_attach_url_to_card(self):
        name = "Testing from Python - url"
        card = self._add_card(name)

        card.attach(name='lwn', url='http://lwn.net/')
        card.fetch()
        self.assertEquals(card.badges['attachments'], 1)
        card.delete()

    def test52_get_cards(self):
        cards = self._board.get_cards()
        self.assertEquals(len(cards), 4)

        for card in cards:
            if card.name == 'Testing from Python':
                self.assertEqual(card.description, 'Description goes here')
            elif card.name == 'Testing from Python - no desc':
                self.assertEqual(card.description, '')
            elif card.name == 'Card with comments':
                self.assertEqual(card.description, '')
            else:
                self.fail(msg='Unexpected card found')

        self.assertIsInstance(self._board.all_cards(), list)
        self.assertIsInstance(self._board.open_cards(), list)
        self.assertIsInstance(self._board.closed_cards(), list)

    def test52_add_card_set_due(self):
        name = "Testing from Python"
        description = "Description goes here"
        card = self._list.add_card(name, description)

        # Set the due date to be 3 days from now
        today = datetime.today()
        day_detla = 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)

    def test53_checklist(self):
        name = "Testing from Python"
        description = "Description goes here"
        card = self._list.add_card(name, description)

        name = 'Checklists'
        checklist = card.add_checklist(name, ['item1', 'item2'])
        self.assertIsNotNone(checklist, msg="checklist is None")
        self.assertIsNotNone(checklist.id, msg="id not provided")
        self.assertEquals(checklist.name, name)
        checklist.rename('Renamed')
        self.assertEquals(checklist.name, 'Renamed')

    def test54_set(self):
        name = "Testing from Python"
        description = "Description goes here"
        card = self._list.add_card('noname')
        card.set_name(name)
        card.set_description(description)
        self.assertEquals(card.name, name)
        self.assertEquals(card.description, description)

    def test60_delete_cards(self):
        cards = self._board.get_cards()
        for card in cards:
            card.delete()

    def test70_all_members(self):
        self.assertTrue(len(self._board.all_members()) > 0)

    def test71_normal_members(self):
        self.assertTrue(len(self._board.normal_members()) >= 0)

    def test72_admin_members(self):
        self.assertTrue(len(self._board.admin_members()) > 0)

    def test73_owner_members(self):
        members = self._board.owner_members()
        self.assertTrue(len(members) > 0)
        member = members[0].fetch()
        self.assertNotEqual(member.status, None)
        self.assertNotEqual(member.id, None)
        self.assertNotEqual(member.bio, None)
        self.assertNotEqual(member.url, None)
        self.assertNotEqual(member.username, None)
        self.assertNotEqual(member.full_name, None)
        self.assertNotEqual(member.initials, None)
        member2 = self._trello.get_member(member.id)
        self.assertEqual(member.username, member2.username)

    def test80_unauthorized(self):
        client = TrelloClient('a')
        self.assertRaises(Unauthorized, client.list_boards)

    def test81_resource_unavailable(self):
        self.assertRaises(ResourceUnavailable, self._trello.get_card, '0')

    def test90_get_board(self):
        board = self._trello.get_board(self._board.id)
        self.assertEqual(self._board.name, board.name)
Example #48
0
def tasks_by_tag(request, tag_slug=None):
    u = request.user

    inf = Profile.objects.get(user=u)
    if inf.api_key and inf.api_secret:
        key = inf.api_key
        secret = inf.api_secret
        try:
            client = TrelloClient(api_key=key, api_secret=secret)
        except:
            messages.info(request, "Неправильные данные trello")
        trello_board = client.list_boards()[0]
        trello_list = trello_board.list_lists()[-1]
        tasks_from_trello = trello_list.list_cards()

    def filter_tags(tags_by_task):
            list_of_tags = []
            for e in tags_by_task:
                for e2 in e:
                    list_of_tags.append(e2)
            uniq_list_of_tags = set(list_of_tags)
            return uniq_list_of_tags

    tasks = TodoItem.objects.filter(owner=u).all()

    tag = None
    if tag_slug:
        tag = get_object_or_404(Tag, slug=tag_slug)
        tasks = tasks.filter(tags__in=[tag])

    tags_of_task = []
    for task in tasks:
        taska = task.description
        taga = task.tags.all()
        both = (taska, taga)
        tags_of_task.append(both)
        


    all_tags = []
    for t in tasks:
        all_tags.append(list(t.tags.all()))
    all_tags = filter_tags(all_tags)

    hmt = tasks.count()
    hmt_cmpl = tasks.filter(is_completed=True).count()


    def tags(task):
        intersect = list(filter(lambda x: x in task.tags.all(), all_tags))
        return intersect

#    tags_of_tasks = {}
#   for t in tasks:
#        for tt in list(t.tags.all()):
#            if t.description in tags_of_tasks:
#                tags_of_task[t.description] += tt
#            else:
#                tags_of_task[t.description] = list(tt)


    return render(
        request,
        "tasks/list_by_tag.html",
        {
        "tag": tag,
        "tasks": tasks,
        "all_tags": all_tags,
        "how_much": hmt,
        "hmt_cmpl": hmt_cmpl,
        "tags": tags,
        "trello": tasks_from_trello,
        "tags_and_task": tags_of_task,
        },
    )
Example #49
0
 def test80_unauthorized(self):
     client = TrelloClient('a')
     self.assertRaises(Unauthorized, client.list_boards)
Example #50
0
 def __init__(self):
     self.client = TrelloClient(
         api_key=os.getenv('TRELLO_API_KEY'),
         api_secret=os.getenv('TRELLO_API_SECRET'),
         token=os.getenv('OAUTH_TOKEN'),
         token_secret=os.getenv('OAUTH_TOKEN_SECRET'))
Example #51
0
# Reading configuration and authentication data
with open(CONFIG_FILE_NAME, 'r') as conf_file:
    conf_data = json.load(conf_file)
auth_data = conf_data[AUTH_DATA_KEY]

# Logging in to Pocket
pocket_consumer_key = conf_data[AUTH_DATA_KEY]['pocket_consumer_key']
pocket_client = Pocket(
    conf_data[AUTH_DATA_KEY]['pocket_consumer_key'],
    conf_data[AUTH_DATA_KEY]['pocket_user_credentials']['access_token'])
logger.info('Logged in to Pocket')

# Logging in to Trello
trello_client = TrelloClient(
    api_key=conf_data[AUTH_DATA_KEY]['trello_api_key'],
    token=conf_data[AUTH_DATA_KEY]['trello_token'])
trello_list = trello_client.get_list(conf_data['trello_list_id'])
logger.info('Logged in to Trello')

now_timestamp = int(datetime.now().timestamp())
since_timestamp = conf_data[
    'pocket_last_checked'] if 'pocket_last_checked' in conf_data else now_timestamp

new_pocket_items, _ = pocket_client.get(since=since_timestamp)
logger.info('Fetched new Pocket items')

if len(new_pocket_items['list']) == 0:
    logger.info('No new items.')
else:
    for pocket_item_id, pocket_item_data in new_pocket_items['list'].items():
Example #52
0
    def post(self):
        """ Collect data from the HTML form to fill in a Trello card.

        That card will be uploaded to Suggestion Box board, on the corresponding
        list, determined by the "System" attribute given in the form.
        """
        # Get form data
        date = datetime.now()
        title = self.get_argument('title')
        area = self.get_argument('area')
        system = self.get_argument('system')
        importance = self.get_argument('importance')
        difficulty = self.get_argument('difficulty')
        user = self.get_current_user()
        description = self.get_argument('description')
        suggestion = self.get_argument('suggestion')

        client = TrelloClient(api_key=self.application.trello_api_key,
                              api_secret=self.application.trello_api_secret,
                              token=self.application.trello_token)

        # Get Suggestion Box board
        boards = client.list_boards()
        suggestion_box = None
        for b in boards:
            if b.name == 'Suggestion Box':
                suggestion_box = client.get_board(b.id)
                break

        # Get the board lists (which correspond to System in the form data) and
        # concretely get the list where the card will go
        lists = b.all_lists()
        card_list = None
        for l in lists:
            if l.name == system:
                card_list = l
                break

        # Create new card using the info from the form
        new_card = card_list.add_card(
            TITLE_TEMPLATE.format(title=title, area=area))
        new_card.set_description(
            DESCRIPTION_TEMPLATE.format(date=date.ctime(),
                                        area=area,
                                        system=system,
                                        importance=importance,
                                        difficulty=difficulty,
                                        user=user.name,
                                        description=description,
                                        suggestion=suggestion))

        # Save the information of the card in the database
        self.application.suggestions_db.create({
            'date': date.isoformat(),
            'card_id': new_card.id,
            'description': new_card.description,
            'name': new_card.name,
            'url': new_card.url,
            'archived': False
        })

        self.set_status(200)
class TrelloCollector(object):
    """
    Class representing all Trello information required to do the SysDesEng reporting.
    """

    def __init__(self, report_config, trello_secret):
        self.logger = logging.getLogger(__name__)
        self.client = TrelloClient(api_key = trello_secret[':consumer_key'],
                                   api_secret = trello_secret[':consumer_secret'],
                                   token = trello_secret[':oauth_token'],
                                   token_secret = trello_secret[':oauth_token_secret'])

        #Extract report configuration parameters
        trello_sources = report_config[':trello_sources'];
        #self.report_parameters = report_config[':output_metadata'];
        gen_date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")

        self.content = { ':output_metadata' : {
                              ':gen_date': gen_date, #Report name is built as :report_name + gen_date (where :report_name is taken from the config)
                              ':trello_sources': {
                                 ':boards':{},
                                 ':lists': {},
                                 ':cards': [] }}}

        self.load_config(trello_sources, self.content[':output_metadata'][':trello_sources'])
        self.logger.debug("Report output metadata: %s" % (self.content[':output_metadata']))

    def load_config(self, config_src, report_metadata):
        """ load all config data related to trello sources and structure them in the report_metadata"""
        for card_type in config_src.keys(): #card_type is project|assignment|epic
            for board_t in config_src[card_type].keys():
                board_id = config_src[card_type][board_t][':board_id']
                if not board_id in report_metadata: # initialize if the board wasn't present during the iterations over other card_type's
                    if not board_id in report_metadata[':boards']:
                        report_metadata[':boards'][board_id] = {};
                    report_metadata[':boards'][board_id][':board_id'] = config_src[card_type][board_t][':board_id'] #copy board id
                    report_metadata[':boards'][board_id][':board_name'] = board_t
                    if not ':lists' in report_metadata[':boards'][board_id]:
                        report_metadata[':boards'][board_id][':lists'] = []

                #iterate through all the lists and populate them
                for list_t in config_src[card_type][board_t][':lists'].keys():
                    self.logger.debug("Adding board %s, list %s to the report" % (config_src[card_type][board_t][':board_id'], config_src[card_type][board_t][':lists'][list_t]))
                    list_id = config_src[card_type][board_t][':lists'][list_t]
                    report_metadata[':lists'][list_id] = {};
                    report_metadata[':lists'][list_id][':list_id'] = list_id
                    report_metadata[':lists'][list_id][':completed'] = False;
                    report_metadata[':lists'][list_id][':card_type'] = card_type;
                    report_metadata[':lists'][list_id][':board_id'] = board_id
                    report_metadata[':boards'][board_id][':lists'].append(list_id)
                if ':done_lists' in config_src[card_type][board_t]:
                    for list_t in config_src[card_type][board_t][':done_lists'].keys():
                        self.logger.debug("Adding board %s, Done list %s to the report" % (config_src[card_type][board_t][':board_id'], config_src[card_type][board_t][':done_lists'][list_t]))
                        list_id = config_src[card_type][board_t][':done_lists'][list_t]
                        report_metadata[':lists'][list_id] = {};
                        report_metadata[':lists'][list_id][':list_id'] = list_id
                        report_metadata[':lists'][list_id][':completed'] = True;
                        report_metadata[':lists'][list_id][':card_type'] = card_type;
                        report_metadata[':lists'][list_id][':board_id'] = board_id
                        report_metadata[':boards'][board_id][':lists'].append(list_id)

    def list_boards(self):
        syseng_boards = self.client.list_boards()
        for board in syseng_boards:
            for tlist in board.all_lists():
                self.logger.info('board name: %s is here, board ID is: %s; list %s is here, list ID is: %s' % (board.name, board.id, tlist.name, tlist.id)) 

    def parse_trello(self, deep_scan):
        """
        :deep_scan: If deep_scan is True the scan will traverse actions, otherwise just a light scan(much faster)
        Main function to parse all Trello boards and lists.
        """
        trello_sources = self.content[':output_metadata'][':trello_sources'];
        self.logger.debug('The sources are %s' % (trello_sources))

        for board_id in trello_sources[':boards'].keys():
            tr_board = self.client.get_board(board_id);
            tr_board.fetch(); # get all board properties
            members = [ (m.id, m.full_name) for m in tr_board.get_members()];
            trello_sources[':boards'][board_id][':members'] = members;
            self.logger.info('----- querying board %s -----' % (trello_sources[':boards'][board_id][':board_name']))
            self.logger.debug('Board members are %s' % (trello_sources[':boards'][board_id][':members']))

            #trello_sources[board_id][':cards'] = []
            cards = tr_board.get_cards();

    
            for card in cards:
                card_content = {}
                card_content[':name'] = card.name
                card_content[':id'] = card.id
                card_content[':members'] = []
                card_content[':board_id'] = tr_board.id
                for member_id in card.member_ids:
                    for (m_id, m_full_name) in members:
                        if member_id == m_id :
                           card_content[':members'].append((m_id,m_full_name))
                card_content[':desc'] = card.desc
                card_content[':short_url'] = card.url
                card_content[':labels'] = [(label.name,label.color) for label in card.labels]
                #self.logger.debug('Card: {0} | LABELES are {1}'.format(card_content[':name'], card_content[':labels']))
                card_content[':board_name'] = tr_board.name
                card_content[':list_id'] = card.list_id
                if card.due:
                    card_content[':due_date'] = arrow.get(card.due).format('YYYY-MM-DD HH:mm:ss')
                trello_sources[':cards'].append(card_content);

            self.logger.debug('%s cards were collected' % (len(cards)))

            tr_board.fetch_actions(action_filter="commentCard,updateCard:idList,createCard,copyCard,moveCardToBoard,convertToCardFromCheckItem",action_limit=1000);
            trello_sources[':boards'][board_id][':actions'] = sorted(tr_board.actions,key=lambda act: act['date'], reverse=True)
            self.logger.debug('%s actions were collected' % (len(trello_sources[':boards'][board_id][':actions'])))
            #self.logger.debug('Oldest action is %s' % (trello_sources[':boards'][board_id][':actions'][-1]))

            tr_lists = tr_board.all_lists()
            for tr_list in tr_lists:
                if tr_list.id in trello_sources[':lists']:
                    trello_sources[':lists'][tr_list.id][':name'] = tr_list.name;
            self.logger.info('the lists are %s' % (tr_lists))

        return self.content


    def parse_card_details(self, card_id):
        card = card_details.CardDetails(card_id, self.client, self.content[':output_metadata'])
        details = card.fill_details();
        #self.logger.debug('Card\'s details are: %s' % (details))
        return details
# Find a workbook by name and open the first sheet
# Make sure you use the right name here.
try:
    wks = client.open_by_url(
        'https://docs.google.com/spreadsheets/d/1bvZwG4J2_F1977kGKQ8xpRIsky0DXm5iJZwlfy1qYx4/edit#gid=0'
    ).worksheet('Sprint')
except (ValueError, NameError):
    print "Invalid URL"

slack_token = 'xoxp-245385053858-244739387712-263087848417-a00879edad580a942fd6d21752ff7e5b'
sc = SlackClient(slack_token)

client = TrelloClient(
    api_key='01d3f30b9fc6a6027e4ff6aebc5e1e51',
    api_secret=
    '10e77f89144a7fac3d6c08458d62ab2eb73dd398d8dc1a745a43f9b6218c3925',
    token='a6d76d00692bae27f064c8142d6789c7fdccdbe94a2847e559b50665f37cddaa',
    token_secret='0211b712c27726253211e5fd108e46e7')


def get_board_id(my_board):
    for board in client.list_boards():
        if my_board == board.name:
            return board.id


def get_list_id(board, my_list):
    for lista in board.list_lists():
        if lista.name == my_list:
            return lista.id
Example #55
0
def trelloinit(config):
    trelloconfig = config["trello"]
    client = TrelloClient(api_key=trelloconfig["api_key"],
                          api_secret=trelloconfig["api_secret"])
    return (client, client.get_board(trelloconfig["board_id"]))
Example #56
0
from trello import TrelloClient
import json

# api_key='your-key' - 05571f7ecf0d9177c020b9ab3495aaac
# api_secret='your-secret' - 03a65f30fb4946c03cba7998327f7e10025493f7e036408d6efbcdbd63fc66f5
# token='your-oauth-token-key' - 1316a12594687b611d0c631896b9b421436bd955d0d376162521c5ed267155d8
# token_secret='your-oauth-token-secret' - 5d0d9ac40b148703315c54e64b7998d2

client = TrelloClient(api_key='05571f7ecf0d9177c020b9ab3495aaac',
    api_secret='03a65f30fb4946c03cba7998327f7e10025493f7e036408d6efbcdbd63fc66f5',
    token='1316a12594687b611d0c631896b9b421436bd955d0d376162521c5ed267155d8',
    token_secret='5d0d9ac40b148703315c54e64b7998d2'
)

def getTableros(filtro=""):
    filtroPasado = filtro
    tableros = client.list_boards(board_filter=filtroPasado)
    lista = []
    
    registros = [(tn.name, tn.id) for tn in tableros]
    for f in registros:
        campos = ['nombre_tablero', 'id_tablero']
        convertir = dict(zip(campos, f))
        lista.append(convertir)
    tablerosDevolver = json.dumps(lista)
    return tablerosDevolver

# Obtener un tablero por su ID
tablero = client.get_board('57581f7d6a945e2f6630a793')
print(tablero)
Example #57
0
class TrelloAPI(object):
    TRELLO_API_KEY = os.getenv('TRELLO_API_KEY')
    MY_TOKEN = os.getenv('MY_TOKEN')
    TOKEN_SECRET = os.getenv('TOKEN_SECRET')
    CURRENT_YEAR_BOARD_NAME = 'My Goals'
    WEEKLY_PLANNING_BOARD_NAME = 'Weekly Planning'

    def __init__(self):
        try:
            self.client = TrelloClient(
                api_key=self.TRELLO_API_KEY,
                api_secret='your-secret',
                token=self.MY_TOKEN,
                token_secret=self.TOKEN_SECRET
            )
            self.all_current_year_lists = self._map_all_current_year_lists()
            self.all_week_lists = self._map_all_week_lists()
        except ConnectionError:
            print("There is a problem with internet connection")

    def _map_all_current_year_lists(self):
        board = self.get_current_year_board()
        board_name_to_id = {i.name: i for i in board.all_lists()}
        return board_name_to_id

    def _map_all_week_lists(self):
        board = self.get_my_week_board()
        board_name_to_id = {i.name: i for i in board.all_lists()}
        return board_name_to_id

    def get_yearly_tasks_list(self, list_name):
        if list_name in self.all_current_year_lists:
            return self.all_current_year_lists[list_name]
        else:
            current_board = self.get_current_year_board()
            tasks_list = TrelloAPI.get_list_by_name(board=current_board, list_name=list_name)
            return tasks_list

    def get_current_year_board(self):
        for board in self.get_boards():
            if board.name == self.CURRENT_YEAR_BOARD_NAME:
                return board
        raise BoardNotFoundException(('We cant find {} board.'.format(self.CURRENT_YEAR_BOARD_NAME)))

    def get_weekly_tasks_list(self, list_name):
        if list_name in self.all_week_lists:
            return self.all_week_lists[list_name]
        else:
            current_board = self.get_my_week_board()
            tasks_list = TrelloAPI.get_list_by_name(board=current_board, list_name=list_name)
            return tasks_list

    def get_my_week_board(self):
        for board in self.get_boards():
            if board.name == self.WEEKLY_PLANNING_BOARD_NAME:
                return board
        raise BoardNotFoundException('We cant find {} board.'.format(self.WEEKLY_PLANNING_BOARD_NAME))

    def get_boards(self):
        return self.client.list_boards()

    @staticmethod
    def get_list_by_name(board, list_name):
        board_name_to_id = {i.name: i for i in board.all_lists()}
        trello_list = board_name_to_id.get(list_name)
        if trello_list is None:
            raise ListNotFoundException("We can't find list {} in board {} !".format(list_name, board.name))
        return trello_list
Example #58
0
def trelloToSQL():
    '''
    Liest Trello-Karten aus Liste "Texte lektoriert" des "Play-Boards" aus
    und wandelt Sie mit Pandoc in html um. Inklusive Literaturverzeichnis.
    Zusätzlich werden ein paar weitere Formatierungen vorgenommen.
    Das Ergebnis wird dann in die Datenbank geschrieben.
    Die Trello-Karten werden hinterher verschoben.
    '''
    from Scholien.models import Artikel

    client = TrelloClient(api_key=settings.TRELLO_API_KEY, token=settings.TRELLO_TOKEN)
    play_board = client.get_board('55d5dfee98d40fcb68fc0e0b')
    played_board = client.get_board('55c4665a4afe2f058bd3cb0a')
    target_list = played_board.get_list('5774e15c515d20dd2aa0b534')

    for list in play_board.open_lists():
        if list.name == "Texte lektoriert":
            print('%d lektorierte(n) Text(e) gefunden.' % len(list.list_cards()))
            # Karten werden von unten nach oben abgearbeitet.
            for card in list.list_cards()[::-1]:
                title = card.name
                text = card.desc
                fobj_out = codecs.open(os.path.join(md_path, "%s.md" % title), "w", "utf-8")
                # meta = codecs.open("%s" %meta,"r","utf-8")
                # fobj_out.write(meta.read())

                # ids
                p = re.compile(r"§§.*")
                id = p.findall(text)
                id = id[0][2:] if id else title
                priority = 1 if id[0] == '!' else 0
                id = slugify(id)
                text = p.sub("", text, count=1)

                fobj_out.write("---\nbibliography: {}\n---\n\n{}\n\n## Literatur".format(bib, text))
                fobj_out.close

                # to html
                fobj_out = codecs.open(os.path.join(md_path, "%s.md" % title), "r", "utf-8")
                md = fobj_out.read()
                extra_args = []
                filters = ['pandoc-citeproc']
                html = pypandoc.convert(md, 'html', format='md',  extra_args=extra_args, filters=filters)

                # blockquotes mit class versehen
                p = re.compile("<blockquote>")
                html = p.sub("<blockquote class=\"blockquote\">", html)

                # Gedankenstriche ("--" nach "–")
                p = re.compile("--")
                html = p.sub("&ndash;", html)

                # Trennungszeichen
                p = re.compile(r"<p>&lt;&lt;&lt;</p>")
                split = re.split(p, html)
                public = split[0]
                # lstrip entfernt mögliche Absätze am Anfang.
                private = split[1].lstrip() if len(split) > 1 else ""
                if not private:
                    print('Keinen privaten Teil gefunden für', title)
                    # print(html)

                try:
                    art_neu = Artikel.objects.create(
                        slug=id, bezeichnung=title, inhalt=public,
                        inhalt_nur_fuer_angemeldet=private, prioritaet=priority
                    )  # *art_neu* currently not in use
                    print('%s erfolgreich in DB übertragen.' % title)
                except IntegrityError as e:
                    print('Artikel schon vorhanden')
                except Exception as e:
                    print(title, 'failed:', e)
                    continue

                card.change_board(played_board.id, target_list.id)
                card.set_pos('top')
Example #59
0
 def __init__(self):
     self.client = TrelloClient(
         api_key='XXXXXX',
         api_secret='XXXXXX',
         token='XXXXXX'
     )
Example #60
0
class DailyTrello(object):

    ##Init Trello connection
    def __init__(self):
        self.client = TrelloClient(
            api_key='XXXXXX',
            api_secret='XXXXXX',
            token='XXXXXX'
        )

    ##Access specific board and specific board list.
    ##I already knew my list id so I was able to use get_list
    def accessBoards(self):
        boards = self.client.list_boards()
        for b in boards:
            if b.name == "ToDo":
                board = b
                ##List id is the XXXXX param
                edit = board.get_list("XXXXX")
                return edit
        return None

    ##Other solution if ID is not known
    """
    def accessBoards(self):
        boards = self.client.list_boards()
        for b in boards:
            if b.name == "ToDo":
                board = b
                ############################
                ##None is the filter, some filter must be included
                lists = board.get_lists(None)
                ############################
                for list in lists:
                    if list.name == "THE LIST YOU'RE LOOKING FOR":
                        return list
        return None
    """

    ##How to find list ID
    """
    def findListID(self):
        boards = client.list_boards()
        for b in boards:
            if b.name == "ToDo":
                board = b
                ############################
                ##None is the filter, some filter must be included
                lists = board.get_lists(None)
                ############################
                for aList in lists:
                    if aList.name == "NAME OF LIST":
                        ################
                        print(aList.id)
                        ################
    """

    def dailyCheck(self):
        exeLoc = os.path.dirname(os.path.realpath(sys.argv[0]))
        os.chdir(exeLoc)
        os.chdir('..')
        os.chdir('..')
        fin = open(os.getcwd() + "\\cardData\\data.txt","r")
        lines = fin.readlines()
        fin.close()
        lines = [line.strip() for line in lines]
        ## second element is the date

        ## date.today() > datetime.datetime.strptime(lines[1],'%Y-%m-%d').date()
        ## check for new day
        
        if date.today() > datetime.datetime.strptime(lines[1],'%Y-%m-%d').date():
            fout = open(os.getcwd() + "\\cardData\\data.txt", "w")
            fout.write("Date:\n" + str(date.today()))
            fout.close()

            edit = self.accessBoards()

            try:
                fin = open(os.getcwd() + "\\cardData\\RepeatCards.txt", "r")
                cards = fin.readlines()
                cards = [card.strip() for card in cards]
                for c in cards:
                    edit.add_card(c)
            except:
                pass