class ListCommand(ExpressionCommand): def __init__(self, p_args, p_todolist, #pragma: no branch p_out=lambda a: None, p_err=lambda a: None, p_prompt=lambda a: None): super().__init__( p_args, p_todolist, p_out, p_err, p_prompt) self.printer = None self.sort_expression = config().sort_string() self.show_all = False self.ids = None self.format = config().list_format() def _poke_icalendar(self): """ Attempts to import the icalendar package. Returns True if it succeeds, otherwise False. """ try: import icalendar as _ except ImportError: # pragma: no cover self.error("icalendar package is not installed.") return False return True def _process_flags(self): opts, args = self.getopt('f:F:i:n:Ns:x') for opt, value in opts: if opt == '-x': self.show_all = True elif opt == '-s': self.sort_expression = value elif opt == '-f': if value == 'json': from topydo.lib.JsonPrinter import JsonPrinter self.printer = JsonPrinter() elif value == 'ical': if self._poke_icalendar(): from topydo.lib.IcalPrinter import IcalPrinter self.printer = IcalPrinter(self.todolist) else: self.printer = None elif opt == '-F': self.format = value elif opt == '-N': # 2 lines are assumed to be taken up by printing the next prompt # display at least one item self.limit = self._N_lines() elif opt == '-n': try: self.limit = int(value) except ValueError: pass # use default value in configuration elif opt == '-i': self.ids = value.split(',') # when a user requests a specific ID, it should always be shown self.show_all = True self.args = args def _filters(self): """ Additional filters to: - select particular todo items given with the -i flag, - hide appropriately tagged items in the absense of the -x flag. """ filters = super()._filters() if self.ids: def get_todo(p_id): """ Safely obtains a todo item given the user-supplied ID. Returns None if an invalid ID was entered. """ try: return self.todolist.todo(p_id) except InvalidTodoException: return None todos = [get_todo(i) for i in self.ids] filters.append(InstanceFilter(todos)) if not self.show_all: filters.append(HiddenTagFilter()) return filters def _print(self): """ Prints the todos in the right format. Defaults to normal text output (with possible colors and other pretty printing). If a format was specified on the commandline, this format is sent to the output. """ if self.printer is None: # create a standard printer with some filters indent = config().list_indent() final_format = ' ' * indent + self.format filters = [] filters.append(PrettyPrinterFormatFilter(self.todolist, final_format)) self.printer = pretty_printer_factory(self.todolist, filters) self.out(self.printer.print_list(self._view().todos)) def _N_lines(self): ''' Determine how many lines to print, such that the number of items displayed will fit on the terminal (i.e one 'screen-ful' of items) This looks at the environmental prompt variable, and tries to determine how many lines it takes up. On Windows, it does this by looking for the '$_' sequence, which indicates a new line, in the environmental variable PROMPT. Otherwise, it looks for a newline ('\n') in the environmental variable PS1. ''' lines_in_prompt = 1 # prompt is assumed to take up one line, even # without any newlines in it if "win32" in sys.platform: lines_in_prompt += 1 # Windows will typically print a free line after # the program output a = re.findall('\$_', os.getenv('PROMPT', '')) lines_in_prompt += len(a) else: a = re.findall('\\n', os.getenv('PS1', '')) lines_in_prompt += len(a) n_lines = get_terminal_size().lines - lines_in_prompt # print a minimum of one item n_lines = max(n_lines, 1) return n_lines def execute(self): if not super().execute(): return False try: self._process_flags() except SyntaxError: # pragma: no cover # importing icalendar failed, most likely due to Python 3.2 self.error("icalendar is not supported in this Python version.") return False self._print() return True def usage(self): return """Synopsis: ls [-x] [-s <SORT EXPRESSION>] [-f <OUTPUT FORMAT>] [-F <FORMAT STRING>] [-i <NUMBER 1>[,<NUMBER 2> ...]] [-N | -n <INTEGER>] [EXPRESSION]""" def help(self): return """\
class ListCommand(ExpressionCommand): def __init__(self, p_args, p_todolist, #pragma: no branch p_out=lambda a: None, p_err=lambda a: None, p_prompt=lambda a: None): super().__init__( p_args, p_todolist, p_out, p_err, p_prompt) self.printer = None self.sort_expression = config().sort_string() self.show_all = False self.ids = None self.format = config().list_format() def _poke_icalendar(self): """ Attempts to import the icalendar package. Returns True if it succeeds, otherwise False. """ try: import icalendar as _ except ImportError: # pragma: no cover self.error("icalendar package is not installed.") return False return True def _process_flags(self): opts, args = self.getopt('f:F:i:n:Ns:x') for opt, value in opts: if opt == '-x': self.show_all = True elif opt == '-s': self.sort_expression = value elif opt == '-f': if value == 'json': from topydo.lib.JsonPrinter import JsonPrinter self.printer = JsonPrinter() elif value == 'ical': if self._poke_icalendar(): from topydo.lib.IcalPrinter import IcalPrinter self.printer = IcalPrinter(self.todolist) else: self.printer = None elif opt == '-F': self.format = value elif opt == '-N': # 2 lines are assumed to be taken up by printing the next prompt # display at least one item self.limit = max(get_terminal_size().lines - 2, 1) elif opt == '-n': try: self.limit = int(value) except ValueError: pass # use default value in configuration elif opt == '-i': self.ids = value.split(',') # when a user requests a specific ID, it should always be shown self.show_all = True self.args = args def _filters(self): """ Additional filters to select particular todo items given with the -i flag. """ filters = super()._filters() if self.ids: def get_todo(p_id): """ Safely obtains a todo item given the user-supplied ID. Returns None if an invalid ID was entered. """ try: return self.todolist.todo(p_id) except InvalidTodoException: return None todos = [get_todo(i) for i in self.ids] filters.append(InstanceFilter(todos)) return filters def _print(self): """ Prints the todos in the right format. Defaults to normal text output (with possible colors and other pretty printing). If a format was specified on the commandline, this format is sent to the output. """ if self.printer is None: # create a standard printer with some filters indent = config().list_indent() final_format = ' ' * indent + self.format filters = [] filters.append(PrettyPrinterFormatFilter(self.todolist, final_format)) self.printer = pretty_printer_factory(self.todolist, filters) self.out(self.printer.print_list(self._view().todos)) def execute(self): if not super().execute(): return False try: self._process_flags() except SyntaxError: # pragma: no cover # importing icalendar failed, most likely due to Python 3.2 self.error("icalendar is not supported in this Python version.") return False self._print() return True def usage(self): return """Synopsis: ls [-x] [-s <SORT EXPRESSION>] [-f <OUTPUT FORMAT>] [-F <FORMAT STRING>] [-i <NUMBER 1>[,<NUMBER 2> ...]] [-N | -n <INTEGER>] [EXPRESSION]""" def help(self): return """\
class ListCommand(ExpressionCommand): def __init__(self, p_args, p_todolist, p_out=lambda a: None, p_err=lambda a: None, p_prompt=lambda a: None): super(ListCommand, self).__init__( p_args, p_todolist, p_out, p_err, p_prompt) self.printer = None self.sort_expression = config().sort_string() self.show_all = False def _poke_icalendar(self): """ Attempts to import the icalendar package. Returns True if it succeeds, otherwise False. Raises a SyntaxError when icalendar couldn't be imported (most likely under Python 3.2. """ try: import icalendar as _ except ImportError: # pragma: no cover self.error("icalendar package is not installed.") return False # may also raise SyntaxError, but we'll deal with that in execute() return True def _process_flags(self): opts, args = self.getopt('f:s:x') for opt, value in opts: if opt == '-x': self.show_all = True elif opt == '-s': self.sort_expression = value elif opt == '-f': if value == 'json': self.printer = JsonPrinter() elif value == 'ical': if self._poke_icalendar(): self.printer = IcalPrinter(self.todolist) else: self.printer = None self.args = args def _print(self): """ Prints the todos in the right format. Defaults to normal text output (with possible colors and other pretty printing. If a format was specified on the commandline, this format is sent to the output. """ if self.printer == None: # create a standard printer with some filters indent = config().list_indent() hidden_tags = config().hidden_tags() filters = [] filters.append(PrettyPrinterIndentFilter(indent)) filters.append(PrettyPrinterHideTagFilter(hidden_tags)) self.printer = pretty_printer_factory(self.todolist, filters) self.out(self.printer.print_list(self._view().todos)) def execute(self): if not super(ListCommand, self).execute(): return False try: self._process_flags() except SyntaxError: # pragma: no cover # importing icalendar failed, most likely due to Python 3.2 self.error("icalendar is not supported in this Python version.") return False self._print() return True def usage(self): return """ Synopsis: ls [-x] [-s <sort_expression>] [-f <format>] [expression]""" def help(self): return """\