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
f77c801a
Commit
f77c801a
authored
Apr 24, 2019
by
Luko van der Maas
Browse files
Merge branch 'feature/newsletter-planning' into 'master'
Add newsletter planning feature See merge request
!1206
parents
18baa35a
eb3a112b
Changes
13
Hide whitespace changes
Inline
Side-by-side
website/events/api/viewsets.py
View file @
f77c801a
...
...
@@ -215,8 +215,7 @@ class RegistrationViewSet(GenericViewSet, RetrieveModelMixin,
def
destroy
(
self
,
request
,
pk
=
None
,
**
kwargs
):
registration
=
self
.
get_object
()
try
:
services
.
cancel_registration
(
request
,
registration
.
member
,
services
.
cancel_registration
(
registration
.
member
,
registration
.
event
)
return
Response
(
status
=
204
)
except
RegistrationError
as
e
:
...
...
website/events/emails.py
View file @
f77c801a
"""The emails defined by the events package"""
from
django.conf
import
settings
from
django.core.mail
import
EmailMessage
from
django.template.loader
import
get_template
from
django.utils
import
translation
...
...
@@ -6,15 +7,13 @@ from django.utils.translation import ugettext_lazy as _
from
events.models
import
Registration
from
members.models
import
Profile
from
thaliawebsite.templatetags
import
baseurl
def
notify_first_waiting
(
request
,
event
):
def
notify_first_waiting
(
event
):
"""
Send an email to the first person on the waiting list
when someone cancels their registration
:param request: the request object
:param event: the event
"""
if
(
event
.
max_participants
is
not
None
and
...
...
@@ -42,7 +41,7 @@ def notify_first_waiting(request, event):
'event'
:
event
,
'registration'
:
first_waiting
,
'member'
:
first_waiting_member
,
'base_url'
:
baseurl
.
baseurl
(
context
=
{
'request'
:
request
})
'base_url'
:
settings
.
BASE_URL
})
EmailMessage
(
...
...
website/events/services.py
View file @
f77c801a
...
...
@@ -118,11 +118,10 @@ def create_registration(member, event):
raise
RegistrationError
(
_
(
"You may not register."
))
def
cancel_registration
(
request
,
member
,
event
):
def
cancel_registration
(
member
,
event
):
"""
Cancel a user registration for an event
:param request: the request object
:param member: the user
:param event: the event
"""
...
...
@@ -138,7 +137,7 @@ def cancel_registration(request, member, event):
if
(
event_permissions
(
member
,
event
)[
"cancel_registration"
]
and
registration
):
if
registration
.
queue_position
==
0
:
emails
.
notify_first_waiting
(
request
,
event
)
emails
.
notify_first_waiting
(
event
)
if
(
event
.
send_cancel_email
and
event
.
after_cancel_deadline
):
...
...
website/events/templates/events/organiser_email.txt
View file @
f77c801a
{% load baseurl %}
Hi,
Hi,
A member that was registered for the event '{{ event.title }}' that you're organising has cancelled their registration after the deadline.
...
...
website/events/tests/test_services.py
View file @
f77c801a
...
...
@@ -234,7 +234,7 @@ class ServicesTest(TestCase):
}
with
self
.
assertRaises
(
RegistrationError
):
services
.
cancel_registration
(
None
,
self
.
member
,
self
.
event
)
services
.
cancel_registration
(
self
.
member
,
self
.
event
)
registration
=
Registration
.
objects
.
create
(
event
=
self
.
event
,
...
...
@@ -242,22 +242,22 @@ class ServicesTest(TestCase):
)
with
self
.
assertRaises
(
RegistrationError
):
services
.
cancel_registration
(
None
,
self
.
member
,
self
.
event
)
services
.
cancel_registration
(
self
.
member
,
self
.
event
)
perms_mock
.
return_value
[
"cancel_registration"
]
=
True
services
.
cancel_registration
(
None
,
self
.
member
,
self
.
event
)
notify_first_mock
.
assert_called_once_with
(
None
,
self
.
event
)
services
.
cancel_registration
(
self
.
member
,
self
.
event
)
notify_first_mock
.
assert_called_once_with
(
self
.
event
)
self
.
event
.
send_cancel_email
=
True
self
.
event
.
save
()
services
.
cancel_registration
(
None
,
self
.
member
,
self
.
event
)
services
.
cancel_registration
(
self
.
member
,
self
.
event
)
self
.
event
.
cancel_deadline
=
timezone
.
make_aware
(
datetime
(
2017
,
1
,
1
))
self
.
event
.
save
()
services
.
cancel_registration
(
None
,
self
.
member
,
self
.
event
)
services
.
cancel_registration
(
self
.
member
,
self
.
event
)
notify_organiser_mock
.
assert_called_once_with
(
self
.
event
,
registration
)
registration
.
refresh_from_db
()
...
...
@@ -271,7 +271,7 @@ class ServicesTest(TestCase):
date
=
timezone
.
make_aware
(
datetime
(
2017
,
9
,
1
))
)
services
.
cancel_registration
(
None
,
self
.
member
,
self
.
event
)
services
.
cancel_registration
(
self
.
member
,
self
.
event
)
@
mock
.
patch
(
'events.services.event_permissions'
)
def
test_update_registration
(
self
,
perms_mock
):
...
...
website/events/views.py
View file @
f77c801a
...
...
@@ -122,7 +122,7 @@ class EventCancelView(View):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
event
=
get_object_or_404
(
Event
,
pk
=
kwargs
[
'pk'
])
try
:
services
.
cancel_registration
(
request
,
request
.
member
,
event
)
services
.
cancel_registration
(
request
.
member
,
event
)
messages
.
success
(
request
,
_
(
"Registration successfully cancelled."
))
except
RegistrationError
as
e
:
...
...
website/newsletters/emails.py
View file @
f77c801a
...
...
@@ -11,11 +11,10 @@ from partners.models import Partner
from
newsletters
import
services
def
send_newsletter
(
request
,
newsletter
):
def
send_newsletter
(
newsletter
):
"""
Sends the newsletter as HTML and plaintext email
:param request: the request object
:param newsletter: the newsletter to be send
"""
partners
=
Partner
.
objects
.
filter
(
is_main_partner
=
True
)
...
...
@@ -47,8 +46,7 @@ def send_newsletter(request, newsletter):
'newsletter'
:
newsletter
,
'agenda_events'
:
events
,
'main_partner'
:
main_partner
,
'lang_code'
:
language
[
0
],
'request'
:
request
'lang_code'
:
language
[
0
]
}
html_message
=
html_template
.
render
(
context
)
...
...
website/newsletters/management/commands/createnewsletterhtml.py
View file @
f77c801a
from
django.core.management.base
import
BaseCommand
from
django.http
import
HttpRequest
from
newsletters
import
emails
,
model
s
from
newsletters
import
models
,
service
s
class
Command
(
BaseCommand
):
...
...
@@ -32,4 +32,4 @@ class Command(BaseCommand):
request
.
META
[
'SERVER_PORT'
]
=
options
[
'server-port'
]
for
n
in
models
.
Newsletter
.
objects
.
all
():
if
n
.
sent
or
options
[
'include-unsent'
]:
email
s
.
save_to_disk
(
n
,
request
)
service
s
.
save_to_disk
(
n
,
request
)
website/newsletters/management/commands/sendplannednewsletters.py
0 → 100644
View file @
f77c801a
from
django.core.management.base
import
BaseCommand
from
django.utils
import
timezone
from
newsletters
import
emails
from
newsletters.models
import
Newsletter
class
Command
(
BaseCommand
):
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'pk'
)
def
handle
(
self
,
*
args
,
**
options
):
newsletters
=
Newsletter
.
objects
.
filter
(
send_date__lte
=
timezone
.
now
(),
sent
=
False
)
for
n
in
newsletters
:
emails
.
send_newsletter
(
n
)
website/newsletters/migrations/0007_newsletter_send_date.py
0 → 100644
View file @
f77c801a
# Generated by Django 2.1.7 on 2019-04-08 15:31
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'newsletters'
,
'0006_make_newslettercontent_non_abstract'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'newsletter'
,
name
=
'send_date'
,
field
=
models
.
DateTimeField
(
blank
=
True
,
null
=
True
,
verbose_name
=
'Send date'
),
),
]
website/newsletters/models.py
View file @
f77c801a
...
...
@@ -2,6 +2,7 @@
from
django.core.exceptions
import
ValidationError
from
django.db
import
models
from
django.urls
import
reverse
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext_lazy
as
_
from
tinymce.models
import
HTMLField
...
...
@@ -29,6 +30,12 @@ class Newsletter(models.Model, metaclass=ModelTranslateMeta):
null
=
True
)
send_date
=
models
.
DateTimeField
(
verbose_name
=
_
(
'Send date'
),
blank
=
True
,
null
=
True
,
)
description
=
MultilingualField
(
HTMLField
,
verbose_name
=
_
(
'Introduction'
),
...
...
@@ -60,6 +67,11 @@ class Newsletter(models.Model, metaclass=ModelTranslateMeta):
'description_en'
:
_
(
'Please make sure all urls are absolute '
'and contain http(s)://.'
)
})
if
self
.
send_date
and
self
.
send_date
<=
timezone
.
now
():
errors
.
update
({
'send_date'
:
_
(
'Please make sure the send date is '
'not in the past.'
)
})
if
errors
:
raise
ValidationError
(
errors
)
...
...
website/newsletters/views.py
View file @
f77c801a
...
...
@@ -106,7 +106,7 @@ def admin_send(request, pk):
return
redirect
(
newsletter
)
if
request
.
POST
:
emails
.
send_newsletter
(
request
,
newsletter
)
emails
.
send_newsletter
(
newsletter
)
newsletter
.
sent
=
True
newsletter
.
save
()
...
...
website/thaliawebsite/templatetags/baseurl.py
View file @
f77c801a
"""Obtain the base url"""
from
django.conf
import
settings
from
django.template
import
Library
register
=
Library
()
# pylint: disable=invalid-name
@
register
.
simple_tag
(
takes_context
=
True
)
def
baseurl
(
context
):
@
register
.
simple_tag
()
def
baseurl
():
"""
:return:
a
BASE_URL
template context for the current request.
:return:
the
BASE_URL
defined in the settings
"""
request
=
context
[
'request'
]
if
request
.
is_secure
():
scheme
=
'https://'
else
:
scheme
=
'http://'
return
scheme
+
request
.
get_host
()
return
settings
.
BASE_URL
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment