1 from functools
import wraps
4 from django
.shortcuts
import render
5 from django
.http
import HttpResponse
, HttpResponseRedirect
, \
6 HttpResponseForbidden
, Http404
7 from django
.views
.decorators
.cache
import never_cache
, cache_control
8 from django
.views
.decorators
.vary
import vary_on_cookie
9 from django
.core
.urlresolvers
import reverse
10 from django
.utils
.translation
import ugettext
as _
11 from django
.contrib
import messages
13 from mygpo
.core
.proxy
import proxy_object
14 from mygpo
.publisher
.auth
import require_publisher
, is_publisher
15 from mygpo
.publisher
.forms
import SearchPodcastForm
16 from mygpo
.publisher
.utils
import listener_data
, episode_listener_data
, \
17 check_publisher_permission
, subscriber_data
18 from mygpo
.web
.heatmap
import EpisodeHeatmap
19 from mygpo
.web
.views
.episode
import oldid_decorator
, slug_id_decorator
20 from mygpo
.web
.views
.podcast
import \
21 slug_id_decorator
as podcast_slug_id_decorator
, \
22 oldid_decorator
as podcast_oldid_decorator
23 from mygpo
.web
.utils
import get_podcast_link_target
, normalize_twitter
24 from django
.contrib
.sites
.models
import RequestSite
25 from mygpo
.data
.tasks
import update_podcasts
26 from mygpo
.decorators
import requires_token
, allowed_methods
27 from mygpo
.users
.models
import User
28 from mygpo
.db
.couchdb
.episode
import episodes_for_podcast
29 from mygpo
.db
.couchdb
.podcast
import podcast_by_id
, podcasts_by_id
, \
30 podcast_for_url
, podcastgroup_for_slug_id
, podcastgroup_for_oldid
, \
31 podcastgroup_by_id
, update_additional_data
32 from mygpo
.db
.couchdb
.episode_state
import episode_listener_counts
36 @cache_control(private
=True)
38 if is_publisher(request
.user
):
39 podcasts
= podcasts_by_id(request
.user
.published_objects
)
40 site
= RequestSite(request
)
41 update_token
= request
.user
.get_token('publisher_update_token')
42 form
= SearchPodcastForm()
43 return render(request
, 'publisher/home.html', {
44 'update_token': update_token
,
51 site
= RequestSite(request
)
52 return render(request
, 'publisher/info.html', {
58 @cache_control(private
=True)
60 def search_podcast(request
):
61 form
= SearchPodcastForm(request
.POST
)
63 url
= form
.cleaned_data
['url']
65 podcast
= podcast_for_url(url
)
69 url
= get_podcast_link_target(podcast
, 'podcast-publisher-detail')
71 url
= reverse('publisher')
73 return HttpResponseRedirect(url
)
77 @cache_control(private
=True)
79 @allowed_methods(['GET', 'POST'])
80 def podcast(request
, podcast
):
82 if not check_publisher_permission(request
.user
, podcast
):
83 return HttpResponseForbidden()
85 timeline_data
= listener_data([podcast
])
86 subscription_data
= subscriber_data([podcast
])[-20:]
89 group
= podcastgroup_by_id(podcast
.group
)
93 update_token
= request
.user
.publisher_update_token
95 heatmap
= EpisodeHeatmap(podcast
.get_id())
97 site
= RequestSite(request
)
98 feedurl_quoted
= urllib
.quote(podcast
.url
)
100 return render(request
, 'publisher/podcast.html', {
105 'timeline_data': timeline_data
,
106 'subscriber_data': subscription_data
,
107 'update_token': update_token
,
109 'feedurl_quoted': feedurl_quoted
,
114 @cache_control(private
=True)
116 def group(request
, group
):
118 podcasts
= group
.podcasts
120 # users need to have publisher access for at least one of the group's podcasts
121 if not any([check_publisher_permission(request
.user
, p
) for p
in podcasts
]):
122 return HttpResponseForbidden()
124 timeline_data
= listener_data(podcasts
)
125 subscription_data
= list(subscriber_data(podcasts
))[-20:]
127 return render(request
, 'publisher/group.html', {
129 'timeline_data': timeline_data
,
130 'subscriber_data': subscription_data
,
135 @cache_control(private
=True)
137 def update_podcast(request
, podcast
):
139 if not check_publisher_permission(request
.user
, podcast
):
140 return HttpResponseForbidden()
142 update_podcasts
.delay([podcast
.url
])
143 messages
.success(request
, _('The update has been scheduled. It might take some time until the results are visible.'))
145 url
= get_podcast_link_target(podcast
, 'podcast-publisher-detail')
146 return HttpResponseRedirect(url
)
150 @cache_control(private
=True)
152 def save_podcast(request
, podcast
):
153 twitter
= normalize_twitter(request
.POST
.get('twitter', ''))
154 update_additional_data(podcast
, twitter
)
155 messages
.success(request
, _('Data updated'))
156 url
= get_podcast_link_target(podcast
, 'podcast-publisher-detail')
157 return HttpResponseRedirect(url
)
163 def new_update_token(request
, username
):
164 request
.user
.create_new_token('publisher_update_token')
166 messages
.success(request
, _('Publisher token updated'))
167 return HttpResponseRedirect(reverse('publisher'))
171 @requires_token(token_name
='publisher_update_token')
172 def update_published_podcasts(request
, username
):
173 user
= User
.get_user(username
)
177 published_podcasts
= podcasts_by_id(user
.published_objects
)
178 update_podcasts
.delay([podcast
.url
for podcast
in published_podcasts
])
179 return HttpResponse('Updated:\n' + '\n'.join([p
.url
for p
in published_podcasts
]), mimetype
='text/plain')
183 @cache_control(private
=True)
185 def episodes(request
, podcast
):
187 if not check_publisher_permission(request
.user
, podcast
):
188 return HttpResponseForbidden()
190 episodes
= episodes_for_podcast(podcast
, descending
=True)
191 listeners
= dict(episode_listener_counts(podcast
))
193 max_listeners
= max(listeners
.values() + [0])
195 def annotate_episode(episode
):
196 listener_count
= listeners
.get(episode
._id
, None)
197 return proxy_object(episode
, listeners
=listener_count
)
199 episodes
= map(annotate_episode
, episodes
)
201 return render(request
, 'publisher/episodes.html', {
203 'episodes': episodes
,
204 'max_listeners': max_listeners
210 @cache_control(private
=True)
211 @allowed_methods(['GET', 'POST'])
212 def episode(request
, episode
):
214 podcast
= podcast_by_id(episode
.podcast
)
216 if not check_publisher_permission(request
.user
, podcast
):
217 return HttpResponseForbidden()
219 if request
.method
== 'POST':
220 form
= None #EpisodeForm(request.POST, instance=e)
224 elif request
.method
== 'GET':
225 form
= None #EpisodeForm(instance=e)
227 timeline_data
= list(episode_listener_data(episode
))
229 heatmap
= EpisodeHeatmap(episode
.podcast
, episode
._id
,
230 duration
=episode
.duration
)
232 return render(request
, 'publisher/episode.html', {
236 'timeline_data': timeline_data
,
242 @cache_control(private
=True)
244 current_site
= RequestSite(request
)
245 return render(request
, 'link.html', {
251 @cache_control(private
=True)
252 def advertise(request
):
253 site
= RequestSite(request
)
254 return render(request
, 'publisher/advertise.html', {
259 def group_slug_id_decorator(f
):
261 def _decorator(request
, slug_id
, *args
, **kwargs
):
262 group
= podcastgroup_for_slug_id(slug_id
)
267 return f(request
, group
, *args
, **kwargs
)
272 def group_oldid_decorator(f
):
274 def _decorator(request
, pid
, *args
, **kwargs
):
277 except (TypeError, ValueError):
280 group
= podcastgroup_for_oldid(pid
)
285 return f(request
, group
, *args
, **kwargs
)
291 episode_oldid
= oldid_decorator(episode
)
292 podcast_oldid
= podcast_oldid_decorator(podcast
)
293 update_podcast_oldid
= podcast_oldid_decorator(update_podcast
)
294 save_podcast_oldid
= podcast_oldid_decorator(save_podcast
)
295 episodes_oldid
= podcast_oldid_decorator(episodes
)
296 group_oldid
= group_oldid_decorator(group
)
298 episode_slug_id
= slug_id_decorator(episode
)
299 podcast_slug_id
= podcast_slug_id_decorator(podcast
)
300 episodes_slug_id
= podcast_slug_id_decorator(episodes
)
301 update_podcast_slug_id
= podcast_slug_id_decorator(update_podcast
)
302 save_podcast_slug_id
= podcast_slug_id_decorator(save_podcast
)
303 group_slug_id
= group_slug_id_decorator(group
)