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
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
.db
.couchdb
.podcast
import get_podcast_languages
, podcasts_by_id
, \
32 random_podcasts
, podcasts_to_dict
, podcast_for_url
, \
33 get_flattr_podcasts
, get_flattr_podcast_count
34 from mygpo
.db
.couchdb
.directory
import category_for_tag
35 from mygpo
.db
.couchdb
.podcastlist
import random_podcastlists
, \
36 podcastlist_count
, podcastlists_by_rating
40 @cache_control(private
=True)
41 def toplist(request
, num
=100, lang
=None):
43 lang
= process_lang_params(request
)
45 toplist
= PodcastToplist(lang
)
46 entries
= toplist
[:num
]
48 max_subscribers
= max([p
.subscriber_count() for (oldp
, p
) in entries
]) if entries
else 0
49 current_site
= RequestSite(request
)
51 languages
= get_podcast_languages()
52 all_langs
= get_language_names(languages
)
54 return render(request
, 'toplist.html', {
56 'max_subscribers': max_subscribers
,
59 'all_languages': all_langs
,
64 """ A carousel demo """
66 @method_decorator(cache_control(private
=True))
67 @method_decorator(vary_on_cookie
)
68 def get(self
, request
):
70 return render(request
, 'carousel.html', {
71 # evaluated lazyly, cached by template
76 class Directory(View
):
77 """ The main directory page """
79 @method_decorator(cache_control(private
=True))
80 @method_decorator(vary_on_cookie
)
81 def get(self
, request
):
83 return render(request
, 'directory.html', {
85 # evaluated lazyly, cached by template
87 'trending_podcasts': TrendingPodcasts(''),
88 'podcastlists': self
.get_random_list(),
89 'random_podcasts': self
.get_random_podcast(),
93 def get_random_list(self
, podcasts_per_list
=5):
94 random_list
= next(random_podcastlists(), None)
97 random_list
= proxy_object(random_list
)
98 random_list
.more_podcasts
= max(0, len(random_list
.podcasts
) - podcasts_per_list
)
99 random_list
.podcasts
= podcasts_by_id(random_list
.podcasts
[:podcasts_per_list
])
100 random_list
.user
= User
.get(random_list
.user
)
104 def get_random_podcast(self
):
105 random_podcast
= next(random_podcasts(), None)
107 yield random_podcast
.get_podcast()
110 @cache_control(private
=True)
112 def category(request
, category
, page_size
=20):
113 category
= category_for_tag(category
)
115 return HttpResponseNotFound()
117 # Make sure page request is an int. If not, deliver first page.
119 page
= int(request
.GET
.get('page', '1'))
123 entries
= category
.get_podcasts( (page
-1) * page_size
, page
*page_size
)
124 podcasts
= filter(None, entries
)
125 num_pages
= ceil(len(category
.podcasts
) / page_size
)
127 page_list
= get_page_list(1, num_pages
, page
, 15)
129 return render(request
, 'category.html', {
131 'category': category
.label
,
132 'page_list': page_list
,
139 @cache_control(private
=True)
141 def search(request
, template
='search.html', args
={}):
143 if 'q' in request
.GET
:
144 q
= request
.GET
.get('q', '').encode('utf-8')
147 page
= int(request
.GET
.get('page', 1))
151 results
, total
= search_podcasts(q
=q
, skip
=RESULTS_PER_PAGE
*(page
-1))
152 num_pages
= ceil(total
/ RESULTS_PER_PAGE
)
154 page_list
= get_page_list(1, num_pages
, page
, 15)
161 max_subscribers
= max([p
.subscriber_count() for p
in results
] + [0])
162 current_site
= RequestSite(request
)
164 return render(request
, template
, dict(
167 page_list
= page_list
,
168 max_subscribers
= max_subscribers
,
169 domain
= current_site
.domain
,
174 @cache_control(private
=True)
176 def episode_toplist(request
, num
=100):
177 lang
= process_lang_params(request
)
179 toplist
= EpisodeToplist(language
=lang
)
180 entries
= list(map(proxy_object
, toplist
[:num
]))
182 # load podcast objects
183 podcast_ids
= [e
.podcast
for e
in entries
]
184 podcasts
= podcasts_to_dict(podcast_ids
, True)
185 for entry
in entries
:
186 entry
.podcast
= podcasts
.get(entry
.podcast
, None)
188 current_site
= RequestSite(request
)
190 # Determine maximum listener amount (or 0 if no entries exist)
191 max_listeners
= max([0]+[e
.listeners
for e
in entries
])
193 languages
= get_podcast_languages()
194 all_langs
= get_language_names(languages
)
196 return render(request
, 'episode_toplist.html', {
198 'max_listeners': max_listeners
,
201 'all_languages': all_langs
,
205 @cache_control(private
=True)
207 def podcast_lists(request
, page_size
=20):
209 # Make sure page request is an int. If not, deliver first page.
211 page
= int(request
.GET
.get('page', '1'))
215 lists
= podcastlists_by_rating(skip
=(page
-1) * page_size
, limit
=page_size
)
218 def _prepare_list(l
):
219 user
= User
.get(l
.user
)
221 l
.username
= user
.username
224 lists
= map(_prepare_list
, lists
)
226 num_pages
= int(ceil(podcastlist_count() / float(page_size
)))
228 page_list
= get_page_list(1, num_pages
, page
, 15)
230 return render(request
, 'podcast_lists.html', {
232 'page_list': page_list
,
237 class MissingPodcast(View
):
238 """ Check if a podcast is missing """
240 @method_decorator(login_required
)
241 def get(self
, request
):
243 site
= RequestSite(request
)
245 # check if we're doing a query
246 url
= request
.GET
.get('q', None)
253 podcast
= podcast_for_url(url
)
255 # if the podcast does already exist, there's nothing more to do
259 # check if we could add a podcast for the given URL
262 updater
= PodcastUpdater()
265 can_add
= updater
.verify_podcast_url(url
)
267 except (ParserException
, FetchFeedException
,
268 NoEpisodesException
) as ex
:
270 messages
.error(request
, str(ex
))
272 return render(request
, 'missing.html', {
280 class AddPodcast(View
):
281 """ Add a missing podcast"""
283 @method_decorator(login_required
)
284 @method_decorator(cache_control(private
=True))
285 @method_decorator(vary_on_cookie
)
286 def post(self
, request
):
288 url
= request
.POST
.get('url', None)
293 updater
= PodcastUpdater()
296 podcast
= updater
.update(url
)
298 messages
.success(request
, _('The podcast has been added'))
300 return HttpResponseRedirect(get_podcast_link_target(podcast
))
302 except (ParserException
, FetchFeedException
,
303 NoEpisodesException
) as ex
:
304 messages
.error(request
, str(ex
))
306 add_page
= '%s?q=%s' % (reverse('missing-podcast'), url
)
307 return HttpResponseRedirect(add_page
)
311 class FlattrPodcastList(View
):
312 """ Lists podcasts that have Flattr payment URLs """
314 @method_decorator(cache_control(private
=True))
315 @method_decorator(vary_on_cookie
)
316 def get(self
, request
, page_size
=20):
318 # Make sure page request is an int. If not, deliver first page.
320 page
= int(request
.GET
.get('page', '1'))
324 podcasts
= get_flattr_podcasts( (page
-1) * page_size
, page_size
)
325 podcast_count
= get_flattr_podcast_count()
326 num_pages
= ceil(podcast_count
/ page_size
)
327 page_list
= get_page_list(1, num_pages
, page
, 15)
329 max_subscribers
= max([p
.subscriber_count() for p
in podcasts
] + [0])
332 flattr_auth
= user
.is_authenticated() and bool(user
.get_wksetting(FLATTR_TOKEN
))
334 return render(request
, 'flattr-podcasts.html', {
335 'podcasts': podcasts
,
336 'page_list': page_list
,
337 'current_page': page
,
338 'flattr_auth': flattr_auth
,
339 'max_subscribers': max_subscribers
,