paniktags.py 11.3 KB
Newer Older
fred's avatar
fred committed
1 2
import email.utils
import datetime
fred's avatar
fred committed
3
import json
fred's avatar
fred committed
4
import re
fred's avatar
fred committed
5
import time
fred's avatar
fred committed
6
import urlparse
fred's avatar
fred committed
7
import urllib2
8 9
import uuid

fred's avatar
fred committed
10
from django import template
11
from django.conf import settings
fred's avatar
fred committed
12
from django.core.urlresolvers import reverse
Simon Daron's avatar
Simon Daron committed
13
from django.db.models.query import QuerySet
Simon Daron's avatar
Simon Daron committed
14 15
from datetime import datetime, timedelta

fred's avatar
fred committed
16
from emissions.models import Emission, Episode, NewsItem, SoundFile, Focus
Simon Daron's avatar
Simon Daron committed
17
from emissions.utils import period_program
fred's avatar
fred committed
18

fred's avatar
fred committed
19 20
from panikombo.models import Topik

fred's avatar
fred committed
21
from panikweb import utils
22
from panikweb import search
fred's avatar
fred committed
23

fred's avatar
fred committed
24 25 26 27
register = template.Library()

@register.filter(name='zip')
def zip_lists(a, b):
fred's avatar
fred committed
28
    return zip(a, b)
29

Simon Daron's avatar
Simon Daron committed
30
@register.inclusion_tag('includes/audio.html', takes_context=True)
31
def audio(context, sound=None, embed=False, display_fragment_name=False):
Simon Daron's avatar
Simon Daron committed
32
    return {
Simon Daron's avatar
Simon Daron committed
33
        'episode': context.get('episode'),
34 35
        'sound': sound,
        'display_fragment_name': display_fragment_name,
36
        'embed': embed,
Simon Daron's avatar
Simon Daron committed
37 38
    }

Simon Daron's avatar
Simon Daron committed
39 40 41 42 43 44 45
@register.inclusion_tag('listen/nav.html', takes_context=True)
def listen_nav(context, date=None, klass=None):
    return {
        'class': klass,
        'categories': context.get('categories'),
    }

46
@register.inclusion_tag('news/nav.html', takes_context=True)
47
def news_nav(context, date=None, klass=None):
48
    return {
49
        'class': klass,
50
        'newsitem': context.get('newsitem'),
Simon Daron's avatar
Simon Daron committed
51
        'categories': context.get('categories'),
52
        'news': context.get('news'),
fred's avatar
fred committed
53
        'search_query': context.get('search_query'),
54 55
    }

Simon Daron's avatar
Simon Daron committed
56
@register.inclusion_tag('emissions/nav.html', takes_context=True)
Simon Daron's avatar
Simon Daron committed
57
def emission_nav(context, date=None, klass=None):
Simon Daron's avatar
Simon Daron committed
58
    return {
Simon Daron's avatar
Simon Daron committed
59 60
        'class': klass,
        'categories': context.get('categories'),
61
        'episodes': context.get('episodes'),
Simon Daron's avatar
Simon Daron committed
62 63
        'emission': context.get('emission'),
        'episode': context.get('episode'),
fred's avatar
fred committed
64
        'search_query': context.get('search_query'),
Simon Daron's avatar
Simon Daron committed
65 66
    }

67 68 69 70 71 72 73
@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,
    }
74
@register.inclusion_tag('episodes/resume.html', takes_context=True)
75
def episode_resume(context, date=None, model=None, klass=None):
76
    return {
77
        'model': model,
78
        'class': klass,
79 80 81 82
        'episode': context.get('episode'),
        'date': date,
    }

83 84
@register.inclusion_tag('episodes/detail.html', takes_context=True)
def episode_detail(context, date=None):
fred's avatar
fred committed
85 86
    soundfiles = SoundFile.objects.select_related().filter(
            fragment=True, podcastable=True, episode=context.get('episode'))
87 88 89 90
    return {
        'episode': context.get('episode'),
        'emission': context.get('emission'),
        'diffusions': context.get('diffusions'),
fred's avatar
fred committed
91
        'soundfiles': soundfiles,
92
        'date': date,
fred's avatar
fred committed
93
        'topiks': context.get('topiks'),
94 95
    }

