Merge branch 'django15'
[mygpo.git] / mygpo / share / views.py
blobbb454cfcea19dffe08a72c7fc0a3c25be145bf27
1 from functools import wraps
3 from django.core.urlresolvers import reverse
4 from django.http import Http404, HttpResponseRedirect, HttpResponseForbidden
5 from django.shortcuts import render
6 from django.utils.text import slugify
7 from django.contrib.sites.models import RequestSite
8 from django.contrib.auth.decorators import login_required
9 from django.contrib import messages
10 from django.utils.translation import ugettext as _
11 from django.views.decorators.vary import vary_on_cookie
12 from django.views.decorators.cache import cache_control
13 from django.views.generic.base import View
14 from django.utils.decorators import method_decorator
16 from mygpo.core.proxy import proxy_object
17 from mygpo.api.simple import format_podcast_list
18 from mygpo.share.models import PodcastList
19 from mygpo.users.models import User
20 from mygpo.directory.views import search as directory_search
21 from mygpo.decorators import repeat_on_conflict
22 from mygpo.flattr import Flattr
23 from mygpo.userfeeds.feeds import FavoriteFeed
24 from mygpo.db.couchdb.podcast import podcasts_by_id, podcast_for_url
25 from mygpo.db.couchdb.podcastlist import podcastlist_for_user_slug, \
26 podcastlists_for_user
27 from mygpo.data.feeddownloader import PodcastUpdater
31 def list_decorator(must_own=False):
32 def _tmp(f):
33 @wraps(f)
34 def _decorator(request, username, listname, *args, **kwargs):
36 user = User.get_user(username)
37 if not user:
38 raise Http404
40 if must_own and request.user != user:
41 return HttpResponseForbidden()
43 plist = podcastlist_for_user_slug(user._id, listname)
45 if plist is None:
46 raise Http404
48 return f(request, plist, user, *args, **kwargs)
50 return _decorator
52 return _tmp
55 @login_required
56 def search(request, username, listname):
57 return directory_search(request, 'list_search.html',
58 {'listname': listname})
61 @login_required
62 def lists_own(request):
64 lists = podcastlists_for_user(request.user._id)
66 return render(request, 'lists.html', {
67 'lists': lists
71 def lists_user(request, username):
73 user = User.get_user(username)
74 if not user:
75 raise Http404
77 lists = podcastlists_for_user(user._id)
79 return render(request, 'lists_user.html', {
80 'lists': lists,
81 'user': user,
85 @list_decorator(must_own=False)
86 def list_show(request, plist, owner):
88 is_own = owner == request.user
89 site = RequestSite(request)
91 plist = proxy_object(plist)
93 podcasts = podcasts_by_id(plist.podcasts)
94 plist.podcasts = podcasts
96 max_subscribers = max([p.subscriber_count() for p in podcasts] + [0])
98 thing = plist.get_flattr_thing(site.domain, owner.username)
99 flattr = Flattr(owner, site.domain)
100 flattr_autosubmit = flattr.get_autosubmit_url(thing)
102 return render(request, 'list.html', {
103 'podcastlist': plist,
104 'max_subscribers': max_subscribers,
105 'owner': owner,
106 'flattr_autosubmit': flattr_autosubmit,
107 'domain': site.domain,
108 'is_own': is_own,
112 @list_decorator(must_own=False)
113 def list_opml(request, plist, owner):
114 podcasts = podcasts_by_id(plist.podcasts)
115 return format_podcast_list(podcasts, 'opml', plist.title)
118 @login_required
119 def create_list(request):
120 title = request.POST.get('title', None)
122 if not title:
123 messages.error(request, _('You have to specify a title.'))
124 return HttpResponseRedirect(reverse('lists-overview'))
126 slug = slugify(title)
128 if not slug:
129 messages.error(request, _('"{title}" is not a valid title').format(
130 title=title))
131 return HttpResponseRedirect(reverse('lists-overview'))
133 plist = podcastlist_for_user_slug(request.user._id, slug)
135 if plist is None:
136 plist = PodcastList()
137 plist.title = title
138 plist.slug = slug
139 plist.user = request.user._id
140 plist.save()
142 list_url = reverse('list-show', args=[request.user.username, slug])
143 return HttpResponseRedirect(list_url)
146 @login_required
147 @list_decorator(must_own=True)
148 def add_podcast(request, plist, owner, podcast_id):
150 @repeat_on_conflict(['plist'])
151 def _add(plist, podcast_id):
152 plist.podcasts.append(podcast_id)
153 plist.save()
155 _add(plist=plist, podcast_id=podcast_id)
157 list_url = reverse('list-show', args=[owner.username, plist.slug])
158 return HttpResponseRedirect(list_url)
161 @login_required
162 @list_decorator(must_own=True)
163 def remove_podcast(request, plist, owner, podcast_id):
165 @repeat_on_conflict(['plist'])
166 def _remove(plist, podcast_id):
167 plist.podcasts.remove(podcast_id)
168 plist.save()
170 _remove(plist=plist, podcast_id=podcast_id)
172 list_url = reverse('list-show', args=[owner.username, plist.slug])
173 return HttpResponseRedirect(list_url)
176 @login_required
177 @list_decorator(must_own=True)
178 def delete_list(request, plist, owner):
179 plist.delete()
180 return HttpResponseRedirect(reverse('lists-overview'))
183 @login_required
184 @list_decorator(must_own=False)
185 def rate_list(request, plist, owner):
186 rating_val = int(request.GET.get('rate', None))
188 @repeat_on_conflict(['plist'])
189 def _rate(plist, rating_val, user):
190 plist.rate(rating_val, user._id)
191 plist.save()
193 _rate(plist, rating_val, request.user)
195 messages.success(request, _('Thanks for rating!'))
197 list_url = reverse('list-show', args=[owner.username, plist.slug])
198 return HttpResponseRedirect(list_url)
201 class FavoritesPublic(View):
203 public = True
205 @method_decorator(vary_on_cookie)
206 @method_decorator(cache_control(private=True))
207 @method_decorator(login_required)
208 def post(self, request):
210 if self.public:
211 request.user.favorite_feeds_token = ''
212 request.user.save()
214 else:
215 request.user.create_new_token('favorite_feeds_token', 8)
216 request.user.save()
218 token = request.user.favorite_feeds_token
220 return HttpResponseRedirect(reverse('share-favorites'))
224 class ShareFavorites(View):
226 @method_decorator(vary_on_cookie)
227 @method_decorator(cache_control(private=True))
228 @method_decorator(login_required)
229 def get(self, request):
230 user = request.user
232 favfeed = FavoriteFeed(user)
233 site = RequestSite(request)
234 feed_url = favfeed.get_public_url(site.domain)
236 podcast = podcast_for_url(feed_url)
238 token = request.user.favorite_feeds_token
240 return render(request, 'share/favorites.html', {
241 'feed_token': token,
242 'site': site,
243 'podcast': podcast,
247 class PublicSubscriptions(View):
249 public = True
251 @method_decorator(vary_on_cookie)
252 @method_decorator(cache_control(private=True))
253 @method_decorator(login_required)
254 def post(self, request):
256 self.update(request.user)
258 return HttpResponseRedirect(reverse('share'))
261 @repeat_on_conflict(['user'])
262 def update(self, user):
263 if self.public:
264 user.subscriptions_token = ''
265 else:
266 user.create_new_token('subscriptions_token')
268 user.save()
271 class FavoritesFeedCreateEntry(View):
272 """ Creates a Podcast object for the user's favorites feed """
274 @method_decorator(vary_on_cookie)
275 @method_decorator(cache_control(private=True))
276 @method_decorator(login_required)
277 def post(self, request):
278 user = request.user
280 feed = FavoriteFeed(user)
281 site = RequestSite(request)
282 feed_url = feed.get_public_url(site.domain)
284 podcast = podcast_for_url(feed_url, create=True)
286 if not podcast.get_id() in user.published_objects:
287 user.published_objects.append(podcast.get_id())
288 user.save()
290 updater = PodcastUpdater()
291 updater.update(feed_url)
293 return HttpResponseRedirect(reverse('share-favorites'))
296 @login_required
297 def overview(request):
298 user = request.user
299 site = RequestSite(request)
301 subscriptions_token = user.get_token('subscriptions_token')
302 userpage_token = user.get_token('userpage_token')
303 favfeed_token = user.get_token('favorite_feeds_token')
305 favfeed = FavoriteFeed(user)
306 favfeed_url = favfeed.get_public_url(site.domain)
307 favfeed_podcast = podcast_for_url(favfeed_url)
309 return render(request, 'share/overview.html', {
310 'site': site,
311 'subscriptions_token': subscriptions_token,
312 'userpage_token': userpage_token,
313 'favfeed_token': favfeed_token,
314 'favfeed_podcast': favfeed_podcast,
318 @login_required
319 def set_token_public(request, token_name, public):
321 if public:
322 @repeat_on_conflict(['user'])
323 def _update(user):
324 setattr(user, token_name, '')
325 user.save()
327 else:
328 @repeat_on_conflict(['user'])
329 def _update(user):
330 user.create_new_token(token_name)
331 user.save()
333 _update(user=request.user)
335 return HttpResponseRedirect(reverse('share'))