Beispiel #1
0
    def __init__(self, p_todo):
        # clients use this to associate this widget with the given todo item
        self.todo = p_todo

        todo_text = TEXT_FORMATTER.parse(p_todo)
        priority_text = PRIO_FORMATTER.parse(p_todo)

        # split todo_text at each occurrence of tag/project/context/url
        txt_pattern = r'|'.join([PRJ_CON_PATTERN, TAG_PATTERN, URL_PATTERN])
        txt_pattern = r'(' + txt_pattern + r')'
        txt_splitted = re.split(txt_pattern, todo_text)
        txt_markup = []

        # Examine each substring and apply relevant palette entry if needed
        for substring in txt_splitted:
            # re.split can generate empty strings when capturing group is used
            if not substring:
                continue
            if re.match(TAG_PATTERN, substring):
                txt_markup.append((PaletteItem.METADATA, substring))
            elif re.match(URL_PATTERN, substring):
                txt_markup.append((PaletteItem.LINK, substring))
            elif re.match(PRJ_CON_PATTERN, substring):
                if substring.startswith('+'):
                    txt_markup.append((PaletteItem.PROJECT, substring))
                else:
                    txt_markup.append((PaletteItem.CONTEXT, substring))
            else:
                txt_markup.append(substring)

        self.id_widget = urwid.Text('', align='right')
        priority_widget = urwid.Text(priority_text)
        self.text_widget = urwid.Text(txt_markup)

        progress = to_urwid_color(progress_color(p_todo)) if config().colors() else PaletteItem.DEFAULT
        self.progress_bar = urwid.AttrMap(
                urwid.SolidFill(' '),
                {},
        )
        self.update_progress()

        self.columns = urwid.Columns(
            [
                (1, self.progress_bar),
                (4, self.id_widget),
                (3, priority_widget),
                ('weight', 1, self.text_widget),
            ],
            dividechars=1,
            box_columns=[0] # the progress bar adapts its height to the rest
        )

        self.widget = urwid.AttrMap(
            self.columns,
            _markup(p_todo, p_focus=False),
            _markup(p_todo, p_focus=True)
        )

        super().__init__(self.widget)
    def test_progress30(self):
        """ Progress color determined by parent """
        todolist = TodoList([
            "Foo id:1",
            "Bar p:1",
        ])

        color = progress_color(todolist.todo(2))

        # the parent has no influence here
        self.assertEqual(color.color, 2)
    def test_progress29(self):
        """ Progress color determined by parent """
        todolist = TodoList([
            "Overdue id:1 due:2015-12-31",
            "Bar p:1 t:2016-01-01 due:2016-01-01",
        ])

        color = progress_color(todolist.todo(2))

        # the parent has no influence here
        self.assertEqual(color.color, 3)
    def test_progress29(self):
        """ Progress color determined by parent """
        todolist = TodoList([
            "Overdue id:1 due:2015-12-31",
            "Bar p:1 t:2016-01-01 due:2016-01-01",
        ])

        color = progress_color(todolist.todo(2))

        # the parent has no influence here
        self.assertEqual(color.color, 3)
    def test_progress30(self):
        """ Progress color determined by parent """
        todolist = TodoList([
            "Foo id:1",
            "Bar p:1",
        ])

        color = progress_color(todolist.todo(2))

        # the parent has no influence here
        self.assertEqual(color.color, 2)
    def test_progress28(self):
        """ Progress color determined by parent """
        todolist = TodoList([
            "Overdue id:1 due:2015-12-31",
            "Bar p:1",
        ])

        color = progress_color(todolist.todo(2))

        # color the subitem red because it has no color of its own and its
        # parent is overdue
        self.assertEqual(color.color, 1)
    def test_progress28(self):
        """ Progress color determined by parent """
        todolist = TodoList([
            "Overdue id:1 due:2015-12-31",
            "Bar p:1",
        ])

        color = progress_color(todolist.todo(2))

        # color the subitem red because it has no color of its own and its
        # parent is overdue
        self.assertEqual(color.color, 1)
 def test_progress10(self):
     set_256_colors()
     color = progress_color(Todo('Foo due:2016-01-02'))
     # a length of 14 days is assumed
     self.assertEqual(color.color, 208)
    def test_progress8(self):
        """ Due today (256) """

        set_256_colors()
        color = progress_color(Todo('Foo due:2016-01-01'))
        self.assertEqual(color.color, 202)
 def test_progress27(self):
     """ Creation date after due date """
     set_256_colors()
     color = progress_color(Todo('2016-01-03 Foo due:2016-01-02'))
     # a length of 14 days is assumed
     self.assertEqual(color.color, 208)
 def test_progress27(self):
     """ Creation date after due date """
     set_256_colors()
     color = progress_color(Todo('2016-01-03 Foo due:2016-01-02'))
     # a length of 14 days is assumed
     self.assertEqual(color.color, 208)
 def test_progress24(self):
     """ Due tomorrow (creation date + start date) """
     set_256_colors()
     color = progress_color(
         Todo('2015-12-01 Foo due:2016-01-02 t:2015-12-31'))
     self.assertEqual(color.color, 118)
 def test_progress20(self):
     """ Due tomorrow (creation date + strict recurrence + start date) """
     set_256_colors()
     color = progress_color(
         Todo('2015-12-01 Foo due:2016-01-02 rec:+1d t:2016-01-02'))
     self.assertEqual(color.color, 22)
