1 from __future__
import division
3 from itertools
import imap
as map
6 from django
.http
import HttpResponseNotFound
, Http404
, HttpResponseRedirect
7 from django
.core
.urlresolvers
import reverse
8 from django
.shortcuts
import render
9 from django
.contrib
.sites
.models
import RequestSite
10 from django
.views
.decorators
.cache
import cache_control
11 from django
.views
.decorators
.vary
import vary_on_cookie
12 from django
.utils
.decorators
import method_decorator
13 from django
.views
.generic
.base
import View
, TemplateView
14 from django
.contrib
.auth
.decorators
import login_required
15 from django
.contrib
import messages
16 from django
.utils
.translation
import ugettext
as _
18 from feedservice
.parse
.models
import ParserException
19 from feedservice
.parse
import FetchFeedException
21 from mygpo
.core
.proxy
import proxy_object
22 from mygpo
.directory
.toplist
import PodcastToplist
, EpisodeToplist
, \
24 from mygpo
.directory
.search
import search_podcasts
25 from mygpo
.web
.utils
import process_lang_params
, get_language_names
, \
26 get_page_list
, get_podcast_link_target
27 from mygpo
.directory
.tags
import Topics
28 from mygpo
.users
.models
import User
29 from mygpo
.users
.settings
import FLATTR_TOKEN
30 from mygpo
.data
.feeddownloader
import PodcastUpdater
, NoEpisodesException
31 from mygpo
.data
.tasks
import update_podcasts
32 from mygpo
.db
.couchdb
.podcast
import get_podcast_languages
, podcasts_by_id
, \
33 random_podcasts
, podcasts_to_dict
, podcast_for_url
, \
34 get_flattr_podcasts
, get_flattr_podcast_count
35 from mygpo
.db
.couchdb
.directory
import category_for_tag
36 from mygpo
.db
.couchdb
.podcastlist
import random_podcastlists
, \
37 podcastlist_count
, podcastlists_by_rating
41 @cache_control(private
=True)
42 def toplist(request
, num
=100, lang
=None):
44 lang
= process_lang_params(request
)
46 toplist
= PodcastToplist(lang
)
47 entries
= toplist
[:num
]
49 max_subscribers
= max([p
.subscriber_count() for (oldp
, p
) in entries
]) if entries
else 0
50 current_site
= RequestSite(request
)
52 languages
= get_podcast_languages()
53 all_langs
= get_language_names(languages
)
55 return render(request
, 'toplist.html', {
57 'max_subscribers': max_subscribers
,
60 'all_languages': all_langs
,
65 """ A carousel demo """
67 @method_decorator(cache_control(private
=True))
68 @method_decorator(vary_on_cookie
)
69 def get(self
, request
):
71 return render(request
, 'carousel.html', {
72 # evaluated lazyly, cached by template
77 class Directory(View
):
78 """ The main directory page """
80 @method_decorator(cache_control(private
=True))
81 @method_decorator(vary_on_cookie
)
82 def get(self
, request
):
84 return render(request
, 'directory.html', {
86 # evaluated lazyly, cached by template
88 'trending_podcasts': TrendingPodcasts(''),
89 'podcastlists': self
.get_random_list(),
90 'random_podcasts': self
.get_random_podcast(),
94 def get_random_list(self
, podcasts_per_list
=5):
95 random_list
= next(random_podcastlists(), None)
98 random_list
= proxy_object(random_list
)
99 random_list
.more_podcasts
= max(0, len(random_list
.podcasts
) - podcasts_per_list
)
100 random_list
.podcasts
= podcasts_by_id(random_list
.podcasts
[:podcasts_per_list
])
101 random_list
.user
= User
.get(random_list
.user
)
105 def get_random_podcast(self
):
106 random_podcast
= next(random_podcasts(), None)
108 yield random_podcast
.get_podcast()
111 @cache_control(private
=True)
113 def category(request
, category
, page_size
=20):
114 category
= category_for_tag(category
)
116 return HttpResponseNotFound()
118 # Make sure page request is an int. If not, deliver first page.
120 page
= int(request
.GET
.get('page', '1'))
124 entries
= category
.get_podcasts( (page
-1) * page_size
, page
*page_size
)
125 podcasts
= filter(None, entries
)
126 num_pages
= int(ceil(len(category
.podcasts
) / page_size
))
128 page_list
= get_page_list(1, num_pages
, page
, 15)
130 return render(request
, 'category.html', {
132 'category': category
.label
,
133 'page_list': page_list
,
140 @cache_control(private
=True)
142 def search(request
, template
='search.html', args
={}):
144 if 'q' in request
.GET
:
145 q
= request
.GET
.get('q', '').encode('utf-8')
148 page
= int(request
.GET
.get('page', 1))
152 results
, total
= search_podcasts(q
=q
, skip
=RESULTS_PER_PAGE
*(page
-1))
153 num_pages
= int(ceil(total
/ RESULTS_PER_PAGE
))
155 page_list
= get_page_list(1, num_pages
, page
, 15)
162 max_subscribers
= max([p
.subscriber_count() for p
in results
] + [0])
163 current_site
= RequestSite(request
)
165 return render(request
, template
, dict(
168 page_list
= page_list
,
169 max_subscribers
= max_subscribers
,
170 domain
= current_site
.domain
,
175 @cache_control(private
=True)
177 def episode_toplist(request
, num
=100):
178 lang
= process_lang_params(request
)
180 toplist
= EpisodeToplist(language
=lang
)
181 entries
= list(map(proxy_object
, toplist
[:num
]))
183 # load podcast objects
184 podcast_ids
= [e
.podcast
for e
in entries
]
185 podcasts
= podcasts_to_dict(podcast_ids
, True)
186 for entry
in entries
:
187 entry
.podcast
= podcasts
.get(entry
.podcast
, None)
189 current_site
= RequestSite(request
)
191 # Determine maximum listener amount (or 0 if no entries exist)
192 max_listeners
= max([0]+[e
.listeners
for e
in entries
])
194 languages
= get_podcast_languages()
195 all_langs
= get_language_names(languages
)
197 return render(request
, 'episode_toplist.html', {
199 'max_listeners': max_listeners
,
202 'all_languages': all_langs
,
206 @cache_control(private
=True)
208 def podcast_lists(request
, page_size
=20):
210 # Make sure page request is an int. If not, deliver first page.
212 page
= int(request
.GET
.get('page', '1'))
216 lists
= podcastlists_by_rating(skip
=(page
-1) * page_size
, limit
=page_size
)
219 def _prepare_list(l
):
220 user
= User
.get(l
.user
)
222 l
.username
= user
.username
225 lists
= map(_prepare_list
, lists
)
227 num_pages
= int(ceil(podcastlist_count() / float(page_size
)))
229 page_list
= get_page_list(1, num_pages
, page
, 15)
231 return render(request
, 'podcast_lists.html', {
233 'page_list': page_list
,
238 class MissingPodcast(View
):
239 """ Check if a podcast is missing """
241 @method_decorator(login_required
)
242 def get(self
, request
):
244 site
= RequestSite(request
)
246 # check if we're doing a query
247 url
= request
.GET
.get('q', None)
254 podcast
= podcast_for_url(url
)
256 # if the podcast does already exist, there's nothing more to do
260 # check if we could add a podcast for the given URL
263 updater
= PodcastUpdater()
266 can_add
= updater
.verify_podcast_url(url
)
268 except (ParserException
, FetchFeedException
,
269 NoEpisodesException
) as ex
:
271 messages
.error(request
, str(ex
))
273 return render(request
, 'missing.html', {
281 class AddPodcast(View
):
282 """ Add a missing podcast"""
284 @method_decorator(login_required
)
285 @method_decorator(cache_control(private
=True))
286 @method_decorator(vary_on_cookie
)
287 def post(self
, request
):
289 url
= request
.POST
.get('url', None)
294 res
= update_podcasts
.delay([url
])
296 return HttpResponseRedirect(reverse('add-podcast-status',
300 class AddPodcastStatus(TemplateView
):
301 """ Status of adding a podcast """
303 template_name
= 'directory/add-podcast-status.html'
305 def get(self
, request
, task_id
):
306 result
= update_podcasts
.AsyncResult(task_id
)
308 if not result
.ready():
309 return self
.render_to_response({
314 podcasts
= result
.get()
315 messages
.success(request
, _('%d podcasts added' % len(podcasts
)))
317 except (ParserException
, FetchFeedException
,
318 NoEpisodesException
) as ex
:
319 messages
.error(request
, str(ex
))
322 return self
.render_to_response({
324 'podcasts': podcasts
,
329 class FlattrPodcastList(View
):
330 """ Lists podcasts that have Flattr payment URLs """
332 @method_decorator(cache_control(private
=True))
333 @method_decorator(vary_on_cookie
)
334 def get(self
, request
, page_size
=20):
336 # Make sure page request is an int. If not, deliver first page.
338 page
= int(request
.GET
.get('page', '1'))
342 podcasts
= get_flattr_podcasts( (page
-1) * page_size
, page_size
)
343 podcast_count
= get_flattr_podcast_count()
344 num_pages
= int(ceil(podcast_count
/ page_size
))
345 page_list
= get_page_list(1, num_pages
, page
, 15)
347 max_subscribers
= max([p
.subscriber_count() for p
in podcasts
] + [0])
350 flattr_auth
= user
.is_authenticated() and bool(user
.get_wksetting(FLATTR_TOKEN
))
352 return render(request
, 'flattr-podcasts.html', {
353 'podcasts': podcasts
,
354 'page_list': page_list
,
355 'current_page': page
,
356 'flattr_auth': flattr_auth
,
357 'max_subscribers': max_subscribers
,