96 97 98 99 100 101 102
@register.inclusion_tag('emissions/detail.html', takes_context=True)
def emission_detail(context, date=None):
    return {
        'emission': context.get('emission'),
        'schedules': context.get('schedules'),
    }

Simon Daron's avatar
Simon Daron committed
103 104 105 106 107 108 109
@register.inclusion_tag('emissions/resume.html', takes_context=True)
def emission_resume(context, date=None):
    return {
        'emission': context.get('emission'),
        'schedules': context.get('schedules'),
    }

Simon Daron's avatar
Simon Daron committed
110 111 112 113 114 115 116
@register.inclusion_tag('emissions/inline.html', takes_context=True)
def emission_inline(context, date=None):
    return {
        'emission': context.get('emission'),
        'schedules': context.get('schedules'),
    }

117
@register.inclusion_tag('soundfiles/resume.html')
fred's avatar
fred committed
118 119 120
def soundfile_resume(soundfile, date=None):
    return {'soundfile': soundfile,
            'date': date}
121

122 123 124 125 126 127 128
@register.inclusion_tag('includes/player.html', takes_context=True)
def player(context):

    return {
        'unique': uuid.uuid4(),
        'soundfiles': context.get('soundfiles'),
    }
129

130 131
@register.inclusion_tag('includes/metaNav.html', takes_context=True)
def metanav(context, active=None):
fred's avatar
fred committed
132 133 134 135 136 137 138 139 140 141 142 143 144 145
    request_path = context['request'].path
    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'
146
    return {
fred's avatar
fred committed
147
        'LANGUAGE_CODE': context.get('LANGUAGE_CODE'),
fred's avatar
fred committed
148
        'sectionName': section,
fred's avatar
fred committed
149
        }
150

151 152
@register.inclusion_tag('includes/week.html')
def weekview(year=None, week=None):
fred's avatar
fred committed
153 154 155 156
    year = year if year else datetime.today().isocalendar()[0]
    week = week if week else datetime.today().isocalendar()[1]

    date = utils.tofirstdayinisoweek(year, week)
Simon Daron's avatar
Simon Daron committed
157 158 159 160 161 162 163
    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)})
164

165 166 167 168 169 170 171 172 173 174
    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]
175
    weekday = weekday if weekday is not None else datetime.today().weekday()
176 177 178 179 180 181 182 183

    date = utils.tofirstdayinisoweek(year, week)
    date = datetime(*date.timetuple()[:3])

    days = []
    for day in range(7):
        days.append({'datetime': date+timedelta(days=day)})

184 185 186 187 188 189
    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]

Simon Daron's avatar
Simon Daron committed
190 191
    return {
        'days': days,
192
        'weekday': weekday,
Simon Daron's avatar
Simon Daron committed
193 194
        'week': week,
        'year': year,
195 196 197 198
        'previous_week_year': previous_week_year,
        'previous_week_no': previous_week_no,
        'next_week_year': next_week_year,
        'next_week_no': next_week_no,
Simon Daron's avatar
Simon Daron committed
199 200
    }

201

Simon Daron's avatar
Simon Daron committed
202 203
@register.inclusion_tag('news/inline.html', takes_context=True)
def news_inline(context, klass=None, logo=None):
204
    return {
Simon Daron's avatar
Simon Daron committed
205
            'content': context.get('content'),
206 207 208
            'class': klass,
            'logo': logo
    }
fred's avatar
fred committed
209

fred's avatar
fred committed
210 211
@register.inclusion_tag('news/roll.html')
def newsroll():
Simon Daron's avatar
Simon Daron committed
212
    return {
fred's avatar
fred committed
213 214
        'news': Focus.objects.filter(current=True).select_related('emission', 'newsitem',
            'soundfile', 'episode', 'newsitem__category').order_by('?')[:3]
Simon Daron's avatar
Simon Daron committed
215 216
    }

fred's avatar
fred committed
217

Simon Daron's avatar
Simon Daron committed
218 219 220 221
@register.filter
def jsonify(object):
    if isinstance(object, QuerySet):
        return serialize('json', object)
