clean merge forward

- Legacy-Id: 9584
This commit is contained in:
Robert Sparks 2015-04-27 20:24:40 +00:00
commit b0ce25aa44
18 changed files with 312 additions and 34 deletions

View file

@ -67,6 +67,9 @@ def build_all_agenda_slices(meeting):
date_slices = {} date_slices = {}
for ts in meeting.timeslot_set.exclude(type__in=['reg','break']).order_by('time','name'): for ts in meeting.timeslot_set.exclude(type__in=['reg','break']).order_by('time','name'):
#for ts in meeting.timeslot_set.exclude(type__in=['reg','break','other']).order_by('time','name'):
#for ts in meeting.timeslot_set.order_by('time','name'):
#for ts in meeting.timeslot_set.filter(type='offagenda').order_by('time','name'):
ymd = ts.time.date() ymd = ts.time.date()
if ymd not in date_slices and ts.location != None: if ymd not in date_slices and ts.location != None:

View file

@ -0,0 +1,141 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import datetime
from django.db import migrations
def backfill_91_other_meetings(apps, schema_editor):
Meeting = apps.get_model('meeting', 'Meeting')
Schedule = apps.get_model('meeting', 'Schedule')
ScheduledSession = apps.get_model('meeting', 'ScheduledSession')
Room = apps.get_model('meeting', 'Room')
Group = apps.get_model('group', 'Group')
Person = apps.get_model('person', 'Person')
ietf91 = Meeting.objects.filter(number=91).first()
if not ietf91:
print "IETF91 not found, no data changed"
else:
agenda91 = Schedule.objects.get(meeting=ietf91,pk=ietf91.agenda.pk)
south_pacific_1 = Room.objects.get(meeting=ietf91,name="South Pacific 1")
south_pacific_2 = Room.objects.get(meeting=ietf91,name="South Pacific 2")
rainbow_12 = Room.objects.get(meeting=ietf91,name="Rainbow Suite 1/2")
lehua_suite = Room.objects.get(meeting=ietf91,name="Lehua Suite")
kahili = Room.objects.get(meeting=ietf91,name="Kahili")
coral_2 = Room.objects.get(meeting=ietf91,name="Coral 2")
south_pacific_3 = Room.objects.create(meeting=ietf91,name="South Pacific 3",capacity=20)
rainbow_suite_3 = Room.objects.create(meeting=ietf91,name="Rainbow Suite 3",capacity=20)
rainbow_23 = Room.objects.create(meeting=ietf91,name="Rainbow Suite 2/3",capacity=210)
south_pacific_34 = Room.objects.create(meeting=ietf91,name="South Pacific 3/4",capacity=210)
iolani_67 = Room.objects.create(meeting=ietf91,name="Iolani 6/7",capacity=40)
sea_pearl_12 = Room.objects.create(meeting=ietf91,name="Sea Pearl 1/2",capacity=40)
sea_pearl_2 = Room.objects.create(meeting=ietf91,name="Sea Pearl 2",capacity=20)
coral_lounge = Room.objects.create(meeting=ietf91,name="Coral Lounge", capacity=1200)
hibiscus = Room.objects.create(meeting=ietf91,name="Hibiscus", capacity=20)
tiare = Room.objects.create(meeting=ietf91,name="Tiare Suite", capacity=20)
iesg = Group.objects.get(acronym='iesg')
iab = Group.objects.get(acronym='iab')
rsoc = Group.objects.get(acronym='rsoc')
iaoc = Group.objects.get(acronym='iaoc')
nomcom = Group.objects.get(acronym='nomcom2014')
isoc = Group.objects.get(acronym='isoc')
secr = Group.objects.get(acronym='secretariat')
isocbot = Group.objects.create(acronym='isocbot',name="Internet Society Board of Trustees",state_id='active',type_id='isoc',parent=isoc)
isocfell = Group.objects.create(acronym='isocfell',name="Internet Society Fellows",state_id='active',type_id='isoc',parent=isoc)
system = Person.objects.get(name='(System)')
for d, h, m, duration, type_id, groups, room, slotname, label in [
( 9, 8, 0, 120, 'offagenda', [secr], rainbow_suite_3, 'WEIRDS Interop', 'WEIRDS Interop'),
( 9, 8, 30, 90, 'lead', [iesg], south_pacific_2, 'Breakfast', None),
( 9, 9, 0, 240, 'offagenda', [secr], lehua_suite, 'RMCAT Interim', 'RMCAT Interim Meeting'),
( 9, 9, 0, 60, 'lead', [nomcom], iolani_67, 'Breakfast', 'Nomcom Breakfast'),
( 9, 9, 0, 150, 'lead', [iesg], south_pacific_2, 'Meeting', None),
( 9, 9, 0, 360, 'offagenda', [secr], hibiscus, 'Meeting', 'RootOPS'),
( 9, 9, 30, 360, 'offagenda', [secr], kahili, 'TLS Interim', 'TLS WG Interim'),
( 9, 11, 0, 480, 'offagenda', [secr], coral_lounge, 'T-Shirt Distribution', 'T-shirt Distribution'),
( 9, 11, 30, 150, 'lead', [iesg,iab], south_pacific_2, 'Lunch', 'IAB/IESG Lunch'),
( 9, 12, 0, 360, 'offagenda', [secr], south_pacific_1, 'Terminal Room', 'Terminal Room Open to Attendees'),
( 9, 14, 0, 180, 'lead', [iab], south_pacific_2, 'Meeting', None),
( 9, 16, 0, 120, 'offagenda', [secr], coral_2, 'Meeting', 'Web Object Encryption'),
( 9, 17, 0, 120, 'offagenda', [secr], sea_pearl_12, 'Reception', "Companion's Reception"), # Should this appear on agenda?
( 9, 19, 0, 180, 'offagenda', [isocfell], rainbow_23, 'Dinner', 'ISOC Fellows Reception/Dinner'),
( 9, 19, 0, 180, 'offagenda', [secr], lehua_suite, 'Meeting', 'Huawei'),
( 9, 21, 0, 180, 'lead', [secr], sea_pearl_12, 'Gathering', 'AMS/IESG/IABIAOC Gathering'),
( 10, 0, 0, 1440, 'offagenda', [secr], south_pacific_1, 'Terminal Room', 'Terminal Room Open to Attendees'),
( 10, 7, 0, 120, 'lead', [iesg,iab], south_pacific_2, 'Breakfast', 'IESG/IAB Breakfast'),
( 10, 7, 0, 120, 'lead', [nomcom], iolani_67, 'Breakfast', 'Nomcom Breakfast'),
( 10, 8, 0, 600, 'offagenda', [secr], coral_lounge, 'T-shirt Distribution', 'T-shirt Distribution'),
( 10, 11, 30, 90, 'offagenda', [secr], south_pacific_2, 'Meeting', 'OPS Directorate Meeting'),
( 10, 11, 30, 90, 'offagenda', [secr], rainbow_suite_3, 'Meeting', 'IETF/3GPP Meeting'),
( 10, 11, 30, 90, 'offagenda', [secr], lehua_suite, 'Meeting', 'RTG Area Meeting'),
( 10, 19, 0, 240, 'offagenda', [secr], south_pacific_2, 'Meeting', 'Huawei'),
( 11, 0, 0, 1440, 'offagenda', [secr], south_pacific_1, 'Terminal Room', 'Terminal Room Open to Attendees'),
( 11, 7, 0, 120, 'lead', [iesg], south_pacific_2, 'Breakfast', None),
( 11, 7, 0, 120, 'lead', [nomcom], iolani_67, 'Breakfast', 'Nomcom Breakfast'),
( 11, 7, 0, 120, 'lead', [iab], rainbow_suite_3, 'Breakfast', None),
( 11, 7, 0, 60, 'lead', [iab], tiare, 'Meeting', 'Vendor Selection Committee Meeting'),
( 11, 8, 0, 600, 'offagenda', [secr], coral_lounge, 'T-shirt Distribution', 'T-shirt Distribution'),
( 11, 9, 0, 90, 'offagenda', [secr], south_pacific_2, 'Meeting', 'DHCPv6bis Team Meeting'),
( 11, 11, 30, 90, 'offagenda', [secr], south_pacific_2, 'Meeting', 'SECdir Meeting'),
( 11, 11, 30, 90, 'offagenda', [secr], rainbow_suite_3, 'Lunch', 'RSAG/ISEB Lunch'),
( 11, 16, 0, 240, 'offagenda', [secr], south_pacific_2, 'Meeting', 'Verisign Corporate Meeting'),
( 12, 0, 0, 1440, 'offagenda', [secr], south_pacific_1, 'Terminal Room', 'Terminal Room Open to Attendees'),
( 12, 7, 30, 90, 'lead', [iaoc], south_pacific_3, 'Breakfast', None),
( 12, 7, 0, 120, 'lead', [nomcom], iolani_67, 'Breakfast', 'Nomcom Breakfast'),
( 12, 8, 0, 540, 'offagenda', [secr], coral_lounge, 'T-shirt Distribution', 'T-shirt Distribution'),
( 12, 8, 0, 240, 'offagenda', [secr], south_pacific_2, 'Meeting', 'DIME WG'),
( 12, 11, 30, 90, 'offagenda', [secr], rainbow_suite_3, 'Lunch', 'RFC Editor Lunch'),
( 12, 15, 0, 120, 'offagenda', [secr], south_pacific_2, 'Meeting', 'YANG Advice'),
( 12, 17, 0, 240, 'offagenda', [secr], rainbow_suite_3, 'Meeting', 'Huawei (POC Wil Liu)'),
( 12, 20, 0, 150, 'offagenda', [secr], south_pacific_2, 'Meeting', 'ICANN SSAC'),
( 13, 0, 0, 1440, 'offagenda', [secr], south_pacific_1, 'Terminal Room', 'Terminal Room Open to Attendees'),
( 13, 7, 0, 120, 'lead', [iab], rainbow_suite_3, 'Breakfast', None),
( 13, 7, 0, 120, 'lead', [nomcom], iolani_67, 'Breakfast', 'Nomcom Breakfast'),
( 13, 11, 30, 90, 'lead', [iab], sea_pearl_2, 'Meeting', 'IAB Liaison Oversight'),
( 13, 11, 30, 90, 'lead', [rsoc], rainbow_suite_3, 'Lunch', None),
( 14, 0, 0, 900, 'offagenda', [secr], south_pacific_1, 'Terminal Room', 'Terminal Room Open to Attendees'),
( 14, 7, 0, 120, 'lead', [nomcom], iolani_67, 'Breakfast', 'Nomcom Breakfast'),
( 14, 11, 0, 360, 'offagenda', [isoc], south_pacific_34,'Meeeting', 'ISOC AC Meeting'),
( 14, 13, 30, 90, 'lead', [iesg,iab], south_pacific_2, 'Lunch', 'IESG/IAB Lunch'),
( 14, 18, 0, 60, 'offagenda', [isocbot], rainbow_23, 'Reception', 'ISOC Board Reception for IETF Leadership'),
( 14, 19, 0, 180, 'offagenda', [isocbot], rainbow_23, 'Dinner', 'ISOC Board Dinner for IETF Leadership'),
( 15, 8, 0, 60, 'offagenda', [isocbot], rainbow_12, 'Breakfast', 'ISOC Board of Trustees Breakfast'),
( 15, 8, 0, 540, 'offagenda', [isocbot], south_pacific_34,'Meeting', 'ISOC Board of Trustees Meeting'),
( 15, 12, 0, 60, 'offagenda', [isocbot], rainbow_12, 'Lunch', 'ISOC Board of Trustees Lunch'),
( 16, 8, 0, 60, 'offagenda', [isocbot], rainbow_12, 'Breakfast', 'ISOC Board of Trustees Breakfast'),
( 16, 8, 0, 540, 'offagenda', [isocbot], south_pacific_34,'Meeting', 'ISOC Board of Trustees Meeting'),
( 16, 12, 0, 60, 'offagenda', [isocbot], rainbow_12, 'Lunch', 'ISOC Board of Trustees Lunch'),
]:
ts = ietf91.timeslot_set.create(type_id=type_id, name=slotname,
time=datetime.datetime(2014,11,d,h,m,0),
duration=datetime.timedelta(minutes=duration),
location=room,show_location=(type_id not in ['lead','offagenda']))
for group in groups:
session = ietf91.session_set.create(name= label or "%s %s"%(group.acronym.upper(),slotname),
group=group, attendees=25,
requested=datetime.datetime(2014,11,1,0,0,0),
requested_by=system, status_id='sched')
ScheduledSession.objects.create(schedule=agenda91, timeslot=ts, session=session)
class Migration(migrations.Migration):
dependencies = [
('meeting', '0004_auto_20150308_0446'),
('name', '0004_auto_20150318_1140'),
('group', '0003_auto_20150304_0743'),
('person', '0004_auto_20150308_0440'),
]
operations = [
migrations.RunPython(backfill_91_other_meetings)
]

