Reverted to release 4.72 versions of several functions and methods, starting

with agenda_info() and the view functions that use it.  Also changed
meeting/tests/agenda.py to accept matching return values.  Reverted old
supporting models and proxy models to 4.72 versions, too, in meeting/proxy.py
and proceedings/models.py.  Updated the proxy models which rely on TimeSlot
to work properly with the m2m sessions field, and adjusted some other
functions, such as session_agenda() to also understand the m2m sessions
field (and its reverse).  Added an understanding of the "bof-conc" state
to the code which returns 'BOF' or 'WG' for agenda templates.
 - Legacy-Id: 6452
This commit is contained in:
Henrik Levkowetz 2013-10-15 17:54:42 +00:00
parent ff403d07ef
commit e33fe28a2c
6 changed files with 232 additions and 85 deletions

View file

@ -25,7 +25,7 @@ from ietf.ietfauth.decorators import has_role
from ietf.utils.history import find_history_active_at
from ietf.doc.models import Document, State
from ietf.proceedings.models import Meeting as OldMeeting, IESGHistory, Switches
from ietf.proceedings.models import Meeting as OldMeeting, MeetingTime, IESGHistory, Switches
# New models
from ietf.meeting.models import Meeting, TimeSlot, Session
@ -171,11 +171,7 @@ def find_ads_for_meeting(meeting):
ads.append(IESGHistory().from_role(x, meeting_time))
return ads
def agenda_info(num=None, name=None):
"""
XXX this should really be a method on Meeting
"""
def agenda_info(num=None):
try:
if num != None:
meeting = OldMeeting.objects.get(number=num)
@ -184,26 +180,31 @@ def agenda_info(num=None, name=None):
except OldMeeting.DoesNotExist:
raise Http404("No meeting information for meeting %s available" % num)
if name is not None:
try:
agenda = meeting.schedule_set.get(name=name)
except Schedule.DoesNotExist:
raise Http404("Meeting %s has no agenda named %s" % (num, name))
else:
agenda = meeting.agenda
if agenda is None:
raise Http404("Meeting %s has no agenda set yet" % (num))
ntimeslots,scheduledsessions = get_ntimeslots_from_agenda(agenda)
# now go through the timeslots, only keeping those that are
# sessions/plenary/training and don't occur at the same time
timeslots = []
time_seen = set()
for t in MeetingTime.objects.filter(meeting=meeting, type__in=("session", "plenary", "other")).order_by("time").select_related():
if not t.time in time_seen:
time_seen.add(t.time)
timeslots.append(t)
update = Switches().from_object(meeting)
venue = meeting.meeting_venue
ads = find_ads_for_meeting(meeting)
active_agenda = State.objects.get(type='agenda', slug='active')
plenary_agendas = Document.objects.filter(session__meeting=meeting, session__scheduledsession__timeslot__type="plenary", type="agenda", ).distinct()
ads = []
meeting_time = datetime.datetime.combine(meeting.date, datetime.time(0, 0, 0))
for g in Group.objects.filter(type="area").order_by("acronym"):
history = find_history_active_at(g, meeting_time)
if history and history != g:
if history.state_id == "active":
ads.extend(IESGHistory().from_role(x, meeting_time) for x in history.rolehistory_set.filter(name="ad").select_related())
else:
if g.state_id == "active":
ads.extend(IESGHistory().from_role(x, meeting_time) for x in g.role_set.filter(name="ad").select_related('group', 'person'))
active_agenda = State.objects.get(used=True, type='agenda', slug='active')
plenary_agendas = Document.objects.filter(session__meeting=meeting, session__slots__type="plenary", type="agenda", ).distinct()
plenaryw_agenda = plenaryt_agenda = "The Plenary has not been scheduled"
for agenda in plenary_agendas:
if active_agenda in agenda.states.all():
@ -222,7 +223,7 @@ def agenda_info(num=None, name=None):
else:
plenaryw_agenda = s
return ntimeslots, scheduledsessions, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda
return timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda
# get list of all areas, + IRTF + IETF (plenaries).
def get_pseudo_areas():

View file