fred's avatar
fred committed
222
    return json.dumps(object)
Simon Daron's avatar
Simon Daron committed
223

Simon Daron's avatar
Simon Daron committed
224 225 226 227 228 229 230 231 232 233 234 235 236
@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 )

237 238

def remove_facet(facet_id, url, facet):
fred's avatar
fred committed
239
    scheme, netloc, path, query, fragment = list(urlparse.urlsplit(str(url)))
240
    facet = '%s_exact:%s' % (facet_id, facet.encode('utf-8'))
fred's avatar
fred committed
241 242 243 244 245
    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])
fred's avatar
fred committed
246
    return unicode(re.sub(r'&page=\d+', '', url), 'utf-8')
fred's avatar
fred committed
247

248 249 250
@register.filter
def remove_tag_facet(url, facet):
    return remove_facet('tags', url, facet)
fred's avatar
fred committed
251 252 253

@register.filter
def remove_category_facet(url, facet):
254
    return remove_facet('categories', url, facet)
fred's avatar
fred committed
255

fred's avatar
fred committed
256 257 258

@register.filter
def remove_news_category_facet(url, facet):
259
    return remove_facet('news_categories', url, facet)
fred's avatar
fred committed
260

fred's avatar
fred committed
261
@register.filter
262 263 264 265 266
def remove_format_facet(url, facet):
    return remove_facet('format', url, facet)


def append_facet(facet_id, url, facet):
fred's avatar
fred committed
267
    facet = urllib2.quote(facet.encode('utf-8'), safe='')
fred's avatar
fred committed
268 269
    if not '?' in url:
        url = url + '?'
270 271 272 273 274
    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)
fred's avatar
fred committed
275 276 277

@register.filter
def append_category_facet(url, facet):
278
    return append_facet('categories', url, facet)
279

fred's avatar
fred committed
280 281
@register.filter
def append_news_category_facet(url, facet):
282 283 284 285 286 287
    return append_facet('news_categories', url, facet)

@register.filter
def append_format_facet(url, facet):
    return append_facet('format', url, facet)

288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310

@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(template.context.Context({'result': result}, autoescape=context.autoescape))
311 312 313 314 315


@register.inclusion_tag('includes/piwik.html')
def piwik():
    return {'enabled': settings.ENABLE_PIWIK}
fred's avatar
fred committed
316 317 318 319 320 321 322


@register.filter
def rfc822(datetime):
    if datetime is None:
        return ''
    return email.utils.formatdate(time.mktime(datetime.timetuple()))
323 324 325

@register.inclusion_tag('includes/related.html', takes_context=False)
def related_objects(object):
fred's avatar
fred committed
326
    sqs = search.MoreLikeThisSearchQuerySet().models(Emission, Episode, NewsItem)
327
    return {'more_like_this': sqs.more_like_this(object)[:12]}
fred's avatar
fred committed
328

fred's avatar
fred committed
329 330 331
@register.inclusion_tag('includes/topik.html', takes_context=True)
def topik(context, topik):
    return {'topik': topik}
fred's avatar
fred committed
332 333 334 335 336 337 338 339 340 341 342 343 344

@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,
fred's avatar
fred committed
345
            'emission_slug': object.soundfile.episode.emission.slug})
fred's avatar
fred committed
346 347
    if object.page:
        return object.page.get_online_url()
fred's avatar
fred committed
348
    return ''
fred's avatar
fred committed
349 350 351

@register.filter
def facet_tag(tag):
fred's avatar
fred committed
352
    return tag.name
fred's avatar
fred committed
353 354 355 356 357 358 359 360 361 362


@register.filter
def image_file(page):
    try:
        matching_topik = Topik.objects.get(page=page)
        return matching_topik.image
    except Topik.DoesNotExist:
        pass
    return None
fred's avatar
fred committed
363 364 365 366 367 368 369


@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
370 371 372 373 374 375

@register.filter
def as_absolute_url(url):
    if url.startswith('/'):
        url = settings.WEBSITE_BASE_URL + url.lstrip('/')
    return url