diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py
index a78b4effe5..e34828b547 100644
--- a/common/djangoapps/student/models.py
+++ b/common/djangoapps/student/models.py
@@ -47,8 +47,6 @@ from course_modes.models import CourseMode
from ratelimitbackend import admin
-import analytics
-
unenroll_done = Signal(providing_args=["course_enrollment"])
log = logging.getLogger(__name__)
AUDIT_LOG = logging.getLogger("audit")
@@ -708,7 +706,6 @@ class CourseEnrollment(models.Model):
if activation_changed or mode_changed:
self.save()
-
if activation_changed:
if self.is_active:
self.emit_event(EVENT_NAME_ENROLLMENT_ACTIVATED)
@@ -722,7 +719,7 @@ class CourseEnrollment(models.Model):
else:
unenroll_done.send(sender=None, course_enrollment=self)
-
+
self.emit_event(EVENT_NAME_ENROLLMENT_DEACTIVATED)
dog_stats_api.increment(
@@ -752,16 +749,6 @@ 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:
- analytics.track(self.user_id, event_name, {
- 'category': 'conversion',
- 'label': self.course_id.to_deprecated_string(),
- 'org': self.course_id.org,
- 'course': self.course_id.course,
- 'run': self.course_id.run,
- 'mode': self.mode,
- })
except: # pylint: disable=bare-except
if event_name and self.course_id:
log.exception('Unable to emit event %s for user %s and course %s', event_name, self.user.username, self.course_id)
@@ -786,8 +773,6 @@ class CourseEnrollment(models.Model):
It is expected that this method is called from a method which has already
verified the user authentication and access.
-
- Also emits relevant events for analytics purposes.
"""
enrollment = cls.get_or_create_enrollment(user, course_key)
enrollment.update_enrollment(is_active=True, mode=mode)
diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee
index 592c9b3a0c..e8326f55e9 100644
--- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee
+++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee
@@ -300,8 +300,7 @@ class @Problem
Logger.log 'problem_check', @answers
# Segment.io
- analytics.track "edx.bi.course.problem.checked",
- category: "courseware"
+ analytics.track "Problem Checked",
problem_id: @id
answers: @answers
diff --git a/common/lib/xmodule/xmodule/js/src/sequence/display.coffee b/common/lib/xmodule/xmodule/js/src/sequence/display.coffee
index 784075a355..76557a517c 100644
--- a/common/lib/xmodule/xmodule/js/src/sequence/display.coffee
+++ b/common/lib/xmodule/xmodule/js/src/sequence/display.coffee
@@ -128,8 +128,7 @@ class @Sequence
analytics.pageview @id
# navigation by clicking the tab directly
- analytics.track "edx.bi.course.sequential.direct.clicked",
- category: "courseware"
+ analytics.track "Accessed Sequential Directly",
sequence_id: @id
current_sequential: @position
target_sequential: new_position
@@ -168,10 +167,9 @@ class @Sequence
# navigation using the next or previous arrow button.
tracking_messages =
- seq_prev: "edx.bi.course.sequential.previous.clicked"
- seq_next: "edx.bi.course.sequential.next.clicked"
+ seq_prev: "Accessed Previous Sequential"
+ seq_next: "Accessed Next Sequential"
analytics.track tracking_messages[direction],
- category: "courseware"
sequence_id: @id
current_sequential: @position
target_sequential: new_position
diff --git a/common/static/js/spec/utility_spec.js b/common/static/js/spec/utility_spec.js
index c268d816dc..c44d36e893 100644
--- a/common/static/js/spec/utility_spec.js
+++ b/common/static/js/spec/utility_spec.js
@@ -16,26 +16,3 @@ describe('utility.rewriteStaticLinks', function () {
).toBe('
')
});
});
-
-describe('utility.appendParameter', function() {
- it('creates and populates query string with provided parameter', function() {
- expect(appendParameter('/cambridge', 'season', 'fall')).toBe('/cambridge?season=fall')
- });
- it('appends provided parameter to existing query string parameters', function() {
- expect(appendParameter('/cambridge?season=fall', 'color', 'red')).toBe('/cambridge?season=fall&color=red')
- });
- it('appends provided parameter to existing query string with a trailing ampersand', function() {
- expect(appendParameter('/cambridge?season=fall&', 'color', 'red')).toBe('/cambridge?season=fall&color=red')
- });
- it('overwrites existing parameter with provided value', function() {
- expect(appendParameter('/cambridge?season=fall', 'season', 'winter')).toBe('/cambridge?season=winter');
- expect(appendParameter('/cambridge?season=fall&color=red', 'color', 'orange')).toBe('/cambridge?season=fall&color=orange');
- });
-});
-
-describe('utility.parseQueryString', function() {
- it('converts a non-empty query string into a key/value object', function() {
- expect(JSON.stringify(parseQueryString('season=fall'))).toBe(JSON.stringify({season:'fall'}));
- expect(JSON.stringify(parseQueryString('season=fall&color=red'))).toBe(JSON.stringify({season:'fall', color:'red'}));
- });
-});
diff --git a/common/static/js/src/utility.js b/common/static/js/src/utility.js
index ab899711f8..7b5dd5a6bb 100644
--- a/common/static/js/src/utility.js
+++ b/common/static/js/src/utility.js
@@ -38,129 +38,4 @@ window.rewriteStaticLinks = function(content, from, to) {
// note: add other protocols here
var regex = new RegExp("(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}([-a-zA-Z0-9@:%_\+.~#?&//=]*))?"+from, 'g');
return content.replace(regex, replacer);
-};
-
-// Appends a parameter to a path; useful for indicating initial or return signin, for example
-window.appendParameter = function(path, key, value) {
- // Check if the given path already contains a query string by looking for the ampersand separator
- if (path.indexOf("?") > -1) {
- var splitPath = path.split("?");
- var parameters = window.parseQueryString(splitPath[1]);
- // Check if the provided key already exists in the query string
- if (key in parameters) {
- // Overwrite the existing key's value with the provided value
- parameters[key] = value;
-
- // Reconstruct the path, including the overwritten key/value pair
- var reconstructedPath = splitPath[0] + "?";
- for (var k in parameters) {
- reconstructedPath = reconstructedPath + k + "=" + parameters[k] + "&";
- }
- // Strip the trailing ampersand
- return reconstructedPath.slice(0, -1);
- } else {
- // Check for a trailing ampersand
- if (path[path.length - 1] != "&") {
- // Append signin parameter to the existing query string
- return path + "&" + key + "=" + value;
- } else {
- // Append signin parameter to the existing query string, excluding the ampersand
- return path + key + "=" + value;
- }
- }
- } else {
- // Append new query string containing the provided parameter
- return path + "?" + key + "=" + value;
- }
-};
-
-// Convert a query string to a key/value object
-window.parseQueryString = function(queryString) {
- var parameters = {}, queries, pair, i, l;
-
- // Split the query string into key/value pairs
- queries = queryString.split("&");
-
- // Break the array of strings into an object
- for (i = 0, l = queries.length; i < l; i++) {
- pair = queries[i].split('=');
- parameters[pair[0]] = pair[1];
- }
-
- return parameters
-};
-
-// Check if the user recently enrolled in a course by looking at a referral URL
-window.checkRecentEnrollment = function(referrer) {
- var enrolledIn = null;
-
- // Check if the referrer URL contains a query string
- if (referrer.indexOf("?") > -1) {
- referrerQueryString = referrer.split("?")[1];
- } else {
- referrerQueryString = "";
- }
-
- if (referrerQueryString != "") {
- // Convert a non-empty query string into a key/value object
- var referrerParameters = window.parseQueryString(referrerQueryString);
- if ("course_id" in referrerParameters && "enrollment_action" in referrerParameters) {
- if (referrerParameters.enrollment_action == "enroll") {
- enrolledIn = referrerParameters.course_id;
- }
- }
- }
-
- return enrolledIn
-};
-
-window.assessUserSignIn = function(parameters, userID, email, username) {
- // Check if the user has logged in to enroll in a course - designed for when "Register" button registers users on click (currently, this could indicate a course registration when there may not have yet been one)
- var enrolledIn = window.checkRecentEnrollment(document.referrer);
-
- // Check if the user has just registered
- if (parameters.signin == "initial") {
- window.trackAccountRegistration(enrolledIn, userID, email, username);
- } else {
- window.trackReturningUserSignIn(enrolledIn, userID, email, username);
- }
-};
-
-window.trackAccountRegistration = function(enrolledIn, userID, email, username) {
- // Alias the user's anonymous history with the user's new identity (for Mixpanel)
- analytics.alias(userID);
-
- // Map the user's activity to their newly assigned ID
- analytics.identify(userID, {
- email: email,
- username: username
- });
-
- // Track the user's account creation
- analytics.track("edx.bi.user.account.registered", {
- category: "conversion",
- label: enrolledIn != null ? enrolledIn : "none"
- });
-};
-
-window.trackReturningUserSignIn = function(enrolledIn, userID, email, username) {
- // Map the user's activity to their assigned ID
- analytics.identify(userID, {
- email: email,
- username: username
- });
-
- // Track the user's sign in
- analytics.track("edx.bi.user.account.authenticated", {
- category: "conversion",
- label: enrolledIn != null ? enrolledIn : "none"
- });
-};
-
-window.identifyUser = function(userID, email, username) {
- // If the signin parameter isn't present but the query string is non-empty, map the user's activity to their assigned ID
- analytics.identify(userID, {
- email: email,
- username: username
- });
-};
+};
\ No newline at end of file
diff --git a/lms/djangoapps/instructor_analytics/__init__.py b/lms/djangoapps/analytics/__init__.py
similarity index 100%
rename from lms/djangoapps/instructor_analytics/__init__.py
rename to lms/djangoapps/analytics/__init__.py
diff --git a/lms/djangoapps/instructor_analytics/basic.py b/lms/djangoapps/analytics/basic.py
similarity index 100%
rename from lms/djangoapps/instructor_analytics/basic.py
rename to lms/djangoapps/analytics/basic.py
diff --git a/lms/djangoapps/instructor_analytics/csvs.py b/lms/djangoapps/analytics/csvs.py
similarity index 100%
rename from lms/djangoapps/instructor_analytics/csvs.py
rename to lms/djangoapps/analytics/csvs.py
diff --git a/lms/djangoapps/instructor_analytics/distributions.py b/lms/djangoapps/analytics/distributions.py
similarity index 100%
rename from lms/djangoapps/instructor_analytics/distributions.py
rename to lms/djangoapps/analytics/distributions.py
diff --git a/lms/djangoapps/instructor_analytics/management/__init__.py b/lms/djangoapps/analytics/management/__init__.py
similarity index 100%
rename from lms/djangoapps/instructor_analytics/management/__init__.py
rename to lms/djangoapps/analytics/management/__init__.py
diff --git a/lms/djangoapps/instructor_analytics/management/commands/__init__.py b/lms/djangoapps/analytics/management/commands/__init__.py
similarity index 100%
rename from lms/djangoapps/instructor_analytics/management/commands/__init__.py
rename to lms/djangoapps/analytics/management/commands/__init__.py
diff --git a/lms/djangoapps/instructor_analytics/tests/__init__.py b/lms/djangoapps/analytics/tests/__init__.py
similarity index 100%
rename from lms/djangoapps/instructor_analytics/tests/__init__.py
rename to lms/djangoapps/analytics/tests/__init__.py
diff --git a/lms/djangoapps/instructor_analytics/tests/test_basic.py b/lms/djangoapps/analytics/tests/test_basic.py
similarity index 94%
rename from lms/djangoapps/instructor_analytics/tests/test_basic.py
rename to lms/djangoapps/analytics/tests/test_basic.py
index 3cb70033db..5aae8d524f 100644
--- a/lms/djangoapps/instructor_analytics/tests/test_basic.py
+++ b/lms/djangoapps/analytics/tests/test_basic.py
@@ -7,7 +7,7 @@ from student.models import CourseEnrollment
from student.tests.factories import UserFactory
from opaque_keys.edx.locations import SlashSeparatedCourseKey
-from instructor_analytics.basic import enrolled_students_features, AVAILABLE_FEATURES, STUDENT_FEATURES, PROFILE_FEATURES
+from analytics.basic import enrolled_students_features, AVAILABLE_FEATURES, STUDENT_FEATURES, PROFILE_FEATURES
class TestAnalyticsBasic(TestCase):
diff --git a/lms/djangoapps/instructor_analytics/tests/test_csvs.py b/lms/djangoapps/analytics/tests/test_csvs.py
similarity index 98%
rename from lms/djangoapps/instructor_analytics/tests/test_csvs.py
rename to lms/djangoapps/analytics/tests/test_csvs.py
index 41c0426cc9..d6673b95a4 100644
--- a/lms/djangoapps/instructor_analytics/tests/test_csvs.py
+++ b/lms/djangoapps/analytics/tests/test_csvs.py
@@ -3,7 +3,7 @@
from django.test import TestCase
from nose.tools import raises
-from instructor_analytics.csvs import create_csv_response, format_dictlist, format_instances
+from analytics.csvs import create_csv_response, format_dictlist, format_instances
class TestAnalyticsCSVS(TestCase):
diff --git a/lms/djangoapps/instructor_analytics/tests/test_distributions.py b/lms/djangoapps/analytics/tests/test_distributions.py
similarity index 97%
rename from lms/djangoapps/instructor_analytics/tests/test_distributions.py
rename to lms/djangoapps/analytics/tests/test_distributions.py
index ce75d47fc6..2975186b29 100644
--- a/lms/djangoapps/instructor_analytics/tests/test_distributions.py
+++ b/lms/djangoapps/analytics/tests/test_distributions.py
@@ -6,7 +6,7 @@ from student.models import CourseEnrollment
from student.tests.factories import UserFactory
from opaque_keys.edx.locations import SlashSeparatedCourseKey
-from instructor_analytics.distributions import profile_distribution, AVAILABLE_PROFILE_FEATURES
+from analytics.distributions import profile_distribution, AVAILABLE_PROFILE_FEATURES
class TestAnalyticsDistributions(TestCase):
diff --git a/lms/djangoapps/class_dashboard/dashboard_data.py b/lms/djangoapps/class_dashboard/dashboard_data.py
index 5a4ba202aa..bd203a0ad5 100644
--- a/lms/djangoapps/class_dashboard/dashboard_data.py
+++ b/lms/djangoapps/class_dashboard/dashboard_data.py
@@ -10,7 +10,7 @@ from django.utils.translation import ugettext as _
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.inheritance import own_metadata
-from instructor_analytics.csvs import create_csv_response
+from analytics.csvs import create_csv_response
from opaque_keys.edx.locations import Location
diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py
index 67e2eaa84c..b9516b8f19 100644
--- a/lms/djangoapps/instructor/views/api.py
+++ b/lms/djangoapps/instructor/views/api.py
@@ -47,9 +47,9 @@ from instructor.enrollment import (
)
from instructor.access import list_with_level, allow_access, revoke_access, update_forum_role
from instructor.offline_gradecalc import student_grades
-import instructor_analytics.basic
-import instructor_analytics.distributions
-import instructor_analytics.csvs
+import analytics.basic
+import analytics.distributions
+import analytics.csvs
import csv
from submissions import api as sub_api # installed from the edx-submissions repository
@@ -538,7 +538,7 @@ def get_grading_config(request, course_id):
course = get_course_with_access(
request.user, 'staff', course_id, depth=None
)
- grading_config_summary = instructor_analytics.basic.dump_grading_context(course)
+ grading_config_summary = analytics.basic.dump_grading_context(course)
response_payload = {
'course_id': course_id.to_deprecated_string(),
@@ -561,14 +561,14 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=W06
"""
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
- available_features = instructor_analytics.basic.AVAILABLE_FEATURES
+ available_features = analytics.basic.AVAILABLE_FEATURES
query_features = [
'id', 'username', 'name', 'email', 'language', 'location',
'year_of_birth', 'gender', 'level_of_education', 'mailing_address',
'goals',
]
- student_data = instructor_analytics.basic.enrolled_students_features(course_id, query_features)
+ student_data = analytics.basic.enrolled_students_features(course_id, query_features)
# Provide human-friendly and translatable names for these features. These names
# will be displayed in the table generated in data_download.coffee. It is not (yet)
@@ -598,8 +598,8 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=W06
}
return JsonResponse(response_payload)
else:
- header, datarows = instructor_analytics.csvs.format_dictlist(student_data, query_features)
- return instructor_analytics.csvs.create_csv_response("enrolled_profiles.csv", header, datarows)
+ header, datarows = analytics.csvs.format_dictlist(student_data, query_features)
+ return analytics.csvs.create_csv_response("enrolled_profiles.csv", header, datarows)
@ensure_csrf_cookie
@@ -610,8 +610,8 @@ def get_anon_ids(request, course_id): # pylint: disable=W0613
Respond with 2-column CSV output of user-id, anonymized-user-id
"""
# TODO: the User.objects query and CSV generation here could be
- # centralized into instructor_analytics. Currently instructor_analytics
- # has similar functionality but not quite what's needed.
+ # centralized into analytics. Currently analytics has similar functionality
+ # but not quite what's needed.
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
def csv_response(filename, header, rows):
"""Returns a CSV http response for the given header and rows (excel/utf-8)."""
@@ -655,7 +655,7 @@ def get_distribution(request, course_id):
else:
feature = str(feature)
- available_features = instructor_analytics.distributions.AVAILABLE_PROFILE_FEATURES
+ available_features = analytics.distributions.AVAILABLE_PROFILE_FEATURES
# allow None so that requests for no feature can list available features
if not feature in available_features + (None,):
return HttpResponseBadRequest(strip_tags(
@@ -666,12 +666,12 @@ def get_distribution(request, course_id):
'course_id': course_id.to_deprecated_string(),
'queried_feature': feature,
'available_features': available_features,
- 'feature_display_names': instructor_analytics.distributions.DISPLAY_NAMES,
+ 'feature_display_names': analytics.distributions.DISPLAY_NAMES,
}
p_dist = None
if not feature is None:
- p_dist = instructor_analytics.distributions.profile_distribution(course_id, feature)
+ p_dist = analytics.distributions.profile_distribution(course_id, feature)
response_payload['feature_results'] = {
'feature': p_dist.feature,
'feature_display_name': p_dist.feature_display_name,
diff --git a/lms/envs/dev.py b/lms/envs/dev.py
index 074dcf5092..83484cbfbf 100644
--- a/lms/envs/dev.py
+++ b/lms/envs/dev.py
@@ -268,21 +268,22 @@ ANALYTICS_DATA_URL = "http://127.0.0.1:8080"
ANALYTICS_DATA_TOKEN = ""
FEATURES['ENABLE_ANALYTICS_ACTIVE_COUNT'] = False
-##### Segment.io ######
+##### segment-io ######
# 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
-###################### Payment ######################
+###################### Payment ##############################3
CC_PROCESSOR['CyberSource']['SHARED_SECRET'] = os.environ.get('CYBERSOURCE_SHARED_SECRET', '')
CC_PROCESSOR['CyberSource']['MERCHANT_ID'] = os.environ.get('CYBERSOURCE_MERCHANT_ID', '')
CC_PROCESSOR['CyberSource']['SERIAL_NUMBER'] = os.environ.get('CYBERSOURCE_SERIAL_NUMBER', '')
CC_PROCESSOR['CyberSource']['PURCHASE_ENDPOINT'] = os.environ.get('CYBERSOURCE_PURCHASE_ENDPOINT', '')
-########################## USER API ##########################
+
+########################## USER API ########################
EDX_API_KEY = None
####################### Shoppingcart ###########################
diff --git a/lms/startup.py b/lms/startup.py
index b073a16334..8487c52186 100644
--- a/lms/startup.py
+++ b/lms/startup.py
@@ -10,7 +10,6 @@ settings.INSTALLED_APPS # pylint: disable=W0104
from django_startup import autostartup
import edxmako
import logging
-import analytics
log = logging.getLogger(__name__)
@@ -32,11 +31,6 @@ 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 settings.SEGMENT_IO_LMS_KEY:
- analytics.init(settings.SEGMENT_IO_LMS_KEY, flush_at=50)
-
def add_mimetypes():
"""
diff --git a/lms/static/coffee/src/instructor_dashboard_tracking.coffee b/lms/static/coffee/src/instructor_dashboard_tracking.coffee
index e32f5f57bd..eaeb3a4862 100644
--- a/lms/static/coffee/src/instructor_dashboard_tracking.coffee
+++ b/lms/static/coffee/src/instructor_dashboard_tracking.coffee
@@ -1,5 +1,4 @@
if $('.instructor-dashboard-wrapper').length == 1
- analytics.track "edx.bi.course.legacy_instructor_dashboard.loaded",
- category: "courseware"
+ analytics.track "Loaded a Legacy Instructor Dashboard Page",
location: window.location.pathname
dashboard_page: $('.navbar .selectedmode').text()
diff --git a/lms/templates/login.html b/lms/templates/login.html
index 293bd5d934..7035c56d97 100644
--- a/lms/templates/login.html
+++ b/lms/templates/login.html
@@ -59,16 +59,16 @@
next = decodeURIComponent(next);
}
if (next && !isExternal(next)) {
- location.href=appendParameter(next, "signin", "return");
+ location.href=next;
} else if(json.redirect_url){
- location.href=appendParameter(json.redirect_url, "signin", "return");
+ location.href=json.redirect_url;
} else {
- location.href=appendParameter("${reverse('dashboard')}", "signin", "return");
+ location.href="${reverse('dashboard')}";
}
} else if(json.hasOwnProperty('redirect')) {
var u=decodeURI(window.location.search);
if (!isExternal(json.redirect)) { // a paranoid check. Our server is the one providing json.redirect
- location.href=appendParameter(json.redirect+u, "signin", "return");
+ location.href=json.redirect+u;
} // else we just remain on this page, which is fine since this particular path implies a login failure
// that has been generated via packet tampering (json.redirect has been messed with).
} else {
@@ -103,7 +103,7 @@
function thirdPartySignin(event, url) {
event.preventDefault();
- window.location.href = appendParameter(url, "signin", "return");
+ window.location.href = url;
}
(function post_form_if_pipeline_running(pipeline_running) {
diff --git a/lms/templates/main.html b/lms/templates/main.html
index 1c81419f7f..8fca033e36 100644
--- a/lms/templates/main.html
+++ b/lms/templates/main.html
@@ -95,6 +95,8 @@
<%include file="${google_analytics_file}" />
+ <%include file="widgets/segment-io.html" />
+
% if style_overrides_file:
@@ -121,8 +123,6 @@
<%static:js group='module-js'/>
<%block name="js_extra"/>
-
- <%include file="widgets/segment-io.html" />