@ -253,6 +253,7 @@ class TimeSlot(models.Model):
session = sessions.get() if sessions.count() == 1 else None
return session
@property
def time_desc(self):
return u"%s-%s" % (self.time.strftime("%H%M"), (self.time + self.duration).strftime("%H%M"))

View file

@ -5,8 +5,6 @@ from django.conf import settings
from ietf.utils.proxy import TranslatingManager
from models import *
import debug
class MeetingProxy(Meeting):
objects = TranslatingManager(dict(meeting_num="number"), always_filter=dict(type="ietf"))
@ -116,7 +114,7 @@ class SwitchesProxy(Meeting):
def updated(self):
from django.db.models import Max
import pytz
ts = max(self.timeslot_set.aggregate(Max('modified'))["modified__max"],
ts = max(self.timeslot_set.aggregate(Max('modified'))["modified__max"],
self.session_set.aggregate(Max('modified'))["modified__max"])
tz = pytz.timezone(settings.PRODUCTION_TIMEZONE)
ts = tz.localize(ts)
@ -151,6 +149,100 @@ class MeetingVenueProxy(Meeting):
class Meta:
proxy = True
class MeetingTimeProxy(TimeSlot):
# the old MeetingTimes did not include a room, so there we can't
# do a proper mapping - instead this proxy is one TimeSlot and
# uses the information in that to emulate a MeetingTime and enable
# retrieval of the other related TimeSlots
objects = TranslatingManager(dict(day_id="time", time_desc="time"))
def from_object(self, base):
for f in base._meta.fields:
setattr(self, f.name, getattr(base, f.name))
return self
#time_id = models.AutoField(primary_key=True)
@property
def time_id(self):
return self.pk
#time_desc = models.CharField(max_length=100)
@property
def time_desc(self):
return u"%s-%s" % (self.time.strftime("%H%M"), (self.time + self.duration).strftime("%H%M"))
#meeting = models.ForeignKey(Meeting, db_column='meeting_num') # same name
#day_id = models.IntegerField()
@property
def day_id(self):
return (self.time.date() - self.meeting.date).days
#session_name = models.ForeignKey(SessionName,null=True)
@property
def session_name(self):
if self.type_id not in ("session", "plenary"):
return None
class Dummy(object):
def __unicode__(self):
return self.session_name
d = Dummy()
d.session_name = self.name
return d
def __str__(self):
return "[%s] |%s| %s" % (self.meeting.number, self.time.strftime('%A'), self.time_desc)
def sessions(self):
if not hasattr(self, "sessions_cache"):
self.sessions_cache = WgMeetingSessionProxy.objects.filter(meeting=self.meeting, time=self.time, type__in=("session", "plenary", "other")).exclude(type="session", sessions=None)
return self.sessions_cache
def sessions_by_area(self):
return [ {"area":session.area()+session.acronym(), "info":session} for session in self.sessions() ]
def meeting_date(self):
return self.time.date()
def registration(self):
if not hasattr(self, '_reg_info'):
try:
self._reg_info = MeetingTimeProxy.objects.get(meeting=self.meeting, time__month=self.time.month, time__day=self.time.day, type="reg")
except MeetingTimeProxy.DoesNotExist:
self._reg_info = None
return self._reg_info
def reg_info(self):
reg_info = self.registration()
if reg_info and reg_info.time_desc:
return "%s %s" % (reg_info.time_desc, reg_info.name)
else:
return ""
def break_info(self):
breaks = MeetingTimeProxy.objects.filter(meeting=self.meeting, time__month=self.time.month, time__day=self.time.day, type="break").order_by("time")
for brk in breaks:
if brk.time_desc[-4:] == self.time_desc[:4]:
return brk
return None
def is_plenary(self):
return self.type_id == "plenary"
# from NonSession
#non_session_id = models.AutoField(primary_key=True)
@property
def non_session_id(self):
return self.id
#day_id = models.IntegerField(blank=True, null=True) # already wrapped
#non_session_ref = models.ForeignKey(NonSessionRef)
@property
def non_session_ref(self):
return 1 if self.type_id == "reg" else 3
#meeting = models.ForeignKey(Meeting, db_column='meeting_num') 3 same name
#time_desc = models.CharField(blank=True, max_length=75) # already wrapped
#show_break_location = models.BooleanField()
@property
def show_break_location(self):
return self.show_location
def day(self):
return self.time.strftime("%A")
class Meta:
proxy = True
NonSessionProxy = MeetingTimeProxy
class WgMeetingSessionProxy(TimeSlot):
# we model WgMeetingSession as a TimeSlot, to make the illusion
# complete we thus have to forward all the session stuff to the
@ -299,7 +391,7 @@ class WgMeetingSessionProxy(TimeSlot):
filename = docs[0].external_url
return "%s/minutes/%s" % (self.meeting.number, filename)
def slides(self,interimvar=0):
return SlideProxy.objects.filter(session__timeslot=self).order_by("order")
return SlideProxy.objects.filter(session__slots=self).order_by("order")
def interim_meeting(self):
return False
def length_session1_desc(self):
@ -377,7 +469,7 @@ class WgMeetingSessionProxy(TimeSlot):
if not self.session or not self.session.group:
return ""
if self.session.group and self.session.group.type_id == "wg":
if self.session.group.state_id == "bof":
if self.session.group.state_id in ["bof", "bof-conc" ]:
return "BOF"
else:
return "WG"

View file

@ -30,7 +30,7 @@ class AgendaInfoTestCase(TestCase):
def test_AgendaInfo(self):
from ietf.meeting.views import agenda_info
num = '83'
timeslots, scheduledsessions, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
# I think that "timeslots" here, is unique times, not actually
# the timeslots array itself.
self.assertEqual(len(timeslots),26)
@ -42,7 +42,7 @@ class AgendaInfoTestCase(TestCase):
def test_AgendaInfoReturnsSortedTimeSlots(self):
from ietf.meeting.views import agenda_info
num = '83'
timeslots, scheduledsessions, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
for slotnum in range(0,len(timeslots)-1):
# debug
#sys.stdout.write("%d: %s vs %d: %s\n" % (timeslots[slotnum].pk,
@ -74,7 +74,7 @@ class AgendaInfoTestCase(TestCase):
from ietf.meeting.views import agenda_info
num = '83b'
try:
timeslots, scheduledsessions, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
# fail!!!
self.assertFalse(True)
except Http404:
@ -121,7 +121,7 @@ class AgendaInfoTestCase(TestCase):
def test_AgendaInfoNamedSlotSessionsByArea(self):
from ietf.meeting.views import agenda_info
num = '83'
timeslots, scheduledsessions, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
# the third timeslot should be 1300-1450 on Sunday March 25.
# it should have three things:
#1300-1450 Tools for Creating Internet-Drafts Tutorial - 241
@ -130,8 +130,8 @@ class AgendaInfoTestCase(TestCase):
#import pdb
#pdb.set_trace()
slot3 = timeslots[2]
self.assertEqual(slot3.time_desc(), "1300-1450")
events = slot3.scheduledsessions_at_same_time
self.assertEqual(slot3.time_desc, "1300-1450")
events = slot3.scheduledsessions_at_same_time()
self.assertEqual(len(events), 3)
def test_serialize_constraint(self):

View file

@ -413,49 +413,33 @@ def edit_agendas(request, num=None, order=None):
RequestContext(request)),
mimetype="text/html")
##############################################################################
def iphone_agenda(request, num, name):
timeslots, scheduledsessions, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num, name)
timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
groups_meeting = set();
for ss in scheduledsessions:
if ss.session is not None:
groups_meeting.add(ss.session.group.acronym)
groups_meeting = [];
for slot in timeslots:
for session in slot.sessions():
groups_meeting.append(session.acronym())
groups_meeting = set(groups_meeting);
wgs = IETFWG.objects.filter(status=IETFWG.ACTIVE).filter(group_acronym__acronym__in = groups_meeting).order_by('group_acronym__acronym')
rgs = IRTF.objects.all().filter(acronym__in = groups_meeting).order_by('acronym')
areas = get_areas()
areas = Area.objects.filter(status=Area.ACTIVE).order_by('area_acronym__acronym')
template = "meeting/m_agenda.html"
return render_to_response(template,
{"timeslots":timeslots,
"scheduledsessions":scheduledsessions,
"update":update,
"meeting":meeting,
"venue":venue,
"ads":ads,
"areas":areas,
"plenaryw_agenda":plenaryw_agenda,
"plenaryt_agenda":plenaryt_agenda,
"wg_list" : wgs,
"rg_list" : rgs},
{"timeslots":timeslots, "update":update, "meeting":meeting, "venue":venue, "ads":ads,
"plenaryw_agenda":plenaryw_agenda, "plenaryt_agenda":plenaryt_agenda,
"wg_list" : wgs, "rg_list" : rgs, "area_list" : areas},
context_instance=RequestContext(request))
def text_agenda(request, num=None, name=None):
timeslots, scheduledsessions, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num, name)
timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
plenaryw_agenda = " "+plenaryw_agenda.strip().replace("\n", "\n ")
plenaryt_agenda = " "+plenaryt_agenda.strip().replace("\n", "\n ")
return HttpResponse(render_to_string("meeting/agenda.txt",
{"timeslots":timeslots,
"scheduledsessions":scheduledsessions,
"update":update,
"meeting":meeting,
"venue":venue,
"ads":ads,
"plenaryw_agenda":plenaryw_agenda,
"plenaryt_agenda":plenaryt_agenda, },
{"timeslots":timeslots, "update":update, "meeting":meeting, "venue":venue, "ads":ads,
"plenaryw_agenda":plenaryw_agenda, "plenaryt_agenda":plenaryt_agenda, },
RequestContext(request)), mimetype="text/plain")
def read_agenda_file(num, doc):
@ -473,9 +457,9 @@ def read_agenda_file(num, doc):
def session_agenda(request, num, session):
d = Document.objects.filter(type="agenda", session__meeting__number=num)
if session == "plenaryt":
d = d.filter(session__name__icontains="technical", session__timeslot__type="plenary")
d = d.filter(session__name__icontains="technical", session__slots__type="plenary")
elif session == "plenaryw":
d = d.filter(session__name__icontains="admin", session__timeslot__type="plenary")
d = d.filter(session__name__icontains="admin", session__slots__type="plenary")
else:
d = d.filter(session__group__acronym=session)
@ -649,7 +633,7 @@ def week_view(request, num=None):
return render_to_response(template,
{"timeslots":timeslots,"render_types":["Session","Other","Break","Plenary"]}, context_instance=RequestContext(request))
def ical_agenda(request, num=None, schedule_name=None):
def ical_agenda(request, num=None, name=None):
meeting = get_meeting(num)
q = request.META.get('QUERY_STRING','') or ""
@ -660,7 +644,7 @@ def ical_agenda(request, num=None, schedule_name=None):
# Process the special flags.
# "-wgname" will remove a working group from the output.
# "~Type" will add that type to the output.
# "~Type" will add that type to the output.
# "-~Type" will remove that type from the output
# Current types are:
# Session, Other (default on), Break, Plenary (default on)
@ -676,16 +660,13 @@ def ical_agenda(request, num=None, schedule_name=None):
elif item[0] == '~':
include_types |= set([item[1:2].upper()+item[2:]])
schedule = get_schedule(meeting, schedule_name)
scheduledsessions = get_scheduledsessions_from_schedule(schedule)
scheduledsessions = scheduledsessions.filter(
Q(timeslot__type__name__in = include_types) |
Q(session__group__acronym__in = filter) |
Q(session__group__parent__acronym__in = filter)
).exclude(Q(session__group__acronym__in = exclude))
timeslots = TimeSlot.objects.filter(Q(meeting__id = meeting.id),
Q(type__name__in = include_types) |
Q(sessions__group__acronym__in = filter) |
Q(sessions__group__parent__acronym__in = filter)
).exclude(Q(sessions__group__acronym__in = exclude))
#.exclude(Q(session__group__isnull = False),
#Q(session__group__acronym__in = exclude) |
#Q(session__group__acronym__in = exclude) |
#Q(session__group__parent__acronym__in = exclude))
if meeting.time_zone:
@ -701,11 +682,15 @@ def ical_agenda(request, num=None, schedule_name=None):
vtimezone = None
return HttpResponse(render_to_string("meeting/agenda.ics",
{"scheduledsessions":scheduledsessions, "meeting":meeting, "vtimezone": vtimezone },
{"timeslots":timeslots, "meeting":meeting, "vtimezone": vtimezone },
RequestContext(request)), mimetype="text/calendar")
def csv_agenda(request, num=None, name=None):
timeslots, scheduledsessions, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num, name)
timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
#wgs = IETFWG.objects.filter(status=IETFWG.ACTIVE).order_by('group_acronym__acronym')
#rgs = IRTF.objects.all().order_by('acronym')
#areas = Area.objects.filter(status=Area.ACTIVE).order_by('area_acronym__acronym')
# we should really use the Python csv module or something similar
# rather than a template file which is one big mess

