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 panikweb import utils
22 from panikweb import search
24 register = template.Library()
26 @register.filter(name='zip')
30 @register.inclusion_tag('includes/audio.html', takes_context=True)
31 def audio(context, sound=None, embed=False, display_fragment_name=False):
33 'episode': context.get('episode'),
35 'display_fragment_name': display_fragment_name,
39 @register.inclusion_tag('listen/nav.html', takes_context=True)
40 def listen_nav(context, date=None, klass=None):
43 'categories': context.get('categories'),
46 @register.inclusion_tag('news/nav.html', takes_context=True)
47 def news_nav(context, date=None, klass=None):
50 'newsitem': context.get('newsitem'),
51 'categories': context.get('categories'),
52 'news': context.get('news'),
53 'search_query': context.get('search_query'),
56 @register.inclusion_tag('emissions/nav.html', takes_context=True)
57 def emission_nav(context, date=None, klass=None):
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'),
67 @register.inclusion_tag('episodes/inline.html', takes_context=True)
68 def episode_inline(context, date=None, model=None, klass=None):
71 'episode': context.get('episode'),
74 @register.inclusion_tag('episodes/resume.html', takes_context=True)
75 def episode_resume(context, date=None, model=None, klass=None):
79 'episode': context.get('episode'),
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'))
88 'episode': context.get('episode'),
89 'emission': context.get('emission'),
90 'diffusions': context.get('diffusions'),
91 'soundfiles': soundfiles,
93 'topiks': context.get('topiks'),
96 @register.inclusion_tag('emissions/detail.html', takes_context=True)
97 def emission_detail(context, date=None):
99 'emission': context.get('emission'),
100 'schedules': context.get('schedules'),
103 @register.inclusion_tag('emissions/resume.html', takes_context=True)
104 def emission_resume(context, date=None):
106 'emission': context.get('emission'),
107 'schedules': context.get('schedules'),
110 @register.inclusion_tag('emissions/inline.html', takes_context=True)
111 def emission_inline(context, date=None):
113 'emission': context.get('emission'),
114 'schedules': context.get('schedules'),
117 @register.inclusion_tag('soundfiles/resume.html')
118 def soundfile_resume(soundfile, date=None):
119 return {'soundfile': soundfile,
122 @register.inclusion_tag('includes/player.html', takes_context=True)
126 'unique': uuid.uuid4(),
127 'soundfiles': context.get('soundfiles'),
130 @register.inclusion_tag('includes/metaNav.html', takes_context=True)
131 def metanav(context):
133 request_path = context['request'].path
135 # a context without 'requests' may happen when rendering error pages
138 if request_path == '/':
140 elif request_path.startswith('/actus/'):
142 elif request_path.startswith('/sons/'):
144 elif request_path.startswith('/topiks'):
146 elif request_path.startswith('/emissions') or request_path == '/grille' or request_path == '/programme/':
147 section = 'Emissions'
148 elif request_path == '/recherche/':
151 'LANGUAGE_CODE': context.get('LANGUAGE_CODE'),
152 'sectionName': section,
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]
160 date = utils.tofirstdayinisoweek(year, week)
161 date = datetime(*date.timetuple()[:3])
163 program = period_program(date, date+timedelta(days=7))
166 days.append({'cells': [x for x in program if x.is_on_weekday(day+1)],
167 'datetime': date+timedelta(days=day)})
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()
181 date = utils.tofirstdayinisoweek(year, week)
182 date = datetime(*date.timetuple()[:3])
186 days.append({'datetime': date+timedelta(days=day)})
188 previous_week = date - timedelta(days=7)
189 previous_week_year, previous_week_no = previous_week.isocalendar()[:2]
191 next_week = date + timedelta(days=7)
192 next_week_year, next_week_no = next_week.isocalendar()[:2]
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,
206 @register.inclusion_tag('news/inline.html', takes_context=True)
207 def news_inline(context, klass=None, logo=None):
209 'content': context.get('content'),
214 @register.inclusion_tag('news/roll.html')
217 'news': Focus.objects.filter(current=True).select_related('emission', 'newsitem',
218 'soundfile', 'episode', 'newsitem__category').order_by('?')[:3]
224 if isinstance(object, QuerySet):
225 return serialize('json', object)
226 return json.dumps(object)
229 def strreplace ( string, args ):
230 find = args.split(',')[0]
231 replace = args.split(',')[1]
232 return string.replace(find,replace)
235 def replace ( string, args ):
236 search = args.split(args[0])[1]
237 replace = args.split(args[0])[2]
239 return re.sub( search, replace, string )
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')
253 def remove_tag_facet(url, facet):
254 return remove_facet('tags', url, facet)
257 def remove_category_facet(url, facet):
258 return remove_facet('categories', url, facet)
262 def remove_news_category_facet(url, facet):
263 return remove_facet('news_categories', url, facet)
266 def remove_format_facet(url, facet):
267 return remove_facet('format', url, facet)
270 def append_facet(facet_id, url, facet):
271 facet = quote(facet.encode('utf-8'), safe='')
274 return re.sub(r'&page=\d+', '', url + '&selected_facets=%s_exact:%s' % (facet_id, facet))
277 def append_tag_facet(url, facet):
278 return append_facet('tags', url, facet)
281 def append_category_facet(url, facet):
282 return append_facet('categories', url, facet)
285 def append_news_category_facet(url, facet):
286 return append_facet('news_categories', url, facet)
289 def append_format_facet(url, facet):
290 return append_facet('format', url, facet)
294 def search_result_template(parser, token):
296 tag_name, result_str = token.split_contents()
298 raise template.TemplateSyntaxError("%r tag requires exactly one argument" % token.contents.split()[0])
299 return FormatSearchResultNode(result_str)
302 class FormatSearchResultNode(template.Node):
303 def __init__(self, result_str):
304 self.result_var = template.Variable(result_str)
306 def render(self, context):
307 result = self.result_var.resolve(context)
310 'emission': 'emissions',
311 'episode': 'episodes'
313 t = template.loader.get_template('%s/search_result.html' % dir_mapping.get(result.model_name))
314 return t.render({'result': result})
317 @register.inclusion_tag('includes/piwik.html')
319 return {'enabled': settings.ENABLE_PIWIK}
323 def rfc822(datetime):
326 return email.utils.formatdate(time.mktime(datetime.timetuple()))
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]}
333 @register.inclusion_tag('includes/topik.html', takes_context=True)
334 def topik(context, topik):
335 return {'topik': topik}
338 def get_focus_url(object):
340 return reverse('newsitem-view', kwargs={'slug': object.newsitem.slug})
342 return reverse('emission-view', kwargs={'slug': object.emission.slug})
344 return reverse('episode-view', kwargs={
345 'slug': object.episode.slug, 'emission_slug': object.episode.emission.slug})
347 return reverse('episode-view', kwargs={
348 'slug': object.soundfile.episode.slug,
349 'emission_slug': object.soundfile.episode.emission.slug})
351 return object.page.get_online_url()
360 def set_absolute_urls(text):
361 text = text.replace('src="/', 'src="%s' % settings.WEBSITE_BASE_URL)
362 text = text.replace('href="/', 'href="%s' % settings.WEBSITE_BASE_URL)
366 def as_absolute_url(url):
367 if url.startswith('/'):
368 url = settings.WEBSITE_BASE_URL + url.lstrip('/')