~mapperr/trl

201aa0f23999fb5fa2a66084dd996188d96e57a7 — mapperr 3 years ago f0199cf
Print board labels
M tests/unit/test_shortener.py => tests/unit/test_shortener.py +8 -6
@@ 3,16 3,17 @@ from typing import List
from unittest import mock
from unittest.mock import Mock

from trullo.normalizer import Normalizer
from trullo.shortcuttable import Shortcuttable
from trullo.shortener import Shortener
from trullo.trl_board import TrlBoard
from trullo.trl_card import TrlCard
from trullo.trl_label import TrlLabel
from trullo.trl_list import TrlList


class TestShortener(unittest.TestCase):
    def test_matches(self):
        sh = Shortener
        sh = Normalizer
        start_match = sh.is_a_match('pil', 'pillow')
        self.assertTrue(start_match)
        middle_match = sh.is_a_match('grat', 'integration')


@@ 21,7 22,7 @@ class TestShortener(unittest.TestCase):
        self.assertTrue(end_match)

    def test_wrong_matches(self):
        sh = Shortener
        sh = Normalizer
        match = sh.is_a_match('spil', 'pillow')
        self.assertFalse(match)



@@ 39,7 40,7 @@ class TestShortener(unittest.TestCase):
            mock.create_autospec(Shortcuttable, spec_set=True)
        short4.get_normalized_name = Mock(return_value='')

        sh = Shortener
        sh = Normalizer
        shorties = [short1, short2]
        matches: List = sh.get_matches('er', shorties)
        self.assertEqual(1, len(matches))


@@ 63,8 64,10 @@ class TestShortener(unittest.TestCase):
                        {'name': ' Implement a trim() function',
                         'shortLink': shortLink})
        list1 = TrlList('idl1', {'name': 'To Do'})
        label1 = TrlLabel('idlb1', lblname := 'feature',
                          {'name': lblname, 'color': 'blue'}, 'blue')
        board1 = TrlBoard('idb1', shortLink := 'p01UyT', [list1],
                          [card1, card2, card3],
                          [card1, card2, card3], [label1],
                          {'name': 'my Super Board',
                           'shortLink': shortLink})



@@ 103,4 106,3 @@ class TestShortener(unittest.TestCase):
        self.assertNotIn('U', board1_n)
        self.assertIn('mysuper', board1_n)
        self.assertIn('p01u', board1_n)


M trullo.py => trullo.py +6 -2
@@ 5,6 5,7 @@ usage:
    trl b [<board_shortcut>]
    trl l [<list_shortcuts>...]
    trl ll
    trl lb
    trl c <card_shortcut> [o | m <list_shortcut> | e | n <list_shortcut>]
    trl c n <list_shortcut>
    trl g <api_path>


@@ 59,7 60,7 @@ import tempfile
from docopt import docopt

from trullo.printer import Printer
from trullo.shortener import Shortener
from trullo.normalizer import Normalizer
from trullo.tclient import TClient
from trullo.tconfig import TConfig
from trullo.usecases import Usecases


@@ 79,7 80,7 @@ if __name__ == '__main__':

    usecases = Usecases(TConfig(selected_board_filepath),
                        TClient(),
                        Shortener(),
                        Normalizer(),
                        Printer())

    selected_board_id, selected_board_name = usecases.get_selected_board()


@@ 107,6 108,9 @@ if __name__ == '__main__':
    elif args['ll']:
        usecases.print_board_lists()

    elif args['lb']:
        usecases.print_board_labels()

    elif args['l']:
        list_shortcuts = args['<list_shortcuts>']
        usecases.print_lists(list_shortcuts)

A trullo/normalizer.py => trullo/normalizer.py +31 -0
@@ 0,0 1,31 @@
from typing import List

import attr

from trullo.shortcuttable import Shortcuttable


@attr.s(auto_attribs=True)
class Normalizer:
    @staticmethod
    def normalize(string: str) -> str:
        result = ''
        for char in string:
            if char.lower() not in 'qwertyuiopasdfghjklzxcvbnm1234567890':
                continue
            result += char.lower()
        return result

    @staticmethod
    def get_matches(
            shortcut: str,
            shortcuttables: List[Shortcuttable]) -> List[any]:
        return [
            shortcuttable for shortcuttable in shortcuttables
            if Normalizer.is_a_match(
                shortcut,
                shortcuttable.get_normalized_name())]

    @staticmethod
    def is_a_match(shortcut: str, normalized_name: str) -> bool:
        return shortcut in normalized_name

M trullo/printer.py => trullo/printer.py +5 -6
@@ 2,7 2,7 @@ from typing import List, Optional

import attr

from trullo.shortener import Shortener
from trullo.normalizer import Normalizer
from trullo.trl_board import TrlBoard
from trullo.trl_card import TrlCard



@@ 36,17 36,16 @@ class Printer:
                      f"[{list_.raw_data['id'].lower()}]")
                for card in board.cards:
                    if card.raw_data['idList'] == list_.id:
                        card_output = f"\t[{card.raw_data['shortLink'].lower()}] "
                        card_output = \
                            f"\n\t{card.raw_data['name']}" \
                            f"\n\t[{card.raw_data['shortLink'].lower()}] "
                        for raw_label in card.raw_data['labels']:
                            card_output += f'({raw_label["name"]}) '
                        card_output += f"{card.raw_data['name']}"
                        print(card_output)
        print()

    @staticmethod
    def print_board_lists(board: TrlBoard):
        symbol_count_lists = Shortener.get_min_symbols_to_uniq(
            [list_.get_normalized_name() for list_ in board.lists])
        print(f"{board.raw_data['shortUrl']}")
        print('------------------------------')
        print(f"{board.raw_data['name']}")


@@ 80,5 79,5 @@ class Printer:
    def _there_is_a_match(normalized_name: str, shortcuts: List[str]) -> bool:
        return len([
            shortcut for shortcut in shortcuts
            if Shortener.is_a_match(shortcut, normalized_name)
            if Normalizer.is_a_match(shortcut, normalized_name)
        ]) > 0

D trullo/shortener.py => trullo/shortener.py +0 -67
@@ 1,67 0,0 @@
from typing import List
from typing import Set

import attr

from trullo.shortcuttable import Shortcuttable


@attr.s(auto_attribs=True)
class Shortener:
    @staticmethod
    def normalize(string: str) -> str:
        result = ''
        for char in string:
            if char.lower() not in 'qwertyuiopasdfghjklzxcvbnm1234567890':
                continue
            result += char.lower()
        return result

    @staticmethod
    def get_min_symbols_to_uniq(strings: List[str]) -> int:
        symbol_counter = 1
        longest_item_length = Shortener.get_longest_item_length(strings)
        string_list = [
            string_item[0:symbol_counter].lower()
            for string_item in strings
        ]
        while symbol_counter < longest_item_length \
                and Shortener.are_there_duplicates(string_list):
            symbol_counter += 1
            string_list = [
                string_item[0:symbol_counter].lower()
                for string_item in strings
            ]
        return symbol_counter

    @staticmethod
    def are_there_duplicates(list_: List[str]):
        set_: Set[str] = set()
        for elem in list_:
            if elem in set_:
                return True
            else:
                set_.add(elem)
        return False

    @staticmethod
    def get_longest_item_length(list_: List[str]) -> int:
        longest_length = 0
        for string in list_:
            length = len(string)
            if length > longest_length:
                longest_length = length
        return longest_length

    @staticmethod
    def get_matches(
            shortcut: str,
            shortcuttables: List[Shortcuttable]) -> List[any]:
        return [shortcuttable for shortcuttable in shortcuttables
                if Shortener.is_a_match(
                shortcut, shortcuttable.get_normalized_name())
                ]

    @staticmethod
    def is_a_match(shortcut: str, normalized_name: str) -> bool:
        return shortcut in normalized_name

M trullo/tclient.py => trullo/tclient.py +10 -2
@@ 7,6 7,7 @@ import requests

from trullo.trl_board import TrlBoard
from trullo.trl_card import TrlCard
from trullo.trl_label import TrlLabel
from trullo.trl_list import TrlList

logger = logging.getLogger(__name__)


@@ 61,13 62,20 @@ class TClient:

    def get_board(self, board_id: str) -> TrlBoard:
        res = self.get(f'/batch?urls=/board/{board_id},'
                       f'/board/{board_id}/labels,'
                       f'/board/{board_id}/lists/open,'
                       f'/board/{board_id}/cards/open')
        board = TrlBoard(board_id, board_id, [], [], res[0]['200'])
        board = TrlBoard(board_id, board_id, [], [], [], res[0]['200'])
        for item in res[1]['200']:
            label = TrlLabel(item['id'],
                             item['name'],
                             item,
                             item['color'] if 'color' in item else None)
            board.labels.append(label)
        for item in res[2]['200']:
            list_ = TrlList(item['id'], item)
            board.lists.append(list_)
        for item in res[2]['200']:
        for item in res[3]['200']:
            card = TrlCard(item['id'], item['shortLink'], item)
            board.cards.append(card)
        return board

M trullo/trl_board.py => trullo/trl_board.py +4 -2
@@ 2,9 2,10 @@ from typing import Dict, List

