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