fix missing podcasts in podcast lists
[mygpo.git] / mygpo / share / views.py
blob38620d4b49510bca103caf21668a8dc527232a70
1 from functools import wraps
2 from datetime import datetime
4 from django.core.urlresolvers import reverse
5 from django.http import Http404, HttpResponseRedirect, HttpResponseForbidden
6 from django.shortcuts import render
7 from django.utils.text import slugify
8 from django.contrib.sites.models import RequestSite
9 from django.contrib.auth.decorators import login_required
10 from django.contrib import messages
11 from django.utils.translation import ugettext as _
12 from django.views.decorators.vary import vary_on_cookie
13 from django.views.decorators.cache import cache_control
14 from django.views.generic.base import View
15 from django.utils.decorators import method_decorator
17 from mygpo.utils import get_timestamp
18 from mygpo.core.proxy import proxy_object
19 from mygpo.api.simple import format_podcast_list
20 from mygpo.share.models import PodcastList
21 from mygpo.users.models import User
22 from mygpo.directory.views import search as directory_search
23 from mygpo.decorators import repeat_on_conflict
24 from mygpo.flattr import Flattr
25 from mygpo.userfeeds.feeds import FavoriteFeed
26 from mygpo.db.couchdb.podcast import podcasts_groups_by_id, podcast_for_url
27 from mygpo.db.couchdb.podcastlist import podcastlist_for_user_slug, \
28 podcastlists_for_user
29 from mygpo.data.feeddownloader import PodcastUpdater
33 def list_decorator(must_own=False):
34 def _tmp(f):
35 @wraps(f)
36 def _decorator(request, username, listname, *args, **kwargs):
38 user = User.get_user(username)
39 if not user:
40 raise Http404
42 if must_own and request.user != user:
43 return HttpResponseForbidden()
45 plist = podcastlist_for_user_slug(user._id, listname)
47 if plist is None:
48 raise Http404
50 return f(request, plist, user, *args, **kwargs)
52 return _decorator
54 return _tmp
57 @login_required
58 def search(request, username, listname):
59 return directory_search(request, 'list_search.html',
60 {'listname': listname})
63 @login_required
64 def lists_own(request):
66 lists = podcastlists_for_user(request.user._id)
68 return render(request, 'lists.html', {
69 'lists': lists
73 def lists_user(request, username):
75 user = User.get_user(username)
76 if not user:
77 raise Http404
79 lists = podcastlists_for_user(user._id)
81 return render(request, 'lists_user.html', {
82 'lists': lists,
83 'user': user,
87 @list_decorator(must_own=False)
88 def list_show(request, plist, owner):
90 is_own = owner == request.user
91 site = RequestSite(request)
93 plist = proxy_object(plist)
95 podcasts = list(podcasts_groups_by_id(plist.podcasts))
96 plist.podcasts = podcasts
98 max_subscribers = max([p.subscriber_count() for p in podcasts] + [0])
100 thing = plist.get_flattr_thing(site.domain, owner.username)
101 flattr = Flattr(owner, site.domain, request.is_secure())
102 flattr_autosubmit = flattr.get_autosubmit_url(thing)
104 return render(request, 'list.html', {
105 'podcastlist': plist,
106 'max_subscribers': max_subscribers,
107 'owner': owner,
108 'flattr_autosubmit': flattr_autosubmit,
109 'domain': site.domain,
110 'is_own': is_own,
114 @list_decorator(must_own=False)
115 def list_opml(request, plist, owner):
116 podcasts = podcasts_groups_by_id(plist.podcasts)
117 return format_podcast_list(podcasts, 'opml', plist.title)
120 @login_required
121 def create_list(request):
122 title = request.POST.get('title', None)
124 if not title:
125 messages.error(request, _('You have to specify a title.'))
126 return HttpResponseRedirect(reverse('lists-overview'))
128 slug = slugify(title)
130 if not slug:
131 messages.error(request, _('"{title}" is not a valid title').format(
132 title=title))
133 return HttpResponseRedirect(reverse('lists-overview'))
135 plist = podcastlist_for_user_slug(request.user._id, slug)
137 if plist is None:
138 plist = PodcastList()
139 plist.created_timestamp = get_timestamp(datetime.utcnow())
140 plist.title = title
141 plist.slug = slug
142 plist.user = request.user._id
143 plist.save()
145 list_url = reverse('list-show', args=[request.user.username, slug])
146 return HttpResponseRedirect(list_url)
149 @login_required
150 @list_decorator(must_own=True)
151 def add_podcast(request, plist, owner, podcast_id):
153 @repeat_on_conflict(['plist'])
154 def _add(plist, podcast_id):
155 plist.podcasts.append(podcast_id)
156 plist.save()
158 _add(plist=plist, podcast_id=podcast_id)
160 list_url = reverse('list-show', args=[owner.username, plist.slug])
161 return HttpResponseRedirect(list_url)
164 @login_required
165 @list_decorator(must_own=True)
166 def remove_podcast(request, plist, owner, podcast_id):
168 @repeat_on_conflict(['plist'])
169 def _remove(plist, podcast_id):
170 plist.podcasts.remove(podcast_id)
171 plist.save()
173 _remove(plist=plist, podcast_id=podcast_id)
175 list_url = reverse('list-show', args=[owner.username, plist.slug])
176 return HttpResponseRedirect(list_url)
179 @login_required
180 @list_decorator(must_own=True)
181 def delete_list(request, plist, owner):
182 plist.delete()
183 return HttpResponseRedirect(reverse('lists-overview'))
186 @login_required
187 @list_decorator(must_own=False)
188 def rate_list(request, plist, owner):
189 rating_val = int(request.GET.get('rate', None))
191 @repeat_on_conflict(['plist'])
192 def _rate(plist, rating_val, user):
193 plist.rate(rating_val, user._id)
194 plist.save()
196 _rate(plist, rating_val, request.user)
198 messages.success(request, _('Thanks for rating!'))
200 list_url = reverse('list-show', args=[owner.username, plist.slug])
201 return HttpResponseRedirect(list_url)
204 class FavoritesPublic(View):
206 public = True
208 @method_decorator(vary_on_cookie)
209 @method_decorator(cache_control(private=True))
210 @method_decorator(login_required)
211 def post(self, request):
213 if self.public:
214 request.user.favorite_feeds_token = ''
215 request.user.save()
217 else:
218 request.user.create_new_token('favorite_feeds_token', 8)
219 request.user.save()
221 token = request.user.favorite_feeds_token
223 return HttpResponseRedirect(reverse('share-favorites'))
227 class ShareFavorites(View):
229 @method_decorator(vary_on_cookie)
230 @method_decorator(cache_control(private=True))
231 @method_decorator(login_required)
232 def get(self, request):
233 user = request.user
235 favfeed = FavoriteFeed(user)
236 site = RequestSite(request)
237 feed_url = favfeed.get_public_url(site.domain)
239 podcast = podcast_for_url(feed_url)
241 token = request.user.favorite_feeds_token
243 return render(request, 'share/favorites.html', {
244 'feed_token': token,
245 'site': site,
246 'podcast': podcast,
250 class PublicSubscriptions(View):
252 public = True
254 @method_decorator(vary_on_cookie)
255 @method_decorator(cache_control(private=True))
256 @method_decorator(login_required)
257 def post(self, request):
259 self.update(request.user)
261 return HttpResponseRedirect(reverse('share'))
264 @repeat_on_conflict(['user'])
265 def update(self, user):
266 if self.public:
267 user.subscriptions_token = ''
268 else:
269 user.create_new_token('subscriptions_token')
271 user.save()
274 class FavoritesFeedCreateEntry(View):
275 """ Creates a Podcast object for the user's favorites feed """
277 @method_decorator(vary_on_cookie)
278 @method_decorator(cache_control(private=True))
279 @method_decorator(login_required)
280 def post(self, request):
281 user = request.user
283 feed = FavoriteFeed(user)
284 site = RequestSite(request)
285 feed_url = feed.get_public_url(site.domain)
287 podcast = podcast_for_url(feed_url, create=True)
289 if not podcast.get_id() in user.published_objects:
290 user.published_objects.append(podcast.get_id())
291 user.save()
293 updater = PodcastUpdater()
294 updater.update(feed_url)
296 return HttpResponseRedirect(reverse('share-favorites'))
299 @login_required
300 def overview(request):
301 user = request.user
302 site = RequestSite(request)
304 subscriptions_token = user.get_token('subscriptions_token')
305 userpage_token = user.get_token('userpage_token')
306 favfeed_token = user.get_token('favorite_feeds_token')
308 favfeed = FavoriteFeed(user)
309 favfeed_url = favfeed.get_public_url(site.domain)
310 favfeed_podcast = podcast_for_url(favfeed_url)
312 return render(request, 'share/overview.html', {
313 'site': site,
314 'subscriptions_token': subscriptions_token,
315 'userpage_token': userpage_token,
316 'favfeed_token': favfeed_token,
317 'favfeed_podcast': favfeed_podcast,
321 @login_required
322 def set_token_public(request, token_name, public):
324 if public:
325 @repeat_on_conflict(['user'])
326 def _update(user):
327 setattr(user, token_name, '')
328 user.save()
330 else:
331 @repeat_on_conflict(['user'])
332 def _update(user):
333 user.create_new_token(token_name)
334 user.save()
336 _update(user=request.user)
338 return HttpResponseRedirect(reverse('share'))