Skip to content
GitLab
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
"""
import
csv
import
datetime
from
django.contrib
import
admin
from
django.contrib.auth.admin
import
UserAdmin
as
BaseUserAdmin
from
django.contrib.auth.models
import
User
...
...
@@ -12,6 +11,7 @@ from django.http import HttpResponse
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext_lazy
as
_
from
members.models
import
EmailChange
from
.
import
forms
,
models
...
...
@@ -145,6 +145,8 @@ class MemberAdmin(UserAdmin):
return
False
admin
.
site
.
register
(
EmailChange
)
# re-register User admin
admin
.
site
.
unregister
(
User
)
admin
.
site
.
register
(
User
,
UserAdmin
)
website/members/api/serializers.py
View file @
3be5cfc5
from
base64
import
b64encode
from
django.contrib.staticfiles.finders
import
find
as
find_static_file
from
django.templatetags.static
import
static
from
django.urls
import
reverse
from
rest_framework
import
serializers
from
thaliawebsite.api.services
import
create_image_thumbnail_dict
from
events.api.serializers
import
CalenderJSSerializer
from
members.models
import
Member
from
members.services
import
member_achievements
from
thaliawebsite.api.services
import
create_image_thumbnail_dict
from
utils.templatetags.thumbnail
import
thumbnail
...
...
website/members/api/viewsets.py
View file @
3be5cfc5
import
copy
from
datetime
import
datetime
from
django.utils
import
timezone
from
pytz.exceptions
import
InvalidTimeError
from
rest_framework
import
permissions
from
rest_framework
import
viewsets
,
filters
from
rest_framework.decorators
import
list_route
from
rest_framework.exceptions
import
ParseError
from
rest_framework.response
import
Response
from
pytz.exceptions
import
InvalidTimeError
from
members.api.serializers
import
(
MemberBirthdaySerializer
,
MemberRetrieveSerializer
,
...
...
website/members/emails.py
View file @
3be5cfc5
from
datetime
import
timedelta
from
django.core
import
mail
from
django.template
import
loader
from
django.template.defaultfilters
import
floatformat
from
django.urls
import
reverse
from
django.utils
import
translation
from
django.utils.datetime_safe
import
datetime
from
django.utils.translation
import
ugettext
as
_
from
django.template.defaultfilters
import
floatformat
from
members.models
import
Member
from
thaliawebsite
import
settings
...
...
@@ -92,7 +92,7 @@ def send_expiration_announcement(dry_run=False):
'members/email/expiration_announcement.txt'
,
{
'name'
:
member
.
get_full_name
(),
'membership_price'
:
floatformat
(
settings
.
MEMBERSHIP_PRICES
[
'year'
],
2
settings
.
MEMBERSHIP_PRICES
[
'year'
],
2
)})
mail
.
EmailMessage
(
_
(
'Membership expiration announcement'
),
...
...
@@ -125,3 +125,54 @@ def send_welcome_message(user, password, language):
user
.
email_user
(
_
(
'Welcome to Study Association Thalia'
),
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
from
django.contrib.auth.models
import
User
from
django.utils.translation
import
ugettext_lazy
as
_
from
members
import
emails
,
models
from
.models
import
Profile
from
members
import
emails
class
ProfileForm
(
forms
.
ModelForm
):
...
...
@@ -116,3 +116,9 @@ class UserChangeForm(BaseUserChangeForm):
self
.
cleaned_data
[
'username'
]
=
(
self
.
cleaned_data
[
'username'
]
.
lower
())
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 ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-0
5-29 16:25
+0200\n"
"PO-Revision-Date: 2018-0
5-29
1
6
:2
6
+0200\n"
"POT-Creation-Date: 2018-0
6-07 14:17
+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"
"Language-Team: \n"
"Language: nl\n"
...
...
@@ -16,61 +16,61 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\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"
msgstr "lidtype"
#: admin.py:5
7
#: admin.py:5
8
msgid "Age"
msgstr "Leeftijd"
#: admin.py:6
2
#: admin.py:6
3
msgid "≥ 18"
msgstr "≥ 18"
#: admin.py:6
3
#: admin.py:6
4
msgid "< 18"
msgstr "< 18"
#: admin.py:6
4
#: admin.py:6
5
msgid "Unknown"
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"
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"
msgstr "Achternaam"
#: admin.py:11
2
#: admin.py:11
3
msgid "Address"
msgstr "Adres"
#: admin.py:11
3
#: admin.py:11
4
msgid "Address line 2"
msgstr "Tweede adresregel"
#: admin.py:11
3
models.py:21
7
#: admin.py:11
4
models.py:21
8
msgid "Postal code"
msgstr "Postcode"
#: admin.py:11
3
models.py:22
3
#: admin.py:11
4
models.py:22
4
msgid "City"
msgstr "Woonplaats"
#: admin.py:12
3
#: admin.py:12
4
msgid "Download address label for selected users"
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"
msgstr "Studentnummer"
#: admin.py:13
8
#: admin.py:13
9
msgid "Download student number label for selected users"
msgstr "Download studentnummers voor geselecteerde gebruikers"
...
...
@@ -78,34 +78,46 @@ msgstr "Download studentnummers voor geselecteerde gebruikers"
msgid "Members"
msgstr "Leden"
#: emails.py:
28
#: emails.py:
30
msgid "Membership announcement"
msgstr "Mededeling over lidmaatschap"
#: emails.py:
38
#: emails.py:
40
msgid "Membership announcement sent"
msgstr "Mededeling over lidmaatschap verzonden"
#: emails.py:6
0
#: emails.py:6
2
msgid "Membership information check"
msgstr "Controle gegevens lidmaatschap"
#: emails.py:7
0
#: emails.py:7
2
msgid "Membership information check sent"
msgstr "Controle gegevens lidmaatschap verzonden"
#: emails.py:9
4
#: emails.py:9
9
msgid "Membership expiration announcement"
msgstr "Verlopen lidmaatschap"
#: emails.py:10
4
#: emails.py:10
9
msgid "Membership expiration announcement sent"
msgstr "Meldingen vervallen lidmaatschap verzonden"
#: emails.py:12
2
#: emails.py:12
7
msgid "Welcome to Study Association 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
msgid "Please enter a bank account"
msgstr "Voer een bankrekening in"
...
...
@@ -122,83 +134,83 @@ msgstr "Deze e-mail zal het gegenereerde wachtwoord bevatten"
msgid "Email address"
msgstr "E-mailadres"
#: models.py:12
5
#: models.py:12
6
msgid "Is this user currently active"
msgstr "Is deze user op dit moment actief"
#: models.py:1
59
#: models.py:1
60
msgid "Computing Science"
msgstr "Informatica"
#: models.py:16
0
#: models.py:16
1
msgid "Information Sciences"
msgstr "Informatiekunde"
#: models.py:17
4
templates/members/profile.html:44
#: models.py:17
5
templates/members/profile.html:44
msgid "Study programme"
msgstr "Studie"
#: models.py:18
4
#: models.py:18
5
msgid "Enter a valid student- or e/z/u-number."
msgstr "Voer een geldig student- of e/z/u-nummer in."
#: models.py:19
0
#: models.py:19
1
msgid "Starting year"
msgstr "Startjaar"
#: models.py:19
1
#: models.py:19
2
msgid "The year this member started studying."
msgstr "Het jaar waarop dit lid begon met studeren."
#: models.py:20
2
#: models.py:20
3
msgid "Include the house number"
msgstr "Inclusief huisnummer"
#: models.py:20
4
#: models.py:20
5
msgid "Street and house number"
msgstr "Straat en huisnummer"
#: models.py:21
0
#: models.py:21
1
msgid "Second address line"
msgstr "Tweede adresregel"
#: models.py:2
29
#: models.py:2
30
msgid "Phone number"
msgstr "Telefoonnummer"
#: models.py:23
0
#: models.py:23
1
msgid "Enter a phone number so Thalia may reach you"
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"
msgstr "Voer svp een geldig telefoonnummer in"
#: models.py:24
3
#: models.py:24
4
msgid "Emergency contact name"
msgstr "Contact voor noodgevallen"
#: models.py:24
4
#: models.py:24
5
msgid "Who should we contact in case of emergencies"
msgstr "Wie Thalia moet bereiken in bij noodgevallen"
#: models.py:25
1
#: models.py:25
2
msgid "Emergency contact phone number"
msgstr "Telefoonnummer noodcontact"
#: models.py:25
2
#: models.py:25
3
msgid "The phone number for the emergency contact"
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"
msgstr "Verjaardag"
#: models.py:2
69
#: models.py:2
70
msgid "Display birthday"
msgstr "Laat verjaardag zien"
#: models.py:27
1
#: models.py:27
2
msgid ""
"Show your birthday to other members on your profile page and in the birthday "
"calendar"
...
...
@@ -206,107 +218,107 @@ msgstr ""
"Toon je verjaardag aan andere leden op je profielpagina en in de "
"verjaardagskalender"
#: models.py:27
8
templates/members/profile.html:48
#: models.py:27
9
templates/members/profile.html:48
msgid "Website"
msgstr "Website"
#: models.py:2
79
#: models.py:2
80
msgid "Website to display on your profile page"
msgstr "Website om op je profiel te linken"
#: models.py:28
5
#: models.py:28
6
msgid "Profile text"
msgstr "Profieltekst"
#: models.py:28
6
#: models.py:28
7
msgid "Text to display on your profile"
msgstr "Tekst om te laten zien op je profielpagina"
#: models.py:29
4
#: models.py:29
5
msgid "Initials"
msgstr "Initialen"
#: models.py:30
1
#: models.py:30
2
msgid "Nickname"
msgstr "Bijnaam"
#: models.py:30
8
#: models.py:30
9
msgid "How to display name"
msgstr "Weergave naam"
#: models.py:30
9
#: models.py:3
1
0
msgid "Show full name"
msgstr "Volledige naam"
#: models.py:31
0
#: models.py:31
1
msgid "Show only nickname"
msgstr "Alleen initialen"
#: models.py:31
1
#: models.py:31
2
msgid "Show only first name"
msgstr "Alleen voornaam"
#: models.py:31
2
#: models.py:31
3
msgid "Show initials and last name"
msgstr "Alleen initialen en achternaam"
#: models.py:31
3
#: models.py:31
4
msgid "Show name like \"John 'nickname' Doe\""
msgstr "Laat zien als \"John 'bijnaam' Doe\""
#: models.py:31
4
#: models.py:31
5
msgid "Show nickname and last name"
msgstr "Laat bijnaam en achternaam zien"
#: models.py:3
19
#: models.py:3
20
msgid "Photo"
msgstr "Foto"
#: models.py:32
7
#: models.py:32
8
msgid "Which events can this member attend"
msgstr "Welke evenementen mag dit lid bijwonen"
#: models.py:32
8
#: models.py:32
9
msgid "All events"
msgstr "Alle evenementen"
#: models.py:3
29
#: models.py:3
30
msgid "User may not attend events"
msgstr "Gebruiker mag niet naar evenementen"
#: models.py:33
0
#: models.py:33
1
msgid "User may not attend drinks"
msgstr "Gebruiker mag niet naar borrels"
#: models.py:33
1
#: models.py:33
2
msgid "User may not attend anything"
msgstr "Gebruiker mag nergens heen"
#: models.py:33
8
#: models.py:33
9
msgid "Preferred language"
msgstr "Voorkeurstaal"
#: models.py:3
39
#: models.py:3
40
msgid "Preferred language for e.g. newsletters"
msgstr "Voorkeurstaal voor b.v.b. nieuwsbrieven"
#: models.py:34
6
#: models.py:34
7
msgid "Receive opt-in mailings"
msgstr "Ontvang opt-in mailings"
#: models.py:34
7
#: models.py:34
8
msgid "Receive mailings about vacancies and events from Thalia's sponsors."
msgstr "Ontvang mailings over vacatures en evenementen van Thalia's sponsoren."
#: models.py:35
3
#: models.py:35
4
msgid "Receive newsletter"
msgstr "Ontvang nieuwsbrief"
#: models.py:35
4
#: models.py:35
5
msgid "Receive the Thalia Newsletter"
msgstr "Ontvang de Thalia nieuwsbrief"
#: models.py:36
1
#: models.py:36
2
msgid ""
"Yes, I want Thalia to take the membership fees from my bank account through "
"direct debit for each year."
...
...
@@ -314,90 +326,126 @@ msgstr ""
"Ja, ik wil dat Thalia verschuldigde lidmaatschapsgelden elk jaar van mijn "
"bankrekening afschrijft."
#: models.py:36
4
#: models.py:36
5
msgid "No, I will pay the contribution myself"
msgstr "Nee, ik zal de contributie zelf betalen"
#: models.py:36
5
#: models.py:36
6
msgid "Direct debit"
msgstr "Automatische afschijving"
#: models.py:36
6
#: models.py:36
7
msgid "Each year, have Thalia take the membership fees from my bank account"
msgstr ""
"Laat Thalia elk jaar het lidmaatschapsgeld van mijn bankrekening afschrijven"
#: models.py:37
2
#: models.py:37
3
msgid "Bank account"
msgstr "Bankrekening"
#: models.py:37
3
#: models.py:37
4
msgid "Bank account for direct debit"
msgstr "Bankrekening voor automatische afschrijving"
#: models.py:39
7
#: models.py:39
8
msgid "Display name"
msgstr "Weergavenaam"
#: models.py:42
6
#: models.py:42
7
msgid "You need to enter a nickname to use it as display name"
msgstr ""
"Je moet een bijnaam invoeren voordat je deze kunt gebruiken als weergavenaam"
#: models.py:43
1
#: models.py:43
2
msgid "A birthday cannot be in the future."
msgstr "Een verjaardag kan niet in de toekomst liggen."
#: models.py:48
1
#: models.py:48
2
msgid "Member"
msgstr "Lid"
#: models.py:48
2
#: models.py:48
3
msgid "Supporter"
msgstr "Begunstiger"
#: models.py:48
3
#: models.py:48
4
msgid "Honorary Member"
msgstr "Erelid"
#: models.py:48
8
templates/members/profile.html:37
#: models.py:48
9
templates/members/profile.html:37
msgid "Membership type"
msgstr "Lidtype"
#: models.py:49
4
#: models.py:49
5
msgid "User"
msgstr "Gebruiker"
#: models.py:49
8
#: models.py:49
9
msgid "Membership since"
msgstr "Lid sinds"
#: models.py:
499
#: models.py:
500
msgid "The date the member started holding this membership."
msgstr "De datum waarop het lid dit lidmaatschap is begonnen."
#: models.py:50
4
#: models.py:50
5
msgid "Membership until"
msgstr "Lid tot"
#: models.py:50
5
#: models.py:50
6
msgid "The date the member stops holding this membership."
msgstr "De datum waarop het lid dit lidmaatschap beëindigd."
#: models.py:51
6
#: models.py:51
7
msgid "End date can't be before start date"
msgstr "De einddatum kan niet eerder zijn dan de startdatum"
#: models.py:53
0
models.py:53
2
#: models.py:53
1
models.py:53
3
msgid "A membership already exists for that period"
msgstr "Er bestaat al een lidmaatschap voor deze periode"