]> git.0d.be Git - panikweb.git/blob - panikweb/paniktags/templatetags/paniktags.py
topiks: use a flat list for pages
[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 urlparse
7 import urllib2
8 import uuid
9
10 from django import template
11 from django.conf import settings
12 from django.core.urlresolvers import reverse
13 from django.db.models.query import QuerySet
14 from datetime import datetime, timedelta
15
16 from emissions.models import Emission, Episode, NewsItem, SoundFile, Focus
17 from emissions.utils import period_program
18
19 from panikombo.models import Topik
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         'topiks': context.get('topiks'),
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, active=None):
132     request_path = context['request'].path
133     section = 'About'
134     if request_path == '/':
135         section = 'Home'
136     elif request_path.startswith('/actus/'):
137         section = 'News'
138     elif request_path.startswith('/sons/'):
139         section = 'Listen'
140     elif request_path.startswith('/topiks'):
141         section = 'Topiks'
142     elif request_path.startswith('/emissions') or request_path == '/grille' or request_path == '/programme/':
143         section = 'Emissions'
144     elif request_path == '/recherche/':
145         section = 'Search'
146     return {
147         'LANGUAGE_CODE': context.get('LANGUAGE_CODE'),
148         'sectionName': section,
149         }
150
151 @register.inclusion_tag('includes/week.html')
152 def weekview(year=None, week=None):
153     year = year if year else datetime.today().isocalendar()[0]
154     week = week if week else datetime.today().isocalendar()[1]
155
156     date = utils.tofirstdayinisoweek(year, week)
157     date = datetime(*date.timetuple()[:3])
158
159     program = period_program(date, date+timedelta(days=7))
160     days = []
161     for day in range(7):
162         days.append({'cells': [x for x in program if x.is_on_weekday(day+1)],
163                      'datetime': date+timedelta(days=day)})
164
165     return {
166         'days': days,
167         'week': week,
168         'year': year,
169     }
170
171 @register.inclusion_tag('includes/week-nav.html')
172 def weeknav(year=None, week=None, weekday=None):
173     year = year if year else datetime.today().isocalendar()[0]
174     week = week if week else datetime.today().isocalendar()[1]
175     weekday = weekday if weekday is not None else datetime.today().weekday()
176
177     date = utils.tofirstdayinisoweek(year, week)
178     date = datetime(*date.timetuple()[:3])
179
180     days = []
181     for day in range(7):
182         days.append({'datetime': date+timedelta(days=day)})
183
184     previous_week = date - timedelta(days=7)
185     previous_week_year, previous_week_no = previous_week.isocalendar()[:2]
186
187     next_week = date + timedelta(days=7)
188     next_week_year, next_week_no = next_week.isocalendar()[:2]
189
190     return {
191         'days': days,
192         'weekday': weekday,
193         'week': week,
194         'year': year,
195         'previous_week_year': previous_week_year,
196         'previous_week_no': previous_week_no,
197         'next_week_year': next_week_year,
198         'next_week_no': next_week_no,
199     }
200
201
202 @register.inclusion_tag('news/inline.html', takes_context=True)
203 def news_inline(context, klass=None, logo=None):
204     return {
205             'content': context.get('content'),
206             'class': klass,
207             'logo': logo
208     }
209
210 @register.inclusion_tag('news/roll.html')
211 def newsroll():
212     return {
213         'news': Focus.objects.filter(current=True).select_related('emission', 'newsitem',
214             'soundfile', 'episode', 'newsitem__category').order_by('?')[:3]
215     }
216
217
218 @register.filter
219 def jsonify(object):
220     if isinstance(object, QuerySet):
221         return serialize('json', object)
222     return json.dumps(object)
223
224 @register.filter
225 def strreplace ( string, args ): 
226     find  = args.split(',')[0]
227     replace = args.split(',')[1]
228     return string.replace(find,replace)
229
230 @register.filter
231 def replace ( string, args ): 
232     search  = args.split(args[0])[1]
233     replace = args.split(args[0])[2]
234
235     return re.sub( search, replace, string )
236
237
238 def remove_facet(facet_id, url, facet):
239     scheme, netloc, path, query, fragment = list(urlparse.urlsplit(str(url)))
240     facet = '%s_exact:%s' % (facet_id, facet.encode('utf-8'))
241     query_string = urlparse.parse_qsl(query)
242     query_string = [x for x in query_string if not (
243         x[0] == 'selected_facets' and x[1] == facet)]
244     query = '&'.join(['%s=%s' % x for x in query_string])
245     url = urlparse.urlunsplit([scheme, netloc, path, query, None])
246     return re.sub(r'&page=\d+', '', url)
247
248 @register.filter
249 def remove_tag_facet(url, facet):
250     return remove_facet('tags', url, facet)
251
252 @register.filter
253 def remove_category_facet(url, facet):
254     return remove_facet('categories', url, facet)
255
256
257 @register.filter
258 def remove_news_category_facet(url, facet):
259     return remove_facet('news_categories', url, facet)
260
261 @register.filter
262 def remove_format_facet(url, facet):
263     return remove_facet('format', url, facet)
264
265
266 def append_facet(facet_id, url, facet):
267     facet = urllib2.quote(facet.encode('utf-8'), safe='')
268     if not '?' in url:
269         url = url + '?'
270     return re.sub(r'&page=\d+', '', url + '&selected_facets=%s_exact:%s' % (facet_id, facet))
271
272 @register.filter
273 def append_tag_facet(url, facet):
274     return append_facet('tags', url, facet)
275
276 @register.filter
277 def append_category_facet(url, facet):
278     return append_facet('categories', url, facet)
279
280 @register.filter
281 def append_news_category_facet(url, facet):
282     return append_facet('news_categories', url, facet)
283
284 @register.filter
285 def append_format_facet(url, facet):
286     return append_facet('format', url, facet)
287
288
289 @register.tag
290 def search_result_template(parser, token):
291     try:
292         tag_name, result_str = token.split_contents()
293     except ValueError:
294         raise template.TemplateSyntaxError("%r tag requires exactly one argument" % token.contents.split()[0])
295     return FormatSearchResultNode(result_str)
296
297
298 class FormatSearchResultNode(template.Node):
299     def __init__(self, result_str):
300         self.result_var = template.Variable(result_str)
301
302     def render(self, context):
303         result = self.result_var.resolve(context)
304         dir_mapping = {
305             'newsitem': 'news',
306             'emission': 'emissions',
307             'episode': 'episodes'
308         }
309         t = template.loader.get_template('%s/search_result.html' % dir_mapping.get(result.model_name))
310         return t.render(template.context.Context({'result': result}, autoescape=context.autoescape))
311
312
313 @register.inclusion_tag('includes/piwik.html')
314 def piwik():
315     return {'enabled': settings.ENABLE_PIWIK}
316
317
318 @register.filter
319 def rfc822(datetime):
320     if datetime is None:
321         return ''
322     return email.utils.formatdate(time.mktime(datetime.timetuple()))
323
324 @register.inclusion_tag('includes/related.html', takes_context=False)
325 def related_objects(object):
326     sqs = search.MoreLikeThisSearchQuerySet().models(Emission, Episode, NewsItem)
327     return {'more_like_this': sqs.more_like_this(object)[:12]}
328
329 @register.inclusion_tag('includes/topik.html', takes_context=True)
330 def topik(context, topik):
331     return {'topik': topik}
332
333 @register.filter
334 def get_focus_url(object):
335     if object.newsitem:
336         return reverse('newsitem-view', kwargs={'slug': object.newsitem.slug})
337     if object.emission:
338         return reverse('emission-view', kwargs={'slug': object.emission.slug})
339     if object.episode:
340         return reverse('episode-view', kwargs={
341             'slug': object.episode.slug, 'emission_slug': object.episode.emission.slug})
342     if object.soundfile:
343         return reverse('episode-view', kwargs={
344             'slug': object.soundfile.episode.slug,
345             'emission_slug': object.soundfile.episode.emission.slug})
346     if object.page:
347         return object.page.get_online_url()
348     return ''
349
350 @register.filter
351 def facet_tag(tag):
352     return tag.name
353
354
355 @register.filter
356 def image_file(page):
357     try:
358         matching_topik = Topik.objects.get(page=page)
359         return matching_topik.image
360     except Topik.DoesNotExist:
361         pass
362     return None