1 from datetime import date
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 _
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
14 from combo.data.models import CellBase
15 from combo.data.library import register_cell_class
17 from emissions.models import Episode, NewsItem
20 class SoundCell(CellBase):
21 soundfile = models.ForeignKey('emissions.SoundFile', null=True)
24 verbose_name = _('Sound')
26 def render(self, context):
27 tmpl = template.loader.get_template('panikombo/audio.html')
28 context['soundfile'] = self.soundfile
29 return tmpl.render(context)
31 def get_default_form_class(self):
32 from .forms import SoundCellForm
35 def get_included_items(self):
36 if not self.soundfile:
38 return [self.soundfile.episode]
40 def get_additional_label(self):
42 if self.soundfile.fragment:
43 return u'%s - %s - %s' % (
44 self.soundfile.episode.emission.title,
45 self.soundfile.episode.title,
49 self.soundfile.episode.emission.title,
50 self.soundfile.episode.title)
56 class EpisodeCell(CellBase):
57 episode = models.ForeignKey('emissions.Episode', null=True)
60 verbose_name = _('Episode')
62 def render(self, context):
63 tmpl = template.loader.get_template('panikombo/episode.html')
64 context['episode'] = self.episode
66 context['soundfile'] = self.episode.main_sound
67 return tmpl.render(context)
69 def get_included_items(self):
74 def get_default_form_class(self):
75 from .forms import EpisodeCellForm
76 return EpisodeCellForm
78 def get_additional_label(self):
81 self.episode.emission.title,
86 def get_parsed_tags(tagstring):
87 tags = parse_tags(tagstring)
88 return [x for x in Tag.objects.filter(name__in=tags)]
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')),
103 template_name = 'panikombo/episode_auto_selection.html'
107 verbose_name = _('Automatic Episode Selection')
109 def get_included_items(self):
110 episodes_queryset = Episode.objects.select_related()
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())
116 and_tags = get_parsed_tags(self.and_tags)
117 episodes_queryset = episodes_queryset.filter(tags__in=and_tags)
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()
146 return episodes_queryset
148 def get_cell_extra_context(self, context):
149 ctx = super(EpisodeAutoSelectionCell, self).get_cell_extra_context(context)
150 ctx['title'] = self.title
152 if (self.category or self.period or self.tags.count()):
153 ctx['episodes'] = self.get_included_items()
159 def get_default_form_class(self):
160 from .forms import EpisodeAutoSelectionCellForm
161 return EpisodeAutoSelectionCellForm
163 def get_additional_label(self):
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)
177 template_name = 'panikombo/newsitem_auto_selection.html'
180 verbose_name = _('Automatic Newsitem Selection')
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())
187 and_tags = get_parsed_tags(self.and_tags)
188 newsitems_queryset = newsitems_queryset.filter(tags__in=and_tags)
190 newsitems_queryset = newsitems_queryset.filter(event_date__gte=date.today())
192 newsitems_queryset = newsitems_queryset.filter(category=self.category)
193 newsitems_queryset = newsitems_queryset.order_by('-event_date', '-creation_timestamp')
194 return newsitems_queryset
196 def get_cell_extra_context(self, context):
197 ctx = super(NewsItemAutoSelectionCell, self).get_cell_extra_context(context)
198 ctx['title'] = self.title
200 if self.tags.count() or self.future or self.category:
201 ctx['newsitems'] = self.get_included_items()
203 ctx['newsitems'] = []
207 def get_default_form_class(self):
208 from .forms import NewsItemAutoSelectionCellForm
209 return NewsItemAutoSelectionCellForm
211 def get_additional_label(self):
217 def get_topik_image_path(instance, filename):
218 return os.path.join('images', 'topik', instance.page.slug,
219 os.path.basename(filename))
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)
226 # denormalized from Focus
227 got_focus = models.DateTimeField(default=None, null=True, blank=True)
228 has_focus = models.BooleanField(default=False)
230 def __unicode__(self):
232 return super(Topik, self).__unicode__()
233 return unicode(self.page)
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)
246 class TopikCell(CellBase):
247 topik = models.ForeignKey(Topik, null=True)
248 text = RichTextField(_('Text'), blank=True, null=True)
250 template_name = 'panikombo/topik-cell.html'
253 verbose_name = _('Topik')
255 def get_additional_label(self):
258 return self.topik.page.title