show Flattr button only when logged into flattr and payment_url is available
[mygpo.git] / mygpo / web / views / settings.py
blobf63048dcecf9438a2404ef3f442cc249274f323e
2 # This file is part of my.gpodder.org.
4 # my.gpodder.org is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or (at your
7 # option) any later version.
9 # my.gpodder.org is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
12 # License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with my.gpodder.org. If not, see <http://www.gnu.org/licenses/>.
18 from django.shortcuts import render
19 from django.core.urlresolvers import reverse
20 from django.http import HttpResponseRedirect
21 from django.contrib.auth import logout
22 from django.contrib import messages
23 from django.forms import ValidationError
24 from django.utils.translation import ugettext as _
25 from django.contrib.auth.decorators import login_required
26 from django.contrib.sites.models import RequestSite
27 from django.views.decorators.vary import vary_on_cookie
28 from django.views.decorators.cache import never_cache, cache_control
29 from django.utils.decorators import method_decorator
30 from django.views.generic.base import View
31 from django.utils.html import strip_tags
33 from django_couchdb_utils.auth.models import UsernameException, \
34 PasswordException
36 from mygpo.decorators import allowed_methods, repeat_on_conflict
37 from mygpo.web.forms import UserAccountForm, ProfileForm, FlattrForm
38 from mygpo.web.utils import normalize_twitter
39 from mygpo.flattr import Flattr
40 from mygpo.users.settings import PUBLIC_SUB_PODCAST, PUBLIC_SUB_USER, \
41 FLATTR_TOKEN, FLATTR_AUTO
42 from mygpo.db.couchdb.podcast import podcast_by_id, podcasts_to_dict
43 from mygpo.db.couchdb.podcast_state import podcast_state_for_user_podcast, \
44 subscriptions_by_user
45 from mygpo.db.couchdb.user import update_flattr_settings
48 @login_required
49 @vary_on_cookie
50 @cache_control(private=True)
51 @allowed_methods(['GET', 'POST'])
52 def account(request):
54 if request.method == 'GET':
56 site = RequestSite(request)
57 flattr = Flattr(request.user, site.domain)
58 userpage_token = request.user.get_token('userpage_token')
60 profile_form = ProfileForm({
61 'twitter': request.user.twitter,
62 'about': request.user.about,
65 form = UserAccountForm({
66 'email': request.user.email,
67 'public': request.user.get_wksetting(PUBLIC_SUB_USER)
70 flattr_form = FlattrForm({
71 'enable': request.user.get_wksetting(FLATTR_AUTO),
72 'token': request.user.get_wksetting(FLATTR_TOKEN),
75 return render(request, 'account.html', {
76 'form': form,
77 'profile_form': profile_form,
78 'flattr_form': flattr_form,
79 'flattr': flattr,
80 'userpage_token': userpage_token,
83 try:
84 form = UserAccountForm(request.POST)
86 if not form.is_valid():
87 raise ValueError(_('Oops! Something went wrong. Please double-check the data you entered.'))
89 if form.cleaned_data['password_current']:
90 if not request.user.check_password(form.cleaned_data['password_current']):
91 raise ValueError('Current password is incorrect')
93 request.user.set_password(form.cleaned_data['password1'])
95 request.user.email = form.cleaned_data['email']
97 try:
98 request.user.save()
99 except (UsernameException, PasswordException) as ex:
100 messages.error(request, str(ex))
102 messages.success(request, 'Account updated')
104 except (ValueError, ValidationError) as e:
105 messages.error(request, str(e))
107 return render(request, 'account.html', {
108 'form': form,
112 class ProfileView(View):
113 """ Updates the public profile and redirects back to the account view """
115 def post(self, request):
116 user = request.user
118 form = ProfileForm(request.POST)
120 if not form.is_valid():
121 raise ValueError(_('Oops! Something went wrong. Please double-check the data you entered.'))
123 request.user.twitter = normalize_twitter(form.cleaned_data['twitter'])
124 request.user.about = strip_tags(form.cleaned_data['about'])
126 request.user.save()
127 messages.success(request, _('Data updated'))
129 return HttpResponseRedirect(reverse('account') + '#profile')
132 class FlattrSettingsView(View):
133 """ Updates Flattr settings and redirects back to the Account page """
135 def post(self, request):
136 user = request.user
138 form = FlattrForm(request.POST)
140 if not form.is_valid():
141 raise ValueError('asdf')
143 auto_flattr = form.cleaned_data.get('enable', False)
144 update_flattr_settings(user, None, auto_flattr)
146 return HttpResponseRedirect(reverse('account') + '#flattr')
149 class FlattrLogout(View):
150 """ Removes Flattr authentication token """
152 def get(self, request):
153 user = request.user
154 update_flattr_settings(user, False, False)
155 return HttpResponseRedirect(reverse('account') + '#flattr')
158 class FlattrTokenView(View):
159 """ Callback for the Flattr authentication
161 Updates the user's Flattr token and redirects back to the account page """
163 def get(self, request):
165 user = request.user
166 site = RequestSite(request)
167 flattr = Flattr(user, site.domain)
169 url = request.build_absolute_uri()
170 token = flattr.process_retrieved_code(url)
171 if token:
172 messages.success(request, _('Authentication successful'))
173 update_flattr_settings(user, token)
175 else:
176 messages.error(request, _('Authentication failed. Try again later'))
178 return HttpResponseRedirect(reverse('account') + '#flattr')
182 @login_required
183 @never_cache
184 @allowed_methods(['GET', 'POST'])
185 def delete_account(request):
187 if request.method == 'GET':
188 return render(request, 'delete_account.html')
190 @repeat_on_conflict(['user'])
191 def do_delete(user):
192 user.is_active = False
193 user.deleted = True
194 user.save()
196 do_delete(user=request.user)
197 logout(request)
199 return render(request, 'deleted_account.html')
203 class DefaultPrivacySettings(View):
205 public = True
207 @method_decorator(login_required)
208 @method_decorator(never_cache)
209 def post(self, request):
210 self.set_privacy_settings(user=request.user)
211 messages.success(request, 'Success')
212 return HttpResponseRedirect(reverse('privacy'))
214 @repeat_on_conflict(['user'])
215 def set_privacy_settings(self, user):
216 user.settings[PUBLIC_SUB_USER.name] = self.public
217 user.save()
220 class PodcastPrivacySettings(View):
222 public = True
224 @method_decorator(login_required)
225 @method_decorator(never_cache)
226 def post(self, request, podcast_id):
227 podcast = podcast_by_id(podcast_id)
228 state = podcast_state_for_user_podcast(request.user, podcast)
229 self.set_privacy_settings(state=state)
230 messages.success(request, 'Success')
231 return HttpResponseRedirect(reverse('privacy'))
233 @repeat_on_conflict(['state'])
234 def set_privacy_settings(self, state):
235 state.settings[PUBLIC_SUB_PODCAST.name] = self.public
236 state.save()
240 @login_required
241 @never_cache
242 def privacy(request):
243 site = RequestSite(request)
245 subscriptions = subscriptions_by_user(request.user)
246 podcasts = podcasts_to_dict([x[1] for x in subscriptions])
248 included_subscriptions = set(filter(None, [podcasts.get(x[1], None) for x in subscriptions if x[0] == True]))
249 excluded_subscriptions = set(filter(None, [podcasts.get(x[1], None) for x in subscriptions if x[0] == False]))
251 return render(request, 'privacy.html', {
252 'public_subscriptions': request.user.get_wksetting(PUBLIC_SUB_USER),
253 'included_subscriptions': included_subscriptions,
254 'excluded_subscriptions': excluded_subscriptions,
255 'domain': site.domain,
259 @vary_on_cookie
260 @cache_control(private=True)
261 @login_required
262 def share(request):
263 site = RequestSite(request)
265 if 'public_subscriptions' in request.GET:
266 @repeat_on_conflict(['user'])
267 def _update(user):
268 user.subscriptions_token = ''
269 user.save()
271 elif 'private_subscriptions' in request.GET:
272 @repeat_on_conflict(['user'])
273 def _update(user):
274 user.create_new_token('subscriptions_token')
275 user.save()
277 else:
278 _update = None
280 if _update:
281 _update(user=request.user)
283 token = request.user.get_token('subscriptions_token')
285 return render(request, 'share.html', {
286 'site': site,
287 'token': token,