Source code for boardinghouse.contrib.demo.models

import datetime

from django.conf import settings
from django.db import models
from django.utils import six, timezone
from django.utils.functional import cached_property
from django.utils.timesince import timesince, timeuntil
from django.utils.translation import ugettext as _

import pytz

from boardinghouse.base import SharedSchemaMixin
from boardinghouse.exceptions import Forbidden
from boardinghouse.schema import activate_schema, deactivate_schema


[docs]class ExpiringObjectsQuerySet(models.query.QuerySet):
[docs] def expired(self): "Expired demos" return self.filter(expires_at__lt=timezone.now().replace(tzinfo=pytz.utc))
[docs] def active(self): "Non-expired demos" return self.filter(expires_at__gte=timezone.now().replace(tzinfo=pytz.utc))
[docs]@six.python_2_unicode_compatible class DemoSchema(SharedSchemaMixin, models.Model): """A User's demo setup. Each user may only have at most one DemoSchema object, which will have an expiry date. We retain a reference to the template from which it was cloned, so we can easily reset it. """ user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, primary_key=True, related_name='demo_schema') expires_at = models.DateTimeField() from_template = models.ForeignKey('template.SchemaTemplate', on_delete=models.CASCADE, related_name='demo_schemata', limit_choices_to=~models.Q(use_for_demo=None)) objects = ExpiringObjectsQuerySet.as_manager() class Meta: verbose_name = 'user demo' verbose_name_plural = 'user demos' def __str__(self): if self.expired: return u'Expired demo for {0} (expired {1} ago)'.format(self.user, timesince(self.expires_at)) return u'Demo for {0}: expires at {1} ({2} from now)'.format(self.user, self.expires_at, timeuntil(self.expires_at)) @cached_property def schema(self): return '{0}{1}'.format(settings.BOARDINGHOUSE_DEMO_PREFIX, self.user_id) @property def expired(self): return self.expires_at < timezone.now().replace(tzinfo=pytz.utc) @property def name(self): return _('Demo schema ({template_name})').format(template_name=self.from_template.name) @property def _clone(self): return self.from_template.schema def save(self, *args, **kwargs): if not self.expires_at: self.expires_at = datetime.datetime.utcnow().replace(tzinfo=pytz.utc) + settings.BOARDINGHOUSE_DEMO_PERIOD return super(DemoSchema, self).save(*args, **kwargs) def activate(self): if self.expired: raise DemoSchemaExpired() activate_schema(self.schema) def deactivate(self): deactivate_schema()
[docs]class DemoSchemaExpired(Forbidden): pass
class ValidDemoTemplateManager(models.Manager): def get_queryset(self): return super(ValidDemoTemplateManager, self).get_queryset().filter(template_schema__is_active=True)
[docs]class ValidDemoTemplate(SharedSchemaMixin, models.Model): template_schema = models.OneToOneField('template.SchemaTemplate', primary_key=True, on_delete=models.CASCADE, related_name='use_for_demo') objects = ValidDemoTemplateManager() def __str__(self): return '{0} is valid as a demo source'.format(self.template_schema)