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
16 from datetime import datetime, timedelta
18 from emissions.models import Emission, Episode, NewsItem, SoundFile, Focus
19 from emissions.utils import period_program
21 from panikombo.models import Topik
23 from panikweb import utils
24 from panikweb import search
26 register = template.Library()
28 @register.filter(name='zip')
32 @register.inclusion_tag('includes/audio.html', takes_context=True)
33 def audio(context, sound=None, embed=False, display_fragment_name=False):
35 'episode': context.get('episode'),
37 'display_fragment_name': display_fragment_name,
41 @register.inclusion_tag('listen/nav.html', takes_context=True)
42 def listen_nav(context, date=None, klass=None):
45 'categories': context.get('categories'),
48 @register.inclusion_tag('news/nav.html', takes_context=True)
49 def news_nav(context, date=None, klass=None):
52 'newsitem': context.get('newsitem'),
53 'categories': context.get('categories'),
54 'news': context.get('news'),
55 'search_query': context.get('search_query'),
58 @register.inclusion_tag('emissions/nav.html', takes_context=True)
59 def emission_nav(context, date=None, klass=None):
62 'categories': context.get('categories'),
63 'episodes': context.get('episodes'),
64 'emission': context.get('emission'),
65 'episode': context.get('episode'),
66 'search_query': context.get('search_query'),
69 @register.inclusion_tag('episodes/inline.html', takes_context=True)
70 def episode_inline(context, date=None, model=None, klass=None):
73 'episode': context.get('episode'),
76 @register.inclusion_tag('episodes/resume.html', takes_context=True)
77 def episode_resume(context, date=None, model=None, klass=None):
81 'episode': context.get('episode'),
85 @register.inclusion_tag('episodes/detail.html', takes_context=True)
86 def episode_detail(context, date=None):
87 soundfiles = SoundFile.objects.select_related().filter(
88 fragment=True, podcastable=True, episode=context.get('episode'))
90 'episode': context.get('episode'),
91 'emission': context.get('emission'),
92 'diffusions': context.get('diffusions'),
93 'soundfiles': soundfiles,
95 'topiks': context.get('topiks'),
98 @register.inclusion_tag('emissions/detail.html', takes_context=True)
99 def emission_detail(context, date=None):
101 'emission': context.get('emission'),
102 'schedules': context.get('schedules'),
105 @register.inclusion_tag('emissions/resume.html', takes_context=True)
106 def emission_resume(context, date=None):
108 'emission': context.get('emission'),
109 'schedules': context.get('schedules'),
112 @register.inclusion_tag('emissions/inline.html', takes_context=True)
113 def emission_inline(context, date=None):
115 'emission': context.get('emission'),
116 'schedules': context.get('schedules'),
119 @register.inclusion_tag('soundfiles/resume.html')
120 def soundfile_resume(soundfile, date=None):
121 return {'soundfile': soundfile,
124 @register.inclusion_tag('includes/player.html', takes_context=True)
128 'unique': uuid.uuid4(),
129 'soundfiles': context.get('soundfiles'),
132 @register.inclusion_tag('includes/metaNav.html', takes_context=True)
133 def metanav(context, active=None):
134 request_path = context['request'].path
136 if request_path == '/':
138 elif request_path.startswith('/actus/'):
140 elif request_path.startswith('/sons/'):
142 elif request_path.startswith('/topiks'):
144 elif request_path.startswith('/emissions') or request_path == '/grille' or request_path == '/programme/':
145 section = 'Emissions'
146 elif request_path == '/recherche/':
149 'LANGUAGE_CODE': context.get('LANGUAGE_CODE'),
150 'sectionName': section,
153 @register.inclusion_tag('includes/week.html')
154 def weekview(year=None, week=None):
155 year = year if year else datetime.today().isocalendar()[0]
156 week = week if week else datetime.today().isocalendar()[1]
158 date = utils.tofirstdayinisoweek(year, week)
159 date = datetime(*date.timetuple()[:3])
161 program = period_program(date, date+timedelta(days=7))
164 days.append({'cells': [x for x in program if x.is_on_weekday(day+1)],
165 'datetime': date+timedelta(days=day)})
173 @register.inclusion_tag('includes/week-nav.html')
174 def weeknav(year=None, week=None, weekday=None):
175 year = year if year else datetime.today().isocalendar()[0]
176 week = week if week else datetime.today().isocalendar()[1]
177 weekday = weekday if weekday is not None else datetime.today().weekday()
179 date = utils.tofirstdayinisoweek(year, week)
180 date = datetime(*date.timetuple()[:3])
184 days.append({'datetime': date+timedelta(days=day)})
186 previous_week = date - timedelta(days=7)
187 previous_week_year, previous_week_no = previous_week.isocalendar()[:2]
189 next_week = date + timedelta(days=7)
190 next_week_year, next_week_no = next_week.isocalendar()[:2]
197 'previous_week_year': previous_week_year,
198 'previous_week_no': previous_week_no,
199 'next_week_year': next_week_year,
200 'next_week_no': next_week_no,
204 @register.inclusion_tag('news/inline.html', takes_context=True)
205 def news_inline(context, klass=None, logo=None):
207 'content': context.get('content'),
212 @register.inclusion_tag('news/roll.html')
215 'news': Focus.objects.filter(current=True).select_related('emission', 'newsitem',
216 'soundfile', 'episode', 'newsitem__category').order_by('?')[:3]
222 if isinstance(object, QuerySet):
223 return serialize('json', object)
224 return json.dumps(object)
227 def strreplace ( string, args ):
228 find = args.split(',')[0]
229 replace = args.split(',')[1]
230 return string.replace(find,replace)
233 def replace ( string, args ):
234 search = args.split(args[0])[1]
235 replace = args.split(args[0])[2]
237 return re.sub( search, replace, string )
240 def remove_facet(facet_id, url, facet):
241 scheme, netloc, path, query, fragment = list(urlparse.urlsplit(str(url)))
242 facet = '%s_exact:%s' % (facet_id, facet.encode('utf-8'))
243 query_string = urlparse.parse_qsl(query)
244 query_string = [x for x in query_string if not (
245 x[0] == 'selected_facets' and x[1] == facet)]
246 query = '&'.join(['%s=%s' % x for x in query_string])
247 url = urlparse.urlunsplit([scheme, netloc, path, query, None])
248 return force_text(re.sub(r'&page=\d+', '', url), 'utf-8')
251 def remove_tag_facet(url, facet):
252 return remove_facet('tags', url, facet)
255 def remove_category_facet(url, facet):
256 return remove_facet('categories', url, facet)
260 def remove_news_category_facet(url, facet):
261 return remove_facet('news_categories', url, facet)
264 def remove_format_facet(url, facet):
265 return remove_facet('format', url, facet)
268 def append_facet(facet_id, url, facet):
269 facet = quote(facet.encode('utf-8'), safe='')
272 return re.sub(r'&page=\d+', '', url + '&selected_facets=%s_exact:%s' % (facet_id, facet))
275 def append_tag_facet(url, facet):
276 return append_facet('tags', url, facet)
279 def append_category_facet(url, facet):
280 return append_facet('categories', url, facet)
283 def append_news_category_facet(url, facet):
284 return append_facet('news_categories', url, facet)
287 def append_format_facet(url, facet):
288 return append_facet('format', url, facet)
292 def search_result_template(parser, token):
294 tag_name, result_str = token.split_contents()
296 raise template.TemplateSyntaxError("%r tag requires exactly one argument" % token.contents.split()[0])
297 return FormatSearchResultNode(result_str)
300 class FormatSearchResultNode(template.Node):
301 def __init__(self, result_str):
302 self.result_var = template.Variable(result_str)
304 def render(self, context):
305 result = self.result_var.resolve(context)
308 'emission': 'emissions',
309 'episode': 'episodes'
311 t = template.loader.get_template('%s/search_result.html' % dir_mapping.get(result.model_name))
312 return t.render({'result': result})
315 @register.inclusion_tag('includes/piwik.html')
317 return {'enabled': settings.ENABLE_PIWIK}
321 def rfc822(datetime):
324 return email.utils.formatdate(time.mktime(datetime.timetuple()))
326 @register.inclusion_tag('includes/related.html', takes_context=False)
327 def related_objects(object):
328 sqs = search.MoreLikeThisSearchQuerySet().models(Emission, Episode, NewsItem)
329 return {'more_like_this': sqs.more_like_this(object)[:12]}
331 @register.inclusion_tag('includes/topik.html', takes_context=True)
332 def topik(context, topik):
333 return {'topik': topik}
336 def get_focus_url(object):
338 return reverse('newsitem-view', kwargs={'slug': object.newsitem.slug})
340 return reverse('emission-view', kwargs={'slug': object.emission.slug})
342 return reverse('episode-view', kwargs={
343 'slug': object.episode.slug, 'emission_slug': object.episode.emission.slug})
345 return reverse('episode-view', kwargs={
346 'slug': object.soundfile.episode.slug,
347 'emission_slug': object.soundfile.episode.emission.slug})
349 return object.page.get_online_url()
358 def image_file(page):
360 matching_topik = Topik.objects.get(page=page)
361 return matching_topik.image
362 except Topik.DoesNotExist:
368 def set_absolute_urls(text):
369 text = text.replace('src="/', 'src="%s' % settings.WEBSITE_BASE_URL)
370 text = text.replace('href="/', 'href="%s' % settings.WEBSITE_BASE_URL)
374 def as_absolute_url(url):
375 if url.startswith('/'):
376 url = settings.WEBSITE_BASE_URL + url.lstrip('/')