View file

@ -20,7 +20,6 @@ from django.db import models
from django.conf import settings
from ietf.idtracker.models import Acronym, PersonOrOrgInfo, IRTF, AreaGroup, Area, IETFWG
from ietf.utils.broken_foreign_key import BrokenForeignKey
from ietf.meeting.models import TimeSlot
import datetime
#from ietf.utils import log
@ -274,6 +273,74 @@ class IESGHistory(models.Model):
verbose_name = "Meeting AD info"
verbose_name_plural = "Meeting AD info"
class MeetingTime(models.Model):
time_id = models.AutoField(primary_key=True)
time_desc = models.CharField(max_length=100)
meeting = models.ForeignKey(Meeting, db_column='meeting_num')
day_id = models.IntegerField()
session_name = models.ForeignKey(SessionName,null=True)
def __str__(self):
return "[%d] |%s| %s" % (self.meeting_id, (self.meeting.start_date + datetime.timedelta(self.day_id)).strftime('%A'), self.time_desc)
def sessions(self):
"""
Get all sessions that are scheduled at this time.
"""
sessions = WgMeetingSession.objects.filter(
models.Q(sched_time_id1=self.time_id) |
models.Q(sched_time_id2=self.time_id) |
models.Q(sched_time_id3=self.time_id) |
models.Q(combined_time_id1=self.time_id) |
models.Q(combined_time_id2=self.time_id))
for s in sessions:
if s.sched_time_id1_id == self.time_id:
s.room_id = s.sched_room_id1
s.ordinality = 1
elif s.sched_time_id2_id == self.time_id:
s.room_id = s.sched_room_id2
s.ordinality = 2
elif s.sched_time_id3_id == self.time_id:
s.room_id = s.sched_room_id3
s.ordinality = 3
elif s.combined_time_id1_id == self.time_id:
s.room_id = s.combined_room_id1
s.ordinality = 4
elif s.combined_time_id2_id == self.time_id:
s.room_id = s.combined_room_id2
s.ordinality = 5
else:
s.room_id = 0
s.ordinality = 0
return sessions
def sessions_by_area(self):
return [ {"area":session.area()+session.acronym(), "info":session} for session in self.sessions() ]
def meeting_date(self):
return self.meeting.get_meeting_date(self.day_id)
def registration(self):
if hasattr(self, '_reg_info'):
return self._reg_info
reg = NonSession.objects.get(meeting=self.meeting, day_id=self.day_id, non_session_ref=1)
reg.name = reg.non_session_ref.name
self._reg_info = reg
return reg
def reg_info(self):
reg_info = self.registration()
if reg_info.time_desc:
return "%s %s" % (reg_info.time_desc, reg_info.name)
else:
return ""
def break_info(self):
breaks = NonSession.objects.filter(meeting=self.meeting).exclude(non_session_ref=1).filter(models.Q(day_id=self.day_id) | models.Q(day_id__isnull=True)).order_by('time_desc')
for brk in breaks:
if brk.time_desc[-4:] == self.time_desc[:4]:
brk.name = brk.non_session_ref.name
return brk
return None
def is_plenary(self):
return self.session_name_id in [9, 10]
class Meta:
db_table = 'meeting_times'
verbose_name = "Meeting slot time"
class MeetingRoom(models.Model):
room_id = models.AutoField(primary_key=True)
meeting = models.ForeignKey(Meeting, db_column='meeting_num')
@ -318,19 +385,19 @@ class WgMeetingSession(models.Model, ResolveAcronym):
last_modified_date = models.DateField(null=True, blank=True)
ad_comments = models.TextField(blank=True,null=True)
sched_room_id1 = models.ForeignKey(MeetingRoom, db_column='sched_room_id1', null=True, blank=True, related_name='here1')
sched_time_id1 = BrokenForeignKey(TimeSlot, db_column='sched_time_id1', null=True, blank=True, related_name='now1')
sched_time_id1 = BrokenForeignKey(MeetingTime, db_column='sched_time_id1', null=True, blank=True, related_name='now1')
sched_date1 = models.DateField(null=True, blank=True)
sched_room_id2 = models.ForeignKey(MeetingRoom, db_column='sched_room_id2', null=True, blank=True, related_name='here2')
sched_time_id2 = BrokenForeignKey(TimeSlot, db_column='sched_time_id2', null=True, blank=True, related_name='now2')
sched_time_id2 = BrokenForeignKey(MeetingTime, db_column='sched_time_id2', null=True, blank=True, related_name='now2')
sched_date2 = models.DateField(null=True, blank=True)
sched_room_id3 = models.ForeignKey(MeetingRoom, db_column='sched_room_id3', null=True, blank=True, related_name='here3')
sched_time_id3 = BrokenForeignKey(TimeSlot, db_column='sched_time_id3', null=True, blank=True, related_name='now3')
sched_time_id3 = BrokenForeignKey(MeetingTime, db_column='sched_time_id3', null=True, blank=True, related_name='now3')
sched_date3 = models.DateField(null=True, blank=True)
special_agenda_note = models.CharField(blank=True, max_length=255)
combined_room_id1 = models.ForeignKey(MeetingRoom, db_column='combined_room_id1', null=True, blank=True, related_name='here4')
combined_time_id1 = BrokenForeignKey(TimeSlot, db_column='combined_time_id1', null=True, blank=True, related_name='now4')
combined_time_id1 = BrokenForeignKey(MeetingTime, db_column='combined_time_id1', null=True, blank=True, related_name='now4')
combined_room_id2 = models.ForeignKey(MeetingRoom, db_column='combined_room_id2', null=True, blank=True, related_name='here5')
combined_time_id2 = BrokenForeignKey(TimeSlot, db_column='combined_time_id2', null=True, blank=True, related_name='now5')
combined_time_id2 = BrokenForeignKey(MeetingTime, db_column='combined_time_id2', null=True, blank=True, related_name='now5')
def __str__(self):
return "%s at %s" % (self.acronym(), self.meeting)
def agenda_file(self,interimvar=0):
@ -544,11 +611,12 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
MeetingOld = Meeting
ProceedingOld = Proceeding
MeetingVenueOld = MeetingVenue
MeetingTimeOld = MeetingTime
WgMeetingSessionOld = WgMeetingSession
SlideOld = Slide
SwitchesOld = Switches
IESGHistoryOld = IESGHistory
from ietf.meeting.proxy import MeetingProxy as Meeting, ProceedingProxy as Proceeding, MeetingVenueProxy as MeetingVenue, WgMeetingSessionProxy as WgMeetingSession, SlideProxy as Slide, SwitchesProxy as Switches, IESGHistoryProxy as IESGHistory
from ietf.meeting.proxy import MeetingProxy as Meeting, ProceedingProxy as Proceeding, MeetingVenueProxy as MeetingVenue, MeetingTimeProxy as MeetingTime, WgMeetingSessionProxy as WgMeetingSession, SlideProxy as Slide, SwitchesProxy as Switches, IESGHistoryProxy as IESGHistory
# changes done by convert-096.py:changed maxlength to max_length
# removed core