From fc55ff2bfa2a751c98356c247bb5b71bef25a0b1 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Fri, 21 Oct 2022 19:30:36 -0300 Subject: [PATCH 1/5] fix: render upcoming.ics timestamps correctly Both correctly display timestamps in the claimed time zones and format the date-times in correct iCalendar format. --- ietf/doc/templatetags/ietf_filters.py | 19 +++++++++++++++++++ ietf/templates/meeting/upcoming.ics | 8 ++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/ietf/doc/templatetags/ietf_filters.py b/ietf/doc/templatetags/ietf_filters.py index e7e5a411724..867612f9167 100644 --- a/ietf/doc/templatetags/ietf_filters.py +++ b/ietf/doc/templatetags/ietf_filters.py @@ -502,6 +502,25 @@ def ics_esc(text): text = re.sub(r"([\n,;\\])", r"\\\1", text) return text +@register.simple_tag +def ics_date_time(dt, tzname): + """Render a datetime as an iCalendar date-time + + dt a datetime, localized to the timezone to be displayed + tzname is the name for this timezone + + Caller must arrange for a VTIMEZONE for the tzname to be included in the iCalendar file. + Output includes a ':'. Use like: + DTSTART{% ics_date_time timestamp 'America/Los_Angeles' %} + to get + DTSTART;TZID=America/Los_Angeles:20221021T111200 + """ + timestamp = dt.strftime('%Y%m%dT%H%M%S') + if tzname.lower() == 'utc': + return f':{timestamp}Z' + else: + return f';TZID={ics_esc(tzname)}:{timestamp}' + @register.filter def consensus(doc): """Returns document consensus Yes/No/Unknown.""" diff --git a/ietf/templates/meeting/upcoming.ics b/ietf/templates/meeting/upcoming.ics index 0f2e68b274a..4a1d3dcdc9d 100644 --- a/ietf/templates/meeting/upcoming.ics +++ b/ietf/templates/meeting/upcoming.ics @@ -1,4 +1,4 @@ -{% load humanize %}{% autoescape off %}{% load ietf_filters %}BEGIN:VCALENDAR +{% load humanize tz %}{% autoescape off %}{% load ietf_filters %}BEGIN:VCALENDAR VERSION:2.0 METHOD:PUBLISH PRODID:-//IETF//datatracker.ietf.org ical upcoming//EN @@ -8,8 +8,8 @@ SUMMARY:{% if item.session.name %}{{item.session.group.acronym|lower}} - {{item. {% if item.schedule.meeting.city %}LOCATION:{{item.schedule.meeting.city}},{{item.schedule.meeting.country}} {% endif %}STATUS:{{item.session.ical_status}} CLASS:PUBLIC -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 -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 +DTSTART{% ics_date_time item.timeslot.local_start_time item.schedule.meeting.time_zone %} +DTEND{% ics_date_time item.timeslot.local_end_time item.schedule.meeting.time_zone %} DTSTAMP:{{ item.timeslot.modified|date:"Ymd" }}T{{ item.timeslot.modified|date:"His" }}Z {% if item.session.agenda %}URL:{{item.session.agenda.get_href}} DESCRIPTION:{{item.timeslot.name|ics_esc}}\n{% if item.session.agenda_note %} @@ -25,7 +25,7 @@ LOCATION:{{ meeting.city }},{{ meeting.country }}{% endif %} CLASS:PUBLIC DTSTART;VALUE=DATE{% if meeting.time_zone %};TZID={{ meeting.time_zone|ics_esc }}{% endif %}:{{ meeting.date|date:"Ymd" }} DTEND;VALUE=DATE{% if meeting.time_zone %};TZID={{ meeting.time_zone|ics_esc }}{% endif %}:{{ meeting.end_date|date:"Ymd" }} -DTSTAMP:{{ meeting.cached_updated|date:"Ymd" }}T{{ meeting.cached_updated|date:"His" }}Z +DTSTAMP{% ics_date_time meeting.cached_updated|utc 'utc' %} URL:{{ request.scheme }}://{{ request.get_host }}{% url 'agenda' num=meeting.number %} END:VEVENT {% endfor %}END:VCALENDAR{% endautoescape %} From 90add24d5aca21078386617852ebd7c7980d58f0 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Fri, 21 Oct 2022 19:37:18 -0300 Subject: [PATCH 2/5] refactor: also render DTSTAMP using ics_date_time tag --- ietf/templates/meeting/upcoming.ics | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ietf/templates/meeting/upcoming.ics b/ietf/templates/meeting/upcoming.ics index 4a1d3dcdc9d..a448aeb59d5 100644 --- a/ietf/templates/meeting/upcoming.ics +++ b/ietf/templates/meeting/upcoming.ics @@ -10,7 +10,7 @@ SUMMARY:{% if item.session.name %}{{item.session.group.acronym|lower}} - {{item. CLASS:PUBLIC DTSTART{% ics_date_time item.timeslot.local_start_time item.schedule.meeting.time_zone %} DTEND{% ics_date_time item.timeslot.local_end_time item.schedule.meeting.time_zone %} -DTSTAMP:{{ item.timeslot.modified|date:"Ymd" }}T{{ item.timeslot.modified|date:"His" }}Z +DTSTAMP:{% ics_date_time item.timeslot.modified|utc 'utc' %} {% if item.session.agenda %}URL:{{item.session.agenda.get_href}} DESCRIPTION:{{item.timeslot.name|ics_esc}}\n{% if item.session.agenda_note %} Note: {{item.session.agenda_note|ics_esc}}\n{% endif %}{% for material in item.session.materials.all %} From 7b9f24032d63a9af7b5ac7d8e833c4e029f30858 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Fri, 21 Oct 2022 19:39:50 -0300 Subject: [PATCH 3/5] fix: render valid date-times in agenda.ics --- ietf/templates/meeting/agenda.ics | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ietf/templates/meeting/agenda.ics b/ietf/templates/meeting/agenda.ics index 778905147e5..b7a8d3031b3 100644 --- a/ietf/templates/meeting/agenda.ics +++ b/ietf/templates/meeting/agenda.ics @@ -8,9 +8,9 @@ SUMMARY:{% if item.session.name %}{{item.session.name|ics_esc}}{% else %}{% if n {% if item.timeslot.show_location %}LOCATION:{{item.timeslot.get_location}} {% endif %}STATUS:{{item.session.ical_status}} CLASS:PUBLIC -DTSTART;TZID={{schedule.meeting.time_zone|ics_esc}}:{{ item.timeslot.time|date:"Ymd" }}T{{item.timeslot.time|date:"Hi"}}00 -DTEND;TZID={{schedule.meeting.time_zone|ics_esc}}:{{ item.timeslot.end_time|date:"Ymd" }}T{{item.timeslot.end_time|date:"Hi"}}00 -DTSTAMP:{{ item.timeslot.modified|date:"Ymd" }}T{{ item.timeslot.modified|date:"His" }}Z{% if item.session.agenda %} +DTSTART{% ics_date_time item.timeslot.local_start_time schedule.meeting.time_zone %} +DTEND{% ics_date_time item.timeslot.local_end_time schedule.meeting.time_zone %} +DTSTAMP:{% ics_date_time item.timeslot.modified|utc 'utc' %}{% if item.session.agenda %} URL:{{item.session.agenda.get_versionless_href}}{% endif %} DESCRIPTION:{{item.timeslot.name|ics_esc}}\n{% if item.session.agenda_note %} Note: {{item.session.agenda_note|ics_esc}}\n{% endif %}{% if item.timeslot.location.webex_url %} From 88ab670b8d97ccea36425c4473b4f52ae3d8ac74 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Fri, 21 Oct 2022 19:42:57 -0300 Subject: [PATCH 4/5] 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. --- ietf/templates/meeting/important_dates_for_meeting.ics | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ietf/templates/meeting/important_dates_for_meeting.ics b/ietf/templates/meeting/important_dates_for_meeting.ics index bc505e687b9..181bfe15e0c 100644 --- a/ietf/templates/meeting/important_dates_for_meeting.ics +++ b/ietf/templates/meeting/important_dates_for_meeting.ics @@ -1,9 +1,9 @@ -{% load tz %}{% for d in meeting.important_dates %}BEGIN:VEVENT +{% load tz ietf_filters %}{% for d in meeting.important_dates %}BEGIN:VEVENT UID:ietf-{{ meeting.number }}-{{ d.name_id }}-{{ d.date.isoformat }} SUMMARY:IETF {{ meeting.number }}: {{ d.name.name }} CLASS:PUBLIC DTSTART{% if not d.midnight_cutoff %};VALUE=DATE{% endif %}:{{ d.date|date:"Ymd" }}{% if d.midnight_cutoff %}235900Z{% endif %} -DTSTAMP:{{ meeting.cached_updated|utc|date:"Ymd" }}T{{ meeting.cached_updated|utc|date:"His" }}Z +DTSTAMP{% ics_date_time meeting.cached_updated|utc 'utc' %} TRANSP:TRANSPARENT DESCRIPTION:{{ d.name.desc }}{% if first and d.name.slug == 'openreg' or first and d.name.slug == 'earlybird' %}\n Register here: https://www.ietf.org/how/meetings/register/{% endif %}{% if d.name.slug == 'opensched' %}\n From f59c3380526ccfd4c1ef24b8895f36f513470779 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Fri, 21 Oct 2022 19:53:38 -0300 Subject: [PATCH 5/5] test: test ics_date_time tag --- ietf/doc/templatetags/ietf_filters.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ietf/doc/templatetags/ietf_filters.py b/ietf/doc/templatetags/ietf_filters.py index 867612f9167..f472f8b0389 100644 --- a/ietf/doc/templatetags/ietf_filters.py +++ b/ietf/doc/templatetags/ietf_filters.py @@ -502,6 +502,7 @@ def ics_esc(text): text = re.sub(r"([\n,;\\])", r"\\\1", text) return text + @register.simple_tag def ics_date_time(dt, tzname): """Render a datetime as an iCalendar date-time @@ -514,6 +515,15 @@ def ics_date_time(dt, tzname): DTSTART{% ics_date_time timestamp 'America/Los_Angeles' %} to get DTSTART;TZID=America/Los_Angeles:20221021T111200 + + >>> ics_date_time(datetime.datetime(2022,1,2,3,4,5), 'utc') + ':20220102T030405Z' + + >>> ics_date_time(datetime.datetime(2022,1,2,3,4,5), 'UTC') + ':20220102T030405Z' + + >>> ics_date_time(datetime.datetime(2022,1,2,3,4,5), 'America/Los_Angeles') + ';TZID=America/Los_Angeles:20220102T030405' """ timestamp = dt.strftime('%Y%m%dT%H%M%S') if tzname.lower() == 'utc': @@ -521,6 +531,7 @@ def ics_date_time(dt, tzname): else: return f';TZID={ics_esc(tzname)}:{timestamp}' + @register.filter def consensus(doc): """Returns document consensus Yes/No/Unknown."""