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.encoding import force_text, python_2_unicode_compatible
8 from django.utils.translation import ugettext_lazy as _
10 from ckeditor.fields import RichTextField
11 from taggit.models import Tag
12 from taggit.managers import TaggableManager
13 from taggit.utils import parse_tags
15 from combo.data.models import CellBase
16 from combo.data.library import register_cell_class
18 from emissions.models import Episode, NewsItem
21 class SoundCell(CellBase):
22 soundfile = models.ForeignKey('emissions.SoundFile', null=True)
25 verbose_name = _('Sound')
27 def render(self, context):
28 tmpl = template.loader.get_template('panikombo/audio.html')
29 context['soundfile'] = self.soundfile
30 return tmpl.render(context)
32 def get_default_form_class(self):
33 from .forms import SoundCellForm
36 def get_included_items(self):
37 if not self.soundfile:
39 return [self.soundfile.episode]
41 def get_additional_label(self):
43 if self.soundfile.fragment:
44 return u'%s - %s - %s' % (
45 self.soundfile.episode.emission.title,
46 self.soundfile.episode.title,
50 self.soundfile.episode.emission.title,
51 self.soundfile.episode.title)
57 class EpisodeCell(CellBase):
58 episode = models.ForeignKey('emissions.Episode', null=True)
61 verbose_name = _('Episode')
63 def render(self, context):
64 tmpl = template.loader.get_template('panikombo/episode.html')
65 context['episode'] = self.episode
67 context['soundfile'] = self.episode.main_sound
68 return tmpl.render(context)
70 def get_included_items(self):
75 def get_default_form_class(self):
76 from .forms import EpisodeCellForm
77 return EpisodeCellForm
79 def get_additional_label(self):
82 self.episode.emission.title,
87 def get_parsed_tags(tagstring):
88 tags = parse_tags(tagstring)
89 return [x for x in Tag.objects.filter(name__in=tags)]
93 class EpisodeAutoSelectionCell(CellBase):
94 title = models.CharField(_('Title'), max_length=50, blank=True)
95 tags = TaggableManager(_('Tags'), blank=True)
96 and_tags = models.CharField(_('And Tags'), max_length=100, blank=True)
97 category = models.ForeignKey('emissions.Category', null=True, blank=True)
98 period = models.PositiveSmallIntegerField(
99 _('Period'), default=0,
100 choices=((0, _('All')),
104 template_name = 'panikombo/episode_auto_selection.html'
108 verbose_name = _('Automatic Episode Selection')
110 def get_included_items(self):
111 episodes_queryset = Episode.objects.select_related()
113 episodes_queryset = episodes_queryset.filter(emission__categories__in=[self.category.id])
114 if self.tags.count():
115 episodes_queryset = episodes_queryset.filter(tags__in=self.tags.all())
117 and_tags = get_parsed_tags(self.and_tags)
118 episodes_queryset = episodes_queryset.filter(tags__in=and_tags)
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)'''],
126 tables=['emissions_diffusion'])
127 episodes_queryset = episodes_queryset.order_by(Lower('title')).distinct()
128 elif self.period == 1:
129 episodes_queryset = episodes_queryset.extra(
130 select={ 'first_diffusion': 'emissions_diffusion.datetime', },
131 select_params=(False, True),
132 where=['''datetime = (SELECT MIN(datetime) FROM emissions_diffusion
133 WHERE episode_id = emissions_episode.id) AND
134 datetime >= CURRENT_TIMESTAMP'''],
135 tables=['emissions_diffusion'])
136 episodes_queryset = episodes_queryset.order_by('-first_diffusion').distinct()
137 elif self.period == 2:
138 episodes_queryset = episodes_queryset.extra(
139 select={ 'first_diffusion': 'emissions_diffusion.datetime', },
140 select_params=(False, True),
141 where=['''datetime = (SELECT MIN(datetime) FROM emissions_diffusion
142 WHERE episode_id = emissions_episode.id) AND
143 datetime < CURRENT_TIMESTAMP'''],
144 tables=['emissions_diffusion'])
145 episodes_queryset = episodes_queryset.order_by('-first_diffusion').distinct()
147 return episodes_queryset
149 def get_cell_extra_context(self, context):
150 ctx = super(EpisodeAutoSelectionCell, self).get_cell_extra_context(context)
151 ctx['title'] = self.title
153 if (self.category or self.period or self.tags.count()):
154 ctx['episodes'] = self.get_included_items()
160 def get_default_form_class(self):
161 from .forms import EpisodeAutoSelectionCellForm
162 return EpisodeAutoSelectionCellForm
164 def get_additional_label(self):
170 class NewsItemAutoSelectionCell(CellBase):
171 title = models.CharField(_('Title'), max_length=50, blank=True)
172 tags = TaggableManager(_('Tags'), blank=True)
173 and_tags = models.CharField(_('And Tags'), max_length=100, blank=True)
174 future = models.BooleanField(_('Future Events Only'), default=True)
175 category = models.ForeignKey('emissions.NewsCategory',
176 verbose_name=_('Category'), null=True, blank=True)
178 template_name = 'panikombo/newsitem_auto_selection.html'
181 verbose_name = _('Automatic Newsitem Selection')
183 def get_included_items(self):
184 newsitems_queryset = NewsItem.objects.select_related()
185 if self.tags.count():
186 newsitems_queryset = newsitems_queryset.filter(tags__in=self.tags.all())
188 and_tags = get_parsed_tags(self.and_tags)
189 newsitems_queryset = newsitems_queryset.filter(tags__in=and_tags)
191 newsitems_queryset = newsitems_queryset.filter(event_date__gte=date.today())
193 newsitems_queryset = newsitems_queryset.filter(category=self.category)
194 newsitems_queryset = newsitems_queryset.order_by('-event_date', '-creation_timestamp')
195 return newsitems_queryset
197 def get_cell_extra_context(self, context):
198 ctx = super(NewsItemAutoSelectionCell, self).get_cell_extra_context(context)
199 ctx['title'] = self.title
201 if self.tags.count() or self.future or self.category:
202 ctx['newsitems'] = self.get_included_items()
204 ctx['newsitems'] = []
208 def get_default_form_class(self):
209 from .forms import NewsItemAutoSelectionCellForm
210 return NewsItemAutoSelectionCellForm
212 def get_additional_label(self):
218 def get_topik_image_path(instance, filename):
219 return os.path.join('images', 'topik', instance.page.slug,
220 os.path.basename(filename))
222 @python_2_unicode_compatible
223 class Topik(models.Model):
224 page = models.ForeignKey('data.Page')
225 image = models.ImageField(_('Image'),
226 upload_to=get_topik_image_path, max_length=250, null=True, blank=True)
228 # denormalized from Focus
229 got_focus = models.DateTimeField(default=None, null=True, blank=True)
230 has_focus = models.BooleanField(default=False)
234 return super(Topik, self).__str__()
235 return force_text(self.page)
238 class ItemTopik(models.Model):
239 newsitem = models.ForeignKey('emissions.NewsItem', verbose_name=_('News Item'),
240 null=True, blank=True)
241 episode = models.ForeignKey('emissions.Episode', verbose_name=_('Episode'),
242 null=True, blank=True)
243 topik = models.ForeignKey('Topik', verbose_name='Topik',
244 null=True, blank=True)
248 class TopikCell(CellBase):
249 topik = models.ForeignKey(Topik, null=True)
250 text = RichTextField(_('Text'), blank=True, null=True)
252 template_name = 'panikombo/topik-cell.html'
255 verbose_name = _('Topik')
257 def get_additional_label(self):
260 return self.topik.page.title