]> git.0d.be Git - django-panik-combo.git/blob - panikombo/models.py
update auto cells to generic render() method
[django-panik-combo.git] / panikombo / models.py
1 from datetime import date
2 import os
3
4 from django import template
5 from django.db import models
6 from django.utils.translation import ugettext_lazy as _
7
8 from ckeditor.fields import RichTextField
9 from taggit.models import Tag
10 from taggit.managers import TaggableManager
11 from taggit.utils import parse_tags
12
13 from combo.data.models import CellBase
14 from combo.data.library import register_cell_class
15
16 from emissions.models import Episode, NewsItem
17
18 @register_cell_class
19 class SoundCell(CellBase):
20     soundfile = models.ForeignKey('emissions.SoundFile', null=True)
21
22     class Meta:
23         verbose_name = _('Sound')
24
25     def render(self, context):
26         tmpl = template.loader.get_template('panikombo/audio.html')
27         context['soundfile'] = self.soundfile
28         return tmpl.render(context)
29
30     def get_default_form_class(self):
31         from .forms import SoundCellForm
32         return SoundCellForm
33
34     def get_included_items(self):
35         if not self.soundfile:
36             return []
37         return [self.soundfile.episode]
38
39     def get_additional_label(self):
40         if self.soundfile:
41             if self.soundfile.fragment:
42                 return u'%s - %s - %s' % (
43                         self.soundfile.episode.emission.title,
44                         self.soundfile.episode.title,
45                         self.soundfile.title)
46             else:
47                 return u'%s - %s' % (
48                         self.soundfile.episode.emission.title,
49                         self.soundfile.episode.title)
50
51         return ''
52
53
54 @register_cell_class
55 class EpisodeCell(CellBase):
56     episode = models.ForeignKey('emissions.Episode', null=True)
57
58     class Meta:
59         verbose_name = _('Episode')
60
61     def render(self, context):
62         tmpl = template.loader.get_template('panikombo/episode.html')
63         context['episode'] = self.episode
64         if self.episode:
65             context['soundfile'] = self.episode.main_sound
66         return tmpl.render(context)
67
68     def get_included_items(self):
69         if not self.episode:
70             return []
71         return [self.episode]
72
73     def get_default_form_class(self):
74         from .forms import EpisodeCellForm
75         return EpisodeCellForm
76
77     def get_additional_label(self):
78         if self.episode:
79             return u'%s - %s' % (
80                         self.episode.emission.title,
81                         self.episode.title)
82         return ''
83
84
85 def get_parsed_tags(tagstring):
86     tags = parse_tags(tagstring)
87     return [x for x in Tag.objects.filter(name__in=tags)]
88
89
90 @register_cell_class
91 class EpisodeAutoSelectionCell(CellBase):
92     title = models.CharField(_('Title'), max_length=50, blank=True)
93     tags = TaggableManager(_('Tags'), blank=True)
94     and_tags = models.CharField(_('And Tags'), max_length=100, blank=True)
95     category = models.ForeignKey('emissions.Category', null=True, blank=True)
96     period = models.PositiveSmallIntegerField(
97             _('Period'), default=0,
98             choices=((0, _('All')),
99                      (1, _('Future')),
100                      (2, _('Past'))))
101
102     template_name = 'panikombo/episode_auto_selection.html'
103
104
105     class Meta:
106         verbose_name = _('Automatic Episode Selection')
107
108     def get_included_items(self):
109         episodes_queryset = Episode.objects.select_related()
110         if self.category:
111             episodes_queryset = episodes_queryset.filter(emission__categories__in=[self.category.id])
112         if self.tags.count():
113             episodes_queryset = episodes_queryset.filter(tags__in=self.tags.all())
114             if self.and_tags:
115                 and_tags = get_parsed_tags(self.and_tags)
116                 episodes_queryset = episodes_queryset.filter(tags__in=and_tags)
117
118         if self.period == 0:
119             episodes_queryset = episodes_queryset.extra(
120                     select={ 'first_diffusion': 'emissions_diffusion.datetime', },
121                     select_params=(False, True),
122                     where=['''datetime = (SELECT MIN(datetime) FROM emissions_diffusion
123                                            WHERE episode_id = emissions_episode.id)'''],
124                     tables=['emissions_diffusion'])
125         elif self.period == 1:
126             episodes_queryset = episodes_queryset.extra(
127                     select={ 'first_diffusion': 'emissions_diffusion.datetime', },
128                     select_params=(False, True),
129                     where=['''datetime = (SELECT MIN(datetime) FROM emissions_diffusion
130                                            WHERE episode_id = emissions_episode.id) AND
131                                                  datetime >= CURRENT_TIMESTAMP'''],
132                     tables=['emissions_diffusion'])
133         elif self.period == 2:
134             episodes_queryset = episodes_queryset.extra(
135                     select={ 'first_diffusion': 'emissions_diffusion.datetime', },
136                     select_params=(False, True),
137                     where=['''datetime = (SELECT MIN(datetime) FROM emissions_diffusion
138                                            WHERE episode_id = emissions_episode.id) AND
139                                                  datetime < CURRENT_TIMESTAMP'''],
140                     tables=['emissions_diffusion'])
141
142         return episodes_queryset
143
144     def get_cell_extra_context(self, context):
145         ctx = super(EpisodeAutoSelectionCell, self).get_cell_extra_context(context)
146         ctx['title'] = self.title
147
148         if (self.category or self.period or self.tags.count()):
149             episodes_queryset = self.get_included_items()
150             episodes_queryset = episodes_queryset.order_by('-first_diffusion').distinct()
151             ctx['episodes'] = episodes_queryset
152         else:
153             ctx['episodes'] = []
154
155         return ctx
156
157     def get_default_form_class(self):
158         from .forms import EpisodeAutoSelectionCellForm
159         return EpisodeAutoSelectionCellForm
160
161     def get_additional_label(self):
162         if self.title:
163             return self.title
164         return ''
165
166 @register_cell_class
167 class NewsItemAutoSelectionCell(CellBase):
168     title = models.CharField(_('Title'), max_length=50, blank=True)
169     tags = TaggableManager(_('Tags'), blank=True)
170     and_tags = models.CharField(_('And Tags'), max_length=100, blank=True)
171     future = models.BooleanField(_('Future Events Only'), default=True)
172     category = models.ForeignKey('emissions.NewsCategory',
173             verbose_name=_('Category'), null=True, blank=True)
174
175     template_name = 'panikombo/newsitem_auto_selection.html'
176
177     class Meta:
178         verbose_name = _('Automatic Newsitem Selection')
179
180     def get_included_items(self):
181         newsitems_queryset = NewsItem.objects.select_related()
182         if self.tags.count():
183             newsitems_queryset = newsitems_queryset.filter(tags__in=self.tags.all())
184             if self.and_tags:
185                 and_tags = get_parsed_tags(self.and_tags)
186                 newsitems_queryset = newsitems_queryset.filter(tags__in=and_tags)
187         if self.future:
188             newsitems_queryset = newsitems_queryset.filter(event_date__gte=date.today())
189         if self.category:
190             newsitems_queryset = newsitems_queryset.filter(category=self.category)
191         newsitems_queryset = newsitems_queryset.order_by('-event_date', '-creation_timestamp')
192         return newsitems_queryset
193
194     def get_cell_extra_context(self, context):
195         ctx = super(NewsItemAutoSelectionCell, self).get_cell_extra_context(context)
196         ctx['title'] = self.title
197
198         if self.tags.count() or self.future or self.category:
199             ctx['newsitems'] = self.get_included_items()
200         else:
201             ctx['newsitems'] = []
202
203         return ctx
204
205     def get_default_form_class(self):
206         from .forms import NewsItemAutoSelectionCellForm
207         return NewsItemAutoSelectionCellForm
208
209     def get_additional_label(self):
210         if self.title:
211             return self.title
212         return ''
213
214
215 def get_topik_image_path(instance, filename):
216     return os.path.join('images', 'topik', instance.page.slug,
217             os.path.basename(filename))
218
219 class Topik(models.Model):
220     page = models.ForeignKey('data.Page')
221     image = models.ImageField(_('Image'),
222             upload_to=get_topik_image_path, max_length=250, null=True, blank=True)
223
224     # denormalized from Focus
225     got_focus = models.DateTimeField(default=None, null=True, blank=True)
226     has_focus = models.BooleanField(default=False)
227
228     def __unicode__(self):
229         if not self.page:
230             return super(Topik, self).__unicode__()
231         return unicode(self.page)
232
233
234 class ItemTopik(models.Model):
235     newsitem = models.ForeignKey('emissions.NewsItem', verbose_name=_('News Item'),
236             null=True, blank=True)
237     episode = models.ForeignKey('emissions.Episode', verbose_name=_('Episode'),
238             null=True, blank=True)
239     topik = models.ForeignKey('Topik', verbose_name='Topik',
240             null=True, blank=True)
241
242
243 @register_cell_class
244 class TopikCell(CellBase):
245     topik = models.ForeignKey(Topik, null=True)
246     text = RichTextField(_('Text'), blank=True, null=True)
247
248     template_name = 'panikombo/topik-cell.html'
249
250     class Meta:
251         verbose_name = _('Topik')
252
253     def get_additional_label(self):
254         if not self.topik:
255             return ''
256         return self.topik.page.title