+import email.utils
+import datetime
+import json
+import re
+import time
+import uuid
+
from django import template
+from django.conf import settings
+from django.core.urlresolvers import reverse
+from django.db.models.query import QuerySet
+from django.utils.encoding import force_text
+from django.utils.http import quote
+from django.utils.six.moves.urllib import parse as urlparse
+
+from datetime import datetime, timedelta
+
+from emissions.models import Emission, Episode, NewsItem, SoundFile, Focus
+from emissions.utils import period_program
+
+from panikombo.models import Topik
+
+from panikweb import utils
+from panikweb import search
register = template.Library()
@register.filter(name='zip')
def zip_lists(a, b):
- return zip(a, b)
+ return zip(a, b)
+
+@register.inclusion_tag('includes/audio.html', takes_context=True)
+def audio(context, sound=None, embed=False, display_fragment_name=False):
+ return {
+ 'episode': context.get('episode'),
+ 'sound': sound,
+ 'display_fragment_name': display_fragment_name,
+ 'embed': embed,
+ }
+
+@register.inclusion_tag('listen/nav.html', takes_context=True)
+def listen_nav(context, date=None, klass=None):
+ return {
+ 'class': klass,
+ 'categories': context.get('categories'),
+ }
+
+@register.inclusion_tag('news/nav.html', takes_context=True)
+def news_nav(context, date=None, klass=None):
+ return {
+ 'class': klass,
+ 'newsitem': context.get('newsitem'),
+ 'categories': context.get('categories'),
+ 'news': context.get('news'),
+ 'search_query': context.get('search_query'),
+ }
+
+@register.inclusion_tag('emissions/nav.html', takes_context=True)
+def emission_nav(context, date=None, klass=None):
+ return {
+ 'class': klass,
+ 'categories': context.get('categories'),
+ 'episodes': context.get('episodes'),
+ 'emission': context.get('emission'),
+ 'episode': context.get('episode'),
+ 'search_query': context.get('search_query'),
+ }
+
+@register.inclusion_tag('episodes/inline.html', takes_context=True)
+def episode_inline(context, date=None, model=None, klass=None):
+ return {
+ 'class': klass,
+ 'episode': context.get('episode'),
+ 'date': date,
+ }
+@register.inclusion_tag('episodes/resume.html', takes_context=True)
+def episode_resume(context, date=None, model=None, klass=None):
+ return {
+ 'model': model,
+ 'class': klass,
+ 'episode': context.get('episode'),
+ 'date': date,
+ }
+
+@register.inclusion_tag('episodes/detail.html', takes_context=True)
+def episode_detail(context, date=None):
+ soundfiles = SoundFile.objects.select_related().filter(
+ fragment=True, podcastable=True, episode=context.get('episode'))
+ return {
+ 'episode': context.get('episode'),
+ 'emission': context.get('emission'),
+ 'diffusions': context.get('diffusions'),
+ 'soundfiles': soundfiles,
+ 'date': date,
+ 'topiks': context.get('topiks'),
+ }
+
+@register.inclusion_tag('emissions/detail.html', takes_context=True)
+def emission_detail(context, date=None):
+ return {
+ 'emission': context.get('emission'),
+ 'schedules': context.get('schedules'),
+ }
+
+@register.inclusion_tag('emissions/resume.html', takes_context=True)
+def emission_resume(context, date=None):
+ return {
+ 'emission': context.get('emission'),
+ 'schedules': context.get('schedules'),
+ }
+
+@register.inclusion_tag('emissions/inline.html', takes_context=True)
+def emission_inline(context, date=None):
+ return {
+ 'emission': context.get('emission'),
+ 'schedules': context.get('schedules'),
+ }
+
+@register.inclusion_tag('soundfiles/resume.html')
+def soundfile_resume(soundfile, date=None):
+ return {'soundfile': soundfile,
+ 'date': date}
+
+@register.inclusion_tag('includes/player.html', takes_context=True)
+def player(context):
+
+ return {
+ 'unique': uuid.uuid4(),
+ 'soundfiles': context.get('soundfiles'),
+ }
+
+@register.inclusion_tag('includes/metaNav.html', takes_context=True)
+def metanav(context, active=None):
+ try:
+ request_path = context['request'].path
+ except KeyError:
+ # a context without 'requests' may happen when rendering error pages
+ request_path = 'xxx'
+ section = 'About'
+ if request_path == '/':
+ section = 'Home'
+ elif request_path.startswith('/actus/'):
+ section = 'News'
+ elif request_path.startswith('/sons/'):
+ section = 'Listen'
+ elif request_path.startswith('/topiks'):
+ section = 'Topiks'
+ elif request_path.startswith('/emissions') or request_path == '/grille' or request_path == '/programme/':
+ section = 'Emissions'
+ elif request_path == '/recherche/':
+ section = 'Search'
+ return {
+ 'LANGUAGE_CODE': context.get('LANGUAGE_CODE'),
+ 'sectionName': section,
+ }
+
+@register.inclusion_tag('includes/week.html')
+def weekview(year=None, week=None):
+ year = year if year else datetime.today().isocalendar()[0]
+ week = week if week else datetime.today().isocalendar()[1]
+
+ date = utils.tofirstdayinisoweek(year, week)
+ date = datetime(*date.timetuple()[:3])
+
+ program = period_program(date, date+timedelta(days=7))
+ days = []
+ for day in range(7):
+ days.append({'cells': [x for x in program if x.is_on_weekday(day+1)],
+ 'datetime': date+timedelta(days=day)})
+
+ return {
+ 'days': days,
+ 'week': week,
+ 'year': year,
+ }
+
+@register.inclusion_tag('includes/week-nav.html')
+def weeknav(year=None, week=None, weekday=None):
+ year = year if year else datetime.today().isocalendar()[0]
+ week = week if week else datetime.today().isocalendar()[1]
+ weekday = weekday if weekday is not None else datetime.today().weekday()
+
+ date = utils.tofirstdayinisoweek(year, week)
+ date = datetime(*date.timetuple()[:3])
+
+ days = []
+ for day in range(7):
+ days.append({'datetime': date+timedelta(days=day)})
+
+ previous_week = date - timedelta(days=7)
+ previous_week_year, previous_week_no = previous_week.isocalendar()[:2]
+
+ next_week = date + timedelta(days=7)
+ next_week_year, next_week_no = next_week.isocalendar()[:2]
+
+ return {
+ 'days': days,
+ 'weekday': weekday,
+ 'week': week,
+ 'year': year,
+ 'previous_week_year': previous_week_year,
+ 'previous_week_no': previous_week_no,
+ 'next_week_year': next_week_year,
+ 'next_week_no': next_week_no,
+ }
+
+
+@register.inclusion_tag('news/inline.html', takes_context=True)
+def news_inline(context, klass=None, logo=None):
+ return {
+ 'content': context.get('content'),
+ 'class': klass,
+ 'logo': logo
+ }
+
+@register.inclusion_tag('news/roll.html')
+def newsroll():
+ return {
+ 'news': Focus.objects.filter(current=True).select_related('emission', 'newsitem',
+ 'soundfile', 'episode', 'newsitem__category').order_by('?')[:3]
+ }
+
+
+@register.filter
+def jsonify(object):
+ if isinstance(object, QuerySet):
+ return serialize('json', object)
+ return json.dumps(object)
+
+@register.filter
+def strreplace ( string, args ):
+ find = args.split(',')[0]
+ replace = args.split(',')[1]
+ return string.replace(find,replace)
+
+@register.filter
+def replace ( string, args ):
+ search = args.split(args[0])[1]
+ replace = args.split(args[0])[2]
+
+ return re.sub( search, replace, string )
+
+
+def remove_facet(facet_id, url, facet):
+ scheme, netloc, path, query, fragment = list(urlparse.urlsplit(str(url)))
+ facet = '%s_exact:%s' % (facet_id, facet.encode('utf-8'))
+ query_string = urlparse.parse_qsl(query)
+ query_string = [x for x in query_string if not (
+ x[0] == 'selected_facets' and x[1] == facet)]
+ query = '&'.join(['%s=%s' % x for x in query_string])
+ url = urlparse.urlunsplit([scheme, netloc, path, query, None])
+ return force_text(re.sub(r'&page=\d+', '', url), 'utf-8')
+
+@register.filter
+def remove_tag_facet(url, facet):
+ return remove_facet('tags', url, facet)
+
+@register.filter
+def remove_category_facet(url, facet):
+ return remove_facet('categories', url, facet)
+
+
+@register.filter
+def remove_news_category_facet(url, facet):
+ return remove_facet('news_categories', url, facet)
+
+@register.filter
+def remove_format_facet(url, facet):
+ return remove_facet('format', url, facet)
+
+
+def append_facet(facet_id, url, facet):
+ facet = quote(facet.encode('utf-8'), safe='')
+ if not '?' in url:
+ url = url + '?'
+ return re.sub(r'&page=\d+', '', url + '&selected_facets=%s_exact:%s' % (facet_id, facet))
+
+@register.filter
+def append_tag_facet(url, facet):
+ return append_facet('tags', url, facet)
+
+@register.filter
+def append_category_facet(url, facet):
+ return append_facet('categories', url, facet)
+
+@register.filter
+def append_news_category_facet(url, facet):
+ return append_facet('news_categories', url, facet)
+
+@register.filter
+def append_format_facet(url, facet):
+ return append_facet('format', url, facet)
+
+
+@register.tag
+def search_result_template(parser, token):
+ try:
+ tag_name, result_str = token.split_contents()
+ except ValueError:
+ raise template.TemplateSyntaxError("%r tag requires exactly one argument" % token.contents.split()[0])
+ return FormatSearchResultNode(result_str)
+
+
+class FormatSearchResultNode(template.Node):
+ def __init__(self, result_str):
+ self.result_var = template.Variable(result_str)
+
+ def render(self, context):
+ result = self.result_var.resolve(context)
+ dir_mapping = {
+ 'newsitem': 'news',
+ 'emission': 'emissions',
+ 'episode': 'episodes'
+ }
+ t = template.loader.get_template('%s/search_result.html' % dir_mapping.get(result.model_name))
+ return t.render({'result': result})
+
+
+@register.inclusion_tag('includes/piwik.html')
+def piwik():
+ return {'enabled': settings.ENABLE_PIWIK}
+
+
+@register.filter
+def rfc822(datetime):
+ if datetime is None:
+ return ''
+ return email.utils.formatdate(time.mktime(datetime.timetuple()))
+
+@register.inclusion_tag('includes/related.html', takes_context=False)
+def related_objects(object):
+ sqs = search.MoreLikeThisSearchQuerySet().models(Emission, Episode, NewsItem)
+ return {'more_like_this': sqs.more_like_this(object)[:12]}
+
+@register.inclusion_tag('includes/topik.html', takes_context=True)
+def topik(context, topik):
+ return {'topik': topik}
+
+@register.filter
+def get_focus_url(object):
+ if object.newsitem:
+ return reverse('newsitem-view', kwargs={'slug': object.newsitem.slug})
+ if object.emission:
+ return reverse('emission-view', kwargs={'slug': object.emission.slug})
+ if object.episode:
+ return reverse('episode-view', kwargs={
+ 'slug': object.episode.slug, 'emission_slug': object.episode.emission.slug})
+ if object.soundfile:
+ return reverse('episode-view', kwargs={
+ 'slug': object.soundfile.episode.slug,
+ 'emission_slug': object.soundfile.episode.emission.slug})
+ if object.page:
+ return object.page.get_online_url()
+ return ''
+
+@register.filter
+def facet_tag(tag):
+ return tag.name
+
+
+@register.filter
+def image_file(page):
+ try:
+ matching_topik = Topik.objects.get(page=page)
+ return matching_topik.image
+ except Topik.DoesNotExist:
+ pass
+ return None
+
+
+@register.filter
+def set_absolute_urls(text):
+ text = text.replace('src="/', 'src="%s' % settings.WEBSITE_BASE_URL)
+ text = text.replace('href="/', 'href="%s' % settings.WEBSITE_BASE_URL)
+ return text
+
+@register.filter
+def as_absolute_url(url):
+ if url.startswith('/'):
+ url = settings.WEBSITE_BASE_URL + url.lstrip('/')
+ return url