Port and proxy remaining meeting views, adjusting the models slightly

- Legacy-Id: 3296
This commit is contained in:
Ole Laursen 2011-08-10 17:09:35 +00:00
parent 7f27d912c3
commit 12bd2f93d7
11 changed files with 400 additions and 176 deletions
ietf
redesign

View file

@ -1147,9 +1147,10 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
AcronymOld = Acronym
IESGLoginOld = IESGLogin
IETFWGOld = IETFWG
IRTFOld = IRTF
from redesign.doc.proxy import InternetDraft, IDInternal, BallotInfo, Rfc
from redesign.name.proxy import IDState, IDSubState
from redesign.group.proxy import Area, Acronym, IETFWG
from redesign.group.proxy import Area, Acronym, IETFWG, IRTF
from redesign.person.proxy import IESGLogin

View file

@ -1,6 +1,6 @@
# old meeting models can be found in ../proceedings/models.py
import pytz
import pytz, datetime
from django.db import models
from timedeltafield import TimedeltaField
@ -8,7 +8,7 @@ from timedeltafield import TimedeltaField
from redesign.group.models import Group
from redesign.person.models import Person
from redesign.doc.models import Document
from redesign.name.models import TimeSlotTypeName, SessionStatusName, ConstraintName
from redesign.name.models import MeetingTypeName, TimeSlotTypeName, SessionStatusName, ConstraintName
countries = pytz.country_names.items()
countries.sort(lambda x,y: cmp(x[1], y[1]))
@ -17,9 +17,10 @@ timezones = [(name, name) for name in pytz.common_timezones]
timezones.sort()
class Meeting(models.Model):
# Number is not an integer any more, in order to be able to accomodate
# interim meetings (and other variations?)
# number is either the number for IETF meetings, or some other
# identifier for interim meetings/IESG retreats/liaison summits/...
number = models.CharField(max_length=64)
type = models.ForeignKey(MeetingTypeName)
# Date is useful when generating a set of timeslot for this meeting, but
# is not used to determine date for timeslot instances thereafter, as
# they have their own datetime field.
@ -37,11 +38,10 @@ class Meeting(models.Model):
def __str__(self):
return "IETF-%s" % (self.number)
def time_zone_offset(self):
return pytz.timezone(self.time_zone).localize(datetime.datetime.combine(self.date, datetime.time(0, 0))).strftime("%z")
def get_meeting_date (self,offset):
return self.date + datetime.timedelta(days=offset)
# cut-off dates (draft submission cut-of, wg agenda cut-off, minutes
# submission cut-off), and more, are probably methods of this class,
# rather than fields on a Proceedings class.
@classmethod
def get_first_cut_off(cls):
@ -60,6 +60,13 @@ class Meeting(models.Model):
date = cls.objects.all().order_by('-date')[0].date
return date + datetime.timedelta(days=-date.weekday(), weeks=1)
# the various dates are currently computed
def get_submission_start_date(self):
return self.date + datetime.timedelta(days=-90)
def get_submission_cut_off_date(self):
return self.date + datetime.timedelta(days=33)
def get_submission_correction_date(self):
return self.date + datetime.timedelta(days=59)
class Room(models.Model):
meeting = models.ForeignKey(Meeting)
@ -82,8 +89,10 @@ class TimeSlot(models.Model):
time = models.DateTimeField()
duration = TimedeltaField()
location = models.ForeignKey(Room, blank=True, null=True)
show_location = models.BooleanField(default=True)
show_location = models.BooleanField(default=True, help_text="Show location in agenda")
materials = models.ManyToManyField(Document, blank=True)
session = models.ForeignKey('Session', null=True, blank=True, help_text=u"Scheduled group session, if any")
modified = models.DateTimeField(default=datetime.datetime.now)
def __unicode__(self):
location = self.get_location()
@ -120,7 +129,6 @@ class Constraint(models.Model):
class Session(models.Model):
meeting = models.ForeignKey(Meeting)
timeslot = models.ForeignKey(TimeSlot, null=True, blank=True) # Null until session has been scheduled
group = models.ForeignKey(Group) # The group type determines the session type. BOFs also need to be added as a group.
attendees = models.IntegerField(null=True, blank=True)
agenda_note = models.CharField(blank=True, max_length=255)
@ -132,16 +140,15 @@ class Session(models.Model):
#
status = models.ForeignKey(SessionStatusName)
scheduled = models.DateTimeField(null=True, blank=True)
modified = models.DateTimeField(null=True, blank=True)
modified = models.DateTimeField(default=datetime.datetime.now)
# contains the materials while the session is being requested,
# when it is scheduled, timeslot.materials should be used (FIXME: ask Henrik)
# when it is scheduled, timeslot.materials should be used
materials = models.ManyToManyField(Document, blank=True)
def __unicode__(self):
return u"%s: %s %s" % (self.meeting, self.group.acronym, self.timeslot.time.strftime("%H%M") if self.timeslot else "(unscheduled)")
# Agendas, Minutes and Slides are all mapped to Document.
timeslots = self.timeslot_set.order_by('time')
return u"%s: %s %s" % (self.meeting, self.group.acronym, timeslots[0].time.strftime("%H%M") if timeslots else "(unscheduled)")
# IESG history is extracted from GroupHistory, rather than hand coded in a
# separate table.