import attr

from trullo.normalizer import Normalizer
from trullo.shortcuttable import Shortcuttable
from trullo.shortener import Shortener
from trullo.trl_card import TrlCard
from trullo.trl_label import TrlLabel
from trullo.trl_list import TrlList




@@ 14,9 15,10 @@ class TrlBoard(Shortcuttable):
    short_link: str
    lists: List[TrlList]
    cards: List[TrlCard]
    labels: List[TrlLabel]
    raw_data: Dict

    def get_normalized_name(self) -> str:
        return Shortener.normalize(
        return Normalizer.normalize(
            f"{self.raw_data['name']}{self.raw_data['shortLink']}"
        )

M trullo/trl_card.py => trullo/trl_card.py +2 -2
@@ 3,7 3,7 @@ from typing import Dict
import attr

from trullo.shortcuttable import Shortcuttable
from trullo.shortener import Shortener
from trullo.normalizer import Normalizer


@attr.s(auto_attribs=True)


@@ 13,6 13,6 @@ class TrlCard(Shortcuttable):
    raw_data: Dict

    def get_normalized_name(self):
        return Shortener.normalize(
        return Normalizer.normalize(
            f"{self.raw_data['name']}{self.raw_data['shortLink']}"
        )

A trullo/trl_label.py => trullo/trl_label.py +21 -0
@@ 0,0 1,21 @@
from typing import Dict, Optional

import attr

from trullo.normalizer import Normalizer
from trullo.shortcuttable import Shortcuttable


@attr.s(auto_attribs=True)
class TrlLabel(Shortcuttable):
    id: str
    name: str
    raw_data: Dict
    color: Optional[str] = attr.ib(default=None)

    def get_normalized_name(self) -> str:
        return Normalizer.normalize(
            f"{self.raw_data['name']}"
            f"{self.color if self.color is not None else ''}"
            f"{self.id}"
        )

M trullo/trl_list.py => trullo/trl_list.py +2 -2
@@ 3,7 3,7 @@ from typing import Dict
import attr

from trullo.shortcuttable import Shortcuttable
from trullo.shortener import Shortener
from trullo.normalizer import Normalizer


@attr.s(auto_attribs=True)


@@ 12,6 12,6 @@ class TrlList(Shortcuttable):
    raw_data: Dict

    def get_normalized_name(self) -> str:
        return Shortener.normalize(
        return Normalizer.normalize(
            f"{self.raw_data['name']}{self.id}"
        )

M trullo/usecases.py => trullo/usecases.py +10 -5
@@ 6,8 6,8 @@ from typing import Optional, Tuple, List

import attr

from trullo.normalizer import Normalizer
from trullo.printer import Printer
from trullo.shortener import Shortener
from trullo.tclient import TClient
from trullo.tconfig import TConfig
from trullo.trl_board import TrlBoard


@@ 19,7 19,7 @@ from trullo.trl_list import TrlList
class Usecases:
    tconfig: TConfig
    tclient: TClient
    shortener: Shortener
    shortener: Normalizer
    printer: Printer
    selected_board_id: Optional[str] = attr.ib(default=None)
    selected_board_name: Optional[str] = attr.ib(default=None)


@@ 84,7 84,7 @@ class Usecases:

    def create_card(self, target_list_shortcut: str):
        board = self.tclient.get_board(self.selected_board_id)
        matching_lists: List[TrlList] = Shortener.get_matches(
        matching_lists: List[TrlList] = Normalizer.get_matches(
            target_list_shortcut,
            board.lists
        )


@@ 115,7 115,7 @@ class Usecases:

    def move_card(self, card_shortcut: str, target_list_shortcut: str):
        board = self.tclient.get_board(self.selected_board_id)
        matching_lists: List[TrlList] = Shortener.get_matches(
        matching_lists: List[TrlList] = Normalizer.get_matches(
            target_list_shortcut,
            board.lists
        )


@@ 143,7 143,7 @@ class Usecases:

    def _get_card(self, card_shortcut):
        board = self.tclient.get_board(self.selected_board_id)
        matching_cards: List[TrlCard] = Shortener.get_matches(
        matching_cards: List[TrlCard] = Normalizer.get_matches(
            card_shortcut,
            board.cards
        )


@@ 192,3 192,8 @@ class Usecases:
            lines = fd.readlines()
        return urllib.parse.quote(lines[1].replace('\n', ''), safe=''), \
               urllib.parse.quote(str.join('', lines[2:]), safe='')

    def print_board_labels(self):
        board = self.tclient.get_board(self.selected_board_id)
        for label in board.labels:
            print('{:12} {}'.format(label.color, label.name))