Example #1
0
    def run(self, args):
        if args.interactive:
            return ListInteractive(self.service).run(args)

        if args.group is None:
            group = self.service.group.get_active_group()
        else:
            group = self.service.group.get(args.group)

        if group is None:
            raise TodoException(
                "<Group: {name}> not found".format(name=args.group))

        todos = self.service.todo.get_all(group[0], args.state)

        RenderOutput(
            "{subsequent_indent}{bold}{blue}{group_name}{reset}\n").render(
                subsequent_indent=" " * 4, group_name=group[0] or "global")

        for todo in todos:
            RenderOutputWithTextwrap("{completed} {bold}{todo_id}{reset}: ",
                                     "{name}").render(
                                         completed="✓" if todo[3] else "x",
                                         name=todo[1],
                                         todo_id=todo[0])

        RenderOutput(
            "{prefix}{grey}{items} item{singular_or_plural}: {completed} completed, {uncompleted} left"
        ).render(
            prefix="\n" if group[1] > 0 else "",
            items=group[1],
            singular_or_plural=singular_or_plural(group[1]),
            uncompleted=group[2],
            completed=group[3],
        )
Example #2
0
    def run(self, args):
        group = self._get_group_or_raise(args.name)

        self.service.group.use(group[0])

        RenderOutput("Set {blue}{group_name}{reset} as default").render(
            group_name=group[0] or "global")
Example #3
0
    def run(self, args):
        groups = self.service.group.get_all(args.state)
        if not groups:
            return RenderOutput("No{state} {bold}{blue}groups{reset} exist"
                                ).render(state=interpret_state(args.state))

        for group in groups:
            RenderOutput(
                "{bold}{blue}{group_name}{reset}: {items} item{singular_or_plural}: "
                "{completed} completed, {uncompleted} left").render(
                    group_name=group[0],
                    items=group[1],
                    singular_or_plural=singular_or_plural(group[1]),
                    uncompleted=group[2],
                    completed=group[3],
                )

        self._print_footer(groups)
Example #4
0
    def run(self, args):
        try:
            todo = self._get_todo_or_raise(args.id)
            RenderOutput(
                "{subsequent_indent}{bold}{blue}{group_name}{reset}\n").render(
                    group_name=todo[1] or "UNGROUPED",
                    subsequent_indent=" " * 4)

            RenderOutput("{details}").render(details=todo[3])

            RenderOutputWithTextwrap(
                "\n{grey}{completed} {bold}{todo_id}{normal}: ",
                "{details}").render(details=todo[2],
                                    completed="✓" if todo[4] else "x",
                                    todo_id=todo[0])
        except Error as e:
            raise TodoException(
                "Error occurred, could not get {bold}<Todo: %s>{reset}" %
                args.id, e)
Example #5
0
 def run(self, args):
     try:
         todo = self._get_todo_or_raise(args.id)
         self.service.todo.uncomplete(todo[0])
         RenderOutput(
             "{bold}{red}x {reset}{todo_id}{normal}: {name}").render(
                 todo_id=todo[0], name=todo[2])
     except Error as e:
         raise TodoException(
             "Error occurred, could not uncomplete <Todo: %s>" % args.id, e)
Example #6
0
    def _render_todos(self, todos, group):
        RenderOutput(
            "{subsequent_indent}{bold}{blue}{group_name}{reset}\n").render(
                subsequent_indent=" " * 4, group_name=group[0] or "global")

        for todo in todos:
            RenderOutputWithTextwrap("{completed} {bold}{todo_id}{reset}  ",
                                     "{name}").render(
                                         completed="✓" if todo[3] else "x",
                                         name=todo[1],
                                         todo_id=todo[0])

        RenderOutput(
            "{prefix}{grey}{items} item{singular_or_plural}: {completed} completed, {uncompleted} left"
        ).render(
            prefix="\n" if group[1] > 0 else "",
            items=group[1],
            singular_or_plural=singular_or_plural(group[1]),
            uncompleted=group[2],
            completed=group[3],
        )