View file

@ -39,15 +39,12 @@ class MeetingProxy(Meeting):
def get_meeting_date (self,offset):
return self.start_date + datetime.timedelta(days=offset)
def num(self):
return self.meeting_num
return self.number
@property
def meeting_venue(self):
return MeetingVenueProxy().from_object(self)
class Meta:
proxy = True
@classmethod
def get_first_cut_off(cls):
start_date = cls.objects.all().order_by('-date')[0].start_date
@ -65,6 +62,60 @@ class MeetingProxy(Meeting):
start_date = cls.objects.all().order_by('-date')[0].start_date
return start_date + datetime.timedelta(days=-start_date.weekday(), weeks=1)
class Meta:
proxy = True
class ProceedingProxy(Meeting):
objects = TranslatingManager(dict(meeting_num="number"))
#meeting_num = models.ForeignKey(Meeting, db_column='meeting_num', unique=True, primary_key=True)
@property
def meeting_num(self):
return MeetingProxy().from_object(self)
@property
def meeting_num_id(self):
return self.number
#dir_name = models.CharField(blank=True, max_length=25)
@property
def dir_name(self):
return self.number
#sub_begin_date = models.DateField(null=True, blank=True)
@property
def sub_begin_date(self):
return self.get_submission_start_date()
#sub_cut_off_date = models.DateField(null=True, blank=True)
@property
def sub_cut_off_date(self):
return self.get_submission_cut_off_date()
#frozen = models.IntegerField(null=True, blank=True)
#c_sub_cut_off_date = models.DateField(null=True, blank=True)
@property
def c_sub_cut_off_date(self):
return self.get_submission_correction_date()
#pr_from_date = models.DateField(null=True, blank=True)
#pr_to_date = models.DateField(null=True, blank=True)
def __str__(self):
return "IETF %s" % (self.meeting_num_id)
class Meta:
proxy = True
class SwitchesProxy(Meeting):
def from_object(self, base):
for f in base._meta.fields:
setattr(self, f.name, getattr(base, f.name))
return self
#name = models.CharField(max_length=100)
#val = models.IntegerField(null=True, blank=True)
#updated_date = models.DateField(null=True, blank=True)
#updated_time = models.TimeField(null=True, blank=True)
def updated(self):
from django.db.models import Max
return max(self.timeslot_set.aggregate(Max('modified'))["modified__max"],
self.session_set.aggregate(Max('modified'))["modified__max"])
class Meta:
proxy = True
class MeetingVenueProxy(Meeting):
objects = TranslatingManager(dict(meeting_num="number"))
@ -191,58 +242,100 @@ class WgMeetingSessionProxy(TimeSlot):
# because some previous sessions are now really time slots, to
# make the illusion complete we thus have to forward all the
# session stuff to the real session
objects = TranslatingManager(dict(group_acronym_id="session__group"))
objects = TranslatingManager(dict(group_acronym_id="session__group",
status__id=lambda v: ("state", {4: "sched"}[v])))
def from_object(self, base):
for f in base._meta.fields:
setattr(self, f.name, getattr(base, f.name))
return self
def get_session(self):
if not hasattr(self, "_session_cache"):
s = self.session_set.all()
self._session_cache = s[0] if s else None
return self._session_cache
#session_id = models.AutoField(primary_key=True)
@property
def session_id(self):
return self.id
#session_id = models.AutoField(primary_key=True) # same name
#meeting = models.ForeignKey(Meeting, db_column='meeting_num') # same name
#group_acronym_id = models.IntegerField()
@property
def group_acronym_id(self):
s = self.get_session()
return s.group_id if s else -1
return self.session.group_id if self.session else -1
#irtf = models.NullBooleanField()
@property
def irtf(self):
return 1 if self.session and self.session.group and self.session.group.type == "rg" else 0
#num_session = models.IntegerField()
@property
def num_session(self):
return 1 if self.session else 0
#length_session1 = models.CharField(blank=True, max_length=100)
@property
def length_session1(self):
if not self.session:
return "0"
secs = self.session.requested_duration.seconds
if secs == 0:
return "0"
return str((secs / 60 - 30) / 30)
#length_session2 = models.CharField(blank=True, max_length=100)
@property
def length_session2(self):
return "0"
#length_session3 = models.CharField(blank=True, max_length=100)
@property
def length_session3(self):
return "0"
def conflicting_group_acronyms(self, level):
if not self.session:
return ""
conflicts = Constraint.objects.filter(meeting=self.meeting_id,
target=self.session.group,
name=level)
return " ".join(c.source.acronym for c in conflicts)
#conflict1 = models.CharField(blank=True, max_length=255)
@property
def conflict1(self):
return self.conflicting_group_acronyms("conflict")
#conflict2 = models.CharField(blank=True, max_length=255)
@property
def conflict2(self):
return self.conflicting_group_acronyms("conflic2")
#conflict3 = models.CharField(blank=True, max_length=255)
@property
def conflict3(self):
return self.conflicting_group_acronyms("conflic3")
#conflict_other = models.TextField(blank=True)
@property
def conflict_other(self):
return ""
#special_req = models.TextField(blank=True)
@property
def special_req(self):
return self.session.comments if self.session else ""
#number_attendee = models.IntegerField(null=True, blank=True)
@property
def number_attendee(self):
return self.get_session().attendees if self.get_session() else 0
return self.session.attendees if self.session else 0
#approval_ad = models.IntegerField(null=True, blank=True)
#status = models.ForeignKey(SessionStatus, null=True, blank=True) # same name
#ts_status_id = models.IntegerField(null=True, blank=True)
#requested_date = models.DateField(null=True, blank=True)
@property
def requested_date(self):
return self.session.requested.date() if self.session else None
#approved_date = models.DateField(null=True, blank=True)
#requested_by = BrokenForeignKey(PersonOrOrgInfo, db_column='requested_by', null=True, null_values=(0, 888888))
@property
def requested_by(self):
return self.session.requested_by if self.session else None
#scheduled_date = models.DateField(null=True, blank=True)
@property
def scheduled_date(self):
return self.get_session().scheduled.date() if self.get_session() else ""
return self.session.scheduled.date() if self.session else ""
#last_modified_date = models.DateField(null=True, blank=True)
@property
def last_modified_date(self):
return self.get_session().modified.date() if self.get_session() else ""
return self.session.modified.date() if self.session else ""
#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(MeetingTime, db_column='sched_time_id1', null=True, blank=True, related_name='now1')
@ -256,7 +349,7 @@ class WgMeetingSessionProxy(TimeSlot):
#special_agenda_note = models.CharField(blank=True, max_length=255)
@property
def special_agenda_note(self):
return self.get_session().agenda_note if self.get_session() else ""
return self.session.agenda_note if self.session else ""
#combined_room_id1 = models.ForeignKey(MeetingRoom, db_column='combined_room_id1', null=True, blank=True, related_name='here4')
#combined_time_id1 = models.ForeignKey(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')
@ -285,41 +378,21 @@ class WgMeetingSessionProxy(TimeSlot):
filename = docs[0].external_url
return "%s/minutes/%s" % (self.meeting.number, filename)
def slides(self,interimvar=0):
"""
Get all slides of this session.
"""
# FIXME
irtfvar = 0
if self.irtf:
irtfvar = self.group_acronym_id
if interimvar == 0:
try:
if self.interim:
interimvar = 1
except AttributeError:
interimvar = 0
slides = Slide.objects.filter(meeting=self.meeting,group_acronym_id=self.group_acronym_id,irtf=irtfvar,interim=interimvar).order_by("order_num")
return slides
def interim_meeting (self):
# FIXME
if self.minute_file(1):
return True
elif self.agenda_file(1):
return True
elif self.slides(1):
return True
else:
return False
def length_session1_desc (self):
if self.requested_duration.seconds == 60 * 60:
return "1 hour"
else:
return "%.1f hours" % (float(self.requested_duration.seconds) / (60 * 60))
def length_session2_desc (self):
return SlideProxy.objects.filter(timeslot=self).order_by("order")
def interim_meeting(self):
return False
def length_session1_desc(self):
l = self.length_session1
return { "0": "", "1": "1 hour", "2": "1.5 hours", "3": "2 hours", "4": "2.5 hours"}[l]
def length_session2_desc(self):
return ""
def length_session3_desc (self):
def length_session3_desc(self):
return ""
@property
def ordinality(self):
return 1
@property
def room_id(self):
class Dummy: pass
@ -329,51 +402,53 @@ class WgMeetingSessionProxy(TimeSlot):
# from ResolveAcronym:
def acronym(self):
s = self.get_session()
if not s:
if not self.session:
if self.type_id == "plenary":
if "Operations and Administration" in self.name:
return "plenaryw"
if "Technical" in self.name:
return "plenaryt"
for m in self.materials.filter(type="agenda"):
if "plenaryw" in m.name:
return "plenaryw"
if "plenaryt" in m.name:
return "plenaryt"
return ""
return "%s" % self.pk
if hasattr(self, "interim"):
return "i" + s.group.acronym
return "i" + self.session.group.acronym
else:
return s.group.acronym
return self.session.group.acronym
def acronym_lower(self):
return self.acronym().lower()
def acronym_name(self):
s = self.get_session()
if not s:
if not self.session:
return self.name
if hasattr(self, "interim"):
return s.group.name + " (interim)"
return self.session.group.name + " (interim)"
else:
return s.group.name
return self.session.group.name
def area(self):
s = self.get_session()
if not s:
if not self.session:
return ""
return s.group.parent.acronym
return self.session.group.parent.acronym
def area_name(self):
s = self.get_session()
if not s:
if self.type_id == "plenary":
return "Plenary Sessions"
elif self.type_id == "other":
return "Training"
elif not self.session:
return ""
return s.group.parent.name
return self.session.group.parent.name
def isWG(self):
s = self.get_session()
if not s or not s.group:
if not self.session or not self.session.group:
return False
if s.group.type_id == "wg" and s.group.state_id != "bof":
if self.session.group.type_id == "wg" and self.session.group.state_id != "bof":
return True
def group_type_str(self):
s = self.get_session()
if not s or not s.group:
if not self.session or not self.session.group:
return ""
if s.group and s.group.type_id == "wg":
if s.group.state_id == "bof":
if self.session.group and self.session.group.type_id == "wg":
if self.session.group.state_id == "bof":
return "BOF"
else:
return "WG"
@ -383,3 +458,43 @@ class WgMeetingSessionProxy(TimeSlot):
class Meta:
proxy = True
class SlideProxy(Document):
objects = TranslatingManager(dict(), always_filter=dict(type="slides"))
SLIDE_TYPE_CHOICES=(
('1', '(converted) HTML'),
('2', 'PDF'),
('3', 'Text'),
('4', 'PowerPoint -2003 (PPT)'),
('5', 'Microsoft Word'),
('6', 'PowerPoint 2007- (PPTX)'),
)
#meeting = models.ForeignKey(Meeting, db_column='meeting_num')
@property
def meeting_id(self):
return self.name.split("-")[1]
#group_acronym_id = models.IntegerField(null=True, blank=True)
#slide_num = models.IntegerField(null=True, blank=True)
@property
def slide_name(self):
return int(self.name.split("-")[3])
#slide_type_id = models.IntegerField(choices=SLIDE_TYPE_CHOICES)
#slide_name = models.CharField(blank=True, max_length=255)
@property
def slide_name(self):
return self.title
#irtf = models.IntegerField()
#interim = models.BooleanField()
#order_num = models.IntegerField(null=True, blank=True)
@property
def order_num(self):
return self.order
#in_q = models.IntegerField(null=True, blank=True)
def acronym():
return self.name.split("-")[2]
def __str__(self):
return "IETF%d: %s slides (%s)" % (self.meeting_id, self.acronym(), self.slide_name)
def file_loc(self):
return "%s/slides/%s" % (self.meeting_id, self.external_url)
class Meta:
proxy = True

