diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 69635d6219..f20f6b029d 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -4432,6 +4432,73 @@ def upcoming_ical(request): response['Content-Disposition'] = 'attachment; filename="upcoming.ics"' return response +def render_important_dates_ical(meetings, request): + """Generate important dates using the icalendar library""" + cal = Calendar() + cal.add("prodid", "-//IETF//datatracker.ietf.org ical importantdates//EN") + cal.add("version", "2.0") + cal.add("method", "PUBLISH") + + for meeting in meetings: + for important_date in meeting.important_dates: + event = Event() + event.add("uid", f"ietf-{meeting.number}-{important_date.name_id}-" + f"{important_date.date.isoformat()}") + event.add("summary", f"IETF {meeting.number}: {important_date.name.name}") + event.add("class", "PUBLIC") + + if not important_date.midnight_cutoff: + event.add("dtstart", important_date.date) + else: + event.add("dtstart", datetime.datetime.combine( + important_date.date, + datetime.time(23, 59, 0, tzinfo=pytz.UTC)) + ) + + event.add("transp", "TRANSPARENT") + event.add("dtstamp", meeting.cached_updated) + description_lines = [important_date.name.desc] + if important_date.name.slug in ('openreg', 'earlybird'): + description_lines.append( + "Register here: https://www.ietf.org/how/meetings/register/") + if important_date.name.slug == 'opensched': + description_lines.append("To request a Working Group session, use the " + "IETF Meeting Session Request Tool:") + description_lines.append(f"{request.scheme}://{request.get_host()}" + f"{reverse('ietf.meeting.views_session_request.list_view')}") + description_lines.append("If you are working on a BOF request, it is " + "highly recommended to tell the IESG") + description_lines.append("now by sending an email to iesg@ietf.org " + "to get advance help with the request.") + if important_date.name.slug == 'cutoffwgreq': + description_lines.append("To request a Working Group session, use the " + "IETF Meeting Session Request Tool:") + description_lines.append(f"{request.scheme}://{request.get_host()}" + f"{reverse('ietf.meeting.views_session_request.list_view')}") + if important_date.name.slug == 'cutoffbofreq': + description_lines.append("To request a BOF, please see instructions on " + "Requesting a BOF:") + description_lines.append("https://www.ietf.org/how/bofs/bof-procedures/") + if important_date.name.slug == 'idcutoff': + description_lines.append("Upload using the I-D Submission Tool:") + description_lines.append(f"{request.scheme}://{request.get_host()}" + f"{reverse('ietf.submit.views.upload_submission')}") + if important_date.name.slug in ( + 'draftwgagenda', + 'revwgagenda', + 'procsub', + 'revslug' + ): + description_lines.append("Upload using the Meeting Materials " + "Management Tool:") + description_lines.append(f"{request.scheme}://{request.get_host()}" + f"{reverse('ietf.meeting.views.materials', + kwargs={'num': meeting.number})}") + + event.add("description", "\n".join(description_lines)) + cal.add_component(event) + + return cal.to_ical().decode("utf-8") def upcoming_json(request): '''Return Upcoming meetings in json format''' @@ -5050,11 +5117,8 @@ def important_dates(request, num=None, output_format=None): if output_format == 'ics': preprocess_meeting_important_dates(meetings) - ics = render_to_string('meeting/important_dates.ics', { - 'meetings': meetings, - }, request=request) - # icalendar response file should have '\r\n' line endings per RFC5545 - response = HttpResponse(parse_ical_line_endings(ics), content_type='text/calendar') + response = HttpResponse(render_important_dates_ical(meetings, request), + content_type='text/calendar') response['Content-Disposition'] = 'attachment; filename="important-dates.ics"' return response diff --git a/ietf/templates/meeting/important_dates.ics b/ietf/templates/meeting/important_dates.ics deleted file mode 100644 index 35079e01eb..0000000000 --- a/ietf/templates/meeting/important_dates.ics +++ /dev/null @@ -1,5 +0,0 @@ -{% load humanize %}{% autoescape off %}{% load ietf_filters %}BEGIN:VCALENDAR -VERSION:2.0 -METHOD:PUBLISH -PRODID:-//IETF//datatracker.ietf.org ical importantdates//EN -{% for meeting in meetings %}{% include "meeting/important_dates_for_meeting.ics" %}{% endfor %}END:VCALENDAR{% endautoescape %} diff --git a/ietf/templates/meeting/important_dates_for_meeting.ics b/ietf/templates/meeting/important_dates_for_meeting.ics deleted file mode 100644 index e6d403da93..0000000000 --- a/ietf/templates/meeting/important_dates_for_meeting.ics +++ /dev/null @@ -1,24 +0,0 @@ -{# Copyright The IETF Trust 2025, All Rights Reserved #} -{% 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{% 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 - To request a Working Group session, use the IETF Meeting Session Request Tool:\n - {{ request.scheme }}://{{ request.get_host}}{% url 'ietf.meeting.views_session_request.list_view' %}\n - If you are working on a BOF request, it is highly recommended to tell the IESG\n - now by sending an email to iesg@ietf.org to get advance help with the request.{% endif %}{% if d.name.slug == 'cutoffwgreq' %}\n - To request a Working Group session, use the IETF Meeting Session Request Tool:\n - {{ request.scheme }}://{{ request.get_host }}{% url 'ietf.meeting.views_session_request.list_view' %}{% endif %}{% if d.name.slug == 'cutoffbofreq' %}\n - To request a BOF, please see instructions on Requesting a BOF:\n - https://www.ietf.org/how/bofs/bof-procedures/{% endif %}{% if d.name.slug == 'idcutoff' %}\n - Upload using the I-D Submission Tool:\n - {{ request.scheme }}://{{ request.get_host }}{% url 'ietf.submit.views.upload_submission' %}{% endif %}{% if d.name.slug == 'draftwgagenda' or d.name.slug == 'revwgagenda' or d.name.slug == 'procsub' or d.name.slug == 'revslug' %}\n - Upload using the Meeting Materials Management Tool:\n - {{ request.scheme }}://{{ request.get_host }}{% url 'ietf.meeting.views.materials' num=meeting.number %}{% endif %} -END:VEVENT -{% endfor %}