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], )
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")
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)
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)
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)
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], )
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))
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)
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, )
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
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 )
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)
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)
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)
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()