diff --git a/gcalcli/argparsers.py b/gcalcli/argparsers.py index 3e84cc0..0326d57 100644 --- a/gcalcli/argparsers.py +++ b/gcalcli/argparsers.py @@ -108,9 +108,10 @@ def __call__(self, parser, namespace, value, option_string=None): def validwidth(value): + minwidth=30 ival = int(value) - if ival < 10: - raise argparse.ArgumentTypeError('Width must be a number >= 10') + if ival < minwidth: + raise argparse.ArgumentTypeError(f'Width must be a number >= {minwidth}') return ival @@ -146,9 +147,7 @@ def locale_has_24_hours(): def get_auto_width(): - console_width = get_terminal_size().columns - day_width = int((console_width - 8) / 7) - return day_width if day_width > 9 else 10 + return get_terminal_size().columns def get_calendars_parser(nargs_multiple: bool) -> argparse.ArgumentParser: @@ -204,12 +203,11 @@ def get_output_parser(parents=[]): default=False, help='Hide events that have been declined', ) - auto_width = get_auto_width() output_parser.add_argument( '--width', '-w', - default=auto_width, - dest='cal_width', + default=get_auto_width(), + dest='width', type=validwidth, help='Set output width', ) diff --git a/gcalcli/gcal.py b/gcalcli/gcal.py index 3c8619d..514e960 100644 --- a/gcalcli/gcal.py +++ b/gcalcli/gcal.py @@ -79,10 +79,16 @@ def __init__( self.printer = printer self.options = options self.userless_mode = userless_mode + self.width = {} self.details = options.get('details', {}) - # stored as detail, but provided as option: TODO: fix that - self.details['width'] = options.get('width', 80) + + # Store overall calendar width and width for day table cells + self.width['cal'] = int(options.get('width', 80)) + day_width = int(( self.width['cal'] - 8) / 7) + # Mimimal day table cell is 10 + self.width['day'] = day_width if day_width > 9 else 10 + if self.userless_mode: print( "Running in GCALCLI_USERLESS_MODE. Most operations will fail!", @@ -463,7 +469,7 @@ def _get_week_events(self, start_dt, end_dt, event_list): days_since_epoch(event['s'])): week_events[event_daynum].append( EventTitle( - '\n' + self.options['cal_width'] * '-', + '\n' + self.width['day'] * '-', self.options['color_now_marker'] ) ) @@ -526,7 +532,7 @@ def _word_cut(self, word): stop = 0 for i, char in enumerate(word): stop += self._printed_len(char) - if stop >= self.options['cal_width']: + if stop >= self.width['day']: return stop, i + 1 def _next_cut(self, string): @@ -537,7 +543,7 @@ def _next_cut(self, string): for i, word in enumerate(words): word_lens.append(self._printed_len(word)) - if (word_lens[-1] + print_len) >= self.options['cal_width']: + if (word_lens[-1] + print_len) >= self.width['day']: # this many words is too many, try to cut at the prev word cut_idx = len(' '.join(words[:i])) @@ -555,11 +561,11 @@ def _get_cut_index(self, event_string): # newline in string is a special case idx = event_string.find('\n') - if idx > -1 and idx <= self.options['cal_width']: + if idx > -1 and idx <= self.width['day']: return (self._printed_len(event_string[:idx]), len(event_string[:idx])) - if print_len <= self.options['cal_width']: + if print_len <= self.width['day']: return (print_len, len(event_string)) else: @@ -575,7 +581,7 @@ def _GraphEvents(self, cmd, start_datetime, count, event_list): while (len(event_list) and event_list[0]['s'] < start_datetime): event_list = event_list[1:] - day_width_line = self.options['cal_width'] * self.printer.art['hrz'] + day_width_line = self.width['day'] * self.printer.art['hrz'] days = 7 if self.options['cal_weekend'] else 5 # Get the localized day names... January 1, 2001 was a Monday day_names = [date(2001, 1, i + 1).strftime('%A') for i in range(days)] @@ -593,7 +599,7 @@ def build_divider(left, center, right): week_top = build_divider('ulc', 'ute', 'urc') week_divider = build_divider('lte', 'crs', 'rte') week_bottom = build_divider('llc', 'bte', 'lrc') - empty_day = self.options['cal_width'] * ' ' + empty_day = self.width['day'] * ' ' if cmd == 'calm': # month titlebar @@ -601,7 +607,7 @@ def build_divider(left, center, right): self.printer.msg(month_title_top + '\n', color_border) month_title = start_datetime.strftime('%B %Y') - month_width = (self.options['cal_width'] * days) + (days - 1) + month_width = (self.width['day'] * days) + (days - 1) month_title += ' ' * (month_width - self._printed_len(month_title)) self.printer.art_msg('vrt', color_border) @@ -619,7 +625,7 @@ def build_divider(left, center, right): self.printer.art_msg('vrt', color_border) for day_name in day_names: day_name += ' ' * ( - self.options['cal_width'] - self._printed_len(day_name) + self.width['day'] - self._printed_len(day_name) ) self.printer.msg(day_name, self.options['color_date']) self.printer.art_msg('vrt', color_border) @@ -654,7 +660,7 @@ def build_divider(left, center, right): tmp_date_color = self.options['color_now_marker'] d += ' **' - d += ' ' * (self.options['cal_width'] - self._printed_len(d)) + d += ' ' * (self.width['day'] - self._printed_len(d)) # print dates self.printer.art_msg('vrt', color_border) @@ -687,7 +693,7 @@ def build_divider(left, center, right): curr_event = week_events[j][0] print_len, cut_idx = self._get_cut_index(curr_event.title) - padding = ' ' * (self.options['cal_width'] - print_len) + padding = ' ' * (self.width['day'] - print_len) self.printer.msg( curr_event.title[:cut_idx] + padding, @@ -747,23 +753,23 @@ def _format_descr(descr, indent, box): if box: wrapper.initial_indent = (indent + ' ') wrapper.subsequent_indent = (indent + ' ') - wrapper.width = (self.details.get('width') - 2) + wrapper.width = (self.width['cal'] - 2) else: wrapper.initial_indent = indent wrapper.subsequent_indent = indent - wrapper.width = self.details.get('width') + wrapper.width = self.width['cal'] new_descr = '' for line in descr.split('\n'): if box: tmp_line = wrapper.fill(line) for single_line in tmp_line.split('\n'): single_line = single_line.ljust( - self.details.get('width'), ' ' + self.width['cal'], ' ' ) new_descr += single_line[:len(indent)] + \ self.printer.art['vrt'] + \ single_line[(len(indent) + 1): - (self.details.get('width') - 1)] + \ + (self.width['cal'] - 1)] + \ self.printer.art['vrt'] + '\n' else: new_descr += wrapper.fill(line) + '\n' @@ -915,7 +921,7 @@ def _format_descr(descr, indent, box): descr_indent + self.printer.art['ulc'] + (self.printer.art['hrz'] * - ((self.details.get('width') - len(descr_indent)) + ((self.width['cal'] - len(descr_indent)) - 2 ) ) + @@ -925,7 +931,7 @@ def _format_descr(descr, indent, box): descr_indent + self.printer.art['llc'] + (self.printer.art['hrz'] * - ((self.details.get('width') - len(descr_indent)) + ((self.width['cal'] - len(descr_indent)) - 2 ) ) + @@ -940,7 +946,7 @@ def _format_descr(descr, indent, box): ) else: marker = descr_indent + '-' * \ - (self.details.get('width') - len(descr_indent)) + (self.width['cal'] - len(descr_indent)) xstr = '%s Description:\n%s\n%s\n%s\n' % ( details_indent, marker, diff --git a/tests/test_argparsers.py b/tests/test_argparsers.py index b4b9078..35994b3 100644 --- a/tests/test_argparsers.py +++ b/tests/test_argparsers.py @@ -32,23 +32,23 @@ def fake_get_terminal_size(): return fake_get_terminal_size output_parser = argparsers.get_output_parser() - argv = shlex.split('-w 9') + argv = shlex.split('-w 29') with pytest.raises(SystemExit): output_parser.parse_args(argv) - argv = shlex.split('-w 10') - assert output_parser.parse_args(argv).cal_width == 10 + argv = shlex.split('-w 30') + assert output_parser.parse_args(argv).width == 30 argv = shlex.split('') monkeypatch.setattr(argparsers, 'get_terminal_size', sub_terminal_size(70)) output_parser = argparsers.get_output_parser() - assert output_parser.parse_args(argv).cal_width == 10 + assert output_parser.parse_args(argv).width == 70 argv = shlex.split('') monkeypatch.setattr(argparsers, 'get_terminal_size', sub_terminal_size(100)) output_parser = argparsers.get_output_parser() - assert output_parser.parse_args(argv).cal_width == 13 + assert output_parser.parse_args(argv).width == 100 def test_search_parser(): diff --git a/tests/test_gcalcli.py b/tests/test_gcalcli.py index 29f67af..abc6ac2 100644 --- a/tests/test_gcalcli.py +++ b/tests/test_gcalcli.py @@ -86,7 +86,7 @@ def test_cal_query(capsys, PatchedGCalI): art = gcal.printer.art expect_top = ( gcal.printer.colors[gcal.options['color_border']] + art['ulc'] + - art['hrz'] * gcal.options['cal_width']) + art['hrz'] * gcal.width['day']) assert captured.out.startswith(expect_top) gcal.CalQuery('calm') @@ -348,13 +348,13 @@ def test_iterate_events(capsys, PatchedGCalI): def test_next_cut(PatchedGCalI): gcal = PatchedGCalI() # default width is 10 - test_cal_width = 10 - gcal.options['cal_width'] = test_cal_width + test_day_width = 10 + gcal.width['day'] = test_day_width event_title = "first looooong" assert gcal._next_cut(event_title) == (5, 5) - event_title = "tooooooloooong" - assert gcal._next_cut(event_title) == (test_cal_width, test_cal_width) + event_title = "tooooooooooooooooooooooooloooooooooong" + assert gcal._next_cut(event_title) == (test_day_width, test_day_width) event_title = "one two three four" assert gcal._next_cut(event_title) == (7, 7)