allow only one program or diffusion for pages;

in cms.signals, manage cases when Diffusion.initial is set/changed &
clean up;

fix bug in loglist nav when max_age is 0 (no limit);

work on design for date lists;

fix bug in player on item removal;
This commit is contained in:
bkfox 2017-06-19 00:21:22 +02:00
parent 5fbac07829
commit f6e0d8d956
9 changed files with 123 additions and 44 deletions

View File

@ -922,7 +922,7 @@ class Diffusion(models.Model):
return super().save(*args, **kwargs) return super().save(*args, **kwargs)
if self.initial: if self.initial:
# force link to the top initial diffusion # force link to the first diffusion
if self.initial.initial: if self.initial.initial:
self.initial = self.initial.initial self.initial = self.initial.initial
self.program = self.initial.program self.program = self.initial.program

View File

@ -420,7 +420,7 @@ class Publication(BasePage):
class ProgramPage(Publication): class ProgramPage(Publication):
program = models.ForeignKey( program = models.OneToOneField(
aircox.models.Program, aircox.models.Program,
verbose_name = _('program'), verbose_name = _('program'),
related_name = 'page', related_name = 'page',
@ -515,11 +515,11 @@ class Track(aircox.models.Track,Orderable):
class DiffusionPage(Publication): class DiffusionPage(Publication):
order_field = 'diffusion__start' order_field = 'diffusion__start'
diffusion = models.ForeignKey( diffusion = models.OneToOneField(
aircox.models.Diffusion, aircox.models.Diffusion,
verbose_name = _('diffusion'), verbose_name = _('diffusion'),
related_name = 'page', related_name = 'page',
null=True, null=True, blank = True,
# not blank because we enforce the connection to a diffusion # not blank because we enforce the connection to a diffusion
# (still users always tend to break sth) # (still users always tend to break sth)
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
@ -548,6 +548,9 @@ class DiffusionPage(Publication):
], heading=_('Content')), ], heading=_('Content')),
InlinePanel('links', label=_('Links')) InlinePanel('links', label=_('Links'))
] + Page.promote_panels ] + Page.promote_panels
settings_panels = Publication.settings_panels + [
FieldPanel('diffusion')
]
@classmethod @classmethod
def from_diffusion(cl, diff, model = None, **kwargs): def from_diffusion(cl, diff, model = None, **kwargs):
@ -572,8 +575,8 @@ class DiffusionPage(Publication):
""" """
initial = diff.initial or diff initial = diff.initial or diff
if initial.page.all().count(): if hasattr(initial, 'page'):
item = initial.page.all().first() item = initial.page
else: else:
item = cl.from_diffusion(diff, ListItem) item = cl.from_diffusion(diff, ListItem)
item.live = True item.live = True
@ -590,6 +593,13 @@ class DiffusionPage(Publication):
item.date = diff.start item.date = diff.start
item.css_class = 'diffusion' item.css_class = 'diffusion'
now = tz.now()
if diff.start <= now <= diff.end:
print('now!', diff)
item.css_class = ' now'
item.now = True
return item return item
def get_archive(self): def get_archive(self):
@ -721,7 +731,7 @@ class LogsPage(DatedListPage):
on_delete = models.SET_NULL, on_delete = models.SET_NULL,
help_text = _('(required) related station') help_text = _('(required) related station')
) )
age_max = models.IntegerField( max_age = models.IntegerField(
_('maximum age'), _('maximum age'),
default=15, default=15,
help_text = _('maximum days in the past allowed to be shown. ' help_text = _('maximum days in the past allowed to be shown. '
@ -740,7 +750,7 @@ class LogsPage(DatedListPage):
content_panels = DatedListPage.content_panels + [ content_panels = DatedListPage.content_panels + [
MultiFieldPanel([ MultiFieldPanel([
FieldPanel('station'), FieldPanel('station'),
FieldPanel('age_max'), FieldPanel('max_age'),
FieldPanel('reverse'), FieldPanel('reverse'),
], heading=_('Configuration')), ], heading=_('Configuration')),
] ]
@ -749,20 +759,21 @@ class LogsPage(DatedListPage):
""" """
Return a list of dates availables for the navigation Return a list of dates availables for the navigation
""" """
# there might be a bug if age_max < nav_days # there might be a bug if max_age < nav_days
today = tz.now().date() today = tz.now().date()
first = min(date, today) first = min(date, today)
first = max( first - tz.timedelta(days = self.nav_days-1), first = first - tz.timedelta(days = self.nav_days-1)
today - tz.timedelta(days = self.age_max)) if self.max_age:
first = max(first, today - tz.timedelta(days = self.max_age))
return [ first + tz.timedelta(days=i) return [ first + tz.timedelta(days=i)
for i in range(0, self.nav_days) ] for i in range(0, self.nav_days) ]
def get_queryset(self, request, context): def get_queryset(self, request, context):
today = tz.now().date() today = tz.now().date()
if context['nav_dates']['next'] > today: if self.max_age and context['nav_dates']['next'] > today:
context['nav_dates']['next'] = None context['nav_dates']['next'] = None
if context['nav_dates']['prev'] < \ if self.max_age and context['nav_dates']['prev'] < \
today - tz.timedelta(days = self.age_max): today - tz.timedelta(days = self.max_age):
context['nav_dates']['prev'] = None context['nav_dates']['prev'] = None
logs = [] logs = []

View File

@ -1,3 +1,4 @@
from django.db.models import Q
from django.db.models.signals import post_save, pre_delete from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.translation import ugettext as _, ugettext_lazy from django.utils.translation import ugettext as _, ugettext_lazy
@ -142,17 +143,49 @@ def program_post_saved(sender, instance, created, *args, **kwargs):
parent.add_child(instance = page) parent.add_child(instance = page)
def void_pages_of(page_set):
"""
Return a queryset from page_set that select only empty pages. If
`inverse` is True, select only pages that are not empty.
Empty is defined on theses parameters:
- `numchild = 0` => no children
- no headline
- no body
"""
if not page_set.count():
return
page_set = page_set.filter(numchild = 0)
# as publications
page_set = models.Publication.objects.filter(
page_ptr_id__in = page_set.values('pk')
)
# only empty
q = (Q(headline__isnull = True) | Q(headline = '')) & \
(Q(body__isnull = True) | Q(body = ''))
return page_set.filter(q)
@receiver(pre_delete, sender=aircox.Program) @receiver(pre_delete, sender=aircox.Program)
def program_post_deleted(sender, instance, *args, **kwargs): def program_post_deleted(sender, instance, *args, **kwargs):
for page in instance.page.all(): void_pages_of(instance.page).delete()
if page.specific.body or Page.objects.descendant_of(page).count():
continue
page.delete()
@receiver(post_save, sender=aircox.Diffusion) @receiver(post_save, sender=aircox.Diffusion)
def diffusion_post_saved(sender, instance, created, *args, **kwargs): def diffusion_post_saved(sender, instance, created, *args, **kwargs):
if not created or instance.page.count(): initial = instance.initial
if initial:
if not created and hasattr(instance, 'page'):
# fuck it
page = instance.page
page.diffusion = None
page.save()
return
if instance.page:
return return
page = models.DiffusionPage.from_diffusion( page = models.DiffusionPage.from_diffusion(
@ -164,9 +197,5 @@ def diffusion_post_saved(sender, instance, created, *args, **kwargs):
@receiver(pre_delete, sender=aircox.Diffusion) @receiver(pre_delete, sender=aircox.Diffusion)
def diffusion_pre_deleted(sender, instance, *args, **kwargs): def diffusion_pre_deleted(sender, instance, *args, **kwargs):
for page in instance.page.all(): void_pages_of(instance.page).delete()
if page.specific.body or Page.objects.descendant_of(page).count():
continue
page.delete()

View File

@ -187,25 +187,13 @@ ul.list, .list > ul {
/** content: list items in full page **/ /** content: list items in full page **/
.content > .list .list_item { .content > .list:not(.date_list) .list_item {
min-width: 20em; min-width: 20em;
display: inline-block; display: inline-block;
min-height: 2.5em; min-height: 2.5em;
margin: 0.4em; margin: 0.4em;
} }
.content > .list .date_list_item time {
color: #007EDF;
display: block;
margin-left: -0.5em;
}
.content > .list .date_list_item {
width: 100%;
}
/** content: date list **/ /** content: date list **/
.date_list nav { .date_list nav {
text-align:center; text-align:center;
@ -246,6 +234,40 @@ ul.list, .list > ul {
margin-top: 0em; margin-top: 0em;
} }
.date_list_item time {
color: #007EDF;
}
.date_list_item.now {
font-size: 1.2em;
}
.date_list_item img.now {
width: 1.3em;
vertical-align: middle;
}
/** content: date list in full page **/
.content > .date_list .date_list_item time {
color: #007EDF;
font-size: 1.1em;
display: block;
}
.content > .date_list .date_list_item:nth-child(2n+1) {
box-shadow: inset 0em 0em 3em rgba(0, 124, 226, 0.1);
background-color: rgba(0, 124, 226, 0.05);
}
.content > .date_list {
padding: 0 10%;
margin: auto;
width: 80%;
}
/** content: comments **/ /** content: comments **/
.comments form input:not([type=checkbox]), .comments form input:not([type=checkbox]),

View File

@ -148,8 +148,10 @@ Playlist.prototype = {
this.playlist.removeChild(sound.item); this.playlist.removeChild(sound.item);
this.save(); this.save();
this.player.stop() if(this.sound == sound) {
this.next(false); this.player.stop()
this.next(false);
}
}, },
select: function(sound, play = true) { select: function(sound, play = true) {

View File

@ -3,16 +3,24 @@ Configurable item to be put in a dated list. Work like list_item, the layout
is just a bit different. is just a bit different.
{% endcomment %} {% endcomment %}
{% load static %}
{% load i18n %}
{% load wagtailimages_tags %} {% load wagtailimages_tags %}
<a {% if item.url %}href="{{ item.url }}" {% endif %} <a {% if item.url %}href="{{ item.url }}" {% endif %}
class="list_item date_list_item {% if not item_big_cover %}flex_row {% endif %}{% if item.css_class %}{{ item.css_class }}{% endif %}" class="list_item date_list_item {{ item.css_class|default_if_none:"" }}{% if not item_big_cover %} flex_row{% endif %}"
title="{{ item.date|date:"l d F Y" }}" title="{{ item.date|date:"l d F Y" }}"
> >
{% if not item.show_in_menus and item.date and item_date_format != '' %} {% if not item.show_in_menus and item.date and item_date_format != '' %}
{% with date_format=item_date_format|default_if_none:'l d F, H:i' %} {% with date_format=item_date_format|default_if_none:'l d F, H:i' %}
<time datetime="{{ item.date }}"> <time datetime="{{ item.date }}">
{% if item.now %}
<img src="{% static "aircox/images/play.png" %}"
title="{% trans "happening now!" %}"
alt="{% trans "happening now!" %}" class="now">
{% endif %}
{{ item.date|date:date_format }} {{ item.date|date:date_format }}
</time> </time>
{% endwith %} {% endwith %}

View File

@ -15,7 +15,7 @@ Options:
{% load wagtailimages_tags %} {% load wagtailimages_tags %}
<a {% if item.url %}href="{{ item.url }}" {% endif %} <a {% if item.url %}href="{{ item.url }}" {% endif %}
class="list_item {% if not item_big_cover %}flex_row {% endif %}{% if item.css_class %}{{ item.css_class }}{% endif %}"> class="list_item {{ item.css_class|default_if_none:"" }}{% if not item_big_cover %} flex_row{% endif %}">
{% if item.cover %} {% if item.cover %}
{% if item_big_cover %} {% if item_big_cover %}
{% image item.cover max-640x480 class="cover big" height="" width="" %} {% image item.cover max-640x480 class="cover big" height="" width="" %}
@ -23,6 +23,7 @@ Options:
{% image item.cover fill-64x64 class="cover small" %} {% image item.cover fill-64x64 class="cover small" %}
{% endif %} {% endif %}
{% endif %} {% endif %}
<div class="flex_item"> <div class="flex_item">
<h3 class="title">{{ item.title }}</h3> <h3 class="title">{{ item.title }}</h3>

View File

@ -222,11 +222,16 @@ class GenericMenu(Menu):
""" """
pass pass
@staticmethod
def page_of(item):
return item.page
def page_url(self, item): def page_url(self, item):
if item.page.count(): page = self.page_of(item)
if page:
name = 'wagtailadmin_explore' \ name = 'wagtailadmin_explore' \
if self.explore else 'wagtailadmin_pages:edit' if self.explore else 'wagtailadmin_pages:edit'
return reverse(name, args=[item.page.first().id]) return reverse(name, args=[page.id])
parent_page = self.get_parent(item) parent_page = self.get_parent(item)
if not parent_page: if not parent_page:
@ -311,7 +316,7 @@ class TodayMenu(GenericMenu):
attrs = {} attrs = {}
qs = PageRevision.objects.filter(page = item.page.first()) qs = PageRevision.objects.filter(page = item.page)
if qs.count(): if qs.count():
headline = qs.latest('created_at').content_json headline = qs.latest('created_at').content_json
headline = json.loads(headline).get('headline') headline = json.loads(headline).get('headline')

View File

@ -21,6 +21,7 @@ This file is used as a reminder, can be used as crappy documentation too.
- category page - category page
- for timetable, logs, etc. make station optional - for timetable, logs, etc. make station optional
- django's message css displayed on pages when element is modified (remove bullet) - django's message css displayed on pages when element is modified (remove bullet)
- articles preview in different format
# conventions # conventions