X-Git-Url: https://git.0d.be/?p=django-panik-combo.git;a=blobdiff_plain;f=panikombo%2Fmodels.py;h=2907b86cb22fdf868a7efde55422654cbcd39e10;hp=0f74a5b3a2132f9959b6cdc4e9963f80d5ccb388;hb=5dda5b2c6ebe426361c3f8f4e92e2f070e5a6fe1;hpb=e960f6c41cc47f908e5e685e9f8be029cce3d8c3 diff --git a/panikombo/models.py b/panikombo/models.py index 0f74a5b..2907b86 100644 --- a/panikombo/models.py +++ b/panikombo/models.py @@ -1,10 +1,22 @@ +from datetime import date +import os + from django import template from django.db import models +from django.db.models.functions import Lower +from django.utils.encoding import force_text, python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ +from ckeditor.fields import RichTextField +from taggit.models import Tag +from taggit.managers import TaggableManager +from taggit.utils import parse_tags + from combo.data.models import CellBase from combo.data.library import register_cell_class +from emissions.models import Episode, NewsItem + @register_cell_class class SoundCell(CellBase): soundfile = models.ForeignKey('emissions.SoundFile', null=True) @@ -21,6 +33,11 @@ class SoundCell(CellBase): from .forms import SoundCellForm return SoundCellForm + def get_included_items(self): + if not self.soundfile: + return [] + return [self.soundfile.episode] + def get_additional_label(self): if self.soundfile: if self.soundfile.fragment: @@ -46,9 +63,15 @@ class EpisodeCell(CellBase): def render(self, context): tmpl = template.loader.get_template('panikombo/episode.html') context['episode'] = self.episode - context['soundfile'] = self.episode.main_sound + if self.episode: + context['soundfile'] = self.episode.main_sound return tmpl.render(context) + def get_included_items(self): + if not self.episode: + return [] + return [self.episode] + def get_default_form_class(self): from .forms import EpisodeCellForm return EpisodeCellForm @@ -59,3 +82,178 @@ class EpisodeCell(CellBase): self.episode.emission.title, self.episode.title) return '' + + +def get_parsed_tags(tagstring): + tags = parse_tags(tagstring) + return [x for x in Tag.objects.filter(name__in=tags)] + + +@register_cell_class +class EpisodeAutoSelectionCell(CellBase): + title = models.CharField(_('Title'), max_length=50, blank=True) + tags = TaggableManager(_('Tags'), blank=True) + and_tags = models.CharField(_('And Tags'), max_length=100, blank=True) + category = models.ForeignKey('emissions.Category', null=True, blank=True) + period = models.PositiveSmallIntegerField( + _('Period'), default=0, + choices=((0, _('All')), + (1, _('Future')), + (2, _('Past')))) + + template_name = 'panikombo/episode_auto_selection.html' + + + class Meta: + verbose_name = _('Automatic Episode Selection') + + def get_included_items(self): + episodes_queryset = Episode.objects.select_related() + if self.category: + episodes_queryset = episodes_queryset.filter(emission__categories__in=[self.category.id]) + if self.tags.count(): + episodes_queryset = episodes_queryset.filter(tags__in=self.tags.all()) + if self.and_tags: + and_tags = get_parsed_tags(self.and_tags) + episodes_queryset = episodes_queryset.filter(tags__in=and_tags) + + if self.period == 0: + episodes_queryset = episodes_queryset.extra( + select={ 'first_diffusion': 'emissions_diffusion.datetime', }, + select_params=(False, True), + where=['''datetime = (SELECT MIN(datetime) FROM emissions_diffusion + WHERE episode_id = emissions_episode.id)'''], + tables=['emissions_diffusion']) + episodes_queryset = episodes_queryset.order_by('first_diffusion').distinct() + elif self.period == 1: + episodes_queryset = episodes_queryset.extra( + select={ 'first_diffusion': 'emissions_diffusion.datetime', }, + select_params=(False, True), + where=['''datetime = (SELECT MIN(datetime) FROM emissions_diffusion + WHERE episode_id = emissions_episode.id) AND + datetime >= CURRENT_TIMESTAMP'''], + tables=['emissions_diffusion']) + episodes_queryset = episodes_queryset.order_by('-first_diffusion').distinct() + elif self.period == 2: + episodes_queryset = episodes_queryset.extra( + select={ 'first_diffusion': 'emissions_diffusion.datetime', }, + select_params=(False, True), + where=['''datetime = (SELECT MIN(datetime) FROM emissions_diffusion + WHERE episode_id = emissions_episode.id) AND + datetime < CURRENT_TIMESTAMP'''], + tables=['emissions_diffusion']) + episodes_queryset = episodes_queryset.order_by('-first_diffusion').distinct() + + return episodes_queryset + + def get_cell_extra_context(self, context): + ctx = super(EpisodeAutoSelectionCell, self).get_cell_extra_context(context) + ctx['title'] = self.title + + if (self.category or self.period or self.tags.count()): + ctx['episodes'] = self.get_included_items() + else: + ctx['episodes'] = [] + + return ctx + + def get_default_form_class(self): + from .forms import EpisodeAutoSelectionCellForm + return EpisodeAutoSelectionCellForm + + def get_additional_label(self): + if self.title: + return self.title + return '' + +@register_cell_class +class NewsItemAutoSelectionCell(CellBase): + title = models.CharField(_('Title'), max_length=50, blank=True) + tags = TaggableManager(_('Tags'), blank=True) + and_tags = models.CharField(_('And Tags'), max_length=100, blank=True) + future = models.BooleanField(_('Future Events Only'), default=True) + category = models.ForeignKey('emissions.NewsCategory', + verbose_name=_('Category'), null=True, blank=True) + + template_name = 'panikombo/newsitem_auto_selection.html' + + class Meta: + verbose_name = _('Automatic Newsitem Selection') + + def get_included_items(self): + newsitems_queryset = NewsItem.objects.select_related() + if self.tags.count(): + newsitems_queryset = newsitems_queryset.filter(tags__in=self.tags.all()) + if self.and_tags: + and_tags = get_parsed_tags(self.and_tags) + newsitems_queryset = newsitems_queryset.filter(tags__in=and_tags) + if self.future: + newsitems_queryset = newsitems_queryset.filter(event_date__gte=date.today()) + if self.category: + newsitems_queryset = newsitems_queryset.filter(category=self.category) + newsitems_queryset = newsitems_queryset.order_by('-event_date', '-creation_timestamp') + return newsitems_queryset + + def get_cell_extra_context(self, context): + ctx = super(NewsItemAutoSelectionCell, self).get_cell_extra_context(context) + ctx['title'] = self.title + + if self.tags.count() or self.future or self.category: + ctx['newsitems'] = self.get_included_items() + else: + ctx['newsitems'] = [] + + return ctx + + def get_default_form_class(self): + from .forms import NewsItemAutoSelectionCellForm + return NewsItemAutoSelectionCellForm + + def get_additional_label(self): + if self.title: + return self.title + return '' + + +def get_topik_image_path(instance, filename): + return os.path.join('images', 'topik', instance.page.slug, + os.path.basename(filename)) + +@python_2_unicode_compatible +class Topik(models.Model): + page = models.ForeignKey('data.Page') + image = models.ImageField(_('Image'), + upload_to=get_topik_image_path, max_length=250, null=True, blank=True) + + # denormalized from Focus + got_focus = models.DateTimeField(default=None, null=True, blank=True) + has_focus = models.BooleanField(default=False) + + def __str__(self): + if not self.page: + return super(Topik, self).__str__() + return force_text(self.page) + + +class ItemTopik(models.Model): + newsitem = models.ForeignKey('emissions.NewsItem', verbose_name=_('News Item'), + null=True, blank=True) + episode = models.ForeignKey('emissions.Episode', verbose_name=_('Episode'), + null=True, blank=True) + page = models.ForeignKey('data.Page', null=True, blank=True) + + +@register_cell_class +class TopikCell(CellBase): + topik = models.ForeignKey(Topik, null=True) + text = RichTextField(_('Text'), blank=True, null=True) + + template_name = 'panikombo/topik-cell.html' + + class Meta: + verbose_name = _('Topik') + + def get_additional_label(self): + if not self.topik: + return '' + return self.topik.page.title