Merged in the contents of commit [6337] from mcr@sandelman.ca, with some changes to take out dead code that inadvertently came back in.

- Legacy-Id: 6344
Note: SVN reference [6337] has been migrated to Git commit d0d1d949a9328da6c4e30d8f5e0d14ffb204e678
This commit is contained in:
Henrik Levkowetz 2013-10-02 21:53:28 +00:00
parent 08e90fd63f
commit a3c8adfdf6
50 changed files with 3331 additions and 629 deletions

View file

@ -1,3 +1,51 @@
ietfdb (4.80) ietf; urgench=high
This is a major release which provides the code drop from phase 3 of the
Agenda Scheduling Tool. The code has been merged in, and a lot of minor
alignments done. Deployment of this will make the phase 3 agenda editing
tools available from the main ietf site, will align the database schema with
that used in the ongoing development work, and will provide the correct
models for secretariat tool adaptations.
* Reworked the TestCase code and fixture loading substantially, resulting
in a substantial speed increase for tests when run on a transaction-
capable database engine.
* Added an index page for nomcoms, at /nomcom/, with links to nomcom
pages and announcements, where they exist.
* Fixed some bugs in the EncryptedTextField class.
* Fixed the language of the nomination confirmation message.
* Changed 'requirement' to 'desired expertise' in user-visible places in
the nomcom app.
* Fixed a wrong secretariat template extension name.
* Provide the missing safe_rep function required in the back-ported
assertIsNone() test case method.
* Added an explanatory paragraph to the Desired Expertise page.
* The exception string for submission upload read errors seems to have
changed after we switched to wsgi, from "Client read error" to "request
data read error". Now looking for just "read error".
* Tweaked the introductory text on the Desired Expertise page.
* Added a makefixture management command, from
http://djangosnippets.org/snippets/918/, somewhat hacked.
* Updated fixtures, built to be more internally consistent in order to be
able to pre-load them for the test suite.
* Fixed the manyfold duplicated position names in the position selection
drop-down list in the nomcom private index page. Fixes issue #1137.
-- Henrik Levkowetz <henrik@netnod.se> 01 Oct 2013 16:54:16 +0200
ietfdb (4.72) ietf; urgency=medium
* Added a migration for a new ConstraintName field: penalty

View file

@ -11,7 +11,7 @@ from ietf.group.colors import fg_group_colors, bg_group_colors
import datetime
import debug
class GroupInfo(models.Model):
time = models.DateTimeField(default=datetime.datetime.now)
name = models.CharField(max_length=80)
@ -101,10 +101,14 @@ class Group(GroupInfo):
group1['name'] = self.name
group1['state'] = self.state.slug
group1['type'] = self.type.slug
group1['parent_href'] = urljoin(host_scheme, self.parent.json_url())
if self.parent is not None:
group1['parent_href'] = urljoin(host_scheme, self.parent.json_url())
# uncomment when people URL handle is created
#if self.ad is not None:
# group1['ad_href'] = urljoin(host_scheme, self.ad.url())
try:
if self.ad is not None:
group1['ad_href'] = urljoin(host_scheme, self.ad.json_url())
except Person.DoesNotExist:
pass
group1['list_email'] = self.list_email
group1['list_subscribe'] = self.list_subscribe
group1['list_archive'] = self.list_archive

View file

@ -28,8 +28,13 @@ from ietf.settings import LOG_DIR
log = logging.getLogger(__name__)
import debug
@dajaxice_register
def readonly(request, meeting_num, schedule_id):
debug.say('readonly()')
debug.show('meeting_num')
debug.show('schedule_id')
meeting = get_meeting(meeting_num)
schedule = get_schedule_by_id(meeting, schedule_id)
@ -61,6 +66,30 @@ def readonly(request, meeting_num, schedule_id):
'owner_href': request.build_absolute_uri(schedule.owner.json_url()),
'read_only': read_only})
@group_required('Area Director','Secretariat')
@dajaxice_register
def update_timeslot_pinned(request, schedule_id, scheduledsession_id, pinned=False):
schedule = get_object_or_404(Schedule, pk = int(schedule_id))
meeting = schedule.meeting
cansee,canedit = agenda_permissions(meeting, schedule, request.user)
if not canedit:
raise Http403
return json.dumps({'error':'no permission'})
if scheduledsession_id is not None:
ss_id = int(scheduledsession_id)
if ss_id != 0:
ss = get_object_or_404(schedule.scheduledsession_set, pk=ss_id)
ss.pinned = pinned
ss.save()
return json.dumps({'message':'valid'})
@group_required('Area Director','Secretariat')
@dajaxice_register
def update_timeslot(request, schedule_id, session_id, scheduledsession_id=None, extended_from_id=None, duplicate=False):
@ -458,7 +487,10 @@ def session_json(request, num, sessionid):
try:
session = meeting.session_set.get(pk=int(sessionid))
except Session.DoesNotExist:
return json.dumps({'error':"no such session %s" % sessionid})
# return json.dumps({'error':"no such session %s" % sessionid})
return HttpResponse(json.dumps({'error':"no such session %s" % sessionid}),
status = 404,
mimetype="application/json")
sess1 = session.json_dict(request.build_absolute_uri('/'))
return HttpResponse(json.dumps(sess1, sort_keys=True, indent=2),
@ -466,6 +498,25 @@ def session_json(request, num, sessionid):
# Would like to cache for 1 day, but there are invalidation issues.
#@cache_page(86400)
def constraint_json(request, num, constraintid):
meeting = get_meeting(num)
try:
constraint = meeting.constraint_set.get(pk=int(constraintid))
except Constraint.DoesNotExist:
return HttpResponse(json.dumps({'error':"no such constraint %s" % constraintid}),
status = 404,
mimetype="application/json")
json1 = constraint.json_dict(request.get_host_protocol())
return HttpResponse(json.dumps(json1, sort_keys=True, indent=2),
mimetype="application/json")
# Cache for 2 hour2
#@cache_page(7200)
# caching is a problem if there Host: header changes.
#
def session_constraints(request, num, sessionid):
meeting = get_meeting(num)

View file

@ -1454,5 +1454,9 @@
{"pk": 22491, "model": "meeting.constraint", "fields": {"source": 1847, "meeting": 83, "target": 1751, "name": "conflic2"}},
{"pk": 22492, "model": "meeting.constraint", "fields": {"source": 1847, "meeting": 83, "target": 1817, "name": "conflic2"}},
{"pk": 22493, "model": "meeting.constraint", "fields": {"source": 1847, "meeting": 83, "target": 1728, "name": "conflic2"}},
{"pk": 22494, "model": "meeting.constraint", "fields": {"source": 1847, "meeting": 83, "target": 1789, "name": "conflic2"}}
]
{"pk": 22494, "model": "meeting.constraint", "fields": {"source": 1847, "meeting": 83, "target": 1789, "name": "conflic2"}},
{"pk": 23000, "model": "meeting.constraint", "fields": {"source": 1816, "meeting": 83, "name": "bethere", "person": 103539}},
{"pk": 23001, "model": "meeting.constraint", "fields": {"source": 1816, "meeting": 83, "name": "bethere", "person": 108554}},
{"pk": 23002, "model": "meeting.constraint", "fields": {"source": 1816, "meeting": 83, "name": "bethere", "person": 102830}}
]

View file

@ -10,8 +10,11 @@ from tempfile import mkstemp
from django import forms
from django.http import Http404
from django.http import HttpRequest
from django.db.models import Max, Q
from django.conf import settings
from django.core.cache import cache
from django.utils.cache import get_cache_key
import debug
import urllib
@ -344,3 +347,15 @@ def agenda_permissions(meeting, schedule, user):
canedit = True
return cansee,canedit
def session_constraint_expire(session):
from django.core.urlresolvers import reverse
from ajax import session_constraints
path = reverse(session_constraints, args=[session.meeting.number, session.pk])
request = HttpRequest()
request.path = path
key = get_cache_key(request)
if key is not None and cache.has_key(key):
cache.delete(key)

View file

