Bump python-dateutil from 2.7.3 to 2.7.4
[mygpo.git] / mygpo / subscriptions / views.py
blobdc3939c0352119bef57562eff57dcdb2deff5bbd
1 from datetime import datetime
3 from django.urls import reverse
4 from django.contrib.auth.decorators import login_required
5 from django.contrib.sites.requests import RequestSite
6 from django.shortcuts import render, get_object_or_404
7 from django.http import HttpResponse
8 from django.views.decorators.vary import vary_on_cookie
9 from django.views.decorators.cache import cache_control
10 from django.utils.translation import ugettext as _
11 from django.contrib.syndication.views import Feed
12 from django.contrib.auth import get_user_model
14 from mygpo.podcasts.models import Podcast
15 from mygpo.subscriptions.models import Subscription
16 from mygpo.users.settings import PUBLIC_SUB_PODCAST
17 from mygpo.api import simple
18 from mygpo.subscriptions import get_subscribed_podcasts
19 from mygpo.decorators import requires_token
20 from mygpo.users.models import HistoryEntry
21 from mygpo.subscriptions import (get_subscribed_podcasts,
22 get_subscription_change_history, get_subscription_history)
23 from mygpo.web.utils import get_podcast_link_target
24 from mygpo.utils import parse_bool
25 from mygpo.decorators import requires_token
26 from mygpo.web.utils import symbian_opml_changes
30 @vary_on_cookie
31 @cache_control(private=True)
32 @login_required
33 def show_list(request):
34 current_site = RequestSite(request)
35 subscriptionlist = create_subscriptionlist(request)
36 return render(request, 'subscriptions.html', {
37 'subscriptionlist': subscriptionlist,
38 'url': current_site,
39 'podcast_ad': Podcast.objects.get_advertised_podcast(),
42 @vary_on_cookie
43 @cache_control(private=True)
44 @login_required
45 def download_all(request):
46 podcasts = get_subscribed_podcasts(request.user)
47 response = simple.format_podcast_list(podcasts, 'opml', request.user.username)
48 response['Content-Disposition'] = 'attachment; filename=all-subscriptions.opml'
49 return response
52 def create_subscriptionlist(request):
53 user = request.user
55 # get all non-deleted subscriptions
56 subscriptions = Subscription.objects.filter(user=user)\
57 .exclude(deleted=True)\
58 .select_related('podcast', 'client')
60 # grou clients by subscribed podcasts
61 subscription_list = {}
62 for subscription in subscriptions:
63 podcast = subscription.podcast
65 if not podcast in subscription_list:
66 subscription_list[podcast] = {
67 'podcast': podcast,
68 'devices': [],
69 'episodes': podcast.episode_count,
72 subscription_list[podcast]['devices'].append(subscription.client)
74 # sort most recently updated podcast first
75 subscriptions = subscription_list.values()
76 now = datetime.utcnow()
77 sort_key = lambda s: s['podcast'].latest_episode_timestamp or now
78 subscriptions = sorted(subscriptions, key=sort_key, reverse=True)
79 return subscriptions
82 @requires_token(token_name='subscriptions_token')
83 def subscriptions_feed(request, username):
84 # Create to feed manually so we can wrap the token-authentication around it
85 f = SubscriptionsFeed(username)
86 obj = f.get_object(request, username)
87 feedgen = f.get_feed(obj, request)
88 response = HttpResponse(content_type=feedgen.content_type)
89 feedgen.write(response, 'utf-8')
90 return response
93 class SubscriptionsFeed(Feed):
94 """ A feed showing subscription changes for a certain user """
96 NUM_ITEMS = 20
98 def __init__(self, username):
99 self.username = username
101 def get_object(self, request, username):
102 self.site = RequestSite(request)
103 User = get_user_model()
104 user = get_object_or_404(User, username=username)
105 return user
107 def title(self, user):
108 return _('%(username)s\'s Podcast Subscriptions on %(site)s') % \
109 dict(username=user.username, site=self.site)
111 def description(self, user):
112 return _('Recent changes to %(username)s\'s podcast subscriptions on %(site)s') % \
113 dict(username=user.username, site=self.site)
115 def link(self, user):
116 return reverse('shared-subscriptions', args=[user.username])
118 def items(self, user):
119 history = get_subscription_history(user, public_only=True)
120 history = get_subscription_change_history(history)
121 history = list(history)[-self.NUM_ITEMS:]
122 return history
124 def author_name(self, user):
125 return user.username
127 def author_link(self, user):
128 return reverse('shared-subscriptions', args=[user.username])
130 # entry-specific data below
132 description_template = "subscription-feed-description.html"
134 def item_title(self, entry):
135 if entry.action == 'subscribe':
136 s = _('%(username)s subscribed to %(podcast)s (%(site)s)')
137 else:
138 s = _('%(username)s unsubscribed from %(podcast)s (%(site)s)')
140 return s % dict(username=self.username,
141 podcast=entry.podcast.display_title,
142 site=self.site)
144 def item_link(self, item):
145 return get_podcast_link_target(item.podcast)
147 def item_pubdate(self, item):
148 return item.timestamp
152 @requires_token(token_name='subscriptions_token', denied_template='user_subscriptions_denied.html')
153 def for_user(request, username):
154 User = get_user_model()
155 user = get_object_or_404(User, username=username)
156 subscriptions = get_subscribed_podcasts(user, only_public=True)
157 token = user.profile.get_token('subscriptions_token')
159 return render(request, 'user_subscriptions.html', {
160 'subscriptions': subscriptions,
161 'other_user': user,
162 'token': token,
165 @requires_token(token_name='subscriptions_token')
166 def for_user_opml(request, username):
167 User = get_user_model()
168 user = get_object_or_404(User, username=username)
169 subscriptions = get_subscribed_podcasts(user, only_public=True)
171 if parse_bool(request.GET.get('symbian', False)):
172 subscriptions = map(symbian_opml_changes,
173 [p.podcast for p in subscriptions])
175 response = render(request, 'user_subscriptions.opml', {
176 'subscriptions': subscriptions,
177 'other_user': user
179 response['Content-Disposition'] = 'attachment; filename=%s-subscriptions.opml' % username
180 return response