Merge pull request #564 from cptpcrd/performance
[mygpo.git] / mygpo / users / views / settings.py
blob9fdbd28d9529b57ab7d29f2756d271af1b912635
1 from django.shortcuts import render
2 from django.urls import reverse
3 from django.http import HttpResponseRedirect
4 from django.contrib.auth import logout
5 from django.contrib import messages
6 from django.forms import ValidationError
7 from django.utils.translation import gettext as _
8 from django.contrib.auth.decorators import login_required
9 from django.contrib.contenttypes.models import ContentType
10 from django.contrib.sites.requests import RequestSite
11 from django.views.decorators.vary import vary_on_cookie
12 from django.views.decorators.cache import never_cache, cache_control
13 from django.utils.decorators import method_decorator
14 from django.views.generic.base import View
15 from django.utils.html import strip_tags
17 from mygpo.podcasts.models import Podcast
18 from mygpo.usersettings.models import UserSettings
19 from mygpo.decorators import allowed_methods
20 from mygpo.web.forms import UserAccountForm, ProfileForm
21 from mygpo.web.utils import normalize_twitter
22 from mygpo.users.settings import PUBLIC_SUB_USER, PUBLIC_SUB_PODCAST
25 @login_required
26 @vary_on_cookie
27 @cache_control(private=True)
28 @allowed_methods(["GET", "POST"])
29 def account(request):
31 if request.method == "GET":
33 site = RequestSite(request)
34 userpage_token = request.user.profile.get_token("userpage_token")
36 profile_form = ProfileForm(
38 "twitter": request.user.profile.twitter,
39 "about": request.user.profile.about,
43 form = UserAccountForm(
45 "email": request.user.email,
46 "public": request.user.profile.settings.get_wksetting(PUBLIC_SUB_USER),
50 return render(
51 request,
52 "account.html",
54 "site": site,
55 "form": form,
56 "profile_form": profile_form,
57 "userpage_token": userpage_token,
61 try:
62 form = UserAccountForm(request.POST)
64 if not form.is_valid():
65 raise ValueError(
67 "Oops! Something went wrong. Please double-check the data you entered."
71 if form.cleaned_data["password_current"]:
72 if not request.user.check_password(form.cleaned_data["password_current"]):
73 raise ValueError("Current password is incorrect")
75 request.user.set_password(form.cleaned_data["password1"])
77 request.user.email = form.cleaned_data["email"]
79 try:
80 request.user.save()
81 except Exception as ex:
82 # TODO: which exception?
83 messages.error(request, str(ex))
85 messages.success(request, "Account updated")
87 except (ValueError, ValidationError) as e:
88 messages.error(request, str(e))
90 return render(request, "account.html", {"form": form})
93 class ProfileView(View):
94 """Updates the public profile and redirects back to the account view"""
96 def post(self, request):
97 user = request.user
99 form = ProfileForm(request.POST)
101 if not form.is_valid():
102 raise ValueError(
104 "Oops! Something went wrong. Please double-check the data you entered."
108 request.user.twitter = normalize_twitter(form.cleaned_data["twitter"])
109 request.user.about = strip_tags(form.cleaned_data["about"])
111 request.user.save()
112 messages.success(request, _("Data updated"))
114 return HttpResponseRedirect(reverse("account") + "#profile")
117 class AccountRemoveGoogle(View):
118 """Removes the connected Google account"""
120 @method_decorator(login_required)
121 def post(self, request):
122 request.user.google_email = None
123 request.user.save()
124 messages.success(request, _("Your account has been disconnected"))
125 return HttpResponseRedirect(reverse("account"))
128 @login_required
129 @never_cache
130 @allowed_methods(["GET", "POST"])
131 def delete_account(request):
133 if request.method == "GET":
134 return render(request, "delete_account.html")
136 user = request.user
137 user.is_active = False
138 user.save()
139 logout(request)
140 return render(request, "deleted_account.html")
143 class DefaultPrivacySettings(View):
145 public = True
147 @method_decorator(login_required)
148 @method_decorator(never_cache)
149 def post(self, request):
150 settings = request.user.profile.settings
151 settings.set_setting(PUBLIC_SUB_USER.name, self.public)
152 settings.save()
153 return HttpResponseRedirect(reverse("privacy"))
156 class PodcastPrivacySettings(View):
158 public = True
160 @method_decorator(login_required)
161 @method_decorator(never_cache)
162 def post(self, request, podcast_id):
163 podcast = Podcast.objects.get(id=podcast_id)
165 settings, created = UserSettings.objects.get_or_create(
166 user=request.user,
167 content_type=ContentType.objects.get_for_model(podcast),
168 object_id=podcast.pk,
171 settings.set_wksetting(PUBLIC_SUB_PODCAST, self.public)
172 settings.save()
173 return HttpResponseRedirect(reverse("privacy"))
176 @login_required
177 @never_cache
178 def privacy(request):
179 site = RequestSite(request)
180 user = request.user
182 podcasts = (
183 Podcast.objects.filter(subscription__user=user)
184 .distinct("pk")
185 .prefetch_related("slugs")
187 private = UserSettings.objects.get_private_podcasts(user)
189 subscriptions = []
190 for podcast in podcasts:
192 subscriptions.append((podcast, podcast in private))
194 return render(
195 request,
196 "privacy.html",
198 "private_subscriptions": not request.user.profile.settings.get_wksetting(
199 PUBLIC_SUB_USER
201 "subscriptions": subscriptions,
202 "domain": site.domain,
207 @vary_on_cookie
208 @cache_control(private=True)
209 @login_required
210 def share(request):
211 site = RequestSite(request)
213 user = request.user
215 if "public_subscriptions" in request.GET:
216 user.profile.subscriptions_token = ""
217 user.profile.save()
219 elif "private_subscriptions" in request.GET:
220 user.profile.create_new_token("subscriptions_token")
221 user.profile.save()
223 token = user.profile.get_token("subscriptions_token")
225 return render(request, "share.html", {"site": site, "token": token})