File 0001-Fix-width-argument-set-overall-width.patch of Package gcalcli

From 5ee61bf22a4dc2619261f2122189fc80ad5fff83 Mon Sep 17 00:00:00 2001
From: Mischa Salle <msalle@nikhef.nl>
Date: Mon, 20 Jan 2025 13:14:01 +0100
Subject: [PATCH 1/4] Fix width argument, set overall width

Fix the width for the description details, both default and as cmdline option,
and make sure we don't break the width of the calw and calm output.
The (pretty much undocumented) option --width/-w option was used for setting the
width of a day table cell in calw and calm but seemed to also be intended for
setting the overall width of the description in agenda. The latter part was
broken and the details description width would always default to 80.
We change the behaviour to set the overall width of the table, defaulting to the
terminal width, both for calw and calm and for description details. The width of
the day cell is calculated from the overall width.
---
 gcalcli/argparsers.py | 12 +++++------
 gcalcli/gcal.py       | 46 ++++++++++++++++++++++++-------------------
 2 files changed, 31 insertions(+), 27 deletions(-)

diff --git a/gcalcli/argparsers.py b/gcalcli/argparsers.py
index 5baadce..d832b57 100644
--- a/gcalcli/argparsers.py
+++ b/gcalcli/argparsers.py
@@ -66,9 +66,10 @@ class DetailsAction(argparse._AppendAction):
 
 
 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
 
 
@@ -100,9 +101,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 +115,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 6cce704..1c938d3 100644
--- a/gcalcli/gcal.py
+++ b/gcalcli/gcal.py
@@ -68,10 +68,16 @@ class GoogleCalendarInterface:
         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)
+
+        # 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
+
         self._get_cached()
 
         self._select_cals(cal_names)
@@ -340,7 +346,7 @@ class GoogleCalendarInterface:
                             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 +412,7 @@ class GoogleCalendarInterface:
         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 +423,7 @@ class GoogleCalendarInterface:
         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 +441,11 @@ class GoogleCalendarInterface:
 
         # 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,7 +461,7 @@ class GoogleCalendarInterface:
         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)]
@@ -472,7 +478,7 @@ class GoogleCalendarInterface:
         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 +486,7 @@ class GoogleCalendarInterface:
             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)
@@ -498,7 +504,7 @@ class GoogleCalendarInterface:
         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)
@@ -533,7 +539,7 @@ class GoogleCalendarInterface:
                     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)
@@ -566,7 +572,7 @@ class GoogleCalendarInterface:
 
                     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 +632,23 @@ class GoogleCalendarInterface:
             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 +800,7 @@ class GoogleCalendarInterface:
                         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 +810,7 @@ class GoogleCalendarInterface:
                         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 +825,7 @@ class GoogleCalendarInterface:
                 )
             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,
-- 
2.43.0

openSUSE Build Service is sponsored by