Added model UrlResource with FK to Room

This will make it easier to support audio and video streaming links
which vary by meeting, but are fixed by Room. Also added migrations,
resource, admin support, supporting methods, and a bit of refactoring.
 - Legacy-Id: 11644
This commit is contained in:
Henrik Levkowetz 2016-07-13 13:07:20 +00:00
parent 14e97a732c
commit 7bc8e043f1
5 changed files with 141 additions and 16 deletions

View file

@ -1,11 +1,21 @@
from django.contrib import admin
from ietf.meeting.models import (Meeting, Room, Session, TimeSlot, Constraint, Schedule,
SchedTimeSessAssignment, ResourceAssociation, FloorPlan)
SchedTimeSessAssignment, ResourceAssociation, FloorPlan, UrlResource)
class UrlResourceAdmin(admin.ModelAdmin):
list_display = ['name', 'room', 'url', ]
raw_id_fields = ['room', ]
admin.site.register(UrlResource, UrlResourceAdmin)
class UrlResourceInline(admin.TabularInline):
model = UrlResource
class RoomAdmin(admin.ModelAdmin):
list_display = ["id", "meeting", "name", "capacity", "functional_name", "x1", "y1", "x2", "y2", ]
list_filter = ["meeting"]
inlines = [UrlResourceInline, ]
ordering = ["-meeting"]
admin.site.register(Room, RoomAdmin)
@ -97,7 +107,7 @@ admin.site.register(SchedTimeSessAssignment, SchedTimeSessAssignmentAdmin)
class ResourceAssociationAdmin(admin.ModelAdmin):
list_display = ["desc", "icon", "desc", ]
list_display = ["name", "icon", "desc", ]
admin.site.register(ResourceAssociation, ResourceAssociationAdmin)
class FloorPlanAdmin(admin.ModelAdmin):

View file

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('name', '0013_add_group_type_verbose_name_data'),
('meeting', '0026_add_floorplan_data'),
]
operations = [
migrations.CreateModel(
name='UrlResource',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('url', models.URLField(null=True, blank=True)),
('name', models.ForeignKey(to='name.RoomResourceName')),
('room', models.ForeignKey(to='meeting.Room')),
],
options={
},
bases=(models.Model,),
),
]

View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
rooms = [
("Bellevue", "http://ietf96streaming.dnsalias.net/ietf/ietf961.m3u"),
("Charlottenburg I", "http://ietf96streaming.dnsalias.net/ietf/ietf962.m3u"),
("Charlottenburg II/III", "http://ietf96streaming.dnsalias.net/ietf/ietf963.m3u"),
("Lincke", "http://ietf96streaming.dnsalias.net/ietf/ietf964.m3u"),
("Potsdam I", "http://ietf96streaming.dnsalias.net/ietf/ietf965.m3u"),
("Potsdam II", "http://ietf96streaming.dnsalias.net/ietf/ietf966.m3u"),
("Potsdam III", "http://ietf96streaming.dnsalias.net/ietf/ietf967.m3u"),
("Schoeneberg", "http://ietf96streaming.dnsalias.net/ietf/ietf968.m3u"),
("Tiergarten", "http://ietf96streaming.dnsalias.net/ietf/ietf969.m3u"),
]
def forward(apps, schema_editor):
Room = apps.get_model('meeting','Room')
Meeting = apps.get_model('meeting','Meeting')
UrlResource = apps.get_model('meeting','UrlResource')
RoomResourceName = apps.get_model('name','RoomResourceName')
meeting = Meeting.objects.get(number='96')
audiostream, _ = RoomResourceName.objects.get_or_create(slug='audiostream', name='Audio Stream', desc='Audio streaming support')
for item in rooms:
name, url = item
try:
room = Room.objects.get(name=name, meeting=meeting)
urlres, _ = UrlResource.objects.get_or_create(name=audiostream, room=room, url=url)
except Room.DoesNotExist:
import sys
sys.stderr.write("\nNo such room: %s" % name)
def backward(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('meeting', '0027_urlresource'),
]
operations = [
migrations.RunPython(forward,backward)
]

View file

