diff --git a/docs/conf.py b/docs/conf.py index 8d46f11..9af073e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -39,7 +39,8 @@ MOCK_MODULES = [ "dateutil", "httplib2", "oauth2client", - "apiclient" + "apiclient", + "googleapiclient.errors" ] diff --git a/i3pystatus/google_calendar.py b/i3pystatus/google_calendar.py index 3ba3eee..25e41c6 100644 --- a/i3pystatus/google_calendar.py +++ b/i3pystatus/google_calendar.py @@ -5,10 +5,11 @@ import oauth2client import pytz from apiclient import discovery from dateutil import parser +from googleapiclient.errors import HttpError -from i3pystatus import IntervalModule +from i3pystatus import IntervalModule, logger from i3pystatus.core.color import ColorRangeModule -from i3pystatus.core.util import internet, require +from i3pystatus.core.util import internet, require, user_open class GoogleCalendar(IntervalModule, ColorRangeModule): @@ -56,6 +57,11 @@ class GoogleCalendar(IntervalModule, ColorRangeModule): service = None credentials = None + display_event = None + + def on_click(self, button, **kwargs): + self.open_calendar() + def init(self): self.colors = self.get_hex_color_range(self.end_color, self.start_color, self.urgent_seconds * 2) @@ -64,22 +70,23 @@ class GoogleCalendar(IntervalModule, ColorRangeModule): if not self.service: self.connect_service() - display_event = self.get_next_event() - if display_event: - start_time = display_event['start_time'] + self.display_event = self.get_next_event() + if self.display_event: + start_time = self.display_event['start_time'] now = datetime.datetime.now(tz=pytz.UTC) alert_time = now + datetime.timedelta(seconds=self.urgent_seconds) - display_event['remaining_time'] = str((start_time - now)).partition('.')[0] + self.display_event['remaining_time'] = str((start_time - now)).partition('.')[0] urgent = alert_time > start_time color = self.get_color(now, start_time) self.output = { - 'full_text': self.format.format(**display_event), + 'full_text': self.format.format(**self.display_event), 'color': color, 'urgent': urgent } else: + self.display_event = None self.output = { 'full_text': "", } @@ -108,17 +115,25 @@ class GoogleCalendar(IntervalModule, ColorRangeModule): return event def get_events(self): - now, later = self.get_timerange() - events_result = self.service.events().list( - calendarId='primary', - timeMin=now, - timeMax=later, - maxResults=10, - singleEvents=True, - orderBy='startTime', - timeZone='utc' - ).execute() - return events_result.get('items', []) + events = [] + try: + now, later = self.get_timerange() + events_result = self.service.events().list( + calendarId='primary', + timeMin=now, + timeMax=later, + maxResults=10, + singleEvents=True, + orderBy='startTime', + timeZone='utc' + ).execute() + events = events_result.get('items', []) + except HttpError as e: + if e.resp.status in (500, 503): + logger.warn("GoogleCalendar received %s while retrieving events" % e.resp.status) + else: + raise + return events def get_timerange(self): now = datetime.datetime.utcnow() @@ -132,3 +147,9 @@ class GoogleCalendar(IntervalModule, ColorRangeModule): v = self.percentage(seconds_to_event, self.urgent_seconds) color = self.get_gradient(v, self.colors) return color + + def open_calendar(self): + if self.display_event: + calendar_url = self.display_event.get('htmlLink', None) + if calendar_url: + user_open(calendar_url)