From 16ae35ae19860f729f7d97f8828858e782104394 Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Sun, 27 Oct 2013 12:16:37 +0000 Subject: [PATCH] Rewrote html and text agenda templates to take schedule as data. - Legacy-Id: 6495 --- ietf/meeting/models.py | 39 +++++++++- ietf/meeting/urls.py | 12 ++-- ietf/meeting/views.py | 16 ++--- ietf/templates/meeting/agenda.html | 112 ++++++++++++++++------------- ietf/templates/meeting/agenda.txt | 36 +++++----- 5 files changed, 130 insertions(+), 85 deletions(-) diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index 46d5bbc45..d4daf7b60 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -3,6 +3,8 @@ import pytz, datetime from urlparse import urljoin import copy +import os + import debug from django.db import models @@ -463,6 +465,11 @@ class Schedule(models.Model): def base_url(self): return "/meeting/%s/agenda/%s" % (self.meeting.number, self.name) + # temporary property to pacify the places where Schedule.scheduledsession_set is used + @property + def scheduledsession_set(self): + return self.assignments + # def url_edit(self): # return "/meeting/%s/agenda/%s/edit" % (self.meeting.number, self.name) # @@ -584,6 +591,15 @@ class Schedule(models.Model): self.badness = badness return badness + def area_list(self): + return ( self.assignments.filter(session__group__type__slug__in=['wg', 'rg', 'ag'], + session__group__parent__isnull=False) + .order_by('session__group__parent__acronym') + .values_list('session__group__parent__acronym', flat=True) + .distinct() ) + + def groups(self): + return Group.objects.filter(type__slug__in=['wg', 'rg', 'ag'], session__scheduledsession__schedule=self).distinct().order_by('parent__acronym', 'acronym') class ScheduledSession(models.Model): """ @@ -593,13 +609,16 @@ class ScheduledSession(models.Model): """ timeslot = models.ForeignKey('TimeSlot', null=False, blank=False, help_text=u"") session = models.ForeignKey('Session', null=True, default=None, help_text=u"Scheduled session") - schedule = models.ForeignKey('Schedule', null=False, blank=False, help_text=u"Who made this agenda") + schedule = models.ForeignKey('Schedule', null=False, blank=False, related_name='assignments') extendedfrom = models.ForeignKey('ScheduledSession', null=True, default=None, help_text=u"Timeslot this session is an extension of") modified = models.DateTimeField(default=datetime.datetime.now) notes = models.TextField(blank=True) badness = models.IntegerField(default=0, blank=True, null=True) pinned = models.BooleanField(default=False, help_text="Do not move session during automatic placement") + class Meta: + ordering = ["timeslot__time", "session__group__parent__name", "session__group__acronym", "session__name", ] + # use to distinguish this from FakeScheduledSession in placement.py faked = "real" @@ -724,7 +743,6 @@ class ScheduledSession(models.Model): ss["pinned"] = self.pinned return ss - class Constraint(models.Model): """ Specifies a constraint on the scheduling. @@ -1142,3 +1160,20 @@ class Session(models.Model): self.badness_log(1, "badgroup: %s badness = %u\n" % (self.group.acronym, badness)) return badness + def agenda_text(self): + doc = self.agenda() + if doc: + path = os.path.join(settings.AGENDA_PATH, self.meeting.number, "agenda", doc.external_url) + if os.path.exists(path): + with open(path) as f: + return f.read() + else: + "No agenda file found" + else: + return "The agenda has not been uploaded yet." + + def type(self): + if self.group.type.slug in [ "wg" ]: + return "BOF" if self.group.state.slug in ["bof", "bof-conc"] else "WG" + else: + return "" diff --git a/ietf/meeting/urls.py b/ietf/meeting/urls.py index d021f90dc..5433a68f7 100644 --- a/ietf/meeting/urls.py +++ b/ietf/meeting/urls.py @@ -7,13 +7,13 @@ from ietf.meeting import ajax urlpatterns = patterns('', (r'^(?P\d+)/materials.html$', views.materials), - (r'^agenda/$', views.agenda_html_request), + (r'^agenda/$', views.agenda), (r'^agenda-utc(?:.html)?$', views.html_agenda_utc), - (r'^agenda(?:.html)?$', views.agenda_html_request), + (r'^agenda(?:.html)?$', views.agenda), (r'^agenda/edit$', views.edit_agenda), (r'^requests.html$', redirect_to, {"url": '/meeting/requests', "permanent": True}), (r'^requests$', views.meeting_requests), - (r'^agenda.txt$', views.text_agenda), + (r'^agenda(?P.txt)$', views.agenda), (r'^agenda/agenda.ics$', views.ical_agenda), (r'^agenda.ics$', views.ical_agenda), (r'^agenda.csv$', views.csv_agenda), @@ -22,12 +22,12 @@ urlpatterns = patterns('', (r'^(?P\d+)/schedule/edit$', views.edit_agenda), (r'^(?P\d+)/schedule/(?P[A-Za-z0-9-:_]+)/edit$', views.edit_agenda), (r'^(?P\d+)/schedule/(?P[A-Za-z0-9-:_]+)/details$', views.edit_agenda_properties), - (r'^(?P\d+)/schedule/(?P[A-Za-z0-9-:_]+)(?:.html)?/?$', views.agenda_html_request), - (r'^(?P\d+)/agenda(?:.html)?/?$', views.agenda_html_request), + (r'^(?P\d+)/schedule/(?P[A-Za-z0-9-:_]+)(?P.html)?/?$', views.agenda), + (r'^(?P\d+)/agenda(?P.html)?/?$', views.agenda), (r'^(?P\d+)/agenda-utc(?:.html)?/?$', views.html_agenda_utc), (r'^(?P\d+)/requests.html$', redirect_to, {"url": '/meeting/%(num)s/requests', "permanent": True}), (r'^(?P\d+)/requests$', views.meeting_requests), - (r'^(?P\d+)/agenda.txt$', views.text_agenda), + (r'^(?P\d+)/agenda(?P.txt)$', views.agenda), (r'^(?P\d+)/agenda.ics$', views.ical_agenda), (r'^(?P\d+)/agenda.csv$', views.csv_agenda), (r'^(?P\d+)/agendas/edit$', views.edit_agendas), diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index f5cd8248f..2b6bdad4d 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -432,15 +432,13 @@ def iphone_agenda(request, num, name): "wg_list" : wgs, "rg_list" : rgs, "area_list" : areas}, context_instance=RequestContext(request)) - -def text_agenda(request, num=None, name=None): - timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num) - plenaryw_agenda = " "+plenaryw_agenda.strip().replace("\n", "\n ") - plenaryt_agenda = " "+plenaryt_agenda.strip().replace("\n", "\n ") - return HttpResponse(render_to_string("meeting/agenda.txt", - {"timeslots":timeslots, "update":update, "meeting":meeting, "venue":venue, "ads":ads, - "plenaryw_agenda":plenaryw_agenda, "plenaryt_agenda":plenaryt_agenda, }, - RequestContext(request)), mimetype="text/plain") +def agenda(request, num=None, name=None, ext=".html"): + mimetype = {".html":"text/html", ".txt": "text/plain", ".ics":"text/calendar", ".csv":"text/csv"} + meeting = get_meeting(num) + schedule = get_schedule(meeting, name) + updated = Switches().from_object(meeting).updated() + return HttpResponse(render_to_string("meeting/agenda"+ext, + {"schedule":schedule, "updated": updated}, RequestContext(request)), mimetype=mimetype[ext]) def read_agenda_file(num, doc): # XXXX FIXME: the path fragment in the code below should be moved to diff --git a/ietf/templates/meeting/agenda.html b/ietf/templates/meeting/agenda.html index b4ccb8151..0c388602f 100644 --- a/ietf/templates/meeting/agenda.html +++ b/ietf/templates/meeting/agenda.html @@ -2,7 +2,7 @@ {% load ietf_filters %} {# Copyright The IETF Trust 2007, All Rights Reserved #} {% load humanize %} -{% block title %}IETF {{ meeting.number }} Meeting Agenda{% endblock %} +{% block title %}IETF {{ schedule.meeting.number }} Meeting Agenda{% endblock %} {% block morecss %} table#agenda { border: 0; border-collapse:collapse; } @@ -81,17 +81,17 @@ img.hidden { display: none; } {% endblock pagehead %} {% block bodyAttrs %}onload='setGroupState();updateAgendaColors()'{% endblock %} {% block content %} -