@ -280,7 +280,6 @@ class Meeting(models.Model):
class ResourceAssociation(models.Model):
name = models.ForeignKey(RoomResourceName)
#url = models.UrlField() # not sure what this was for.
icon = models.CharField(max_length=64) # icon to be found in /static/img
desc = models.CharField(max_length=256)
@ -344,7 +343,7 @@ class Room(models.Model):
'name': self.name,
'capacity': self.capacity,
}
# floorplan support
def left(self):
return min(self.x1, self.x2) if (self.x1 and self.x2) else 0
def top(self):
@ -361,9 +360,24 @@ class Room(models.Model):
if self.functional_name[0].isdigit():
return ""
return self.functional_name
# audio stream support
def audio_stream_url(self):
urlresource = self.urlresource_set.filter(name_id='audiostream').first()
return urlresource.url if urlresource else None
def video_stream_url(self):
urlresource = self.urlresource_set.filter(name_id__in=['meetecho', ]).first()
return urlresource.url if urlresource else None
#
class Meta:
ordering = ["-meeting", "name"]
class UrlResource(models.Model):
"For things like audio stream urls, meetecho stream urls"
name = models.ForeignKey(RoomResourceName)
room = models.ForeignKey(Room)
url = models.URLField(null=True, blank=True)
def floorplan_path(instance, filename):
root, ext = os.path.splitext(filename)
return u"%s/floorplan-%s-%s%s" % (settings.FLOORPLAN_MEDIA_DIR, instance.meeting.number, xslugify(instance.name), ext)
@ -373,6 +387,9 @@ class FloorPlan(models.Model):
meeting = models.ForeignKey(Meeting)
order = models.SmallIntegerField()
image = models.ImageField(storage=NoLocationMigrationFileSystemStorage(), upload_to=floorplan_path, blank=True, default=None)
#
def __unicode__(self):
return 'floorplan-%s-%s' % (self.meeting.number, xslugify(self.name))
# === Schedules, Sessions, Timeslots and Assignments ===========================
@ -423,6 +440,7 @@ class TimeSlot(models.Model):
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
@ -452,26 +470,28 @@ class TimeSlot(models.Model):
name_parts.append(location)
return ' - '.join(name_parts)
@property
def tz(self):
if self.meeting.time_zone:
return pytz.timezone(self.meeting.time_zone)
else:
return None
if not hasattr(self, '_cached_tz'):
if self.meeting.time_zone:
self._cached_tz = pytz.timezone(self.meeting.time_zone)
else:
self._cached_tz = None
return self._cached_tz
def tzname(self):
if self.tz:
return self.tz.tzname(self.time)
if self.tz():
return self.tz().tzname(self.time)
else:
return ""
def utc_start_time(self):
if self.tz:
local_start_time = self.tz.localize(self.time)
if self.tz():
local_start_time = self.tz().localize(self.time)
return local_start_time.astimezone(pytz.utc)
else:
return None
def utc_end_time(self):
if self.tz:
local_end_time = self.tz.localize(self.end_time())
if self.tz():
local_end_time = self.tz().localize(self.end_time())
return local_end_time.astimezone(pytz.utc)
else:
return None

View file

@ -8,7 +8,8 @@ from tastypie.cache import SimpleCache
from ietf import api
from ietf.meeting.models import ( Meeting, ResourceAssociation, Constraint, Room, Schedule, Session,
TimeSlot, SchedTimeSessAssignment, SessionPresentation, FloorPlan )
TimeSlot, SchedTimeSessAssignment, SessionPresentation, FloorPlan,
UrlResource)
from ietf.name.resources import MeetingTypeNameResource
class MeetingResource(ModelResource):
@ -252,3 +253,22 @@ class SessionPresentationResource(ModelResource):
}
api.meeting.register(SessionPresentationResource())
from ietf.name.resources import RoomResourceNameResource
class UrlResourceResource(ModelResource):
name = ToOneField(RoomResourceNameResource, 'name')
room = ToOneField(RoomResource, 'room')
class Meta:
queryset = UrlResource.objects.all()
serializer = api.Serializer()
cache = SimpleCache()
#resource_name = 'urlresource'
filtering = {
"id": ALL,
"url": ALL,
"name": ALL_WITH_RELATIONS,
"room": ALL_WITH_RELATIONS,
}
api.meeting.register(UrlResourceResource())