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
.usersettings
.models
import UserSettings
35 from mygpo
.decorators
import allowed_methods
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
, PUBLIC_SUB_PODCAST
, \
40 FLATTR_TOKEN
, FLATTR_AUTO
, FLATTR_MYGPO
, FLATTR_USERNAME
45 @cache_control(private
=True)
46 @allowed_methods(['GET', 'POST'])
49 if request
.method
== 'GET':
51 site
= RequestSite(request
)
52 flattr
= Flattr(request
.user
, site
.domain
, request
.is_secure())
53 userpage_token
= request
.user
.profile
.get_token('userpage_token')
55 profile_form
= ProfileForm({
56 'twitter': request
.user
.profile
.twitter
,
57 'about': request
.user
.profile
.about
,
60 form
= UserAccountForm({
61 'email': request
.user
.email
,
62 'public': request
.user
.profile
.settings
.get_wksetting(PUBLIC_SUB_USER
)
65 flattr_form
= FlattrForm({
66 'enable': request
.user
.profile
.settings
.get_wksetting(FLATTR_AUTO
),
67 'token': request
.user
.profile
.settings
.get_wksetting(FLATTR_TOKEN
),
68 'flattr_mygpo': request
.user
.profile
.settings
.get_wksetting(FLATTR_MYGPO
),
69 'username': request
.user
.profile
.settings
.get_wksetting(FLATTR_USERNAME
),
72 return render(request
, 'account.html', {
75 'profile_form': profile_form
,
76 'flattr_form': flattr_form
,
78 'userpage_token': userpage_token
,
82 form
= UserAccountForm(request
.POST
)
84 if not form
.is_valid():
85 raise ValueError(_('Oops! Something went wrong. Please double-check the data you entered.'))
87 if form
.cleaned_data
['password_current']:
88 if not request
.user
.check_password(form
.cleaned_data
['password_current']):
89 raise ValueError('Current password is incorrect')
91 request
.user
.set_password(form
.cleaned_data
['password1'])
93 request
.user
.email
= form
.cleaned_data
['email']
97 except Exception as ex
:
98 # TODO: which exception?
99 messages
.error(request
, str(ex
))
101 messages
.success(request
, 'Account updated')
103 except (ValueError, ValidationError
) as e
:
104 messages
.error(request
, str(e
))
106 return render(request
, 'account.html', {
111 class ProfileView(View
):
112 """ Updates the public profile and redirects back to the account view """
114 def post(self
, request
):
117 form
= ProfileForm(request
.POST
)
119 if not form
.is_valid():
120 raise ValueError(_('Oops! Something went wrong. Please double-check the data you entered.'))
122 request
.user
.twitter
= normalize_twitter(form
.cleaned_data
['twitter'])
123 request
.user
.about
= strip_tags(form
.cleaned_data
['about'])
126 messages
.success(request
, _('Data updated'))
128 return HttpResponseRedirect(reverse('account') + '#profile')
131 class FlattrSettingsView(View
):
132 """ Updates Flattr settings and redirects back to the Account page """
134 def post(self
, request
):
137 form
= FlattrForm(request
.POST
)
139 if not form
.is_valid():
140 raise ValueError('asdf')
142 auto_flattr
= form
.cleaned_data
.get('enable', False)
143 flattr_mygpo
= form
.cleaned_data
.get('flattr_mygpo', False)
144 username
= form
.cleaned_data
.get('username', '')
146 settings
= user
.profile
.settings
147 settings
.set_wksetting(FLATTR_AUTO
, auto_flattr
)
148 settings
.set_wksetting(FLATTR_MYGPO
, flattr_mygpo
)
149 settings
.set_wksetting(FLATTR_USERNAME
, username
)
152 return HttpResponseRedirect(reverse('account') + '#flattr')
155 class FlattrLogout(View
):
156 """ Removes Flattr authentication token """
158 def get(self
, request
):
160 settings
= user
.profile
.settings
161 settings
.set_wksetting(FLATTR_AUTO
, False)
162 settings
.set_wksetting(FLATTR_TOKEN
, False)
163 settings
.set_wksetting(FLATTR_MYGPO
, False)
165 return HttpResponseRedirect(reverse('account') + '#flattr')
168 class FlattrTokenView(View
):
169 """ Callback for the Flattr authentication
171 Updates the user's Flattr token and redirects back to the account page """
173 def get(self
, request
):
176 site
= RequestSite(request
)
177 flattr
= Flattr(user
, site
.domain
, request
.is_secure())
179 url
= request
.build_absolute_uri()
180 token
= flattr
.process_retrieved_code(url
)
182 messages
.success(request
, _('Authentication successful'))
183 settings
= user
.profile
.settings
184 settings
.set_wksetting(FLATTR_TOKEN
, token
)
188 messages
.error(request
, _('Authentication failed. Try again later'))
190 return HttpResponseRedirect(reverse('account') + '#flattr')
193 class AccountRemoveGoogle(View
):
194 """ Removes the connected Google account """
196 @method_decorator(login_required
)
197 def post(self
, request
):
198 request
.user
.google_email
= None
200 messages
.success(request
, _('Your account has been disconnected'))
201 return HttpResponseRedirect(reverse('account'))
206 @allowed_methods(['GET', 'POST'])
207 def delete_account(request
):
209 if request
.method
== 'GET':
210 return render(request
, 'delete_account.html')
212 user
.is_active
= False
216 return render(request
, 'deleted_account.html')
220 class DefaultPrivacySettings(View
):
224 @method_decorator(login_required
)
225 @method_decorator(never_cache
)
226 def post(self
, request
):
227 profile
= request
.user
.profile
228 profile
.set_setting(PUBLIC_SUB_USER
.name
, self
.public
)
230 return HttpResponseRedirect(reverse('privacy'))
233 class PodcastPrivacySettings(View
):
237 @method_decorator(login_required
)
238 @method_decorator(never_cache
)
239 def post(self
, request
, podcast_id
):
240 podcast
= Podcast
.objects
.get(id=podcast_id
)
242 settings
, created
= UserSettings
.objects
.get_or_create(
244 content_type
=ContentType
.objects
.get_for_model(podcast
),
245 object_id
=podcast
.pk
,
248 settings
.set_wksetting(PUBLIC_SUB_PODCAST
, self
.public
)
250 return HttpResponseRedirect(reverse('privacy'))
255 def privacy(request
):
256 site
= RequestSite(request
)
259 podcasts
= Podcast
.objects
.filter(subscription__user
=user
)\
261 private
= UserSettings
.objects
.get_private_podcasts(user
)
264 for podcast
in podcasts
:
266 subscriptions
.append( (podcast
, podcast
in private
) )
268 return render(request
, 'privacy.html', {
269 'private_subscriptions': not request
.user
.profile
.settings
.get_wksetting(PUBLIC_SUB_USER
),
270 'subscriptions': subscriptions
,
271 'domain': site
.domain
,
276 @cache_control(private
=True)
279 site
= RequestSite(request
)
283 if 'public_subscriptions' in request
.GET
:
284 user
.profile
.subscriptions_token
= ''
287 elif 'private_subscriptions' in request
.GET
:
288 user
.profile
.create_new_token('subscriptions_token')
291 token
= user
.profile
.get_token('subscriptions_token')
293 return render(request
, 'share.html', {