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