c5d6bf0a3ee2a90250a594b4a48fe6efb26f4069
[redakcja.git] / apps / catalogue / models / image.py
1 # -*- coding: utf-8 -*-
2 #
3 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
5 #
6 from django.conf import settings
7 from django.db import models
8 from django.template.loader import render_to_string
9 from django.utils.translation import ugettext_lazy as _
10 from catalogue.helpers import cached_in_field
11 from catalogue.tasks import refresh_instance
12 from dvcs import models as dvcs_models
13
14
15 class Image(dvcs_models.Document):
16     """ An editable chunk of text. Every Book text is divided into chunks. """
17     REPO_PATH = settings.CATALOGUE_IMAGE_REPO_PATH
18
19     image = models.FileField(_('image'), upload_to='catalogue/images')
20     title = models.CharField(_('title'), max_length=255, blank=True)
21     slug = models.SlugField(_('slug'), unique=True)
22     public = models.BooleanField(_('public'), default=True, db_index=True)
23
24     # cache
25     _short_html = models.TextField(null=True, blank=True, editable=False)
26     _new_publishable = models.NullBooleanField(editable=False)
27     _published = models.NullBooleanField(editable=False)
28     _changed = models.NullBooleanField(editable=False)
29
30     class Meta:
31         app_label = 'catalogue'
32         ordering = ['title']
33         verbose_name = _('image')
34         verbose_name_plural = _('images')
35         permissions = [('can_pubmark_image', 'Can mark images for publishing')]
36
37     # Representing
38     # ============
39
40     def __unicode__(self):
41         return self.title
42
43     @models.permalink
44     def get_absolute_url(self):
45         return ("catalogue_image", [self.slug])
46
47     # State & cache
48     # =============
49
50     def accessible(self, request):
51         return self.public or request.user.is_authenticated()
52
53     def is_new_publishable(self):
54         change = self.publishable()
55         if not change:
56             return False
57         return change.publish_log.exists()
58     new_publishable = cached_in_field('_new_publishable')(is_new_publishable)
59
60     def is_published(self):
61         return self.publish_log.exists()
62     published = cached_in_field('_published')(is_published)
63
64     def is_changed(self):
65         if self.head is None:
66             return False
67         return not self.head.publishable
68     changed = cached_in_field('_changed')(is_changed)
69
70     @cached_in_field('_short_html')
71     def short_html(self):
72         return render_to_string(
73                     'catalogue/image_short.html', {'image': self})
74
75     def refresh(self):
76         """This should be done offline."""
77         self.short_html
78         self.single
79         self.new_publishable
80         self.published
81
82     def touch(self):
83         update = {
84             "_changed": self.is_changed(),
85             "_short_html": None,
86             "_new_publishable": self.is_new_publishable(),
87             "_published": self.is_published(),
88         }
89         Image.objects.filter(pk=self.pk).update(**update)
90         refresh_instance(self)
91
92     def refresh(self):
93         """This should be done offline."""
94         self.changed
95         self.short_html