View file

@ -370,7 +370,7 @@ class TimeSlot(models.Model):
return u"%s: %s-%s %s, %s" % (self.meeting.number, self.time.strftime("%m-%d %H:%M"), (self.time + self.duration).strftime("%H:%M"), self.name, location) return u"%s: %s-%s %s, %s" % (self.meeting.number, self.time.strftime("%m-%d %H:%M"), (self.time + self.duration).strftime("%H:%M"), self.name, location)
def end_time(self): def end_time(self):
return self.time + self.duration return self.time + self.duration
def get_location(self): def get_hidden_location(self):
location = self.location location = self.location
if location: if location:
location = location.name location = location.name
@ -378,6 +378,10 @@ class TimeSlot(models.Model):
location = self.meeting.reg_area location = self.meeting.reg_area
elif self.type_id == "break": elif self.type_id == "break":
location = self.meeting.break_area location = self.meeting.break_area
return location
def get_location(self):
location = self.get_hidden_location()
if not self.show_location: if not self.show_location:
location = "" location = ""
return location return location
@ -626,8 +630,7 @@ class Schedule(models.Model):
.distinct() ) .distinct() )
def groups(self): def groups(self):
return Group.objects.filter(type__slug__in=['wg', 'rg', 'ag', 'iab'], parent__isnull=False, return Group.objects.filter(type__slug__in=['wg', 'rg', 'ag', 'iab'], parent__isnull=False, session__scheduledsession__schedule=self).exclude(session__scheduledsession__timeslot__type__in=['lead','offagenda']).distinct().order_by('parent__acronym', 'acronym')
session__scheduledsession__schedule=self).distinct().order_by('parent__acronym', 'acronym')
# calculate badness of entire schedule # calculate badness of entire schedule
def calc_badness(self): def calc_badness(self):