View file

@ -19,7 +19,7 @@ from django.template.loader import render_to_string
from django.conf import settings
from django.utils.decorators import decorator_from_middleware
from django.middleware.gzip import GZipMiddleware
from django.db.models import Count
from django.db.models import Count, Max
from ietf.idtracker.models import InternetDraft
from ietf.idrfc.idrfc_wrapper import IdWrapper
from ietf.utils.pipe import pipe
@ -42,19 +42,38 @@ def show_html_materials(request, meeting_num=None):
if now > begin_date:
sub_began = 1
# List of WG sessions and Plenary sessions
queryset_list = WgMeetingSession.objects.filter(Q(meeting=meeting_num, group_acronym_id__gte = -2, status__id=4), Q(irtf__isnull=True) | Q(irtf=0))
queryset_irtf = WgMeetingSession.objects.filter(meeting=meeting_num, group_acronym_id__gte = -2, status__id=4, irtf__gt=0)
queryset_interim = []
queryset_training = []
for item in list(WgMeetingSession.objects.filter(meeting=meeting_num)):
if item.interim_meeting():
item.interim=1
queryset_interim.append(item)
if item.group_acronym_id < -2:
if item.slides():
queryset_training.append(item)
cache_version = WgProceedingsActivities.objects.aggregate(Count('id'))
return object_list(request,queryset=queryset_list, template_name="meeting/list.html",allow_empty=True, extra_context={'meeting_num':meeting_num,'irtf_list':queryset_irtf, 'interim_list':queryset_interim, 'training_list':queryset_training, 'begin_date':begin_date, 'cut_off_date':cut_off_date, 'cor_cut_off_date':cor_cut_off_date,'sub_began':sub_began,'cache_version':cache_version})
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
queryset_list = []
queryset_irtf = []
queryset_interim = [] # currently ignored, have no way of handling interim here
queryset_training = []
for item in WgMeetingSession.objects.filter(meeting=meeting_num):
if item.type_id in ("session", "plenary"):
if item.session and item.session.group and item.session.group.type_id == "rg":
queryset_irtf.append(item)
else:
queryset_list.append(item)
else:
if item.type_id == "other" and item.slides():
queryset_training.append(item)
from redesign.doc.models import Document
cache_version = Document.objects.filter(timeslot__meeting__number=meeting_num).aggregate(Max('time'))["time__max"]
else:
queryset_list = WgMeetingSession.objects.filter(Q(meeting=meeting_num, group_acronym_id__gte = -2, status__id=4), Q(irtf__isnull=True) | Q(irtf=0))
queryset_irtf = WgMeetingSession.objects.filter(meeting=meeting_num, group_acronym_id__gte = -2, status__id=4, irtf__gt=0)
queryset_interim = []
queryset_training = []
for item in list(WgMeetingSession.objects.filter(meeting=meeting_num)):
if item.interim_meeting():
item.interim=1
queryset_interim.append(item)
if item.group_acronym_id < -2:
if item.slides():
queryset_training.append(item)
cache_version = WgProceedingsActivities.objects.aggregate(Count('id'))
return render_to_response("meeting/list.html",
{'meeting_num':meeting_num,'object_list': queryset_list, 'irtf_list':queryset_irtf, 'interim_list':queryset_interim, 'training_list':queryset_training, 'begin_date':begin_date, 'cut_off_date':cut_off_date, 'cor_cut_off_date':cor_cut_off_date,'sub_began':sub_began,'cache_version':cache_version},
context_instance=RequestContext(request))
def current_materials(request):
meeting = Meeting.objects.order_by('-meeting_num')[0]
@ -83,7 +102,7 @@ def agenda_info(num=None):
for n in meetings:
try:
timeslots = MeetingTime.objects.select_related().filter(meeting=n).order_by("day_id", "time_desc")
update = Switches.objects.get(id=1) # FIXME
update = Switches.objects.get(id=1)
meeting= Meeting.objects.get(meeting_num=n)
venue = MeetingVenue.objects.get(meeting_num=n)
break
@ -91,7 +110,7 @@ def agenda_info(num=None):
continue
else:
raise Http404("No meeting information for meeting %s available" % num)
ads = list(IESGHistory.objects.select_related().filter(meeting=n)) # FIXME
ads = list(IESGHistory.objects.select_related().filter(meeting=n))
if not ads:
ads = list(IESGHistory.objects.select_related().filter(meeting=str(int(n)-1)))
ads.sort(key=(lambda item: item.area.area_acronym.acronym))
@ -117,12 +136,12 @@ def agenda_infoREDESIGN(num=None):
time_seen.add(t.time)
timeslots.append(t)
update = Switches.objects.get(id=1) # FIXME
update = Switches().from_object(meeting)
venue = meeting.meeting_venue
ads = list(IESGHistory.objects.select_related().filter(meeting=meeting.number)) # FIXME
ads = list(IESGHistory.objects.select_related().filter(meeting=int(meeting.number)))
if not ads:
ads = list(IESGHistory.objects.select_related().filter(meeting=str(int(meeting.number)-1)))
ads = list(IESGHistory.objects.select_related().filter(meeting=int(meeting.number)-1))
ads.sort(key=(lambda item: item.area.area_acronym.acronym))
from redesign.doc.models import Document
@ -153,8 +172,6 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
def html_agenda(request, num=None):
timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(num)
#timeslots = timeslots[:10]
groups_meeting = [];
for slot in timeslots:
for session in slot.sessions():
@ -397,7 +414,7 @@ def ical_agenda(request, num=None):
if session.area() == '' or session.area().find('plenary') > 0 or (session.area().lower() in include):
filter.append(session.acronym())
return HttpResponse(render_to_string("meeting/agenda.ics",
return HttpResponse(render_to_string("meeting/agendaREDESIGN.ics" if settings.USE_DB_REDESIGN_PROXY_CLASSES else "meeting/agenda.ics",
{"filter":set(filter), "timeslots":timeslots, "update":update, "meeting":meeting, "venue":venue, "ads":ads,
"plenaryw_agenda":plenaryw_agenda, "plenaryt_agenda":plenaryt_agenda,
"now":now},

View file

@ -59,7 +59,8 @@ admin.site.register(SessionName, SessionNameAdmin)
class SlideAdmin(admin.ModelAdmin):
list_filter = ['meeting', ]
pass
admin.site.register(Slide, SlideAdmin)
if not settings.USE_DB_REDESIGN_PROXY_CLASSES:
admin.site.register(Slide, SlideAdmin)
class SwitchesAdmin(admin.ModelAdmin):
pass

View file

@ -587,10 +587,13 @@ class MeetingHour(models.Model):
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
MeetingOld = Meeting
ProceedingOld = Proceeding
MeetingVenueOld = MeetingVenue
MeetingTimeOld = MeetingTime
WgMeetingSessionOld = WgMeetingSession
from ietf.meeting.proxy import MeetingProxy as Meeting, MeetingVenueProxy as MeetingVenue, MeetingTimeProxy as MeetingTime, WgMeetingSessionProxy as WgMeetingSession
SlideOld = Slide
SwitchesOld = Switches
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
# changes done by convert-096.py:changed maxlength to max_length
# removed core

View file

@ -0,0 +1,35 @@
{% load humanize %}{% autoescape off %}{% load ietf_filters %}BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
{% if meeting.time_zone %}BEGIN:VTIMEZONE
TZID:{{meeting.time_zone}}
BEGIN:STANDARD
TZOFFSETFROM:{{meeting.time_zone_offset}}
TZOFFSETTO:{{meeting.time_zone_offset}}
TZNAME:{{meeting.time_zone}}
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
{% endif %}{% for slot in timeslots %}{% ifchanged %}{% if slot.session_name and slot.break_info %}BEGIN:VEVENT
UID:ietf-{{meeting.num}}-break-{{slot.time_id}}
SUMMARY:{{slot.break_info.name}}
{% if venue.break_area_name and slot.break_info.show_break_location %}LOCATION:{{venue.break_area_name}}
{% endif %}STATUS:TENTATIVE
CLASS:PUBLIC
DTSTART{% if meeting.time_zone %};TZID="{{meeting.time_zone}}"{%endif%}:{{ slot.meeting_date|date:"Ymd" }}T{{slot.break_info.time_desc|slice:":4"}}00
DTEND{% if meeting.time_zone %};TZID="{{meeting.time_zone}}"{%endif%}:{{ slot.meeting_date|date:"Ymd" }}T{{slot.break_info.time_desc|slice:"5:9"}}00
DTSTAMP:{{ now|date:"Ymd" }}T{{ now|date:"His" }}Z
END:VEVENT
{% endif %}{% endifchanged %}{% for session in slot.sessions %}{%for f in filter%}{%ifequal f session.acronym%}BEGIN:VEVENT
UID:ietf-{{meeting.num}}-{{session.acronym}}-{{session.ordinality}}
SUMMARY:{% if session.area %}{% ifnotequal session.area "1plenary" %}{{session.acronym|upper}} - {% endifnotequal %}{% endif %}{{session.acronym_name}}
LOCATION:{{session.room_id.room_name}}
STATUS:TENTATIVE
CLASS:PUBLIC
DTSTART{% if meeting.time_zone %};TZID="{{meeting.time_zone}}"{%endif%}:{{ slot.meeting_date|date:"Ymd" }}T{{slot.time_desc|slice:":4"}}00
DTEND{% if meeting.time_zone %};TZID="{{meeting.time_zone}}"{%endif%}:{{ slot.meeting_date|date:"Ymd" }}T{{slot.time_desc|slice:"5:9"}}00
DTSTAMP:{{ now|date:"Ymd" }}T{{ now|date:"His" }}Z
{% if session.description %}DESCRIPTION:
{{ session.description|escapejs }}
{% endif %}END:VEVENT
{%endifequal%}{%endfor%}{% endfor %}{% endfor %}END:VCALENDAR{% endautoescape %}

View file

@ -29,6 +29,7 @@ class DocumentInfo(models.Model):
abstract = models.TextField()
rev = models.CharField(verbose_name="revision", max_length=16, blank=True)
pages = models.IntegerField(blank=True, null=True)
order = models.IntegerField(default=1)
intended_std_level = models.ForeignKey(IntendedStdLevelName, blank=True, null=True)
std_level = models.ForeignKey(StdLevelName, blank=True, null=True)
ad = models.ForeignKey(Person, verbose_name="area director", related_name='ad_%(class)s_set', blank=True, null=True)

View file

@ -119,6 +119,11 @@ class IETFWG(Group):
return { "active": 1, "dormant": 2, "conclude": 3 }[self.state_id]
#area_director = models.ForeignKey(AreaDirector, null=True)
#meeting_scheduled = models.CharField(blank=True, max_length=3)
@property
def meeting_scheduled(self):
from meeting.models import Meeting
latest_meeting = Meeting.objects.order_by('-date')[0]
return "YES" if self.session_set.filter(meeting=latest_meeting) else "NO"
#email_address = models.CharField(blank=True, max_length=60)
@property
def email_address(self):

View file

@ -15,7 +15,7 @@ from django.template.defaultfilters import slugify
from ietf.idtracker.models import AreaDirector, IETFWG, Acronym, IRTF
from ietf.meeting.models import *
from ietf.proceedings.models import Meeting as MeetingOld, MeetingVenue, MeetingRoom, NonSession, WgMeetingSession, WgAgenda
from ietf.proceedings.models import Meeting as MeetingOld, MeetingVenue, MeetingRoom, NonSession, WgMeetingSession, WgAgenda, Minute, Slide
from redesign.person.models import *
from redesign.doc.models import Document, DocAlias
from redesign.importing.utils import get_or_create_email, old_person_to_person
@ -23,12 +23,14 @@ from redesign.name.models import *
from redesign.name.utils import name
# imports Meeting, MeetingVenue, MeetingRoom, NonSession, WgMeetingSession, WgAgenda
# imports Meeting, MeetingVenue, MeetingRoom, NonSession, WgMeetingSession, WgAgenda, Minute, Slide
# assumptions:
# - persons have been imported
# - groups have been imported
ietf_meeting = name(MeetingTypeName, "ietf", "IETF")
interim_meeting = name(MeetingTypeName, "interim", "Interim")
session_status_mapping = {
1: name(SessionStatusName, "schedw", "Waiting for Scheduling"),
@ -47,9 +49,15 @@ registration_slot = name(TimeSlotTypeName, "reg", "Registration")
plenary_slot = name(TimeSlotTypeName, "plenary", "Plenary")
other_slot = name(TimeSlotTypeName, "other", "Other")
conflict_constraint = name(ConstraintName, "conflict", "Conflicts with")
conflict_constraints = {
1: name(ConstraintName, "conflict", "Conflicts with"),
2: name(ConstraintName, "conflic2", "Conflicts with (secondary)"),
3: name(ConstraintName, "conflic3", "Conflicts with (tertiary)"),
}
agenda_doctype = name(DocTypeName, "agenda", "Agenda")
minutes_doctype = name(DocTypeName, "minutes", "Minutes")
slides_doctype = name(DocTypeName, "slides", "Slides")
system_person = Person.objects.get(name="(System)")
obviously_bogus_date = datetime.date(1970, 1, 1)
@ -63,6 +71,7 @@ for o in MeetingOld.objects.all():
m = Meeting(number="%s" % o.meeting_num)
m.pk = o.pk
m.type = ietf_meeting
m.date = o.start_date
m.city = o.city
@ -141,22 +150,6 @@ def parse_time_desc(o):
return (datetime.datetime.combine(d, start_time), datetime.datetime.combine(d, end_time))
def get_or_create_session_timeslot(meeting_time, room):
meeting = Meeting.objects.get(number=s.meeting_id)
starts, ends = parse_time_desc(meeting_time)
try:
slot = TimeSlot.objects.get(meeting=meeting, time=starts, location=room)
except TimeSlot.DoesNotExist:
slot = TimeSlot(meeting=meeting, time=starts, location=room)
slot.type = session_slot
slot.name = meeting_time.session_name.session_name if meeting_time.session_name_id else "Unknown"
slot.duration = ends - starts
slot.save()
return slot
requested_length_mapping = {
None: 0, # assume NULL to mean nothing particular requested
"1": 60 * 60,
@ -165,42 +158,53 @@ requested_length_mapping = {
"4": 150 * 60,
}
def import_materials_for_timeslot(timeslot, session=None, wg_meeting_session=None):
def import_materials(wg_meeting_session, timeslot=None, session=None):
if timeslot:
meeting = timeslot.meeting
materials = timeslot.materials
else:
meeting = session.meeting
materials = session.materials
if wg_meeting_session:
def import_material_kind(kind, doctype):
# import agendas
irtf = 0
if wg_meeting_session.irtf:
irtf = wg_meeting_session.group_acronym_id
agendas = WgAgenda.objects.filter(meeting=wg_meeting_session.meeting_id,
group_acronym_id=wg_meeting_session.group_acronym_id,
irtf=irtf)
found = kind.objects.filter(meeting=wg_meeting_session.meeting_id,
group_acronym_id=wg_meeting_session.group_acronym_id,
irtf=irtf,
interim=0)
for o in agendas:
for o in found:
if session:
acronym = session.group.acronym
else:
acronym = os.path.splitext(o.filename)[0].lower()
rev = "01"
name = ("agenda-%s-%s-%s" % (meeting.number, acronym, rev))
acronym = wg_meeting_session.acronym()
name = "%s-%s-%s" % (doctype.slug, meeting.number, acronym)
if kind == Slide:
name += "-%s" % o.slide_num
try:
d = Document.objects.get(type=agenda_doctype, docalias__name=name)
d = Document.objects.get(type=doctype, docalias__name=name)
except Document.DoesNotExist:
d = Document(type=agenda_doctype, name=name)
d = Document(type=doctype, name=name)
if session:
session_name = session.group.acronym.upper()
else:
session_name = timeslot.name
d.title = u"Agenda for %s at %s" % (session_name, meeting)
d.external_url = o.filename # save filenames for now as they don't appear to be quite regular
if kind == Slide:
d.title = o.slide_name
l = o.file_loc()
d.external_url = l[l.find("slides/") + len("slides/"):]
d.order = o.order_num or 1
else:
d.title = u"%s for %s at %s" % (doctype.name, session_name, meeting)
d.external_url = o.filename # save filenames for now as they don't appear to be quite regular
d.rev = "01"
d.group = session.group if session else None
d.save()
@ -208,7 +212,11 @@ def import_materials_for_timeslot(timeslot, session=None, wg_meeting_session=Non
materials.add(d)
for o in WgMeetingSession.objects.all().order_by("pk").filter(pk=1699):
import_material_kind(WgAgenda, agenda_doctype)
import_material_kind(Minute, minutes_doctype)
import_material_kind(Slide, slides_doctype)
for o in WgMeetingSession.objects.all().order_by("pk"):
# num_session is unfortunately not quite reliable, seems to be
# right for 1 or 2 but not 3 and it's sometimes null
sessions = o.num_session or 1
@ -217,22 +225,35 @@ for o in WgMeetingSession.objects.all().order_by("pk").filter(pk=1699):
print "importing WgMeetingSession", o.pk, "subsessions", sessions
print o.sched_time_id1, o.sched_time_id2, o.sched_time_id3
for i in range(1, 1 + sessions):
pk = o.pk + (i - 1) * 10000 # move extra session out of the way
try:
s = Session.objects.get(pk=pk)
except:
s = Session(pk=pk)
s.meeting = Meeting.objects.get(number=o.meeting_id)
sched_time_id = getattr(o, "sched_time_id%s" % i)
if sched_time_id:
room = Room.objects.get(pk=getattr(o, "sched_room_id%s_id" % i))
s.timeslot = get_or_create_session_timeslot(sched_time_id, room)
else:
s.timeslot = None
def get_timeslot(attr):
meeting_time = getattr(o, attr)
if not meeting_time:
return None
room = Room.objects.get(pk=getattr(o, attr.replace("time", "room") + "_id"))
starts, ends = parse_time_desc(meeting_time)
slots = TimeSlot.objects.filter(meeting=s.meeting, time=starts, location=room).filter(models.Q(session=s) | models.Q(session=None))
if slots:
slot = slots[0]
else:
slot = TimeSlot(meeting=s.meeting, time=starts, location=room)
slot.type = session_slot
slot.name = meeting_time.session_name.session_name if meeting_time.session_name_id else "Unknown"
slot.duration = ends - starts
return slot
timeslot = get_timeslot("sched_time_id%s" % i)
if o.irtf:
s.group = Group.objects.get(acronym=IRTF.objects.get(pk=o.group_acronym_id).acronym.lower())
else:
@ -241,22 +262,24 @@ for o in WgMeetingSession.objects.all().order_by("pk").filter(pk=1699):
# this wasn't actually a WG session, but rather a tutorial
# or similar, don't create a session but instead modify
# the time slot appropriately
if not s.timeslot:
if not timeslot:
print "IGNORING unscheduled non-WG-session", acronym.name
continue
if sched_time_id.session_name_id:
s.timeslot.name = sched_time_id.session_name.session_name
meeting_time = getattr(o, "sched_time_id%s" % i)
if meeting_time.session_name_id:
timeslot.name = meeting_time.session_name.session_name
else:
s.timeslot.name = acronym.name
timeslot.name = acronym.name
if "Plenary" in s.timeslot.name:
s.timeslot.type = plenary_slot
if "Plenary" in timeslot.name:
timeslot.type = plenary_slot
else:
s.timeslot.type = other_slot
s.timeslot.save()
timeslot.type = other_slot
timeslot.modified = o.last_modified_date
timeslot.save()
import_materials_for_timeslot(s.timeslot, wg_meeting_session=o)
import_materials(o, timeslot=timeslot)
continue
@ -266,14 +289,12 @@ for o in WgMeetingSession.objects.all().order_by("pk").filter(pk=1699):
s.requested = o.requested_date or obviously_bogus_date
s.requested_by = old_person_to_person(o.requested_by) if o.requested_by else system_person
s.requested_duration = requested_length_mapping[getattr(o, "length_session%s" % i)]
comments = []
special_req = (o.special_req or "").strip()
if special_req:
comments.append(u"Special requests:\n" + special_req)
s.comments = (o.special_req or "").strip()
conflict_other = (o.conflict_other or "").strip()
if conflict_other:
comments.append(u"Other conflicts:\n" + conflict_other)
s.comments = u"\n\n".join(comments)
if s.comments:
s.comments += " "
s.comments += u"(other conflicts: %s)" % conflict_other
s.status = session_status_mapping[o.status_id or 5]
s.scheduled = o.scheduled_date
@ -281,8 +302,24 @@ for o in WgMeetingSession.objects.all().order_by("pk").filter(pk=1699):
s.save()
import_materials_for_timeslot(s.timeslot, session=s, wg_meeting_session=o)
if timeslot:
timeslot.session = s
timeslot.modified = s.modified
timeslot.save()
import_materials(o, timeslot=timeslot, session=s)
# some sessions have been scheduled over multiple time slots
if i < 3:
timeslot = get_timeslot("combined_time_id%s" % i)
if timeslot:
timeslot.session = s
timeslot.modified = s.modified
timeslot.save()
import_materials(o, timeslot=timeslot, session=s)
for i in (1, 2, 3):
conflict = (getattr(o, "conflict%s" % i) or "").replace(",", " ").lower()
conflicting_groups = [g for g in conflict.split() if g]
for target in Group.objects.filter(acronym__in=conflicting_groups):
@ -290,7 +327,7 @@ for o in WgMeetingSession.objects.all().order_by("pk").filter(pk=1699):
meeting=s.meeting,
source=target,
target=s.group,
name=conflict_constraint)
name=conflict_constraints[i])
# missing following fields from old: ts_status_id (= third session

View file

@ -62,8 +62,10 @@ class IntendedStdLevelName(NameModel):
Practice, Historic, ..."""
class BallotPositionName(NameModel):
""" Yes, NoObjection, Abstain, Discuss, Recuse """
class MeetingTypeName(NameModel):
"""IETF, Interim"""
class SessionStatusName(NameModel):
""" Waiting for Approval, Approved, Waiting for Scheduling, Scheduled, Cancelled, Disapproved"""
"""Waiting for Approval, Approved, Waiting for Scheduling, Scheduled, Cancelled, Disapproved"""
class TimeSlotTypeName(NameModel):
"""Session, Break, Registration"""
class ConstraintName(NameModel):