diff --git a/cms/admin.py b/cms/admin.py index 1a6a9fe..1b1ce7f 100644 --- a/cms/admin.py +++ b/cms/admin.py @@ -1,3 +1,5 @@ +import copy + from django.contrib import admin from django.utils.translation import ugettext as _, ugettext_lazy @@ -67,6 +69,7 @@ def inject_related_inline(post_model, prepend = False, inline = None): verbose_name = _('Related post') inline = inline or InlineModel + inline.fieldsets = copy.deepcopy(inline.fieldsets) # remove bound attributes for none, dic in inline.fieldsets: @@ -78,6 +81,12 @@ def inject_related_inline(post_model, prepend = False, inline = None): inject_inline(post_model._meta.get_field('related').rel.to, inline, prepend) +def inject(model, name, value): + registry = admin.site._registry + if not model in registry: + return TypeError('{} not in admin registry'.format(model.__name__)) + setattr(registry[model], name, value) + def inject_inline(model, inline, prepend = False): registry = admin.site._registry if not model in registry: diff --git a/cms/models.py b/cms/models.py index 915bdc0..6db4fc4 100644 --- a/cms/models.py +++ b/cms/models.py @@ -7,7 +7,7 @@ from django.utils.text import slugify from django.utils.translation import ugettext as _, ugettext_lazy from django.core.urlresolvers import reverse -from django.db.models.signals import Signal, post_save +from django.db.models.signals import Signal, post_save, pre_save from django.dispatch import receiver import bleach @@ -265,11 +265,24 @@ class RelatedMeta (models.base.ModelBase): @classmethod def make_auto_create(cl, model): + """ + Enable auto_create on the given RelatedPost model if it is available. + """ if not model._relation.rel_to_post: return - def handler(sender, instance, created, *args, **kwargs): + def handler_rel(sender, instance, created, *args, **kwargs): + """ + handler for the related object + """ rel = model._relation + # TODO: make the check happen by overriding inline save function + # this check is done in order to allow creation of multiple + # models when using admin.inlines: related is saved before + # the post, so no post is found, then create an extra post + if hasattr(instance, '__cms_post'): + return + post = model.objects.filter(related = instance) if post.count(): post = post[0] @@ -280,7 +293,7 @@ class RelatedMeta (models.base.ModelBase): return post.rel_to_post() post.save(avoid_sync = True) - post_save.connect(handler, model._relation.model, False) + post_save.connect(handler_rel, model._relation.model, False) def __new__ (cl, name, bases, attrs): # TODO: allow proxy models and better inheritance diff --git a/cms/routes.py b/cms/routes.py index 3aa53c3..c31f395 100644 --- a/cms/routes.py +++ b/cms/routes.py @@ -135,6 +135,9 @@ class ThreadRoute(Route): class DateRoute(Route): + """ + Select posts using a date with format yyyy/mm/dd; + """ name = 'date' url_args = [ ('year', '[0-9]{4}'), @@ -160,6 +163,11 @@ class DateRoute(Route): class SearchRoute(Route): + """ + Search post using request.GET['q']. It searches in fields designated by + model.search_fields + """ + # TODO: q argument in url_args -> need to allow optional url_args name = 'search' @classmethod @@ -183,3 +191,27 @@ class SearchRoute(Route): } +class TagsRoute(Route): + """ + Select posts that contains the given tags. The tags are separated + by a '+'. + """ + name = 'tags' + url_args = [ + ('tags', '(\w|-|_|\+)+') + ] + + @classmethod + def get_queryset(cl, model, request, tags, **kwargs): + tags = tags.split('+') + return model.objects.filter(tags__name__in=tags) + + @classmethod + def get_title(cl, model, request, tags, **kwargs): + return _('Tagged %(model)s with %(tags)s') % { + 'model': model._meta.verbose_name_plural, + 'tags': tags.replace('+', ', ') + } + + + diff --git a/cms/templates/aircox/cms/detail.html b/cms/templates/aircox/cms/detail.html index 475b01d..11ddd5d 100644 --- a/cms/templates/aircox/cms/detail.html +++ b/cms/templates/aircox/cms/detail.html @@ -16,9 +16,8 @@ {% if object.tags.all %} - {# TODO: url to the tags #}
- {{ object.tags.all|join:', ' }} + {{ object|post_tags:' - '|safe }}
{% endif %} diff --git a/cms/templatetags/aircox_cms.py b/cms/templatetags/aircox_cms.py index 9e250e6..d5975a6 100644 --- a/cms/templatetags/aircox_cms.py +++ b/cms/templatetags/aircox_cms.py @@ -1,13 +1,33 @@ from django import template from django.core.urlresolvers import reverse +import aircox.cms.routes as routes + + register = template.Library() +@register.filter(name='post_tags') +def post_tags(post, sep = '-'): + """ + print the list of all the tags of the given post, with url if available + """ + tags = post.tags.all() + r = [] + for tag in tags: + try: + r.append('{name}'.format( + url = post.route_url(routes.TagsRoute, tags = tag), + name = tag, + )) + except: + r.push(tag) + return sep.join(r) + @register.filter(name='threads') def threads(post, sep = '/'): """ - print a list of all parents, from top to bottom + print the list of all the parents of the given post, from top to bottom """ posts = [post] while posts[0].thread: diff --git a/cms/views.py b/cms/views.py index 99df7fc..67ee5ac 100644 --- a/cms/views.py +++ b/cms/views.py @@ -60,7 +60,7 @@ class BaseView: Return a context with all attributes of this classe plus 'view' set to self. """ - context = super().get_context_data(**kwargs) + context = {} # update from sections if self.sections: @@ -76,6 +76,8 @@ class BaseView: 'content': self.sections.render(self.request, **kwargs) }) + context.update(super().get_context_data(**kwargs)) + # then from me context.update({ 'website': self.website, diff --git a/notes.md b/notes.md index ff279c2..5f8c47f 100644 --- a/notes.md +++ b/notes.md @@ -3,13 +3,15 @@ - debug/prod configuration # TODO: +- general: + - timezone shit + - programs: - schedule: - (old) schedule.to_string unused? commented - check one week on two - write more tests - sounds: - - print sounds of diffusions - inline admin - one sound, one diffusion? @@ -36,6 +38,7 @@ - website: - diffusions: - filter sounds for undiffused diffusions + - print sounds of diffusions - player: - "listen" + "favorite" buttons made easy + automated - single mode / play next auto diff --git a/programs/admin.py b/programs/admin.py index 30705db..9837fe0 100755 --- a/programs/admin.py +++ b/programs/admin.py @@ -69,7 +69,7 @@ class ProgramAdmin(NameableAdmin): schedule.short_description = _("Schedule") list_display = ('id', 'name', 'active', 'schedule') - fields = NameableAdmin.fields + [ 'station', 'active' ] + fields = NameableAdmin.fields + [ 'active' ] # TODO list_display inlines = [ ScheduleInline, StreamInline ] diff --git a/website/admin.py b/website/admin.py index a8440a7..34cbc9c 100644 --- a/website/admin.py +++ b/website/admin.py @@ -12,14 +12,14 @@ class TrackInline(SortableTabularInline): form = forms.TrackForm model = programs.Track sortable = 'position' - extra = 10 + extra = 4 admin.site.register(models.Article, cms.PostAdmin) admin.site.register(models.Program, cms.RelatedPostAdmin) admin.site.register(models.Diffusion, cms.RelatedPostAdmin) -cms.inject_related_inline(models.Program, True) cms.inject_inline(programs.Diffusion, TrackInline, True) +cms.inject_related_inline(models.Program, True) cms.inject_related_inline(models.Diffusion, True) cms.inject_related_inline(models.Sound, True) diff --git a/website/sections.py b/website/sections.py index a1d47e0..f60db99 100644 --- a/website/sections.py +++ b/website/sections.py @@ -77,13 +77,14 @@ class Diffusions(sections.List): type = programs.Diffusion.Type.normal ) if self.object: - object = self.object.related - if type(object) == programs.Program: - qs = qs.filter(program = object) - elif type(object) == programs.Diffusion: - if object.initial: - object = object.initial - qs = qs.filter(initial = object) | qs.filter(pk = object.pk) + obj = self.object.related + obj_type = type(obj) + if obj_type == programs.Program: + qs = qs.filter(program = obj) + elif obj_type == programs.Diffusion: + if obj.initial: + obj = obj.initial + qs = qs.filter(initial = obj) | qs.filter(pk = obj.pk) if filter_args: qs = qs.filter(**filter_args).order_by('start') @@ -212,13 +213,17 @@ class Schedule(Diffusions): def get_object_list(self): date = self.date_or_default() - qs = routes.DateRoute.get_queryset( - models.Diffusion, self.request, - year = date.year, - month = date.month, - day = date.day - ).order_by('date') - return qs + year, month, day = date.year, date.month, date.day + + diffs = [d.initial if d.initial else d + for d in programs.Diffusion.objects.filter( + start__year = year, + start__month = month, + start__day = day, + ) + ] + return models.Diffusion.objects.filter(related__in = diffs). \ + order_by('date') def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs)