Files
web2.0-backend/infoscreen/models.py
T
2016-09-27 21:15:04 +03:00

218 lines
6.4 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
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
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(),
'create_template_url': self.get_create_template_url(),
'options': {}
}
def delete(self):
# since generic foreignkeys suck. delete infoitems 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):
def get_template_url(self):
return "/static/html/abb.html"
@staticmethod
def get_create_template_url():
return "/static/html/abb_create.html"
class SossoInfoItem(InfoItem):
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):
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 ExternalImageInfoItem(InfoItem):
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 somekind 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 ABBJob(models.Model):
sw_id = models.IntegerField(default=-1)
title = models.CharField(max_length=255)
QR = models.CharField(max_length=255, default="")
created = models.DateTimeField(default=timezone.now)
def get_dict(self):
return {
"title": self.title,
"QR": self.QR,
}
def __str__(self):
return self.title
class ImageUploadForm(forms.Form):
'''
Form used to handle imageuploads to
infoscreen app
'''
name = forms.CharField()
image = forms.ImageField()