[Migration] remove podcasts_to_dict
[mygpo.git] / mygpo / web / views / settings.py
blobe5ef3667de9c3f00d40d2325a584eb29ed209396
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.couchauth.models import UsernameException, \
34 PasswordException
36 from mygpo.podcasts.models import Podcast
37 from mygpo.core.podcasts import PODCAST_SORT
38 from mygpo.decorators import allowed_methods, repeat_on_conflict
39 from mygpo.web.forms import UserAccountForm, ProfileForm, FlattrForm
40 from mygpo.web.utils import normalize_twitter
41 from mygpo.flattr import Flattr
42 from mygpo.users.settings import PUBLIC_SUB_USER, \
43 FLATTR_TOKEN, FLATTR_AUTO, FLATTR_MYGPO, FLATTR_USERNAME
44 from mygpo.db.couchdb.podcast_state import podcast_state_for_user_podcast, \
45 subscriptions_by_user, set_podcast_privacy_settings
46 from mygpo.db.couchdb.user import update_flattr_settings, \
47 set_users_google_email
51 @login_required
52 @vary_on_cookie
53 @cache_control(private=True)
54 @allowed_methods(['GET', 'POST'])
55 def account(request):
57 if request.method == 'GET':
59 site = RequestSite(request)
60 flattr = Flattr(request.user, site.domain, request.is_secure())
61 userpage_token = request.user.get_token('userpage_token')
63 profile_form = ProfileForm({
64 'twitter': request.user.twitter,
65 'about': request.user.about,
68 form = UserAccountForm({
69 'email': request.user.email,
70 'public': request.user.get_wksetting(PUBLIC_SUB_USER)
73 flattr_form = FlattrForm({
74 'enable': request.user.get_wksetting(FLATTR_AUTO),
75 'token': request.user.get_wksetting(FLATTR_TOKEN),
76 'flattr_mygpo': request.user.get_wksetting(FLATTR_MYGPO),
77 'username': request.user.get_wksetting(FLATTR_USERNAME),
80 return render(request, 'account.html', {
81 'site': site,
82 'form': form,
83 'profile_form': profile_form,
84 'flattr_form': flattr_form,
85 'flattr': flattr,
86 'userpage_token': userpage_token,
89 try:
90 form = UserAccountForm(request.POST)
92 if not form.is_valid():
93 raise ValueError(_('Oops! Something went wrong. Please double-check the data you entered.'))
95 if form.cleaned_data['password_current']:
96 if not request.user.check_password(form.cleaned_data['password_current']):
97 raise ValueError('Current password is incorrect')
99 request.user.set_password(form.cleaned_data['password1'])
101 request.user.email = form.cleaned_data['email']
103 try:
104 request.user.save()
105 except (UsernameException, PasswordException) as ex:
106 messages.error(request, str(ex))
108 messages.success(request, 'Account updated')
110 except (ValueError, ValidationError) as e:
111 messages.error(request, str(e))
113 return render(request, 'account.html', {
114 'form': form,
118 class ProfileView(View):
119 """ Updates the public profile and redirects back to the account view """
121 def post(self, request):
122 user = request.user
124 form = ProfileForm(request.POST)
126 if not form.is_valid():
127 raise ValueError(_('Oops! Something went wrong. Please double-check the data you entered.'))
129 request.user.twitter = normalize_twitter(form.cleaned_data['twitter'])
130 request.user.about = strip_tags(form.cleaned_data['about'])
132 request.user.save()
133 messages.success(request, _('Data updated'))
135 return HttpResponseRedirect(reverse('account') + '#profile')
138 class FlattrSettingsView(View):
139 """ Updates Flattr settings and redirects back to the Account page """
141 def post(self, request):
142 user = request.user
144 form = FlattrForm(request.POST)
146 if not form.is_valid():
147 raise ValueError('asdf')
149 auto_flattr = form.cleaned_data.get('enable', False)
150 flattr_mygpo = form.cleaned_data.get('flattr_mygpo', False)
151 username = form.cleaned_data.get('username', '')
152 update_flattr_settings(user, None, auto_flattr, flattr_mygpo, username)
154 return HttpResponseRedirect(reverse('account') + '#flattr')
157 class FlattrLogout(View):
158 """ Removes Flattr authentication token """
160 def get(self, request):
161 user = request.user
162 update_flattr_settings(user, False, False, False)
163 return HttpResponseRedirect(reverse('account') + '#flattr')
166 class FlattrTokenView(View):
167 """ Callback for the Flattr authentication
169 Updates the user's Flattr token and redirects back to the account page """
171 def get(self, request):
173 user = request.user
174 site = RequestSite(request)
175 flattr = Flattr(user, site.domain, request.is_secure())
177 url = request.build_absolute_uri()
178 token = flattr.process_retrieved_code(url)
179 if token:
180 messages.success(request, _('Authentication successful'))
181 update_flattr_settings(user, token)
183 else:
184 messages.error(request, _('Authentication failed. Try again later'))
186 return HttpResponseRedirect(reverse('account') + '#flattr')
189 class AccountRemoveGoogle(View):
190 """ Removes the connected Google account """
192 @method_decorator(login_required)
193 def post(self, request):
194 set_users_google_email(request.user, None)
195 messages.success(request, _('Your account has been disconnected'))
196 return HttpResponseRedirect(reverse('account'))
199 @login_required
200 @never_cache
201 @allowed_methods(['GET', 'POST'])
202 def delete_account(request):
204 if request.method == 'GET':
205 return render(request, 'delete_account.html')
207 @repeat_on_conflict(['user'])
208 def do_delete(user):
209 user.is_active = False
210 user.deleted = True
211 user.save()
213 do_delete(user=request.user)
214 logout(request)
216 return render(request, 'deleted_account.html')
220 class DefaultPrivacySettings(View):
222 public = True
224 @method_decorator(login_required)
225 @method_decorator(never_cache)
226 def post(self, request):
227 self.set_privacy_settings(user=request.user)
228 return HttpResponseRedirect(reverse('privacy'))
230 @repeat_on_conflict(['user'])
231 def set_privacy_settings(self, user):
232 user.settings[PUBLIC_SUB_USER.name] = self.public
233 user.save()
236 class PodcastPrivacySettings(View):
238 public = True
240 @method_decorator(login_required)
241 @method_decorator(never_cache)
242 def post(self, request, podcast_id):
243 podcast = Podcast.objects.get(id=podcast_id)
244 state = podcast_state_for_user_podcast(request.user, podcast)
245 set_podcast_privacy_settings(state, self.public)
246 return HttpResponseRedirect(reverse('privacy'))
249 @login_required
250 @never_cache
251 def privacy(request):
252 site = RequestSite(request)
254 subscriptions = subscriptions_by_user(request.user)
255 podcasts = Podcast.objects.filter(id__in=[x[1] for x in subscriptions])
256 podcasts = {podcast.id: podcast for podcast in podcast}
258 subs = set((podcasts.get(x[1], None), not x[0]) for x in subscriptions)
259 subs = sorted(subs, key=lambda (p, _): PODCAST_SORT(p))
261 return render(request, 'privacy.html', {
262 'private_subscriptions': not request.user.get_wksetting(PUBLIC_SUB_USER),
263 'subscriptions': subs,
264 'domain': site.domain,
268 @vary_on_cookie
269 @cache_control(private=True)
270 @login_required
271 def share(request):
272 site = RequestSite(request)
274 if 'public_subscriptions' in request.GET:
275 @repeat_on_conflict(['user'])
276 def _update(user):
277 user.subscriptions_token = ''
278 user.save()
280 elif 'private_subscriptions' in request.GET:
281 @repeat_on_conflict(['user'])
282 def _update(user):
283 user.create_new_token('subscriptions_token')
284 user.save()
286 else:
287 _update = None
289 if _update:
290 _update(user=request.user)
292 token = request.user.get_token('subscriptions_token')
294 return render(request, 'share.html', {
295 'site': site,
296 'token': token,