diff --git a/gcalcli/argparsers.py b/gcalcli/argparsers.py index 5baadcec..1d1cca0b 100644 --- a/gcalcli/argparsers.py +++ b/gcalcli/argparsers.py @@ -66,9 +66,12 @@ 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( + 'Width must be a number >= %d' % minwidth + ) return ival @@ -100,9 +103,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_output_parser(parents=[]): @@ -116,9 +117,8 @@ def get_output_parser(parents=[]): output_parser.add_argument( '--nodeclined', action='store_true', dest='ignore_declined', 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', + '--width', '-w', default=get_auto_width(), dest='width', type=validwidth, help='Set output width') has_24_hours = locale_has_24_hours() output_parser.add_argument( diff --git a/gcalcli/gcal.py b/gcalcli/gcal.py index 6cce704c..a85ba510 100644 --- a/gcalcli/gcal.py +++ b/gcalcli/gcal.py @@ -68,10 +68,18 @@ def __init__(self, cal_names=(), printer=PRINTER, **options): self.cals = [] self.printer = printer self.options = options + self.width = {} self.details = options.get('details', {}) - # stored as detail, but provided as option: TODO: fix that - self.details['width'] = options.get('width', 80) + + # Number of days to print in calw/calm + self.days = 7 if self.options.get('cal_weekend', True) else 5 + # Store overall calendar width and width for day table cells + self.width['cal'] = int(options.get('width', 80)) + day_width = int(( self.width['cal'] - self.days - 1) / self.days) + # Minimal day table cell is 10 + self.width['day'] = day_width if day_width > 9 else 10 + self._get_cached() self._select_cals(cal_names) @@ -340,7 +348,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'] ) ) @@ -406,7 +414,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): @@ -417,7 +425,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])) @@ -435,11 +443,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: @@ -455,24 +463,25 @@ 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'] - days = 7 if self.options['cal_weekend'] else 5 + day_width_line = self.width['day'] * self.printer.art['hrz'] # 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)] + day_names = [date(2001, 1, i + 1).strftime('%A') + for i in range(self.days)] if not self.options['cal_monday'] or not self.options['cal_weekend']: day_names = day_names[6:] + day_names[:6] def build_divider(left, center, right): return ( self.printer.art[left] + day_width_line + - ((days - 1) * (self.printer.art[center] + day_width_line)) + + ( (self.days - 1) * (self.printer.art[center] + + day_width_line) ) + self.printer.art[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 @@ -480,7 +489,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'] * self.days) + (self.days - 1) month_title += ' ' * (month_width - self._printed_len(month_title)) self.printer.art_msg('vrt', color_border) @@ -498,7 +507,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) @@ -515,7 +524,7 @@ def build_divider(left, center, right): for i in range(count): # create and print the date line for a week - for j in range(days): + for j in range(self.days): if cmd == 'calw': d = (start_week_datetime + timedelta(days=j)).strftime('%d %b') @@ -533,7 +542,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) @@ -555,7 +564,7 @@ def build_divider(left, center, right): # stop when everything has been printed done = True self.printer.art_msg('vrt', color_border) - for j in range(days): + for j in range(self.days): if not week_events[j]: # no events today self.printer.msg( @@ -566,7 +575,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, @@ -626,23 +635,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' @@ -794,7 +803,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 ) ) + @@ -804,7 +813,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 ) ) + @@ -819,7 +828,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 03ab5562..aa462ac2 100644 --- a/tests/test_argparsers.py +++ b/tests/test_argparsers.py @@ -30,23 +30,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 dddf86e9..a0855b5c 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') @@ -296,13 +296,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)