# Path: boardinghouse/contrib/demo/models.py
# 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()
# 
# 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)


from django import forms
from django.contrib import admin
from django.utils.timesince import timesince, timeuntil
from .models import DemoSchema, ValidDemoTemplate

    def __init__(self, *args, **kwargs):
        super(ValidDemoInline.form, self).__init__(*args, **kwargs)
        if self.instance.pk:
            self.initial['use_for_demo'] = True

    def save(self, commit=True):
        if self.cleaned_data.get('use_for_demo', False):
            return super(ValidDemoInline.form, self).save(commit)
        elif commit:
            # There's no visible way I can think of to actually get commit=False from the admin,
            # but I'm not game to omit the elif clause, in case there is a case I'm not aware of.
            # Otherwise, it may delete the object when it should not be deleted.
            self.instance.delete()
        return self.instance


# Inject an inline to allow marking as valid for demo.
class ValidDemoInline(admin.StackedInline):
    model = ValidDemoTemplate
    can_delete = False
    template = 'admin/edit_inline/use-for-demo.html'
    form = ValidDemoInlineForm


def use_for_demo(obj):
    return bool(obj.use_for_demo)
use_for_demo.empty_value_display = False
use_for_demo.boolean = True


# Path: boardinghouse/contrib/demo/models.py
# 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()
# 
# 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)


# Path: boardinghouse/contrib/demo/admin.py
from django import forms
from django.contrib import admin
from django.utils.timesince import timesince, timeuntil
from .models import DemoSchema, ValidDemoTemplate


    def __init__(self, *args, **kwargs):
        super(ValidDemoInline.form, self).__init__(*args, **kwargs)
        if self.instance.pk:
            self.initial['use_for_demo'] = True

    def save(self, commit=True):
        if self.cleaned_data.get('use_for_demo', False):
            return super(ValidDemoInline.form, self).save(commit)
        elif commit:
            # There's no visible way I can think of to actually get commit=False from the admin,
            # but I'm not game to omit the elif clause, in case there is a case I'm not aware of.
            # Otherwise, it may delete the object when it should not be deleted.
            self.instance.delete()
        return self.instance


# Inject an inline to allow marking as valid for demo.
class ValidDemoInline(admin.StackedInline):
    model = ValidDemoTemplate
    can_delete = False
    template = 'admin/edit_inline/use-for-demo.html'
    form = ValidDemoInlineForm


def use_for_demo(obj):
    return bool(obj.use_for_demo)
use_for_demo.empty_value_display = False
use_for_demo.boolean = True


SchemaTemplate = ValidDemoTemplate._meta.pk.remote_field.model