datatracker/ietf/meeting/models.py
Henrik Levkowetz d383fac853 Merged branch/iola/migration-fixes@4319, containing these changesets from olau@iola.dk:
- [4319]: Only query for regular IETF meetings when calculating cut off dates
     (reported by Ryan Cross).

   - [4311]: Fix bug in liaison form that prevents Secretariat users from posting
     statements on behalf of SDO liaison managers in some cases.


   - [4310]: Fix problem with direct replyto path in liaison form not using role
     emails (reported by Stephanie McCammon).


   - [4307]: Fix missing return in liaison proxy, fixes problem with from email
     on https://datatracker.ietf.org/liaison/1154/ as reported by Stephanie
     McCammon.


   - [4260]: Move note about IANA scraping messages, apparently I managed to
     put it in the wrong place (they're of course scraping draft approvals, not
     the ballot announcements).


   - [4253]: Move last call announcement text to last call event rather than
     stuffing it inside the state change event.


   - [4252]: Declare coding system to work around annoying problem when the
     date produced by SVN is localized.
 - Legacy-Id: 4331
Note: SVN reference [4252] has been migrated to Git commit 5858454c74

Note: SVN reference [4253] has been migrated to Git commit 25cb532348

Note: SVN reference [4260] has been migrated to Git commit 7b2963aaf0

Note: SVN reference [4307] has been migrated to Git commit b418e5d141

Note: SVN reference [4310] has been migrated to Git commit 9b4415fe51

Note: SVN reference [4311] has been migrated to Git commit bbeaa2d022

Note: SVN reference [4319] has been migrated to Git commit 7db44f8e50
2012-04-26 19:34:57 +00:00

173 lines
7.3 KiB
Python

# old meeting models can be found in ../proceedings/models.py
import pytz, datetime
from django.db import models
from django.conf import settings
from timedeltafield import TimedeltaField
from ietf.group.models import Group
from ietf.person.models import Person
from ietf.doc.models import Document
from ietf.name.models import MeetingTypeName, TimeSlotTypeName, SessionStatusName, ConstraintName
countries = pytz.country_names.items()
countries.sort(lambda x,y: cmp(x[1], y[1]))
timezones = [(name, name) for name in pytz.common_timezones]
timezones.sort()
class Meeting(models.Model):
# number is either the number for IETF meetings, or some other
# identifier for interim meetings/IESG retreats/liaison summits/...
number = models.CharField(unique=True, 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.
date = models.DateField()
city = models.CharField(blank=True, max_length=255)
country = models.CharField(blank=True, max_length=2, choices=countries)
# We can't derive time-zone from country, as there are some that have
# more than one timezone, and the pytz module doesn't provide timezone
# lookup information for all relevant city/country combinations.
time_zone = models.CharField(blank=True, max_length=255, choices=timezones)
venue_name = models.CharField(blank=True, max_length=255)
venue_addr = models.TextField(blank=True)
break_area = models.CharField(blank=True, max_length=255)
reg_area = models.CharField(blank=True, max_length=255)
def __unicode__(self):
if self.type_id == "ietf":
return "IETF-%s" % (self.number)
else:
return self.number
def time_zone_offset(self):
# Look at the time of 8 o'clock sunday, rather than 0h sunday, to get
# the right time after a possible summer/winter time change.
return pytz.timezone(self.time_zone).localize(datetime.datetime.combine(self.date, datetime.time(8, 0))).strftime("%z")
def get_meeting_date (self,offset):
return self.date + datetime.timedelta(days=offset)
@classmethod
def get_first_cut_off(cls):
date = cls.objects.all().filter(type="ietf").order_by('-date')[0].date
offset = datetime.timedelta(days=settings.FIRST_CUTOFF_DAYS)
return date - offset
@classmethod
def get_second_cut_off(cls):
date = cls.objects.all().filter(type="ietf").order_by('-date')[0].date
offset = datetime.timedelta(days=settings.SECOND_CUTOFF_DAYS)
return date - offset
@classmethod
def get_ietf_monday(cls):
date = cls.objects.all().filter(type="ietf").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=settings.SUBMISSION_START_DAYS)
def get_submission_cut_off_date(self):
return self.date + datetime.timedelta(days=settings.SUBMISSION_CUTOFF_DAYS)
def get_submission_correction_date(self):
return self.date + datetime.timedelta(days=settings.SUBMISSION_CORRECTION_DAYS)
class Room(models.Model):
meeting = models.ForeignKey(Meeting)
name = models.CharField(max_length=255)
def __unicode__(self):
return self.name
class TimeSlot(models.Model):
"""
Everything that would appear on the meeting agenda of a meeting is
mapped to a time slot, including breaks. Sessions are connected to
TimeSlots during scheduling. A template function to populate a
meeting with an appropriate set of TimeSlots is probably also
needed.
"""
meeting = models.ForeignKey(Meeting)
type = models.ForeignKey(TimeSlotTypeName)
name = models.CharField(max_length=255)
time = models.DateTimeField()
duration = TimedeltaField()
location = models.ForeignKey(Room, blank=True, null=True)
show_location = models.BooleanField(default=True, help_text="Show location in agenda")
session = models.ForeignKey('Session', null=True, blank=True, help_text=u"Scheduled session, if any")
modified = models.DateTimeField(default=datetime.datetime.now)
def __unicode__(self):
location = self.get_location()
if not location:
location = "(no location)"
return u"%s: %s-%s %s, %s" % (self.meeting.number, self.time.strftime("%m-%d %H:%M"), (self.time + self.duration).strftime("%H:%M"), self.name, location)
def end_time(self):
return self.time + self.duration
def get_location(self):
location = self.location
if location:
location = location.name
elif self.type_id == "reg":
location = self.meeting.reg_area
elif self.type_id == "break":
location = self.meeting.break_area
if not self.show_location:
location = ""
return location
class Constraint(models.Model):
"""Specifies a constraint on the scheduling between source and
target, e.g. some kind of conflict."""
meeting = models.ForeignKey(Meeting)
source = models.ForeignKey(Group, related_name="constraint_source_set")
target = models.ForeignKey(Group, related_name="constraint_target_set")
name = models.ForeignKey(ConstraintName)
def __unicode__(self):
return u"%s %s %s" % (self.source, self.name.name.lower(), self.target)
class Session(models.Model):
"""Session records that a group should have a session on the
meeting (time and location is stored in a TimeSlot) - if multiple
timeslots are needed, multiple sessions will have to be created.
Training sessions and similar are modeled by filling in a
responsible group (e.g. Edu team) and filling in the name."""
meeting = models.ForeignKey(Meeting)
name = models.CharField(blank=True, max_length=255, help_text="Name of session, in case the session has a purpose rather than just being a group meeting")
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)
requested = models.DateTimeField(default=datetime.datetime.now)
requested_by = models.ForeignKey(Person)
requested_duration = TimedeltaField(default=0)
comments = models.TextField(blank=True)
status = models.ForeignKey(SessionStatusName)
scheduled = models.DateTimeField(null=True, blank=True)
modified = models.DateTimeField(default=datetime.datetime.now)
materials = models.ManyToManyField(Document, blank=True)
def agenda(self):
try:
return self.materials.get(type="agenda",states__type="agenda",states__slug="active")
except Exception, e:
return None
def __unicode__(self):
if self.meeting.type_id == "interim":
return self.meeting.number
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)")