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
52e28d91
Commit
52e28d91
authored
Jun 15, 2017
by
Adeel Khan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implementing connection timeout for sailthru api call.
LEARNER-1186
parent
95b3055f
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
114 additions
and
33 deletions
+114
-33
lms/djangoapps/email_marketing/migrations/0005_emailmarketingconfiguration_user_registration_cookie_timeout_delay.py
+19
-0
lms/djangoapps/email_marketing/models.py
+8
-0
lms/djangoapps/email_marketing/signals.py
+23
-29
lms/djangoapps/email_marketing/tasks.py
+40
-0
lms/djangoapps/email_marketing/tests/test_signals.py
+24
-4
No files found.
lms/djangoapps/email_marketing/migrations/0005_emailmarketingconfiguration_user_registration_cookie_timeout_delay.py
0 → 100644
View file @
52e28d91
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'email_marketing'
,
'0004_emailmarketingconfiguration_welcome_email_send_delay'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'emailmarketingconfiguration'
,
name
=
'user_registration_cookie_timeout_delay'
,
field
=
models
.
FloatField
(
default
=
1.5
,
help_text
=
'The number of seconds to delay/timeout wait to get cookie values from sailthru.'
),
),
]
lms/djangoapps/email_marketing/models.py
View file @
52e28d91
...
@@ -136,6 +136,14 @@ class EmailMarketingConfiguration(ConfigurationModel):
...
@@ -136,6 +136,14 @@ class EmailMarketingConfiguration(ConfigurationModel):
)
)
)
)
# The number of seconds to delay/timeout wait to get cookie values from sailthru.
user_registration_cookie_timeout_delay
=
models
.
fields
.
FloatField
(
default
=
1.5
,
help_text
=
_
(
"The number of seconds to delay/timeout wait to get cookie values from sailthru."
)
)
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
u"Email marketing configuration: New user list
%
s, Activation template:
%
s"
%
\
return
u"Email marketing configuration: New user list
%
s, Activation template:
%
s"
%
\
(
self
.
sailthru_new_user_list
,
self
.
sailthru_activation_template
)
(
self
.
sailthru_new_user_list
,
self
.
sailthru_activation_template
)
lms/djangoapps/email_marketing/signals.py
View file @
52e28d91
...
@@ -9,9 +9,10 @@ from django.conf import settings
...
@@ -9,9 +9,10 @@ from django.conf import settings
from
django.dispatch
import
receiver
from
django.dispatch
import
receiver
from
sailthru.sailthru_client
import
SailthruClient
from
sailthru.sailthru_client
import
SailthruClient
from
sailthru.sailthru_error
import
SailthruClientError
from
sailthru.sailthru_error
import
SailthruClientError
from
celery.exceptions
import
TimeoutError
from
email_marketing.models
import
EmailMarketingConfiguration
from
email_marketing.models
import
EmailMarketingConfiguration
from
lms.djangoapps.email_marketing.tasks
import
update_user
,
update_user_email
from
lms.djangoapps.email_marketing.tasks
import
update_user
,
update_user_email
,
get_email_cookies_via_sailthru
from
student.cookies
import
CREATE_LOGON_COOKIE
from
student.cookies
import
CREATE_LOGON_COOKIE
from
student.views
import
REGISTER_USER
from
student.views
import
REGISTER_USER
from
util.model_utils
import
USER_FIELD_CHANGED
from
util.model_utils
import
USER_FIELD_CHANGED
...
@@ -54,41 +55,34 @@ def add_email_marketing_cookies(sender, response=None, user=None,
...
@@ -54,41 +55,34 @@ def add_email_marketing_cookies(sender, response=None, user=None,
if
sailthru_content
:
if
sailthru_content
:
post_parms
[
'cookies'
]
=
{
'anonymous_interest'
:
sailthru_content
}
post_parms
[
'cookies'
]
=
{
'anonymous_interest'
:
sailthru_content
}
try
:
time_before_call
=
datetime
.
datetime
.
now
()
sailthru_client
=
SailthruClient
(
email_config
.
sailthru_key
,
email_config
.
sailthru_secret
)
sailthru_response
=
get_email_cookies_via_sailthru
.
delay
(
user
.
email
,
post_parms
)
log
.
info
(
'Sending to Sailthru the user interest cookie [
%
s] for user [
%
s]'
,
post_parms
.
get
(
'cookies'
,
''
),
user
.
email
)
time_before_call
=
datetime
.
datetime
.
now
()
sailthru_response
=
\
try
:
sailthru_client
.
api_post
(
"user"
,
post_parms
)
# synchronous call to get result of an asynchronous celery task, with timeout
sailthru_response
.
get
(
timeout
=
email_config
.
user_registration_cookie_timeout_delay
,
propagate
=
True
)
cookie
=
sailthru_response
.
result
except
TimeoutError
as
exc
:
log
.
error
(
"Timeout error while attempting to obtain cookie from Sailthru:
%
s"
,
unicode
(
exc
))
return
response
except
SailthruClientError
as
exc
:
except
SailthruClientError
as
exc
:
log
.
error
(
"Exception attempting to obtain cookie from Sailthru:
%
s"
,
unicode
(
exc
))
log
.
error
(
"Exception attempting to obtain cookie from Sailthru:
%
s"
,
unicode
(
exc
))
return
response
return
response
if
sailthru_response
.
is_ok
():
if
not
cookie
:
if
'keys'
in
sailthru_response
.
json
and
'cookie'
in
sailthru_response
.
json
[
'keys'
]:
log
.
error
(
"No cookie returned attempting to obtain cookie from Sailthru for
%
s"
,
user
.
email
)
cookie
=
sailthru_response
.
json
[
'keys'
][
'cookie'
]
return
response
response
.
set_cookie
(
'sailthru_hid'
,
cookie
,
max_age
=
365
*
24
*
60
*
60
,
# set for 1 year
domain
=
settings
.
SESSION_COOKIE_DOMAIN
,
path
=
'/'
,
)
_log_sailthru_api_call_time
(
time_before_call
)
else
:
log
.
error
(
"No cookie returned attempting to obtain cookie from Sailthru for
%
s"
,
user
.
email
)
else
:
else
:
error
=
sailthru_response
.
get_error
()
response
.
set_cookie
(
# generally invalid email address
'sailthru_hid'
,
log
.
info
(
"Error attempting to obtain cookie from Sailthru:
%
s"
,
error
.
get_message
())
cookie
,
max_age
=
365
*
24
*
60
*
60
,
# set for 1 year
domain
=
settings
.
SESSION_COOKIE_DOMAIN
,
path
=
'/'
,
)
_log_sailthru_api_call_time
(
time_before_call
)
return
response
return
response
...
...
lms/djangoapps/email_marketing/tasks.py
View file @
52e28d91
...
@@ -17,6 +17,46 @@ log = logging.getLogger(__name__)
...
@@ -17,6 +17,46 @@ log = logging.getLogger(__name__)
SAILTHRU_LIST_CACHE_KEY
=
"email.marketing.cache"
SAILTHRU_LIST_CACHE_KEY
=
"email.marketing.cache"
@task
(
bind
=
True
)
def
get_email_cookies_via_sailthru
(
self
,
user_email
,
post_parms
):
"""
Adds/updates Sailthru cookie information for a new user.
Args:
post_parms(dict): User profile information to pass as 'vars' to Sailthru
Returns:
cookie(str): cookie fetched from Sailthru
"""
email_config
=
EmailMarketingConfiguration
.
current
()
if
not
email_config
.
enabled
:
return
None
try
:
sailthru_client
=
SailthruClient
(
email_config
.
sailthru_key
,
email_config
.
sailthru_secret
)
log
.
info
(
'Sending to Sailthru the user interest cookie [
%
s] for user [
%
s]'
,
post_parms
.
get
(
'cookies'
,
''
),
user_email
)
sailthru_response
=
sailthru_client
.
api_post
(
"user"
,
post_parms
)
except
SailthruClientError
as
exc
:
log
.
error
(
"Exception attempting to obtain cookie from Sailthru:
%
s"
,
unicode
(
exc
))
raise
SailthruClientError
if
sailthru_response
.
is_ok
():
if
'keys'
in
sailthru_response
.
json
and
'cookie'
in
sailthru_response
.
json
[
'keys'
]:
cookie
=
sailthru_response
.
json
[
'keys'
][
'cookie'
]
return
cookie
else
:
log
.
error
(
"No cookie returned attempting to obtain cookie from Sailthru for
%
s"
,
user_email
)
else
:
error
=
sailthru_response
.
get_error
()
# generally invalid email address
log
.
info
(
"Error attempting to obtain cookie from Sailthru:
%
s"
,
error
.
get_message
())
return
None
# pylint: disable=not-callable
# pylint: disable=not-callable
@task
(
bind
=
True
,
default_retry_delay
=
3600
,
max_retries
=
24
)
@task
(
bind
=
True
,
default_retry_delay
=
3600
,
max_retries
=
24
)
def
update_user
(
self
,
sailthru_vars
,
email
,
site
=
None
,
new_user
=
False
,
activation
=
False
):
def
update_user
(
self
,
sailthru_vars
,
email
,
site
=
None
,
new_user
=
False
,
activation
=
False
):
...
...
lms/djangoapps/email_marketing/tests/test_signals.py
View file @
52e28d91
...
@@ -25,7 +25,8 @@ from email_marketing.tasks import (
...
@@ -25,7 +25,8 @@ from email_marketing.tasks import (
_get_list_from_email_marketing_provider
,
_get_list_from_email_marketing_provider
,
_get_or_create_user_list
,
_get_or_create_user_list
,
update_user
,
update_user
,
update_user_email
update_user_email
,
get_email_cookies_via_sailthru
)
)
from
student.tests.factories
import
UserFactory
,
UserProfileFactory
from
student.tests.factories
import
UserFactory
,
UserProfileFactory
from
util.json_request
import
JsonResponse
from
util.json_request
import
JsonResponse
...
@@ -98,13 +99,10 @@ class EmailMarketingTests(TestCase):
...
@@ -98,13 +99,10 @@ class EmailMarketingTests(TestCase):
self
.
request
.
COOKIES
[
'anonymous_interest'
]
=
'cookie_content'
self
.
request
.
COOKIES
[
'anonymous_interest'
]
=
'cookie_content'
mock_get_current_request
.
return_value
=
self
.
request
mock_get_current_request
.
return_value
=
self
.
request
mock_sailthru
.
return_value
=
SailthruResponse
(
JsonResponse
({
'keys'
:
{
'cookie'
:
'test_cookie'
}}))
mock_sailthru
.
return_value
=
SailthruResponse
(
JsonResponse
({
'keys'
:
{
'cookie'
:
'test_cookie'
}}))
cookie_log
=
"Sending to Sailthru the user interest cookie [{'anonymous_interest': 'cookie_content'}]"
\
' for user [test@edx.org]'
with
LogCapture
(
LOGGER_NAME
,
level
=
logging
.
INFO
)
as
logger
:
with
LogCapture
(
LOGGER_NAME
,
level
=
logging
.
INFO
)
as
logger
:
add_email_marketing_cookies
(
None
,
response
=
response
,
user
=
self
.
user
)
add_email_marketing_cookies
(
None
,
response
=
response
,
user
=
self
.
user
)
logger
.
check
(
logger
.
check
(
(
LOGGER_NAME
,
'INFO'
,
cookie_log
),
(
LOGGER_NAME
,
'INFO'
,
(
LOGGER_NAME
,
'INFO'
,
'Started at {start} and ended at {end}, time spent:{delta} milliseconds'
.
format
(
'Started at {start} and ended at {end}, time spent:{delta} milliseconds'
.
format
(
start
=
datetime
.
datetime
.
now
()
.
isoformat
(
' '
),
start
=
datetime
.
datetime
.
now
()
.
isoformat
(
' '
),
...
@@ -121,6 +119,28 @@ class EmailMarketingTests(TestCase):
...
@@ -121,6 +119,28 @@ class EmailMarketingTests(TestCase):
self
.
assertEquals
(
response
.
cookies
[
'sailthru_hid'
]
.
value
,
"test_cookie"
)
self
.
assertEquals
(
response
.
cookies
[
'sailthru_hid'
]
.
value
,
"test_cookie"
)
@patch
(
'email_marketing.signals.SailthruClient.api_post'
)
@patch
(
'email_marketing.signals.SailthruClient.api_post'
)
def
test_get_cookies_via_sailthu
(
self
,
mock_sailthru
):
cookies
=
{
'cookie'
:
'test_cookie'
}
mock_sailthru
.
return_value
=
SailthruResponse
(
JsonResponse
({
'keys'
:
cookies
}))
post_parms
=
{
'id'
:
self
.
user
.
email
,
'fields'
:
{
'keys'
:
1
},
'vars'
:
{
'last_login_date'
:
datetime
.
datetime
.
now
()
.
strftime
(
"
%
Y-
%
m-
%
d"
)},
'cookies'
:
{
'anonymous_interest'
:
'cookie_content'
}
}
expected_cookie
=
get_email_cookies_via_sailthru
.
delay
(
self
.
user
.
email
,
post_parms
)
mock_sailthru
.
assert_called_with
(
'user'
,
{
'fields'
:
{
'keys'
:
1
},
'cookies'
:
{
'anonymous_interest'
:
'cookie_content'
},
'id'
:
TEST_EMAIL
,
'vars'
:
{
'last_login_date'
:
ANY
}})
self
.
assertEqual
(
cookies
[
'cookie'
],
expected_cookie
.
result
)
@patch
(
'email_marketing.signals.SailthruClient.api_post'
)
def
test_drop_cookie_error_path
(
self
,
mock_sailthru
):
def
test_drop_cookie_error_path
(
self
,
mock_sailthru
):
"""
"""
test that error paths return no cookie
test that error paths return no cookie
...
...
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