Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
54ae1c62
Unverified
Commit
54ae1c62
authored
Nov 08, 2017
by
Gabe Mulley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
support theming of ACE emails
parent
d037a19c
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
334 additions
and
8 deletions
+334
-8
openedx/core/djangoapps/schedules/management/commands/tests/send_email_base.py
+26
-1
openedx/core/djangoapps/schedules/tasks.py
+17
-7
openedx/core/lib/celery/task_utils.py
+49
-0
themes/red-theme/lms/templates/schedules/edx_ace/common/base_body.html
+196
-0
themes/red-theme/lms/templates/schedules/edx_ace/common/return_to_course_cta.html
+27
-0
themes/red-theme/lms/templates/schedules/edx_ace/recurringnudge_day3/email/body.txt
+19
-0
No files found.
openedx/core/djangoapps/schedules/management/commands/tests/send_email_base.py
View file @
54ae1c62
...
...
@@ -22,6 +22,7 @@ from openedx.core.djangoapps.schedules import resolvers, tasks
from
openedx.core.djangoapps.schedules.resolvers
import
_get_datetime_beginning_of_day
from
openedx.core.djangoapps.schedules.tests.factories
import
ScheduleConfigFactory
,
ScheduleFactory
from
openedx.core.djangoapps.site_configuration.tests.factories
import
SiteConfigurationFactory
,
SiteFactory
from
openedx.core.djangoapps.theming.tests.test_util
import
with_comprehensive_theme
from
openedx.core.djangoapps.waffle_utils.testutils
import
WAFFLE_TABLES
from
openedx.core.djangolib.testing.utils
import
CacheIsolationTestCase
,
FilteredQueryCountMixin
from
student.models
import
CourseEnrollment
...
...
@@ -38,6 +39,11 @@ ORG_DEADLINE_QUERY = 1 # courseware_orgdynamicupgradedeadlineconfiguration
COURSE_DEADLINE_QUERY
=
1
# courseware_coursedynamicupgradedeadlineconfiguration
COMMERCE_CONFIG_QUERY
=
1
# commerce_commerceconfiguration
USER_QUERY
=
1
THEME_PREVIEW_QUERY
=
1
THEME_QUERY
=
1
SCHEDULE_CONFIG_QUERY
=
1
NUM_QUERIES_SITE_SCHEDULES
=
(
SITE_QUERY
+
SITE_CONFIG_QUERY
+
...
...
@@ -52,6 +58,14 @@ NUM_QUERIES_FIRST_MATCH = (
+
COMMERCE_CONFIG_QUERY
)
NUM_QUERIES_PER_MESSAGE_DELIVERY
=
(
SITE_QUERY
+
SCHEDULE_CONFIG_QUERY
+
USER_QUERY
+
THEME_PREVIEW_QUERY
+
THEME_QUERY
)
LOG
=
logging
.
getLogger
(
__name__
)
...
...
@@ -219,10 +233,12 @@ class ScheduleSendEmailTestBase(FilteredQueryCountMixin, CacheIsolationTestCase)
@patch.object
(
tasks
,
'ace'
)
@patch.object
(
tasks
,
'Message'
)
def
test_deliver_config
(
self
,
is_enabled
,
mock_message
,
mock_ace
):
user
=
UserFactory
.
create
()
schedule_config_kwargs
=
{
'site'
:
self
.
site_config
.
site
,
self
.
deliver_config
:
is_enabled
,
}
mock_message
.
from_string
.
return_value
.
recipient
.
username
=
user
.
username
ScheduleConfigFactory
.
create
(
**
schedule_config_kwargs
)
mock_msg
=
Mock
()
...
...
@@ -383,7 +399,7 @@ class ScheduleSendEmailTestBase(FilteredQueryCountMixin, CacheIsolationTestCase)
num_expected_messages
=
1
if
self
.
consolidates_emails_for_learner
else
message_count
self
.
assertEqual
(
len
(
sent_messages
),
num_expected_messages
)
with
self
.
assertNumQueries
(
2
):
with
self
.
assertNumQueries
(
NUM_QUERIES_PER_MESSAGE_DELIVERY
):
self
.
deliver_task
(
*
sent_messages
[
0
])
self
.
assertEqual
(
mock_channel
.
deliver
.
call_count
,
1
)
...
...
@@ -393,6 +409,8 @@ class ScheduleSendEmailTestBase(FilteredQueryCountMixin, CacheIsolationTestCase)
self
.
assertNotIn
(
"{{"
,
template
)
self
.
assertNotIn
(
"}}"
,
template
)
return
mock_channel
.
deliver
.
mock_calls
def
_check_if_email_sent_for_experience
(
self
,
test_config
):
current_day
,
offset
,
target_day
,
_
=
self
.
_get_dates
(
offset
=
test_config
.
offset
)
...
...
@@ -412,3 +430,10 @@ class ScheduleSendEmailTestBase(FilteredQueryCountMixin, CacheIsolationTestCase)
))
self
.
assertEqual
(
mock_ace
.
send
.
called
,
test_config
.
email_sent
)
@with_comprehensive_theme
(
'red-theme'
)
def
test_templates_with_theme
(
self
):
calls_to_deliver
=
self
.
_assert_template_for_offset
(
self
.
expected_offsets
[
0
],
1
)
_name
,
(
_msg
,
email
),
_kwargs
=
calls_to_deliver
[
0
]
self
.
assertIn
(
'TEST RED THEME MARKER'
,
email
.
body_html
)
openedx/core/djangoapps/schedules/tasks.py
View file @
54ae1c62
...
...
@@ -2,7 +2,9 @@ import datetime
import
logging
from
celery.task
import
task
,
Task
from
crum
import
CurrentRequestUserMiddleware
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
from
django.contrib.sites.models
import
Site
from
django.core.exceptions
import
ValidationError
...
...
@@ -17,7 +19,8 @@ from openedx.core.djangoapps.monitoring_utils import set_custom_metric
from
openedx.core.djangoapps.schedules
import
message_types
from
openedx.core.djangoapps.schedules.models
import
Schedule
,
ScheduleConfig
from
openedx.core.djangoapps.schedules
import
resolvers
from
openedx.core.djangoapps.theming.middleware
import
CurrentSiteThemeMiddleware
from
openedx.core.lib.celery.task_utils
import
emulate_http_request
LOG
=
logging
.
getLogger
(
__name__
)
...
...
@@ -177,15 +180,22 @@ class ScheduleCourseUpdate(ScheduleMessageBaseTask):
def
_schedule_send
(
msg_str
,
site_id
,
delivery_config_var
,
log_prefix
):
if
_is_delivery_enabled
(
site_id
,
delivery_config_var
,
log_prefix
):
site
=
Site
.
objects
.
get
(
pk
=
site_id
)
if
_is_delivery_enabled
(
site
,
delivery_config_var
,
log_prefix
):
msg
=
Message
.
from_string
(
msg_str
)
_annonate_send_task_for_monitoring
(
msg
)
LOG
.
debug
(
'
%
s: Sending message =
%
s'
,
log_prefix
,
msg_str
)
ace
.
send
(
msg
)
user
=
User
.
objects
.
get
(
username
=
msg
.
recipient
.
username
)
middleware_classes
=
[
CurrentRequestUserMiddleware
,
CurrentSiteThemeMiddleware
,
]
with
emulate_http_request
(
site
=
site
,
user
=
user
,
middleware_classes
=
middleware_classes
):
_annonate_send_task_for_monitoring
(
msg
)
LOG
.
debug
(
'
%
s: Sending message =
%
s'
,
log_prefix
,
msg_str
)
ace
.
send
(
msg
)
def
_is_delivery_enabled
(
site_id
,
delivery_config_var
,
log_prefix
):
site
=
Site
.
objects
.
get
(
pk
=
site_id
)
def
_is_delivery_enabled
(
site
,
delivery_config_var
,
log_prefix
):
if
getattr
(
ScheduleConfig
.
current
(
site
),
delivery_config_var
,
False
):
return
True
else
:
...
...
openedx/core/lib/celery/task_utils.py
0 → 100644
View file @
54ae1c62
from
contextlib
import
contextmanager
from
django.http
import
HttpRequest
,
HttpResponse
@contextmanager
def
emulate_http_request
(
site
=
None
,
user
=
None
,
middleware_classes
=
None
):
"""
Generate a fake HTTP request and run selected middleware on it.
This is used to enable features that assume they are running as part of an HTTP request handler. Many of these
features retrieve the "current" request from a thread local managed by crum. They will make a call like
crum.get_current_request() or something similar.
Since some tasks are kicked off by a management commands (which does not have an HTTP request) and then executed
in celery workers there is no "current HTTP request". Instead we just populate the global state that is most
commonly used on request objects.
Arguments:
site (Site): The site that this request should emulate. Defaults to None.
user (User): The user that initiated this fake request. Defaults to None
middleware_classes (list): A list of classes that implement Django's middleware interface.
"""
request
=
HttpRequest
()
request
.
user
=
user
request
.
site
=
site
middleware_classes
=
middleware_classes
or
[]
middleware_instances
=
[
klass
()
for
klass
in
middleware_classes
]
response
=
HttpResponse
()
for
middleware
in
middleware_instances
:
_run_method_if_implemented
(
middleware
,
'process_request'
,
request
)
try
:
yield
except
Exception
as
exc
:
for
middleware
in
reversed
(
middleware_instances
):
_run_method_if_implemented
(
middleware
,
'process_exception'
,
request
,
exc
)
else
:
for
middleware
in
reversed
(
middleware_instances
):
_run_method_if_implemented
(
middleware
,
'process_response'
,
request
,
response
)
def
_run_method_if_implemented
(
instance
,
method_name
,
*
args
,
**
kwargs
):
if
hasattr
(
instance
,
method_name
):
return
getattr
(
instance
,
method_name
)(
*
args
,
**
kwargs
)
else
:
return
None
themes/red-theme/lms/templates/schedules/edx_ace/common/base_body.html
0 → 100644
View file @
54ae1c62
This diff is collapsed.
Click to expand it.
themes/red-theme/lms/templates/schedules/edx_ace/common/return_to_course_cta.html
0 → 100644
View file @
54ae1c62
{% load i18n %}
<p>
{# email client support for style sheets is pretty spotty, so we have to inline all of these styles #}
<a
{%
if
course_ids
|
length
>
1 %}
href="{{ dashboard_url }}"
{% else %}
href="{{ course_url }}"
{% endif %}
style="
color: #ffffff;
text-decoration: none;
border-radius: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
background-color: #960909;
border-top: 12px solid #960909;
border-bottom: 12px solid #960909;
border-right: 50px solid #960909;
border-left: 50px solid #960909;
display: inline-block;
">
{# old email clients require the use of the font tag :( #}
<font
color=
"#ffffff"
><b>
{{ course_cta_text }}
</b></font>
</a>
</p>
themes/red-theme/lms/templates/schedules/edx_ace/recurringnudge_day3/email/body.txt
0 → 100644
View file @
54ae1c62
{% load i18n %}
This is the RED theme!
{% if course_ids|length > 1 %}
{% blocktrans trimmed %}
Remember when you enrolled in {{ course_name }}, and other courses on edX.org? We do, and we’re glad
to have you! Come see what everyone is learning.
{% endblocktrans %}
{% trans "Start learning now" %} <{{ dashboard_url }}>
{% else %}
{% blocktrans trimmed %}
Remember when you enrolled in {{ course_name }} on edX.org? We do, and we’re glad
to have you! Come see what everyone is learning.
{% endblocktrans %}
{% trans "Start learning now" %} <{{ course_url }}>
{% endif %}
{% include "schedules/edx_ace/common/upsell_cta.txt"%}
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