Skip to content

Commit 8759339

Browse files
committed
Make the upcoming meetings iCal group the IETF meetings into one
block and add important dates. Also fix a couple of bugs found by running the generated .ics through the icalendar.org validator. - Legacy-Id: 18434
1 parent 0aa0f7d commit 8759339

6 files changed

Lines changed: 67 additions & 44 deletions

File tree

ietf/meeting/tests_views.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,7 +1931,6 @@ def test_upcoming(self):
19311931
make_meeting_test_data(create_interims=True)
19321932
url = urlreverse("ietf.meeting.views.upcoming")
19331933
today = datetime.date.today()
1934-
add_event_info_to_session_qs(Session.objects.filter(meeting__type='interim', group__acronym='mars')).filter(current_status='apprw').first()
19351934
mars_interim = add_event_info_to_session_qs(Session.objects.filter(meeting__type='interim', meeting__date__gt=today, group__acronym='mars')).filter(current_status='sched').first().meeting
19361935
ames_interim = add_event_info_to_session_qs(Session.objects.filter(meeting__type='interim', meeting__date__gt=today, group__acronym='ames')).filter(current_status='canceled').first().meeting
19371936
r = self.client.get(url)
@@ -1944,19 +1943,28 @@ def test_upcoming(self):
19441943
self.check_interim_tabs(url)
19451944

19461945
def test_upcoming_ical(self):
1947-
make_meeting_test_data(create_interims=True)
1946+
meeting = make_meeting_test_data(create_interims=True)
1947+
populate_important_dates(meeting)
1948+
19481949
url = urlreverse("ietf.meeting.views.upcoming_ical")
19491950
r = self.client.get(url)
19501951
self.assertEqual(r.status_code, 200)
1952+
1953+
today = datetime.date.today()
1954+
mars_interim = add_event_info_to_session_qs(Session.objects.filter(meeting__type='interim', meeting__date__gt=today, group__acronym='mars')).filter(current_status='sched').first().meeting
1955+
ames_interim = add_event_info_to_session_qs(Session.objects.filter(meeting__type='interim', meeting__date__gt=today, group__acronym='ames')).filter(current_status='canceled').first().meeting
1956+
self.assertContains(r, mars_interim.number)
1957+
self.assertContains(r, ames_interim.number)
1958+
self.assertContains(r, 'IETF 72')
19511959
self.assertEqual(r.get('Content-Type'), "text/calendar")
1952-
self.assertEqual(r.content.count(b'UID'), 7)
1960+
self.assertEqual(r.content.count(b'UID'), 3 + meeting.importantdate_set.count())
1961+
19531962
# check filtered output
19541963
url = url + '?filters=mars'
19551964
r = self.client.get(url)
19561965
self.assertEqual(r.status_code, 200)
19571966
self.assertEqual(r.get('Content-Type'), "text/calendar")
1958-
# print r.content
1959-
self.assertEqual(r.content.count(b'UID'), 2)
1967+
self.assertEqual(r.content.count(b'UID'), 2 + meeting.importantdate_set.count())
19601968

19611969

19621970
def test_upcoming_json(self):

