2525from ietf .group .utils import can_manage_materials
2626from ietf .name .models import MeetingTypeName , TimeSlotTypeName , SessionStatusName , ConstraintName , RoomResourceName
2727from ietf .person .models import Person
28+ from ietf .utils .storage import NoLocationMigrationFileSystemStorage
2829
2930countries = pytz .country_names .items ()
3031countries .sort (lambda x ,y : cmp (x [1 ], y [1 ]))
@@ -274,6 +275,8 @@ def updated(self):
274275 class Meta :
275276 ordering = ["-date" , "id" ]
276277
278+ # === Rooms, Resources, Floorplans =============================================
279+
277280class ResourceAssociation (models .Model ):
278281 name = models .ForeignKey (RoomResourceName )
279282 #url = models.UrlField() # not sure what this was for.
@@ -298,6 +301,15 @@ class Room(models.Model):
298301 capacity = models .IntegerField (null = True , blank = True )
299302 resources = models .ManyToManyField (ResourceAssociation , blank = True )
300303 session_types = models .ManyToManyField (TimeSlotTypeName , blank = True )
304+ # floorplan-related properties
305+ floorplan = models .ForeignKey ('FloorPlan' , null = True , blank = True , default = None )
306+ # floorplan: room pixel position : (0,0) is top left of image, (xd, yd)
307+ # is room width, height.
308+ x1 = models .SmallIntegerField (null = True , blank = True , default = None )
309+ y1 = models .SmallIntegerField (null = True , blank = True , default = None )
310+ x2 = models .SmallIntegerField (null = True , blank = True , default = None )
311+ y2 = models .SmallIntegerField (null = True , blank = True , default = None )
312+ # end floorplan-related stuff
301313
302314 def __unicode__ (self ):
303315 return "%s size: %s" % (self .name , self .capacity )
@@ -332,6 +344,36 @@ def json_dict(self, host_scheme):
332344 'capacity' : self .capacity ,
333345 }
334346
347+ def left (self ):
348+ return min (self .x1 , self .x2 ) if (self .x1 and self .x2 ) else 0
349+ def top (self ):
350+ return min (self .y1 , self .y2 ) if (self .y1 and self .y2 ) else 0
351+ def right (self ):
352+ return max (self .x1 , self .x2 ) if (self .x1 and self .x2 ) else 0
353+ def bottom (self ):
354+ return max (self .y1 , self .y2 ) if (self .y1 and self .y2 ) else 0
355+ def functional_display_name (self ):
356+ if not self .functional_name :
357+ return ""
358+ if self .functional_name .lower ().startswith ('breakout' ):
359+ return ""
360+ if self .functional_name [0 ].isdigit ():
361+ return ""
362+ return self .functional_name
363+ class Meta :
364+ ordering = ["-meeting" , "name" ]
365+
366+ def floorplan_path (instance , filename ):
367+ root , ext = os .path .splitext (filename )
368+ return u"%s/floorplan-%s-%s%s" % (settings .FLOORPLAN_MEDIA_DIR , instance .meeting .number , slugify (instance .name ), ext )
369+
370+ class FloorPlan (models .Model ):
371+ name = models .CharField (max_length = 255 )
372+ meeting = models .ForeignKey (Meeting )
373+ order = models .SmallIntegerField ()
374+ image = models .ImageField (storage = NoLocationMigrationFileSystemStorage (), upload_to = floorplan_path , blank = True , default = None )
375+
376+ # === Schedules, Sessions, Timeslots and Assignments ===========================
335377
336378class TimeSlot (models .Model ):
337379 """
@@ -1307,3 +1349,4 @@ def badness_fast(self, timeslot, scheduleslot, session_pk_list):
13071349 if self .badness_test (1 ):
13081350 self .badness_log (1 , "badgroup: %s badness = %u\n " % (self .group .acronym , badness ))
13091351 return badness
1352+
0 commit comments