Beispiel #14
0
    def print_list(self, p_todos):
        def node_label(p_todo):
            """
            Prints an HTML table for a node label with some todo details.
            """
            def escape_dot_label(p_string):
                """
                HTML like labels in Dot may not have raw ampersands, quotes or
                angle brackets. These should be properly replaced with the
                escaped character notation.
                """

                return p_string.replace('&', '&').replace(
                    '"', '&quot;').replace('<', '&lt;').replace('>', '&gt;')

            node_result = '<<TABLE CELLBORDER="0" CELLSPACING="1" VALIGN="top">'

            def print_row(p_value1, p_value2):
                return '<TR><TD ALIGN="RIGHT">{}</TD><TD ALIGN="LEFT">{}</TD></TR>'.format(
                    p_value1, p_value2)

            node_result += '<TR><TD><B>{}</B></TD><TD BALIGN="LEFT"><B>{}{}{}</B></TD></TR>'.format(
                self.todolist.number(p_todo),
                "<S>" if todo.is_completed() else "",
                "<BR />".join(map(escape_dot_label, wrap(p_todo.text(), 35))),
                "</S>" if todo.is_completed() else "",
            )

            priority = p_todo.priority()
            start_date = p_todo.start_date()
            due_date = p_todo.due_date()

            if priority or start_date or due_date:
                node_result += '<HR/>'

            if priority:
                node_result += print_row('Prio:', p_todo.priority())

            if start_date:
                node_result += print_row(
                    'Starts:', "{} ({})".format(start_date.isoformat(),
                                                humanize_date(start_date)))

            if due_date:
                node_result += print_row(
                    'Due:', "{} ({})".format(due_date.isoformat(),
                                             humanize_date(due_date)))

            node_result += '</TABLE>>'

            return node_result

        def foreground(p_background):
            """
            Chooses a suitable foreground color (black or white) given a
            background color.
            """

            (r, g, b) = p_background.as_rgb()
            brightness = (r * 299 + g * 587 + b * 114) / (255 * 1000)

            return '#ffffff' if brightness < 0.5 else '#000000'

        node_name = lambda t: '_' + str(self.todolist.number(t))

        result = 'digraph topydo {\n'
        result += 'node [ shape="none" margin="0" fontsize="9" fontname="Helvetica" ]\n'

        # print todos
        for todo in p_todos:
            background_color = progress_color(todo)

            result += '  {} [label={} style=filled fillcolor="{}" fontcolor="{}"]\n'.format(
                node_name(todo),
                node_label(todo),
                background_color.as_html(),
                foreground(background_color),
            )

        # print edges
        for todo in p_todos:
            # only print the children that are actually in the list of todos
            children = set(p_todos) & set(
                self.todolist.children(todo, p_only_direct=True))

            for child in sorted(list(children), key=lambda t: t.text()):
                result += '  {} -> {}\n'.format(node_name(todo),
                                                node_name(child))

        todos_without_dependencies = [
            todo for todo in p_todos if not self.todolist.children(todo)
            and not self.todolist.parents(todo)
        ]
        for index in range(0, len(todos_without_dependencies) - 1):
            this_todo = todos_without_dependencies[index]
            next_todo = todos_without_dependencies[index + 1]
            result += '  {} -> {} [style="invis"]\n'.format(
                node_name(this_todo), node_name(next_todo))

        result += '}\n'
        return result
 def test_progress5(self):
     """ Test overdue tasks """
     color = progress_color(Todo('Foo due:2015-12-31'))
     self.assertEqual(color.color, 1)
    def test_progress4(self):
        """ Test progress of task with no length (but with creation date). """
        set_256_colors()

        color = progress_color(Todo('2016-02-11 Foo'))
        self.assertEqual(color.color, 22)
    def test_progress3(self):
        """ Test progress of task with no length """
        set_256_colors()

        color = progress_color(Todo('Foo'))
        self.assertEqual(color.color, 22)
 def test_progress1(self):
     """ Test progress of task with no length """
     color = progress_color(Todo('Foo'))
     self.assertEqual(color.color, 2)
 def test_progress21(self):
     """ Due tomorrow (creation date + start date) """
     color = progress_color(Todo('2016-12-01 Foo due:2016-01-02 t:2016-01-02'))
     self.assertEqual(color.color, 2)
 def test_progress24(self):
     """ Due tomorrow (creation date + start date) """
     set_256_colors()
     color = progress_color(Todo('2015-12-01 Foo due:2016-01-02 t:2015-12-31'))
     self.assertEqual(color.color, 118)
 def test_progress12(self):
     """ Due tomorrow (creation date) """
     set_256_colors()
     color = progress_color(Todo('2016-01-01 Foo due:2016-01-02'))
     self.assertEqual(color.color, 22)
    def test_progress6(self):
        """ Test overdue tasks """
        set_256_colors()

        color = progress_color(Todo('Foo due:2015-12-31'))
        self.assertEqual(color.color, 196)
 def test_progress16(self):
     """ Due tomorrow (creation date + recurrence) """
     set_256_colors()
     color = progress_color(Todo('2015-12-01 Foo due:2016-01-02 rec:1d'))
     self.assertEqual(color.color, 22)
 def test_progress20(self):
     """ Due tomorrow (creation date + strict recurrence + start date) """
     set_256_colors()
     color = progress_color(Todo('2015-12-01 Foo due:2016-01-02 rec:+1d t:2016-01-02'))
     self.assertEqual(color.color, 22)
 def test_progress14(self):
     """ Due tomorrow (recurrence) """
     set_256_colors()
     color = progress_color(Todo('Foo due:2016-01-02 rec:1d'))
     self.assertEqual(color.color, 22)
 def test_progress1(self):
     """ Test progress of task with no length """
     color = progress_color(Todo('Foo'))
     self.assertEqual(color.color, 2)
 def test_progress21(self):
     """ Due tomorrow (creation date + start date) """
     color = progress_color(
         Todo('2016-12-01 Foo due:2016-01-02 t:2016-01-02'))
     self.assertEqual(color.color, 2)
    def test_progress4(self):
        """ Test progress of task with no length (but with creation date). """
        set_256_colors()

        color = progress_color(Todo('2016-02-11 Foo'))
        self.assertEqual(color.color, 22)
 def test_progress26(self):
     """ Start date after due date """
     set_256_colors()
     color = progress_color(Todo('Foo due:2016-01-02 t:2016-01-03'))
     # a length of 14 days is assumed
     self.assertEqual(color.color, 208)
    def test_progress6(self):
        """ Test overdue tasks """
        set_256_colors()

        color = progress_color(Todo('Foo due:2015-12-31'))
        self.assertEqual(color.color, 196)
 def test_progress7(self):
     """ Due today """
     color = progress_color(Todo('Foo due:2016-01-01'))
     self.assertEqual(color.color, 3)
 def test_progress26(self):
     """ Start date after due date """
     set_256_colors()
     color = progress_color(Todo('Foo due:2016-01-02 t:2016-01-03'))
     # a length of 14 days is assumed
     self.assertEqual(color.color, 208)
    def test_progress8(self):
        """ Due today (256) """

        set_256_colors()
        color = progress_color(Todo('Foo due:2016-01-01'))
        self.assertEqual(color.color, 202)
 def test_progress9(self):
     """ Due tomorrow """
     color = progress_color(Todo('Foo due:2016-01-02'))
     # a length of 14 days is assumed
     self.assertEqual(color.color, 3)
    def test_progress3(self):
        """ Test progress of task with no length """
        set_256_colors()

        color = progress_color(Todo('Foo'))
        self.assertEqual(color.color, 22)
 def test_progress10(self):
     set_256_colors()
     color = progress_color(Todo('Foo due:2016-01-02'))
     # a length of 14 days is assumed
     self.assertEqual(color.color, 208)
 def test_progress5(self):
     """ Test overdue tasks """
     color = progress_color(Todo('Foo due:2015-12-31'))
     self.assertEqual(color.color, 1)
 def test_progress11(self):
     """ Due tomorrow (creation date) """
     color = progress_color(Todo('2016-01-01 Foo due:2016-01-02'))
     # a length of 14 days is assumed
     self.assertEqual(color.color, 2)
 def test_progress7(self):
     """ Due today """
     color = progress_color(Todo('Foo due:2016-01-01'))
     self.assertEqual(color.color, 3)
 def test_progress12(self):
     """ Due tomorrow (creation date) """
     set_256_colors()
     color = progress_color(Todo('2016-01-01 Foo due:2016-01-02'))
     self.assertEqual(color.color, 22)
 def test_progress9(self):
     """ Due tomorrow """
     color = progress_color(Todo('Foo due:2016-01-02'))
     # a length of 14 days is assumed
     self.assertEqual(color.color, 3)
