Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
thalia
concrexit
Commits
3be5cfc5
Verified
Commit
3be5cfc5
authored
Jun 07, 2018
by
Sébastiaan Versteeg
Browse files
Add email change feature to members
parent
73fa3a39
Changes
25
Hide whitespace changes
Inline
Side-by-side
website/members/admin.py
View file @
3be5cfc5
...
@@ -3,7 +3,6 @@ This module registers admin pages for the models
...
@@ -3,7 +3,6 @@ This module registers admin pages for the models
"""
"""
import
csv
import
csv
import
datetime
import
datetime
from
django.contrib
import
admin
from
django.contrib
import
admin
from
django.contrib.auth.admin
import
UserAdmin
as
BaseUserAdmin
from
django.contrib.auth.admin
import
UserAdmin
as
BaseUserAdmin
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
...
@@ -12,6 +11,7 @@ from django.http import HttpResponse
...
@@ -12,6 +11,7 @@ from django.http import HttpResponse
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
members.models
import
EmailChange
from
.
import
forms
,
models
from
.
import
forms
,
models
...
@@ -145,6 +145,8 @@ class MemberAdmin(UserAdmin):
...
@@ -145,6 +145,8 @@ class MemberAdmin(UserAdmin):
return
False
return
False
admin
.
site
.
register
(
EmailChange
)
# re-register User admin
# re-register User admin
admin
.
site
.
unregister
(
User
)
admin
.
site
.
unregister
(
User
)
admin
.
site
.
register
(
User
,
UserAdmin
)
admin
.
site
.
register
(
User
,
UserAdmin
)
website/members/api/serializers.py
View file @
3be5cfc5
from
base64
import
b64encode
from
base64
import
b64encode
from
django.contrib.staticfiles.finders
import
find
as
find_static_file
from
django.contrib.staticfiles.finders
import
find
as
find_static_file
from
django.templatetags.static
import
static
from
django.templatetags.static
import
static
from
django.urls
import
reverse
from
django.urls
import
reverse
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
thaliawebsite.api.services
import
create_image_thumbnail_dict
from
events.api.serializers
import
CalenderJSSerializer
from
events.api.serializers
import
CalenderJSSerializer
from
members.models
import
Member
from
members.models
import
Member
from
members.services
import
member_achievements
from
members.services
import
member_achievements
from
thaliawebsite.api.services
import
create_image_thumbnail_dict
from
utils.templatetags.thumbnail
import
thumbnail
from
utils.templatetags.thumbnail
import
thumbnail
...
...
website/members/api/viewsets.py
View file @
3be5cfc5
import
copy
import
copy
from
datetime
import
datetime
from
datetime
import
datetime
from
django.utils
import
timezone
from
django.utils
import
timezone
from
pytz.exceptions
import
InvalidTimeError
from
rest_framework
import
permissions
from
rest_framework
import
permissions
from
rest_framework
import
viewsets
,
filters
from
rest_framework
import
viewsets
,
filters
from
rest_framework.decorators
import
list_route
from
rest_framework.decorators
import
list_route
from
rest_framework.exceptions
import
ParseError
from
rest_framework.exceptions
import
ParseError
from
rest_framework.response
import
Response
from
rest_framework.response
import
Response
from
pytz.exceptions
import
InvalidTimeError
from
members.api.serializers
import
(
MemberBirthdaySerializer
,
from
members.api.serializers
import
(
MemberBirthdaySerializer
,
MemberRetrieveSerializer
,
MemberRetrieveSerializer
,
...
...
website/members/emails.py
View file @
3be5cfc5
from
datetime
import
timedelta
from
datetime
import
timedelta
from
django.core
import
mail
from
django.core
import
mail
from
django.template
import
loader
from
django.template
import
loader
from
django.template.defaultfilters
import
floatformat
from
django.urls
import
reverse
from
django.utils
import
translation
from
django.utils
import
translation
from
django.utils.datetime_safe
import
datetime
from
django.utils.datetime_safe
import
datetime
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.template.defaultfilters
import
floatformat
from
members.models
import
Member
from
members.models
import
Member
from
thaliawebsite
import
settings
from
thaliawebsite
import
settings
...
@@ -92,7 +92,7 @@ def send_expiration_announcement(dry_run=False):
...
@@ -92,7 +92,7 @@ def send_expiration_announcement(dry_run=False):
'members/email/expiration_announcement.txt'
,
'members/email/expiration_announcement.txt'
,
{
'name'
:
member
.
get_full_name
(),
{
'name'
:
member
.
get_full_name
(),
'membership_price'
:
floatformat
(
'membership_price'
:
floatformat
(
settings
.
MEMBERSHIP_PRICES
[
'year'
],
2
settings
.
MEMBERSHIP_PRICES
[
'year'
],
2
)})
)})
mail
.
EmailMessage
(
mail
.
EmailMessage
(
_
(
'Membership expiration announcement'
),
_
(
'Membership expiration announcement'
),
...
@@ -125,3 +125,54 @@ def send_welcome_message(user, password, language):
...
@@ -125,3 +125,54 @@ def send_welcome_message(user, password, language):
user
.
email_user
(
user
.
email_user
(
_
(
'Welcome to Study Association Thalia'
),
_
(
'Welcome to Study Association Thalia'
),
email_body
)
email_body
)
def
send_email_change_confirmation_messages
(
change_request
):
member
=
change_request
.
member
with
translation
.
override
(
member
.
profile
.
language
):
mail
.
EmailMessage
(
'[THALIA] {}'
.
format
(
_
(
'Please confirm your email change'
)),
loader
.
render_to_string
(
'members/email/email_change_confirm.txt'
,
{
'confirm_link'
:
'{}{}'
.
format
(
'https://thalia.nu'
,
reverse
(
'members:email-change-confirm'
,
args
=
[
change_request
.
confirm_key
]
)),
'name'
:
member
.
first_name
}
),
settings
.
WEBSITE_FROM_ADDRESS
,
[
change_request
.
email
]
).
send
()
mail
.
EmailMessage
(
'[THALIA] {}'
.
format
(
_
(
'Please verify your email address'
)),
loader
.
render_to_string
(
'members/email/email_change_verify.txt'
,
{
'confirm_link'
:
'{}{}'
.
format
(
'https://thalia.nu'
,
reverse
(
'members:email-change-verify'
,
args
=
[
change_request
.
verify_key
]
)),
'name'
:
member
.
first_name
}
),
settings
.
WEBSITE_FROM_ADDRESS
,
[
change_request
.
email
]
).
send
()
def
send_email_change_completion_message
(
change_request
):
change_request
.
member
.
email_user
(
'[THALIA] {}'
.
format
(
_
(
'Your email address has been changed'
)),
loader
.
render_to_string
(
'members/email/email_change_completed.txt'
,
{
'name'
:
change_request
.
member
.
first_name
}
))
website/members/forms.py
View file @
3be5cfc5
...
@@ -6,8 +6,8 @@ from django.contrib.auth.forms import UserCreationForm as BaseUserCreationForm
...
@@ -6,8 +6,8 @@ from django.contrib.auth.forms import UserCreationForm as BaseUserCreationForm
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
members
import
emails
,
models
from
.models
import
Profile
from
.models
import
Profile
from
members
import
emails
class
ProfileForm
(
forms
.
ModelForm
):
class
ProfileForm
(
forms
.
ModelForm
):
...
@@ -116,3 +116,9 @@ class UserChangeForm(BaseUserChangeForm):
...
@@ -116,3 +116,9 @@ class UserChangeForm(BaseUserChangeForm):
self
.
cleaned_data
[
'username'
]
=
(
self
.
cleaned_data
[
'username'
]
self
.
cleaned_data
[
'username'
]
=
(
self
.
cleaned_data
[
'username'
]
.
lower
())
.
lower
())
super
().
clean
()
super
().
clean
()
class
EmailChangeForm
(
forms
.
ModelForm
):
class
Meta
:
model
=
models
.
EmailChange
fields
=
[
'email'
,
'member'
]
website/members/locale/nl/LC_MESSAGES/django.mo
View file @
3be5cfc5
No preview for this file type
website/members/locale/nl/LC_MESSAGES/django.po
View file @
3be5cfc5
...
@@ -7,8 +7,8 @@ msgid ""
...
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
msgstr ""
"Project-Id-Version: \n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-0
5-29 16:25
+0200\n"
"POT-Creation-Date: 2018-0
6-07 14:17
+0200\n"
"PO-Revision-Date: 2018-0
5-29
1
6
:2
6
+0200\n"
"PO-Revision-Date: 2018-0
6-07
1
4
:2
5
+0200\n"
"Last-Translator: Sébastiaan Versteeg <se_bastiaan@outlook.com>\n"
"Last-Translator: Sébastiaan Versteeg <se_bastiaan@outlook.com>\n"
"Language-Team: \n"
"Language-Team: \n"
"Language: nl\n"
"Language: nl\n"
...
@@ -16,61 +16,61 @@ msgstr ""
...
@@ -16,61 +16,61 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit
1.8.7.1
\n"
"X-Generator: Poedit
2.0.4
\n"
#: admin.py:
39
#: admin.py:
40
msgid "membership type"
msgid "membership type"
msgstr "lidtype"
msgstr "lidtype"
#: admin.py:5
7
#: admin.py:5
8
msgid "Age"
msgid "Age"
msgstr "Leeftijd"
msgstr "Leeftijd"
#: admin.py:6
2
#: admin.py:6
3
msgid "≥ 18"
msgid "≥ 18"
msgstr "≥ 18"
msgstr "≥ 18"
#: admin.py:6
3
#: admin.py:6
4
msgid "< 18"
msgid "< 18"
msgstr "< 18"
msgstr "< 18"
#: admin.py:6
4
#: admin.py:6
5
msgid "Unknown"
msgid "Unknown"
msgstr "Onbekend"
msgstr "Onbekend"
#: admin.py:11
2
admin.py:13
1
forms.py:87
#: admin.py:11
3
admin.py:13
2
forms.py:87
msgid "First name"
msgid "First name"
msgstr "Voornaam"
msgstr "Voornaam"
#: admin.py:11
2
admin.py:13
1
forms.py:95
#: admin.py:11
3
admin.py:13
2
forms.py:95
msgid "Last name"
msgid "Last name"
msgstr "Achternaam"
msgstr "Achternaam"
#: admin.py:11
2
#: admin.py:11
3
msgid "Address"
msgid "Address"
msgstr "Adres"
msgstr "Adres"
#: admin.py:11
3
#: admin.py:11
4
msgid "Address line 2"
msgid "Address line 2"
msgstr "Tweede adresregel"
msgstr "Tweede adresregel"
#: admin.py:11
3
models.py:21
7
#: admin.py:11
4
models.py:21
8
msgid "Postal code"
msgid "Postal code"
msgstr "Postcode"
msgstr "Postcode"
#: admin.py:11
3
models.py:22
3
#: admin.py:11
4
models.py:22
4
msgid "City"
msgid "City"
msgstr "Woonplaats"
msgstr "Woonplaats"
#: admin.py:12
3
#: admin.py:12
4
msgid "Download address label for selected users"
msgid "Download address label for selected users"
msgstr "Download adreslabels voor geselecteerde gebruikers"
msgstr "Download adreslabels voor geselecteerde gebruikers"
#: admin.py:13
1
models.py:18
0
#: admin.py:13
2
models.py:18
1
msgid "Student number"
msgid "Student number"
msgstr "Studentnummer"
msgstr "Studentnummer"
#: admin.py:13
8
#: admin.py:13
9
msgid "Download student number label for selected users"
msgid "Download student number label for selected users"
msgstr "Download studentnummers voor geselecteerde gebruikers"
msgstr "Download studentnummers voor geselecteerde gebruikers"
...
@@ -78,34 +78,46 @@ msgstr "Download studentnummers voor geselecteerde gebruikers"
...
@@ -78,34 +78,46 @@ msgstr "Download studentnummers voor geselecteerde gebruikers"
msgid "Members"
msgid "Members"
msgstr "Leden"
msgstr "Leden"
#: emails.py:
28
#: emails.py:
30
msgid "Membership announcement"
msgid "Membership announcement"
msgstr "Mededeling over lidmaatschap"
msgstr "Mededeling over lidmaatschap"
#: emails.py:
38
#: emails.py:
40
msgid "Membership announcement sent"
msgid "Membership announcement sent"
msgstr "Mededeling over lidmaatschap verzonden"
msgstr "Mededeling over lidmaatschap verzonden"
#: emails.py:6
0
#: emails.py:6
2
msgid "Membership information check"
msgid "Membership information check"
msgstr "Controle gegevens lidmaatschap"
msgstr "Controle gegevens lidmaatschap"
#: emails.py:7
0
#: emails.py:7
2
msgid "Membership information check sent"
msgid "Membership information check sent"
msgstr "Controle gegevens lidmaatschap verzonden"
msgstr "Controle gegevens lidmaatschap verzonden"
#: emails.py:9
4
#: emails.py:9
9
msgid "Membership expiration announcement"
msgid "Membership expiration announcement"
msgstr "Verlopen lidmaatschap"
msgstr "Verlopen lidmaatschap"
#: emails.py:10
4
#: emails.py:10
9
msgid "Membership expiration announcement sent"
msgid "Membership expiration announcement sent"
msgstr "Meldingen vervallen lidmaatschap verzonden"
msgstr "Meldingen vervallen lidmaatschap verzonden"
#: emails.py:12
2
#: emails.py:12
7
msgid "Welcome to Study Association Thalia"
msgid "Welcome to Study Association Thalia"
msgstr "Welkom bij Studievereniging Thalia"
msgstr "Welkom bij Studievereniging Thalia"
#: emails.py:135
msgid "Please confirm your email change"
msgstr "Bevestig de verandering van je e-mailadres"
#: emails.py:153
msgid "Please verify your email address"
msgstr "Verifieer je nieuwe e-mailadres"
#: emails.py:173
msgid "Your email address has been changed"
msgstr "Je e-mailadres is aangepast"
#: forms.py:31
#: forms.py:31
msgid "Please enter a bank account"
msgid "Please enter a bank account"
msgstr "Voer een bankrekening in"
msgstr "Voer een bankrekening in"
...
@@ -122,83 +134,83 @@ msgstr "Deze e-mail zal het gegenereerde wachtwoord bevatten"
...
@@ -122,83 +134,83 @@ msgstr "Deze e-mail zal het gegenereerde wachtwoord bevatten"
msgid "Email address"
msgid "Email address"
msgstr "E-mailadres"
msgstr "E-mailadres"
#: models.py:12
5
#: models.py:12
6
msgid "Is this user currently active"
msgid "Is this user currently active"
msgstr "Is deze user op dit moment actief"
msgstr "Is deze user op dit moment actief"
#: models.py:1
59
#: models.py:1
60
msgid "Computing Science"
msgid "Computing Science"
msgstr "Informatica"
msgstr "Informatica"
#: models.py:16
0
#: models.py:16
1
msgid "Information Sciences"
msgid "Information Sciences"
msgstr "Informatiekunde"
msgstr "Informatiekunde"
#: models.py:17
4
templates/members/profile.html:44
#: models.py:17
5
templates/members/profile.html:44
msgid "Study programme"
msgid "Study programme"
msgstr "Studie"
msgstr "Studie"
#: models.py:18
4
#: models.py:18
5
msgid "Enter a valid student- or e/z/u-number."
msgid "Enter a valid student- or e/z/u-number."
msgstr "Voer een geldig student- of e/z/u-nummer in."
msgstr "Voer een geldig student- of e/z/u-nummer in."
#: models.py:19
0
#: models.py:19
1
msgid "Starting year"
msgid "Starting year"
msgstr "Startjaar"
msgstr "Startjaar"
#: models.py:19
1
#: models.py:19
2
msgid "The year this member started studying."
msgid "The year this member started studying."
msgstr "Het jaar waarop dit lid begon met studeren."
msgstr "Het jaar waarop dit lid begon met studeren."
#: models.py:20
2
#: models.py:20
3
msgid "Include the house number"
msgid "Include the house number"
msgstr "Inclusief huisnummer"
msgstr "Inclusief huisnummer"
#: models.py:20
4
#: models.py:20
5
msgid "Street and house number"
msgid "Street and house number"
msgstr "Straat en huisnummer"
msgstr "Straat en huisnummer"
#: models.py:21
0
#: models.py:21
1
msgid "Second address line"
msgid "Second address line"
msgstr "Tweede adresregel"
msgstr "Tweede adresregel"
#: models.py:2
29
#: models.py:2
30
msgid "Phone number"
msgid "Phone number"
msgstr "Telefoonnummer"
msgstr "Telefoonnummer"
#: models.py:23
0
#: models.py:23
1
msgid "Enter a phone number so Thalia may reach you"
msgid "Enter a phone number so Thalia may reach you"
msgstr "Voer een telefoonnummer in zodat Thalia je kan bereiken"
msgstr "Voer een telefoonnummer in zodat Thalia je kan bereiken"
#: models.py:23
3
models.py:25
5
#: models.py:23
4
models.py:25
6
msgid "Please enter a valid phone number"
msgid "Please enter a valid phone number"
msgstr "Voer svp een geldig telefoonnummer in"
msgstr "Voer svp een geldig telefoonnummer in"
#: models.py:24
3
#: models.py:24
4
msgid "Emergency contact name"
msgid "Emergency contact name"
msgstr "Contact voor noodgevallen"
msgstr "Contact voor noodgevallen"
#: models.py:24
4
#: models.py:24
5
msgid "Who should we contact in case of emergencies"
msgid "Who should we contact in case of emergencies"
msgstr "Wie Thalia moet bereiken in bij noodgevallen"
msgstr "Wie Thalia moet bereiken in bij noodgevallen"
#: models.py:25
1
#: models.py:25
2
msgid "Emergency contact phone number"
msgid "Emergency contact phone number"
msgstr "Telefoonnummer noodcontact"
msgstr "Telefoonnummer noodcontact"
#: models.py:25
2
#: models.py:25
3
msgid "The phone number for the emergency contact"
msgid "The phone number for the emergency contact"
msgstr "Het telefoonummer van de noodcontact"
msgstr "Het telefoonummer van de noodcontact"
#: models.py:26
4
templates/members/profile.html:52
#: models.py:26
5
templates/members/profile.html:52
msgid "Birthday"
msgid "Birthday"
msgstr "Verjaardag"
msgstr "Verjaardag"
#: models.py:2
69
#: models.py:2
70
msgid "Display birthday"
msgid "Display birthday"
msgstr "Laat verjaardag zien"
msgstr "Laat verjaardag zien"
#: models.py:27
1
#: models.py:27
2
msgid ""
msgid ""
"Show your birthday to other members on your profile page and in the birthday "
"Show your birthday to other members on your profile page and in the birthday "
"calendar"
"calendar"
...
@@ -206,107 +218,107 @@ msgstr ""
...
@@ -206,107 +218,107 @@ msgstr ""
"Toon je verjaardag aan andere leden op je profielpagina en in de "
"Toon je verjaardag aan andere leden op je profielpagina en in de "
"verjaardagskalender"
"verjaardagskalender"
#: models.py:27
8
templates/members/profile.html:48
#: models.py:27
9
templates/members/profile.html:48
msgid "Website"
msgid "Website"
msgstr "Website"
msgstr "Website"
#: models.py:2
79
#: models.py:2
80
msgid "Website to display on your profile page"
msgid "Website to display on your profile page"
msgstr "Website om op je profiel te linken"
msgstr "Website om op je profiel te linken"
#: models.py:28
5
#: models.py:28
6
msgid "Profile text"
msgid "Profile text"
msgstr "Profieltekst"
msgstr "Profieltekst"
#: models.py:28
6
#: models.py:28
7
msgid "Text to display on your profile"
msgid "Text to display on your profile"
msgstr "Tekst om te laten zien op je profielpagina"
msgstr "Tekst om te laten zien op je profielpagina"
#: models.py:29
4
#: models.py:29
5
msgid "Initials"
msgid "Initials"
msgstr "Initialen"
msgstr "Initialen"
#: models.py:30
1
#: models.py:30
2
msgid "Nickname"
msgid "Nickname"
msgstr "Bijnaam"
msgstr "Bijnaam"
#: models.py:30
8
#: models.py:30
9
msgid "How to display name"
msgid "How to display name"
msgstr "Weergave naam"
msgstr "Weergave naam"
#: models.py:30
9
#: models.py:3
1
0
msgid "Show full name"
msgid "Show full name"
msgstr "Volledige naam"
msgstr "Volledige naam"
#: models.py:31
0
#: models.py:31
1
msgid "Show only nickname"