Example #7
0
    def run(self, args):
        if args.group is None:
            group = self.service.group.get_active_group()
        else:
            group = self.service.group.get(args.group)

        if group is None:
            raise TodoException("<Group: {name}> not found".format(name=args.group))

        todos = self.service.todo.get_all(group[0], args.state)

        RenderOutput("{count}").render(count=len(todos))
Example #8
0
    def run(self, args):
        try:
            group_name = self.service.group.add(args.name)

            RenderOutput("Created group {blue}{group_name}").render(
                group_name=group_name)
        except IntegrityError as e:
            raise TodoException(
                "`{bold}<Group: %s>{reset}` already exists." % args.name, e)
        except Error as e:
            raise TodoException("Error occurred, could not create a new group",
                                e)
Example #9
0
    def _print_footer(self, groups):
        group_count = len(groups)
        summary = [res for res in zip(*groups)][2:]
        completed_groups_count = sum(1 for x in summary[0] if x == 0)

        RenderOutput(
            "\n{grey}{group_count} group{singular_or_plural}: {completed} completed, {uncompleted} left"
        ).render(
            group_count=group_count,
            singular_or_plural=singular_or_plural(group_count),
            completed=completed_groups_count,
            uncompleted=group_count - completed_groups_count,
        )
Example #10
0
    def _render_todos_interactive(self, todos, group, state):
        todos_count = len(todos)
        if todos_count == 0:
            return RenderOutput(
                "No{state} {bold}{blue}{name}{reset} {bold}todos{reset} to be listed"
            ).render(state=interpret_state(state), name=group[0] or "global")

        with Menu() as menu:
            menu.clear()
            menu.render_header("{group_name}".format(group_name=group[0]))

            current_pos = 0
            while True:
                menu.refresh()
                menu.render_subheader(
                    "{items} item{singular_or_plural}: {completed} completed, {uncompleted} left"
                    .format(
                        items=group[1],
                        singular_or_plural=singular_or_plural(group[1]),
                        completed=group[3],
                        uncompleted=group[2],
                    ))

                for index, todo in enumerate(todos):
                    menu.render_todo(todo, index, current_pos)

                menu.render_commands(todos_count)

                command = menu.get_command()

                if command == COMMANDS.DOWN:
                    current_pos = current_pos + 1 if current_pos + 1 < todos_count else 0
                elif command == COMMANDS.UP:
                    current_pos = current_pos - 1 if current_pos > 0 else todos_count - 1

                todo = todos[current_pos]
                if command == COMMANDS.TOGGLE:
                    # toggle todo
                    if todo[3]:
                        # uncomplete todo
                        self.service.todo.uncomplete(todo[0])
                        group = group[:2] + (group[2] + 1, group[3] - 1)
                    else:
                        # complete todo
                        self.service.todo.complete(todo[0])
                        group = group[:2] + (group[2] - 1, group[3] + 1)
                    # update list
                    todos[current_pos] = todo[:3] + (not todo[3], )
                elif command == COMMANDS.QUIT:
                    break
