schedule section; page view with arbitrary content

This commit is contained in:
bkfox 2016-06-06 12:10:10 +02:00
parent a2f2165935
commit 19f7ceaf9f
6 changed files with 169 additions and 31 deletions

View File

@ -2,7 +2,7 @@ from django.contrib import admin
import aircox.cms.models as models import aircox.cms.models as models
admin.site.register(cms.Article) admin.site.register(models.Article)
admin.site.register(cms.Comment) admin.site.register(models.Comment)

View File

@ -38,10 +38,12 @@ class Routable:
) )
@classmethod @classmethod
def route_url(cl, route, kwargs = None): def route_url(cl, route, **kwargs):
name = cl._website.name_of_model(cl) name = cl._website.name_of_model(cl)
name = route.get_view_name(name) name = route.get_view_name(name)
return reverse(name, kwargs = kwargs) r = reverse(name, kwargs = kwargs)
return r
class Comment(models.Model, Routable): class Comment(models.Model, Routable):
thread_type = models.ForeignKey( thread_type = models.ForeignKey(
@ -162,8 +164,10 @@ class Post (models.Model, Routable):
return qs return qs
def detail_url(self): def detail_url(self):
return self.route_url(routes.DetailRoute, return self.route_url(
{ 'pk': self.pk, 'slug': slugify(self.title) }) routes.DetailRoute,
pk = self.pk, slug = slugify(self.title)
)
def get_object_list(self, request, object, **kwargs): def get_object_list(self, request, object, **kwargs):
type = ContentType.objects.get_for_model(object) type = ContentType.objects.get_for_model(object)

View File

@ -1,4 +1,5 @@
from django.db import models from django.db import models
from django.utils import timezone as tz
from django.conf.urls import url from django.conf.urls import url
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.utils import timezone from django.utils import timezone
@ -137,8 +138,8 @@ class DateRoute(Route):
name = 'date' name = 'date'
url_args = [ url_args = [
('year', '[0-9]{4}'), ('year', '[0-9]{4}'),
('month', '[0-9]{2}'), ('month', '[0-1]?[0-9]'),
('day', '[0-9]{1,2}'), ('day', '[0-3]?[0-9]'),
] ]
@classmethod @classmethod
@ -151,11 +152,10 @@ class DateRoute(Route):
@classmethod @classmethod
def get_title(cl, model, request, year, month, day, **kwargs): def get_title(cl, model, request, year, month, day, **kwargs):
return _('%(model)s of %(year)/%(month)/%(day)') % { date = tz.datetime(year = int(year), month = int(month), day = int(day))
return _('%(model)s of %(date)s') % {
'model': model._meta.verbose_name_plural, 'model': model._meta.verbose_name_plural,
'year': year, 'date': date.strftime('%A %d %B %Y'),
'month': month,
'day': day
} }

View File

@ -1,7 +1,7 @@
from django.templatetags.static import static from django.templatetags.static import static
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.views.generic import ListView, DetailView from django.views.generic import ListView, DetailView
from django.views.generic.base import View from django.views.generic.base import View, TemplateView
from django.utils.translation import ugettext as _, ugettext_lazy from django.utils.translation import ugettext as _, ugettext_lazy
from django.contrib import messages from django.contrib import messages
from django.http import Http404 from django.http import Http404
@ -13,7 +13,8 @@ class PostBaseView:
website = None # corresponding website website = None # corresponding website
title = '' # title of the page title = '' # title of the page
embed = False # page is embed (if True, only post content is printed embed = False # page is embed (if True, only post content is printed
classes = '' # extra classes for the content attrs = '' # attr for the HTML element of the content
css_classes = ''# css classes for the HTML element of the content
def get_base_context(self, **kwargs): def get_base_context(self, **kwargs):
""" """
@ -108,11 +109,13 @@ class PostListView(PostBaseView, ListView):
self.route.get_title(self.model, self.request, self.route.get_title(self.model, self.request,
**self.kwargs) **self.kwargs)
context['title'] = title context.update({
context['base_template'] = 'aircox/cms/website.html' 'title': title,
context['css_class'] = 'list' if not self.css_class else \ 'base_template': 'aircox/cms/website.html',
'list ' + self.css_class 'css_class': 'list' if not self.css_class else \
context['list'] = self.list 'list ' + self.css_class,
'list': self.list,
})
# FIXME: list.url = if self.route: self.model(self.route, self.kwargs) else '' # FIXME: list.url = if self.route: self.model(self.route, self.kwargs) else ''
return context return context
@ -155,11 +158,13 @@ class PostDetailView(DetailView, PostBaseView):
context.update(self.get_base_context()) context.update(self.get_base_context())
kwargs['object'] = self.object kwargs['object'] = self.object
context['content'] = ''.join([ context.update({
section.get(request = self.request, **kwargs) 'content': ''.join([
for section in self.sections section.get(request = self.request, **kwargs)
]) for section in self.sections
context['css_class'] = 'detail' ]),
'css_class': 'detail',
})
return context return context
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
@ -176,3 +181,34 @@ class PostDetailView(DetailView, PostBaseView):
return self.get(request, *args, **kwargs) return self.get(request, *args, **kwargs)
class PageView(TemplateView, PostBaseView):
"""
A simple page view. Used to render pages that have arbitrary content
without linked post object.
"""
template_name = 'aircox/cms/detail.html'
sections = []
css_class = 'page'
def __init__(self, *args, **kwargs):
css_class = 'css_class' in kwargs and kwargs.pop('css_class')
if css_class:
self.css_class += ' ' + css_class
super().__init__(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update(self.get_base_context())
context.update({
'title': self.title,
'content': ''.join([
section.get(request = self.request, **kwargs)
for section in self.sections
]),
})
return context

View File

@ -1,3 +1,6 @@
from django.utils.text import slugify
from django.conf.urls import url
import aircox.cms.routes as routes import aircox.cms.routes as routes
import aircox.cms.views as views import aircox.cms.views as views
@ -104,6 +107,22 @@ class Website:
self.urls += [ route.as_url(name, view) for route in routes ] self.urls += [ route.as_url(name, view) for route in routes ]
self.registry[name] = model self.registry[name] = model
def register_page(self, name, view = views.PageView, path = None,
**view_kwargs):
"""
Register a page that is accessible to the given path. If path is None,
use a slug of the name.
"""
view = view.as_view(
website = self,
**view_kwargs
)
self.urls.append(url(
slugify(name) if path is None else path,
view = view,
name = name,
))
def register(self, name, model, sections = None, routes = None, def register(self, name, model, sections = None, routes = None,
list_view = views.PostListView, list_view = views.PostListView,
detail_view = views.PostDetailView, detail_view = views.PostDetailView,

View File

@ -6,7 +6,7 @@ import aircox.cms.models as cms
import aircox.cms.routes as routes import aircox.cms.routes as routes
import aircox.cms.sections as sections import aircox.cms.sections as sections
import website.models as models import aircox.website.models as models
class Diffusions(sections.List): class Diffusions(sections.List):
@ -22,12 +22,14 @@ class Diffusions(sections.List):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.__dict__.update(kwargs) self.__dict__.update(kwargs)
def get_diffs(self): def get_diffs(self, **filter_args):
qs = programs.Diffusion.objects.filter( qs = programs.Diffusion.objects.filter(
type = programs.Diffusion.Type.normal type = programs.Diffusion.Type.normal
) )
if self.object: if self.object:
qs = qs.filter(program = self.object.related) qs = qs.filter(program = self.object.related)
if filter_args:
qs = qs.filter(**filter_args).order_by('start')
r = [] r = []
if self.next_count: if self.next_count:
@ -70,10 +72,10 @@ class Diffusions(sections.List):
@property @property
def url(self): def url(self):
if self.object: if self.object:
return models.Diffusion.route_url(routes.ThreadRoute, { return models.Diffusion.route_url(routes.ThreadRoute,
'pk': self.object.id, pk = self.object.id,
'thread_model': 'program', thread_model = 'program',
}) )
return models.Diffusion.route_url(routes.AllRoute) return models.Diffusion.route_url(routes.AllRoute)
@property @property
@ -81,7 +83,6 @@ class Diffusions(sections.List):
if not self.show_schedule: if not self.show_schedule:
return None return None
def str_sched(sched): def str_sched(sched):
info = ' <span class="info">(' + _('rerun of %(day)s') % { info = ' <span class="info">(' + _('rerun of %(day)s') % {
'day': sched.initial.date.strftime('%A') 'day': sched.initial.date.strftime('%A')
@ -112,6 +113,84 @@ class Playlist(sections.List):
for track in tracks ] for track in tracks ]
class Schedule(Diffusions):
"""
Schedule printing diffusions starting at the given date
* date: if set use this date instead of now;
* days: number of days to show;
* time_format: force format of the date in schedule header;
"""
date = None
days = 7
time_format = '%a. %d'
def get_diffs(self):
date = self.date or tz.datetime.now()
return super().get_diffs(
start__year = date.year,
start__month = date.month,
start__day = date.day,
)
@property
def header(self):
date = self.date or tz.datetime.now()
date.replace(hour = 0, minute = 0, second = 0, microsecond = 0)
curr = date - tz.timedelta(days=date.weekday())
last = curr + tz.timedelta(days=7)
r = """
<script>function update_schedule(url, event) {
var target = event.currentTarget;
while(target && target.className.indexOf('section'))
target = target.parentNode;
if(!target)
return false;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState != 4 || xhr.status != 200 && xhr.status)
return;
var obj = document.createElement('div');
obj.innerHTML = xhr.responseText;
obj = obj.getElementsByTagName('ul');
console.log(obj)
if(!obj)
return;
obj = obj[0];
target.replaceChild(obj, target.querySelector('ul'))
target.querySelector('nav a').href = url
}
xhr.open('GET', url + '?embed=1', true);
xhr.send();
return false;
}
</script>
"""
while curr < last:
r += \
'<a href="{url}"{extra} '\
'onclick="return update_schedule(\'{url}\', event)">{title}</a>' \
.format(
title = curr.strftime(self.time_format),
extra = ' class="selected"' if curr == date else '',
url = models.Diffusion.route_url(
routes.DateRoute,
year = curr.year, month = curr.month, day = curr.day,
)
)
curr += tz.timedelta(days=1)
return r
#class DatesOfDiffusion(sections.List): #class DatesOfDiffusion(sections.List):
# title = _('Dates of diffusion') # title = _('Dates of diffusion')
# #