@@ -4430,16 +4430,7 @@ def upcoming_ical(request):
44304430 else :
44314431 ietfs = []
44324432
4433- meeting_vtz = {meeting .vtimezone () for meeting in meetings }
4434- meeting_vtz .discard (None )
4435-
4436- # icalendar response file should have '\r\n' line endings per RFC5545
4437- response = render_to_string ('meeting/upcoming.ics' , {
4438- 'vtimezones' : '' .join (sorted (meeting_vtz )),
4439- 'assignments' : assignments ,
4440- 'ietfs' : ietfs ,
4441- }, request = request )
4442- response = parse_ical_line_endings (response )
4433+ response = render_upcoming_ical (assignments , ietfs , request )
44434434
44444435 response = HttpResponse (response , content_type = 'text/calendar' )
44454436 response ['Content-Disposition' ] = 'attachment; filename="upcoming.ics"'
@@ -4513,6 +4504,64 @@ def render_important_dates_ical(meetings, request):
45134504
45144505 return cal .to_ical ().decode ("utf-8" )
45154506
4507+ def render_upcoming_ical (assignments , meetings , request ):
4508+ """Generate upcoming using the icalendar library"""
4509+
4510+ cal = Calendar ()
4511+ cal .add ("prodid" , "-//IETF//datatracker.ietf.org ical upcoming//EN" )
4512+ cal .add ("version" , "2.0" )
4513+ cal .add ("method" , "PUBLISH" )
4514+
4515+ for item in assignments :
4516+ event = Event ()
4517+
4518+ event .add ("uid" , f"ietf-{ item .session .meeting .number } -{ item .timeslot .pk } " )
4519+ event .add ("summary" , f"{ item .session .group .acronym .lower ()} - { item .session .name if item .session .name else item .session .group .name } " )
4520+
4521+ if item .schedule .meeting .city :
4522+ event .add ("location" , f"{ item .schedule .meeting .city } ,{ item .schedule .meeting .country } " )
4523+
4524+ event .add ("status" , item .session .ical_status )
4525+ event .add ("class" , "PUBLIC" )
4526+
4527+ event .add ("dtstart" , item .timeslot .utc_start_time ())
4528+ event .add ("dtend" , item .timeslot .utc_end_time ())
4529+ event .add ("dtstamp" , item .timeslot .modified )
4530+ if item .session .agenda ():
4531+ event .add ("url" , item .session .agenda ().get_href ())
4532+
4533+ description_lines = []
4534+ if item .timeslot .name :
4535+ description_lines .append (f"{ item .timeslot .name } " )
4536+ if item .session .agenda_note :
4537+ description_lines .append (f"Note: { item .session .agenda_note } " )
4538+
4539+ for material in item .session .materials .all ():
4540+ title_part = f" ({ material .title } )" if material .type .name != "Agenda" else ""
4541+ description_lines .append (f"{ material .type } { title_part } : { material .get_href ()} " )
4542+
4543+ if item .session .remote_instructions :
4544+ description_lines .append (f"Remote instructions: { item .session .remote_instructions } " )
4545+
4546+ event .add ("description" , "\n " .join (description_lines ))
4547+ cal .add_component (event )
4548+
4549+ for meeting in meetings :
4550+ event = Event ()
4551+ event .add ("uid" , f"ietf-{ meeting .number } " )
4552+ event .add ("summary" , f"IETF { meeting .number } " )
4553+ if meeting .city :
4554+ event .add ("location" , f"{ meeting .city } ,{ meeting .country } " )
4555+ event .add ("class" , "PUBLIC" )
4556+ event .add ("dtstart" , meeting .date )
4557+ event .add ("dtend" , meeting .end_date () + datetime .timedelta (days = 1 ))
4558+ event .add ("dtstamp" , meeting .cached_updated )
4559+ event .add ("url" , f"{ request .scheme } ://{ request .get_host ()} { reverse ('agenda' , kwargs = {'num' : meeting .number })} " )
4560+
4561+ cal .add_component (event )
4562+
4563+ return cal .to_ical ().decode ("utf-8" )
4564+
45164565def upcoming_json (request ):
45174566 '''Return Upcoming meetings in json format'''
45184567 today = date_today ()
0 commit comments