Files
web2.0-backend/infoscreen/models.py
T
2017-03-08 18:30:38 +02:00

283 lines
7.8 KiB
Python

from django.db import models
from django import forms
from django.utils import timezone
from datetime import datetime
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
class InfoItem(models.Model):
class __meta__:
abstract = True
name = models.CharField(max_length=255)
expire_date = models.DateTimeField(blank=True, null=True) # None means never expiring item
display_name = "Default item"
def get_template_url(self):
raise NotImplementedError("inheriting classes must implement get_template_url")
@staticmethod
def get_create_template_url():
raise NotImplementedError("inheriting classes must implement get_create_template_url")
@classmethod
def create_from_dict(cls, d):
item = cls()
item.update_from_dict(d)
return item
def update_from_dict(self, d):
try:
expire_date = d.pop('expire_date', None)
self.expire_date = datetime.strptime(expire_date, "%Y-%m-%d %H:%M:%S")
except:
pass
dmap = {
'name': 'name',
}
for k, v in d.items():
try:
self.__setattr__(dmap[k], v)
except KeyError:
pass
self.save()
def get_dict(self):
return {
'id': self.id,
'name': self.name,
'item_type': ContentType.objects.get_for_model(self).id,
'template_url': self.get_template_url(),
'display_name': self.display_name,
'create_template_url': self.get_create_template_url(),
'options': {}
}
def delete(self):
# since generic foreign keys suck, delete info items pointing here manually
InfoInstance.objects.filter(item_id=self.id, item_type=ContentType.objects.get_for_model(self)).delete()
super().delete()
@classmethod
def get_subclasses(cls):
for subclass in cls.__subclasses__():
yield from subclass.get_subclasses()
yield subclass
def __str__(self):
return self.name
class ABBInfoItem(InfoItem):
display_name = _("ABB jobs")
def get_template_url(self):
return "/static/html/abb.html"
@staticmethod
def get_create_template_url():
return "/static/html/abb_create.html"
class ExternalWebsiteInfoItem(InfoItem):
display_name = _("External website")
url = models.TextField()
def get_template_url(self):
return "/static/html/external_website.html?url={}".format(self.name)
@staticmethod
def get_create_template_url():
return "/static/html/external_website_create.html"
def get_dict(self):
d = super().get_dict()
d["options"] = {'url': self.url}
return d
@classmethod
def create_from_dict(cls, d):
item = cls()
item.update_from_dict(d)
return item
def get_list(self):
return {
'id':self.id,
'name':self.name,
'url': self.url,
}
def update_from_dict(self, d):
try:
expire_date = d.pop('expire_date', None)
self.expire_date = datetime.strptime(expire_date, "%Y-%m-%d %H:%M:%S")
except:
pass
dmap = {
'name': 'name',
'url': 'url',
}
for k, v in d.items():
try:
self.__setattr__(dmap[k], v)
except KeyError:
pass
self.save()
class SossoInfoItem(InfoItem):
display_name = _("Sössö articles")
def get_template_url(self):
return "/static/html/sosso.html"
@staticmethod
def get_create_template_url():
return "/static/html/sosso_create.html"
class ImageInfoItem(InfoItem):
display_name = _("Image")
img = models.ImageField(upload_to="infoimages/")
def get_template_url(self):
# get param to avoid angular from optimizing same template with different options
return "/static/html/generic_image.html?img={}".format(self.name)
@staticmethod
def get_create_template_url():
return "/static/html/generic_image_create.html"
def get_dict(self):
d = super().get_dict()
d["options"] = {'img': self.img.url}
return d
class HslInfoItem(InfoItem):
display_name = _("HSL timetables")
def get_template_url(self):
return "/static/html/hsl.html"
@staticmethod
def get_create_template_url():
return "/static/html/hsl_create.html"
class ExternalImageInfoItem(InfoItem):
display_name = _("External image")
url = models.TextField()
def get_template_url(self):
return "/static/html/generic_image.html?img={}".format(self.name)
@staticmethod
def get_create_template_url():
return "/static/html/generic_external_image_create.html"
def get_dict(self):
d = super().get_dict()
d["options"] = {'img': self.url}
return d
@classmethod
def create_from_dict(cls, d):
item = cls()
item.update_from_dict(d)
return item
def update_from_dict(self, d):
try:
expire_date = d.pop('expire_date', None)
self.expire_date = datetime.strptime(expire_date, "%Y-%m-%d %H:%M:%S")
except:
pass
dmap = {
'name': 'name',
'url': 'url',
}
for k, v in d.items():
try:
self.__setattr__(dmap[k], v)
except KeyError:
pass
self.save()
class InfoInstance(models.Model):
rotation = models.ForeignKey('Rotation', related_name='instances')
duration = models.FloatField(default=15.0) # seconds
# generic relation to some kind of InfoItem
item_id = models.PositiveIntegerField()
item_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
item = GenericForeignKey('item_type', 'item_id')
@classmethod
def create_from_dict(cls, d):
try:
rotation = Rotation.objects.get(pk=int(d["rotation_id"]))
ct = ContentType.objects.get_for_id(int(d["item_type"]))
item = ct.get_object_for_this_type(pk=int(d["item_id"]))
duration = float(d["duration"])
except:
raise RuntimeError("invalid parameters supplied supplied")
try:
return cls.objects.create(
rotation=rotation,
item=item,
duration=duration
)
except:
raise RuntimeError("error while adding instance to db")
def get_dict(self):
return {
'id': self.id,
'item': self.item.get_dict(),
'duration': self.duration,
}
def __str__(self):
return "{}: {} ({}s)".format(self.rotation.name, self.item.name, self.duration)
class Rotation(models.Model):
name = models.CharField(max_length=255)
def get_dict(self):
# exclude expired items from rotation (note: using tricky syntax to avoid excluding items with no expire_date)
now = timezone.now()
instances = self.instances.all()
filtered = filter(lambda i: (i.item.expire_date or now) >= now, list(instances))
instance_list = list(map(lambda i: i.get_dict(), filtered))
return {
'id':self.id,
'name': self.name,
'instances': instance_list,
}
def get_list(self):
return {
'id':self.id,
'name':self.name,
}
def __str__(self):
return self.name
class ImageUploadForm(forms.Form):
'''
Form used to handle imageuploads to
infoscreen app
'''
name = forms.CharField()
image = forms.ImageField()
class HSLDataModel(models.Model):
data = models.TextField(default="", editable=False)