Merge pull request #9875 from edx/bderusha/segment-cleanup
Segment Clean Up
This commit is contained in:
@@ -243,11 +243,8 @@ if 'DJFS' in AUTH_TOKENS and AUTH_TOKENS['DJFS'] is not None:
|
||||
EMAIL_HOST_USER = AUTH_TOKENS.get('EMAIL_HOST_USER', EMAIL_HOST_USER)
|
||||
EMAIL_HOST_PASSWORD = AUTH_TOKENS.get('EMAIL_HOST_PASSWORD', EMAIL_HOST_PASSWORD)
|
||||
|
||||
# If Segment.io key specified, load it and turn on Segment.io if the feature flag is set
|
||||
# Note that this is the Studio key. There is a separate key for the LMS.
|
||||
SEGMENT_IO_KEY = AUTH_TOKENS.get('SEGMENT_IO_KEY')
|
||||
if SEGMENT_IO_KEY:
|
||||
FEATURES['SEGMENT_IO'] = ENV_TOKENS.get('SEGMENT_IO', False)
|
||||
# Note that this is the Studio key for Segment. There is a separate key for the LMS.
|
||||
SEGMENT_KEY = AUTH_TOKENS.get('SEGMENT_KEY')
|
||||
|
||||
AWS_ACCESS_KEY_ID = AUTH_TOKENS["AWS_ACCESS_KEY_ID"]
|
||||
if AWS_ACCESS_KEY_ID == "":
|
||||
|
||||
@@ -94,7 +94,6 @@
|
||||
"MEDIA_URL": "",
|
||||
"MKTG_URL_LINK_MAP": {},
|
||||
"PLATFORM_NAME": "edX",
|
||||
"SEGMENT_IO_LMS": true,
|
||||
"SERVER_EMAIL": "devops@example.com",
|
||||
"SESSION_COOKIE_DOMAIN": null,
|
||||
"SITE_NAME": "localhost",
|
||||
|
||||
@@ -77,8 +77,8 @@ FEATURES = {
|
||||
# email address for studio staff (eg to request course creation)
|
||||
'STUDIO_REQUEST_EMAIL': '',
|
||||
|
||||
# Segment.io - must explicitly turn it on for production
|
||||
'SEGMENT_IO': False,
|
||||
# Segment - must explicitly turn it on for production
|
||||
'SEGMENT_KEY': None,
|
||||
|
||||
# Enable URL that shows information about the status of various services
|
||||
'ENABLE_SERVICE_STATUS': False,
|
||||
|
||||
@@ -164,12 +164,10 @@ FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
|
||||
############################# SEGMENT-IO ##################################
|
||||
|
||||
# If there's an environment variable set, grab it and turn on Segment.io
|
||||
# If there's an environment variable set, grab it to turn on Segment
|
||||
# Note that this is the Studio key. There is a separate key for the LMS.
|
||||
import os
|
||||
SEGMENT_IO_KEY = os.environ.get('SEGMENT_IO_KEY')
|
||||
if SEGMENT_IO_KEY:
|
||||
FEATURES['SEGMENT_IO'] = True
|
||||
SEGMENT_KEY = os.environ.get('SEGMENT_KEY')
|
||||
|
||||
|
||||
#####################################################################
|
||||
|
||||
@@ -210,8 +210,8 @@ PASSWORD_HASHERS = (
|
||||
'django.contrib.auth.hashers.MD5PasswordHasher',
|
||||
)
|
||||
|
||||
# dummy segment-io key
|
||||
SEGMENT_IO_KEY = '***REMOVED***'
|
||||
# No segment key
|
||||
SEGMENT_KEY = None
|
||||
|
||||
FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ ADDL_INSTALLED_APPS = []
|
||||
AUTH_USE_CAS = False
|
||||
CAS_ATTRIBUTE_CALLBACK = None
|
||||
MICROSITE_ROOT_DIR = ''
|
||||
SEGMENT_IO = False
|
||||
SEGMENT_KEY = None
|
||||
DATADOG = {}
|
||||
ADDL_INSTALLED_APPS = []
|
||||
LOCAL_LOGLEVEL = 'INFO'
|
||||
@@ -235,9 +235,6 @@ vars().update(AUTH_TOKENS)
|
||||
# Manipulate imported settings with code
|
||||
#
|
||||
|
||||
if SEGMENT_IO_KEY:
|
||||
FEATURES['SEGMENT_IO'] = SEGMENT_IO
|
||||
|
||||
if AWS_ACCESS_KEY_ID == "":
|
||||
AWS_ACCESS_KEY_ID = None
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
%>
|
||||
% endif
|
||||
|
||||
% if settings.FEATURES.get('SEGMENT_IO'):
|
||||
<!-- begin Segment.io -->
|
||||
% if settings.SEGMENT_KEY:
|
||||
<!-- begin Segment -->
|
||||
<script type="text/javascript">
|
||||
// if inside course, inject the course location into the JS namespace
|
||||
%if context_course:
|
||||
@@ -15,7 +15,7 @@
|
||||
%endif
|
||||
|
||||
var analytics=analytics||[];analytics.load=function(e){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src=("https:"===document.location.protocol?"https://":"http://")+"d2dq2ahtl5zl1z.cloudfront.net/analytics.js/v1/"+e+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);var r=function(e){return function(){analytics.push([e].concat(Array.prototype.slice.call(arguments,0)))}},i=["identify","track","trackLink","trackForm","trackClick","trackSubmit","pageview","ab","alias","ready"];for(var s=0;s<i.length;s++)analytics[i[s]]=r(i[s])};
|
||||
analytics.load("${ settings.SEGMENT_IO_KEY }");
|
||||
analytics.load("${ settings.SEGMENT_KEY }");
|
||||
|
||||
% if user.is_authenticated():
|
||||
analytics.identify("${ user.id }", {
|
||||
@@ -25,9 +25,9 @@
|
||||
|
||||
% endif
|
||||
</script>
|
||||
<!-- end Segment.io -->
|
||||
<!-- end Segment -->
|
||||
% else:
|
||||
<!-- dummy segment.io -->
|
||||
<!-- dummy Segment -->
|
||||
<script type="text/javascript">
|
||||
%if context_course:
|
||||
var course_location_analytics = "${locator | escapejs}";
|
||||
@@ -36,5 +36,5 @@
|
||||
"track": function() {}
|
||||
};
|
||||
</script>
|
||||
<!-- end dummy segment.io -->
|
||||
<!-- end dummy Segment -->
|
||||
% endif
|
||||
|
||||
@@ -1052,7 +1052,7 @@ class CourseEnrollment(models.Model):
|
||||
with tracker.get_tracker().context(event_name, context):
|
||||
tracker.emit(event_name, data)
|
||||
|
||||
if settings.FEATURES.get('SEGMENT_IO_LMS') and settings.SEGMENT_IO_LMS_KEY:
|
||||
if settings.SEGMENT_KEY:
|
||||
tracking_context = tracker.get_tracker().resolve_context()
|
||||
analytics.track(self.user_id, event_name, {
|
||||
'category': 'conversion',
|
||||
|
||||
@@ -1163,11 +1163,11 @@ def login_user(request, error=""): # pylint: disable=too-many-statements,unused
|
||||
LoginFailures.clear_lockout_counter(user)
|
||||
|
||||
# Track the user's sign in
|
||||
if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY'):
|
||||
if settings.SEGMENT_KEY:
|
||||
tracking_context = tracker.get_tracker().resolve_context()
|
||||
analytics.identify(user.id, {
|
||||
'email': email,
|
||||
'username': username,
|
||||
'username': username
|
||||
})
|
||||
|
||||
analytics.track(
|
||||
@@ -1601,7 +1601,7 @@ def create_account_with_params(request, params):
|
||||
third_party_provider = provider.Registry.get_from_pipeline(running_pipeline)
|
||||
|
||||
# Track the user's registration
|
||||
if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY'):
|
||||
if settings.SEGMENT_KEY:
|
||||
tracking_context = tracker.get_tracker().resolve_context()
|
||||
identity_args = [
|
||||
user.id, # pylint: disable=no-member
|
||||
|
||||
@@ -585,7 +585,7 @@ def set_logged_in_cookies(backend=None, user=None, strategy=None, auth_entry=Non
|
||||
|
||||
@partial.partial
|
||||
def login_analytics(strategy, auth_entry, *args, **kwargs):
|
||||
""" Sends login info to Segment.io """
|
||||
""" Sends login info to Segment """
|
||||
|
||||
event_name = None
|
||||
if auth_entry == AUTH_ENTRY_LOGIN:
|
||||
@@ -593,7 +593,7 @@ def login_analytics(strategy, auth_entry, *args, **kwargs):
|
||||
elif auth_entry in [AUTH_ENTRY_ACCOUNT_SETTINGS]:
|
||||
event_name = 'edx.bi.user.account.linked'
|
||||
|
||||
if event_name is not None and hasattr(settings, 'SEGMENT_IO_LMS_KEY') and settings.SEGMENT_IO_LMS_KEY:
|
||||
if event_name is not None and settings.SEGMENT_KEY:
|
||||
tracking_context = tracker.get_tracker().resolve_context()
|
||||
analytics.track(
|
||||
kwargs['user'].id,
|
||||
|
||||
@@ -67,7 +67,7 @@ def remove_shim_context(event):
|
||||
context = event['context']
|
||||
# These fields are present elsewhere in the event at this point
|
||||
context_fields_to_remove = set(CONTEXT_FIELDS_TO_INCLUDE)
|
||||
# This field is only used for Segment.io web analytics and does not concern researchers
|
||||
# This field is only used for Segment web analytics and does not concern researchers
|
||||
context_fields_to_remove.add('client_id')
|
||||
for field in context_fields_to_remove:
|
||||
if field in context:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Handle events that were forwarded from the segment.io webhook integration"""
|
||||
"""Handle events that were forwarded from the Segment webhook integration"""
|
||||
|
||||
import datetime
|
||||
import json
|
||||
@@ -35,28 +35,28 @@ ERROR_MISSING_RECEIVED_AT = 'Required receivedAt field not found'
|
||||
@csrf_exempt
|
||||
def segmentio_event(request):
|
||||
"""
|
||||
An endpoint for logging events using segment.io's webhook integration.
|
||||
An endpoint for logging events using Segment's webhook integration.
|
||||
|
||||
segment.io provides a custom integration mechanism that initiates a request to a configurable URL every time an
|
||||
Segment provides a custom integration mechanism that initiates a request to a configurable URL every time an
|
||||
event is received by their system. This endpoint is designed to receive those requests and convert the events into
|
||||
standard tracking log entries.
|
||||
|
||||
For now we limit the scope of handled events to track and screen events from mobile devices. In the future we could
|
||||
enable logging of other types of events, however, there is significant overlap with our non-segment.io based event
|
||||
tracking. Given that segment.io is closed third party solution we are limiting its required usage to just
|
||||
enable logging of other types of events, however, there is significant overlap with our non-Segment based event
|
||||
tracking. Given that Segment is closed third party solution we are limiting its required usage to just
|
||||
collecting events from mobile devices for the time being.
|
||||
|
||||
Many of the root fields of a standard edX tracking event are read out of the "properties" dictionary provided by the
|
||||
segment.io event, which is, in turn, provided by the client that emitted the event.
|
||||
Segment event, which is, in turn, provided by the client that emitted the event.
|
||||
|
||||
In order for an event to be accepted and logged the "key" query string parameter must exactly match the django
|
||||
setting TRACKING_SEGMENTIO_WEBHOOK_SECRET. While the endpoint is public, we want to limit access to it to the
|
||||
segment.io servers only.
|
||||
Segment servers only.
|
||||
|
||||
"""
|
||||
|
||||
# Validate the security token. We must use a query string parameter for this since we cannot customize the POST body
|
||||
# in the segment.io webhook configuration, we can only change the URL that they call, so we force this token to be
|
||||
# in the Segment webhook configuration, we can only change the URL that they call, so we force this token to be
|
||||
# included in the URL and reject any requests that do not include it. This also assumes HTTPS is used to make the
|
||||
# connection between their server and ours.
|
||||
expected_secret = getattr(settings, 'TRACKING_SEGMENTIO_WEBHOOK_SECRET', None)
|
||||
@@ -68,7 +68,7 @@ def segmentio_event(request):
|
||||
track_segmentio_event(request)
|
||||
except EventValidationError as err:
|
||||
log.warning(
|
||||
'Unable to process event received from segment.io: message="%s" event="%s"',
|
||||
'Unable to process event received from Segment: message="%s" event="%s"',
|
||||
str(err),
|
||||
request.body
|
||||
)
|
||||
@@ -85,24 +85,24 @@ class EventValidationError(Exception):
|
||||
|
||||
def track_segmentio_event(request): # pylint: disable=too-many-statements
|
||||
"""
|
||||
Record an event received from segment.io to the tracking logs.
|
||||
Record an event received from Segment to the tracking logs.
|
||||
|
||||
This method assumes that the event has come from a trusted source.
|
||||
|
||||
The received event must meet the following conditions in order to be logged:
|
||||
|
||||
* The value of the "type" field of the event must be included in the list specified by the django setting
|
||||
TRACKING_SEGMENTIO_ALLOWED_TYPES. In order to make use of *all* of the features segment.io offers we would have
|
||||
TRACKING_SEGMENTIO_ALLOWED_TYPES. In order to make use of *all* of the features Segment offers we would have
|
||||
to implement some sort of persistent storage of information contained in some actions (like identify). For now,
|
||||
we defer support of those actions and just support a limited set that can be handled without storing information
|
||||
in external state.
|
||||
* The value of the standard "userId" field of the event must be an integer that can be used to look up the user
|
||||
using the primary key of the User model.
|
||||
* Include a "name" field in the properties dictionary that indicates the edX event name. Note this can differ
|
||||
from the "event" field found in the root of a segment.io event. The "event" field at the root of the structure is
|
||||
from the "event" field found in the root of a Segment event. The "event" field at the root of the structure is
|
||||
intended to be human readable, the "name" field is expected to conform to the standard for naming events
|
||||
found in the edX data documentation.
|
||||
* Have originated from a known and trusted segment.io client library. The django setting
|
||||
* Have originated from a known and trusted Segment client library. The django setting
|
||||
TRACKING_SEGMENTIO_SOURCE_MAP maps the known library names to internal "event_source" strings. In order to be
|
||||
logged the event must have a library name that is a valid key in that map.
|
||||
|
||||
@@ -122,11 +122,11 @@ def track_segmentio_event(request): # pylint: disable=too-many-statements
|
||||
# We mostly care about the properties
|
||||
segment_properties = full_segment_event.get('properties', {})
|
||||
|
||||
# Start with the context provided by segment.io in the "client" field if it exists
|
||||
# Start with the context provided by Segment in the "client" field if it exists
|
||||
# We should tightly control which fields actually get included in the event emitted.
|
||||
segment_context = full_segment_event.get('context')
|
||||
|
||||
# Build up the event context by parsing fields out of the event received from segment.io
|
||||
# Build up the event context by parsing fields out of the event received from Segment
|
||||
context = {}
|
||||
|
||||
library_name = segment_context.get('library', {}).get('name')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Ensure we can parse events sent to us from the segment.io webhook integration"""
|
||||
"""Ensure we can parse events sent to us from the Segment webhook integration"""
|
||||
|
||||
from datetime import datetime
|
||||
import json
|
||||
@@ -50,7 +50,7 @@ def expect_failure_with_message(message):
|
||||
EVENT_TRACKING_PROCESSORS=MOBILE_SHIM_PROCESSOR,
|
||||
)
|
||||
class SegmentIOTrackingTestCase(EventTrackingTestCase):
|
||||
"""Test processing of segment.io events"""
|
||||
"""Test processing of Segment events"""
|
||||
|
||||
def setUp(self):
|
||||
super(SegmentIOTrackingTestCase, self).setUp()
|
||||
@@ -85,7 +85,7 @@ class SegmentIOTrackingTestCase(EventTrackingTestCase):
|
||||
self.assert_no_events_emitted()
|
||||
|
||||
def create_request(self, key=None, **kwargs):
|
||||
"""Create a fake request that emulates a request from the segment.io servers to ours"""
|
||||
"""Create a fake request that emulates a request from the Segment servers to ours"""
|
||||
if key is None:
|
||||
key = SECRET
|
||||
|
||||
@@ -106,7 +106,7 @@ class SegmentIOTrackingTestCase(EventTrackingTestCase):
|
||||
self.post_segmentio_event(name=name)
|
||||
|
||||
def post_segmentio_event(self, **kwargs):
|
||||
"""Post a fake segment.io event to the view that processes it"""
|
||||
"""Post a fake Segment event to the view that processes it"""
|
||||
request = self.create_request(
|
||||
data=self.create_segmentio_event_json(**kwargs),
|
||||
content_type='application/json'
|
||||
@@ -114,7 +114,7 @@ class SegmentIOTrackingTestCase(EventTrackingTestCase):
|
||||
segmentio.track_segmentio_event(request)
|
||||
|
||||
def create_segmentio_event(self, **kwargs):
|
||||
"""Populate a fake segment.io event with data of interest"""
|
||||
"""Populate a fake Segment event with data of interest"""
|
||||
action = kwargs.get('action', 'Track')
|
||||
sample_event = {
|
||||
"userId": kwargs.get('user_id', USER_ID),
|
||||
@@ -158,7 +158,7 @@ class SegmentIOTrackingTestCase(EventTrackingTestCase):
|
||||
return sample_event
|
||||
|
||||
def create_segmentio_event_json(self, **kwargs):
|
||||
"""Return a json string containing a fake segment.io event"""
|
||||
"""Return a json string containing a fake Segment event"""
|
||||
return json.dumps(self.create_segmentio_event(**kwargs))
|
||||
|
||||
@expect_failure_with_message(segmentio.WARNING_IGNORED_SOURCE)
|
||||
|
||||
@@ -919,7 +919,7 @@ class GenerateUserCertTests(ModuleStoreTestCase):
|
||||
self.assertIn("Your certificate will be available when you pass the course.", resp.content)
|
||||
|
||||
@patch('courseware.grades.grade', Mock(return_value={'grade': 'Pass', 'percent': 0.75}))
|
||||
@override_settings(CERT_QUEUE='certificates', SEGMENT_IO_LMS_KEY="foobar", FEATURES={'SEGMENT_IO_LMS': True})
|
||||
@override_settings(CERT_QUEUE='certificates', SEGMENT_KEY="foobar")
|
||||
def test_user_with_passing_grade(self):
|
||||
# If user has above passing grading then json will return cert generating message and
|
||||
# status valid code
|
||||
@@ -965,7 +965,7 @@ class GenerateUserCertTests(ModuleStoreTestCase):
|
||||
self.assertIn("Certificate is being created.", resp.content)
|
||||
|
||||
@patch('courseware.grades.grade', Mock(return_value={'grade': 'Pass', 'percent': 0.75}))
|
||||
@override_settings(CERT_QUEUE='certificates', SEGMENT_IO_LMS_KEY="foobar", FEATURES={'SEGMENT_IO_LMS': True})
|
||||
@override_settings(CERT_QUEUE='certificates', SEGMENT_KEY="foobar")
|
||||
def test_user_with_passing_existing_downloadable_cert(self):
|
||||
# If user has already downloadable certificate
|
||||
# then json will return cert generating message with bad request code
|
||||
|
||||
@@ -1383,7 +1383,7 @@ def _track_successful_certificate_generation(user_id, course_id): # pylint: dis
|
||||
None
|
||||
|
||||
"""
|
||||
if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY'):
|
||||
if settings.SEGMENT_KEY:
|
||||
event_name = 'edx.bi.user.certificate.generate'
|
||||
tracking_context = tracker.get_tracker().resolve_context()
|
||||
|
||||
|
||||
@@ -509,7 +509,7 @@ class Order(models.Model):
|
||||
|
||||
"""
|
||||
try:
|
||||
if settings.FEATURES.get('SEGMENT_IO_LMS') and settings.SEGMENT_IO_LMS_KEY:
|
||||
if settings.SEGMENT_KEY:
|
||||
tracking_context = tracker.get_tracker().resolve_context()
|
||||
analytics.track(self.user.id, event_name, { # pylint: disable=no-member
|
||||
'orderId': self.id, # pylint: disable=no-member
|
||||
|
||||
@@ -220,9 +220,8 @@ class OrderTest(ModuleStoreTestCase):
|
||||
self.assertEqual(item.status, status)
|
||||
|
||||
@override_settings(
|
||||
SEGMENT_IO_LMS_KEY="foobar",
|
||||
SEGMENT_KEY="foobar",
|
||||
FEATURES={
|
||||
'SEGMENT_IO_LMS': True,
|
||||
'STORE_BILLING_INFO': True,
|
||||
}
|
||||
)
|
||||
@@ -884,9 +883,8 @@ class CertificateItemTest(ModuleStoreTestCase):
|
||||
self.assertEquals(cert_item.single_item_receipt_template, 'shoppingcart/receipt.html')
|
||||
|
||||
@override_settings(
|
||||
SEGMENT_IO_LMS_KEY="foobar",
|
||||
SEGMENT_KEY="foobar",
|
||||
FEATURES={
|
||||
'SEGMENT_IO_LMS': True,
|
||||
'STORE_BILLING_INFO': True,
|
||||
}
|
||||
)
|
||||
@@ -926,9 +924,8 @@ class CertificateItemTest(ModuleStoreTestCase):
|
||||
self.assertEquals(target_certs[0].order.status, 'purchased')
|
||||
|
||||
@override_settings(
|
||||
SEGMENT_IO_LMS_KEY="foobar",
|
||||
SEGMENT_KEY="foobar",
|
||||
FEATURES={
|
||||
'SEGMENT_IO_LMS': True,
|
||||
'STORE_BILLING_INFO': True,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1939,8 +1939,8 @@ class TestInCourseReverifyView(ModuleStoreTestCase):
|
||||
url += u"?{params}".format(params=urllib.urlencode({"checkpoint": self.reverification_location}))
|
||||
self.assertRedirects(response, url)
|
||||
|
||||
@override_settings(SEGMENT_IO_LMS_KEY="foobar")
|
||||
@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True, 'SEGMENT_IO_LMS': True})
|
||||
@override_settings(SEGMENT_KEY="foobar")
|
||||
@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True})
|
||||
def test_incourse_reverify_get(self):
|
||||
"""
|
||||
Test incourse reverification.
|
||||
@@ -1994,8 +1994,8 @@ class TestInCourseReverifyView(ModuleStoreTestCase):
|
||||
response = self._submit_photos(self.course_key, self.reverification_location, "")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
@override_settings(SEGMENT_IO_LMS_KEY="foobar")
|
||||
@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True, 'SEGMENT_IO_LMS': True})
|
||||
@override_settings(SEGMENT_KEY="foobar")
|
||||
@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True})
|
||||
def test_incourse_reverify_post(self):
|
||||
self._create_checkpoint()
|
||||
self._create_initial_verification()
|
||||
|
||||
@@ -1102,7 +1102,7 @@ class SubmitPhotosView(View):
|
||||
Returns: None
|
||||
|
||||
"""
|
||||
if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY'):
|
||||
if settings.SEGMENT_KEY:
|
||||
tracking_context = tracker.get_tracker().resolve_context()
|
||||
context = {
|
||||
'Google Analytics': {
|
||||
@@ -1439,7 +1439,7 @@ class InCourseReverifyView(View):
|
||||
event_name, user_id, course_id, checkpoint
|
||||
)
|
||||
|
||||
if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY'):
|
||||
if settings.SEGMENT_KEY:
|
||||
tracking_context = tracker.get_tracker().resolve_context()
|
||||
analytics.track(
|
||||
user_id,
|
||||
|
||||
@@ -400,10 +400,7 @@ if 'DJFS' in AUTH_TOKENS and AUTH_TOKENS['DJFS'] is not None:
|
||||
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS = ENV_TOKENS.get('HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS', {})
|
||||
|
||||
############### Mixed Related(Secure/Not-Secure) Items ##########
|
||||
# If Segment.io key specified, load it and enable Segment.io if the feature flag is set
|
||||
SEGMENT_IO_LMS_KEY = AUTH_TOKENS.get('SEGMENT_IO_LMS_KEY')
|
||||
if SEGMENT_IO_LMS_KEY:
|
||||
FEATURES['SEGMENT_IO_LMS'] = ENV_TOKENS.get('SEGMENT_IO_LMS', False)
|
||||
SEGMENT_KEY = AUTH_TOKENS.get('SEGMENT_KEY')
|
||||
|
||||
CC_PROCESSOR_NAME = AUTH_TOKENS.get('CC_PROCESSOR_NAME', CC_PROCESSOR_NAME)
|
||||
CC_PROCESSOR = AUTH_TOKENS.get('CC_PROCESSOR', CC_PROCESSOR)
|
||||
|
||||
@@ -112,7 +112,6 @@
|
||||
"city": "hidden",
|
||||
"country": "required"
|
||||
},
|
||||
"SEGMENT_IO_LMS": true,
|
||||
"SERVER_EMAIL": "devops@example.com",
|
||||
"SESSION_COOKIE_DOMAIN": null,
|
||||
"SITE_NAME": "localhost:8003",
|
||||
|
||||
@@ -182,9 +182,6 @@ FEATURES = {
|
||||
# Staff Debug tool.
|
||||
'ENABLE_STUDENT_HISTORY_VIEW': True,
|
||||
|
||||
# Segment.io for LMS--need to explicitly turn it on for production.
|
||||
'SEGMENT_IO_LMS': False,
|
||||
|
||||
# Provide a UI to allow users to submit feedback from the LMS (left-hand help modal)
|
||||
'ENABLE_FEEDBACK_SUBMISSION': False,
|
||||
|
||||
@@ -611,6 +608,7 @@ USAGE_ID_PATTERN = r'(?P<usage_id>(?:i4x://?[^/]+/[^/]+/[^/]+/[^@]+(?:@[^/]+)?)|
|
||||
|
||||
|
||||
############################## EVENT TRACKING #################################
|
||||
SEGMENT_KEY = None
|
||||
|
||||
# FIXME: Should we be doing this truncation?
|
||||
TRACK_MAX_EVENT = 50000
|
||||
|
||||
@@ -272,12 +272,10 @@ PIPELINE_SASS_ARGUMENTS = '--debug-info --require {proj_dir}/static/sass/bourbon
|
||||
ANALYTICS_SERVER_URL = "http://127.0.0.1:9000/"
|
||||
ANALYTICS_API_KEY = ""
|
||||
|
||||
##### Segment.io ######
|
||||
##### Segment ######
|
||||
|
||||
# If there's an environment variable set, grab it and turn on Segment.io
|
||||
SEGMENT_IO_LMS_KEY = os.environ.get('SEGMENT_IO_LMS_KEY')
|
||||
if SEGMENT_IO_LMS_KEY:
|
||||
FEATURES['SEGMENT_IO_LMS'] = True
|
||||
# If there's an environment variable set, grab it
|
||||
SEGMENT_KEY = os.environ.get('SEGMENT_KEY')
|
||||
|
||||
###################### Payment ######################
|
||||
|
||||
|
||||
@@ -94,7 +94,6 @@ GIT_IMPORT_STATIC = True
|
||||
META_UNIVERSITIES = {}
|
||||
DATADOG = {}
|
||||
EMAIL_FILE_PATH = None
|
||||
SEGMENT_IO_LMS = False
|
||||
|
||||
MONGODB_LOG = {}
|
||||
SESSION_INACTIVITY_TIMEOUT_IN_SECONDS = None
|
||||
@@ -283,8 +282,6 @@ vars().update(AUTH_TOKENS)
|
||||
# Manipulate imported settings with code
|
||||
#
|
||||
|
||||
FEATURES['SEGMENT_IO_LMS'] = SEGMENT_IO_LMS
|
||||
|
||||
if AWS_ACCESS_KEY_ID == "":
|
||||
AWS_ACCESS_KEY_ID = None
|
||||
|
||||
|
||||
@@ -38,10 +38,9 @@ def run():
|
||||
if settings.FEATURES.get('ENABLE_THIRD_PARTY_AUTH', False):
|
||||
enable_third_party_auth()
|
||||
|
||||
# Initialize Segment.io analytics module. Flushes first time a message is received and
|
||||
# every 50 messages thereafter, or if 10 seconds have passed since last flush
|
||||
if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY') and settings.SEGMENT_IO_LMS_KEY: # pylint: disable=line-too-long
|
||||
analytics.write_key = settings.SEGMENT_IO_LMS_KEY
|
||||
# Initialize Segment analytics module by setting the write_key.
|
||||
if settings.SEGMENT_KEY:
|
||||
analytics.write_key = settings.SEGMENT_KEY
|
||||
|
||||
# register any dependency injections that we need to support in edx_proctoring
|
||||
# right now edx_proctoring is dependent on the openedx.core.djangoapps.credit
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
% if settings.FEATURES.get('SEGMENT_IO_LMS'):
|
||||
<!-- begin Segment.io -->
|
||||
% if settings.SEGMENT_KEY:
|
||||
<!-- begin Segment -->
|
||||
<script type="text/javascript">
|
||||
// Asynchronously load Segment.io's analytics.js library
|
||||
// Asynchronously load Segment's analytics.js library
|
||||
window.analytics||(window.analytics=[]),window.analytics.methods=["identify","track","trackLink","trackForm","trackClick","trackSubmit","page","pageview","ab","alias","ready","group","on","once","off"],window.analytics.factory=function(t){return function(){var a=Array.prototype.slice.call(arguments);return a.unshift(t),window.analytics.push(a),window.analytics}};for(var i=0;i<window.analytics.methods.length;i++){var method=window.analytics.methods[i];window.analytics[method]=window.analytics.factory(method)}window.analytics.load=function(t){var a=document.createElement("script");a.type="text/javascript",a.async=!0,a.src=("https:"===document.location.protocol?"https://":"http://")+"d2dq2ahtl5zl1z.cloudfront.net/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(a,n)},window.analytics.SNIPPET_VERSION="2.0.8",
|
||||
analytics.load("${ settings.SEGMENT_IO_LMS_KEY }");
|
||||
analytics.load("${ settings.SEGMENT_KEY }");
|
||||
analytics.page();
|
||||
|
||||
% if user.is_authenticated():
|
||||
@@ -13,9 +13,9 @@
|
||||
});
|
||||
% endif
|
||||
</script>
|
||||
<!-- end Segment.io -->
|
||||
<!-- end Segment -->
|
||||
% else:
|
||||
<!-- dummy segment.io -->
|
||||
<!-- dummy Segment -->
|
||||
<script type="text/javascript">
|
||||
var analytics = {
|
||||
track: function() { return; },
|
||||
@@ -24,5 +24,5 @@
|
||||
page: function() { return; }
|
||||
};
|
||||
</script>
|
||||
<!-- end dummy segment.io -->
|
||||
<!-- end dummy Segment -->
|
||||
% endif
|
||||
|
||||
@@ -261,7 +261,7 @@ def update_email_opt_in(user, org, opt_in):
|
||||
preference.value = str(opt_in)
|
||||
try:
|
||||
preference.save()
|
||||
if settings.FEATURES.get('SEGMENT_IO_LMS') and settings.SEGMENT_IO_LMS_KEY:
|
||||
if settings.SEGMENT_KEY:
|
||||
_track_update_email_opt_in(user.id, org, opt_in)
|
||||
except IntegrityError as err:
|
||||
log.warn(u"Could not update organization wide preference due to IntegrityError: {}".format(err.message))
|
||||
|
||||
@@ -146,7 +146,7 @@ selenium==2.42.1
|
||||
splinter==0.5.4
|
||||
testtools==0.9.34
|
||||
|
||||
# Used for Segment.io analytics
|
||||
# Used for Segment analytics
|
||||
analytics-python==1.1.0
|
||||
|
||||
# Needed for mailchimp(mailing djangoapp)
|
||||
|
||||
Reference in New Issue
Block a user