Files
web2.0-backend/infoscreen/models.py
T
2017-10-31 16:57:56 +02:00

410 lines
12 KiB
Python

"""File containing Infoscreen models."""
from datetime import datetime
from django.db import models
from django import forms
from django.utils import timezone
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):
"""Abstract model representing single Infoscreen item."""
class __meta__:
abstract = True
name = models.CharField(max_length=255)
# expire_date = None means never expiring item
expire_date = models.DateTimeField(blank=True, null=True)
display_name = "Default item"
def get_template_url(self):
"""Get infoscreen template url."""
raise NotImplementedError(
"inheriting classes must implement get_template_url")
@staticmethod
def get_create_template_url():
"""Get create infoscreen template url command."""
raise NotImplementedError(
"inheriting classes must implement get_create_template_url")
@classmethod
def create_from_dict(cls, d):
"""Convert given dict to model."""
item = cls()
item.update_from_dict(d)
return item
def update_from_dict(self, d):
"""Update model based on given dict."""
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):
"""Convert django model to dict and return it."""
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):
"""Delete infoinstance object."""
# 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):
"""Get item subclasses."""
for subclass in cls.__subclasses__():
yield from subclass.get_subclasses()
yield subclass
def __str__(self):
"""Return class name."""
return self.name
class ABBInfoItem(InfoItem):
"""Class for ABB Infoscreen item."""
display_name = _("ABB jobs")
def get_template_url(self):
"""Return ABB infoitem template url."""
return "/static/html/abb.html"
@staticmethod
def get_create_template_url():
"""Call create ABB infoitem template url command."""
return "/static/html/abb_create.html"
class ApyInfoItem(InfoItem):
"""Class for APY Infoscreen item."""
display_name = _("APY Item")
def get_template_url(self):
"""Return APY infoitem template url."""
return "/static/html/apy.html"
@staticmethod
def get_create_template_url():
"""Call create APY infoitem template url command."""
return "/static/html/apy_create.html"
class ExternalWebsiteInfoItem(InfoItem):
"""Class for external website info item."""
display_name = _("External website")
url = models.URLField()
def get_template_url(self):
"""Return external website infoitem template url."""
return "/static/html/external_website.html?url={}".format(self.name)
@staticmethod
def get_create_template_url():
"""Call create external website infoitem template url command."""
return "/static/html/external_website_create.html"
def get_dict(self):
"""Convert django model to dict and return it."""
d = super().get_dict()
d["options"] = {'url': self.url}
return d
@classmethod
def create_from_dict(cls, d):
"""Convert given dict to model."""
item = cls()
item.update_from_dict(d)
return item
def get_list(self):
"""Return list containing infoitem data."""
return {
'id': self.id,
'name': self.name,
'url': self.url,
}
def update_from_dict(self, d):
"""Update model based on given dict."""
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):
"""Class for Sosso Infoscreen item."""
display_name = _("Sössö articles")
def get_template_url(self):
"""Return Sosso infoitem template url."""
return "/static/html/sosso.html"
@staticmethod
def get_create_template_url():
"""Call create Sosso infoitem template url command."""
return "/static/html/sosso_create.html"
class EventInfoItem(InfoItem):
"""Class for Event Infoscreen item."""
display_name = _("Events")
def get_template_url(self):
"""Return Event infoitem template url."""
return "/static/html/events.html"
@staticmethod
def get_create_template_url():
"""Call create Event infoitem template url command."""
return "/static/html/events_create.html"
class ImageInfoItem(InfoItem):
"""Class for Image Infoscreen item."""
display_name = _("Image")
img = models.ImageField(upload_to="infoimages/")
def get_template_url(self):
"""Return Image infoitem template url."""
# 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():
"""Call create Image infoitem template url command."""
return "/static/html/generic_image_create.html"
def get_dict(self):
"""Convert django model to dict and return it."""
d = super().get_dict()
d["options"] = {'img': self.img.url}
return d
class VideoInfoItem(InfoItem):
"""Class for Video Infoscreen item."""
display_name = ("Video")
video = models.FileField(upload_to="infovideos/")
def get_template_url(self):
"""Return Video infoitem template url."""
return "/static/html/generic_video.html?video={}".format(self.name)
@staticmethod
def get_create_template_url():
"""Call create Video infoitem template url command."""
return "/static/html/generic_video_create.html"
def get_dict(self):
"""Convert django model to dict and return it."""
d = super().get_dict()
d["options"] = {'video': self.video.url}
return d
class HslInfoItem(InfoItem):
"""Class for HSL Infoscreen item."""
display_name = _("HSL timetables")
def get_template_url(self):
"""Return HSL infoitem template url."""
return "/static/html/hsl.html"
@staticmethod
def get_create_template_url():
"""Call create HSL infoitem template url command."""
return "/static/html/hsl_create.html"
class ExternalImageInfoItem(InfoItem):
"""Class for External Image Infoscreen item."""
display_name = _("External image")
url = models.URLField()
def get_template_url(self):
"""Return External Image infoitem template url."""
return "/static/html/generic_image.html?img={}".format(self.name)
@staticmethod
def get_create_template_url():
"""Call create External Image infoitem template url command."""
return "/static/html/generic_external_image_create.html"
def get_dict(self):
"""Convert django model to dict and return it."""
d = super().get_dict()
d["options"] = {'img': self.url}
return d
@classmethod
def create_from_dict(cls, d):
"""Convert given dict to model."""
item = cls()
item.update_from_dict(d)
return item
def update_from_dict(self, d):
"""Update model based on given dict."""
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):
"""Class for Info instance in Infoscreen."""
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):
"""Convert given dict to model."""
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):
"""Convert django model to dict and return it."""
return {
'id': self.id,
'item': self.item.get_dict(),
'duration': self.duration,
}
def __str__(self):
"""Return model name."""
return "{}: {} ({}s)".format(
self.rotation.name, self.item.name, self.duration)
class Rotation(models.Model):
"""Class for rotation model."""
name = models.CharField(max_length=255)
def get_dict(self):
"""Convert django model to dict and return it."""
# 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 list containing infoitem data."""
return {
'id': self.id,
'name': self.name,
}
def __str__(self):
"""Return model name."""
return self.name
class ImageUploadForm(forms.Form):
"""Form used to handle imageuploads to infoscreen app."""
name = forms.CharField()
image = forms.ImageField()
class UploadFileForm(forms.Form):
"""Form used for uploading file."""
name = forms.CharField()
video = forms.FileField()