Beispiel #42
0
    def update_progress(self):
        color = to_urwid_color(progress_color(
            self.todo)) if config().colors() else PaletteItem.DEFAULT

        self.progress_bar.set_attr_map(
            {None: urwid.AttrSpec(PaletteItem.DEFAULT, color, 256)})
 def test_progress11(self):
     """ Due tomorrow (creation date) """
     color = progress_color(Todo('2016-01-01 Foo due:2016-01-02'))
     # a length of 14 days is assumed
     self.assertEqual(color.color, 2)
Beispiel #44
0
    def __init__(self, p_todo, p_id_width=4):
        # clients use this to associate this widget with the given todo item
        self.todo = p_todo

        todo_text = TEXT_FORMATTER.parse(p_todo)

        if p_todo.is_completed():
            priority_text = ' x '
        else:
            priority_text = PRIO_FORMATTER.parse(p_todo)

        # split todo_text at each occurrence of tag/project/context/url
        txt_pattern = r'|'.join([PRJ_CON_PATTERN, TAG_PATTERN, URL_PATTERN])
        txt_pattern = r'(' + txt_pattern + r')'
        txt_splitted = re.split(txt_pattern, todo_text)
        txt_markup = []

        # Examine each substring and apply relevant palette entry if needed
        for substring in txt_splitted:
            # re.split can generate empty strings when capturing group is used
            if not substring:
                continue
            if re.match(TAG_PATTERN, substring):
                txt_markup.append((PaletteItem.METADATA, substring))
            elif re.match(URL_PATTERN, substring):
                txt_markup.append((PaletteItem.LINK, substring))
            elif re.match(PRJ_CON_PATTERN, substring):
                if substring.startswith('+'):
                    txt_markup.append((PaletteItem.PROJECT, substring))
                else:
                    txt_markup.append((PaletteItem.CONTEXT, substring))
            else:
                txt_markup.append(substring)

        self.id_widget = urwid.Text('', align='right')
        priority_widget = urwid.Text(priority_text)
        self.text_widget = urwid.Text(txt_markup)

        progress = to_urwid_color(progress_color(
            p_todo)) if config().colors() else PaletteItem.DEFAULT
        self.progress_bar = urwid.AttrMap(
            urwid.SolidFill(' '),
            {},
        )
        self.update_progress()

        self.columns = urwid.Columns(
            [
                (1, self.progress_bar),
                (p_id_width, self.id_widget),
                (3, priority_widget),
                ('weight', 1, self.text_widget),
            ],
            dividechars=1,
            box_columns=[0]  # the progress bar adapts its height to the rest
        )

        self.widget = urwid.AttrMap(self.columns, _markup(p_todo,
                                                          p_focus=False),
                                    _markup(p_todo, p_focus=True))

        super().__init__(self.widget)
