tomsquest / docker-radicale

Docker image for Radicale calendar and contact server :calendar: + security :closed_lock_with_key: + addons :rocket:
GNU General Public License v3.0
562 stars 80 forks source link

Add pytz dependency #77

Closed silaslenz closed 4 years ago

silaslenz commented 4 years ago

Radicale requires pytz for timezone support. As is adding events with for example DTSTART;TZID=Europe/Stockholm;VALUE=DATE-TIME:20200527T101010 results in ERROR:root:No module named 'pytz', similar to here https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=886425

tomsquest commented 4 years ago

Hi, Thanks for reporting it.

I saw this comment by the author of Radicale:

pytz is an optional dependency of vobject. It shouldn't be required, when your iCalendar files are valid https://github.com/Kozea/Radicale/issues/816

So:

I have no strong opinion on pytz, the goal is not to have the smallest of the smallest image.

Thanks, Tom

silaslenz commented 4 years ago

I've used the caldav and icalendar Python packages. Seems like Radicale is actually able to add the event even without pytz, but does print the above mentioned error.

I tried adding an event with and without pytz installed, and with it adds a VTIMEZONE-component to the calendar, see files: with_pytz.txt no_pytz.txt

So according to https://icalendar.org/validator.html Radicale creates invalid ical files without pytz (or maybe py-icalendar should have added the VTIMEZONE-component and Radicale is only able to fix it if pytz is installed?).

I was using this code to add the events:

import caldav
import uuid
import pytz
import icalendar
import datetime

new_calendar = icalendar.Calendar()
event = icalendar.Event()
event.add('uid', uuid.uuid4())
event.add('summary', "test event")
event.add('dtstamp', datetime.datetime.now(tz=pytz.timezone("Europe/Stockholm")))
event.add('dtstart', datetime.datetime.now(tz=pytz.timezone("Europe/Stockholm")))
event.add('dtend', datetime.datetime.now(tz=pytz.timezone("Europe/Stockholm"))+datetime.timedelta(minutes=30))
new_calendar.add_component(event)

calendar = caldav.DAVClient("http://admin:admin@localhost:5232/admin/5367c792-5f90-c3c5-cad7-8e0960b6d1aa/").principal().calendars()[0]
calendar.add_event(new_calendar.to_ical())

And calendar.date_search(datetime.datetime.now(tz=pytz.timezone("Europe/Stockholm")),datetime.datetime.now(tz=pytz.timezone("Europe/Stockholm"))) to find them again. This didn't work without pytz, probably because it is searching at some offset due to the missing timezone information. It finds the event if i search for a wider timespan.

tomsquest commented 4 years ago

Thanks for the detailed answer.

I wonder : why is the code using Timezone instead of sending UTC ? That made the database (here radicale) agnostic of the consumer location/timezone (and this is what I have used at work in all case).

There was some comments, in Radicale, that basically said that the iCalendar spec requires UTC. There is also an answer on Stackoverflow saying to convert to utc using pytz.

silaslenz commented 4 years ago

This isn't relevant for this particular example, but i also use recurring events, and as far as i understand they would become incorrect when switching to/from daylight saving time if using UTC. I'm basing that on this Stack overflow answer: https://stackoverflow.com/a/42941087

tomsquest commented 4 years ago

Hi @silaslenz ,

My comment got lost.

Thanks for the link to this SO answer ! I learnt about recurrence/UTC and daylight savings! Very appreciated.

I am merging this PR and will push a tag ASAP.

silaslenz commented 4 years ago

Perfect! Thanks for the quick merge :)

tomsquest commented 4 years ago

tagged as 2.1.12.1 It should hit Docker Hub soon (ETA 30 minutes I think).