]> git.0d.be Git - panikweb.git/blob - panikweb/paniktags/templatetags/paniktags.py
use pages to get to topiks
[panikweb.git] / panikweb / paniktags / templatetags / paniktags.py
1 import email.utils
2 import datetime
3 import json
4 import re
5 import time
6 import uuid
7
8 from django import template
9 from django.conf import settings
10 from django.core.urlresolvers import reverse
11 from django.db.models.query import QuerySet
12 from django.utils.encoding import force_text
13 from django.utils.http import quote
14 from django.utils.six.moves.urllib import parse as urlparse
15
16 from datetime import datetime, timedelta
17
18 from emissions.models import Emission, Episode, NewsItem, SoundFile, Focus
19 from emissions.utils import period_program
20
21 from panikweb import utils
22 from panikweb import search
23
24 register = template.Library()
25
26 @register.filter(name='zip')
27 def zip_lists(a, b):
28     return zip(a, b)
29
30 @register.inclusion_tag('includes/audio.html', takes_context=True)
31 def audio(context, sound=None, embed=False, display_fragment_name=False):
32     return {
33         'episode': context.get('episode'),
34         'sound': sound,
35         'display_fragment_name': display_fragment_name,
36         'embed': embed,
37     }
38
39 @register.inclusion_tag('listen/nav.html', takes_context=True)
40 def listen_nav(context, date=None, klass=None):
41     return {
42         'class': klass,
43         'categories': context.get('categories'),
44     }
45
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'),
51         'categories': context.get('categories'),
52         'news': context.get('news'),
53         'search_query': context.get('search_query'),
54     }
55
56 @register.inclusion_tag('emissions/nav.html', takes_context=True)
57 def emission_nav(context, date=None, klass=None):
58     return {
59         'class': klass,
60         'categories': context.get('categories'),
61         'episodes': context.get('episodes'),
62         'emission': context.get('emission'),
63         'episode': context.get('episode'),
64         'search_query': context.get('search_query'),
65     }
66
67 @register.inclusion_tag('episodes/inline.html', takes_context=True)
68 def episode_inline(context, date=None, model=None, klass=None):
69     return {
70         'class': klass,
71         'episode': context.get('episode'),
72         'date': date,
73     }
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         'episode': context.get('episode'),
80         'date': date,
81     }
82
83 @register.inclusion_tag('episodes/detail.html', takes_context=True)
84 def episode_detail(context, date=None):
85     soundfiles = SoundFile.objects.select_related().filter(
86             fragment=True, podcastable=True, episode=context.get('episode'))
87     return {
88         'episode': context.get('episode'),
89         'emission': context.get('emission'),
90         'diffusions': context.get('diffusions'),
91         'soundfiles': soundfiles,
92         'date': date,
93         'topik_pages': context.get('topik_pages'),
94     }
95
96 @register.inclusion_tag('emissions/detail.html', takes_context=True)
97 def emission_detail(context, date=None):
98     return {
99         'emission': context.get('emission'),
100         'schedules': context.get('schedules'),
101     }
102
103 @register.inclusion_tag('emissions/resume.html', takes_context=True)
104 def emission_resume(context, date=None):
105     return {
106         'emission': context.get('emission'),
107         'schedules': context.get('schedules'),
108     }
109
110 @register.inclusion_tag('emissions/inline.html', takes_context=True)
111 def emission_inline(context, date=None):
112     return {
113         'emission': context.get('emission'),
114         'schedules': context.get('schedules'),
115     }
116
117 @register.inclusion_tag('soundfiles/resume.html')
118 def soundfile_resume(soundfile, date=None):
119     return {'soundfile': soundfile,
120             'date': date}
121
122 @register.inclusion_tag('includes/player.html', takes_context=True)
123 def player(context):
124
125     return {
126         'unique': uuid.uuid4(),
127         'soundfiles': context.get('soundfiles'),
128     }
129
130 @register.inclusion_tag('includes/metaNav.html', takes_context=True)
131 def metanav(context):
132     try:
133         request_path = context['request'].path
134     except KeyError:
135         # a context without 'requests' may happen when rendering error pages
136         request_path = 'xxx'
137     section = 'About'
138     if request_path == '/':
139         section = 'Home'
140     elif request_path.startswith('/actus/'):
141         section = 'News'
142     elif request_path.startswith('/sons/'):
143         section = 'Listen'
144     elif request_path.startswith('/topiks'):
145         section = 'Topiks'
146     elif request_path.startswith('/emissions') or request_path == '/grille' or request_path == '/programme/':
147         section = 'Emissions'
148     elif request_path == '/recherche/':
149         section = 'Search'
150     return {
151         'LANGUAGE_CODE': context.get('LANGUAGE_CODE'),
152         'sectionName': section,
153         }
154
155 @register.inclusion_tag('includes/week.html')
156 def weekview(year=None, week=None):
157     year = year if year else datetime.today().isocalendar()[0]
158     week = week if week else datetime.today().isocalendar()[1]
159
160     date = utils.tofirstdayinisoweek(year, week)
161     date = datetime(*date.timetuple()[:3])
162
163     program = period_program(date, date+timedelta(days=7))
164     days = []
165     for day in range(7):
166         days.append({'cells': [x for x in program if x.is_on_weekday(day+1)],
167                      'datetime': date+timedelta(days=day)})
168
169     return {
170         'days': days,
171         'week': week,
172         'year': year,
173     }
174
175 @register.inclusion_tag('includes/week-nav.html')
176 def weeknav(year=None, week=None, weekday=None):
177     year = year if year else datetime.today().isocalendar()[0]
178     week = week if week else datetime.today().isocalendar()[1]
179     weekday = weekday if weekday is not None else datetime.today().weekday()
180
181     date = utils.tofirstdayinisoweek(year, week)
182     date = datetime(*date.timetuple()[:3])
183
184     days = []
185     for day in range(7):
186         days.append({'datetime': date+timedelta(days=day)})
187
188     previous_week = date - timedelta(days=7)
189     previous_week_year, previous_week_no = previous_week.isocalendar()[:2]
190
191     next_week = date + timedelta(days=7)
192     next_week_year, next_week_no = next_week.isocalendar()[:2]
193
194     return {
195         'days': days,
196         'weekday': weekday,
197         'week': week,
198         'year': year,
199         'previous_week_year': previous_week_year,
200         'previous_week_no': previous_week_no,
201         'next_week_year': next_week_year,
202         'next_week_no': next_week_no,
203     }
204
205
206 @register.inclusion_tag('news/inline.html', takes_context=True)
207 def news_inline(context, klass=None, logo=None):
208     return {
209             'content': context.get('content'),
210             'class': klass,
211             'logo': logo
212     }
213
214 @register.inclusion_tag('news/roll.html')
215 def newsroll():
216     return {
217         'news': Focus.objects.filter(current=True).select_related('emission', 'newsitem',
218             'soundfile', 'episode', 'newsitem__category').order_by('?')[:3]
219     }
220
221
222 @register.filter
223 def jsonify(object):
224     if isinstance(object, QuerySet):
225         return serialize('json', object)
226     return json.dumps(object)
227
228 @register.filter
229 def strreplace ( string, args ): 
230     find  = args.split(',')[0]
231     replace = args.split(',')[1]
232     return string.replace(find,replace)
233
234 @register.filter
235 def replace ( string, args ): 
236     search  = args.split(args[0])[1]
237     replace = args.split(args[0])[2]
238
239     return re.sub( search, replace, string )
240
241
242 def remove_facet(facet_id, url, facet):
243     scheme, netloc, path, query, fragment = list(urlparse.urlsplit(str(url)))
244     facet = '%s_exact:%s' % (facet_id, facet.encode('utf-8'))
245     query_string = urlparse.parse_qsl(query)
246     query_string = [x for x in query_string if not (
247         x[0] == 'selected_facets' and x[1] == facet)]
248     query = '&'.join(['%s=%s' % x for x in query_string])
249     url = urlparse.urlunsplit([scheme, netloc, path, query, None])
250     return force_text(re.sub(r'&page=\d+', '', url), 'utf-8')
251
252 @register.filter
253 def remove_tag_facet(url, facet):
254     return remove_facet('tags', url, facet)
255
256 @register.filter
257 def remove_category_facet(url, facet):
258     return remove_facet('categories', url, facet)
259
260
261 @register.filter
262 def remove_news_category_facet(url, facet):
263     return remove_facet('news_categories', url, facet)
264
265 @register.filter
266 def remove_format_facet(url, facet):
267     return remove_facet('format', url, facet)
268
269
270 def append_facet(facet_id, url, facet):
271     facet = quote(facet.encode('utf-8'), safe='')
272     if not '?' in url:
273         url = url + '?'
274     return re.sub(r'&page=\d+', '', url + '&selected_facets=%s_exact:%s' % (facet_id, facet))
275
276 @register.filter
277 def append_tag_facet(url, facet):
278     return append_facet('tags', url, facet)
279
280 @register.filter
281 def append_category_facet(url, facet):
282     return append_facet('categories', url, facet)
283
284 @register.filter
285 def append_news_category_facet(url, facet):
286     return append_facet('news_categories', url, facet)
287
288 @register.filter
289 def append_format_facet(url, facet):
290     return append_facet('format', url, facet)
291
292
293 @register.tag
294 def search_result_template(parser, token):
295     try:
296         tag_name, result_str = token.split_contents()
297     except ValueError:
298         raise template.TemplateSyntaxError("%r tag requires exactly one argument" % token.contents.split()[0])
299     return FormatSearchResultNode(result_str)
300
301
302 class FormatSearchResultNode(template.Node):
303     def __init__(self, result_str):
304         self.result_var = template.Variable(result_str)
305
306     def render(self, context):
307         result = self.result_var.resolve(context)
308         dir_mapping = {
309             'newsitem': 'news',
310             'emission': 'emissions',
311             'episode': 'episodes'
312         }
313         t = template.loader.get_template('%s/search_result.html' % dir_mapping.get(result.model_name))
314         return t.render({'result': result})
315
316
317 @register.inclusion_tag('includes/piwik.html')
318 def piwik():
319     return {'enabled': settings.ENABLE_PIWIK}
320
321
322 @register.filter
323 def rfc822(datetime):
324     if datetime is None:
325         return ''
326     return email.utils.formatdate(time.mktime(datetime.timetuple()))
327
328 @register.inclusion_tag('includes/related.html', takes_context=False)
329 def related_objects(object):
330     sqs = search.MoreLikeThisSearchQuerySet().models(Emission, Episode, NewsItem)
331     return {'more_like_this': sqs.more_like_this(object)[:12]}
332
333 @register.inclusion_tag('includes/topik.html', takes_context=True)
334 def topik(context, topik):
335     return {'page': topik}
336
337
338 @register.filter
339 def get_focus_url(object):
340     if object.newsitem:
341         return reverse('newsitem-view', kwargs={'slug': object.newsitem.slug})
342     if object.emission:
343         return reverse('emission-view', kwargs={'slug': object.emission.slug})
344     if object.episode:
345         return reverse('episode-view', kwargs={
346             'slug': object.episode.slug, 'emission_slug': object.episode.emission.slug})
347     if object.soundfile:
348         return reverse('episode-view', kwargs={
349             'slug': object.soundfile.episode.slug,
350             'emission_slug': object.soundfile.episode.emission.slug})
351     if object.page:
352         return object.page.get_online_url()
353     return ''
354
355 @register.filter
356 def facet_tag(tag):
357     return tag.name
358
359
360 @register.filter
361 def set_absolute_urls(text):
362     text = text.replace('src="/', 'src="%s' % settings.WEBSITE_BASE_URL)
363     text = text.replace('href="/', 'href="%s' % settings.WEBSITE_BASE_URL)
364     return text
365
366 @register.filter
367 def as_absolute_url(url):
368     if url.startswith('/'):
369         url = settings.WEBSITE_BASE_URL + url.lstrip('/')
370     return url