Skip to content

Commit

Permalink
Merge pull request #771 from insanum/dtend-duration
Browse files Browse the repository at this point in the history
CreateEventFromVOBJ: if there is no dtend, use the duration if available
  • Loading branch information
dbarnett authored Sep 26, 2024
2 parents 92af8b4 + a4d5a23 commit bcda636
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 45 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ v4.5.0
reading an rc file you needed
* The `import` command now dumps events it couldn't import into a tmp rej.ics
file in a tmp directory for convenient retries
* `import` can also handle events w/o a dtend, using duration if available
* Determine date format to use based on system locale's in "When" inputs
* Respect locally-installed certificates (ajkessel)
* Re-add a `--noauth_local_server` to provide instructions for authenticating
Expand Down
97 changes: 52 additions & 45 deletions gcalcli/ics.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from dataclasses import dataclass
import importlib.util
import io
from datetime import datetime
from datetime import datetime, timedelta
import pathlib
import tempfile
from typing import Any, NamedTuple, Optional
Expand Down Expand Up @@ -79,61 +79,68 @@ def CreateEventFromVOBJ(
print('Location.....%s' % ve.location.value)
event['location'] = ve.location.value

if not hasattr(ve, 'dtstart') or not hasattr(ve, 'dtend'):
printer.err_msg('Error: event does not have a dtstart and dtend!\n')
if not hasattr(ve, 'dtstart') or not ve.dtstart.value:
printer.err_msg('Error: event does not have a dtstart!\n')
return EventData(body=None, source=ve)

if verbose:
if ve.dtstart.value:
print('Start........%s' % ve.dtstart.value.isoformat())
if ve.dtend.value:
print('End..........%s' % ve.dtend.value.isoformat())
if ve.dtstart.value:
print('Local Start..%s' % localize_datetime(ve.dtstart.value))
if ve.dtend.value:
print('Local End....%s' % localize_datetime(ve.dtend.value))

if hasattr(ve, 'rrule'):
if verbose:
print('Recurrence...%s' % ve.rrule.value)

event['recurrence'] = ['RRULE:' + ve.rrule.value]

if hasattr(ve, 'dtstart') and ve.dtstart.value:
# XXX
# Timezone madness! Note that we're using the timezone for the
# calendar being added to. This is OK if the event is in the
# same timezone. This needs to be changed to use the timezone
# from the DTSTART and DTEND values. Problem is, for example,
# the TZID might be "Pacific Standard Time" and Google expects
# a timezone string like "America/Los_Angeles". Need to find a
# way in python to convert to the more specific timezone
# string.
# XXX
# print ve.dtstart.params['X-VOBJ-ORIGINAL-TZID'][0]
# print default_tz
# print dir(ve.dtstart.value.tzinfo)
# print vars(ve.dtstart.value.tzinfo)

start = ve.dtstart.value.isoformat()
if isinstance(ve.dtstart.value, datetime):
event['start'] = {'dateTime': start, 'timeZone': default_tz}
if verbose:
print('Start........%s' % ve.dtstart.value.isoformat())
print('Local Start..%s' % localize_datetime(ve.dtstart.value))

# XXX
# Timezone madness! Note that we're using the timezone for the calendar
# being added to. This is OK if the event is in the same timezone. This
# needs to be changed to use the timezone from the DTSTART and DTEND values.
# Problem is, for example, the TZID might be "Pacific Standard Time" and
# Google expects a timezone string like "America/Los_Angeles". Need to find
# a way in python to convert to the more specific timezone string.
# XXX
# print ve.dtstart.params['X-VOBJ-ORIGINAL-TZID'][0]
# print default_tz
# print dir(ve.dtstart.value.tzinfo)
# print vars(ve.dtstart.value.tzinfo)

start = ve.dtstart.value.isoformat()
if isinstance(ve.dtstart.value, datetime):
event['start'] = {'dateTime': start, 'timeZone': default_tz}
else:
event['start'] = {'date': start}

# All events must have a start, but explicit end is optional.
# If there is no end, use the duration if available, or the start otherwise.
if hasattr(ve, 'dtend') and ve.dtend.value:
end = ve.dtend.value
if verbose:
print('End..........%s' % end.isoformat())
print('Local End....%s' % localize_datetime(end))
else: # using duration instead of end
if hasattr(ve, 'duration') and ve.duration.value:
duration = ve.duration.value
else:
event['start'] = {'date': start}

# NOTE: Reminders added by GoogleCalendarInterface caller.
printer.msg(
"Falling back to 30m duration for imported event w/o "
"explicit duration or end.\n"
)
duration = timedelta(minutes=30)
if verbose:
print('Duration.....%s' % duration)
end = ve.dtstart.value + duration
if verbose:
print('Calculated End........%s' % end.isoformat())
print('Calculated Local End..%s' % localize_datetime(end))

# Can only have an end if we have a start, but not the other
# way around apparently... If there is no end, use the start
if hasattr(ve, 'dtend') and ve.dtend.value:
end = ve.dtend.value.isoformat()
if isinstance(ve.dtend.value, datetime):
event['end'] = {'dateTime': end, 'timeZone': default_tz}
else:
event['end'] = {'date': end}
if isinstance(end, datetime):
event['end'] = {'dateTime': end.isoformat(), 'timeZone': default_tz}
else:
event['end'] = {'date': end.isoformat()}

else:
event['end'] = event['start']
# NOTE: Reminders added by GoogleCalendarInterface caller.

if hasattr(ve, 'description') and ve.description.value.strip():
descr = ve.description.value.strip()
Expand Down

0 comments on commit bcda636

Please sign in to comment.