Beispiel #45
0
    def update_progress(self):
        color = to_urwid_color(progress_color(self.todo)) if config().colors() else PaletteItem.DEFAULT

        self.progress_bar.set_attr_map(
            {None: urwid.AttrSpec(PaletteItem.DEFAULT, color, 256)}
        )
 def test_progress14(self):
     """ Due tomorrow (recurrence) """
     set_256_colors()
     color = progress_color(Todo('Foo due:2016-01-02 rec:1d'))
     self.assertEqual(color.color, 22)
Beispiel #47
0
def color_block(p_todo):
    return '{} {}'.format(
        progress_color(p_todo).as_ansi(p_background=True),
        config().priority_color(p_todo.priority()).as_ansi(),
    )
 def test_progress16(self):
     """ Due tomorrow (creation date + recurrence) """
     set_256_colors()
     color = progress_color(Todo('2015-12-01 Foo due:2016-01-02 rec:1d'))
     self.assertEqual(color.color, 22)
Beispiel #49
0
    def print_list(self, p_todos):
        def node_label(p_todo):
            """
            Prints an HTML table for a node label with some todo details.
            """
            def escape_dot_label(p_string):
                """
                HTML like labels in Dot may not have raw ampersands, quotes or
                angle brackets. These should be properly replaced with the
                escaped character notation.
                """

                return p_string.replace('&', '&amp;').replace('"', '&quot;').replace(
                    '<', '&lt;').replace('>', '&gt;')

            node_result = '<<TABLE CELLBORDER="0" CELLSPACING="1" VALIGN="top">'

            def print_row(p_value1, p_value2):
                return '<TR><TD ALIGN="RIGHT">{}</TD><TD ALIGN="LEFT">{}</TD></TR>'.format(p_value1, p_value2)

            node_result += '<TR><TD><B>{}</B></TD><TD BALIGN="LEFT"><B>{}{}{}</B></TD></TR>'.format(
                self.todolist.number(p_todo),
                "<S>" if todo.is_completed() else "",
                "<BR />".join(map(escape_dot_label, wrap(p_todo.text(), 35))),
                "</S>" if todo.is_completed() else "",
            )

            priority = p_todo.priority()
            start_date = p_todo.start_date()
            due_date = p_todo.due_date()

            if priority or start_date or due_date:
                node_result += '<HR/>'

            if priority:
                node_result += print_row('Prio:', p_todo.priority())

            if start_date:
                node_result += print_row('Starts:', "{} ({})".format(
                    start_date.isoformat(),
                    humanize_date(start_date)
                ))

            if due_date:
                node_result += print_row('Due:', "{} ({})".format(
                    due_date.isoformat(),
                    humanize_date(due_date)
                ))

            node_result += '</TABLE>>'

            return node_result

        def foreground(p_background):
            """
            Chooses a suitable foreground color (black or white) given a
            background color.
            """

            (r, g, b) = p_background.as_rgb()
            brightness = (r * 299 + g * 587 + b * 114) / ( 255 * 1000 )

            return '#ffffff' if brightness < 0.5 else '#000000'

        node_name = lambda t: '_' + str(self.todolist.number(t))

        result = 'digraph topydo {\n'
        result += 'node [ shape="none" margin="0" fontsize="9" fontname="Helvetica" ]\n';

        # print todos
        for todo in p_todos:
            background_color = progress_color(todo)

            result += '  {} [label={} style=filled fillcolor="{}" fontcolor="{}"]\n'.format(
                node_name(todo),
                node_label(todo),
                background_color.as_html(),
                foreground(background_color),
            )

        # print edges
        for todo in p_todos:
            # only print the children that are actually in the list of todos
            children = set(p_todos) & set(self.todolist.children(todo,
                p_only_direct=True))

            for child in sorted(list(children), key=lambda t: t.text()):
                result += '  {} -> {}\n'.format(
                    node_name(todo),
                    node_name(child)
                )

        todos_without_dependencies = [todo for todo in p_todos if not self.todolist.children(todo) and not self.todolist.parents(todo)]
        for index in range(0, len(todos_without_dependencies) - 1):
            this_todo = todos_without_dependencies[index]
            next_todo = todos_without_dependencies[index + 1]
            result += '  {} -> {} [style="invis"]\n'.format(node_name(this_todo), node_name(next_todo))

        result += '}\n'
        return result
Beispiel #50
0
def color_block(p_todo):
    return '{} {}'.format(
        progress_color(p_todo).as_ansi(p_background=True),
        config().priority_color(p_todo.priority()).as_ansi(),
    )