[Migration] move update_flattr_settings to view
[mygpo.git] / mygpo / web / views / settings.py
blob803a22a297603b99c86a6c9c0aa0ca8e62555a86
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 mygpo.podcasts.models import Podcast
34 from mygpo.core.podcasts import PODCAST_SORT
35 from mygpo.decorators import allowed_methods, repeat_on_conflict
36 from mygpo.web.forms import UserAccountForm, ProfileForm, FlattrForm
37 from mygpo.web.utils import normalize_twitter
38 from mygpo.flattr import Flattr
39 from mygpo.users.settings import PUBLIC_SUB_USER, \
40 FLATTR_TOKEN, FLATTR_AUTO, FLATTR_MYGPO, FLATTR_USERNAME
41 from mygpo.db.couchdb.podcast_state import podcast_state_for_user_podcast, \
42 subscriptions_by_user, set_podcast_privacy_settings
43 from mygpo.db.couchdb.user import set_users_google_email
47 @login_required
48 @vary_on_cookie
49 @cache_control(private=True)
50 @allowed_methods(['GET', 'POST'])
51 def account(request):
53 if request.method == 'GET':
55 site = RequestSite(request)
56 flattr = Flattr(request.user, site.domain, request.is_secure())
57 userpage_token = request.user.profile.get_token('userpage_token')
59 profile_form = ProfileForm({
60 'twitter': request.user.profile.twitter,
61 'about': request.user.profile.about,
64 form = UserAccountForm({
65 'email': request.user.email,
66 'public': request.user.profile.get_wksetting(PUBLIC_SUB_USER)
69 flattr_form = FlattrForm({
70 'enable': request.user.profile.get_wksetting(FLATTR_AUTO),
71 'token': request.user.profile.get_wksetting(FLATTR_TOKEN),
72 'flattr_mygpo': request.user.profile.get_wksetting(FLATTR_MYGPO),
73 'username': request.user.profile.get_wksetting(FLATTR_USERNAME),
76 return render(request, 'account.html', {
77 'site': site,
78 'form': form,
79 'profile_form': profile_form,
80 'flattr_form': flattr_form,
81 'flattr': flattr,
82 'userpage_token': userpage_token,
85 try:
86 form = UserAccountForm(request.POST)
88 if not form.is_valid():
89 raise ValueError(_('Oops! Something went wrong. Please double-check the data you entered.'))
91 if form.cleaned_data['password_current']:
92 if not request.user.check_password(form.cleaned_data['password_current']):
93 raise ValueError('Current password is incorrect')
95 request.user.set_password(form.cleaned_data['password1'])
97 request.user.email = form.cleaned_data['email']
99 try:
100 request.user.save()
101 except Exception as ex:
102 # TODO: which exception?
103 messages.error(request, str(ex))
105 messages.success(request, 'Account updated')
107 except (ValueError, ValidationError) as e:
108 messages.error(request, str(e))
110 return render(request, 'account.html', {
111 'form': form,
115 class ProfileView(View):
116 """ Updates the public profile and redirects back to the account view """
118 def post(self, request):
119 user = request.user
121 form = ProfileForm(request.POST)
123 if not form.is_valid():
124 raise ValueError(_('Oops! Something went wrong. Please double-check the data you entered.'))
126 request.user.twitter = normalize_twitter(form.cleaned_data['twitter'])
127 request.user.about = strip_tags(form.cleaned_data['about'])
129 request.user.save()
130 messages.success(request, _('Data updated'))
132 return HttpResponseRedirect(reverse('account') + '#profile')
135 class FlattrSettingsView(View):
136 """ Updates Flattr settings and redirects back to the Account page """
138 def post(self, request):
139 user = request.user
141 form = FlattrForm(request.POST)
143 if not form.is_valid():
144 raise ValueError('asdf')
146 auto_flattr = form.cleaned_data.get('enable', False)
147 flattr_mygpo = form.cleaned_data.get('flattr_mygpo', False)
148 username = form.cleaned_data.get('username', '')
150 user.settings[FLATTR_AUTO.name] = auto_flattr
151 user.settings[FLATTR_MYGPO.name] = flattr_mygpo
152 user.settings[FLATTR_USERNAME.name] = username
153 user.save()
155 return HttpResponseRedirect(reverse('account') + '#flattr')
158 class FlattrLogout(View):
159 """ Removes Flattr authentication token """
161 def get(self, request):
162 user = request.user
163 user.settings[FLATTR_AUTO.name] = False
164 user.settings[FLATTR_TOKEN.name] = False
165 user.settings[FLATTR_MYGPO.name] = False
166 user.save()
167 return HttpResponseRedirect(reverse('account') + '#flattr')
170 class FlattrTokenView(View):
171 """ Callback for the Flattr authentication
173 Updates the user's Flattr token and redirects back to the account page """
175 def get(self, request):
177 user = request.user
178 site = RequestSite(request)
179 flattr = Flattr(user, site.domain, request.is_secure())
181 url = request.build_absolute_uri()
182 token = flattr.process_retrieved_code(url)
183 if token:
184 messages.success(request, _('Authentication successful'))
185 user.settings[FLATTR_TOKEN.name] = token
186 user.save()
188 else:
189 messages.error(request, _('Authentication failed. Try again later'))
191 return HttpResponseRedirect(reverse('account') + '#flattr')
194 class AccountRemoveGoogle(View):
195 """ Removes the connected Google account """
197 @method_decorator(login_required)
198 def post(self, request):
199 set_users_google_email(request.user, None)
200 messages.success(request, _('Your account has been disconnected'))
201 return HttpResponseRedirect(reverse('account'))
204 @login_required
205 @never_cache
206 @allowed_methods(['GET', 'POST'])
207 def delete_account(request):
209 if request.method == 'GET':
210 return render(request, 'delete_account.html')
212 @repeat_on_conflict(['user'])
213 def do_delete(user):
214 user.is_active = False
215 user.deleted = True
216 user.save()
218 do_delete(user=request.user)
219 logout(request)
221 return render(request, 'deleted_account.html')
225 class DefaultPrivacySettings(View):
227 public = True
229 @method_decorator(login_required)
230 @method_decorator(never_cache)
231 def post(self, request):
232 self.set_privacy_settings(user=request.user)
233 return HttpResponseRedirect(reverse('privacy'))
235 @repeat_on_conflict(['user'])
236 def set_privacy_settings(self, user):
237 user.settings[PUBLIC_SUB_USER.name] = self.public
238 user.save()
241 class PodcastPrivacySettings(View):
243 public = True
245 @method_decorator(login_required)
246 @method_decorator(never_cache)
247 def post(self, request, podcast_id):
248 podcast = Podcast.objects.get(id=podcast_id)
249 state = podcast_state_for_user_podcast(request.user, podcast)
250 set_podcast_privacy_settings(state, self.public)
251 return HttpResponseRedirect(reverse('privacy'))
254 @login_required
255 @never_cache
256 def privacy(request):
257 site = RequestSite(request)
259 subscriptions = subscriptions_by_user(request.user)
260 podcast_ids = [x[1] for x in subscriptions]
261 podcasts = Podcast.objects.filter(id__in=podcast_ids).prefetch_related('slugs')
262 podcasts = {podcast.id.hex: podcast for podcast in podcasts}
264 subs = set((podcasts.get(x[1], None), not x[0]) for x in subscriptions)
265 subs = sorted(subs, key=lambda (p, _): PODCAST_SORT(p))
267 return render(request, 'privacy.html', {
268 'private_subscriptions': not request.user.get_wksetting(PUBLIC_SUB_USER),
269 'subscriptions': subs,
270 'domain': site.domain,
274 @vary_on_cookie
275 @cache_control(private=True)
276 @login_required
277 def share(request):
278 site = RequestSite(request)
280 if 'public_subscriptions' in request.GET:
281 @repeat_on_conflict(['user'])
282 def _update(user):
283 user.subscriptions_token = ''
284 user.save()
286 elif 'private_subscriptions' in request.GET:
287 @repeat_on_conflict(['user'])
288 def _update(user):
289 user.create_new_token('subscriptions_token')
290 user.save()
292 else:
293 _update = None
295 if _update:
296 _update(user=request.user)
298 token = request.user.profile.get_token('subscriptions_token')
300 return render(request, 'share.html', {
301 'site': site,
302 'token': token,