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