podcast parsing as a celery task
[mygpo.git] / mygpo / share / views.py
blob9a0765188763ea0c54c9e065b5bf5f2349b9598e
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.template.defaultfilters 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.userfeeds.feeds import FavoriteFeed
23 from mygpo.db.couchdb.podcast import podcasts_by_id, podcast_for_url
24 from mygpo.db.couchdb.podcastlist import podcastlist_for_user_slug, \
25 podcastlists_for_user
26 from mygpo.data.feeddownloader import PodcastUpdater
30 def list_decorator(must_own=False):
31 def _tmp(f):
32 @wraps(f)
33 def _decorator(request, username, listname, *args, **kwargs):
35 user = User.get_user(username)
36 if not user:
37 raise Http404
39 if must_own and request.user != user:
40 return HttpResponseForbidden()
42 plist = podcastlist_for_user_slug(user._id, listname)
44 if plist is None:
45 raise Http404
47 return f(request, plist, user, *args, **kwargs)
49 return _decorator
51 return _tmp
54 @login_required
55 def search(request, username, listname):
56 return directory_search(request, 'list_search.html',
57 {'listname': listname})
60 @login_required
61 def lists_own(request):
63 lists = podcastlists_for_user(request.user._id)
65 return render(request, 'lists.html', {
66 'lists': lists
70 def lists_user(request, username):
72 user = User.get_user(username)
73 if not user:
74 raise Http404
76 lists = podcastlists_for_user(user._id)
78 return render(request, 'lists_user.html', {
79 'lists': lists,
80 'user': user,
84 @list_decorator(must_own=False)
85 def list_show(request, plist, owner):
87 is_own = owner == request.user
89 plist = proxy_object(plist)
91 podcasts = podcasts_by_id(plist.podcasts)
92 plist.podcasts = podcasts
94 max_subscribers = max([p.subscriber_count() for p in podcasts] + [0])
96 site = RequestSite(request)
98 return render(request, 'list.html', {
99 'podcastlist': plist,
100 'max_subscribers': max_subscribers,
101 'owner': owner,
102 'domain': site.domain,
103 'is_own': is_own,
107 @list_decorator(must_own=False)
108 def list_opml(request, plist, owner):
109 podcasts = podcasts_by_id(plist.podcasts)
110 return format_podcast_list(podcasts, 'opml', plist.title)
113 @login_required
114 def create_list(request):
115 title = request.POST.get('title', None)
117 if not title:
118 messages.error(request, _('You have to specify a title.'))
119 return HttpResponseRedirect(reverse('lists-overview'))
121 slug = slugify(title)
123 if not slug:
124 messages.error(request, _('"{title}" is not a valid title').format(
125 title=title))
126 return HttpResponseRedirect(reverse('lists-overview'))
128 plist = podcastlist_for_user_slug(request.user._id, slug)
130 if plist is None:
131 plist = PodcastList()
132 plist.title = title
133 plist.slug = slug
134 plist.user = request.user._id
135 plist.save()
137 list_url = reverse('list-show', args=[request.user.username, slug])
138 return HttpResponseRedirect(list_url)
141 @login_required
142 @list_decorator(must_own=True)
143 def add_podcast(request, plist, owner, podcast_id):
145 @repeat_on_conflict(['plist'])
146 def _add(plist, podcast_id):
147 plist.podcasts.append(podcast_id)
148 plist.save()
150 _add(plist=plist, podcast_id=podcast_id)
152 list_url = reverse('list-show', args=[owner.username, plist.slug])
153 return HttpResponseRedirect(list_url)
156 @login_required
157 @list_decorator(must_own=True)
158 def remove_podcast(request, plist, owner, podcast_id):
160 @repeat_on_conflict(['plist'])
161 def _remove(plist, podcast_id):
162 plist.podcasts.remove(podcast_id)
163 plist.save()
165 _remove(plist=plist, podcast_id=podcast_id)
167 list_url = reverse('list-show', args=[owner.username, plist.slug])
168 return HttpResponseRedirect(list_url)
171 @login_required
172 @list_decorator(must_own=True)
173 def delete_list(request, plist, owner):
174 plist.delete()
175 return HttpResponseRedirect(reverse('lists-overview'))
178 @login_required
179 @list_decorator(must_own=False)
180 def rate_list(request, plist, owner):
181 rating_val = int(request.GET.get('rate', None))
183 plist.rate(rating_val, request.user._id)
184 plist.save()
186 messages.success(request, _('Thanks for rating!'))
188 list_url = reverse('list-show', args=[owner.username, plist.slug])
189 return HttpResponseRedirect(list_url)
192 class FavoritesPublic(View):
194 public = True
196 @method_decorator(vary_on_cookie)
197 @method_decorator(cache_control(private=True))
198 @method_decorator(login_required)
199 def post(self, request):
201 if self.public:
202 request.user.favorite_feeds_token = ''
203 request.user.save()
205 else:
206 request.user.create_new_token('favorite_feeds_token', 8)
207 request.user.save()
209 token = request.user.favorite_feeds_token
211 return HttpResponseRedirect(reverse('share-favorites'))
215 class ShareFavorites(View):
217 @method_decorator(vary_on_cookie)
218 @method_decorator(cache_control(private=True))
219 @method_decorator(login_required)
220 def get(self, request):
221 user = request.user
223 favfeed = FavoriteFeed(user)
224 site = RequestSite(request)
225 feed_url = favfeed.get_public_url(site.domain)
227 podcast = podcast_for_url(feed_url)
229 token = request.user.favorite_feeds_token
231 return render(request, 'share/favorites.html', {
232 'feed_token': token,
233 'site': site,
234 'podcast': podcast,
238 class PublicSubscriptions(View):
240 public = True
242 @method_decorator(vary_on_cookie)
243 @method_decorator(cache_control(private=True))
244 @method_decorator(login_required)
245 def post(self, request):
247 self.update(request.user)
249 return HttpResponseRedirect(reverse('share'))
252 @repeat_on_conflict(['user'])
253 def update(self, user):
254 if self.public:
255 user.subscriptions_token = ''
256 else:
257 user.create_new_token('subscriptions_token')
259 user.save()
262 class FavoritesFeedCreateEntry(View):
263 """ Creates a Podcast object for the user's favorites feed """
265 @method_decorator(vary_on_cookie)
266 @method_decorator(cache_control(private=True))
267 @method_decorator(login_required)
268 def post(self, request):
269 user = request.user
271 feed = FavoriteFeed(user)
272 site = RequestSite(request)
273 feed_url = feed.get_public_url(site.domain)
275 podcast = podcast_for_url(feed_url, create=True)
277 if not podcast.get_id() in user.published_objects:
278 user.published_objects.append(podcast.get_id())
279 user.save()
281 updater = PodcastUpdater([podcast])
282 update.update()
284 return HttpResponseRedirect(reverse('share-favorites'))
287 @login_required
288 def overview(request):
289 user = request.user
290 site = RequestSite(request)
292 subscriptions_token = user.get_token('subscriptions_token')
293 userpage_token = user.get_token('userpage_token')
294 favfeed_token = user.get_token('favorite_feeds_token')
296 favfeed = FavoriteFeed(user)
297 favfeed_url = favfeed.get_public_url(site.domain)
298 favfeed_podcast = podcast_for_url(favfeed_url)
300 return render(request, 'share/overview.html', {
301 'site': site,
302 'subscriptions_token': subscriptions_token,
303 'userpage_token': userpage_token,
304 'favfeed_token': favfeed_token,
305 'favfeed_podcast': favfeed_podcast,
309 @login_required
310 def set_token_public(request, token_name, public):
312 if public:
313 @repeat_on_conflict(['user'])
314 def _update(user):
315 setattr(user, token_name, '')
316 user.save()
318 else:
319 @repeat_on_conflict(['user'])
320 def _update(user):
321 user.create_new_token(token_name)
322 user.save()
324 _update(user=request.user)
326 return HttpResponseRedirect(reverse('share'))