Example #11
0
    def run(self, args):
        try:
            group = self._get_group_or_raise(args.name)
            if group[0] is None or group[0] == "global":
                raise TodoException(
                    "Can't delete `{bold}<Group: global>{reset}`. It must always exist"
                )
            if not args.skip_prompt:
                todo_count = group[2] + group[1]
                post_text = ""
                if todo_count > 0:
                    RenderOutput(
                        "By deleting group {blue}{group_name}{reset}, "
                        "you'll also delete {bold}{todo_count}{normal} todo{singular_or_plural} in that group"
                    ).render(
                        group_name=args.name,
                        todo_count=todo_count,
                        singular_or_plural=singular_or_plural(todo_count),
                    )
                    post_text = ", and {todo_count} todo{singular_or_plural}"
                choice = RenderInput(
                    "[?] Are you sure you want to delete group {blue}{group_name}{reset}? [Y|n] "
                ).render(group_name=group[0])
                if choice not in ("y", "yes", ""):
                    return RenderOutput("Abort!").render()
            self.service.group.delete(group[0])

            RenderOutput("{red}Deleted{reset} {bold}{group_name}{normal}" + post_text).render(
                group_name=group[0],
                todos=post_text,
                singular_or_plural=singular_or_plural(todo_count),
                todo_count=todo_count,
            )
        except Error as e:
            raise TodoException(
                "Error occurred, could not delete `{bold}<Group: %s>{reset}`" % args.name, e
            )
Example #12
0
    def run(self, args):
        try:
            if args.edit:
                details = get_user_input(config["editor"])
            else:
                details = args.details or args.name

            if args.group is None:
                group = self.service.group.get_active_group()
            else:
                group = self.service.group.get(args.group)
            todo_id = self.service.todo.add(args.name, details, group[0], completed=args.state)

            RenderOutput("Created todo {bold}{todo_id}").render(todo_id=todo_id)
        except Error as e:
            raise TodoException("Error occurred, could not create a new todo", e)
Example #13
0
    def run(self, args):
        try:
            todo = self._get_todo_or_raise(args.id)
            if not args.skip_prompt:
                choice = RenderInput(
                    "[?] Are you sure you want to delete todo {bold}{todo_id}{normal}? [Y|n] "
                ).render(todo_id=todo[0])
                if choice not in ("", "y", "ye", "yes"):
                    return RenderOutput("Abort!").render()
            self.service.todo.delete(todo[0])

            RenderOutputWithTextwrap(
                "{red}Deleted{reset} {bold}{todo_id}{reset}: ", "{name}"
            ).render(name=todo[2], todo_id=todo[0], subsequent_indent=" " * 16)
        except Error as e:
            raise TodoException("Error occurred, could not delete <Todo: %s>" % args.id, e)
Example #14
0
    def run(self, args):
        try:
            todo = self._get_todo_or_raise(args.id)
            if not (args.name or args.details or args.group):
                details = get_user_input(config["editor"], str.encode(todo[3]))
                self.service.todo.edit_details(todo[0], details)
            else:
                if args.group:
                    group = self._get_group_or_raise(args.group)
                    self.service.todo.set_group(todo[0], group[0])
                if args.name:
                    self.service.todo.edit_name(todo[0], args.name)
                if args.details:
                    self.service.todo.edit_details(todo[0], args.details)

            RenderOutput("Edited {bold}{todo_id}{reset}: {name}").render(
                todo_id=todo[0], name=args.name or todo[2])
        except Error as e:
            raise TodoException(
                "Error occurred, could not edit <Todo: %s>" % args.id, e)
Example #15
0
    def run(self, args):
        cwd = Path.expanduser(Path.cwd())
        location = Path(
            RenderInput("[?] Configuration location? [{cwd}] ").render(cwd=cwd) or cwd
        ).expanduser()
        if not location.is_dir():
            RenderOutput("Directory {red}{location}{reset} does not exist").render(
                location=location
            )
            return RenderOutput("Abort!").render()
        file = Path(f"{location}/.td.cfg")
        if file.exists():
            RenderOutput("Configuration file {red}{file}{reset} already exists").render(file=file)
            return RenderOutput("Abort!").render()

        group = RenderInput("[?] Choose your default group? ").render()
        if self.service.group.get(group) is None:
            RenderOutput("Group {red}{group}{reset} does not exist").render(group=group or '""')
            return RenderOutput("Abort!").render()

        with open(file, "w+") as f:
            f.write(EXAMPLE_CONFIG.format(group=group))

        RenderOutput("\nConfiguration file {green}successfully{reset} created!").render()