Skip to content

Commit a331fb6

Browse files
fix: fix tz handling in ics files (ietf-tools#4630)
* fix: render upcoming.ics timestamps correctly Both correctly display timestamps in the claimed time zones and format the date-times in correct iCalendar format. * refactor: also render DTSTAMP using ics_date_time tag * fix: render valid date-times in agenda.ics * fix: render valid date-time in important_dates_for_meeting.ics Only touching the DTSTAMP here. The DTSTART has VALUE=DATE so the tag does not handle it. * test: test ics_date_time tag
1 parent 000e843 commit a331fb6

4 files changed

Lines changed: 40 additions & 10 deletions

File tree

ietf/doc/templatetags/ietf_filters.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,36 @@ def ics_esc(text):
502502
text = re.sub(r"([\n,;\\])", r"\\\1", text)
503503
return text
504504

505+
506+
@register.simple_tag
507+
def ics_date_time(dt, tzname):
508+
"""Render a datetime as an iCalendar date-time
509+
510+
dt a datetime, localized to the timezone to be displayed
511+
tzname is the name for this timezone
512+
513+
Caller must arrange for a VTIMEZONE for the tzname to be included in the iCalendar file.
514+
Output includes a ':'. Use like:
515+
DTSTART{% ics_date_time timestamp 'America/Los_Angeles' %}
516+
to get
517+
DTSTART;TZID=America/Los_Angeles:20221021T111200
518+
519+
>>> ics_date_time(datetime.datetime(2022,1,2,3,4,5), 'utc')
520+
':20220102T030405Z'
521+
522+
>>> ics_date_time(datetime.datetime(2022,1,2,3,4,5), 'UTC')
523+
':20220102T030405Z'
524+
525+
>>> ics_date_time(datetime.datetime(2022,1,2,3,4,5), 'America/Los_Angeles')
526+
';TZID=America/Los_Angeles:20220102T030405'
527+
"""
528+
timestamp = dt.strftime('%Y%m%dT%H%M%S')
529+
if tzname.lower() == 'utc':
530+
return f':{timestamp}Z'
531+
else:
532+
return f';TZID={ics_esc(tzname)}:{timestamp}'
533+
534+
505535
@register.filter
506536
def consensus(doc):
507537
"""Returns document consensus Yes/No/Unknown."""

ietf/templates/meeting/agenda.ics

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ SUMMARY:{% if item.session.name %}{{item.session.name|ics_esc}}{% else %}{% if n
88
{% if item.timeslot.show_location %}LOCATION:{{item.timeslot.get_location}}
99
{% endif %}STATUS:{{item.session.ical_status}}
1010
CLASS:PUBLIC
11-
DTSTART;TZID={{schedule.meeting.time_zone|ics_esc}}:{{ item.timeslot.time|date:"Ymd" }}T{{item.timeslot.time|date:"Hi"}}00
12-
DTEND;TZID={{schedule.meeting.time_zone|ics_esc}}:{{ item.timeslot.end_time|date:"Ymd" }}T{{item.timeslot.end_time|date:"Hi"}}00
13-
DTSTAMP:{{ item.timeslot.modified|date:"Ymd" }}T{{ item.timeslot.modified|date:"His" }}Z{% if item.session.agenda %}
11+
DTSTART{% ics_date_time item.timeslot.local_start_time schedule.meeting.time_zone %}
12+
DTEND{% ics_date_time item.timeslot.local_end_time schedule.meeting.time_zone %}
13+
DTSTAMP:{% ics_date_time item.timeslot.modified|utc 'utc' %}{% if item.session.agenda %}
1414
URL:{{item.session.agenda.get_versionless_href}}{% endif %}
1515
DESCRIPTION:{{item.timeslot.name|ics_esc}}\n{% if item.session.agenda_note %}
1616
Note: {{item.session.agenda_note|ics_esc}}\n{% endif %}{% if item.timeslot.location.webex_url %}

ietf/templates/meeting/important_dates_for_meeting.ics

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
{% load tz %}{% for d in meeting.important_dates %}BEGIN:VEVENT
1+
{% load tz ietf_filters %}{% for d in meeting.important_dates %}BEGIN:VEVENT
22
UID:ietf-{{ meeting.number }}-{{ d.name_id }}-{{ d.date.isoformat }}
33
SUMMARY:IETF {{ meeting.number }}: {{ d.name.name }}
44
CLASS:PUBLIC
55
DTSTART{% if not d.midnight_cutoff %};VALUE=DATE{% endif %}:{{ d.date|date:"Ymd" }}{% if d.midnight_cutoff %}235900Z{% endif %}
6-
DTSTAMP:{{ meeting.cached_updated|utc|date:"Ymd" }}T{{ meeting.cached_updated|utc|date:"His" }}Z
6+
DTSTAMP{% ics_date_time meeting.cached_updated|utc 'utc' %}
77
TRANSP:TRANSPARENT
88
DESCRIPTION:{{ d.name.desc }}{% if first and d.name.slug == 'openreg' or first and d.name.slug == 'earlybird' %}\n
99
Register here: https://www.ietf.org/how/meetings/register/{% endif %}{% if d.name.slug == 'opensched' %}\n

ietf/templates/meeting/upcoming.ics

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{% load humanize %}{% autoescape off %}{% load ietf_filters %}BEGIN:VCALENDAR
1+
{% load humanize tz %}{% autoescape off %}{% load ietf_filters %}BEGIN:VCALENDAR
22
VERSION:2.0
33
METHOD:PUBLISH
44
PRODID:-//IETF//datatracker.ietf.org ical upcoming//EN
@@ -8,9 +8,9 @@ SUMMARY:{% if item.session.name %}{{item.session.group.acronym|lower}} - {{item.
88
{% if item.schedule.meeting.city %}LOCATION:{{item.schedule.meeting.city}},{{item.schedule.meeting.country}}
99
{% endif %}STATUS:{{item.session.ical_status}}
1010
CLASS:PUBLIC
11-
DTSTART{% if item.schedule.meeting.time_zone %};TZID={{ item.schedule.meeting.time_zone|ics_esc }}{%endif%}:{{ item.timeslot.time|date:"Ymd" }}T{{item.timeslot.time|date:"Hi"}}00
12-
DTEND{% if item.schedule.meeting.time_zone %};TZID={{ item.schedule.meeting.time_zone|ics_esc }}{%endif%}:{{ item.timeslot.end_time|date:"Ymd" }}T{{item.timeslot.end_time|date:"Hi"}}00
13-
DTSTAMP:{{ item.timeslot.modified|date:"Ymd" }}T{{ item.timeslot.modified|date:"His" }}Z
11+
DTSTART{% ics_date_time item.timeslot.local_start_time item.schedule.meeting.time_zone %}
12+
DTEND{% ics_date_time item.timeslot.local_end_time item.schedule.meeting.time_zone %}
13+
DTSTAMP:{% ics_date_time item.timeslot.modified|utc 'utc' %}
1414
{% if item.session.agenda %}URL:{{item.session.agenda.get_href}}
1515
DESCRIPTION:{{item.timeslot.name|ics_esc}}\n{% if item.session.agenda_note %}
1616
Note: {{item.session.agenda_note|ics_esc}}\n{% endif %}{% for material in item.session.materials.all %}
@@ -25,7 +25,7 @@ LOCATION:{{ meeting.city }},{{ meeting.country }}{% endif %}
2525
CLASS:PUBLIC
2626
DTSTART;VALUE=DATE{% if meeting.time_zone %};TZID={{ meeting.time_zone|ics_esc }}{% endif %}:{{ meeting.date|date:"Ymd" }}
2727
DTEND;VALUE=DATE{% if meeting.time_zone %};TZID={{ meeting.time_zone|ics_esc }}{% endif %}:{{ meeting.end_date|date:"Ymd" }}
28-
DTSTAMP:{{ meeting.cached_updated|date:"Ymd" }}T{{ meeting.cached_updated|date:"His" }}Z
28+
DTSTAMP{% ics_date_time meeting.cached_updated|utc 'utc' %}
2929
URL:{{ request.scheme }}://{{ request.get_host }}{% url 'agenda' num=meeting.number %}
3030
END:VEVENT
3131
{% endfor %}END:VCALENDAR{% endautoescape %}

0 commit comments

Comments
 (0)