Skip to content

Commit 06f409a

Browse files
feat: add agendaupdate for time
Round trips don't work for all day events. The current output format is to present them as events starting and ending at midnight of the same day. But this keeps us from having events starting and ending at midnight of the same day. In the next commit I plan to change the output for all day events so the time fields are blank. Also: - change signature of `Handler.patch()` to include `cal`, which is necessary to extract the timezone - change default of `Handler.fieldnames` from `None` to `[]` to silence a mypy warning. Partially implements insanum#550.
1 parent ba7e543 commit 06f409a

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

gcalcli/details.py

+38-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
"""Handlers for specific details of events."""
22

33
from collections import OrderedDict
4+
from datetime import datetime
45
from itertools import chain
5-
from typing import List, Optional
6+
from typing import List
7+
8+
from dateutil.parser import isoparse, parse
69

710
FMT_DATE = '%Y-%m-%d'
811
FMT_TIME = '%H:%M'
12+
TODAY = datetime.now().date()
913

1014

1115
def _valid_title(event):
@@ -20,15 +24,15 @@ class Handler:
2024

2125
# list of strings for fieldnames provided by this object
2226
# XXX: py36+: change to `fieldnames: List[str]`
23-
fieldnames = None # type: Optional[List[str]]
27+
fieldnames = [] # type: List[str]
2428

2529
@classmethod
2630
def get(cls, event):
2731
"""Return simple string representation for columnar output."""
2832
raise NotImplementedError
2933

3034
@classmethod
31-
def patch(cls, event, fieldname, value):
35+
def patch(cls, cal, event, fieldname, value):
3236
"""Patch event from value."""
3337
raise NotImplementedError
3438

@@ -41,8 +45,8 @@ def get(cls, event):
4145
return [cls._get(event).strip()]
4246

4347
@classmethod
44-
def patch(cls, event, fieldname, value):
45-
cls._patch(cls, event, value)
48+
def patch(cls, cal, event, fieldname, value):
49+
return cls._patch(event, value)
4650

4751

4852
class SimpleSingleFieldHandler(SingleFieldHandler):
@@ -67,6 +71,35 @@ def get(cls, event):
6771
return [event['s'].strftime(FMT_DATE), event['s'].strftime(FMT_TIME),
6872
event['e'].strftime(FMT_DATE), event['e'].strftime(FMT_TIME)]
6973

74+
@classmethod
75+
def patch(cls, cal, event, fieldname, value):
76+
instant_name, _, unit = fieldname.partition('_')
77+
78+
assert instant_name in {'start', 'end'}
79+
80+
if unit == 'date':
81+
instant = event[instant_name] = {}
82+
instant_date = parse(value, default=TODAY)
83+
84+
instant['date'] = instant_date.isoformat()
85+
instant['dateTime'] = None # clear any previous non-all-day time
86+
else:
87+
assert unit == 'time'
88+
89+
# If the time field is empty, do nothing.
90+
# This enables all day events.
91+
if not value.strip():
92+
return
93+
94+
# date must be an earlier TSV field than time
95+
instant = event[instant_name]
96+
instant_date = isoparse(instant['date'])
97+
instant_datetime = parse(value, default=instant_date)
98+
99+
instant['date'] = None # clear all-day date
100+
instant['dateTime'] = instant_datetime.isoformat()
101+
instant['timeZone'] = cal['timeZone']
102+
70103

71104
class Url(Handler):
72105
"""Handler for HTML and legacy Hangout links."""

gcalcli/gcal.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1214,13 +1214,14 @@ def AgendaUpdate(self, file=sys.stdin):
12141214
if len(self.cals) != 1:
12151215
raise GcalcliError('Must specify a single calendar.')
12161216

1217-
cal_id = self.cals[0]['id']
1217+
cal = self.cals[0]
1218+
cal_id = cal['id']
12181219

12191220
for row in reader:
12201221
event = {}
12211222

12221223
for fieldname, value in row.items():
1223-
FIELD_HANDLERS[fieldname].patch(event, value)
1224+
FIELD_HANDLERS[fieldname].patch(cal, event, fieldname, value)
12241225

12251226
self._retry_with_backoff(
12261227
self.get_cal_service()

0 commit comments

Comments
 (0)