IETF {{ meeting.number }} Meeting Agenda

+

IETF {{ schedule.meeting.number }} Meeting Agenda

-

{{ meeting.city }}, {{ meeting.date|date:"F j" }} – {% ifnotequal meeting.date.month meeting.end_date.month %}{{ meeting.end_date|date:"F " }}{% endifnotequal %}{{ meeting.end_date|date:"j, Y" }}
-Updated {{ modified|date:"Y-m-d H:i:s T" }}

+

{{ schedule.meeting.city }}, {{ schedule.meeting.date|date:"F j" }} – {% ifnotequal schedule.meeting.date.month schedule.meeting.end_date.month %}{{ schedule.meeting.end_date|date:"F " }}{% endifnotequal %}{{ schedule.meeting.end_date|date:"j, Y" }}
+Updated {{ updated|date:"Y-m-d H:i:s T" }}

-(There's also a agenda with UTC times, a plaintext agenda and a tools-style agenda available)
+(There's also a agenda with UTC times, a plaintext agenda and a tools-style agenda available)

IETF agendas are subject to change, up to and during the meeting.

-{# cache this part for 15 minutes -- it takes 3-6 seconds to generate #} -{% load cache %}{% cache 900 ietf_meeting_agenda meeting.number %} +{# cache this part for 5 minutes -- it takes 3-6 seconds to generate #} +{% load cache %}{% cache 300 ietf_meeting_agenda schedule.meeting.number %} You can customize the agenda below to show only selected working group sessions. To be able to return to the customized view later, bookmark the resulting URL.
@@ -102,18 +102,18 @@ You can customize the agenda below to show only selected working group sessions. - {% for area in area_list %} + {% for area in schedule.area_list %} {% endfor %} - {% for wg in wg_list %}{% ifchanged wg.parent.acronym %}{% if forloop.counter > 1 %} + {% for wg in schedule.groups %}{% ifchanged wg.parent.acronym %}{% if forloop.counter > 1 %} {% endif %} - - +
Preconfigured .ics links: - {% for area in area_list %} - {{area|upper}} • + {% for area in schedule.area_list %} + {{area|upper}} • {% endfor %} - Non-Area Events + Non-Area Events
-{% if meeting.agenda_note %}

{{ meeting.agenda_note|safe }}

{% endif %} +{% if schedule.meeting.agenda_note %}

{{ schedule.meeting.agenda_note|safe }}

{% endif %} -{% for slot in timeslots %} +{% for item in schedule.assignments.all %} {% ifchanged %} {% endifchanged %} - {% ifchanged %} + {% if item.timeslot.type.slug == 'session' %} + {% ifchanged %} - {% endifchanged %} - {% if slot.type.name = 'Session' %} {% if slot.session.group %} - + {% endifchanged %} + {% endif %} + {% if item.timeslot.type.slug == 'break' or item.timeslot.type.slug == 'reg' or item.timeslot.type.slug == 'other' or item.timeslot.type.slug == 'plenary' %} + {% ifchanged %} + + + + + {% endifchanged %} + {% endif %} + {% if item.timeslot.type.slug = 'session' %} {% if item.session.group %} + - + + + {% if item.session.group.charter %}{{item.session.group.acronym}} + {% else %}{{item.session.group.acronym}}{% endif %} - + + {% if item.session.agenda %}{{item.session.group.name}} + {% else %}{{item.session.group.name}}{% endif %} + {% if item.session.group.state.name = "BOF" %} BOF {% endif %} + {% if item.session.agenda_note %} +
{{item.session.agenda_note}}{% endif %} + - + {% endif %} {% endif %} - {% if slot.type.name = 'Plenary' %} + {% if item.timeslot.type.slug = 'plenary' %}
-

{{ slot.time|date:"l"|upper }}, {{ slot.time|date:"F j, Y" }}

+

{{ item.timeslot.time|date:"l"|upper }}, {{ item.timeslot.time|date:"F j, Y" }}

- {{slot.time|date:"Hi"}}-{{slot.end_time|date:"Hi"}} {{slot.tzname}} + {{item.timeslot.time|date:"Hi"}}-{{item.timeslot.end_time|date:"Hi"}} {{item.timeslot.tzname}} - {% if slot.type.name == 'Session' %}{{ slot.time|date:"l"}}{% endif %} - {{slot.name}} - {% if slot.type.name != 'Session' %} - - {% if slot.show_location %}{{slot.get_location|escape}}{% endif %} - {% endif %} + {{ item.timeslot.time|date:"l"}} {{item.timeslot.name}}
+ {{item.timeslot.time|date:"Hi"}}-{{item.timeslot.end_time|date:"Hi"}} {{item.timeslot.tzname}} + + {{item.timeslot.name}} + - + {% if item.timeslot.show_location %}{{item.timeslot.get_location|escape}}{% endif %} +
- {% if slot.show_location %}{{slot.get_location|escape}}{% endif %}{{slot.session.group.parent.acronym|upper}}{% if item.timeslot.show_location %}{{item.timeslot.get_location|escape}}{% endif %}{{item.session.group.parent.acronym|upper}} - {% if slot.session.group.charter %}{{slot.session.group.acronym}} - {% else %}{{slot.session.group.acronym}}{% endif %} - - {% if slot.session.agenda %}{{slot.session.group.name}} - {% else %}{{slot.session.group.name}}{% endif %} - {% if slot.session.group.state.name = "BOF" %} BOF {% endif %} - {% if slot.session.agenda_note %} -
{{slot.session.agenda_note}}{% endif %}
{% if slot.session.agenda %}drafts: tar|pdf{%endif%}{% if item.session.agenda %}drafts: tar|pdf{%endif%}
- {% if slot.session.agenda %} - {% if slot.session.agenda.file_extension in show_inline%} - + {% if item.session.agenda %} + {% if item.session.agenda.file_extension == "txt" or item.session.agenda.file_extension == "html" or item.session.agenda.file_extension == "htm" %} + {% else %} - Agenda submitted in {{slot.session.agenda.file_extension|upper}} format + Agenda submitted in {{item.session.agenda.file_extension|upper}} format {% endif %} {% else %} No Agenda Submitted {% endif %} - {% if slot.session.slides %} + {% if item.session.slides %}

Slides:

-
    {% for slide in slot.session.slides %} +
      {% for slide in item.session.slides %}
    1. {{ slide.title|clean_whitespace }} @@ -205,14 +217,14 @@ You can customize the agenda below to show only selected working group sessions.
- - {% if slot.session.slides %} + + {% if item.session.slides %}

Slides:

-
    {% for slide in slot.session.slides %} +
      {% for slide in item.session.slides %}
    1. {{ slide.title|clean_whitespace }} diff --git a/ietf/templates/meeting/agenda.txt b/ietf/templates/meeting/agenda.txt index acae1c998..bcc4e9838 100644 --- a/ietf/templates/meeting/agenda.txt +++ b/ietf/templates/meeting/agenda.txt @@ -1,27 +1,27 @@ -{% load humanize %}{% autoescape off %} -{% load ietf_filters %} -{% filter center:72 %}Agenda of the {{ meeting.num|ordinal }} IETF Meeting{% endfilter %} -{% if meeting.agenda_note %} -{% filter center:72 %}{{ meeting.agenda_note|striptags|wrap_text:72|safe }}{% endfilter %} +{% load humanize %}{% load ietf_filters %}{% autoescape off %} + +{% filter center:72 %} Agenda of the {{ schedule.meeting.number|ordinal }} IETF Meeting {% endfilter %} +{% if schedule.meeting.agenda_note %} +{% filter center:72 %}{{ schedule.meeting.agenda_note|striptags|wrap_text:72|safe }}{% endfilter %} {% endif %} -{% filter center:72 %}{{ meeting.start_date|date:"F j" }}-{% ifnotequal meeting.start_date.month meeting.end_date.month %}{{ meeting.end_date|date:"F " }}{% endifnotequal %}{{ meeting.end_date|date:"j, Y" }}{% endfilter %} -{% filter center:72 %}Updated {{ update.updated|date:"Y-m-d H:i:s T" }}{% endfilter %} +{% filter center:72 %}{{ schedule.meeting.date|date:"F j" }}-{% ifnotequal schedule.meeting.date.month schedule.meeting.end_date.month %}{{ schedule.meeting.end_date|date:"F " }}{% endifnotequal %}{{ schedule.meeting.end_date|date:"j, Y" }}{% endfilter %} +{% filter center:72 %}Updated {{ updated|date:"Y-m-d H:i:s T" }}{% endfilter %} {% filter center:72 %}IETF agendas are subject to change, up to and during the meeting.{% endfilter %} +{% for item in schedule.assignments.all.distinct %}{% ifchanged %} -{% for slot in timeslots %}{% ifchanged %} -{{ slot.meeting_date|date:"l"|upper }}, {{ slot.meeting_date|date:"F j, Y" }}{% if slot.reg_info %} -{{ slot.registration.time_desc }} {{ slot.registration.name }}{% if venue.reg_area_name %} - {{ venue.reg_area_name }}{% endif %}{% endif %} -{% endifchanged %}{% if slot.session_name %}{% if slot.break_info %}{{ slot.break_info.time_desc }} {{ slot.break_info.name }}{% if venue.break_area_name and slot.break_info.show_break_location %} - {{ venue.break_area_name }}{% endif %} -{% endif %}{{ slot.time_desc }} {{ slot.session_name }}{% if slot.is_plenary %} - {{ slot.sessions.0.room_id.room_name }}{% endif %}{% ifequal slot.sessions.0.acronym "plenaryw" %} +{{ item.timeslot.time|date:"l"|upper }}, {{ item.timeslot.time|date:"F j, Y" }}{% endifchanged %}{% if item.timeslot.type.slug == "reg" %} +{{ item.timeslot.time_desc }} {{ item.timeslot.name }}{% if schedule.meeting.reg_area %} - {{ schedule.meeting.reg_area }}{% endif %}{% endif %}{% if item.timeslot.type.slug == "plenary" %} +{{ item.timeslot.time_desc }} {{ item.session.name }} - {{ item.timeslot.location.name }} -{{ plenaryw_agenda }}{% endifequal %}{% ifequal slot.sessions.0.acronym "plenaryt" %} + {{ item.session.agenda_text.strip|indent:"3" }} +{% endif %}{% if item.timeslot.type.slug == "session" %}{% if item.session.group %}{% ifchanged %} +{{ item.timeslot.time_desc }} {{ item.timeslot.name }} +{% endifchanged %}{{ item.timeslot.location.name|ljust:14 }} {{ item.session.group.parent.acronym|upper|ljust:4 }} {{ item.session.group.acronym|ljust:10 }} {{ item.session.group.name }} {{ item.session.type }}{% if item.session.agenda_note %} - {{ item.session.agenda_note }}{% endif %} +{% endif %}{% endif %}{% if item.timeslot.type.slug == "break" %} +{{ item.timeslot.time_desc }} {{ item.timeslot.name }}{% if schedule.meeting.break_area and item.timeslot.show_location %} - {{ schedule.meeting.break_area }}{% endif %}{% endif %}{% if item.timeslot.type.slug == "other" %} +{{ item.timeslot.time_desc }} {{ item.timeslot.name }} - {{ item.timeslot.location.name }}{% endif %}{% endfor %} -{{ plenaryt_agenda }}{% endifequal %}{% if not slot.is_plenary %}{% for session in slot.sessions_by_area|dictsort:"area" %} -{{ session.info.room_id.room_name|ljust:14 }} {% if session.info.area %}{{ session.info.area|upper|ljust:4 }} {{ session.info.acronym|ljust:10 }} {% endif %}{{ session.info.acronym_name }} {{ session.info.group_type_str }}{% if session.info.special_agenda_note %} - {{ session.info.special_agenda_note }}{% endif %}{% endfor %}{% endif %} - -{% else %}{% for session in slot.sessions %}{{ slot.time_desc }} {{ session.acronym_name }} - {{ session.room_id.room_name }} -{% endfor %}{% endif %}{% endfor %} ==================================================================== {% endautoescape %}