@ -0,0 +1,347 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'ScheduledSession.badness'
db.add_column('meeting_scheduledsession', 'badness',
self.gf('django.db.models.fields.IntegerField')(default=0, null=True),
keep_default=False)
# Adding field 'Schedule.badness'
db.add_column('meeting_schedule', 'badness',
self.gf('django.db.models.fields.IntegerField')(default=0, null=True),
keep_default=False)
def backwards(self, orm):
# Deleting field 'ScheduledSession.badness'
db.delete_column('meeting_scheduledsession', 'badness')
# Deleting field 'Schedule.badness'
db.delete_column('meeting_schedule', 'badness')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'doc.docalias': {
'Meta': {'object_name': 'DocAlias'},
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'})
},
'doc.document': {
'Meta': {'object_name': 'Document'},
'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "orm['doc.DocumentAuthor']", 'blank': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'external_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.IntendedStdLevelName']", 'null': 'True', 'blank': 'True'}),
'internal_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'primary_key': 'True'}),
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'notify': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1', 'blank': 'True'}),
'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'related': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'reversely_related_document_set'", 'blank': 'True', 'through': "orm['doc.RelatedDocument']", 'to': "orm['doc.DocAlias']"}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'shepherd_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}),
'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}),
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['name.DocTagName']", 'null': 'True', 'blank': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'})
},
'doc.documentauthor': {
'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'},
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1'})
},
'doc.relateddocument': {
'Meta': {'object_name': 'RelatedDocument'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'relationship': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocRelationshipName']"}),
'source': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.DocAlias']"})
},
'doc.state': {
'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': "orm['doc.State']"}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'doc.statetype': {
'Meta': {'object_name': 'StateType'},
'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '30', 'primary_key': 'True'})
},
'group.group': {
'Meta': {'object_name': 'Group'},
'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
'charter': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'chartered_group'", 'unique': 'True', 'null': 'True', 'to': "orm['doc.Document']"}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'list_archive': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'list_email': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'list_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}),
'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'})
},
'meeting.constraint': {
'Meta': {'object_name': 'Constraint'},
'day': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.ConstraintName']"}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
'source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'constraint_source_set'", 'to': "orm['group.Group']"}),
'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'constraint_target_set'", 'null': 'True', 'to': "orm['group.Group']"})
},
'meeting.meeting': {
'Meta': {'object_name': 'Meeting'},
'agenda': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['meeting.Schedule']"}),
'agenda_note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'break_area': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'city': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '2', 'blank': 'True'}),
'date': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
'reg_area': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'time_zone': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.MeetingTypeName']"}),
'venue_addr': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
'meeting.room': {
'Meta': {'object_name': 'Room'},
'capacity': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
'meeting.schedule': {
'Meta': {'object_name': 'Schedule'},
'badness': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']", 'null': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'meeting.scheduledsession': {
'Meta': {'object_name': 'ScheduledSession'},
'badness': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'schedule': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Schedule']"}),
'session': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['meeting.Session']", 'null': 'True'}),
'timeslot': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.TimeSlot']"})
},
'meeting.session': {
'Meta': {'object_name': 'Session'},
'agenda_note': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'attendees': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'materials': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.Document']", 'symmetrical': 'False', 'blank': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'requested': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'requested_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
'requested_duration': ('ietf.meeting.timedeltafield.TimedeltaField', [], {'default': '0'}),
'scheduled': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.SessionStatusName']"})
},
'meeting.timeslot': {
'Meta': {'object_name': 'TimeSlot'},
'duration': ('ietf.meeting.timedeltafield.TimedeltaField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Room']", 'null': 'True', 'blank': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'sessions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'slots'", 'to': "orm['meeting.Session']", 'through': "orm['meeting.ScheduledSession']", 'blank': 'True', 'symmetrical': 'False', 'null': 'True'}),
'show_location': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.TimeSlotTypeName']"})
},
'name.constraintname': {
'Meta': {'ordering': "['order']", 'object_name': 'ConstraintName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.docrelationshipname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocRelationshipName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.doctagname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.doctypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.groupstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.grouptypename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.intendedstdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.meetingtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'MeetingTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.sessionstatusname': {
'Meta': {'ordering': "['order']", 'object_name': 'SessionStatusName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.stdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.streamname': {
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.timeslottypename': {
'Meta': {'ordering': "['order']", 'object_name': 'TimeSlotTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'person.email': {
'Meta': {'object_name': 'Email'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'address': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
},
'person.person': {
'Meta': {'object_name': 'Person'},
'address': ('django.db.models.fields.TextField', [], {'max_length': '255', 'blank': 'True'}),
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'ascii': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'ascii_short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
}
}
complete_apps = ['meeting']

View file

@ -0,0 +1,352 @@
# -*- coding: utf-8 -*-
import datetime
import sys
from south.db import db
from south.v2 import DataMigration
from django.db import models
from ietf.meeting.models import Meeting
def make_essential_person(session, person):
nc = session.people_constraints.create(person = person,
meeting = session.meeting,
name_id = 'bethere',
source = session.group)
nc.save()
#sys.stdout.write("created constraints for %s" % (person))
return nc
def add_bepresent_for_meeting(mtg):
# cribbed from ietf.secr.sreq.views make_bepresent_formset.
for session in mtg.session_set.all():
if session.group is None:
continue
group = session.group
sys.stdout.write (" be there for wg:%s \n" % (session.group))
dict_of_essential_people = {}
# see what people might already be listed.
for x in session.people_constraints.all():
#print "add db: %u %s" % (x.person.pk, x.person)
dict_of_essential_people[x.person.pk] = x
# now, add the co-chairs if they were not already present
chairs = group.role_set.filter(name='chair')
for chairrole in chairs:
chair = chairrole.person
if not chair.pk in dict_of_essential_people:
#print "add chair: %u" % (chair.pk)
dict_of_essential_people[chair.pk] = make_essential_person(session, chair)
# add the responsible AD
if group.ad is not None:
if not group.ad.pk in dict_of_essential_people:
#print "add ad: %u" % (chair.pk)
dict_of_essential_people[group.ad.pk] = make_essential_person(session, group.ad)
#we are done
class Migration(DataMigration):
def forwards(self, orm):
for mtg in Meeting.objects.all():
sys.stdout.write ("Adding bethere constraints for meeting %s..\n" % (mtg.number))
add_bepresent_for_meeting(mtg)
#
#
def backwards(self, orm):
pass
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'doc.document': {
'Meta': {'object_name': 'Document'},
'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "orm['doc.DocumentAuthor']", 'blank': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'external_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.IntendedStdLevelName']", 'null': 'True', 'blank': 'True'}),
'internal_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'primary_key': 'True'}),
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'notify': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1', 'blank': 'True'}),
'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'shepherd_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}),
'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}),
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['name.DocTagName']", 'null': 'True', 'blank': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'})
},
'doc.documentauthor': {
'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'},
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1'})
},
'doc.state': {
'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': "orm['doc.State']"}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'doc.statetype': {
'Meta': {'object_name': 'StateType'},
'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '30', 'primary_key': 'True'})
},
'group.group': {
'Meta': {'object_name': 'Group'},
'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
'charter': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'chartered_group'", 'unique': 'True', 'null': 'True', 'to': "orm['doc.Document']"}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'list_archive': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'list_email': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'list_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}),
'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'})
},
'meeting.constraint': {
'Meta': {'object_name': 'Constraint'},
'day': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.ConstraintName']"}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
'source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'constraint_source_set'", 'to': "orm['group.Group']"}),
'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'constraint_target_set'", 'null': 'True', 'to': "orm['group.Group']"})
},
'meeting.meeting': {
'Meta': {'object_name': 'Meeting'},
'agenda': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['meeting.Schedule']"}),
'agenda_note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'break_area': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'city': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '2', 'blank': 'True'}),
'date': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
'reg_area': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'time_zone': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.MeetingTypeName']"}),
'venue_addr': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
'meeting.room': {
'Meta': {'object_name': 'Room'},
'capacity': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
'meeting.schedule': {
'Meta': {'object_name': 'Schedule'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']", 'null': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'meeting.scheduledsession': {
'Meta': {'object_name': 'ScheduledSession'},
'extendedfrom': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['meeting.ScheduledSession']", 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'schedule': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Schedule']"}),
'session': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['meeting.Session']", 'null': 'True'}),
'timeslot': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.TimeSlot']"})
},
'meeting.session': {
'Meta': {'object_name': 'Session'},
'agenda_note': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'attendees': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'materials': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.Document']", 'symmetrical': 'False', 'blank': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'requested': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'requested_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
'requested_duration': ('ietf.meeting.timedeltafield.TimedeltaField', [], {'default': '0'}),
'scheduled': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.SessionStatusName']"})
},
'meeting.timeslot': {
'Meta': {'object_name': 'TimeSlot'},
'duration': ('ietf.meeting.timedeltafield.TimedeltaField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Room']", 'null': 'True', 'blank': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'sessions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'slots'", 'to': "orm['meeting.Session']", 'through': "orm['meeting.ScheduledSession']", 'blank': 'True', 'symmetrical': 'False', 'null': 'True'}),
'show_location': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.TimeSlotTypeName']"})
},
'name.constraintname': {
'Meta': {'ordering': "['order']", 'object_name': 'ConstraintName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.doctagname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.doctypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.groupstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.grouptypename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.intendedstdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.meetingtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'MeetingTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.sessionstatusname': {
'Meta': {'ordering': "['order']", 'object_name': 'SessionStatusName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.stdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.streamname': {
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.timeslottypename': {
'Meta': {'ordering': "['order']", 'object_name': 'TimeSlotTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'person.email': {
'Meta': {'object_name': 'Email'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'address': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
},
'person.person': {
'Meta': {'object_name': 'Person'},
'address': ('django.db.models.fields.TextField', [], {'max_length': '255', 'blank': 'True'}),
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'ascii': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'ascii_short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
}
}
complete_apps = ['meeting']
symmetrical = True

View file

@ -0,0 +1,317 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'ScheduledSession.pinned'
db.add_column('meeting_scheduledsession', 'pinned',
self.gf('django.db.models.fields.BooleanField')(default=False),
keep_default=False)
def backwards(self, orm):
# Deleting field 'ScheduledSession.pinned'
db.delete_column('meeting_scheduledsession', 'pinned')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'doc.document': {
'Meta': {'object_name': 'Document'},
'abstract': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ad_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['person.Email']", 'symmetrical': 'False', 'through': "orm['doc.DocumentAuthor']", 'blank': 'True'}),
'expires': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'external_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'intended_std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.IntendedStdLevelName']", 'null': 'True', 'blank': 'True'}),
'internal_comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'primary_key': 'True'}),
'note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'notify': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1', 'blank': 'True'}),
'pages': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'rev': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}),
'shepherd': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'shepherd_document_set'", 'null': 'True', 'to': "orm['person.Person']"}),
'states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'std_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StdLevelName']", 'null': 'True', 'blank': 'True'}),
'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.StreamName']", 'null': 'True', 'blank': 'True'}),
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['name.DocTagName']", 'null': 'True', 'blank': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.DocTypeName']", 'null': 'True', 'blank': 'True'})
},
'doc.documentauthor': {
'Meta': {'ordering': "['document', 'order']", 'object_name': 'DocumentAuthor'},
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.Document']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1'})
},
'doc.state': {
'Meta': {'ordering': "['type', 'order']", 'object_name': 'State'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'next_states': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'previous_states'", 'blank': 'True', 'to': "orm['doc.State']"}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['doc.StateType']"}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'doc.statetype': {
'Meta': {'object_name': 'StateType'},
'label': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '30', 'primary_key': 'True'})
},
'group.group': {
'Meta': {'object_name': 'Group'},
'acronym': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '40'}),
'ad': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
'charter': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'chartered_group'", 'unique': 'True', 'null': 'True', 'to': "orm['doc.Document']"}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'list_archive': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'list_email': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'list_subscribe': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']", 'null': 'True', 'blank': 'True'}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupStateName']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.GroupTypeName']", 'null': 'True'}),
'unused_states': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.State']", 'symmetrical': 'False', 'blank': 'True'}),
'unused_tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['name.DocTagName']", 'symmetrical': 'False', 'blank': 'True'})
},
'meeting.constraint': {
'Meta': {'object_name': 'Constraint'},
'day': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'name': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.ConstraintName']"}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True', 'blank': 'True'}),
'source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'constraint_source_set'", 'to': "orm['group.Group']"}),
'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'constraint_target_set'", 'null': 'True', 'to': "orm['group.Group']"})
},
'meeting.meeting': {
'Meta': {'object_name': 'Meeting'},
'agenda': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['meeting.Schedule']"}),
'agenda_note': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'break_area': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'city': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '2', 'blank': 'True'}),
'date': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}),
'reg_area': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'time_zone': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.MeetingTypeName']"}),
'venue_addr': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'venue_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
'meeting.room': {
'Meta': {'object_name': 'Room'},
'capacity': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
'meeting.schedule': {
'Meta': {'object_name': 'Schedule'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']", 'null': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'meeting.scheduledsession': {
'Meta': {'object_name': 'ScheduledSession'},
'extendedfrom': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['meeting.ScheduledSession']", 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'pinned': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'schedule': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Schedule']"}),
'session': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['meeting.Session']", 'null': 'True'}),
'timeslot': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.TimeSlot']"})
},
'meeting.session': {
'Meta': {'object_name': 'Session'},
'agenda_note': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'attendees': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'materials': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['doc.Document']", 'symmetrical': 'False', 'blank': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'requested': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'requested_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']"}),
'requested_duration': ('ietf.meeting.timedeltafield.TimedeltaField', [], {'default': '0'}),
'scheduled': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.SessionStatusName']"})
},
'meeting.timeslot': {
'Meta': {'object_name': 'TimeSlot'},
'duration': ('ietf.meeting.timedeltafield.TimedeltaField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Room']", 'null': 'True', 'blank': 'True'}),
'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['meeting.Meeting']"}),
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'sessions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'slots'", 'to': "orm['meeting.Session']", 'through': "orm['meeting.ScheduledSession']", 'blank': 'True', 'symmetrical': 'False', 'null': 'True'}),
'show_location': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.TimeSlotTypeName']"})
},
'name.constraintname': {
'Meta': {'ordering': "['order']", 'object_name': 'ConstraintName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.doctagname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.doctypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.groupstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.grouptypename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.intendedstdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.meetingtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'MeetingTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.sessionstatusname': {
'Meta': {'ordering': "['order']", 'object_name': 'SessionStatusName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.stdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.streamname': {
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.timeslottypename': {
'Meta': {'ordering': "['order']", 'object_name': 'TimeSlotTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'person.email': {
'Meta': {'object_name': 'Email'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'address': ('django.db.models.fields.CharField', [], {'max_length': '64', 'primary_key': 'True'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Person']", 'null': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
},
'person.person': {
'Meta': {'object_name': 'Person'},
'address': ('django.db.models.fields.TextField', [], {'max_length': '255', 'blank': 'True'}),
'affiliation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'ascii': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'ascii_short': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'time': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
}
}
complete_apps = ['meeting']

View file

@ -112,6 +112,15 @@ class Meeting(models.Model):
return qs[0]
return None
@property
def sessions_that_wont_meet(self):
return self.session_set.filter(status__slug='notmeet')
@property
def sessions_that_can_meet(self):
return self.session_set.exclude(status__slug='notmeet').exclude(status__slug='disappr').exclude(status__slug='deleted').exclude(status__slug='apprw')
def json_url(self):
return "/meeting/%s.json" % (self.number, )
@ -125,7 +134,7 @@ class Meeting(models.Model):
if self.agenda:
agenda_url = urljoin(host_scheme, self.agenda.base_url())
return {
'href': urljoin(host_scheme, self.base_url()),
'href': urljoin(host_scheme, self.json_url()),
'name': self.number,
'submission_start_date': fmt_date(self.get_submission_start_date()),
'submission_cut_off_date': fmt_date(self.get_submission_cut_off_date()),
@ -187,7 +196,7 @@ class Room(models.Model):
capacity = models.IntegerField(null=True, blank=True)
def __unicode__(self):
return self.name
return "%s size: %u" % (self.name, self.capacity)
def delete_timeslots(self):
for ts in self.timeslot_set.all():
@ -363,7 +372,6 @@ class TimeSlot(models.Model):
def json_url(self):
return "/meeting/%s/timeslot/%s.json" % (self.meeting.number, self.id)
"""
This routine takes the current timeslot, which is assumed to have no location,
and assigns a room, and then creates an identical timeslot for all of the other
@ -378,6 +386,7 @@ class TimeSlot(models.Model):
ts.id = None
ts.location = room
ts.save()
self.meeting.create_all_timeslots()
"""
@ -428,6 +437,7 @@ class Schedule(models.Model):
owner = models.ForeignKey(Person)
visible = models.BooleanField(default=True, help_text=u"Make this agenda available to those who know about it")
public = models.BooleanField(default=True, help_text=u"Make this agenda publically available")
badness = models.IntegerField(null=True, blank=True)
# considering copiedFrom = models.ForeignKey('Schedule', blank=True, null=True)
def __unicode__(self):
@ -436,8 +446,12 @@ class Schedule(models.Model):
def base_url(self):
return "/meeting/%s/agenda/%s" % (self.meeting.number, self.name)
def url_edit(self):
return "/meeting/%s/agenda/%s/edit" % (self.meeting.number, self.name)
# def url_edit(self):
# return "/meeting/%s/agenda/%s/edit" % (self.meeting.number, self.name)
#
# @property
# def relurl_edit(self):
# return self.url_edit("")
@property
def visible_token(self):
@ -464,6 +478,10 @@ class Schedule(models.Model):
else:
return "agenda_unofficial"
# returns a dictionary {group -> [scheduledsession+]}
# 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)
@property
def official_token(self):
if self.is_official:
@ -496,6 +514,60 @@ class Schedule(models.Model):
# should include href to list of scheduledsessions, but they have no direct API yet.
return sch
@property
def qs_scheduledsessions_with_assignments(self):
return self.scheduledsession_set.filter(session__isnull=False)
@property
def qs_scheduledsessions_without_assignments(self):
return self.scheduledsession_set.filter(session__isnull=True)
@property
def group_mapping(self):
assignments,sessions,total,scheduled = self.group_session_mapping
return assignments
@property
def group_session_mapping(self):
assignments = dict()
sessions = dict()
total = 0
scheduled = 0
allschedsessions = self.qs_scheduledsessions_with_assignments.filter(timeslot__type = "session").all()
for sess in self.meeting.sessions_that_can_meet.all():
assignments[sess.group] = []
sessions[sess] = None
total =+ 1
for ss in allschedsessions:
assignments[ss.session.group].append(ss)
# XXX can not deal with a session in two slots
sessions[ss.session] = ss
scheduled =+ 1
return assignments,sessions,total,scheduled
# calculate badness of entire schedule
def calc_badness(self):
# now calculate badness
assignments = self.group_mapping
return self.calc_badness1(assignments)
cached_sessions_that_can_meet = None
@property
def sessions_that_can_meet(self):
if self.cached_sessions_that_can_meet is None:
self.cached_sessions_that_can_meet = self.meeting.sessions_that_can_meet.all()
return self.cached_sessions_that_can_meet
# calculate badness of entire schedule
def calc_badness1(self, assignments):
badness = 0
for sess in self.sessions_that_can_meet:
badness += sess.badness(assignments)
self.badness = badness
return badness
class ScheduledSession(models.Model):
"""
This model provides an N:M relationship between Session and TimeSlot.
@ -508,6 +580,11 @@ class ScheduledSession(models.Model):
extendedfrom = models.ForeignKey('ScheduledSession', null=True, default=None, help_text=u"Timeslot this session is an extension of")
modified = models.DateTimeField(default=datetime.datetime.now)
notes = models.TextField(blank=True)
badness = models.IntegerField(default=0, blank=True, null=True)
pinned = models.BooleanField(default=False, help_text="Do not move session during automatic placement")
# use to distinguish this from FakeScheduledSession in placement.py
faked = "real"
def __unicode__(self):
return u"%s [%s<->%s]" % (self.schedule, self.session, self.timeslot)
@ -628,6 +705,7 @@ class ScheduledSession(models.Model):
ss["time"] = date_format(self.timeslot.time, 'Hi')
ss["date"] = time_format(self.timeslot.time, 'Y-m-d')
ss["domid"] = self.timeslot.js_identifier
ss["pinned"] = self.pinned
return ss
@ -636,7 +714,7 @@ class Constraint(models.Model):
Specifies a constraint on the scheduling.
One type (name=conflic?) of constraint is between source WG and target WG,
e.g. some kind of conflict.
Another type (name=adpresent) of constraing is between source WG and
Another type (name=bethere) of constraing is between source WG and
availability of a particular Person, usually an AD.
A third type (name=avoidday) of constraing is between source WG and
a particular day of the week, specified in day.
@ -648,8 +726,37 @@ class Constraint(models.Model):
day = models.DateTimeField(null=True, blank=True)
name = models.ForeignKey(ConstraintName)
active_status = None
def __unicode__(self):
return u"%s %s %s" % (self.source, self.name.name.lower(), self.target)
return u"%s %s target=%s person=%s" % (self.source, self.name.name.lower(), self.target, self.person)
@property
def person_conflicted(self):
if self.person is None:
return "unknown person"
return self.person.name
def status(self):
if self.active_status is not None:
return self.active_status
else:
return True
def __lt__(self, y):
#import sys
#sys.stdout.write("me: %s y: %s\n" % (self.name.slug, y.name.slug))
if self.name.slug == 'conflict' and y.name.slug == 'conflic2':
return True
if self.name.slug == 'conflict' and y.name.slug == 'conflic3':
return True
if self.name.slug == 'conflic2' and y.name.slug == 'conflic3':
return True
return False
@property
def constraint_cost(self):
return self.name.cost();
def json_url(self):
return "/meeting/%s/constraint/%s.json" % (self.meeting.number, self.id)
@ -668,7 +775,8 @@ class Constraint(models.Model):
ct1['meeting_href'] = urljoin(host_scheme, self.meeting.json_url())
return ct1
constraint_cache_uses = 0
constraint_cache_initials = 0
class Session(models.Model):
"""Session records that a group should have a session on the
@ -692,6 +800,8 @@ class Session(models.Model):
materials = models.ManyToManyField(Document, blank=True)
unique_constraints_dict = None
def agenda(self):
items = self.materials.filter(type="agenda",states__type="agenda",states__slug="active")
if items and items[0] is not None:
@ -719,7 +829,7 @@ class Session(models.Model):
ss = self.scheduledsession_set.order_by('timeslot__time')
if ss:
ss0name = ss[0].timeslot.time.strftime("%H%M")
return u"%s: %s %s" % (self.meeting, self.group.acronym, ss0name)
return u"%s: %s %s[%u]" % (self.meeting, self.group.acronym, ss0name, self.pk)
@property
def short_name(self):
@ -750,38 +860,269 @@ class Session(models.Model):
def official_scheduledsession(self):
return self.scheduledsession_for_agenda(self.meeting.agenda)
def unique_constraints(self):
global constraint_cache_uses, constraint_cache_initials
constraint_cache_uses += 1
# this cache keeps the automatic placer from visiting the database continuously
if self.unique_constraints_dict is not None:
constraint_cache_initials += 1
return self.unique_constraints_dict
self.unique_constraints_dict = dict()
for constraint in self.constraints():
self.unique_constraints_dict[constraint.target] = constraint
for constraint in self.reverse_constraints():
# update the constraint if there is a previous one, and
# it is more important than what we had before
if not (constraint in self.unique_constraints_dict) or (self.unique_constraints_dict[constraint.source] < constraint):
self.unique_constraints_dict[constraint.source] = constraint
return self.unique_constraints_dict
def constraints_dict(self, host_scheme):
constraint_list = []
for constraint in self.group.constraint_source_set.filter(meeting=self.meeting):
for constraint in self.constraints():
ct1 = constraint.json_dict(host_scheme)
constraint_list.append(ct1)
for constraint in self.group.constraint_target_set.filter(meeting=self.meeting):
for constraint in self.reverse_constraints():
ct1 = constraint.json_dict(host_scheme)
constraint_list.append(ct1)
return constraint_list
@property
def people_constraints(self):
return self.group.constraint_source_set.filter(meeting=self.meeting, name='bethere')
def json_url(self):
return "/meeting/%s/session/%s.json" % (self.meeting.number, self.id)
def json_dict(self, host_scheme):
sess1 = dict()
sess1['href'] = urljoin(host_scheme, self.json_url())
sess1['group_href'] = urljoin(host_scheme, self.group.json_url())
sess1['group_acronym'] = str(self.group.acronym)
if self.group is not None:
sess1['group'] = self.group.json_dict(host_scheme)
# nuke rest of these as soon as JS cleaned up.
sess1['group_href'] = urljoin(host_scheme, self.group.json_url())
sess1['group_acronym'] = str(self.group.acronym)
if self.group.parent is not None:
sess1['area'] = str(self.group.parent.acronym).upper()
sess1['GroupInfo_state']= str(self.group.state)
sess1['description'] = str(self.group.name)
sess1['group_id'] = str(self.group.pk)
sess1['session_id'] = str(self.pk)
sess1['name'] = str(self.name)
sess1['short_name'] = str(self.name)
sess1['title'] = str(self.short_name)
sess1['short_name'] = str(self.short_name)
sess1['agenda_note'] = str(self.agenda_note)
sess1['attendees'] = str(self.attendees)
sess1['status'] = str(self.status)
if self.comments is not None:
sess1['comments'] = str(self.comments)
sess1['requested_time'] = str(self.requested.strftime("%Y-%m-%d"))
sess1['requested_by'] = str(self.requested_by)
sess1['requested_duration']= "%.1f h" % (float(self.requested_duration.seconds) / 3600)
sess1['area'] = str(self.group.parent.acronym)
sess1['responsible_ad'] = str(self.group.ad)
sess1['GroupInfo_state']= str(self.group.state)
# the related person object sometimes does not exist in the dataset.
try:
if self.requested_by is not None:
sess1['requested_by'] = str(self.requested_by)
except Person.DoesNotExist:
pass
sess1['requested_duration']= "%.1f" % (float(self.requested_duration.seconds) / 3600)
sess1['duration'] = sess1['requested_duration']
sess1['special_request'] = str(self.special_request_token)
return sess1
def badness_test(self, num):
import sys
from settings import BADNESS_CALC_LOG
#sys.stdout.write("num: %u / BAD: %u\n" % (num, BADNESS_CALC_LOG))
return BADNESS_CALC_LOG >= num
def badness_log(self, num, msg):
if self.badness_test(num):
sys.stdout.write(msg)
# this evaluates the current session based upon the constraints
# given, in the context of the assignments in the array.
#
# MATH.
# each failed conflic3 is worth 1000 points
# each failed conflic2 is worth 10000 points
# each failed conflic1 is worth 100000 points
# being in a room too small than asked is worth 200,000 * (size/50)
# being in a room too big by more than 100 is worth 200,000 once.
# a conflict where AD must be in two places is worth 500,000.
# not being scheduled is worth 10,000,000 points
#
def badness(self, assignments):
badness = 0
if not (self.group in assignments):
return 0
conflicts = self.unique_constraints()
if self.badness_test(2):
self.badness_log(2, "badgroup: %s badness calculation has %u constraints\n" % (self.group.acronym, len(conflicts)))
import sys
from settings import BADNESS_UNPLACED, BADNESS_TOOSMALL_50, BADNESS_TOOSMALL_100, BADNESS_TOOBIG, BADNESS_MUCHTOOBIG
count = 0
myss_list = assignments[self.group]
# for each constraint of this sessions' group, by group
if len(myss_list)==0:
if self.badness_test(2):
self.badness_log(2, " 0group: %s is unplaced\n" % (self.group.acronym))
return BADNESS_UNPLACED
for myss in myss_list:
if self.attendees is None or myss.timeslot is None or myss.timeslot.location.capacity is None:
continue
mismatch = self.attendees - myss.timeslot.location.capacity
if mismatch > 100:
# the room is too small by 100
badness += BADNESS_TOOSMALL_100
elif mismatch > 50:
# the room is too small by 50
badness += BADNESS_TOOSMALL_50
elif mismatch < 50:
# the room is too big by 50
badness += BADNESS_TOOBIG
elif mismatch < 100:
# the room is too big by 100 (not intimate enough)
badness += BADNESS_MUCHTOOBIG
for group,constraint in conflicts.items():
if group is None:
# must not be a group constraint.
continue
count += 1
# get the list of sessions for other group.
sess_count = 0
if group in assignments:
sess_count = len(assignments[group])
if self.badness_test(4):
self.badness_log(4, " [%u] 1group: %s session_count: %u\n" % (count, group.acronym, sess_count))
# see if the other group which is conflicted, has an assignment,
if group in assignments:
other_sessions = assignments[group]
# and if it does, see if any of it's sessions conflict with any of my sessions
# (each group could have multiple slots)
#if self.badness_test(4):
# self.badness_log(4, " [%u] 9group: other sessions: %s\n" % (count, other_sessions))
for ss in other_sessions:
# this causes additional database dips
#if self.badness_test(4):
# self.badness_log(4, " [%u] 9group: ss: %s %s\n" % (count, ss, ss.faked))
if ss.session is None:
continue
if ss.timeslot is None:
continue
if self.badness_test(3):
self.badness_log(3, " [%u] 2group: %s vs ogroup: %s\n" % (count, self.group.acronym, ss.session.group.acronym))
if ss.session.group.acronym == self.group.acronym:
continue
if self.badness_test(3):
self.badness_log(3, " [%u] 3group: %s sessions: %s\n" % (count, group.acronym, ss.timeslot.time))
# see if they are scheduled at the same time.
conflictbadness = 0
for myss in myss_list:
if myss.timeslot is None:
continue
if self.badness_test(3):
self.badness_log(3, " [%u] 4group: %s my_sessions: %s vs %s\n" % (count, group.acronym, myss.timeslot.time, ss.timeslot.time))
if ss.timeslot.time == myss.timeslot.time:
newcost = constraint.constraint_cost
if self.badness_test(2):
self.badness_log(2, " [%u] 5group: %s conflicts: %s on %s cost %u\n" % (count, self.group.acronym, ss.session.group.acronym, ss.timeslot.time, newcost))
# yes accumulate badness.
conflictbadness += newcost
ss.badness = conflictbadness
ss.save()
badness += conflictbadness
# done
if self.badness_test(1):
self.badness_log(1, "badgroup: %s badness = %u\n" % (self.group.acronym, badness))
return badness
def setup_conflicts(self):
conflicts = self.unique_constraints()
self.session_conflicts = []
for group,constraint in conflicts.items():
if group is None:
# must not be a group constraint, people constraints TBD.
continue
# get the list of sessions for other group.
for session in self.meeting.session_set.filter(group = group):
# make a tuple...
conflict = (session.pk, constraint)
self.session_conflicts.append(conflict)
# This evaluates the current session based upon the constraints
# given. The conflicts have first been shorted into an array (session_conflicts)
# as a tuple, and include the constraint itself.
#
# While the conflicts are listed by group, the conflicts listed here
# have been resolved into pk of session requests that will conflict.
# This is to make comparison be a straight integer comparison.
#
# scheduleslot contains the list of sessions which are at the same time as
# this item.
#
# timeslot is where this item has been scheduled.
#
# MATH.
# each failed conflic3 is worth 1000 points
# each failed conflic2 is worth 10000 points
# each failed conflic1 is worth 100000 points
# being in a room too small than asked is worth 200,000 * (size/50)
# being in a room too big by more than 100 is worth 200,000 once.
# a conflict where AD must be in two places is worth 500,000.
# not being scheduled is worth 10,000,000 points
#
def badness_fast(self, timeslot, scheduleslot, session_pk_list):
from settings import BADNESS_UNPLACED, BADNESS_TOOSMALL_50, BADNESS_TOOSMALL_100, BADNESS_TOOBIG, BADNESS_MUCHTOOBIG
badness = 0
# see if item has not been scheduled
if timeslot is None:
return BADNESS_UNPLACED
# see if this session is in too small a place.
if self.attendees is not None and timeslot.location.capacity is not None:
mismatch = self.attendees - timeslot.location.capacity
if mismatch > 100:
# the room is too small by 100
badness += BADNESS_TOOSMALL_100
elif mismatch > 50:
# the room is too small by 50
badness += BADNESS_TOOSMALL_50
elif mismatch < 50:
# the room is too big by 50
badness += BADNESS_TOOBIG
elif mismatch < 100:
# the room is too big by 100 (not intimate enough)
badness += BADNESS_MUCHTOOBIG
# now go through scheduleslot items and see if any are conflicts
# inner loop is the shorter one, usually max 8 rooms.
for conflict in self.session_conflicts:
for pkt in session_pk_list:
pk = pkt[0]
if pk == self.pk: # ignore conflicts with self.
continue
if conflict[0] == pk:
ss = pkt[1]
if ss.timeslot is not None and ss.timeslot.location == timeslot.location:
continue # ignore conflicts when two sessions in the same room
constraint = conflict[1]
badness += constraint.constraint_cost
if self.badness_test(1):
self.badness_log(1, "badgroup: %s badness = %u\n" % (self.group.acronym, badness))
return badness

View file

@ -226,5 +226,6 @@ AREA DIRECTORS
APP Applications Area Barry Leiba/Huawei Technologies & Pete Resnick/QTI, a Qualcomm company
GEN General Area Russ Housley/Vigil Security, LLC
OPS Operations and Man Ron Bonica/Juniper Networks & Benoit Claise/Cisco
RAI Real-time Applicat Gonzalo Camarillo/Ericsson
SEC Security Area Stephen Farrell/Trinity College Dublin & Sean Turner/IECA

View file

@ -90,7 +90,7 @@ img.hidden { display: none; }
</style>
<script type="text/javascript" src='/js/agenda2.js'></script>
<script type="text/javascript" src='/js/jquery-1.5.1.min.js'></script>
<script type="text/javascript" src='/js/lib/jquery-1.8.2.min.js'></script>
<script type="text/javascript" src='/js/browsertime.js'></script>
<script type="text/javascript" src='/js/weekview.js'></script>
<script type="text/javascript" >
@ -5281,7 +5281,7 @@ You can customize the agenda below to show only selected working group sessions.
<!-- <script type="text/javascript" src="/js/lib/jquery-1.5.1.min.js"></script> -->
<script type="text/javascript" src="/js/lib/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="/js/yui/yui-20100305.js"></script>
<script type="text/javascript">
//<![CDATA[

View file

@ -1,5 +1,6 @@
import sys
from django.test import Client
from ietf.meeting.tests.ttest import AgendaTransactionalTestCase
from ietf.utils import TestCase
from ietf.name.models import SessionStatusName
from ietf.person.models import Person
@ -22,7 +23,7 @@ class AgendaInfoTestCase(TestCase):
p1 = Person.objects.get(pk = 5376) # Russ Housley
st1 = SessionStatusName.objects.get(slug = "appr")
s1 = m1.session_set.create(name = "newone", group = g1, requested_by = p1, status = st1)
self.assertEqual(s1.__unicode__(), "IETF-83: pkix (unscheduled)")
self.assertEqual(s1.__unicode__(), "IETF-83: pkix (unscheduled)[22090]")
def test_AgendaInfo(self):
from ietf.meeting.views import agenda_info
@ -33,7 +34,8 @@ class AgendaInfoTestCase(TestCase):
self.assertEqual(len(timeslots),26)
self.assertEqual(meeting.number,'83')
self.assertEqual(venue.meeting_num, "83")
self.assertTrue(len(ads) > 0)
# will change as more ADs are added to fixtures
self.assertEqual(len(ads), 8)
def test_AgendaInfoReturnsSortedTimeSlots(self):
from ietf.meeting.views import agenda_info
@ -106,7 +108,7 @@ class AgendaInfoTestCase(TestCase):
from ietf.meeting.views import get_meeting
meeting = get_meeting(num)
session1= Session.objects.get(pk=2157)
self.assertEqual(session1.__unicode__(), u"IETF-83: pkix 0900")
self.assertEqual(session1.__unicode__(), u"IETF-83: pkix 0900[2157]")
def test_sessionstr_interim(self):
"""
@ -153,4 +155,11 @@ class AgendaInfoTestCase(TestCase):
self.assertEqual(avtcore.pk, 2216) # sanity check
self.assertEqual(len(avtcore.scheduledsession_set.filter(schedule = sch83)), 2)
def test_clue_has_ad_present(self):
mtg83 = get_meeting(83)
clue83 = mtg83.session_set.filter(group__acronym='clue')[0]
is_present = clue83.people_constraints
self.assertIsNotNone(is_present, "why is constraint list none")
self.assertEqual(len(is_present), 3)

View file

@ -3,7 +3,7 @@ import sys, datetime
from django.test import Client
from ietf.utils import TestCase
#from ietf.person.models import Person
from ietf.person.models import Person
from django.contrib.auth.models import User
from ietf.meeting.models import TimeSlot, Session, ScheduledSession, Meeting
from ietf.ietfauth.decorators import has_role
@ -44,12 +44,12 @@ class ApiTestCase(TestCase):
ts_two = TimeSlot.objects.get(pk=2372)
ss_one = ScheduledSession.objects.get(pk=2371)
# confirm that it has old timeslot value
# confirm that it has old scheduledsession value
self.assertEqual(ss_one.timeslot, ts_one)
# move this session from one timeslot to another.
# move this session from one scheduledsession to another.
self.client.post('/dajaxice/ietf.meeting.update_timeslot/', {
'argv': '{"schedule_id":"%u", "session_id":"%u", "scheduledsession_id":"2372"}' % (ss_one.schedule.id,ts_one.id)
'argv': '{"schedule_id":"%u", "scheduledsession_id":"%u","session_id":"%u" }' % (ss_one.schedule.id, ts_two.id, ss_one.session.id)
}, **auth_ferrel)
# confirm that without login, it does not have new value
@ -67,9 +67,9 @@ class ApiTestCase(TestCase):
# confirm that it has old timeslot value
self.assertEqual(ss_one.session, s2157)
# move this session from one timeslot to another.
# move this session from one scheduledsession to another.
self.client.post('/dajaxice/ietf.meeting.update_timeslot/', {
'argv': '{"schedule_id":"%u", "session_id":"%u", "scheduledsession_id":"2372"}' % (ss_one.schedule.id,s2157.id)
'argv': '{"schedule_id":"%u", "scheduledsession_id":"%u", "session_id":"%u"}' % (ss_one.schedule.id, ss_two.id, s2157.id)
}, **auth_joeblow)
# confirm that without login, it does not have new value
@ -84,12 +84,15 @@ class ApiTestCase(TestCase):
s2157 = Session.objects.get(pk=2157)
ss_one = ScheduledSession.objects.get(pk=2371)
# confirm that it has old timeslot value
# confirm that it has old session value
self.assertEqual(ss_one.session, s2157)
ss_two = ScheduledSession.objects.get(pk=2372)
self.assertNotEqual(ss_two.session, s2157)
# move this session from one timeslot to another.
self.client.post('/dajaxice/ietf.meeting.update_timeslot/', {
'argv': '{"schedule_id":"%u", "session_id":"%u", "scheduledsession_id":"2372"}' % (ss_one.schedule.id,s2157.id)
'argv': '{"schedule_id":"%u", "scheduledsession_id":"%u", "session_id":"%u"}' % (ss_one.schedule.id, ss_two.id, s2157.id)
}, **auth_wlo)
# confirm that it new scheduledsession object has new session.
@ -104,7 +107,7 @@ class ApiTestCase(TestCase):
s2157 = Session.objects.get(pk=2157)
ss_one = ScheduledSession.objects.get(pk=2371)
# confirm that it has old timeslot value
# confirm that it has old scheduledsession value
self.assertEqual(ss_one.session, s2157)
# move this session from one timeslot to another.
@ -112,7 +115,7 @@ class ApiTestCase(TestCase):
'argv': '{"schedule_id":"%u", "session_id":"%u", "scheduledsession_id":"0"}' % (ss_one.schedule.id,s2157.id)
}, **auth_wlo)
# confirm that it old scheduledsession object has no session.
# confirm that it old scheduledsession object now has no session.
ss_one = ScheduledSession.objects.get(pk=2371)
self.assertEqual(ss_one.session, None)
@ -144,7 +147,7 @@ class ApiTestCase(TestCase):
# move this session from one timeslot to another.
self.client.post('/dajaxice/ietf.meeting.update_timeslot/', {
'argv': '{"schedule_id":"%u", "session_id":"%u", "scheduledsession_id":"%u"}' % (ss_one.schedule.id,s2157.id, 2372)
'argv': '{"schedule_id":"%u", "session_id":"%u", "scheduledsession_id":"%u"}' % (ss_one.schedule.id,s2157.id, ss_two_saved.id)
}, **auth_ietfchair)
# confirm that it new scheduledsession object has no new session.
@ -164,6 +167,16 @@ class ApiTestCase(TestCase):
conflicts = json.loads(resp.content)
self.assertNotEqual(conflicts, None)
def test_conflictInfoIncludesPeople(self):
mtg83 = get_meeting(83)
clue83 = mtg83.session_set.filter(group__acronym='clue')[0]
# retrive some json that shows the conflict for this session.
resp = self.client.get("/meeting/83/session/%u/constraints.json" % (clue83.pk))
conflicts = json.loads(resp.content)
self.assertNotEqual(conflicts, None)
self.assertEqual(len(conflicts), 39)
def test_getMeetingInfoJson(self):
resp = self.client.get('/meeting/83.json')
mtginfo = json.loads(resp.content)
@ -245,6 +258,15 @@ class ApiTestCase(TestCase):
mtginfo = json.loads(resp.content)
self.assertNotEqual(mtginfo, None)
def test_getPersonInfoJson(self):
# 491 is Adrian Ferrel, an AD
af = User.objects.filter(pk = 491)[0]
person = af.person
resp = self.client.get('/person/%u.json' % (person.pk))
#print "json: %s" % (resp.content)
pinfo = json.loads(resp.content)
self.assertNotEqual(pinfo, None)
def test_getSlotJson(self):
mtg83 = get_meeting(83)
slot0 = mtg83.timeslot_set.all()[0]
@ -431,7 +453,7 @@ class ApiTestCase(TestCase):
mtg83 = get_meeting(83)
self.assertEqual(mtg83.agenda, None)
def test_setMeetingAgendaSecretariat(self):
def test_setMeetingAgendaSecretariatPublic(self):
mtg83 = get_meeting(83)
new_sched = mtg83.schedule_set.create(name="funny",
meeting=mtg83,
@ -539,7 +561,7 @@ class ApiTestCase(TestCase):
self.assertEqual(m83perm['read_only'], True)
self.assertEqual(m83perm['write_perm'], False)
def test_setMeetingAgendaSecretariat2(self):
def test_setMeetingAgendaSecretariat(self):
mtg83 = get_meeting(83)
new_sched = mtg83.schedule_set.create(name="funny",
meeting=mtg83,
@ -560,3 +582,38 @@ class ApiTestCase(TestCase):
mtg83 = get_meeting(83)
self.assertEqual(mtg83.agenda, new_sched)
def test_noAuthenticationUpdatePinned(self):
ss_one = ScheduledSession.objects.get(pk=2371)
# confirm that it has old timeslot value
self.assertEqual(ss_one.pinned, False)
# pin this session to this location
self.client.post('/dajaxice/ietf.meeting.update_timeslot_pinned/', {
'argv': '{"schedule_id":"%u", "scheduledsession_id":"%u", "pinned":"%u"}' % (ss_one.schedule.id, ss_one.id, 1)
})
# confirm that without login, it does not have new value
ss_one = ScheduledSession.objects.get(pk=2371)
self.assertEqual(ss_one.pinned, False)
def test_authenticationUpdatePinned(self):
ss_one = ScheduledSession.objects.get(pk=2371)
# confirm that it has old timeslot value
self.assertEqual(ss_one.pinned, False)
extra_headers = auth_wlo
extra_headers['HTTP_ACCEPT']='text/json'
# pin this session to this location
self.client.post('/dajaxice/ietf.meeting.update_timeslot_pinned/', {
'argv': '{"schedule_id":"%u", "scheduledsession_id":"%u", "pinned":"%u"}' % (ss_one.schedule.id, ss_one.id, 1)
}, **extra_headers)
# confirm that without login, it does not have new value
ss_one = ScheduledSession.objects.get(pk=2371)
self.assertEqual(ss_one.pinned, True)

View file

@ -35,9 +35,11 @@ urlpatterns = patterns('',
(r'^(?P<num>\d+)/rooms$', ajax.timeslot_roomsurl),
(r'^(?P<num>\d+)/room/(?P<roomid>\d+).json$', ajax.timeslot_roomurl),
(r'^(?P<num>\d+)/timeslots$', ajax.timeslot_slotsurl),
(r'^(?P<num>\d+)/timeslots.json$', ajax.timeslot_slotsurl),
(r'^(?P<num>\d+)/timeslot/(?P<slotid>\d+).json$', ajax.timeslot_sloturl),
(r'^(?P<num>\d+)/agendas/(?P<schedule_name>[A-Za-z0-9-:_]+).json$', ajax.agenda_infourl),
(r'^(?P<num>\d+)/agendas$', ajax.agenda_infosurl),
(r'^(?P<num>\d+)/agendas.json$', ajax.agenda_infosurl),
(r'^(?P<num>\d+)/week-view.html$', views.week_view),
(r'^(?P<num>\d+)/agenda/week-view.html$', views.week_view),
(r'^(?P<num>\d+)/agenda/(?P<session>[A-Za-z0-9-]+)-drafts.pdf$', views.session_draft_pdf),
@ -45,6 +47,7 @@ urlpatterns = patterns('',
(r'^(?P<num>\d+)/agenda/(?P<session>[A-Za-z0-9-]+)/?$', views.session_agenda),
(r'^(?P<num>\d+)/session/(?P<sessionid>\d+).json', ajax.session_json),
(r'^(?P<num>\d+)/session/(?P<sessionid>\d+)/constraints.json', ajax.session_constraints),
(r'^(?P<num>\d+)/constraint/(?P<constraintid>\d+).json', ajax.constraint_json),
(r'^(?P<meeting_num>\d+).json$', ajax.meeting_json),
(r'^$', views.current_materials),
)

View file

@ -11,6 +11,7 @@ from tempfile import mkstemp
from django import forms
from django.shortcuts import render_to_response, get_object_or_404
from django.utils import simplejson as json
from ietf.idtracker.models import IETFWG, IRTF, Area
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.core.urlresolvers import reverse
@ -46,7 +47,8 @@ from ietf.meeting.helpers import get_areas, get_area_list_from_sessions, get_pse
from ietf.meeting.helpers import build_all_agenda_slices, get_wg_name_list
from ietf.meeting.helpers import get_scheduledsessions_from_schedule, get_all_scheduledsessions_from_schedule
from ietf.meeting.helpers import get_modified_from_scheduledsessions
from ietf.meeting.helpers import get_wg_list, get_meeting, get_schedule, agenda_permissions
from ietf.meeting.helpers import get_wg_list, find_ads_for_meeting
from ietf.meeting.helpers import get_meeting, get_schedule, agenda_permissions
@decorator_from_middleware(GZipMiddleware)
@ -217,11 +219,15 @@ def agenda_create(request, num=None, schedule_name=None):
ss.schedule=newschedule
ss.save()
mapping[oldid] = ss.pk
#print "Copying %u to %u" % (oldid, ss.pk)
# now fix up any extendedfrom references to new set.
for ss in newschedule.scheduledsession_set.all():
if ss.extendedfrom is not None:
ss.extendedfrom = newschedule.scheduledsession_set.get(pk = mapping[ss.extendedfrom.id])
oldid = ss.extendedfrom.id
newid = mapping[oldid]
#print "Fixing %u to %u" % (oldid, newid)
ss.extendedfrom = newschedule.scheduledsession_set.get(pk = newid)
ss.save()
@ -240,7 +246,8 @@ def edit_timeslots(request, num=None):
time_slices,date_slices,slots = meeting.build_timeslices()
meeting_base_url = request.build_absolute_uri(meeting.base_url())
site_base_url =request.build_absolute_uri('/')[:-1] # skip the trailing slash
site_base_url = request.build_absolute_uri('/')[:-1] # skip the trailing slash
rooms = meeting.room_set.order_by("capacity")
rooms = rooms.all()
@ -289,7 +296,8 @@ def edit_agenda(request, num=None, schedule_name=None):
#sys.stdout.write("2 requestor: %u for sched owned by: %u \n" % ( requestor.id, schedule.owner.id ))
meeting_base_url = request.build_absolute_uri(meeting.base_url())
site_base_url =request.build_absolute_uri('/')[:-1] # skip the trailing slash
site_base_url = request.build_absolute_uri('/')[:-1] # skip the trailing slash
rooms = meeting.room_set.order_by("capacity")
rooms = rooms.all()
saveas = SaveAsForm()
@ -307,15 +315,27 @@ def edit_agenda(request, num=None, schedule_name=None):
"meeting_base_url":meeting_base_url},
RequestContext(request)), status=403, mimetype="text/html")
sessions = meeting.session_set.exclude(status__slug='deleted').exclude(status__slug='notmeet').order_by("id", "group", "requested_by")
sessions = meeting.sessions_that_can_meet.order_by("id", "group", "requested_by")
scheduledsessions = get_all_scheduledsessions_from_schedule(schedule)
session_jsons = [ json.dumps(s.json_dict(site_base_url)) for s in sessions ]
# useful when debugging javascript
#session_jsons = session_jsons[1:20]
# get_modified_from needs the query set, not the list
modified = get_modified_from_scheduledsessions(scheduledsessions)
area_list = get_pseudo_areas()
ntimeslots = get_ntimeslots_from_ss(schedule, scheduledsessions)
area_list = get_areas()
wg_name_list = get_wg_name_list(scheduledsessions)
wg_list = get_wg_list(wg_name_list)
ads = find_ads_for_meeting(meeting)
for ad in ads:
# set the default to avoid needing extra arguments in templates
# django 1.3+
ad.default_hostscheme = site_base_url
time_slices,date_slices = build_all_agenda_slices(scheduledsessions, True)
@ -331,8 +351,9 @@ def edit_agenda(request, num=None, schedule_name=None):
"modified": modified,
"meeting":meeting,
"area_list": area_list,
"area_directors" : ads,
"wg_list": wg_list ,
"sessions": sessions,
"session_jsons": session_jsons,
"scheduledsessions": scheduledsessions,
"show_inline": set(["txt","htm","html"]) },
RequestContext(request)), mimetype="text/html")
@ -429,6 +450,18 @@ def text_agenda(request, num=None, name=None):
"plenaryt_agenda":plenaryt_agenda, },
RequestContext(request)), mimetype="text/plain")
def read_agenda_file(num, doc):
# XXXX FIXME: the path fragment in the code below should be moved to
# settings.py. The *_PATH settings should be generalized to format()
# style python format, something like this:
# DOC_PATH_FORMAT = { "agenda": "/foo/bar/agenda-{meeting.number}/agenda-{meeting-number}-{doc.group}*", }
path = os.path.join(settings.AGENDA_PATH, "%s/agenda/%s" % (num, doc.external_url))
if os.path.exists(path):
with open(path) as f:
return f.read()
else:
return None
def session_agenda(request, num, session):
d = Document.objects.filter(type="agenda", session__meeting__number=num)
if session == "plenaryt":
@ -498,18 +531,6 @@ def convert_to_pdf(doc_name):
pipe("ps2pdf "+psname+" "+outpath)
os.unlink(psname)
def read_agenda_file(num, doc):
# XXXX FIXME: the path fragment in the code below should be moved to
# settings.py. The *_PATH settings should be generalized to format()
# style python format, something like this:
# DOC_PATH_FORMAT = { "agenda": "/foo/bar/agenda-{meeting.number}/agenda-{meeting-number}-{doc.group}*", }
path = os.path.join(settings.AGENDA_PATH, "%s/agenda/%s" % (num, doc.external_url))
if os.path.exists(path):
with open(path) as f:
return f.read()
else:
return None
def session_draft_list(num, session):
try:
agenda = Document.objects.filter(type="agenda",
@ -540,7 +561,6 @@ def session_draft_list(num, session):
return sorted(result)
def session_draft_tarfile(request, num, session):
drafts = session_draft_list(num, session);

View file

@ -67,6 +67,12 @@
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="bethere" model="name.constraintname">
<field type="CharField" name="name">Person must be present</field>
<field type="TextField" name="desc"></field>
<field type="BooleanField" name="used">True</field>
<field type="IntegerField" name="order">0</field>
</object>
<object pk="obs" model="name.docrelationshipname">
<field type="CharField" name="name">Obsoletes</field>
<field type="TextField" name="desc"></field>

0
ietf/name/generate_fixtures.py Executable file → Normal file
View file

View file

@ -0,0 +1,185 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
from name.models import ConstraintName
class Migration(DataMigration):
def forwards(self, orm):
types = {'bethere': 'Person must be present'}
for slug, name in types.iteritems():
ConstraintName.objects.get_or_create(slug=slug, name=name, used=True)
def backwards(self, orm):
pass
models = {
'name.ballotpositionname': {
'Meta': {'ordering': "['order']", 'object_name': 'BallotPositionName'},
'blocking': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.constraintname': {
'Meta': {'ordering': "['order']", 'object_name': 'ConstraintName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.dbtemplatetypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DBTemplateTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.docrelationshipname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocRelationshipName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'revname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.docremindertypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocReminderTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.doctagname': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTagName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.doctypename': {
'Meta': {'ordering': "['order']", 'object_name': 'DocTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.feedbacktype': {
'Meta': {'ordering': "['order']", 'object_name': 'FeedbackType'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.groupmilestonestatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupMilestoneStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.groupstatename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupStateName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.grouptypename': {
'Meta': {'ordering': "['order']", 'object_name': 'GroupTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.intendedstdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'IntendedStdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.liaisonstatementpurposename': {
'Meta': {'ordering': "['order']", 'object_name': 'LiaisonStatementPurposeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.meetingtypename': {
'Meta': {'ordering': "['order']", 'object_name': 'MeetingTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.nomineepositionstate': {
'Meta': {'ordering': "['order']", 'object_name': 'NomineePositionState'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.rolename': {
'Meta': {'ordering': "['order']", 'object_name': 'RoleName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.sessionstatusname': {
'Meta': {'ordering': "['order']", 'object_name': 'SessionStatusName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.stdlevelname': {
'Meta': {'ordering': "['order']", 'object_name': 'StdLevelName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.streamname': {
'Meta': {'ordering': "['order']", 'object_name': 'StreamName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
},
'name.timeslottypename': {
'Meta': {'ordering': "['order']", 'object_name': 'TimeSlotTypeName'},
'desc': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '8', 'primary_key': 'True'}),
'used': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
}
}
complete_apps = ['name']
symmetrical = True

22
ietf/person/ajax.py Normal file
View file

@ -0,0 +1,22 @@
from django.utils import simplejson as json
from dajaxice.core import dajaxice_functions
from dajaxice.decorators import dajaxice_register
from ietf.ietfauth.decorators import group_required
from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse, Http404
from ietf.person.models import Person
import datetime
import logging
import sys
from ietf.settings import LOG_DIR
log = logging.getLogger(__name__)
def person_json(request, personid):
person = get_object_or_404(Person, pk=personid)
return HttpResponse(json.dumps(person.json_dict(request.build_absolute_uri("/")),
sort_keys=True, indent=2),
mimetype="text/json")

View file

@ -0,0 +1,265 @@
[
{"pk":1521, "model": "auth.user", "fields": {
"username": "wlo@amsl.com",
"first_name": "Wanda",
"last_name": "Lo",
"email": "",
"is_staff": 0,
"is_active": 1,
"is_superuser":0}},
{"pk":509, "model": "auth.user", "fields": {
"username": "wnl",
"first_name": "Wanda",
"last_name": "Lo",
"password": "sha1$e794c$18ae7fe83e0fa2a16350568818e5a9ef3a29930b",
"email": "",
"is_staff": 0,
"is_active": 1,
"is_superuser":0}},
{"pk":1614, "model": "group.role", "fields": {
"name": "secr",
"group": 4,
"person": 108757,
"email": "wlo@amsl.com"}},
{"pk": 108757, "model": "person.person", "fields": {"name": "Wanda Lo", "ascii_short": null, "time": "2012-02-26 00:04:12", "affiliation": "", "user": 509, "address": "", "ascii": "Wanda Lo"}},
{"pk":432, "model": "auth.user", "fields": {
"username": "rhousley",
"is_staff": 0,
"is_active": 1,
"is_superuser":0}},
{"pk": 5376, "model": "person.person", "fields": {
"name": "Russ Housley",
"time": "2012-02-26 00:04:18",
"affiliation": "Vigil Security, LLC",
"user": 432,
"address": "",
"ascii": "Russ Housley"}},
{"pk":314, "model": "group.role", "fields": {
"name": "chair",
"group": 2,
"person": 5376,
"email": "housley@vigilsec.com"}},
{"pk":1634, "model": "group.role", "fields": {
"name": "ad",
"group": 1008,
"person": 5376,
"email": "housley@vigilsec.com"}},
{
"pk": 432,
"model": "auth.user",
"fields": {
"username": "rhousley",
"first_name": "",
"last_name": "",
"is_active": true,
"is_superuser": false,
"is_staff": false,
"last_login": "2013-08-07 09:20:14",
"groups": [],
"user_permissions": [],
"password": "",
"email": "",
"date_joined": "2010-01-16 14:45:18"
}
},
{"pk":99870, "model": "auth.user", "fields": {
"username": "joeblow",
"is_staff": 0,
"is_active": 1,
"is_superuser":0}},
{"pk": 99871, "model": "person.person", "fields": {
"name": "Joe Blow",
"user": 99871,
"address": "",
"ascii": "Joe Blow"}},
{
"pk": 99871,
"model": "auth.user",
"fields": {
"username": "joeblow@example.com",
"first_name": "",
"last_name": "",
"is_active": true,
"is_superuser": false,
"is_staff": false,
"last_login": "2013-08-07 09:20:14",
"groups": [],
"user_permissions": [],
"password": "",
"email": "",
"date_joined": "2010-01-16 14:45:18"
}
},
{"pk":491, "model": "auth.user", "fields": {
"username": "stephen.farrell@cs.tcd.ie",
"is_staff": 0,
"is_active": 1,
"is_superuser":0}},
{"pk": 19177, "model": "person.person", "fields": {
"name": "Stephen Farrell",
"time": "2012-02-26 00:04:11",
"user": 99871,
"affiliation": "Trinity College Dublin",
"user": 491,
"ascii": "Stephen Farrell"}},
{"pk":1623, "model": "group.role", "fields": {
"name": "ad",
"group": 1260,
"person": 19177,
"email": "stephen.farrell@cs.tcd.ie"}},
{"pk":19483, "model": "person.person", "fields": {
"name": "Sean Turner",
"time": "2012-02-26 00:04:11",
"user": 12345,
"affiliation": "IECA",
"user": 492,
"ascii": "Sean Turner"}},
{
"pk": 103539,
"model": "person.person",
"fields": {
"name": "Gonzalo Camarillo",
"ascii_short": null,
"time": "2012-02-26 00:03:57",
"affiliation": "Ericsson",
"user": 445,
"address": "",
"ascii": "Gonzalo Camarillo"
}
},
{
"pk": 1648,
"model": "group.role",
"fields": {
"person": 103539,
"group": 1683,
"name": "ad",
"email": "gonzalo@example.com"
}
},
{
"pk": 445,
"model": "auth.user",
"fields": {
"username": "gonzalo@example.com",
"first_name": "",
"last_name": "",
"is_active": true,
"is_superuser": false,
"is_staff": false,
"last_login": "2013-08-02 03:19:49",
"groups": [],
"user_permissions": [],
"password": "",
"email": "",
"date_joined": "2010-02-24 00:45:28"
}
},
{
"pk": 102830,
"model": "person.person",
"fields": {
"name": "Mary Barnes",
"ascii_short": "",
"time": "2012-02-26 00:04:03",
"affiliation": "",
"user": 2365,
"address": "",
"ascii": "Mary Barnes"
}
},
{
"pk": 1512,
"model": "group.role",
"fields": {
"person": 102830,
"group": 1816,
"name": "chair",
"email": "mary.example@example.com"
}
},
{
"pk": 2365,
"model": "auth.user",
"fields": {
"username": "mary.example@example.com",
"first_name": "",
"last_name": "",
"is_active": true,
"is_superuser": false,
"is_staff": false,
"last_login": "2013-08-12 08:23:30",
"groups": [],
"user_permissions": [],
"email": "mary.example@example.com",
"date_joined": "2012-08-29 08:08:27"
}
},
{
"pk": 108554,
"model": "person.person",
"fields": {
"name": "Paul Kyzivat",
"ascii_short": null,
"time": "2012-02-26 00:04:04",
"affiliation": "",
"user": 835,
"address": "",
"ascii": "Paul Kyzivat"
}
},
{
"pk": 1516,
"model": "group.role",
"fields": {
"person": 108554,
"group": 1816,
"name": "chair",
"email": "pk+example@example.edu"
}
},
{
"pk": 835,
"model": "auth.user",
"fields": {
"username": "pk+example@example.edu",
"first_name": "",
"last_name": "",
"is_active": true,
"is_superuser": false,
"is_staff": false,
"last_login": "2013-08-08 08:16:39",
"groups": [],
"user_permissions": [],
"email": "",
"date_joined": "2011-10-10 12:35:00"
}
}
]

View file

@ -1,6 +1,7 @@
# Copyright The IETF Trust 2007, All Rights Reserved
import datetime
from urlparse import urljoin
from django.db import models
from django.contrib.auth.models import User
@ -89,21 +90,28 @@ class Person(PersonInfo):
objects = PersonManager()
user = models.OneToOneField(User, blank=True, null=True)
#this variable, if not None, may be used by url() to keep the sitefqdn.
default_hostscheme = None
def person(self): # little temporary wrapper to help porting to new schema
return self
@property
def defurl(self):
return urljoin(self.default_hostscheme,self.json_url())
def json_url(self):
return "/person/%s.json" % (self.id, )
# person json not yet implemented
#def json_dict(self, host_scheme):
# ct1 = dict()
# ct1['person_id'] = self.id
# ct1['href'] = self.url(host_scheme)
# ct1['name'] = self.name
# ct1['ascii'] = self.ascii
# ct1['affliation']= self.affliation
# return ct1
# return info about the person
def json_dict(self, hostscheme):
ct1 = dict()
ct1['person_id'] = self.id
ct1['href'] = urljoin(hostscheme, self.json_url())
ct1['name'] = self.name
ct1['ascii'] = self.ascii
ct1['affiliation']= self.affiliation
return ct1
class PersonHistory(PersonInfo):
person = models.ForeignKey(Person, related_name="history_set")

View file

@ -1,5 +1,7 @@
from django.conf.urls.defaults import patterns, url
from ietf.person import ajax
urlpatterns = patterns('',
(r'^search/$', "ietf.person.views.ajax_search_emails", None, 'ajax_search_emails'),
(r'^(?P<personid>[a-z0-9]+).json$', ajax.person_json),
)

0
ietf/templates/liaisons/field_help.html Executable file → Normal file
View file

0
ietf/templates/liaisons/guide_from_ietf.html Executable file → Normal file
View file

0
ietf/templates/liaisons/guide_to_ietf.html Executable file → Normal file
View file

View file

@ -22,10 +22,10 @@
{% dajaxice_js_import %}
<script type='text/javascript' src='/js/agenda_listeners.js'></script>
<script type='text/javascript' src='/js/agenda_helpers.js'></script>
<script type='text/javascript' src='/js/agenda_property_utils.js'></script>
<script type='text/javascript' src='/js/agendas_edit.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_listeners.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_helpers.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_property_utils.js'></script>
<script type='text/javascript' src='/js/agenda/agendas_edit.js'></script>
{% endblock pagehead %}

View file

@ -9,6 +9,11 @@
{% block morecss %}
{% for area in area_list %}
.{{ area.upcase_acronym}}-scheme, .meeting_event th.{{ area.upcase_acronym}}-scheme, #{{ area.upcase_acronym }}-groups, #selector-{{ area.upcase_acronym }} { color:{{ area.fg_color }}; background-color: {{ area.bg_color }} }
.director-mark-{{ area.upcase_acronym}} {
border: 2px solid {{ area.fg_color}};
color:{{ area.fg_color }};
background-color: {{ area.bg_color }}
}
{% endfor %}
{% endblock morecss %}
@ -29,24 +34,13 @@
<script type='text/javascript' src='/js/jquery-ui-1.9.0.custom/minified/jquery.ui.draggable.min.js'></script>
<!-- <script type='text/javascript' src='/js/jquery-ui-1.8.11.custom.min.js'></script> -->
{% if server_mode %}
{% ifnotequal server_mode "production" %}
<script src="https://towtruck.mozillalabs.com/towtruck.js"></script>
{% endifnotequal %}
{% endif %}
{% dajaxice_js_import %}
<script type='text/javascript' src='/js/spin/dist/spin.min.js'></script>
<script type='text/javascript' src='/js/agenda_edit.js'></script>
<script type='text/javascript' src='/js/agenda_helpers.js'></script>
<script type='text/javascript' src='/js/agenda_objects.js'></script>
<script type='text/javascript' src='/js/agenda_listeners.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_edit.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_helpers.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_objects.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_listeners.js'></script>
<script type='text/javascript'>
@ -64,28 +58,29 @@ function setup_slots(){
days.push("{{day}}");
{% endfor %}
{% for s in sessions %}
session_obj({"title" : "{{ s.short_name }}",
"description":"{{ s.group.name }}",
"special_request": "{{ s.special_request_token }}",
"session_id":"{{s.id}}",
"owner": "{{s.owner.owner}}",
"group_id":"{{s.group.id}}",
"area":"{{s.group.parent.acronym|upper}}",
"duration":"{{s.requested_duration.seconds|durationFormat}}",
"attendees":"{{s.attendees}}",
});
{% for ad in area_directors %}
area_directors["{{ad.area}}"] = [];
{% endfor %}
{% for ad in area_directors %}
area_directors["{{ad.area}}"].push(find_person_by_href("{{ad.defurl}}"));
{% endfor %}
{% autoescape off %}
{% for s in session_jsons %}
session_obj({{s}});
{% endfor %}
{% endautoescape %}
{% for s in scheduledsessions %}
make_ss({ "scheduledsession_id": "{{s.id}}",
"empty": "{{s.empty_str}}",
"timeslot_id":"{{s.timeslot.id}}",
"session_id" :"{{s.session.id}}",
"pinned" :"{{s.pinned}}",
{% if s.session %}{% if s.extendedfrom %}"extendedfrom_id":"{{s.extendedfrom.id}}",
{% endif %}{% endif %}"room" :"{{s.timeslot.location|slugify}}",
{% endif %}{% endif %}"room" :"{{s.timeslot.location.name|slugify}}",
{% if s.slot_to_the_right %}"following_timeslot_id":"{{s.slot_to_the_right.id}}",
{% endif %}"roomtype" :"{{s.slottype|lower}}",
{% endif %}"roomtype" :"{{s.slottype}}",
"time" :"{{s.timeslot.time|date:'Hi' }}",
"date" :"{{s.timeslot.time|date:'Y-m-d'}}",
"domid" :"{{s.timeslot.js_identifier}}"});
@ -141,6 +136,17 @@ Please save this agenda to your account first.
<button class="styled_button">all agendas</button>
</a>
</div>
<div id="hidden_room" class="hide_buttons events_bar_buttons">
<div class="very_small left">hidden rooms:<span id="hidden_rooms" >0/{{rooms|length}}</span></div>
<div><button class="small_button" id="show_hidden_rooms">Show</button></div>
</div>
<div id="hidden_day" class="hide_buttons events_bar_buttons">
<div class="very_small left">hidden days:<span id="hidden_days" >0/{{time_slices|length}}</span></div>
<div><button class="small_button" id="show_hidden_days">Show</button></div>
</div>
</div>
<div id="unassigned_order" class="events_bar_buttons">
<select id="unassigned_sort_button" class="dialog">
<option id="unassigned_alpha" value="alphaname" selected>Alphabetical</option>
@ -219,15 +225,16 @@ Please save this agenda to your account first.
{% for r in rooms %}
<tr id="{{r|to_acceptable_id}}" class="{% cycle 'agenda_row_alt' '' %} agenda_slot">
<tr id="{{r.name|to_acceptable_id}}" class="{% cycle 'agenda_row_alt' '' %} agenda_slot">
<th class="vert_time">
<div class="close very_small close_room top_left small_button" id="close_{{r|to_acceptable_id}}">X</div>
<div class="right room_name">{{r}} <span class="capacity">({{r.capacity}})</span></div>
<div class="close very_small close_room top_left small_button" id="close_{{r.name|to_acceptable_id}}">X</div>
<div class="right room_name">{{r.name}} <span class="capacity">({{r.capacity}})</span></div>
<!-- <span class="hide_room light_blue_border">X</span><span class="left">{{r}}</span></th> -->
<!-- <span class="hide_room light_blue_border">X</span><span class="left">{{r.name}}</span>-->
</th>
{% for day in time_slices %}
{% for slot in date_slices|lookup:day %}
<td id="{{r|slugify}}_{{day}}_{{slot.0|date:'Hi'}}" class="day_{{day}} agenda-column-{{day}}-{{slot.0|date:'Hi'}} agenda_slot agenda_slot_unavailable" capacity="{{r.capacity}}" ></td>
<td id="{{r.name|slugify}}_{{day}}_{{slot.0|date:'Hi'}}" class="day_{{day}} agenda-column-{{day}}-{{slot.0|date:'Hi'}} agenda_slot agenda_slot_unavailable" capacity="{{r.capacity}}" ></td>
{% endfor %}
<td class="day_{{day}} spacer {{day|date:'Y-m-d'}}-spacer"></td>
{% endfor %}
@ -246,9 +253,10 @@ Please save this agenda to your account first.
<div class="ss_info_box">
<div class="ss_info ss_info_left">
<table>
<tr><td class="ss_info_name_short">Group:</td><td id="info_grp"></td></tr>
<tr><td class="ss_info_name_short">Name:</td><td id="info_name"></td></tr>
<tr><td class="ss_info_name_short">Area:</td><td><span id="info_area"></span><button id="show_all_area" class="right">Show All</button></td></tr>
<tr><td class="ss_info_name_short">Group:</td><td><span id="info_grp"></span>
<!-- <button id="agenda_sreq_button" class="right">Edit Request</button> --></tr>
<tr><td class="ss_info_name_short">Name:</td> <td d="info_name"></td></tr>
<tr><td class="ss_info_name_short">Area:</td> <td><span id="info_area"></span><button id="show_all_area" class="right">Show All</button></td></tr>
</table>
</div>
@ -264,45 +272,25 @@ Please save this agenda to your account first.
<div id="conflict_table">
<div id="special_requests">Special Requests</div>
<table>
<tr>
<th class="heading" colspan=2>conflict 1 <span class="small right cb_all_conflict">show all<input id="cb_conflict1" type="checkbox"></span></th>
<th class="border"></th>
<th class="heading" colspan=2>conflict 2<span class="small right cb_all_conflict">show all<input id="cb_conflict2" type="checkbox"></span></th>
<th class="border"></th>
<th class="heading" colspan=2>conflict 3<span class="small right cb_all_conflict">show all<input id="cb_conflict3" type="checkbox"></span></th>
</tr>
<tbody id="conflict_table_body">
<tr id="row01">
<td class="conflict1"></td>
<td class="conflict1"></td>
<td class="border"></td>
<td class="conflict2"></td>
<td class="conflict2"></td>
<td class="border"></td>
<td class="conflict3"></td>
<td class="conflict3"></td>
</tr>
<tr id="row02">
<td class="conflict1"></td>
<td class="conflict1"></td>
<td class="border"></td>
<td class="conflict2"></td>
<td class="conflict2"></td>
<td class="border"></td>
<td class="conflict3"></td>
<td class="conflict3 empty"></td>
</tr>
<tr id="row03">
<td class="conflict1 empty"></td>
<td class="conflict1 empty"></td>
<td class="border"></td>
<td class="conflict2 empty"></td>
<td class="conflict2 empty"></td>
<td class="border"></td>
<td class="conflict3 empty"></td>
<td class="conflict3 empty"></td>
</tr>
<tr class="conflict_list_row">
<td class="conflict_list_title">
Group conflicts
</td>
<td id="conflict_group_list">
<ul>
</ul>
</td>
</tr>
<tr class="conflict_list_row">
<td class="conflict_list_title">
<b>be present</b>
</td>
<td id="conflict_people_list">
<ul>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
@ -311,6 +299,10 @@ Please save this agenda to your account first.
<button class="agenda_selected_buttons small_button" disabled
id="double_slot">Extend</button>
</div>
<div id="agenda_pin_slot" class="button_disabled">
<button class="agenda_selected_buttons small_button" disabled
id="pin_slot">Pin</button>
</div>
<div class="color_legend">
{% for area in area_list %}
<span class="{{area.upcase_acronym}}-scheme"><input class='color_checkboxes' type="checkbox" id="{{area.upcase_acronym}}" value="{{area.upcase_acronym}}-value" checked>{{area.upcase_acronym}}</span>
@ -318,19 +310,6 @@ Please save this agenda to your account first.
</div>
</div>
<div class="show_hidden_things">
<div class="hide_buttons">
<div class="very_small left">hidden rooms:<span id="hidden_rooms" >0/{{rooms|length}}</span></div>
<div class="right"><button class="small_button" id="show_hidden_rooms">Show</button></div>
</div>
<div class="hide_buttons">
<div class="very_small left">hidden days:<span id="hidden_days" >0/{{time_slices|length}}</span></div>
<div class="right"><button class="small_button" id="show_hidden_days">Show</button></div>
</div>
</div>
<div class="agenda_save_box">
<div id="agenda_title"><b>Agenda name: </b><span>{{schedule.name}}</span></div>
@ -347,10 +326,31 @@ Please save this agenda to your account first.
</div>
<!-- some boxes for dialogues -->
<div id="dialog-confirm" title="" style="display:none">
<div id="dialog-confirm-two" title="" style="display:none">
<p>
<span class="ui-icon ui-icon-alert" style="background: white; float: left; margin: 0 7px 20px 0;"></span>
<span id="dialog-confirm-text"></span>
<span class="dialog-confirm-text">Are you sure you want to put two sessions into the same slot?</span>
</p>
</div>
<div id="dialog-confirm-toosmall" title="" style="display:none">
<p>
<span class="ui-icon ui-icon-alert" style="background: white; float: left; margin: 0 7px 20px 0;"></span>
<span class="dialog-confirm-text">The room you are moving to has a lower
room capacity then the requested capacity,<br>
Are you sure you want to continue?
</span>
</p>
</div>
<div id="dialog-confirm-twotoosmall" title="" style="display:none">
<p>
<span class="ui-icon ui-icon-alert" style="background: white; float: left; margin: 0 7px 20px 0;"></span>
<span class="dialog-confirm-text">
The slot you are moving to already has a session in it, <br>
the room is also smaller than the requested amount.<br>
Are you sure you want to continue?
</span>
</p>
</div>

View file

@ -23,10 +23,10 @@
{% dajaxice_js_import %}
<script type='text/javascript' src='/js/agenda_listeners.js'></script>
<script type='text/javascript' src='/js/agenda_helpers.js'></script>
<script type='text/javascript' src='/js/agenda_property_utils.js'></script>
<script type='text/javascript' src='/js/agenda_properties_edit.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_listeners.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_helpers.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_property_utils.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_properties_edit.js'></script>
{% endblock pagehead %}

View file

@ -28,11 +28,11 @@
{% dajaxice_js_import %}
<script type='text/javascript' src='/js/spin.js'></script>
<script type='text/javascript' src='/js/timeslot_edit.js'></script>
<script type='text/javascript' src='/js/agenda_helpers.js'></script>
<script type='text/javascript' src='/js/agenda_objects.js'></script>
<script type='text/javascript' src='/js/agenda_listeners.js'></script>
<script type='text/javascript' src='/js/spin/dist/spin.min.js'></script>
<script type='text/javascript' src='/js/agenda/timeslot_edit.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_helpers.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_objects.js'></script>
<script type='text/javascript' src='/js/agenda/agenda_listeners.js'></script>
<script type='text/javascript'>

View file

@ -1,6 +1,15 @@
.IETF-scheme, .meeting_event th.IETF-scheme, #IETF-groups, #selector-IETF {
color: black;
background-color: white;
}
.IAB-scheme, .meeting_event th.IAB-scheme, #IAB-groups, #selector-IAB {
color: black;
background-color: white;
}
.custom_text_stuff{
position: relative;
margin-top: 40px;
margin-top: 0px;
text-align: center;
font-size: 14px;
font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
@ -60,6 +69,20 @@
right: 5px;
}
.hide_buttons{
margin:4px;
min-width:150px;
color:white;
}
#hidden_room {
right: 200px;
}
#hidden_day {
right: 400px;
}
#unassigned_order {
position: absolute;
top: 3px;
@ -96,6 +119,10 @@ div.meeting_box_bucket_list {
float: left;
}
div.meeting_box_pinned {
/* not sure what to put here yet */
}
table.meeting_event {
/* border:1px solid black; */
/* background:#E0FFFF; */
@ -347,6 +374,16 @@ td.ss_info_name_short{
margin-left:3px;
}
#agenda_pin_slot {
border: 1px solid #89D;
background-color: #EDF5FF;
padding: 5px;
max-width: 150px;
float:left;
margin-top:70px;
margin-left:3px;
}
.button_disabled {
color: #EDF4FF;
text-color: #EDF4FF;
@ -356,6 +393,15 @@ td.ss_info_name_short{
text-color: black;
}
.button_up {
background: #4479BA;
color: #FFF;
}
.button_down {
color: #4479BA;
background: #FFF;
}
.agenda_save_box {
position: absolute;
right: 3px;
@ -373,6 +419,7 @@ td.ss_info_name_short{
}
.schedule_title {
min-width: 100px;
font-size: 10px;
font-family: serif; /* live life a bit */
}
@ -442,15 +489,64 @@ div#conflict_table {
background-color: #89D;
}
div.our-conflict {
padding-left: 20px;
background-image: url('/images/conflict-boxes/narow3.png');
background-position: 8px 50%;
background-repeat: no-repeat;
}
div.our-conflic2 {
padding-left: 20px;
background-image: url('/images/conflict-boxes/narow2.png');
background-position: 8px 50%;
background-repeat: no-repeat;
}
div.our-conflic3 {
padding-left: 20px;
background-image: url('/images/conflict-boxes/narow1.png');
background-position: 8px 50%;
background-repeat: no-repeat;
}
#conflict_table div.conflict {
text-align: left;
padding-top: 2px;
height: 20px;
text-align: left;
}
#conflict_table div.conflict1 {
#conflict_group_list li.conflict {
float: left;
display: inline;
list-style: none;
/* border: 1px solid green; */
width: 80px;
/* height: 20px; */
margin: 1px 2px;
}
#conflict_table div.conflict1 {
#conflict_people_list li.conflict {
float: left;
display: inline;
list-style: none;
padding-bottom: 3px;
/* border: 1px solid green; */
width: 120px;
/* height: 20px; */
margin: 1px 2px;
}
#conflict_table div.conflict1 {
td.conflict_list_title {
width: 30px;
}
td#conflict_group_list {
width: 576px;
}
td#conflict_people_list {
width: 576px;
}
.agenda_column_2012-03-30__1120 {
background-color: red;
@ -533,8 +629,23 @@ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#99beff', end
}
.show_conflict_specific_box {
border: 3px solid red;
}
.show_conflic2_specific_box {
border: 2px solid red;
}
.show_conflic3_specific_box {
border: 1px solid red;
}
.personconflict {
}
.hidepersonconflict {
display: none;
}
.showpersonconflict {
display: inline;
}
.same_group {
background-color: green;
@ -546,9 +657,29 @@ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#99beff', end
background-color: purple;
}
/*
* table.actual* is used in the grid to indicate a conflict.
* div.our-conflic* is used in the info display to give more details
* div.their-conflic* shows the same thing in the opposite direction.
*/
table.actual_conflict {
padding-left: 20px;
background-image: url('/images/clker-1195427724688380074fire_cefa_01.png');
background-image: url('/images/conflict-boxes/narow3.png');
background-position: 8px 50%;
background-repeat: no-repeat;
}
table.actual_conflic2 {
padding-left: 20px;
background-image: url('/images/conflict-boxes/narow2.png');
background-position: 8px 50%;
background-repeat: no-repeat;
}
table.actual_conflic3 {
padding-left: 20px;
background-image: url('/images/conflict-boxes/narow1.png');
background-position: 8px 50%;
background-repeat: no-repeat;
}
@ -627,7 +758,6 @@ table.actual_conflict {
}
.show_hidden_things{
position: absolute;
right: 200px;
bottom: 5px;
@ -642,14 +772,6 @@ table.actual_conflict {
}
.hide_buttons{
margin:4px;
float:left;
min-width:150px;
border-bottom:1px solid #89D;
}
.room_name{
margin-left:12px;
margin-right:4px;
@ -672,7 +794,8 @@ table.actual_conflict {
}
.free_slot{
background-color:rgb(0, 102, 153) !important; /* the important tag should fix any precedence issues */
background-image: url('/images/empty.png') no-repeat;
/* background-color:rgb(0, 102, 153) !important; /* the important tag should fix any precedence issues */
}
@ -900,4 +1023,25 @@ div.line{
.th_column{ /* we need this or the other floating th's won't expand correctly */
min-width:100px;
}
}
.director-right {
float: right;
}
.director-rightup {
position: absolute;
right: 4px;
top: -8px;
}
.director-mark {
border-radius: 6px;
margin-bottom: 1px;
margin-top: 0px;
font-size: 6pt;
padding-left: 2px;
padding-right: 2px;
padding-top: 0px;
padding-bottom: 0px;
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

View file

@ -29,6 +29,7 @@ var slot_status = {}; // indexed by domid, contains an array of ScheduledSes
var slot_objs = {}; // scheduledsession indexed by id.
var group_objs = {}; // list of working groups
var area_directors = {}; // list of promises of area directors, index by href.
var read_only = true; // it is true until we learn otherwise.
var days = [];
@ -68,20 +69,28 @@ $(document).ready(function() {
function initStuff(){
log("initstuff() running...");
setup_slots();
directorpromises = mark_area_directors();
log("setup_slots() ran");
droppable();
log("droppable() ran");
load_all_groups(); // should be in a single big block.
log("groups loaded");
load_events();
log("load_events() ran");
find_meeting_no_room();
listeners();
$.when.apply($,directorpromises).done(function() {
/* can not load events until area director info has been loaded */
log("droppable() ran");
load_events();
log("load_events() ran");
find_meeting_no_room();
listeners();
droppable();
duplicate_sessions = find_double_timeslots();
if(load_conflicts) {
recalculate(null);
}
});
static_listeners();
log("listeners() ran");
calculate_name_select_box();
duplicate_sessions = find_double_timeslots();
start_spin();
@ -94,11 +103,6 @@ function initStuff(){
/* Comment this out for fast loading */
//load_conflicts = false;
if(load_conflicts) {
recalculate(null);
}
}
var __READ_ONLY;

View file

@ -3,7 +3,7 @@
*
* Copyright (c) 2013, The IETF Trust. See ../../../LICENSE.
*
* www.credil.org: Project Orlando 2013
* www.credil.org: Project Orlando 2013
* Author: Justin Hornosty ( justin@credil.org )
* Michael Richardson <mcr@sandelman.ca>
*
@ -135,6 +135,7 @@ function style_empty_slots(){
}
var __debug_load_events = false;
/* this pushes every event into the agendas */
function load_events(){
console.log("load events...");
@ -142,6 +143,9 @@ function load_events(){
/* first delete all html items that might have gotten saved if
* user save-as and went offline.
*/
if(__debug_load_events) {
console.log("processing double slot status relations");
}
$.each(slot_status, function(key) {
ssid_arr = slot_status[key];
@ -153,12 +157,16 @@ function load_events(){
// well as backwards.
if(ssid.extendedfrom_id != false) {
other = slot_objs[ssid.extendedfrom_id];
console.log("slot:",ssid.scheduledsession_id, "extended from: ",key,ssid.extendedfrom_id); // ," is: ", other);
if(__debug_load_events) {
console.log("slot:",ssid.scheduledsession_id, "extended from: ",key,ssid.extendedfrom_id); // ," is: ", other);
}
if(other != undefined) {
ssid.extendedfrom = other;
other.extendedto = ssid;
} else {
console.log("extended from: ",ssid.extendedfrom_id," not found");
if(__debug_load_events) {
console.log("extended from: ",ssid.extendedfrom_id," not found");
}
}
}
}
@ -166,6 +174,9 @@ function load_events(){
// go through the slots again, and if one slot has been extended, then
// extend any other "sister" slots as well.
if(__debug_load_events) {
console.log("marking extended slots for slots with multiple sessions");
}
$.each(slot_status, function(key) {
ssid_arr = slot_status[key];
@ -174,55 +185,78 @@ function load_events(){
ssid = ssid_arr[q];
if(extendedto == undefined &&
ssid.extendedto != undefined) {
if(__debug_load_events) {
console.log("ssid",ssid.session_id,"extended");
}
extendedto = ssid.extendedto;
}
}
for(var q = 0; q<ssid_arr.length; q++){
ssid = ssid_arr[q];
ssid.extendedto = extendedto;
if(__debug_load_events) {
console.log("ssid",ssid.session_id,"extended");
}
}
});
if(__debug_load_events) {
console.log("finding responsible ad");
}
$.each(meeting_objs, function(key) {
session = meeting_objs[key];
session.find_responsible_ad();
});
$.each(slot_status, function(key) {
ssid_arr = slot_status[key]
if(key == "sortable-list"){
//console.log("sortable list");
}else{
console.log("sortable list");
}else {
for(var q = 0; q<ssid_arr.length; q++){
ssid = ssid_arr[q];
slot_id = ("#"+ssid.domid);
//$(slot_id).css('background-color',color_droppable_empty_slot ); //'#006699'
for(var q = 0; q<ssid_arr.length; q++){
ssid = ssid_arr[q];
slot_id = ("#"+ssid.domid);
//console.log("removing class from "+ssid.domid);
/* also, since we are HERE, set the class to indicate if slot is available */
$(slot_id).addClass("agenda_slot_" + ssid.roomtype);
$(slot_id).removeClass("agenda_slot_unavailable");
session = meeting_objs[ssid.session_id];
if (session != null) {
if(ssid.extendedto != undefined) {
session.double_wide = true;
session.slot2 = ssid.extendedto;
if(__debug_load_events) {
console.log("populating slot: ",slot_id,key);
}
if(ssid.extendedfrom == undefined) {
session.slot_status_key = key;
/* also, since we are HERE, set the class to indicate if slot is available */
$(slot_id).addClass("agenda_slot_" + ssid.roomtype);
if(ssid.roomtype == "unavail") {
$(slot_id).removeClass("ui-droppable");
$(slot_id).removeClass("free_slot");
$(slot_id).addClass("agenda_slot_unavailable");
} else {
$(slot_id).removeClass("agenda_slot_unavailable");
$(slot_id).addClass("ui-droppable");
session = meeting_objs[ssid.session_id];
if (session != null) {
if(ssid.extendedto != undefined) {
session.double_wide = true;
session.slot2 = ssid.extendedto;
}
if(ssid.extendedfrom == undefined) {
session.slot_status_key = key;
}
$(slot_id).removeClass('free_slot');
if(ssid.extendedfrom == undefined) {
if(__debug_load_events) {
console.log(" with session", session.title);
}
session.populate_event(key);
}
session.placed(ssid, false);
} else {
$(slot_id).addClass('free_slot');
}
}
$(slot_id).removeClass('free_slot');
if(ssid.extendedfrom == undefined) {
session.populate_event(key);
}
//log("setting "+slot_id+" as used");
session.placed(ssid, false);
} else {
$(slot_id).addClass('free_slot');
}
}
}
});
$.each(meeting_objs, function(key) {
@ -279,7 +313,7 @@ function find_friends(inp){
return ss_arr;
}
else{
console.log("find_friends("+inp+") did not find anything");
//console.log("find_friends("+inp+") did not find anything");
return null;
}
}
@ -508,13 +542,12 @@ var child = null;
function remove_duplicate(timeslot_id, ss_id){
children = $("#"+timeslot_id).children();
child = children;
console.log(children);
for(var i = 0; i< children.length; i++){ // loop to
if($(children[i]).attr('session_id') == ss_id) { // make sure we only remove duplicate.
try{
$(children[i]).remove();
}catch(exception){
console.log(exception);
console.log("exception from remove_duplicate",exception);
}
}
}

View file

@ -3,7 +3,7 @@
*
* Copyright (c) 2013, The IETF Trust. See ../../../LICENSE.
*
* www.credil.org: Project Orlando 2013
* www.credil.org: Project Orlando 2013
* Author: Justin Hornosty ( justin@credil.org )
* Michael Richardson <mcr@sandelman.ca>
*
@ -29,7 +29,9 @@ function resize_listeners() {
/* this function needs to be renamed... it should only deal with listeners who need to be unbound prior to rebinding. */
/* this function needs to be renamed...
it should only deal with listeners who need to be unbound prior to rebinding.
*/
function listeners(){
//$(".agenda_slot td").not(".meeting_event ui-draggable").unbind('click');
//$(".agenda_slot td").not(".meeting_event ui-draggable").click(function(event){ console.log("#meetings clicked"); console.log(event); });
@ -80,41 +82,42 @@ function listeners(){
$("#show_all_button").click(show_all);
resize_th();
}
function toggle_dialog(session, to_slot_id, to_slot, from_slot_id, from_slot, bucket_list, event, ui, dom_obj, slot_occupied, too_small){
var __debug_movement_warnings = false;
var __debug_toggle_result;
var __debug_toggle_parameters;
function toggle_dialog(parameters) {
var result = "null";
var message = "";
console.log(session, to_slot_id, to_slot, from_slot_id, from_slot, bucket_list, event, ui, dom_obj);
if(slot_occupied && !too_small){
message = "Are you sure you want to put two sessions into the same slot?"
if(parameters.slot_occupied==true && parameters.too_small==false) {
dialogid = $( "#dialog-confirm-two" );
}
else if(too_small && !slot_occupied){
message = "The room you are moving to has a lower room capacity then the requested capacity,<br>Are you sure you want to continue?";
else if(parameters.slot_occupied==false && parameters.too_small==true) {
dialogid = $( "#dialog-confirm-toosmall" );
}
else if(too_small && slot_occupied){
message = "The slot you are moving to already has a session in it, the room is also smaller than the requested amount.<br>Are you sure you want to continue?";
else if(parameters.too_small==true && parameters.slot_occupied==true){
dialogid = $( "#dialog-confirm-twotoosmall" );
}
else{
console.log("error, from toggle_dialog:",session, to_slot_id, to_slot, from_slot_id, from_slot, bucket_list, event, ui, dom_obj, slot_occupied, too_small);
return
}
console.log("error, from toggle_dialog:", parameters);
return;
}
$("#dialog-confirm-text").html(message);
$( "#dialog-confirm" ).dialog({
if(__debug_movement_warnings) {
console.log("toggle_dialog param", parameters, "message", message);
__debug_toggle_parameters = parameters;
}
dialogid.dialog({
resizable: true,
modal: true,
buttons: {
"Yes": function() {
$( this ).dialog( "close" );
result = "yes";
session.double_wide = false;
move_slot(session,
to_slot_id, to_slot,
from_slot_id, from_slot,
bucket_list, event, ui, dom_obj, /* same_timeslot=*/true);
__debug_toggle_result = "yes";
parameters.session.double_wide = false;
move_slot(parameters);
},
//"Swap Slots": function(){
// $( this ).dialog( "close" );
@ -122,16 +125,12 @@ function toggle_dialog(session, to_slot_id, to_slot, from_slot_id, from_slot, bu
//},
Cancel: function() {
$( this ).dialog( "close" );
result = "cancel"
__debug_toggle_result = "cancel"
}
}
});
return result;
return __debug_toggle_result;
}
function resize_th(){
@ -434,30 +433,17 @@ function static_listeners(){
sort_unassigned();
}
// this is a counter that keeps track of when all of the constraints have
// been loaded. This could be replaced with a $.Deferred().when mechanism.
// it is reset in recalculate().
var CONFLICT_LOAD_COUNT = 0;
function increment_conflict_load_count() {
CONFLICT_LOAD_COUNT++;
//console.log(CONFLICT_LOAD_COUNT+"/"+meeting_objs_length);
}
// recalculate all conflicts from scratch
function recalculate(event) {
start_spin();
console.log("loading all conflicts");
CONFLICT_LOAD_COUNT = 0;
get_all_conflicts();
do_work(function() {
return CONFLICT_LOAD_COUNT >= meeting_objs_length;
},
function() {
stop_spin();
console.log("showing all conflicts");
show_all_conflicts();
});
var promise = get_all_conflicts();
promise.done(function() {
stop_spin();
console.log("showing all conflicts");
show_all_conflicts();
});
}
function color_legend_click(event){
@ -496,7 +482,7 @@ function set_transparent(){
}else{
$("."+k+"-scheme.meeting_obj").parent().parent().parent().draggable("option","disabled",false);
}
});
}
@ -534,13 +520,9 @@ function meeting_event_click(event){
var container = $(event.target).closest('.meeting_box_container');
if(container == undefined) {
// 20130606 XXX WHEN IS THIS USED?
var slot_obj = { slot_id: meeting_event_id ,
scheduledsession_id:meeting_event_id,
timeslot_id: null,
session_id: meeting_event_id,
}
session.load_session_obj(fill_in_session_info, session.slot);
fill_in_session_info(session, true, session.slot);
// no async necessary, session is completely loaded
//session.load_session_obj(fill_in_session_info, session.slot);
return;
}
@ -560,7 +542,7 @@ function meeting_event_click(event){
}
empty_info_table();
session.load_session_obj(fill_in_session_info, session.slot);
fill_in_session_info(session, true, session.slot);
__DEBUG__SLOT_OBJ = current_timeslot;
__DEBUG__SESSION_OBJ = session;
}
@ -613,13 +595,13 @@ function info_name_select_change(){
last_session = session;
last_session.selectit();
// now set up the call back that might have to retrieve info.
session.load_session_obj(fill_in_session_info, ss);
fill_in_session_info(session, true, ss);
}
else {
ss = meeting_objs[slot_id];
last_session = ss;
last_session.selectit();
ss.load_session_obj(fill_in_session_info, ss);
fill_in_session_info(ss, true, ss.slot);
}
console.log("selecting new item:", last_session.title);
@ -655,6 +637,53 @@ function dajaxice_error(a){
console.log("dajaxice_error");
}
function set_pin_session_button(scheduledsession) {
$("#pin_slot").unbind('click');
if(scheduledsession == undefined) {
return;
}
state = scheduledsession.pinned;
console.log("button set to: ",state);
if(state) {
$("#pin_slot").html("unPin");
$("#agenda_pin_slot").addClass("button_down");
$("#agenda_pin_slot").removeClass("button_up");
$("#pin_slot").click(function(event) {
update_pin_session(scheduledsession, 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);
});
}
}
function update_pin_session(scheduledsession, state) {
start_spin();
console.log("Calling dajaxice", scheduledsession, state);
Dajaxice.ietf.meeting.update_timeslot_pinned(function(message) {
console.log("dajaxice callback");
stop_spin();
if(message.message != "valid") {
alert("Update of pinned failed");
return;
}
scheduledsession.pinned = state;
session = scheduledsession.session()
session.pinned = state;
session.repopulate_event(scheduledsession.domid);
set_pin_session_button(scheduledsession);
},
{
'schedule_id': schedule_id,
'scheduledsession_id': scheduledsession.scheduledsession_id,
'pinned': state
});
}
function fill_in_session_info(session, success, extra) {
if(session == null || session == "None" || !success){
empty_info_table();
@ -665,7 +694,20 @@ function fill_in_session_info(session, success, extra) {
$(".agenda_double_slot").addClass("button_enabled");
$(".agenda_selected_buttons").attr('disabled',false);
session.retrieve_constraints_by_session(draw_constraints, function(){});
if(!read_only) {
$("#agenda_pin_slot").removeClass("button_disabled");
$("#agenda_pin_slot").addClass("button_enabled");
set_pin_session_button(session.slot);
} else {
$("#pin_slot").unbind('click');
}
// here is where we would set up the session request edit button.
// $(".agenda_sreq_button").html(session.session_req_link);
session.retrieve_constraints_by_session().success(function(newobj,status,jq) {
draw_constraints(session);
});
}
function group_name_or_empty(constraint) {
@ -677,60 +719,43 @@ function group_name_or_empty(constraint) {
}
function draw_constraints(session) {
$("#conflict_table_body").html("");
//console.log("5 fill", session.title);
if(!"conflicts" in session) {
console.log("6 done");
return;
if("conflicts" in session) {
var group_icons = "";
$.each(session.conflicts, function(index) {
conflict = session.conflicts[index];
if(conflict.conflict_groupP()) {
group_icons += "<li class='conflict'>"+conflict.conflict_view();
highlight_conflict(conflict);
}
});
if(group_icons == "") {
$("#conflict_group_list").html("none");
} else {
$("#conflict_group_list").html("<ul>"+group_icons+"</ul>");
}
} else {
$("#conflict_group_list").html("none");
}
if("bethere" in session.constraints) {
var people_icons = "";
$.each(session.constraints.bethere, function(index) {
conflict = session.constraints.bethere[index];
if(conflict.conflict_peopleP()) {
people_icons += "<li class='conflict'>"+conflict.conflict_view();
}
});
if(people_icons == "") {
$("#conflict_people_list").html("none");
} else {
$("#conflict_people_list").html("<ul>"+people_icons+"</ul>");
}
} else {
$("#conflict_people_list").html("none");
}
var conflict1_a = session.conflicts[1][0];
var conflict1_b = session.conflicts[1][1];
var conflict2_a = session.conflicts[2][0];
var conflict2_b = session.conflicts[2][1];
var conflict3_a = session.conflicts[3][0];
var conflict3_b = session.conflicts[3][1];
for(var i=0; i<=session.conflict_half_count; i++) {
$("#conflict_table_body").append("<tr><td class='conflict1'>"+
group_name_or_empty(conflict1_a[i])+
"</td>"+
"<td class='conflict1'>"+
group_name_or_empty(conflict1_b[i])+
"</td><td class='border'></td>"+
"<td class='conflict2'>"+
group_name_or_empty(conflict2_a[i])+
"</td>"+
"<td class='conflict2'>"+
group_name_or_empty(conflict2_b[i])+
"</td><td class='border'></td>"+
"<td class='conflict3'>"+
group_name_or_empty(conflict3_a[i])+
"</td>"+
"<td class='conflict3'>"+
group_name_or_empty(conflict3_b[i])+
"</tr>");
highlight_conflict(conflict1_a[i]);
highlight_conflict(conflict1_b[i]);
highlight_conflict(conflict2_a[i]);
highlight_conflict(conflict2_b[i]);
highlight_conflict(conflict3_a[i]);
highlight_conflict(conflict3_b[i]);
// console.log("draw", i,
// group_name_or_empty(conflict1_a[i]),
// group_name_or_empty(conflict1_b[i]),
// group_name_or_empty(conflict2_a[i]),
// group_name_or_empty(conflict2_b[i]),
// group_name_or_empty(conflict3_a[i]),
// group_name_or_empty(conflict3_b[i]));
}
// setup check boxes for conflicts
$('.conflict_checkboxes').unbind('click');
$('.conflict_checkboxes').click(conflict_click);
}
function highlight_conflict(constraint) {
@ -785,7 +810,7 @@ function droppable(){
start: drop_start,
})
$("#meetings td").droppable({
$("#meetings td.ui-droppable").droppable({
over :drop_over,
activate:drop_activate,
out :drop_out,
@ -886,12 +911,12 @@ function drop_drop(event, ui){
var too_small = false;
var occupied = false;
if(from_slot_id == to_slot_id){ // hasn't moved don't do anything
return
}
if(session_attendees > room_capacity){
too_small = true;
}
@ -908,10 +933,17 @@ function drop_drop(event, ui){
}
if(too_small || occupied){
toggle_dialog(session,
to_slot_id, to_slot,
from_slot_id, from_slot,
bucket_list, event, ui, this, occupied, too_small);
toggle_dialog({ "session": session,
"to_slot_id": to_slot_id,
"to_slot": to_slot,
"from_slot_id": from_slot_id,
"from_slot": from_slot,
"bucket_list": bucket_list,
"event": event,
"ui": ui,
"dom_obj": this,
"slot_occupied": occupied,
"too_small": too_small});
return
}
@ -920,18 +952,25 @@ function drop_drop(event, ui){
// (could return if necessary)
session.double_wide = false;
move_slot(session,
to_slot_id, to_slot,
from_slot_id, from_slot,
bucket_list, event, ui, this, /* force=*/false);
move_slot({"session": session,
"to_slot_id": to_slot_id,
"to_slot": to_slot,
"from_slot_id":from_slot_id,
"from_slot": from_slot,
"bucket_list": bucket_list,
"event": event,
"ui": ui,
"dom_obj": this,
"force": false});
}
function recalculate_conflicts_for_session(session, old_column_classes, new_column_classes)
{
// go recalculate things
session.clear_conflict();
session.retrieve_constraints_by_session(find_and_populate_conflicts,
function() {});
session.clear_all_conflicts();
find_and_populate_conflicts(session);
session.examine_people_conflicts(old_column_classes);
var sk;
for(sk in meeting_objs) {
@ -956,8 +995,8 @@ function recalculate_conflicts_for_session(session, old_column_classes, new_colu
column_class.column_tag == old_column_class.column_tag)) {
console.log("recalculating conflicts for:", s.title);
s.clear_conflict();
s.retrieve_constraints_by_session(find_and_populate_conflicts,
function() {});
find_and_populate_conflicts(s);
s.examine_people_conflicts();
}
}
}
@ -969,48 +1008,46 @@ function recalculate_conflicts_for_session(session, old_column_classes, new_colu
var _move_debug = false;
var _LAST_MOVED;
function move_slot(session,
to_slot_id, to_slot,
from_slot_id, from_slot,
bucket_list, event, ui, thiss,
same_timeslot){
/* thiss: is a jquery selector of where the slot will be appeneded to
Naming is in regards to that most often function is called from drop_drop where 'this' is the dom dest.
function move_slot(parameters) {
/* dom_obj: is a jquery selector of where the slot will be appeneded to
Naming is in regards to that most often function is called from
drop_drop where 'this' is the dom dest.
*/
var update_to_slot_worked = false;
if(_move_debug) {
_LAST_MOVED = session;
if(from_slot != undefined) {
console.log("from_slot", from_slot.domid);
_LAST_MOVED = parameters.session;
if(parameters.from_slot != undefined) {
console.log("from_slot", parameters.from_slot.domid);
} else {
console.log("from_slot was unassigned");
}
}
var update_to_slot_worked = false;
if(same_timeslot == null){
same_timeslot = false;
if(parameters.same_timeslot == null){
parameters.same_timeslot = false;
}
if(bucket_list) {
update_to_slot_worked = update_to_slot(session.session_id, to_slot_id, true);
if(parameters.bucket_list) {
update_to_slot_worked = update_to_slot(parameters.session.session_id,
parameters.to_slot_id, true);
}
else{
update_to_slot_worked = update_to_slot(session.session_id, to_slot_id, same_timeslot);
update_to_slot_worked = update_to_slot(parameters.session.session_id,
parameters.to_slot_id, parameters.same_timeslot);
}
if(_move_debug) {
console.log("update_slot_worked", update_to_slot_worked);
}
if(update_to_slot_worked){
if(update_from_slot(session.session_id, from_slot_id)){
remove_duplicate(from_slot_id, session.session_id);
if(update_from_slot(parameters.session.session_id, parameters.from_slot_id)){
remove_duplicate(parameters.from_slot_id, parameters.session.session_id);
// do something
}
else{
if(_move_debug) {
console.log("issue updateing from_slot");
console.log("from_slot_id",from_slot_id, slot_status[from_slot_id]);
console.log("parameters.from_slot_id",parameters.from_slot_id, slot_status[parameters.from_slot_id]);
}
return;
}
@ -1018,77 +1055,74 @@ function move_slot(session,
else{
if(_move_debug) {
console.log("issue updateing to_slot");
console.log("to_slot_id",to_slot_id, slot_status[to_slot_id]);
console.log("to_slot_id",parameters.to_slot_id, slot_status[parameters.to_slot_id]);
}
return;
}
session.slot_status_key = to_slot[arr_key_index].domid
//***** do dajaxice call here ****** //
parameters.session.slot_status_key = parameters.to_slot[arr_key_index].domid;
var eTemplate = session.event_template()
var eTemplate = parameters.session.event_template()
//console.log("this:", thiss);
$(thiss).append(eTemplate);
console.log("dom_obj:", parameters.dom_obj);
$(parameters.dom_obj).append(eTemplate);
ui.draggable.remove();
parameters.ui.draggable.remove();
/* set colours */
$(thiss).removeClass('highlight_free_slot');
if(check_free({id:to_slot_id}) ){
$(thiss).addClass('free_slot')
$(parameters.dom_obj).removeClass('highlight_free_slot');
if(check_free({id:parameters.to_slot_id}) ){
$(parameters.dom_obj).addClass('free_slot')
}
else{
$(thiss).removeClass('free_slot')
$(parameters.dom_obj).removeClass('free_slot')
}
if(check_free({id:from_slot_id}) ){
// $("#"+from_slot_id).css('background-color', color_droppable_empty_slot)
$("#"+from_slot_id).addClass('free_slot');
if(check_free({id:parameters.from_slot_id}) ){
$("#"+parameters.from_slot_id).addClass('free_slot');
}
else{
// $("#"+from_slot_id).css('background-color',none_color);
$("#"+from_slot_id).removeClass('free_slot');
$("#"+parameters.from_slot_id).removeClass('free_slot');
}
$("#"+bucketlist_id).removeClass('free_slot');
/******************************************************/
var schedulesession_id = null;
var scheduledsession = null;
for(var i =0; i< to_slot.length; i++){
if (to_slot[i].session_id == session.session_id){
scheduledsession = to_slot[i];
schedulesession_id = to_slot[i].scheduledsession_id;
for(var i =0; i< parameters.to_slot.length; i++){
if (parameters.to_slot[i].session_id == parameters.session.session_id){
scheduledsession = parameters.to_slot[i];
break;
}
}
if(schedulesession_id != null){
session.placed(scheduledsession, true);
if(scheduledsession != null){
console.log("moved session",parameters.session.title,"to",scheduledsession);
parameters.session.placed(scheduledsession, true);
start_spin();
if(_move_debug) {
console.log('schedule_id',schedule_id,
'session_id', session.session_id,
'scheduledsession_id', schedulesession_id);
'session_id', parameters.session.session_id,
'scheduledsession_id', scheduledsession.scheduledsession_id);
}
if(session.slot2) {
session.double_wide = false;
if(parameters.session.slot2) {
parameters.session.double_wide = false;
Dajaxice.ietf.meeting.update_timeslot(dajaxice_callback,
{
'schedule_id':schedule_id,
'session_id': session.session_id,
'session_id': parameters.session.session_id,
'scheduledsession_id': 0,
});
session.slot2 = undefined;
parameters.session.slot2 = undefined;
}
if(same_timeslot){
if(parameters.same_timeslot){
Dajaxice.ietf.meeting.update_timeslot(dajaxice_callback,
{
'schedule_id':schedule_id,
'session_id': session.session_id,
'scheduledsession_id': schedulesession_id,
'session_id': parameters.session.session_id,
'scheduledsession_id': scheduledsession.scheduledsession__id,
'extended_from_id': 0,
'duplicate':true
});
@ -1096,12 +1130,12 @@ function move_slot(session,
Dajaxice.ietf.meeting.update_timeslot(dajaxice_callback,
{
'schedule_id':schedule_id,
'session_id': session.session_id,
'scheduledsession_id': schedulesession_id,
'session_id': parameters.session.session_id,
'scheduledsession_id': scheduledsession.scheduledsession_id,
});
}
session.update_column_classes([scheduledsession], bucket_list);
parameters.session.update_column_classes([scheduledsession], parameters.bucket_list);
}
else{
if(_move_debug) {
@ -1128,7 +1162,7 @@ function drop_over(event, ui){
}
$(event.draggable).addClass('highlight_current_selected');
$(ui.draggable).addClass('highlight_current_selected');
// $(ui.draggable).css("background",dragging_color);
// $(event.draggable).css("background",dragging_color);
}

View file

@ -4,7 +4,7 @@
*
* Copyright (c) 2013, The IETF Trust. See ../../../LICENSE.
*
* www.credil.org: Project Orlando 2013
* www.credil.org: Project Orlando 2013
* Author: Justin Hornosty ( justin@credil.org )
* Michael Richardson <mcr@sandelman.ca>
*
@ -231,6 +231,7 @@ function insert_timeslotedit_cell(ssid) {
var newpurpose = $("#"+select_id).val()
console.log("setting id: #"+select_id+" to "+newpurpose+" ("+roomtypeclass+")");
// how does dajaxice relay an error?
Dajaxice.ietf.meeting.update_timeslot_purpose(
function(json) {
if(json == "") {