From 71dec7a692d730b2d6ead0db47c2f8ab92f284a7 Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Mon, 26 Oct 2015 22:45:26 +0000 Subject: [PATCH] Moved forward to 6.7.2.dev0 the changes to rename class ScheduledSession to the more correct (but unfortunately also cumbersome) SchedTimeSessAssignment, and rename reverse relationships involving this class appropriately. Accompanying changes in javascript and templates. Migrations to match. - Legacy-Id: 10297 --- ietf/doc/tests_material.py | 4 +- ietf/doc/views_material.py | 8 +-- ietf/meeting/admin.py | 6 +- ietf/meeting/ajax.py | 56 ++++++++-------- ietf/meeting/helpers.py | 20 +++--- .../meeting/management/commands/schedwrite.py | 4 +- .../migrations/0012_auto_20151026_1406.py | 26 ++++++++ .../migrations/0013_auto_20151026_1408.py | 39 +++++++++++ .../migrations/0014_auto_20151026_1414.py | 43 ++++++++++++ ietf/meeting/models.py | 66 +++++++++---------- ietf/meeting/placement.py | 48 +++++++------- ietf/meeting/resources.py | 12 ++-- ietf/meeting/test_data.py | 8 +-- ietf/meeting/tests_api.py | 48 +++++++------- ietf/meeting/tests_js.py | 8 ++- ietf/meeting/tests_views.py | 10 +-- ietf/meeting/urls.py | 4 +- ietf/meeting/views.py | 64 +++++++++--------- ietf/secr/meetings/forms.py | 6 +- ietf/secr/meetings/tests.py | 6 +- ietf/secr/meetings/views.py | 50 +++++++------- ietf/secr/proceedings/proc_utils.py | 10 +-- ietf/secr/proceedings/views.py | 8 +-- ietf/secr/sreq/views.py | 2 +- ietf/secr/utils/meeting.py | 6 +- ietf/static/ietf/js/agenda/agenda_edit.js | 7 +- ietf/static/ietf/js/agenda/agenda_helpers.js | 2 +- .../static/ietf/js/agenda/agenda_listeners.js | 34 +++++----- ietf/static/ietf/js/agenda/agenda_objects.js | 50 +++++++------- ietf/templates/meeting/agenda_by_type.html | 2 +- ietf/templates/meeting/landscape_edit.html | 4 +- ietf/templates/meeting/room-view.html | 2 +- 32 files changed, 385 insertions(+), 278 deletions(-) create mode 100644 ietf/meeting/migrations/0012_auto_20151026_1406.py create mode 100644 ietf/meeting/migrations/0013_auto_20151026_1408.py create mode 100644 ietf/meeting/migrations/0014_auto_20151026_1414.py diff --git a/ietf/doc/tests_material.py b/ietf/doc/tests_material.py index 47569fa0a..c9ed44889 100644 --- a/ietf/doc/tests_material.py +++ b/ietf/doc/tests_material.py @@ -188,7 +188,7 @@ class GroupMaterialTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) - when = meeting.agenda.scheduledsession_set.filter(session__group__acronym='testteam').first().timeslot.time + when = meeting.agenda.assignments.filter(session__group__acronym='testteam').first().timeslot.time mdw = when.date().isoformat() dow = ['mon','tue','wed','thu','fri','sat','sun'][when.weekday()] @@ -212,7 +212,7 @@ class GroupMaterialTests(TestCase): meeting = make_meeting_test_data() meeting.session_set.filter(group__acronym='mars').update(group=doc.group) - session = meeting.agenda.scheduledsession_set.filter(session__group__acronym='testteam').first().session + session = meeting.agenda.assignments.filter(session__group__acronym='testteam').first().session url = urlreverse(edit_material_presentations,kwargs=dict(name=doc.name,acronym='testteam',seq=1)) login_testing_unauthorized(self, "secretary", url) diff --git a/ietf/doc/views_material.py b/ietf/doc/views_material.py index c1c5f6c3c..390d31d2f 100644 --- a/ietf/doc/views_material.py +++ b/ietf/doc/views_material.py @@ -197,18 +197,18 @@ def get_upcoming_manageable_sessions(user, doc, acronym=None, date=None, seq=Non if date: if len(date)==15: start = datetime.datetime.strptime(date,"%Y-%m-%d-%H%M") - refined_candidates = [ sess for sess in refined_candidates if sess.scheduledsession_set.filter(schedule=sess.meeting.agenda,timeslot__time=start) ] + refined_candidates = [ sess for sess in refined_candidates if sess.timeslotassignments.filter(schedule=sess.meeting.agenda,timeslot__time=start) ] else: start = datetime.datetime.strptime(date,"%Y-%m-%d").date() end = start+datetime.timedelta(days=1) - refined_candidates = [ sess for sess in refined_candidates if sess.scheduledsession_set.filter(schedule=sess.meeting.agenda,timeslot__time__range=(start,end)) ] + refined_candidates = [ sess for sess in refined_candidates if sess.timeslotassignments.filter(schedule=sess.meeting.agenda,timeslot__time__range=(start,end)) ] if week_day: try: dow = ['sun','mon','tue','wed','thu','fri','sat'].index(week_day.lower()[:3]) + 1 except ValueError: raise Http404 - refined_candidates = [ sess for sess in refined_candidates if sess.scheduledsession_set.filter(schedule=sess.meeting.agenda,timeslot__time__week_day=dow) ] + refined_candidates = [ sess for sess in refined_candidates if sess.timeslotassignments.filter(schedule=sess.meeting.agenda,timeslot__time__week_day=dow) ] changeable_sessions = [ sess for sess in refined_candidates if can_manage_materials(user, sess.group) ] @@ -226,7 +226,7 @@ def get_upcoming_manageable_sessions(user, doc, acronym=None, date=None, seq=Non # scheduled). def time_sort_key(session): - official_sessions = session.scheduledsession_set.filter(schedule=session.meeting.agenda) + official_sessions = session.timeslotassignments.filter(schedule=session.meeting.agenda) if official_sessions: return official_sessions.first().timeslot.time else: diff --git a/ietf/meeting/admin.py b/ietf/meeting/admin.py index b391e1f3a..f1a92c092 100644 --- a/ietf/meeting/admin.py +++ b/ietf/meeting/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from ietf.meeting.models import Meeting, Room, Session, TimeSlot, Constraint, Schedule, ScheduledSession, ResourceAssociation +from ietf.meeting.models import Meeting, Room, Session, TimeSlot, Constraint, Schedule, SchedTimeSessAssignment, ResourceAssociation class RoomAdmin(admin.ModelAdmin): list_display = ["id", "meeting", "name", "capacity", ] @@ -87,11 +87,11 @@ class ScheduleAdmin(admin.ModelAdmin): admin.site.register(Schedule, ScheduleAdmin) -class ScheduledSessionAdmin(admin.ModelAdmin): +class SchedTimeSessAssignmentAdmin(admin.ModelAdmin): list_display = ["id", "schedule", "timeslot", "session", "modified"] list_filter = ["timeslot__meeting", "schedule"] -admin.site.register(ScheduledSession, ScheduledSessionAdmin) +admin.site.register(SchedTimeSessAssignment, SchedTimeSessAssignmentAdmin) class ResourceAssociationAdmin(admin.ModelAdmin): diff --git a/ietf/meeting/ajax.py b/ietf/meeting/ajax.py index 27cd4d79e..0e1776d08 100644 --- a/ietf/meeting/ajax.py +++ b/ietf/meeting/ajax.py @@ -8,7 +8,7 @@ from django.views.decorators.http import require_POST from ietf.ietfauth.utils import role_required, has_role from ietf.meeting.helpers import get_meeting, get_schedule, agenda_permissions, get_person_by_email, get_schedule_by_name -from ietf.meeting.models import TimeSlot, Session, Schedule, Room, Constraint, ScheduledSession, ResourceAssociation +from ietf.meeting.models import TimeSlot, Session, Schedule, Room, Constraint, SchedTimeSessAssignment, ResourceAssociation from ietf.meeting.views import edit_timeslots, edit_agenda import debug # pyflakes:ignore @@ -151,7 +151,7 @@ def timeslot_roomurl(request, num=None, roomid=None): ############################################################################# ## DAY/SLOT API -## -- this creates groups of timeslots, and associated scheduledsessions. +## -- this creates groups of timeslots, and associated schedtimesessassignments. ############################################################################# AddSlotForm = modelform_factory(TimeSlot, exclude=('meeting','name','location','sessions', 'modified')) @@ -319,7 +319,7 @@ def agenda_update(request, meeting, schedule): @role_required('Secretariat') def agenda_del(request, meeting, schedule): - schedule.delete_scheduledsessions() + schedule.delete_assignments() #debug.log("deleting meeting: %s agenda: %s" % (meeting, meeting.agenda)) if meeting.agenda == schedule: meeting.agenda = None @@ -431,8 +431,8 @@ def sessions_json(request, num): ## Scheduledsesion ############################################################################# -# this creates an entirely *NEW* scheduledsession -def scheduledsessions_post(request, meeting, schedule): +# this creates an entirely *NEW* schedtimesessassignment +def assignments_post(request, meeting, schedule): cansee,canedit,secretariat = agenda_permissions(meeting, schedule, request.user) if not canedit: return HttpResponse(json.dumps({'error':'no permission to modify this agenda'}), @@ -446,15 +446,15 @@ def scheduledsessions_post(request, meeting, schedule): status = 406, content_type="application/json") - ss1 = ScheduledSession(schedule = schedule, + ss1 = SchedTimeSessAssignment(schedule = schedule, session_id = newvalues["session_id"], timeslot_id = newvalues["timeslot_id"]) if("extendedfrom_id" in newvalues): val = int(newvalues["extendedfrom_id"]) try: - ss2 = schedule.scheduledsession_set.get(pk = val) + ss2 = schedule.assignments.get(pk = val) ss1.extendedfrom = ss2 - except ScheduledSession.DoesNotExist: + except SchedTimeSessAssignment.DoesNotExist: return HttpResponse(json.dumps({'error':'invalid extendedfrom value: %u' % val}), status = 406, content_type="application/json") @@ -467,28 +467,28 @@ def scheduledsessions_post(request, meeting, schedule): response['Location'] = ss1_dict["href"], return response -def scheduledsessions_get(request, num, schedule): - scheduledsessions = schedule.scheduledsession_set.all() +def assignments_get(request, num, schedule): + assignments = schedule.assignments.all() - sess1_dict = [ x.json_dict(request.build_absolute_uri('/')) for x in scheduledsessions ] + sess1_dict = [ x.json_dict(request.build_absolute_uri('/')) for x in assignments ] return HttpResponse(json.dumps(sess1_dict, sort_keys=True, indent=2), content_type="application/json") # this returns the list of scheduled sessions for the given named agenda -def scheduledsessions_json(request, num, owner, name): +def assignments_json(request, num, owner, name): meeting, person, schedule = get_meeting_schedule(num, owner, name) if request.method == 'GET': - return scheduledsessions_get(request, meeting, schedule) + return assignments_get(request, meeting, schedule) elif request.method == 'POST': - return scheduledsessions_post(request, meeting, schedule) + return assignments_post(request, meeting, schedule) else: return HttpResponse(json.dumps({'error':'inappropriate action: %s' % (request.method)}), status = 406, content_type="application/json") # accepts both POST and PUT in order to implement Postel Doctrine. -def scheduledsession_update(request, meeting, schedule, ss): +def assignment_update(request, meeting, schedule, ss): cansee,canedit,secretariat = agenda_permissions(meeting, schedule, request.user) if not canedit: return HttpResponse(json.dumps({'error':'no permission to update this agenda'}), @@ -506,7 +506,7 @@ def scheduledsession_update(request, meeting, schedule, ss): return HttpResponse(json.dumps({'message':'valid'}), content_type="application/json") -def scheduledsession_delete(request, meeting, schedule, ss): +def assignment_delete(request, meeting, schedule, ss): cansee,canedit,secretariat = agenda_permissions(meeting, schedule, request.user) if not canedit: return HttpResponse(json.dumps({'error':'no permission to update this agenda'}), @@ -514,13 +514,13 @@ def scheduledsession_delete(request, meeting, schedule, ss): content_type="application/json") # in case there is, somehow, more than one item with the same pk.. XXX - scheduledsessions = schedule.scheduledsession_set.filter(pk = ss.pk) - if len(scheduledsessions) == 0: + assignments = schedule.assignments.filter(pk = ss.pk) + if len(assignments) == 0: return HttpResponse(json.dumps({'error':'no such object'}), status = 404, content_type="application/json") count=0 - for ss in scheduledsessions: + for ss in assignments: ss.delete() count += 1 @@ -528,7 +528,7 @@ def scheduledsession_delete(request, meeting, schedule, ss): status = 200, content_type="application/json") -def scheduledsession_get(request, meeting, schedule, ss): +def assignment_get(request, meeting, schedule, ss): cansee,canedit,secretariat = agenda_permissions(meeting, schedule, request.user) if not cansee: @@ -541,22 +541,22 @@ def scheduledsession_get(request, meeting, schedule, ss): content_type="application/json") # this return a specific session, updates a session or deletes a SPECIFIC scheduled session -def scheduledsession_json(request, num, owner, name, scheduledsession_id): +def assignment_json(request, num, owner, name, assignment_id): meeting, person, schedule = get_meeting_schedule(num, owner, name) - scheduledsessions = schedule.scheduledsession_set.filter(pk = scheduledsession_id) - if len(scheduledsessions) == 0: - return HttpResponse(json.dumps({'error' : 'invalid scheduledsession'}), + assignments = schedule.assignments.filter(pk = assignment_id) + if len(assignments) == 0: + return HttpResponse(json.dumps({'error' : 'invalid assignment'}), content_type="application/json", status=404); - ss = scheduledsessions[0] + ss = assignments[0] if request.method == 'GET': - return scheduledsession_get(request, meeting, schedule, ss) + return assignment_get(request, meeting, schedule, ss) elif request.method == 'PUT' or request.method=='POST': - return scheduledsession_update(request, meeting, schedule, ss) + return assignment_update(request, meeting, schedule, ss) elif request.method == 'DELETE': - return scheduledsession_delete(request, meeting, schedule, ss) + return assignment_delete(request, meeting, schedule, ss) ############################################################################# ## Constraints API diff --git a/ietf/meeting/helpers.py b/ietf/meeting/helpers.py index 71c5cfb39..ba7806672 100644 --- a/ietf/meeting/helpers.py +++ b/ietf/meeting/helpers.py @@ -61,8 +61,8 @@ def get_areas(): Q(state="active", type="area")).order_by('acronym') # get list of areas that are referenced. -def get_area_list_from_sessions(scheduledsessions, num): - return scheduledsessions.filter(timeslot__type = 'Session', +def get_area_list_from_sessions(assignments, num): + return assignments.filter(timeslot__type = 'Session', session__group__parent__isnull = False).order_by( 'session__group__parent__acronym').distinct().values_list( 'session__group__parent__acronym',flat=True) @@ -85,25 +85,25 @@ def build_all_agenda_slices(meeting): time_slices.sort() return time_slices,date_slices -def get_all_scheduledsessions_from_schedule(schedule): - ss = schedule.scheduledsession_set.filter(timeslot__location__isnull = False) +def get_all_assignments_from_schedule(schedule): + ss = schedule.assignments.filter(timeslot__location__isnull = False) ss = ss.filter(session__type__slug='session') ss = ss.order_by('timeslot__time','timeslot__name') return ss -def get_modified_from_scheduledsessions(scheduledsessions): - return scheduledsessions.aggregate(Max('timeslot__modified'))['timeslot__modified__max'] +def get_modified_from_assignments(assignments): + return assignments.aggregate(Max('timeslot__modified'))['timeslot__modified__max'] -def get_wg_name_list(scheduledsessions): - return scheduledsessions.filter(timeslot__type = 'Session', +def get_wg_name_list(assignments): + return assignments.filter(timeslot__type = 'Session', session__group__isnull = False, session__group__parent__isnull = False).order_by( 'session__group__acronym').distinct().values_list( 'session__group__acronym',flat=True) -def get_wg_list(scheduledsessions): - wg_name_list = get_wg_name_list(scheduledsessions) +def get_wg_list(assignments): + wg_name_list = get_wg_name_list(assignments) return Group.objects.filter(acronym__in = set(wg_name_list)).order_by('parent__acronym','acronym') diff --git a/ietf/meeting/management/commands/schedwrite.py b/ietf/meeting/management/commands/schedwrite.py index 173223a61..d21a3b9e7 100644 --- a/ietf/meeting/management/commands/schedwrite.py +++ b/ietf/meeting/management/commands/schedwrite.py @@ -27,7 +27,7 @@ class Command(BaseCommand): meeting = get_meeting(meetingname) schedule = get_schedule(meeting, schedname) - scheduledsessions = schedule.scheduledsession_set.all() + assignments = schedule.assignments.all() # cribbed from django/core/management/commands/dumpdata.py # Check that the serialization format exists; this is a shortcut to @@ -35,7 +35,7 @@ class Command(BaseCommand): if format not in serializers.get_public_serializer_formats(): raise CommandError("Unknown serialization format: %s" % format) - return serializers.serialize(format, scheduledsessions, indent=indent, + return serializers.serialize(format, assignments, indent=indent, use_natural_keys=True) diff --git a/ietf/meeting/migrations/0012_auto_20151026_1406.py b/ietf/meeting/migrations/0012_auto_20151026_1406.py new file mode 100644 index 000000000..002532664 --- /dev/null +++ b/ietf/meeting/migrations/0012_auto_20151026_1406.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('meeting', '0011_ietf92_meetings'), + ] + + operations = [ + migrations.AlterField( + model_name='scheduledsession', + name='session', + field=models.ForeignKey(related_name='timeslotassignments', default=None, to='meeting.Session', help_text='Scheduled session.', null=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='scheduledsession', + name='timeslot', + field=models.ForeignKey(related_name='sessionassignments', to='meeting.TimeSlot'), + preserve_default=True, + ), + ] diff --git a/ietf/meeting/migrations/0013_auto_20151026_1408.py b/ietf/meeting/migrations/0013_auto_20151026_1408.py new file mode 100644 index 000000000..a39501ed6 --- /dev/null +++ b/ietf/meeting/migrations/0013_auto_20151026_1408.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import datetime + + +class Migration(migrations.Migration): + + dependencies = [ + ('meeting', '0012_auto_20151026_1406'), + ] + + operations = [ + migrations.CreateModel( + name='Dummy', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('modified', models.DateTimeField(default=datetime.datetime.now)), + ('notes', models.TextField(blank=True)), + ('badness', models.IntegerField(default=0, null=True, blank=True)), + ('pinned', models.BooleanField(default=False, help_text=b'Do not move session during automatic placement.')), + ('extendedfrom', models.ForeignKey(default=None, to='self', help_text='Timeslot this session is an extension of.', null=True)), + ('schedule', models.ForeignKey(related_name='assignments', to='meeting.Schedule')), + ('session', models.ForeignKey(related_name='timeslotassignments', default=None, to='meeting.Session', help_text='Scheduled session.', null=True)), + ('timeslot', models.ForeignKey(related_name='sessionassignments', to='meeting.TimeSlot')), + ], + options={ + 'ordering': ['timeslot__time', 'timeslot__type__slug', 'session__group__parent__name', 'session__group__acronym', 'session__name'], + }, + bases=(models.Model,), + ), + migrations.AlterField( + model_name='timeslot', + name='sessions', + field=models.ManyToManyField(related_name='slots', to='meeting.Session', through='meeting.Dummy', blank=True, help_text='Scheduled session, if any.', null=True), + preserve_default=True, + ), + ] diff --git a/ietf/meeting/migrations/0014_auto_20151026_1414.py b/ietf/meeting/migrations/0014_auto_20151026_1414.py new file mode 100644 index 000000000..8d36fd524 --- /dev/null +++ b/ietf/meeting/migrations/0014_auto_20151026_1414.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('meeting', '0013_auto_20151026_1408'), + ] + + operations = [ + migrations.RenameModel('ScheduledSession', 'SchedTimeSessAssignment'), + + migrations.AlterField( + model_name='timeslot', + name='sessions', + field=models.ManyToManyField(related_name='slots', to='meeting.Session', through='meeting.SchedTimeSessAssignment', blank=True, help_text='Scheduled session, if any.', null=True), + preserve_default=True, + ), + + migrations.RemoveField( + model_name='dummy', + name='extendedfrom', + ), + migrations.RemoveField( + model_name='dummy', + name='schedule', + ), + migrations.RemoveField( + model_name='dummy', + name='session', + ), + migrations.RemoveField( + model_name='dummy', + name='timeslot', + ), + migrations.DeleteModel( + name='Dummy', + ), + + ] diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index f8b2e127e..cadf19421 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -237,11 +237,11 @@ class Meeting(models.Model): # alltimeslots = self.timeslot_set.all() # for sched in self.schedule_set.all(): # ts_hash = {} -# for ss in sched.scheduledsession_set.all(): +# for ss in sched.assignments.all(): # ts_hash[ss.timeslot] = ss # for ts in alltimeslots: # if not (ts in ts_hash): -# ScheduledSession.objects.create(schedule = sched, +# SchedTimeSessAssignment.objects.create(schedule = sched, # timeslot = ts) def vtimezone(self): @@ -297,7 +297,7 @@ class Room(models.Model): def delete_timeslots(self): for ts in self.timeslot_set.all(): - ts.scheduledsession_set.all().delete() + ts.sessionassignments.all().delete() ts.delete() def create_timeslots(self): @@ -339,14 +339,14 @@ class TimeSlot(models.Model): duration = TimedeltaField() location = models.ForeignKey(Room, blank=True, null=True) show_location = models.BooleanField(default=True, help_text="Show location in agenda.") - sessions = models.ManyToManyField('Session', related_name='slots', through='ScheduledSession', null=True, blank=True, help_text=u"Scheduled session, if any.") + sessions = models.ManyToManyField('Session', related_name='slots', through='SchedTimeSessAssignment', null=True, blank=True, help_text=u"Scheduled session, if any.") modified = models.DateTimeField(default=datetime.datetime.now) # @property def session(self): if not hasattr(self, "_session_cache"): - self._session_cache = self.sessions.filter(scheduledsession__schedule=self.meeting.agenda).first() + self._session_cache = self.sessions.filter(timeslotassignments__schedule=self.meeting.agenda).first() return self._session_cache @property @@ -486,7 +486,7 @@ class TimeSlot(models.Model): # now remove any schedule that might have been made to this # timeslot. - ts.scheduledsession_set.all().delete() + ts.sessionassignments.all().delete() ts.delete() """ @@ -527,11 +527,11 @@ class Schedule(models.Model): def base_url(self): return "/meeting/%s/agenda/%s/%s" % (self.meeting.number, self.owner_email(), self.name) - # temporary property to pacify the places where Schedule.scheduledsession_set is used - @property - def scheduledsession_set(self): - return self.assignments - + # temporary property to pacify the places where Schedule.assignments is used +# @property +# def schedtimesessassignment_set(self): +# return self.assignments +# # def url_edit(self): # return "/meeting/%s/agenda/%s/edit" % (self.meeting.number, self.name) # @@ -571,7 +571,7 @@ class Schedule(models.Model): else: return "agenda_unofficial" - # returns a dictionary {group -> [scheduledsession+]} + # returns a dictionary {group -> [schedtimesessassignment+]} # and it has [] if the session is not placed. # if there is more than one session for that group, # then a list of them is returned (always a list) @@ -582,8 +582,8 @@ class Schedule(models.Model): else: return "unofficial" - def delete_scheduledsessions(self): - self.scheduledsession_set.all().delete() + def delete_assignments(self): + self.assignments.all().delete() def json_url(self): return "%s.json" % self.base_url() @@ -601,12 +601,12 @@ class Schedule(models.Model): else: sch['public'] = "private" sch['owner'] = urljoin(host_scheme, self.owner.json_url()) - # should include href to list of scheduledsessions, but they have no direct API yet. + # should include href to list of assignments, but they have no direct API yet. return sch @property - def qs_scheduledsessions_with_assignments(self): - return self.scheduledsession_set.filter(session__isnull=False) + def qs_assignments_with_sessions(self): + return self.assignments.filter(session__isnull=False) @property def group_mapping(self): @@ -619,7 +619,7 @@ class Schedule(models.Model): sessions = dict() total = 0 scheduled = 0 - allschedsessions = self.qs_scheduledsessions_with_assignments.filter(timeslot__type = "session").all() + allschedsessions = self.qs_assignments_with_sessions.filter(timeslot__type = "session").all() for sess in self.meeting.sessions_that_can_meet.all(): assignments[sess.group] = [] sessions[sess] = None @@ -653,20 +653,20 @@ class Schedule(models.Model): return badness def delete_schedule(self): - self.scheduledsession_set.all().delete() + self.assignments.all().delete() self.delete() -# to be renamed ScheduleTimeslotSessionAssignments (stsa) -class ScheduledSession(models.Model): +# to be renamed SchedTimeSessAssignments (stsa) +class SchedTimeSessAssignment(models.Model): """ This model provides an N:M relationship between Session and TimeSlot. Each relationship is attached to the named agenda, which is owned by a specific person/user. """ - timeslot = models.ForeignKey('TimeSlot', null=False, blank=False) - session = models.ForeignKey('Session', null=True, default=None, help_text=u"Scheduled session.") + timeslot = models.ForeignKey('TimeSlot', null=False, blank=False, related_name='sessionassignments') + session = models.ForeignKey('Session', null=True, default=None, related_name='timeslotassignments', help_text=u"Scheduled session.") 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.") + extendedfrom = models.ForeignKey('self', 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) @@ -675,7 +675,7 @@ class ScheduledSession(models.Model): class Meta: ordering = ["timeslot__time", "timeslot__type__slug", "session__group__parent__name", "session__group__acronym", "session__name", ] - # use to distinguish this from FakeScheduledSession in placement.py + # use to distinguish this from FakeSchedTimeSessAssignment in placement.py faked = "real" def __unicode__(self): @@ -694,7 +694,7 @@ class ScheduledSession(models.Model): def slot_to_the_right(self): s = self.timeslot.slot_to_the_right if s: - return self.schedule.scheduledsession_set.filter(timeslot=s).first() + return self.schedule.assignments.filter(timeslot=s).first() else: return None @@ -736,11 +736,11 @@ class ScheduledSession(models.Model): def json_dict(self, host_scheme): ss = dict() - ss['scheduledsession_id'] = self.id + ss['assignment_id'] = self.id ss['href'] = urljoin(host_scheme, self.json_url()) ss['timeslot_id'] = self.timeslot.id - efset = self.session.scheduledsession_set.filter(schedule=self.schedule).order_by("timeslot__time") + efset = self.session.timeslotassignments.filter(schedule=self.schedule).order_by("timeslot__time") if efset.count() > 1: # now we know that there is some work to do finding the extendedfrom_id. # loop through the list of items @@ -939,7 +939,7 @@ class Session(models.Model): ss0name = "(%s)" % self.status.name else: ss0name = "(unscheduled)" - ss = self.scheduledsession_set.filter(schedule=self.meeting.agenda).order_by('timeslot__time') + ss = self.timeslotassignments.filter(schedule=self.meeting.agenda).order_by('timeslot__time') if ss: ss0name = ','.join([x.timeslot.time.strftime("%a-%H%M") for x in ss]) return u"%s: %s %s %s" % (self.meeting, self.group.acronym, self.name, ss0name) @@ -967,11 +967,11 @@ class Session(models.Model): def reverse_constraints(self): return Constraint.objects.filter(target=self.group, meeting=self.meeting).order_by('name__name') - def scheduledsession_for_agenda(self, schedule): - return self.scheduledsession_set.filter(schedule=schedule)[0] + def timeslotassignment_for_agenda(self, schedule): + return self.timeslotassignments.filter(schedule=schedule)[0] - def official_scheduledsession(self): - return self.scheduledsession_for_agenda(self.meeting.agenda) + def official_timeslotassignment(self): + return self.timeslotassignment_for_agenda(self.meeting.agenda) def unique_constraints(self): global constraint_cache_uses, constraint_cache_initials diff --git a/ietf/meeting/placement.py b/ietf/meeting/placement.py index 495c33c67..1d1be967c 100644 --- a/ietf/meeting/placement.py +++ b/ietf/meeting/placement.py @@ -16,8 +16,8 @@ from datetime import datetime from django.db import models #from settings import BADNESS_UNPLACED, BADNESS_TOOSMALL_50, BADNESS_TOOSMALL_100, BADNESS_TOOBIG, BADNESS_MUCHTOOBIG -#from ietf.meeting.models import Schedule, ScheduledSession,TimeSlot,Room -from ietf.meeting.models import ScheduledSession +#from ietf.meeting.models import Schedule, SchedTimeSessAssignment,TimeSlot,Room +from ietf.meeting.models import SchedTimeSessAssignment from django.template.defaultfilters import slugify, date as date_format, time as time_format def do_prompt(): @@ -36,14 +36,14 @@ class ScheduleSlot(object): self.badness = None self.slotgroups = {} - # this is a partial copy of ScheduledSession's methods. Prune later. + # this is a partial copy of SchedTimeSessAssignment's methods. Prune later. #def __unicode__(self): # return u"%s [%s<->%s]" % (self.schedule, self.session, self.timeslot) # #def __str__(self): # return self.__unicode__() - def add_scheduledsession(self,fs): + def add_assignment(self,fs): self.slotgroups[fs] = fs def scheduled_session_pk(self, assignments): @@ -113,8 +113,8 @@ class UnplacedScheduleSlot(ScheduleSlot): def count(self): return len(self.unplaced_slot_numbers) - def add_scheduledsession(self,fs): - super(UnplacedScheduleSlot, self).add_scheduledsession(fs) + def add_assignment(self,fs): + super(UnplacedScheduleSlot, self).add_assignment(fs) #print "unplaced add: %s" % (fs.available_slot) self.unplaced_slot_numbers.append(fs.available_slot) @@ -126,7 +126,7 @@ class UnplacedScheduleSlot(ScheduleSlot): del self.unplaced_slot_numbers[0] -class FakeScheduledSession(object): +class FakeSchedTimeSessAssignment(object): """ This model provides a fake (not-backed by database) N:M relationship between Session and TimeSlot, but in this case TimeSlot is always None, because the @@ -147,7 +147,7 @@ class FakeScheduledSession(object): self.pinned = False self.scheduleslot = None - def fromScheduledSession(self, ss): # or from another FakeScheduledSession + def fromSchedTimeSessAssignment(self, ss): # or from another FakeSchedTimeSessAssignment self.session = ss.session self.schedule = ss.schedule self.timeslot = ss.timeslot @@ -158,7 +158,7 @@ class FakeScheduledSession(object): def save(self): pass - # this is a partial copy of ScheduledSession's methods. Prune later. + # this is a partial copy of SchedTimeSessAssignment's methods. Prune later. def __unicode__(self): return u"%s [%s<->%s]" % (self.schedule, self.session, self.timeslot) @@ -254,7 +254,7 @@ class FakeScheduledSession(object): def json_dict(self, selfurl): ss = dict() - ss['scheduledsession_id'] = self.id + ss['assignment_id'] = self.id #ss['href'] = self.url(sitefqdn) ss['empty'] = self.empty_str ss['timeslot_id'] = self.timeslot.id @@ -324,13 +324,13 @@ class CurrentScheduleState: if time_column is not None: # needs available_slot to be filled in - time_column.add_scheduledsession(fs) + time_column.add_assignment(fs) #print "adding item: %u to unplaced slots (pinned: %s)" % (fs.available_slot, fs.pinned) def __init__(self, schedule, seed=None): # initialize available_slots with the places that a session can go based upon the - # scheduledsession objects of the provided schedule. - # for each session which is not initially scheduled, also create a scheduledsession + # schedtimesessassignment objects of the provided schedule. + # for each session which is not initially scheduled, also create a schedtimesessassignment # that has a session, but no timeslot. self.recordsteps = True @@ -339,7 +339,7 @@ class CurrentScheduleState: self.lastSaveStep = 0 self.verbose = False - # this maps a *group* to a list of (session,location) pairs, using FakeScheduledSession + # this maps a *group* to a list of (session,location) pairs, using FakeSchedTimeSessAssignment self.current_assignments = {} self.tempdict = {} # used when calculating badness. @@ -368,14 +368,14 @@ class CurrentScheduleState: for timeslot in schedule.meeting.timeslot_set.filter(type = "session").all(): if not timeslot.time in self.timeslots: self.timeslots[timeslot.time] = ScheduleSlot(timeslot.time) - fs = FakeScheduledSession(self.schedule) + fs = FakeSchedTimeSessAssignment(self.schedule) fs.timeslot = timeslot self.add_to_available_slot(fs) self.timeslots[None] = self.unplaced_scheduledslots # make list of things that need placement. for sess in self.meeting.sessions_that_can_be_placed().all(): - fs = FakeScheduledSession(self.schedule) + fs = FakeSchedTimeSessAssignment(self.schedule) fs.session = sess self.sessions[sess] = fs self.current_assignments[sess.group] = [] @@ -383,16 +383,16 @@ class CurrentScheduleState: #print "Then had %u" % (self.total_slots) # now find slots that are not empty. # loop here and the one for useableslots could be merged into one loop - allschedsessions = self.schedule.qs_scheduledsessions_with_assignments.filter(timeslot__type = "session").all() + allschedsessions = self.schedule.qs_assignments_with_sessions.filter(timeslot__type = "session").all() for ss in allschedsessions: # do not need to check for ss.session is not none, because filter above only returns those ones. sess = ss.session if not (sess in self.sessions): #print "Had to create sess for %s" % (sess) - self.sessions[sess] = FakeScheduledSession(self.schedule) + self.sessions[sess] = FakeSchedTimeSessAssignment(self.schedule) fs = self.sessions[sess] #print "Updating %s from %s(%s)" % (fs.session.group.acronym, ss.timeslot.location.name, ss.timeslot.time) - fs.fromScheduledSession(ss) + fs.fromSchedTimeSessAssignment(ss) # if pinned, then do not consider it when selecting, but it needs to be in # current_assignments so that conflicts are calculated. @@ -406,7 +406,7 @@ class CurrentScheduleState: # need to remove any sessions that might have gotten through above, but are in non-session # places, otherwise these could otherwise appear to be unplaced. - allspecialsessions = self.schedule.qs_scheduledsessions_with_assignments.exclude(timeslot__type = "session").all() + allspecialsessions = self.schedule.qs_assignments_with_sessions.exclude(timeslot__type = "session").all() for ss in allspecialsessions: sess = ss.session if sess is None: @@ -693,7 +693,7 @@ class CurrentScheduleState: self.lastSaveStep = self.stepnum # first, remove all assignments in the schedule. - for ss in targetSchedule.scheduledsession_set.all(): + for ss in targetSchedule.assignments.all(): if ss.pinned: continue ss.delete() @@ -702,7 +702,7 @@ class CurrentScheduleState: for fs in self.available_slots: if fs is None: continue - ss = ScheduledSession(timeslot = fs.timeslot, + ss = SchedTimeSessAssignment(timeslot = fs.timeslot, schedule = targetSchedule, session = fs.session) ss.save() @@ -733,7 +733,7 @@ if False: class AutomaticScheduleStep(models.Model): schedule = models.ForeignKey('Schedule', null=False, blank=False, help_text=u"Who made this agenda.") session = models.ForeignKey('Session', null=True, default=None, help_text=u"Scheduled session involved.") - moved_from = models.ForeignKey('ScheduledSession', related_name="+", null=True, default=None, help_text=u"Where session was.") - moved_to = models.ForeignKey('ScheduledSession', related_name="+", null=True, default=None, help_text=u"Where session went.") + moved_from = models.ForeignKey('SchedTimeSessAssignment', related_name="+", null=True, default=None, help_text=u"Where session was.") + moved_to = models.ForeignKey('SchedTimeSessAssignment', related_name="+", null=True, default=None, help_text=u"Where session went.") stepnum = models.IntegerField(default=0, blank=True, null=True) diff --git a/ietf/meeting/resources.py b/ietf/meeting/resources.py index c81f55140..96150d69e 100644 --- a/ietf/meeting/resources.py +++ b/ietf/meeting/resources.py @@ -6,7 +6,7 @@ from tastypie.constants import ALL, ALL_WITH_RELATIONS from ietf import api from ietf.meeting.models import ( Meeting, ResourceAssociation, Constraint, Room, Schedule, Session, - TimeSlot, ScheduledSession, SessionPresentation ) + TimeSlot, SchedTimeSessAssignment, SessionPresentation ) from ietf.name.resources import MeetingTypeNameResource class MeetingResource(ModelResource): @@ -179,15 +179,15 @@ class TimeSlotResource(ModelResource): } api.meeting.register(TimeSlotResource()) -class ScheduledSessionResource(ModelResource): +class SchedTimeSessAssignmentResource(ModelResource): timeslot = ToOneField(TimeSlotResource, 'timeslot') session = ToOneField(SessionResource, 'session', null=True) schedule = ToOneField(ScheduleResource, 'schedule') - extendedfrom = ToOneField('ietf.meeting.resources.ScheduledSessionResource', 'extendedfrom', null=True) + extendedfrom = ToOneField('ietf.meeting.resources.SchedTimeSessAssignmentResource', 'extendedfrom', null=True) class Meta: - queryset = ScheduledSession.objects.all() + queryset = SchedTimeSessAssignment.objects.all() serializer = api.Serializer() - #resource_name = 'scheduledsession' + #resource_name = 'schedtimesessassignment' filtering = { "id": ALL, "modified": ALL, @@ -199,7 +199,7 @@ class ScheduledSessionResource(ModelResource): "schedule": ALL_WITH_RELATIONS, "extendedfrom": ALL_WITH_RELATIONS, } -api.meeting.register(ScheduledSessionResource()) +api.meeting.register(SchedTimeSessAssignmentResource()) diff --git a/ietf/meeting/test_data.py b/ietf/meeting/test_data.py index 0053eb558..ffe9fad0f 100644 --- a/ietf/meeting/test_data.py +++ b/ietf/meeting/test_data.py @@ -2,7 +2,7 @@ import datetime from ietf.doc.models import Document, State from ietf.group.models import Group -from ietf.meeting.models import Meeting, Room, TimeSlot, Session, Schedule, ScheduledSession, ResourceAssociation, SessionPresentation +from ietf.meeting.models import Meeting, Room, TimeSlot, Session, Schedule, SchedTimeSessAssignment, ResourceAssociation, SessionPresentation from ietf.name.models import RoomResourceName from ietf.person.models import Person from ietf.utils.test_data import make_test_data @@ -34,7 +34,7 @@ def make_meeting_test_data(): requested_duration=20, status_id="schedw", scheduled=datetime.datetime.now(),type_id="session") mars_session.resources = [projector] - ScheduledSession.objects.create(timeslot=slot, session=mars_session, schedule=schedule) + SchedTimeSessAssignment.objects.create(timeslot=slot, session=mars_session, schedule=schedule) # ames WG slot = TimeSlot.objects.create(meeting=meeting, type_id="session", duration=30 * 60, location=room, @@ -43,7 +43,7 @@ def make_meeting_test_data(): attendees=10, requested_by=system_person, requested_duration=20, status_id="schedw", scheduled=datetime.datetime.now(),type_id="session") - ScheduledSession.objects.create(timeslot=slot, session=ames_session, schedule=schedule) + SchedTimeSessAssignment.objects.create(timeslot=slot, session=ames_session, schedule=schedule) # IESG breakfast breakfast_slot = TimeSlot.objects.create(meeting=meeting, type_id="lead", duration=90 * 60, @@ -54,7 +54,7 @@ def make_meeting_test_data(): attendees=25, requested_by=system_person, requested_duration=20, status_id="schedw", scheduled=datetime.datetime.now(),type_id="lead") - ScheduledSession.objects.create(timeslot=breakfast_slot, session=iesg_session, schedule=schedule) + SchedTimeSessAssignment.objects.create(timeslot=breakfast_slot, session=iesg_session, schedule=schedule) meeting.agenda = schedule meeting.save() diff --git a/ietf/meeting/tests_api.py b/ietf/meeting/tests_api.py index 5953c928b..3a39d2b32 100644 --- a/ietf/meeting/tests_api.py +++ b/ietf/meeting/tests_api.py @@ -5,7 +5,7 @@ from urlparse import urlsplit from django.core.urlresolvers import reverse as urlreverse from ietf.group.models import Group -from ietf.meeting.models import Schedule, TimeSlot, Session, ScheduledSession, Meeting, Constraint +from ietf.meeting.models import Schedule, TimeSlot, Session, SchedTimeSessAssignment, Meeting, Constraint from ietf.meeting.test_data import make_meeting_test_data from ietf.person.models import Person from ietf.utils.test_utils import TestCase @@ -19,35 +19,35 @@ class ApiTests(TestCase): mars_session = Session.objects.filter(meeting=meeting, group__acronym="mars").first() ames_session = Session.objects.filter(meeting=meeting, group__acronym="ames").first() - mars_scheduled = ScheduledSession.objects.get(session=mars_session) + mars_scheduled = SchedTimeSessAssignment.objects.get(session=mars_session) mars_slot = mars_scheduled.timeslot - ames_scheduled = ScheduledSession.objects.get(session=ames_session) + ames_scheduled = SchedTimeSessAssignment.objects.get(session=ames_session) ames_slot = ames_scheduled.timeslot - def do_unschedule(scheduledsession): - url = urlreverse("ietf.meeting.ajax.scheduledsession_json", - kwargs=dict(num=scheduledsession.session.meeting.number, - owner=scheduledsession.schedule.owner_email(), - name=scheduledsession.schedule.name, - scheduledsession_id=scheduledsession.pk,)) + def do_unschedule(assignment): + url = urlreverse("ietf.meeting.ajax.assignment_json", + kwargs=dict(num=assignment.session.meeting.number, + owner=assignment.schedule.owner_email(), + name=assignment.schedule.name, + assignment_id=assignment.pk,)) return self.client.delete(url) def do_schedule(schedule,session,timeslot): - url = urlreverse("ietf.meeting.ajax.scheduledsessions_json", + url = urlreverse("ietf.meeting.ajax.assignments_json", kwargs=dict(num=session.meeting.number, owner=schedule.owner_email(), name=schedule.name,)) post_data = '{ "session_id": "%s", "timeslot_id": "%s" }'%(session.pk,timeslot.pk) return self.client.post(url,post_data,content_type='application/x-www-form-urlencoded') - def do_extend(schedule,scheduledsession): - session = scheduledsession.session - url = urlreverse("ietf.meeting.ajax.scheduledsessions_json", + def do_extend(schedule, assignment): + session = assignment.session + url = urlreverse("ietf.meeting.ajax.assignments_json", kwargs=dict(num=session.meeting.number, owner=schedule.owner_email(), name=schedule.name,)) - post_data = '{ "session_id": "%s", "timeslot_id": "%s", "extendedfrom_id": "%s" }'%(session.pk,scheduledsession.timeslot.slot_to_the_right.pk,scheduledsession.pk) + post_data = '{ "session_id": "%s", "timeslot_id": "%s", "extendedfrom_id": "%s" }'%(session.pk,assignment.timeslot.slot_to_the_right.pk,assignment.pk) return self.client.post(url,post_data,content_type='application/x-www-form-urlencoded') @@ -56,7 +56,7 @@ class ApiTests(TestCase): # faulty delete r = do_unschedule(mars_scheduled) self.assertEqual(r.status_code, 403) - self.assertEqual(ScheduledSession.objects.get(pk=mars_scheduled.pk).session, mars_session) + self.assertEqual(SchedTimeSessAssignment.objects.get(pk=mars_scheduled.pk).session, mars_session) # faulty post r = do_schedule(schedule,ames_session,mars_slot) self.assertEqual(r.status_code, 403) @@ -88,16 +88,16 @@ class ApiTests(TestCase): r = do_extend(schedule,mars_scheduled) self.assertEqual(r.status_code, 201) self.assertTrue("error" not in json.loads(r.content)) - self.assertEqual(mars_session.scheduledsession_set.count(),2) + self.assertEqual(mars_session.timeslotassignments.count(),2) # Unschedule mars r = do_unschedule(mars_scheduled) self.assertEqual(r.status_code, 200) self.assertTrue("error" not in json.loads(r.content)) # Make sure it got both the original and extended session - self.assertEqual(mars_session.scheduledsession_set.count(),0) + self.assertEqual(mars_session.timeslotassignments.count(),0) - self.assertEqual(ScheduledSession.objects.get(session=ames_session).timeslot, mars_slot) + self.assertEqual(SchedTimeSessAssignment.objects.get(session=ames_session).timeslot, mars_slot) def test_constraints_json(self): @@ -204,15 +204,15 @@ class ApiTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) info = json.loads(r.content) - self.assertEqual(set([x['short_name'] for x in info]),set([s.session.short_name for s in meeting.agenda.scheduledsession_set.filter(session__type_id='session')])) + self.assertEqual(set([x['short_name'] for x in info]),set([s.session.short_name for s in meeting.agenda.assignments.filter(session__type_id='session')])) schedule = meeting.agenda - url = urlreverse("ietf.meeting.ajax.scheduledsessions_json", + url = urlreverse("ietf.meeting.ajax.assignments_json", kwargs=dict(num=meeting.number,owner=schedule.owner_email(),name=schedule.name)) r = self.client.get(url) self.assertEqual(r.status_code, 200) info = json.loads(r.content) - self.assertEqual(len(info),schedule.scheduledsession_set.count()) + self.assertEqual(len(info),schedule.assignments.count()) def test_slot_json(self): @@ -423,7 +423,7 @@ class ApiTests(TestCase): def test_update_timeslot_pinned(self): meeting = make_meeting_test_data() - scheduled = ScheduledSession.objects.filter( + scheduled = SchedTimeSessAssignment.objects.filter( session__meeting=meeting, session__group__acronym="mars").first() url = '/meeting/%s/agenda/%s/%s/session/%u.json' % (meeting.number, meeting.agenda.owner_email(), meeting.agenda.name, scheduled.pk) @@ -437,7 +437,7 @@ class ApiTests(TestCase): self.assertEqual(r.status_code, 403, "post to %s should have failed, no permission, got: %u/%s" % (url, r.status_code, r.content)) - self.assertTrue(not ScheduledSession.objects.get(pk=scheduled.pk).pinned) + self.assertTrue(not SchedTimeSessAssignment.objects.get(pk=scheduled.pk).pinned) # set pinned meeting.agenda.owner = Person.objects.get(user__username="secretary") @@ -451,7 +451,7 @@ class ApiTests(TestCase): self.assertEqual(r.status_code, 200, "post to %s should have worked, but got: %u/%s" % (url, r.status_code, r.content)) - self.assertTrue(ScheduledSession.objects.get(pk=scheduled.pk).pinned) + self.assertTrue(SchedTimeSessAssignment.objects.get(pk=scheduled.pk).pinned) class TimeSlotEditingApiTests(TestCase): diff --git a/ietf/meeting/tests_js.py b/ietf/meeting/tests_js.py index c7e9f3942..103f56a17 100644 --- a/ietf/meeting/tests_js.py +++ b/ietf/meeting/tests_js.py @@ -5,9 +5,11 @@ from unittest import skipIf from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.core.urlresolvers import reverse as urlreverse +import debug # pyflakes:ignore + from ietf.group import colors from ietf.meeting.test_data import make_meeting_test_data -from ietf.meeting.models import ScheduledSession +from ietf.meeting.models import SchedTimeSessAssignment from ietf import settings skip_selenium = getattr(settings,'SKIP_SELENIUM',None) @@ -52,7 +54,7 @@ class ScheduleEditTests(StaticLiveServerTestCase): def testUnschedule(self): - self.assertEqual(ScheduledSession.objects.filter(session__meeting__number=42,session__group__acronym='mars').count(),1) + self.assertEqual(SchedTimeSessAssignment.objects.filter(session__meeting__number=42,session__group__acronym='mars').count(),1) self.login() url = self.absreverse('ietf.meeting.views.edit_agenda',kwargs=dict(num='42',name='test-agenda',owner='plain@example.com')) @@ -69,7 +71,7 @@ class ScheduleEditTests(StaticLiveServerTestCase): self.assertTrue(len(q('#sortable-list #session_1'))>0) time.sleep(0.1) # The API that modifies the database runs async - self.assertEqual(ScheduledSession.objects.filter(session__meeting__number=42,session__group__acronym='mars').count(),0) + self.assertEqual(SchedTimeSessAssignment.objects.filter(session__meeting__number=42,session__group__acronym='mars').count(),0) # The following are useful debugging tools diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index 5f558c262..6a16cee5c 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -50,7 +50,7 @@ class MeetingTests(TestCase): def test_agenda(self): meeting = make_meeting_test_data() session = Session.objects.filter(meeting=meeting, group__acronym="mars").first() - slot = TimeSlot.objects.get(scheduledsession__session=session) + slot = TimeSlot.objects.get(sessionassignments__session=session) self.write_materials_files(meeting, session) @@ -215,7 +215,7 @@ class EditTests(TestCase): self.client.login(username="secretary", password="secretary+password") r = self.client.get(urlreverse("ietf.meeting.views.edit_agenda", kwargs=dict(num=meeting.number))) self.assertEqual(r.status_code, 200) - self.assertTrue("load_scheduledsessions" in r.content) + self.assertTrue("load_assignments" in r.content) def test_save_agenda_as_and_read_permissions(self): meeting = make_meeting_test_data() @@ -316,12 +316,12 @@ class EditTests(TestCase): def test_slot_to_the_right(self): meeting = make_meeting_test_data() session = Session.objects.filter(meeting=meeting, group__acronym="mars").first() - mars_scheduled = session.scheduledsession_set.get() - mars_slot = TimeSlot.objects.get(scheduledsession__session=session) + mars_scheduled = session.timeslotassignments.get() + mars_slot = TimeSlot.objects.get(sessionassignments__session=session) mars_ends = mars_slot.time + mars_slot.duration session = Session.objects.filter(meeting=meeting, group__acronym="ames").first() - ames_slot_qs = TimeSlot.objects.filter(scheduledsession__session=session) + ames_slot_qs = TimeSlot.objects.filter(sessionassignments__session=session) ames_slot_qs.update(time=mars_ends + datetime.timedelta(seconds=11 * 60)) self.assertTrue(not mars_slot.slot_to_the_right) diff --git a/ietf/meeting/urls.py b/ietf/meeting/urls.py index 8fce21cff..28f3bb5f5 100644 --- a/ietf/meeting/urls.py +++ b/ietf/meeting/urls.py @@ -25,8 +25,8 @@ urlpatterns = patterns('', (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+)/details$', views.edit_agenda_properties), (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+).(?P.html)?/?$', views.agenda), (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+)/permissions$', ajax.agenda_permission_api), - (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+)/session/(?P\d+).json$', ajax.scheduledsession_json), - (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+)/sessions.json$', ajax.scheduledsessions_json), + (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+)/session/(?P\d+).json$', ajax.assignment_json), + (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+)/sessions.json$', ajax.assignments_json), (r'^(?P\d+)/agenda/(?P[A-Za-z0-9-.+_]+@[A-Za-z0-9._]+)/(?P[A-Za-z0-9-:_]+).json$', ajax.agenda_infourl), (r'^(?P\d+)/agenda/edit$', views.edit_agenda), (r'^(?P\d+)/agenda(-utc)?(?P.html)?/?$', views.agenda), diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index b3eb6e3ea..98e3aa712 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -29,8 +29,8 @@ from ietf.ietfauth.utils import role_required, has_role from ietf.meeting.models import Meeting, Session, Schedule, Room from ietf.meeting.helpers import get_areas, get_person_by_email, get_schedule_by_name from ietf.meeting.helpers import build_all_agenda_slices, get_wg_name_list -from ietf.meeting.helpers import get_all_scheduledsessions_from_schedule -from ietf.meeting.helpers import get_modified_from_scheduledsessions +from ietf.meeting.helpers import get_all_assignments_from_schedule +from ietf.meeting.helpers import get_modified_from_assignments from ietf.meeting.helpers import get_wg_list, find_ads_for_meeting from ietf.meeting.helpers import get_meeting, get_schedule, agenda_permissions, meeting_updated from ietf.meeting.helpers import preprocess_assignments_for_agenda, read_agenda_file @@ -57,7 +57,7 @@ def materials(request, meeting_num=None): #sessions = Session.objects.filter(meeting__number=meeting_num, timeslot__isnull=False) schedule = get_schedule(meeting, None) - sessions = Session.objects.filter(meeting__number=meeting_num, scheduledsession__schedule=schedule).select_related() + sessions = Session.objects.filter(meeting__number=meeting_num, timeslotassignments__schedule=schedule).select_related() plenaries = sessions.filter(name__icontains='plenary') ietf = sessions.filter(group__parent__type__slug = 'area').exclude(group__acronym='edu') irtf = sessions.filter(group__parent__acronym = 'irtf') @@ -111,7 +111,7 @@ def agenda_create(request, num=None, owner=None, name=None): messages.info(request, "This name contains illegal characters. Please choose another one.") return redirect(edit_agenda, num=num, owner=owner, name=name) - # create the new schedule, and copy the scheduledsessions + # create the new schedule, and copy the assignments try: sched = meeting.schedule_set.get(name=savedname, owner=request.user.person) if sched: @@ -136,7 +136,7 @@ def agenda_create(request, num=None, owner=None, name=None): # keep a mapping so that extendedfrom references can be chased. mapping = {}; - for ss in schedule.scheduledsession_set.all(): + for ss in schedule.assignments.all(): # hack to copy the object, creating a new one # just reset the key, and save it again. oldid = ss.pk @@ -147,12 +147,12 @@ def agenda_create(request, num=None, owner=None, name=None): #print "Copying %u to %u" % (oldid, ss.pk) # now fix up any extendedfrom references to new set. - for ss in newschedule.scheduledsession_set.all(): + for ss in newschedule.assignments.all(): if ss.extendedfrom is not None: oldid = ss.extendedfrom.id newid = mapping[oldid] #print "Fixing %u to %u" % (oldid, newid) - ss.extendedfrom = newschedule.scheduledsession_set.get(pk = newid) + ss.extendedfrom = newschedule.assignments.get(pk = newid) ss.save() @@ -265,13 +265,13 @@ def edit_agenda(request, num=None, owner=None, name=None): "hide_menu": True }, status=403, content_type="text/html") - scheduledsessions = get_all_scheduledsessions_from_schedule(schedule) + assignments = get_all_assignments_from_schedule(schedule) # get_modified_from needs the query set, not the list - modified = get_modified_from_scheduledsessions(scheduledsessions) + modified = get_modified_from_assignments(assignments) area_list = get_areas() - wg_name_list = get_wg_name_list(scheduledsessions) + wg_name_list = get_wg_name_list(assignments) wg_list = get_wg_list(wg_name_list) ads = find_ads_for_meeting(meeting) for ad in ads: @@ -295,7 +295,7 @@ def edit_agenda(request, num=None, owner=None, name=None): "area_list": area_list, "area_directors" : ads, "wg_list": wg_list , - "scheduledsessions": scheduledsessions, + "assignments": assignments, "show_inline": set(["txt","htm","html"]), "hide_menu": True, }) @@ -494,9 +494,9 @@ 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'): + for day in schedule.assignments.dates('timeslot__time','day'): ss_by_day[day]=[] - for ss in schedule.scheduledsession_set.order_by('timeslot__location__functional_name','timeslot__location__name','timeslot__time'): + for ss in schedule.assignments.order_by('timeslot__location__functional_name','timeslot__location__name','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}) @@ -505,20 +505,20 @@ def agenda_by_room(request,num=None): def agenda_by_type(request,num=None,type=None): meeting = get_meeting(num) schedule = get_schedule(meeting) - scheduledsessions = schedule.scheduledsession_set.order_by('session__type__slug','timeslot__time') + assignments = schedule.assignments.order_by('session__type__slug','timeslot__time') if type: - scheduledsessions = scheduledsessions.filter(session__type__slug=type) - return render(request,"meeting/agenda_by_type.html",{"meeting":meeting,"scheduledsessions":scheduledsessions}) + assignments = assignments.filter(session__type__slug=type) + return render(request,"meeting/agenda_by_type.html",{"meeting":meeting,"assignments":assignments}) @role_required('Area Director','Secretariat','IAB') def agenda_by_type_ics(request,num=None,type=None): meeting = get_meeting(num) schedule = get_schedule(meeting) - scheduledsessions = schedule.scheduledsession_set.order_by('session__type__slug','timeslot__time') + assignments = schedule.assignments.order_by('session__type__slug','timeslot__time') if type: - scheduledsessions = scheduledsessions.filter(session__type__slug=type) + assignments = assignments.filter(session__type__slug=type) updated = meeting_updated(meeting) - return render(request,"meeting/agenda.ics",{"schedule":schedule,"updated":updated,"assignments":scheduledsessions},content_type="text/calendar") + return render(request,"meeting/agenda.ics",{"schedule":schedule,"updated":updated,"assignments":assignments},content_type="text/calendar") def session_agenda(request, num, session): d = Document.objects.filter(type="agenda", session__meeting__number=num) @@ -712,17 +712,17 @@ def room_view(request, num=None): if rooms.count() == 0: raise Http404 - scheduledsessions = meeting.agenda.scheduledsession_set.all() + assignments = meeting.agenda.assignments.all() unavailable = meeting.timeslot_set.filter(type__slug='unavail') - if (unavailable.count() + scheduledsessions.count()) == 0 : + if (unavailable.count() + assignments.count()) == 0 : raise Http404 earliest = None latest = None - if scheduledsessions: - earliest = scheduledsessions.aggregate(Min('timeslot__time'))['timeslot__time__min'] - latest = scheduledsessions.aggregate(Max('timeslot__time'))['timeslot__time__max'] + if assignments: + earliest = assignments.aggregate(Min('timeslot__time'))['timeslot__time__min'] + latest = assignments.aggregate(Max('timeslot__time'))['timeslot__time__max'] if unavailable: earliest_unavailable = unavailable.aggregate(Min('time'))['time__min'] @@ -749,13 +749,13 @@ def room_view(request, num=None): t.delta_from_beginning = (t.time - base_time).total_seconds() t.day = (t.time-base_day).days - scheduledsessions = list(scheduledsessions) - for ss in scheduledsessions: + assignments = list(assignments) + for ss in assignments: ss.delta_from_beginning = (ss.timeslot.time - base_time).total_seconds() ss.day = (ss.timeslot.time-base_day).days template = "meeting/room-view.html" - return render(request, template,{"meeting":meeting,"unavailable":unavailable,"scheduledsessions":scheduledsessions,"rooms":rooms,"days":days}) + return render(request, template,{"meeting":meeting,"unavailable":unavailable,"assignments":assignments,"rooms":rooms,"days":days}) def ical_agenda(request, num=None, name=None, ext=None): meeting = get_meeting(num) @@ -823,22 +823,22 @@ def session_details(request, num, acronym, date=None, week_day=None, seq=None): if date: if len(date)==15: start = datetime.datetime.strptime(date,"%Y-%m-%d-%H%M") - sessions = sessions.filter(scheduledsession__schedule=meeting.agenda,scheduledsession__timeslot__time=start) + sessions = sessions.filter(timeslotassignments__schedule=meeting.agenda,timeslotassignments__timeslot__time=start) else: start = datetime.datetime.strptime(date,"%Y-%m-%d").date() end = start+datetime.timedelta(days=1) - sessions = sessions.filter(scheduledsession__schedule=meeting.agenda,scheduledsession__timeslot__time__range=(start,end)) + sessions = sessions.filter(timeslotassignments__schedule=meeting.agenda,timeslotassignments__timeslot__time__range=(start,end)) if week_day: try: dow = ['sun','mon','tue','wed','thu','fri','sat'].index(week_day.lower()[:3]) + 1 except ValueError: raise Http404 - sessions = sessions.filter(scheduledsession__schedule=meeting.agenda,scheduledsession__timeslot__time__week_day=dow) + sessions = sessions.filter(timeslotassignments__schedule=meeting.agenda,timeslotassignments__timeslot__time__week_day=dow) def sort_key(session): - official_sessions = session.scheduledsession_set.filter(schedule=session.meeting.agenda) + official_sessions = session.timeslotassignments.filter(schedule=session.meeting.agenda) if official_sessions: return official_sessions.first().timeslot.time else: @@ -859,7 +859,7 @@ def session_details(request, num, acronym, date=None, week_day=None, seq=None): if len(sessions)==1: session = sessions[0] scheduled_time = "Not yet scheduled" - ss = session.scheduledsession_set.filter(schedule=meeting.agenda).order_by('timeslot__time') + ss = session.timeslotassignments.filter(schedule=meeting.agenda).order_by('timeslot__time') if ss: scheduled_time = ','.join(x.timeslot.time.strftime("%A %b-%d %H%M") for x in ss) # TODO FIXME Deleted materials shouldn't be in the sessionpresentation_set diff --git a/ietf/secr/meetings/forms.py b/ietf/secr/meetings/forms.py index 72a7774f1..6d4ba3aad 100644 --- a/ietf/secr/meetings/forms.py +++ b/ietf/secr/meetings/forms.py @@ -4,7 +4,7 @@ import re from django import forms from ietf.group.models import Group -from ietf.meeting.models import Meeting, Room, TimeSlot, Session, ScheduledSession +from ietf.meeting.models import Meeting, Room, TimeSlot, Session, SchedTimeSessAssignment from ietf.meeting.timedeltafield import TimedeltaFormField, TimedeltaWidget from ietf.name.models import TimeSlotTypeName @@ -63,9 +63,9 @@ class BaseMeetingRoomFormSet(forms.models.BaseInlineFormSet): '''Check that any rooms marked for deletion are not in use''' for form in self.deleted_forms: room = form.cleaned_data['id'] - scheduledsessions = ScheduledSession.objects.filter(timeslot__location=room, + schedtimesessassignments = SchedTimeSessAssignment.objects.filter(timeslot__location=room, session__isnull=False) - if scheduledsessions: + if schedtimesessassignments: raise forms.ValidationError('Cannot delete meeting room %s. Already assigned to some session.' % room.name) class TimeSlotModelChoiceField(forms.ModelChoiceField): diff --git a/ietf/secr/meetings/tests.py b/ietf/secr/meetings/tests.py index bc933d393..52869be71 100644 --- a/ietf/secr/meetings/tests.py +++ b/ietf/secr/meetings/tests.py @@ -8,7 +8,7 @@ from django.conf import settings from django.core.urlresolvers import reverse from ietf.group.models import Group, GroupEvent -from ietf.meeting.models import Meeting, Room, TimeSlot, ScheduledSession +from ietf.meeting.models import Meeting, Room, TimeSlot, SchedTimeSessAssignment from ietf.meeting.test_data import make_meeting_test_data from ietf.person.models import Person from ietf.utils.mail import outbox @@ -139,7 +139,7 @@ class MainTestCase(TestCase): person = Person.objects.get(name="(System)") GroupEvent.objects.create(group=mars_group,time=now,type='sent_notification', by=person,desc='sent scheduled notification for %s' % meeting) - ss = meeting.agenda.scheduledsession_set.get(session__group=ames_group) + ss = meeting.agenda.assignments.get(session__group=ames_group) ss.modified = then ss.save() self.client.login(username="secretary", password="secretary+password") @@ -173,7 +173,7 @@ class MainTestCase(TestCase): # test delete # first unschedule sessions so we can delete - ScheduledSession.objects.filter(schedule=meeting.agenda).delete() + SchedTimeSessAssignment.objects.filter(schedule=meeting.agenda).delete() self.client.login(username="secretary", password="secretary+password") post_dict = { 'room-TOTAL_FORMS': q('input[name="room-TOTAL_FORMS"]').val(), diff --git a/ietf/secr/meetings/views.py b/ietf/secr/meetings/views.py index 24ecdb78e..6366f7b58 100644 --- a/ietf/secr/meetings/views.py +++ b/ietf/secr/meetings/views.py @@ -17,7 +17,7 @@ from django.utils.functional import curry from ietf.ietfauth.utils import role_required from ietf.utils.mail import send_mail from ietf.meeting.helpers import get_meeting -from ietf.meeting.models import Meeting, Session, Room, TimeSlot, ScheduledSession, Schedule +from ietf.meeting.models import Meeting, Session, Room, TimeSlot, SchedTimeSessAssignment, Schedule from ietf.group.models import Group, GroupEvent from ietf.person.models import Person from ietf.secr.meetings.blue_sheets import create_blue_sheets @@ -41,7 +41,7 @@ def assign(session,timeslot,meeting,schedule=None): ''' if schedule == None: schedule = meeting.agenda - ScheduledSession.objects.create(schedule=schedule, + SchedTimeSessAssignment.objects.create(schedule=schedule, session=session, timeslot=timeslot) session.status_id = 'sched' @@ -132,11 +132,11 @@ def build_nonsession(meeting,schedule): duration=slot.duration, show_location=slot.show_location) if session: - ScheduledSession.objects.create(schedule=schedule,session=session,timeslot=ts) + SchedTimeSessAssignment.objects.create(schedule=schedule,session=session,timeslot=ts) def check_nonsession(meeting,schedule): ''' - Ensure non-session timeslots exist and have appropriate ScheduledSession objects + Ensure non-session timeslots exist and have appropriate SchedTimeSessAssignment objects for the specified schedule. ''' slots = TimeSlot.objects.filter(meeting=meeting,type__in=('break','reg','other','plenary','lead','offagenda')) @@ -146,18 +146,18 @@ def check_nonsession(meeting,schedule): plenary = slots.filter(type='plenary').first() if plenary: - scheduledsessions = plenary.scheduledsession_set.all() - if not scheduledsessions.filter(schedule=schedule): - source = scheduledsessions.first().schedule - copy_scheduledsessions(slots,source,schedule) + assignments = plenary.sessionassignments.all() + if not assignments.filter(schedule=schedule): + source = assignments.first().schedule + copy_assignments(slots,source,schedule) -def copy_scheduledsessions(slots,source,target): +def copy_assignments(slots,source,target): ''' - Copy scheduledsession objects from source schedule to target schedule. Slots is + Copy SchedTimeSessAssignment objects from source schedule to target schedule. Slots is a queryset of slots ''' - for ss in ScheduledSession.objects.filter(schedule=source,timeslot__in=slots): - ScheduledSession.objects.create(schedule=target,session=ss.session,timeslot=ss.timeslot) + for ss in SchedTimeSessAssignment.objects.filter(schedule=source,timeslot__in=slots): + SchedTimeSessAssignment.objects.create(schedule=target,session=ss.session,timeslot=ss.timeslot) def get_last_meeting(meeting): last_number = int(meeting.number) - 1 @@ -172,7 +172,7 @@ def is_combined(session,meeting,schedule=None): ''' if schedule == None: schedule = meeting.agenda - if session.scheduledsession_set.filter(schedule=schedule).count() > 1: + if session.timeslotassignments.filter(schedule=schedule).count() > 1: return True else: return False @@ -248,7 +248,7 @@ def sort_groups(meeting,schedule=None): groups_with_sessions = [ s.group for s in sessions ] gset = set(groups_with_sessions) sorted_groups_with_sessions = sorted(gset, key = lambda instance: instance.acronym) - scheduled_sessions = ScheduledSession.objects.filter(schedule=schedule,session__isnull=False) + scheduled_sessions = SchedTimeSessAssignment.objects.filter(schedule=schedule,session__isnull=False) groups_with_timeslots = [ x.session.group for x in scheduled_sessions ] for group in sorted_groups_with_sessions: if group in groups_with_timeslots: @@ -492,7 +492,7 @@ def non_session(request, meeting_id, schedule_name): session.save() # create association - ScheduledSession.objects.create(timeslot=timeslot, + SchedTimeSessAssignment.objects.create(timeslot=timeslot, session=session, schedule=schedule) @@ -517,14 +517,14 @@ def non_session_delete(request, meeting_id, schedule_name, slot_id): ''' This function deletes the non-session TimeSlot. For "other" and "plenary" timeslot types we need to delete the corresponding Session object as well. Check for uploaded - material first. ScheduledSession objects get deleted as well. + material first. SchedTimeSessAssignment objects get deleted as well. ''' meeting = get_object_or_404(Meeting, number=meeting_id) # schedule = get_object_or_404(Schedule, meeting=meeting, name=schedule_name) slot = get_object_or_404(TimeSlot, id=slot_id) if slot.type_id in ('other','plenary','lead'): - scheduledsessions = slot.scheduledsession_set.filter(schedule__meeting=meeting) - session_objects = [ x.session for x in scheduledsessions ] + assignments = slot.sessionassignments.filter(schedule__meeting=meeting) + session_objects = [ x.session for x in assignments ] for session in session_objects: if session.materials.exclude(states__slug='deleted'): messages.error(request, 'Materials have already been uploaded for "%s". You must delete those before deleting the timeslot.' % slot.name) @@ -595,7 +595,7 @@ def notifications(request, meeting_id): meeting = get_object_or_404(Meeting, number=meeting_id) last_notice = GroupEvent.objects.filter(type='sent_notification').first() groups = set() - for ss in meeting.agenda.scheduledsession_set.filter(timeslot__type='session'): + for ss in meeting.agenda.assignments.filter(timeslot__type='session'): last_notice = ss.session.group.latest_event(type='sent_notification') if last_notice and ss.modified > last_notice.time: groups.add(ss.session.group) @@ -604,7 +604,7 @@ def notifications(request, meeting_id): if request.method == "POST": # ensure session state is scheduled - for ss in meeting.agenda.scheduledsession_set.all(): + for ss in meeting.agenda.assignments.all(): session = ss.session if session.status.slug == "schedw": session.status_id = "sched" @@ -635,7 +635,7 @@ def remove_session(request, meeting_id, acronym): now = datetime.datetime.now() for session in sessions: - ss = session.official_scheduledsession() + ss = session.official_timeslotassignment() ss.session = None ss.modified = now ss.save() @@ -756,15 +756,15 @@ def schedule(request, meeting_id, schedule_name, acronym): # COMBINE SECTION - BEFORE -------------- if 'combine' in form.changed_data and not combine: next_slot = get_next_slot(initial_timeslot) - for ss in next_slot.scheduledsession_set.filter(schedule=schedule,session=session): + for ss in next_slot.sessionassignments.filter(schedule=schedule,session=session): ss.session = None ss.save() # --------------------------------------- if any(x in form.changed_data for x in ('day','time','room')): # clear the old association if initial_timeslot: - # delete scheduledsession records to unschedule - session.scheduledsession_set.filter(schedule=schedule).delete() + # delete schedtimesessassignment records to unschedule + session.timeslotassignments.filter(schedule=schedule).delete() if timeslot: assign(session,timeslot,meeting,schedule=schedule) @@ -1009,7 +1009,7 @@ def unschedule(request, meeting_id, schedule_name, session_id): meeting = get_object_or_404(Meeting, number=meeting_id) session = get_object_or_404(Session, id=session_id) - session.scheduledsession_set.filter(schedule=meeting.agenda).delete() + session.timeslotassignments.filter(schedule=meeting.agenda).delete() # TODO: change session state? diff --git a/ietf/secr/proceedings/proc_utils.py b/ietf/secr/proceedings/proc_utils.py index d6bbe66c2..70c9296ae 100644 --- a/ietf/secr/proceedings/proc_utils.py +++ b/ietf/secr/proceedings/proc_utils.py @@ -16,7 +16,7 @@ from ietf.doc.models import Document, RelatedDocument, DocEvent, NewRevisionDocE from ietf.group.models import Group, Role from ietf.group.utils import get_charter_text from ietf.meeting.helpers import get_schedule -from ietf.meeting.models import Session, Meeting, ScheduledSession, SessionPresentation +from ietf.meeting.models import Session, Meeting, SchedTimeSessAssignment, SessionPresentation from ietf.person.models import Person from ietf.secr.proceedings.models import InterimMeeting # proxy model from ietf.secr.proceedings.models import Registration @@ -38,7 +38,7 @@ def check_audio_files(group,meeting): ''' for session in Session.objects.filter(group=group,meeting=meeting,status__in=('sched','schedw')): try: - timeslot = session.official_scheduledsession().timeslot + timeslot = session.official_timeslotassignment().timeslot except IndexError: continue if not (timeslot.location and timeslot.time): @@ -63,7 +63,7 @@ def create_recording(session,meeting,group,url): ''' sequence = get_next_sequence(group,meeting,'recording') name = 'recording-{}-{}-{}'.format(meeting.number,group.acronym,sequence) - time = session.official_scheduledsession().timeslot.time.strftime('%Y-%m-%d %H:%M') + time = session.official_timeslotassignment().timeslot.time.strftime('%Y-%m-%d %H:%M') if url.endswith('mp3'): title = 'Audio recording for {}'.format(time) else: @@ -434,11 +434,11 @@ def gen_acknowledgement(context): def gen_agenda(context): meeting = context['meeting'] schedule = get_schedule(meeting) - scheduledsessions = ScheduledSession.objects.filter(schedule=schedule).exclude(session__isnull=True) + schedtimesessassignments = SchedTimeSessAssignment.objects.filter(schedule=schedule).exclude(session__isnull=True) html = render_to_response('proceedings/agenda.html',{ 'meeting': meeting, - 'scheduledsessions': scheduledsessions} + 'schedtimesessassignments': schedtimesessassignments} ) path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'agenda.html') diff --git a/ietf/secr/proceedings/views.py b/ietf/secr/proceedings/views.py index d25bc5a2f..4ab2ef51f 100644 --- a/ietf/secr/proceedings/views.py +++ b/ietf/secr/proceedings/views.py @@ -26,7 +26,7 @@ from ietf.secr.utils.meeting import get_upload_root, get_materials, get_timeslot from ietf.doc.models import Document, DocAlias, DocEvent, State, NewRevisionDocEvent from ietf.group.models import Group from ietf.ietfauth.utils import has_role, role_required -from ietf.meeting.models import Meeting, Session, TimeSlot, ScheduledSession +from ietf.meeting.models import Meeting, Session, TimeSlot, SchedTimeSessAssignment from ietf.secr.proceedings.forms import EditSlideForm, InterimMeetingForm, RecordingForm, RecordingEditForm, ReplaceSlideForm, UnifiedUploadForm from ietf.secr.proceedings.proc_utils import ( gen_acknowledgement, gen_agenda, gen_areas, gen_attendees, gen_group_pages, gen_index, gen_irtf, gen_overview, gen_plenaries, @@ -279,10 +279,10 @@ def ajax_get_sessions(request, meeting_num, acronym): sessions = Session.objects.filter(meeting=meeting,group=group,status='sched') # order by time scheduled - sessions = sorted(sessions,key = lambda x: x.official_scheduledsession().timeslot.time) + sessions = sorted(sessions,key = lambda x: x.official_timeslotassignment().timeslot.time) for n,session in enumerate(sessions,start=1): - timeslot = session.official_scheduledsession().timeslot + timeslot = session.official_timeslotassignment().timeslot val = '{}: {} {}'.format(n,timeslot.time.strftime('%m-%d %H:%M'),timeslot.location.name) d = {'id':session.id, 'value': val} results.append(d) @@ -793,7 +793,7 @@ def select(request, meeting_num): # iniialize plenary form if has_role(user,['Secretariat','IETF Chair','IAB Chair']): - ss = ScheduledSession.objects.filter(schedule=meeting.agenda,timeslot__type='plenary') + ss = SchedTimeSessAssignment.objects.filter(schedule=meeting.agenda,timeslot__type='plenary') choices = [ (i.session.id, i.session.name) for i in sorted(ss,key=lambda x: x.session.name) ] plenary_form = GroupSelectForm(choices=choices) else: diff --git a/ietf/secr/sreq/views.py b/ietf/secr/sreq/views.py index 734f515b0..0bf47be9a 100644 --- a/ietf/secr/sreq/views.py +++ b/ietf/secr/sreq/views.py @@ -204,7 +204,7 @@ def cancel(request, acronym): session_save(session) # clear schedule assignments if already scheduled - session.scheduledsession_set.all().delete() + session.timeslotassignments.all().delete() # send notifitcation (to_email, cc_list) = gather_address_lists('session_request_cancelled',group=group,person=login) diff --git a/ietf/secr/utils/meeting.py b/ietf/secr/utils/meeting.py index 8c78bd7c7..2d95964be 100644 --- a/ietf/secr/utils/meeting.py +++ b/ietf/secr/utils/meeting.py @@ -52,7 +52,7 @@ def get_session(timeslot, schedule=None): # todo, doesn't account for shared timeslot if not schedule: schedule = timeslot.meeting.agenda - qs = timeslot.sessions.filter(scheduledsession__schedule=schedule) #.exclude(states__slug='deleted') + qs = timeslot.sessions.filter(timeslotassignments__schedule=schedule) #.exclude(states__slug='deleted') if qs: return qs[0] else: @@ -66,7 +66,7 @@ def get_timeslot(session, schedule=None): ''' if not schedule: schedule = session.meeting.agenda - ss = session.scheduledsession_set.filter(schedule=schedule) + ss = session.timeslotassignments.filter(schedule=schedule) if ss: return ss[0].timeslot else: @@ -83,4 +83,4 @@ def get_upload_root(meeting): meeting.date.strftime('%m'), meeting.date.strftime('%d'), meeting.session_set.all()[0].group.acronym) - return path \ No newline at end of file + return path diff --git a/ietf/static/ietf/js/agenda/agenda_edit.js b/ietf/static/ietf/js/agenda/agenda_edit.js index aa018bee3..81bc58692 100644 --- a/ietf/static/ietf/js/agenda/agenda_edit.js +++ b/ietf/static/ietf/js/agenda/agenda_edit.js @@ -24,7 +24,7 @@ //var schedule_id = 0; // what is the schedule we are editing. //var schedule_name; // what is the schedule we are editing. //var schedule_owner_href = ''; // who owns this schedule -//var scheduledsession_post_href; +//var assignments_post_href; //var meeting_base_url; //var site_base_url; //var total_rooms = 0; // the number of rooms @@ -88,7 +88,7 @@ function initStuff(){ $.when.apply($,directorpromises).done(function() { /* can not load events until area director info, - timeslots, sessions, and scheduledsessions + timeslots, sessions, and assignments have been loaded */ log("loading/linking objects"); @@ -174,9 +174,6 @@ function read_only_check() { function print_all_ss(objs){ console.log(objs) } -function get_ss(){ - Dajaxice.ietf.meeting.get_scheduledsessions(print_all_ss); -} /* diff --git a/ietf/static/ietf/js/agenda/agenda_helpers.js b/ietf/static/ietf/js/agenda/agenda_helpers.js index c132496a0..3e78ca8f6 100644 --- a/ietf/static/ietf/js/agenda/agenda_helpers.js +++ b/ietf/static/ietf/js/agenda/agenda_helpers.js @@ -123,7 +123,7 @@ function load_events(){ if(ssid.extendedfrom_id != false) { other = agenda_globals.slot_objs[ssid.extendedfrom_id]; if(__debug_load_events) { - console.log("slot:",ssid.scheduledsession_id, "extended from: ",key,ssid.extendedfrom_id); // ," is: ", other); + console.log("slot:",ssid.assignment_id, "extended from: ",key,ssid.extendedfrom_id); // ," is: ", other); } if(other != undefined) { ssid.extendedfrom = other; diff --git a/ietf/static/ietf/js/agenda/agenda_listeners.js b/ietf/static/ietf/js/agenda/agenda_listeners.js index e36fa4876..f5bee200f 100644 --- a/ietf/static/ietf/js/agenda/agenda_listeners.js +++ b/ietf/static/ietf/js/agenda/agenda_listeners.js @@ -290,7 +290,7 @@ function extend_slot(event) { session = last_session; - console.log("session", session.title, "sslot:", current_scheduledslot.scheduledsession_id); + console.log("session", session.title, "sslot:", current_scheduledslot.assignment_id); /* bind current_timeslot into this function and continuations */ var slot = current_timeslot; @@ -305,10 +305,10 @@ function extend_slot(event) { buttons: { "Yes": { click: function() { - // need to create new scheduledsession + // need to create new assignment var new_ss = make_ss({ "session_id" : session.session_id, "timeslot_id": slot.following_timeslot.timeslot_id, - "extendedfrom_id" : current_scheduledslot.scheduledsession_id}); + "extendedfrom_id" : current_scheduledslot.assignment_id}); // make_ss also adds to slot_status. new_ss.saveit(); @@ -571,7 +571,7 @@ function select_session(session) { if(current_timeslot) { current_timeslot_id = current_timeslot.timeslot_id; } - current_scheduledslot = session.scheduledsession; + current_scheduledslot = session.assignment; if(__debug_meeting_click) { console.log("2 meeting_click:", current_timeslot, session); } @@ -698,13 +698,13 @@ function info_name_select_change(){ console.log("selecting new item:", last_session.title); } -function set_pin_session_button(scheduledsession) { +function set_pin_session_button(assignment) { $("#pin_slot").unbind('click'); - if(scheduledsession == undefined) { - console.log("pin not set, scheduledsession undefined"); + if(assignment == undefined) { + console.log("pin not set, assignment undefined"); return; } - state = scheduledsession.pinned; + state = assignment.pinned; //console.log("button set to: ",state); $("#pin_slot").attr('disabled',false); if(state) { @@ -712,24 +712,24 @@ function set_pin_session_button(scheduledsession) { $("#agenda_pin_slot").addClass("button_down"); $("#agenda_pin_slot").removeClass("button_up"); $("#pin_slot").click(function(event) { - update_pin_session(scheduledsession, false); + update_pin_session(assignment, false); }); } else { $("#pin_slot").html(" Pin "); $("#agenda_pin_slot").addClass("button_up"); $("#agenda_pin_slot").removeClass("button_down"); $("#pin_slot").click(function(event) { - update_pin_session(scheduledsession, true); + update_pin_session(assignment, true); }); } } -function update_pin_session(scheduledsession, state) { +function update_pin_session(assignment, state) { start_spin(); - scheduledsession.set_pinned(state, function(schedulesession) { + assignment.set_pinned(state, function(assignment) { stop_spin(); - session.repopulate_event(scheduledsession.domid()); - set_pin_session_button(scheduledsession); + session.repopulate_event(assignment.domid()); + set_pin_session_button(assignment); }); } @@ -774,7 +774,7 @@ function fill_in_session_info(session, success, extra) { $("#agenda_pin_slot").removeClass("button_disabled"); $("#agenda_pin_slot").addClass("button_enabled"); - set_pin_session_button(session.scheduledsession); + set_pin_session_button(session.assignment); } else { $("#pin_slot").unbind('click'); } @@ -977,7 +977,7 @@ function update_to_slot(session_id, to_slot_id, force){ var to_timeslot = agenda_globals.timeslot_bydomid[to_slot_id]; if(to_timeslot != undefined && (to_timeslot.empty == true || force)) { - // add a new scheduledsession for this, save it. + // add a new assignment for this, save it. var new_ss = make_ss({ "session_id" : session_id, "timeslot_id": to_timeslot.timeslot_id}); // make_ss also adds to slot_status. @@ -1001,7 +1001,7 @@ function update_from_slot(session_id, from_slot_id) { var from_timeslot = agenda_globals.timeslot_bydomid[from_slot_id]; - /* this is a list of scheduledsessions */ + /* this is a list of schedule-timeslot-session-assignments */ var from_scheduledslots = agenda_globals.slot_status[from_slot_id]; var delete_promises = []; diff --git a/ietf/static/ietf/js/agenda/agenda_objects.js b/ietf/static/ietf/js/agenda/agenda_objects.js index 7f2f728b7..c5b57496a 100644 --- a/ietf/static/ietf/js/agenda/agenda_objects.js +++ b/ietf/static/ietf/js/agenda/agenda_objects.js @@ -28,7 +28,7 @@ function AgendaGlobals() { this.sessions_objs = {}; this.timeslot_bydomid = {}; this.timeslot_byid = {}; - this.scheduledsession_promise = undefined; + this.assignment_promise = undefined; this.timeslot_promise = undefined; this.__debug_session_move = false; } @@ -318,7 +318,7 @@ function TimeSlot(){ this.date = undefined; this.domid = undefined; this.empty = true; - this.scheduledsessions = []; + this.assignments = []; this.following_timeslot_id = undefined; this.unscheduled_box = false; } @@ -420,13 +420,13 @@ function load_timeslots(href) { // ++++++++++++++++++ // ScheduledSlot Object -// ScheduledSession is DJANGO name for this object, but needs to be renamed. +// SchedTimeSessAssignment is the DJANGO name for this object // It represents a TimeSlot that can be assigned in this schedule. -// { "scheduledsession_id": "{{s.id}}", +// { "assignment_id": "{{s.id}}", // "href: "{{s.href}}", // "timeslot_id":"{{s.timeslot.id}}", // "session_id" :"{{s.session.id}}", -// "extendedfrom_id" :refers to another scheduledsession by ss.id +// "extendedfrom_id" :refers to another schedtimesessassignment by ss.id function ScheduledSlot(){ this.extendedfrom = undefined; this.extendedto = undefined; @@ -469,7 +469,7 @@ ScheduledSlot.prototype.saveit = function() { var stuff = JSON.stringify(stuffjson, null, '\t'); - var saveit = $.ajax(scheduledsession_post_href,{ + var saveit = $.ajax(assignments_post_href,{ "content-type": "text/json", "type": "POST", "data": stuff, @@ -518,7 +518,7 @@ function remove_from_slot_status(domid, ss_id) { if(agenda_globals.__debug_session_move) { console.log(" checking", index, value, ss_id); } - if(value.scheduledsession_id == ss_id) { + if(value.assignment_id == ss_id) { found_at = index; return; } @@ -539,8 +539,8 @@ ScheduledSlot.prototype.deleteit = function() { }); // now nuke self! var me = this; - delete agenda_globals.slot_objs[this.scheduledsession_id]; - remove_from_slot_status(this.domid(), this.scheduledsession_id); + delete agenda_globals.slot_objs[this.assignment_id]; + remove_from_slot_status(this.domid(), this.assignment_id); return deleteit; }; @@ -553,7 +553,7 @@ function update_if_not_undefined(old, newval) { } ScheduledSlot.prototype.make_unassigned = function() { - this.scheduledsession_id = 0; + this.assignment_id = 0; this.empty = true; this.session_id = null; this.room = "unassigned"; @@ -567,13 +567,13 @@ ScheduledSlot.prototype.make_unassigned = function() { agenda_globals.slot_status[this.domid()]=[]; agenda_globals.slot_status[this.domid()].push(this); - agenda_globals.slot_objs[this.scheduledsession_id] = this; + agenda_globals.slot_objs[this.assignment_id] = this; }; ScheduledSlot.prototype.real_initialize = function(json, extra) { /* do not copy everything over */ this.pinned = update_if_not_undefined(this.pinned, json.pinned); - this.scheduledsession_id = update_if_not_undefined(this.scheduledsession_id, json.scheduledsession_id); + this.assignment_id = update_if_not_undefined(this.assignment_id, json.assignment_id); this.session_id = update_if_not_undefined(this.session_id, json.session_id); this.timeslot_id = update_if_not_undefined(this.timeslot_id, json.timeslot_id); this.href = update_if_not_undefined(this.href, json.href); @@ -605,23 +605,23 @@ ScheduledSlot.prototype.real_initialize = function(json, extra) { } if(this.session_id != undefined) { // remove any old duplicate that might exist. - remove_from_slot_status(this.domid(), this.scheduledsession_id); + remove_from_slot_status(this.domid(), this.assignment_id); if(agenda_globals.__debug_session_move) { console.log(extra, "adding to slot_status", this.domid()); } agenda_globals.slot_status[this.domid()].push(this); - //console.log("filling slot_objs", this.scheduledsession_id); + //console.log("filling slot_objs", this.assignment_id); } } - agenda_globals.slot_objs[this.scheduledsession_id] = this; + agenda_globals.slot_objs[this.assignment_id] = this; }; ScheduledSlot.prototype.initialize = ScheduledSlot.prototype.real_initialize; -function load_scheduledsessions(ts_promise, session_promise, href) { - if(agenda_globals.scheduledsession_promise == undefined) { - agenda_globals.scheduledsession_promise = $.Deferred(); +function load_assignments(ts_promise, session_promise, href) { + if(agenda_globals.assignment_promise == undefined) { + agenda_globals.assignment_promise = $.Deferred(); var ss = $.ajax(href); var ss_loaded = $.when(ss,ts_promise,session_promise); @@ -635,10 +635,10 @@ function load_scheduledsessions(ts_promise, session_promise, href) { //console.log("ss has:", one); make_ss(one); }); - agenda_globals.scheduledsession_promise.resolve(newobj); + agenda_globals.assignment_promise.resolve(newobj); }); } - return agenda_globals.scheduledsession_promise; + return agenda_globals.assignment_promise; } ScheduledSlot.prototype.connect_to_timeslot_session = function() { @@ -658,12 +658,12 @@ ScheduledSlot.prototype.session = function() { if(this.session_id != undefined) { return agenda_globals.meeting_objs[this.session_id]; } else { - console.log("ss id:", this.scheduledsession_id, "timeslot:", this.timeslot_id, this.timeslot.title(), "has null session"); + console.log("ss id:", this.assignment_id, "timeslot:", this.timeslot_id, this.timeslot.title(), "has null session"); return undefined; } }; ScheduledSlot.prototype.slot_title = function() { - return "id#"+this.scheduledsession_id+" dom:"+this.domid(); + return "id#"+this.assignment_id+" dom:"+this.domid(); }; function make_ss(json) { @@ -864,14 +864,14 @@ Session.prototype.on_bucket_list = function() { this.column_class_list = []; this.element().parent("div").addClass("meeting_box_bucket_list"); }; -Session.prototype.placed = function(where, forceslot, scheduledsession) { +Session.prototype.placed = function(where, forceslot, assignment) { this.is_placed = true; // forceslot is set on a move, but unset on initial placement, // as placed might be called more than once for a double slot session. if(forceslot || this.slot==undefined) { this.slot = where; - this.scheduledsession = scheduledsession; + this.assignment = assignment; /* we can not mark old slot as empty, because it might have multiple sessions in it. @@ -1232,7 +1232,7 @@ Session.prototype.generate_info_table = function() { if(this.slot != undefined) { ss = this.slot; if(ss.timeslot_id == null){ - $("#info_location_select").val(agenda_globals.meeting_objs[ss.scheduledsession_id]); + $("#info_location_select").val(agenda_globals.meeting_objs[ss.assignment_id]); }else{ $("#info_location_select").val(ss.timeslot_id); // *** } diff --git a/ietf/templates/meeting/agenda_by_type.html b/ietf/templates/meeting/agenda_by_type.html index 046154d02..b1560c27b 100644 --- a/ietf/templates/meeting/agenda_by_type.html +++ b/ietf/templates/meeting/agenda_by_type.html @@ -26,7 +26,7 @@ li.daylistentry { margin-left:2em; font-weight: 400; } {% block content %}

Agenda for {{meeting}} by Session Type

-{% regroup scheduledsessions by session.type.slug as type_list %} +{% regroup assignments by session.type.slug as type_list %}
    {% for type in type_list %}
  • diff --git a/ietf/templates/meeting/landscape_edit.html b/ietf/templates/meeting/landscape_edit.html index 8c0e06e88..0a2e755f8 100644 --- a/ietf/templates/meeting/landscape_edit.html +++ b/ietf/templates/meeting/landscape_edit.html @@ -60,7 +60,7 @@ var schedule_name = "{{ schedule.name }}"; var meeting_base_url = "{{ meeting_base_url }}"; var schedule_owner_email = "{{ schedule.owner_email }}"; var site_base_url = "{{ site_base_url }}"; -var scheduledsession_post_href = "{% url "ietf.meeting.ajax.scheduledsessions_json" meeting.number schedule.owner_email schedule.name %}"; +var assignments_post_href = "{% url "ietf.meeting.ajax.assignments_json" meeting.number schedule.owner_email schedule.name %}"; var total_days = {{time_slices|length}}; var total_rooms = {{rooms|length}}; @@ -81,7 +81,7 @@ var sess_promise = load_sessions("{% url "ietf.meeting.ajax.sessions_json" meeti promiselist.push(ts_promise); promiselist.push(sess_promise); -var ss_promise = load_scheduledsessions(ts_promise, sess_promise, scheduledsession_post_href); +var ss_promise = load_assignments(ts_promise, sess_promise, assignments_post_href); promiselist.push(ss_promise); console.log("setup_slots run"); diff --git a/ietf/templates/meeting/room-view.html b/ietf/templates/meeting/room-view.html index 7f94ebad1..d1d4ee835 100644 --- a/ietf/templates/meeting/room-view.html +++ b/ietf/templates/meeting/room-view.html @@ -21,7 +21,7 @@ items.push({room_index:room_names.indexOf("{{slot.get_hidden_location}}"),day:{{slot.day}}, delta_from_beginning:{{slot.delta_from_beginning}},time:"{{slot.time|date:"Hi"}}-{{slot.end_time|date:"Hi"}}", verbose_time:"{{slot.time|date:"D M d Hi"}}-{{slot.end_time|date:"Hi"}}",duration:{{slot.duration.total_seconds}}, type:"{{slot.type}}", name:"Unavailable", dayname:"{{ slot.time|date:"l"|upper }}, {{ slot.time|date:"F j, Y" }}" }); } {% endfor %} - {% for ss in scheduledsessions %} + {% for ss in assignments %} if (room_names.indexOf("{{ss.timeslot.get_hidden_location}}") >= 0 ) { items.push({room_index:room_names.indexOf("{{ss.timeslot.get_hidden_location}}"),day:{{ss.day}}, delta_from_beginning:{{ss.delta_from_beginning}},time:"{{ss.timeslot.time|date:"Hi"}}-{{ss.timeslot.end_time|date:"Hi"}}", verbose_time:"{{ss.timeslot.time|date:"D M d Hi"}}-{{ss.timeslot.end_time|date:"Hi"}}",duration:{{ss.timeslot.duration.total_seconds}}, type:"{{ss.timeslot.type}}", {% if ss.session.name %}name:"{{ss.session.name|escapejs}}",{% if ss.session.group.acronym %} wg:"{{ss.session.group.acronym}}",{%endif%}{% else %}{% if ss.timeslot.type.name == "Break" %}name:"{{ss.timeslot.name|escapejs}}", area:"break", wg:"break",{% elif ss.timeslot.type.slug == "unavail" %}name:"Unavailable",{% else %}name:"{{ss.session.group.name|escapejs}}{%if ss.session.group.state.name = "BOF"%} BOF{%endif%}",wg:"{{ss.session.group.acronym}}",state:"{{ss.session.group.state}}",area:"{{ss.session.group.parent.acronym}}",{% endif %}{% endif %} dayname:"{{ ss.timeslot.time|date:"l"|upper }}, {{ ss.timeslot.time|date:"F j, Y" }}"{% if ss.session.agenda %}, agenda:"{{ss.session.agenda.get_absolute_url}}"{% endif %} });