ietf/meeting/utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,3 +560,11 @@ def swap_meeting_schedule_timeslot_assignments(schedule, source_timeslots, targe
560560
if not swapped:
561561
for a in lts_assignments:
562562
a.delete()
563+
564+
def preprocess_meeting_important_dates(meetings):
565+
for m in meetings:
566+
m.cached_updated = m.updated()
567+
m.important_dates = m.importantdate_set.prefetch_related("name")
568+
for d in m.important_dates:
569+
d.midnight_cutoff = "UTC 23:59" in d.name.name
570+

ietf/meeting/views.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
from ietf.meeting.utils import preprocess_constraints_for_meeting_schedule_editor
8282
from ietf.meeting.utils import diff_meeting_schedules, prefetch_schedule_diff_objects
8383
from ietf.meeting.utils import swap_meeting_schedule_timeslot_assignments
84+
from ietf.meeting.utils import preprocess_meeting_important_dates
8485
from ietf.message.utils import infer_message
8586
from ietf.secr.proceedings.utils import handle_upload_file
8687
from ietf.secr.proceedings.proc_utils import (get_progress_stats, post_process, import_audio_files,
@@ -3246,7 +3247,7 @@ def upcoming_ical(request):
32463247

32473248
assignments = list(SchedTimeSessAssignment.objects.filter(
32483249
schedule__in=[m.schedule_id for m in meetings] + [m.schedule.base_id for m in meetings if m.schedule],
3249-
session__in=[s.pk for m in meetings for s in m.sessions],
3250+
session__in=[s.pk for m in meetings for s in m.sessions if m.type_id != 'ietf'],
32503251
timeslot__time__gte=today,
32513252
).order_by(
32523253
'schedule__meeting__date', 'session__type', 'timeslot__time'
@@ -3270,17 +3271,16 @@ def upcoming_ical(request):
32703271
a.session = sessions.get(a.session_id) or a.session
32713272
a.session.ical_status = ical_session_status(a)
32723273

3273-
# gather vtimezones
3274-
vtimezones = set()
3275-
for meeting in meetings:
3276-
if meeting.vtimezone():
3277-
vtimezones.add(meeting.vtimezone())
3278-
vtimezones = ''.join(vtimezones)
3274+
# handle IETFs separately
3275+
ietfs = [m for m in meetings if m.type_id == 'ietf']
3276+
preprocess_meeting_important_dates(ietfs)
32793277

32803278
# icalendar response file should have '\r\n' line endings per RFC5545
32813279
response = render_to_string('meeting/upcoming.ics', {
3282-
'vtimezones': vtimezones,
3283-
'assignments': assignments})
3280+
'vtimezones': ''.join({meeting.vtimezone() for meeting in meetings if meeting.vtimezone()}),
3281+
'assignments': assignments,
3282+
'ietfs': ietfs,
3283+
}, request=request)
32843284
response = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", response)
32853285

32863286
response = HttpResponse(response, content_type='text/calendar')
@@ -3603,11 +3603,7 @@ def important_dates(request, num=None, output_format=None):
36033603
meetings.append(future_meeting)
36043604

36053605
if output_format == 'ics':
3606-
for m in meetings:
3607-
m.cached_updated = m.updated()
3608-
m.important_dates = m.importantdate_set.prefetch_related("name")
3609-
for d in m.important_dates:
3610-
d.midnight_cutoff = "UTC 23:59" in d.name.name
3606+
preprocess_meeting_important_dates(meetings)
36113607

36123608
ics = render_to_string('meeting/important_dates.ics', {
36133609
'meetings': meetings,

ietf/templates/meeting/important_dates.ics

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,4 @@
22
VERSION:2.0
33
METHOD:PUBLISH
44
PRODID:-//IETF//datatracker.ietf.org ical importantdates//EN
5-
{% for meeting in meetings %}{% for d in meeting.important_dates %}BEGIN:VEVENT
6-
UID:ietf-{{ meeting.number }}-{{ d.name_id }}-{{ d.date.isoformat }}
7-
SUMMARY:IETF {{ meeting.number }}: {{ d.name.name }}
8-
CLASS:PUBLIC
9-
DTSTART{% if not d.midnight_cutoff %};VALUE=DATE{% endif %}:{{ d.date|date:"Ymd" }}{% if d.midnight_cutoff %}235900Z{% endif %}
10-
DTSTAMP:{{ meeting.cached_updated|date:"Ymd" }}T{{ meeting.cached_updated|date:"His" }}Z
11-
DESCRIPTION:{{ d.name.desc }} {% if first and d.name.slug == 'openreg' or first and d.name.slug == 'earlybird' %}
12-
Register here: https://www.ietf.org/how/meetings/register/{% endif %}{% if d.name.slug == 'opensched' %}
13-
To request a Working Group session, use the IETF Meeting Session Request Tool:
14-
{{ request.scheme }}://{{ request.get_host}}{% url 'ietf.secr.sreq.views.main' %}
15-
If you are working on a BoF request, it is highly recommended to tell the IESG
16-
now by sending an email to iesg@ietf.org to get advance help with the request.{% endif %}{% if d.name.slug == 'cutoffwgreq' %}
17-
To request a Working Group session, use the IETF Meeting Session Request Tool:
18-
{{ request.scheme }}://{{ request.get_host }}{% url 'ietf.secr.sreq.views.main' %}{% endif %}{% if d.name.slug == 'cutoffbofreq' %}
19-
To request a BOF, please see instructions on Requesting a BOF:
20-
https://www.ietf.org/how/bofs/bof-procedures/{% endif %}{% if d.name.slug == 'idcutoff' %}
21-
Upload using the ID Submission Tool:
22-
{{ 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' %}
23-
Upload using the Meeting Materials Management Tool:
24-
{{ request.scheme }}://{{ request.get_host }}{% url 'ietf.meeting.views.materials' num=meeting.number %}{% endif %}
25-
END:VEVENT
26-
{% endfor %}{% endfor %}END:VCALENDAR{% endautoescape %}
5+
{% for meeting in meetings %}{% include "meeting/important_dates_for_meeting.ics" %}{% endfor %}END:VCALENDAR{% endautoescape %}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{% for d in meeting.important_dates %}BEGIN:VEVENT
2+
UID:ietf-{{ meeting.number }}-{{ d.name_id }}-{{ d.date.isoformat }}
3+
SUMMARY:IETF {{ meeting.number }}: {{ d.name.name }}
4+
CLASS:PUBLIC
5+
DTSTART{% if not d.midnight_cutoff %};VALUE=DATE{% endif %}:{{ d.date|date:"Ymd" }}{% if d.midnight_cutoff %}235900Z{% endif %}
6+
DTSTAMP:{{ meeting.cached_updated|date:"Ymd" }}T{{ meeting.cached_updated|date:"His" }}Z
7+
DESCRIPTION:{{ d.name.desc }} {% if first and d.name.slug == 'openreg' or first and d.name.slug == 'earlybird' %}
8+
Register here: https://www.ietf.org/how/meetings/register/{% endif %}{% if d.name.slug == 'opensched' %}
9+
To request a Working Group session, use the IETF Meeting Session Request Tool:
10+
{{ request.scheme }}://{{ request.get_host}}{% url 'ietf.secr.sreq.views.main' %}
11+
If you are working on a BoF request, it is highly recommended to tell the IESG
12+
now by sending an email to iesg@ietf.org to get advance help with the request.{% endif %}{% if d.name.slug == 'cutoffwgreq' %}
13+
To request a Working Group session, use the IETF Meeting Session Request Tool:
14+
{{ request.scheme }}://{{ request.get_host }}{% url 'ietf.secr.sreq.views.main' %}{% endif %}{% if d.name.slug == 'cutoffbofreq' %}
15+
To request a BOF, please see instructions on Requesting a BOF:
16+
https://www.ietf.org/how/bofs/bof-procedures/{% endif %}{% if d.name.slug == 'idcutoff' %}
17+
Upload using the ID Submission Tool:
18+
{{ 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' %}
19+
Upload using the Meeting Materials Management Tool:
20+
{{ request.scheme }}://{{ request.get_host }}{% url 'ietf.meeting.views.materials' num=meeting.number %}{% endif %}
21+
END:VEVENT
22+
{% endfor %}

ietf/templates/meeting/upcoming.ics

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ SUMMARY:{% if item.session.name %}{{item.session.name|ics_esc}}{% else %}{{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}}"{%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}}"{%endif%}:{{ item.timeslot.end_time|date:"Ymd" }}T{{item.timeslot.end_time|date:"Hi"}}00
11+
DTSTART{% if item.schedule.meeting.time_zone and item.schedule.meeting.time_zone != 'UTC' %};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 and item.schedule.meeting.time_zone != 'UTC' %};TZID={{ item.schedule.meeting.time_zone|ics_esc }}{%endif%}:{{ item.timeslot.end_time|date:"Ymd" }}T{{item.timeslot.end_time|date:"Hi"}}00
1313
DTSTAMP:{{ item.timeslot.modified|date:"Ymd" }}T{{ item.timeslot.modified|date:"His" }}Z
1414
{% if item.session.agenda %}URL:{{item.session.agenda.get_href}}
1515
DESCRIPTION:{{item.timeslot.name|ics_esc}}\n{% if item.session.agenda_note %}
@@ -18,4 +18,14 @@ DESCRIPTION:{{item.timeslot.name|ics_esc}}\n{% if item.session.agenda_note %}
1818
({{material.title|ics_esc}}){% endif %}:
1919
{{material.get_href}}\n{% endfor %}
2020
{% endif %}END:VEVENT
21-
{% endfor %}END:VCALENDAR{% endautoescape %}
21+
{% endfor %}{% for meeting in ietfs %}BEGIN:VEVENT
22+
UID:ietf-{{ meeting.number }}
23+
SUMMARY:IETF {{ meeting.number }}{% if meeting.city %}
24+
LOCATION:{{ meeting.city }},{{ meeting.country }}{% endif %}
25+
CLASS:PUBLIC
26+
DTSTART;VALUE=DATE{% if meeting.time_zone and meeting.time_zone != 'UTC' %};TZID={{ meeting.time_zone|ics_esc }}{% endif %}:{{ meeting.date|date:"Ymd" }}
27+
DTEND;VALUE=DATE{% if meeting.time_zone and meeting.time_zone != 'UTC' %};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
29+
URL:{{ request.scheme }}://{{ request.get_host }}{% url 'ietf.meeting.views.agenda' num=meeting.number %}
30+
END:VEVENT
31+
{% include "meeting/important_dates_for_meeting.ics" %}{% endfor %}END:VCALENDAR{% endautoescape %}

0 commit comments

Comments
 (0)