View file

@ -20,6 +20,7 @@ def make_meeting_test_data():
pname = RoomResourceName.objects.create(name='projector',slug='proj') pname = RoomResourceName.objects.create(name='projector',slug='proj')
projector = ResourceAssociation.objects.create(name=pname,icon="notfound.png",desc="Basic projector") projector = ResourceAssociation.objects.create(name=pname,icon="notfound.png",desc="Basic projector")
room = Room.objects.create(meeting=meeting, name="Test Room", capacity=123) room = Room.objects.create(meeting=meeting, name="Test Room", capacity=123)
breakfast_room = Room.objects.create(meeting=meeting, name="Breakfast Room", capacity=40)
room.resources = [projector] room.resources = [projector]
# mars WG # mars WG
@ -42,6 +43,17 @@ def make_meeting_test_data():
scheduled=datetime.datetime.now()) scheduled=datetime.datetime.now())
ScheduledSession.objects.create(timeslot=slot, session=ames_session, schedule=schedule) ScheduledSession.objects.create(timeslot=slot, session=ames_session, schedule=schedule)
# IESG breakfast
breakfast_slot = TimeSlot.objects.create(meeting=meeting, type_id="lead", duration=90 * 60,
location=breakfast_room,
time=datetime.datetime.combine(datetime.date.today(),datetime.time(7,0)))
iesg_session = Session.objects.create(meeting=meeting, group=Group.objects.get(acronym="iesg"),
name="IESG Breakfast",
attendees=25, requested_by=system_person,
requested_duration=20, status_id="schedw",
scheduled=datetime.datetime.now())
ScheduledSession.objects.create(timeslot=breakfast_slot, session=iesg_session, schedule=schedule)
meeting.agenda = schedule meeting.agenda = schedule
meeting.save() meeting.save()

