def do_stopwatch(self, line): """Creates a new stopwatch for recording time for a particular task. """ parser = ArgumentParser(stdout=self.stdout, prog="stopwatch", add_help=False) parser.add_argument("task", metavar="TASK") parser.add_argument("metric", metavar="METRIC", nargs="?") args = parser.parse_args(line.split()) if not args.task: self._print() self._error("Invalid arguments") return # Get task with specified name and optional metric task = self.current_project.task(args.task, create=False) if not task: self._error("Task {} does not exist.".format(args.task)) return if args.metric: metric = self.current_project.metric(args.metric) if not metric: self._error("Metric {} does not exist.".format(args.metric)) return else: metric = None # Create a stop watch and UI self._print("\n (R)eset | (S)tart | (P)ause | S(t)op\n") self.stdout.write(" Stopped\t--:--:--\r") self.stdout.flush() stopwatch_active = True stopwatch = StopWatch() with cbreak(): while stopwatch_active: user_input_int = ord(self.stdin.read(1)) if 0 <= user_input_int <= 256: user_input = chr(user_input_int).upper() if user_input == "S": stopwatch.start(tick_callback=self._update_printout) elif user_input == "P": stopwatch.pause() elif user_input == "R": stopwatch.reset() elif user_input == "T": stopwatch.stop() stopwatch_active = False # At this point, stopwatch has been stopped, so now attempt to assign # its total duration to the task. if metric: self._assign_time(task, metric, stopwatch.total) else: self._assign_time_interactive(task, stopwatch.total) self.projects.save(self.current_project)
def do_tasks(self, line): """Print out a list of tasks for the current project and accumulated metrics for each task. """ parser = ArgumentParser(stdout=self.stdout, prog="tasks", add_help=False) parser.add_argument("--details", action="store_true") parser.add_argument("pattern", metavar="PATTERN", nargs="?") args = parser.parse_args(line.split()) if not args: self._error("Invalid arguments") return details = args.details pattern = args.pattern if args.pattern else "*" self._title("Tasks") # align printed values for details by finding longest metric name metric_names = [m.name for m in self.current_project.metrics] metric_names.append("Created"), metric_names.append("Last Updated") max_name_len = len(max(metric_names, key=len)) detail_fmt = " {0:" + str(max_name_len) + "} | {1}" for task in sorted( filter(lambda t: fnmatch.fnmatch(t.name, pattern), self.current_project.tasks), key=lambda t: t.name ): self._info(" * " + task.name, extra_newline=False) if details: self._print(" " + "-" * 51) for metric in self.current_project.metrics: metric_value = task.value(metric) value = metric.metric_type.to_str(metric_value) if metric_value else "----" self._print(detail_fmt.format(metric.name, value)) self._print() self._print(detail_fmt.format("Created", task.created)) self._print(detail_fmt.format("Last Updated", task.last_updated)) self._print() self._print()