View file

@ -152,7 +152,10 @@ class ApiTests(TestCase):
self.assertTrue(meeting.room_set.filter(name="new room")) self.assertTrue(meeting.room_set.filter(name="new room"))
timeslots_after = meeting.timeslot_set.count() timeslots_after = meeting.timeslot_set.count()
self.assertEqual((timeslots_after - timeslots_before), (meeting.room_set.count() - 1) * timeslots_before) # It's not clear that what that ajax function is doing is the right thing to do,
# but it currently makes a new timeslot for any existing timeslot.
# The condition tested below relies on the timeslots before this test all having different start and end times
self.assertEqual( timeslots_after, 2 * timeslots_before)
def test_delete_room(self): def test_delete_room(self):
meeting = make_meeting_test_data() meeting = make_meeting_test_data()
@ -201,7 +204,7 @@ class ApiTests(TestCase):
r = self.client.get(url) r = self.client.get(url)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
info = json.loads(r.content) info = json.loads(r.content)
self.assertEqual(set([x['short_name'] for x in info]),set(['mars','ames'])) self.assertEqual(set([x['short_name'] for x in info]),set([s.session.short_name for s in meeting.agenda.scheduledsession_set.all()]))
schedule = meeting.agenda schedule = meeting.agenda
url = urlreverse("ietf.meeting.ajax.scheduledsessions_json", url = urlreverse("ietf.meeting.ajax.scheduledsessions_json",
@ -209,7 +212,7 @@ class ApiTests(TestCase):
r = self.client.get(url) r = self.client.get(url)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
info = json.loads(r.content) info = json.loads(r.content)
self.assertEqual(len(info),2) self.assertEqual(len(info),schedule.scheduledsession_set.count())
def test_slot_json(self): def test_slot_json(self):

View file

@ -11,7 +11,7 @@ from pyquery import PyQuery
from ietf.doc.models import Document from ietf.doc.models import Document
from ietf.meeting.models import Session, TimeSlot from ietf.meeting.models import Session, TimeSlot
from ietf.meeting.test_data import make_meeting_test_data from ietf.meeting.test_data import make_meeting_test_data
from ietf.utils.test_utils import TestCase from ietf.utils.test_utils import TestCase, login_testing_unauthorized
class MeetingTests(TestCase): class MeetingTests(TestCase):
def setUp(self): def setUp(self):
@ -124,6 +124,13 @@ class MeetingTests(TestCase):
self.assertTrue(session.group.acronym in agenda_content) self.assertTrue(session.group.acronym in agenda_content)
self.assertTrue(slot.location.name in agenda_content) self.assertTrue(slot.location.name in agenda_content)
def test_agenda_by_room(self):
meeting = make_meeting_test_data()
url = urlreverse("ietf.meeting.views.agenda_by_room",kwargs=dict(num=meeting.number))
login_testing_unauthorized(self,"secretary",url)
r = self.client.get(url,kwargs=dict(num=meeting.number))
self.assertTrue(all([x in r.content for x in ['mars','IESG Breakfast','Test Room','Breakfast Room']]))
def test_materials(self): def test_materials(self):
meeting = make_meeting_test_data() meeting = make_meeting_test_data()
session = Session.objects.filter(meeting=meeting, group__acronym="mars").first() session = Session.objects.filter(meeting=meeting, group__acronym="mars").first()

View file

@ -33,6 +33,7 @@ urlpatterns = patterns('',
(r'^(?P<num>\d+)/agenda(?P<ext>.txt)$', views.agenda), (r'^(?P<num>\d+)/agenda(?P<ext>.txt)$', views.agenda),
(r'^(?P<num>\d+)/agenda.ics$', views.ical_agenda), (r'^(?P<num>\d+)/agenda.ics$', views.ical_agenda),
(r'^(?P<num>\d+)/agenda(?P<ext>.csv)$', views.agenda), (r'^(?P<num>\d+)/agenda(?P<ext>.csv)$', views.agenda),
(r'^(?P<num>\d+)/agenda/by-room$', views.agenda_by_room),
(r'^(?P<num>\d+)/agendas/edit$', views.edit_agendas), (r'^(?P<num>\d+)/agendas/edit$', views.edit_agendas),
(r'^(?P<num>\d+)/timeslots/edit$', views.edit_timeslots), (r'^(?P<num>\d+)/timeslots/edit$', views.edit_timeslots),
(r'^(?P<num>\d+)/rooms$', ajax.timeslot_roomsurl), (r'^(?P<num>\d+)/rooms$', ajax.timeslot_roomsurl),

View file

@ -6,6 +6,7 @@ import re
import tarfile import tarfile
import urllib import urllib
from tempfile import mkstemp from tempfile import mkstemp
from collections import OrderedDict
import debug # pyflakes:ignore import debug # pyflakes:ignore
@ -367,6 +368,7 @@ def edit_agendas(request, num=None, order=None):
def agenda(request, num=None, name=None, base=None, ext=None): def agenda(request, num=None, name=None, base=None, ext=None):
base = base if base else 'agenda' base = base if base else 'agenda'
ext = ext if ext else '.html' ext = ext if ext else '.html'
# This is misleading - urls.py doesn't send ics through here anymore
mimetype = { mimetype = {
".html":"text/html; charset=%s"%settings.DEFAULT_CHARSET, ".html":"text/html; charset=%s"%settings.DEFAULT_CHARSET,
".txt": "text/plain; charset=%s"%settings.DEFAULT_CHARSET, ".txt": "text/plain; charset=%s"%settings.DEFAULT_CHARSET,
@ -380,7 +382,22 @@ def agenda(request, num=None, name=None, base=None, ext=None):
return render(request, "meeting/no-"+base+ext, {'meeting':meeting }, content_type=mimetype[ext]) return render(request, "meeting/no-"+base+ext, {'meeting':meeting }, content_type=mimetype[ext])
updated = meeting_updated(meeting) updated = meeting_updated(meeting)
return render(request, "meeting/"+base+ext, {"schedule":schedule, "updated": updated}, content_type=mimetype[ext]) filtered_assignments = schedule.assignments.exclude(timeslot__type__in=['lead','offagenda'])
return render(request, "meeting/"+base+ext, {"schedule":schedule, "filtered_assignments":filtered_assignments, "updated": updated}, content_type=mimetype[ext])
#TODO - let the IAB in
@role_required('Area Director','Secretariat')
@ensure_csrf_cookie
def agenda_by_room(request,num=None):
meeting = get_meeting(num)
schedule = get_schedule(meeting)
ss_by_day = OrderedDict()
for day in schedule.scheduledsession_set.dates('timeslot__time','day'):
ss_by_day[day]=[]
for ss in schedule.scheduledsession_set.order_by('timeslot__location','timeslot__time'):
day = ss.timeslot.time.date()
ss_by_day[day].append(ss)
return render(request,"meeting/agenda_by_room.html",{"meeting":meeting,"ss_by_day":ss_by_day})
def read_agenda_file(num, doc): def read_agenda_file(num, doc):
# XXXX FIXME: the path fragment in the code below should be moved to # XXXX FIXME: the path fragment in the code below should be moved to
@ -611,7 +628,7 @@ def ical_agenda(request, num=None, name=None, ext=None):
elif item[0] == '~': elif item[0] == '~':
include_types |= set([item[1:]]) include_types |= set([item[1:]])
assignments = schedule.assignments.filter( assignments = schedule.assignments.exclude(timeslot__type__in=['lead','offagenda']).filter(
Q(timeslot__type__slug__in = include_types) | Q(timeslot__type__slug__in = include_types) |
Q(session__group__acronym__in = include) | Q(session__group__acronym__in = include) |
Q(session__group__parent__acronym__in = include) Q(session__group__parent__acronym__in = include)

View file

@ -1414,7 +1414,7 @@
"order": 0, "order": 0,
"used": true, "used": true,
"name": "None Selected", "name": "None Selected",
"desc": "" "desc": "[None selected]"
}, },
"model": "name.iprlicensetypename", "model": "name.iprlicensetypename",
"pk": "none-selected" "pk": "none-selected"
@ -2079,6 +2079,26 @@
"model": "name.timeslottypename", "model": "name.timeslottypename",
"pk": "reserved" "pk": "reserved"
}, },
{
"fields": {
"order": 0,
"used": true,
"name": "Leadership",
"desc": "Leadership Meetings"
},
"model": "name.timeslottypename",
"pk": "lead"
},
{
"fields": {
"order": 0,
"used": true,
"name": "Off Agenda",
"desc": "Other Meetings Not Published on Agenda"
},
"model": "name.timeslottypename",
"pk": "offagenda"
},
{ {
"fields": { "fields": {
"label": "State" "label": "State"

View file

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
def make_new_slot_types(apps, schema_editor):
TimeSlotTypeName = apps.get_model("name","TimeSlotTypeName")
TimeSlotTypeName.objects.create(slug='lead',name='Leadership',desc='Leadership Meetings',used=True)
TimeSlotTypeName.objects.create(slug='offagenda',name='Off Agenda',desc='Other Meetings Not Published on Agenda',used=True)
class Migration(migrations.Migration):
dependencies = [
('name', '0003_fix_ipr_none_selected_choice'),
]
operations = [
migrations.RunPython(make_new_slot_types)
]

View file

@ -180,6 +180,7 @@ class TimeSlotForm(forms.Form):
class NonSessionForm(TimeSlotForm): class NonSessionForm(TimeSlotForm):
short = forms.CharField(max_length=32,label='Short Name',help_text='Enter an abbreviated session name (used for material file names)',required=False) short = forms.CharField(max_length=32,label='Short Name',help_text='Enter an abbreviated session name (used for material file names)',required=False)
type = forms.ModelChoiceField(queryset=TimeSlotTypeName.objects.filter(slug__in=('other','reg','break','plenary')),empty_label=None) type = forms.ModelChoiceField(queryset=TimeSlotTypeName.objects.filter(slug__in=('other','reg','break','plenary')),empty_label=None)
type = forms.ModelChoiceField(queryset=TimeSlotTypeName.objects.filter(used=True).exclude(slug__in=('session',)),empty_label=None)
group = forms.ModelChoiceField(queryset=Group.objects.filter(acronym__in=('edu','ietf','iepg','tools','iesg','iab','iaoc')),help_text='Required for Session types: other, plenary',required=False) group = forms.ModelChoiceField(queryset=Group.objects.filter(acronym__in=('edu','ietf','iepg','tools','iesg','iab','iaoc')),help_text='Required for Session types: other, plenary',required=False)
show_location = forms.BooleanField(required=False) show_location = forms.BooleanField(required=False)

View file

@ -147,21 +147,21 @@ class MainTestCase(TestCase):
response = self.client.get(url) response = self.client.get(url)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
q = PyQuery(response.content) q = PyQuery(response.content)
self.assertEqual(len(q("#id_rooms_table tr")),2) self.assertEqual(len(q("#id_rooms_table tr input[type='text']")),meeting.room_set.count())
# test delete # test delete
# first unschedule sessions so we can delete # first unschedule sessions so we can delete
ScheduledSession.objects.filter(schedule=meeting.agenda).delete() ScheduledSession.objects.filter(schedule=meeting.agenda).delete()
self.client.login(username="secretary", password="secretary+password") self.client.login(username="secretary", password="secretary+password")
response = self.client.post(url, { post_dict = {
'room-TOTAL_FORMS': q('input[name="room-TOTAL_FORMS"]').val(), 'room-TOTAL_FORMS': q('input[name="room-TOTAL_FORMS"]').val(),
'room-INITIAL_FORMS': q('input[name="room-INITIAL_FORMS"]').val(), 'room-INITIAL_FORMS': q('input[name="room-INITIAL_FORMS"]').val(),
'room-0-meeting': q('input[name="room-0-meeting"]').val(), }
'room-0-id': q('input[name="room-0-id"]').val(), for i in range(meeting.room_set.count()):
'room-0-name': q('input[name="room-0-name"]').val(), for attr in ['meeting','id','name','capacity','DELETE']:
'room-0-capacity': q('input[name="room-0-capacity"]').val(), key = 'room-%d-%s' % (i,attr)
'room-0-DELETE': 'on' post_dict[key] = q('input[name="%s"]' % key).val()
}) response = self.client.post(url, post_dict)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(Room.objects.filter(meeting=meeting).count(),0) self.assertEqual(Room.objects.filter(meeting=meeting).count(),0)
@ -176,6 +176,7 @@ class MainTestCase(TestCase):
meeting = make_meeting_test_data() meeting = make_meeting_test_data()
qs = TimeSlot.objects.filter(meeting=meeting,type='session') qs = TimeSlot.objects.filter(meeting=meeting,type='session')
before = qs.count() before = qs.count()
expected_deletion_count = qs.filter(time=qs.first().time).count()
url = reverse('meetings_times_delete',kwargs={ url = reverse('meetings_times_delete',kwargs={
'meeting_id':42, 'meeting_id':42,
'schedule_name':'test-agenda', 'schedule_name':'test-agenda',
@ -185,7 +186,7 @@ class MainTestCase(TestCase):
response = self.client.get(url) response = self.client.get(url)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
after = TimeSlot.objects.filter(meeting=meeting,type='session').count() after = TimeSlot.objects.filter(meeting=meeting,type='session').count()
self.assertEqual(after,before - (Room.objects.filter(meeting=meeting).count())) self.assertEqual(after,before - expected_deletion_count)
def test_meetings_times_edit(self): def test_meetings_times_edit(self):
meeting = make_meeting_test_data() meeting = make_meeting_test_data()

View file

@ -95,7 +95,7 @@ def build_nonsession(meeting,schedule):
system = Person.objects.get(name='(system)') system = Person.objects.get(name='(system)')
secretariat = Group.objects.get(acronym='secretariat') secretariat = Group.objects.get(acronym='secretariat')
for slot in TimeSlot.objects.filter(meeting=last_meeting,type__in=('break','reg','other','plenary')): for slot in TimeSlot.objects.filter(meeting=last_meeting,type__in=('break','reg','other','plenary','lead')):
new_time = slot.time + delta new_time = slot.time + delta
session = None session = None
# create Session object for Tutorials to hold materials # create Session object for Tutorials to hold materials
@ -128,15 +128,17 @@ def check_nonsession(meeting,schedule):
Ensure non-session timeslots exist and have appropriate ScheduledSession objects Ensure non-session timeslots exist and have appropriate ScheduledSession objects
for the specified schedule. for the specified schedule.
''' '''
slots = TimeSlot.objects.filter(meeting=meeting,type__in=('break','reg','other','plenary')) slots = TimeSlot.objects.filter(meeting=meeting,type__in=('break','reg','other','plenary','lead','offagenda'))
if not slots: if not slots:
build_nonsession(meeting,schedule) build_nonsession(meeting,schedule)
return None return None
scheduledsessions = slots.filter(type='plenary').first().scheduledsession_set.all() plenary = slots.filter(type='plenary').first()
if not scheduledsessions.filter(schedule=schedule): if plenary:
source = scheduledsessions.first().schedule scheduledsessions = plenary.scheduledsession_set.all()
copy_scheduledsessions(slots,source,schedule) if not scheduledsessions.filter(schedule=schedule):
source = scheduledsessions.first().schedule
copy_scheduledsessions(slots,source,schedule)
def copy_scheduledsessions(slots,source,target): def copy_scheduledsessions(slots,source,target):
''' '''
@ -435,7 +437,7 @@ def non_session(request, meeting_id, schedule_name):
check_nonsession(meeting,schedule) check_nonsession(meeting,schedule)
slots = TimeSlot.objects.filter(meeting=meeting,type__in=('break','reg','other','plenary')).order_by('-type__name','time') slots = TimeSlot.objects.filter(meeting=meeting,type__in=('break','reg','other','plenary','lead')).order_by('-type__name','time')
if request.method == 'POST': if request.method == 'POST':
form = NonSessionForm(request.POST) form = NonSessionForm(request.POST)
@ -458,7 +460,7 @@ def non_session(request, meeting_id, schedule_name):
duration=duration, duration=duration,
show_location=form.cleaned_data['show_location']) show_location=form.cleaned_data['show_location'])
if timeslot.type.slug not in ('other','plenary'): if timeslot.type.slug not in ('other','plenary','lead'):
group = Group.objects.get(acronym='secretariat') group = Group.objects.get(acronym='secretariat')
# create associated Session object # create associated Session object
@ -501,7 +503,7 @@ def non_session_delete(request, meeting_id, schedule_name, slot_id):
meeting = get_object_or_404(Meeting, number=meeting_id) meeting = get_object_or_404(Meeting, number=meeting_id)
# schedule = get_object_or_404(Schedule, meeting=meeting, name=schedule_name) # schedule = get_object_or_404(Schedule, meeting=meeting, name=schedule_name)
slot = get_object_or_404(TimeSlot, id=slot_id) slot = get_object_or_404(TimeSlot, id=slot_id)
if slot.type_id in ('other','plenary'): if slot.type_id in ('other','plenary','lead'):
scheduledsessions = slot.scheduledsession_set.filter(schedule__meeting=meeting) scheduledsessions = slot.scheduledsession_set.filter(schedule__meeting=meeting)
session_objects = [ x.session for x in scheduledsessions ] session_objects = [ x.session for x in scheduledsessions ]
for session in session_objects: for session in session_objects:

View file

@ -1,7 +1,7 @@
{% load humanize %}{% autoescape off %}{% load ietf_filters %}"Date","Start","End","Session","Room","Area","Acronym","Type","Description","Session ID","Agenda","Slides" {% load humanize %}{% autoescape off %}{% load ietf_filters %}"Date","Start","End","Session","Room","Area","Acronym","Type","Description","Session ID","Agenda","Slides"
{% for item in schedule.assignments.all.distinct %}{% if item.timeslot.type.slug == "break" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","Break","{{ schedule.meeting.break_area}}","","","","{{ item.timeslot.name }}","b{{ item.timeslot.pk }}","","" {% for item in filtered_assignments.all.distinct %}{% if item.timeslot.type.slug == "break" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","Break","{{ schedule.meeting.break_area}}","","","","{{ item.timeslot.name }}","b{{ item.timeslot.pk }}","",""
{% endif %}{% if item.timeslot.type.slug == "reg" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","{{ item.timeslot.type.name }}","{{ schedule.meeting.reg_area }}","","","","{{ item.timeslot.name }}","r{{item.timeslot.pk}}","","" {% endif %}{% if item.timeslot.type.slug == "reg" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","{{ item.timeslot.type.name }}","{{ schedule.meeting.reg_area }}","","","","{{ item.timeslot.name }}","r{{item.timeslot.pk}}","",""
{% endif %}{% if item.timeslot.type.slug == "other" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","None","{{ item.timeslot.location.name }}","","{{ item.session.group.acronym }}","{% if item.session.group.parent %}{{item.session.group.parent.acronym|upper}}{% endif %}","{{ item.session.name }}","{{item.session.pk}}","","" {% endif %}{% if item.timeslot.type.slug == "other" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","None","{{ item.timeslot.location.name }}","","{{ item.session.group.acronym }}","{% if item.session.group.parent %}{{item.session.group.parent.acronym|upper}}{% endif %}","{{ item.session.name }}","{{item.session.pk}}","",""
{% endif %}{% if item.timeslot.type.slug == "plenary" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","{{ item.session.name }}","{{ item.timeslot.location.name }}","","{{ item.session.group.acronym }}","","{{ item.session.name }}","{{item.session.pk}}","{% if item.session.agenda %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/agenda/{{ item.session.agenda.external_url }}{% endif %}","{% if item.session.slides %}{% for slide in item.session.slides %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/slides/{{ slide.external_url }}{% if not forloop.last %}|{% endif %}{% endfor %}{% endif %}" {% endif %}{% if item.timeslot.type.slug == "plenary" %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","{{ item.session.name }}","{{ item.timeslot.location.name }}","","{{ item.session.group.acronym }}","","{{ item.session.name }}","{{item.session.pk}}","{% if item.session.agenda %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/agenda/{{ item.session.agenda.external_url }}{% endif %}","{% if item.session.slides %}{% for slide in item.session.slides %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/slides/{{ slide.external_url }}{% if not forloop.last %}|{% endif %}{% endfor %}{% endif %}"
{% endif %}{% if item.timeslot.type.slug == "session" and item.session.group %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","{{ item.timeslot.name }}","{{ item.timeslot.location.name }}","{{ item.session.group.parent.acronym|upper }}","{{ item.session.group.acronym }}","{{ item.session.type }}","{{ item.session.group.name }}","{{ item.session.pk}}","{% if item.session.agenda %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/agenda/{{ item.session.agenda.external_url }}{% endif %}","{% if item.session.slides %}{% for slide in item.session.slides %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/slides/{{ slide.external_url }}{% if not forloop.last %}|{% endif %}{% endfor %}{% endif %}" {% endif %}{% if item.timeslot.type.slug == "session" and item.session.group %}"{{ item.timeslot.time|date:"Y-m-d" }}","{{ item.timeslot.time_desc|slice:":4" }}","{{ item.timeslot.time_desc|slice:"5:9" }}","{{ item.timeslot.name }}","{{ item.timeslot.location.name }}","{{ item.session.group.parent.acronym|upper }}","{{ item.session.group.acronym }}","{{ item.session.type }}","{{ item.session.group.name }}","{{ item.session.pk}}","{% if item.session.agenda %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/agenda/{{ item.session.agenda.external_url }}{% endif %}","{% if item.session.slides %}{% for slide in item.session.slides %}http://www.ietf.org/proceedings/{{ schedule.meeting.number }}/slides/{{ slide.external_url }}{% if not forloop.last %}|{% endif %}{% endfor %}{% endif %}"
{% endif %}{% endfor %}{% endautoescape %} {% endif %}{% endfor %}{% endautoescape %}

Can't render this file because it contains an unexpected character in line 1 and column 63.

View file

@ -146,7 +146,7 @@
<iframe seamless class="hidden" id="weekview"></iframe> <iframe seamless class="hidden" id="weekview"></iframe>
<table class="table table-condensed table-striped"> <table class="table table-condensed table-striped">
{% for item in schedule.assignments.all %} {% for item in filtered_assignments.all %}
{% ifchanged item.timeslot.time|date:"Y-m-d" %} {% ifchanged item.timeslot.time|date:"Y-m-d" %}
<tr><th class="gap" colspan="6"></th></tr> <tr><th class="gap" colspan="6"></th></tr>
@ -335,7 +335,7 @@
</div> </div>
<div class="col-md-2 hidden-print bs-docs-sidebar" id="affix"> <div class="col-md-2 hidden-print bs-docs-sidebar" id="affix">
<ul class="nav nav-pills nav-stacked small" data-spy="affix"> <ul class="nav nav-pills nav-stacked small" data-spy="affix">
{% for item in schedule.assignments.all %} {% for item in filtered_assignments.all %}
{% ifchanged item.timeslot.time|date:"Y-m-d" %} {% ifchanged item.timeslot.time|date:"Y-m-d" %}
<li><a href="#{{item.timeslot.time|slugify}}">{{ item.timeslot.time|date:"l, F j, Y" }}</a></li> <li><a href="#{{item.timeslot.time|slugify}}">{{ item.timeslot.time|date:"l, F j, Y" }}</a></li>
{% endifchanged %} {% endifchanged %}

View file

@ -8,7 +8,7 @@
{% filter center:72 %}Updated {{ updated|date:"Y-m-d H:i:s T" }}{% 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 %} {% 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 item in filtered_assignments.all.distinct %}{% ifchanged %}
{{ item.timeslot.time|date:"l"|upper }}, {{ item.timeslot.time|date:"F j, Y" }} {{ item.timeslot.time|date:"l"|upper }}, {{ item.timeslot.time|date:"F j, Y" }}

View file

@ -0,0 +1,40 @@
{% extends "base.html" %}
{% block morecss %}
ul.daylist { list-style:none; padding-left:0; }
li.daylistentry { font-size:162%; font-weight:700; }
li.even { background-color:#EDF5FF; }
li.odd { background-color:white; }
ul.roomlist {list-style:none; padding-left:0; margin-bottom:20px;}
li.roomlistentry { font-weight: 400; }
ul.sessionlist { list-style:none; padding-left:2em; margin-bottom:10px;}
li.sessionlistentry { font-size:62%; }
.lead:after { content: " (DO NOT POST)"; color:red; }
.offagenda:after { content:" (not published on agenda)"; }
{% endblock %}
{% block title %}Agenda for {{meeting}} by Room{% endblock %}
{% block content %}
<h1>Agenda for {{meeting}} by Room</h1>
<ul class="daylist">
{% for day,sessions in ss_by_day.items %}
<li class="daylistentry {% cycle 'even' 'odd' %}">{{day|date:'l, j F Y'}}
{% regroup sessions by timeslot.get_hidden_location as room_list %}
<ul class="roomlist">
{% for room in room_list %}
<li class="roomlistentry">{{room.grouper|default:"Location Unavailable"}}
<ul class="sessionlist">
{% for ss in room.list %}
<li class="sessionlistentry {{ss.timeslot.type.slug}}">{{ss.timeslot.time|date:"H:i"}}-{{ss.timeslot.end_time|date:"H:i"}} {{ss.session.short_name}}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
{% endblock %}

View file

@ -1172,6 +1172,10 @@ Session.prototype.event_template = function() {
} }
//console.log("acronym", groupacronym, this.group.acronym, this.visible_title()); //console.log("acronym", groupacronym, this.group.acronym, this.visible_title());
var durationstring="";
if (this.requested_duration!="0.0") {
durationstring = " ("+this.requested_duration+")"
}
// see comment in ietf.ccs, and // see comment in ietf.ccs, and
// http://stackoverflow.com/questions/5148041/does-firefox-support-position-relative-on-table-elements // http://stackoverflow.com/questions/5148041/does-firefox-support-position-relative-on-table-elements
return "<div class='meeting_box_container' session_id=\""+this.session_id+"\"><div class=\"meeting_box "+bucket_list_style+"\" ><table class='meeting_event "+ return "<div class='meeting_box_container' session_id=\""+this.session_id+"\"><div class=\"meeting_box "+bucket_list_style+"\" ><table class='meeting_event "+
@ -1183,7 +1187,7 @@ Session.prototype.event_template = function() {
this.wg_scheme()+" "+ this.wg_scheme()+" "+
this.area_scheme() +" meeting_obj'>"+ this.area_scheme() +" meeting_obj'>"+
this.visible_title()+ this.visible_title()+
"<span> ("+this.requested_duration+")</span>" + "<span>" + durationstring + "</span>" +
"</th><td class=\"ourconflicts\"></td>"+pinned+"</tr></table>"+ area_mark +"</div></div>"; "</th><td class=\"ourconflicts\"></td>"+pinned+"</tr></table>"+ area_mark +"</div></div>";
}; };