Merge branch 'release'

This commit is contained in:
Julia Hansbrough
2014-07-30 19:35:51 +00:00
26 changed files with 58 additions and 244 deletions

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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

View File

@@ -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,

View File

@@ -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 ###########################

View File

@@ -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():
"""

View File

@@ -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()

View File

@@ -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) {

View File

@@ -95,6 +95,8 @@
<%include file="${google_analytics_file}" />
<%include file="widgets/segment-io.html" />
% if style_overrides_file:
<link rel="stylesheet" type="text/css" href="${static.url(style_overrides_file)}" />
@@ -121,8 +123,6 @@
<%static:js group='module-js'/>
<%block name="js_extra"/>
<%include file="widgets/segment-io.html" />
</body>
</html>

View File

@@ -55,7 +55,7 @@
$('#register-form').on('ajax:success', function(event, json, xhr) {
var url = json.redirect_url || "${reverse('dashboard')}";
location.href = appendParameter(url, "signin", "initial");
location.href = url;
});
$('#register-form').on('ajax:error', function(event, jqXHR, textStatus) {

View File

@@ -1,56 +1,44 @@
% if settings.FEATURES.get('SEGMENT_IO_LMS'):
<!-- begin Segment.io -->
<%! from django.core.urlresolvers import reverse %>
<%! import waffle %>
<% active_flags = " + ".join(waffle.get_flags(request)) %>
<script type="text/javascript">
// Asynchronously load Segment.io'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.page();
% if user.is_authenticated():
// Access the query string, stripping the leading "?"
var queryString = window.location.search.substring(1);
if (queryString != "") {
// Convert the query string to a key/value object
var parameters = window.parseQueryString(queryString);
analytics.identify("${ user.id }", {
"Registered" : true,
email : "${ user.email }",
username : "${ user.username }",
// Count the number of courses in which the user is currently enrolled
"Enrollment Count": ${ sum(1 for course in user.courseenrollment_set.values() if course['is_active'] == True) },
"Active Flags" : "${ active_flags }",
});
if ("signin" in parameters) {
window.assessUserSignIn(parameters, "${user.id}", "${user.email}", "${user.username}");
} else {
window.identifyUser("${user.id}", "${user.email}", "${user.username}");
}
} else {
window.identifyUser("${user.id}", "${user.email}", "${user.username}");
}
% endif
// Get current page URL
var url = window.location.href
// Match on the current url and fire the appropriate pageview event
if (url.indexOf("/register") > -1) {
// Get current page URL and pull out the path
path = window.location.href.split("/")[3]
// Match on the current path and fire the appropriate pageview event
if (path == "register") {
// Registration page viewed
analytics.track("edx.bi.page.register.viewed", {
category: "pageview"
});
} else if (url.indexOf("/login") > -1) {
analytics.page("Registration");
} else if (path == "login") {
// Login page viewed
analytics.track("edx.bi.page.login.viewed", {
category: "pageview"
});
} else if (url.indexOf("/dashboard") > -1) {
analytics.page("Login");
} else if (path == "dashboard") {
// Dashboard viewed
analytics.track("edx.bi.page.dashboard.viewed", {
category: "pageview"
});
analytics.page("Dashboard");
} else {
// This event serves as a catch-all, firing when any other page is viewed
analytics.track("edx.bi.page.other.viewed", {
category: "pageview"
});
analytics.page("Other");
}
</script>
<!-- end Segment.io -->
% else:

View File

@@ -4,6 +4,7 @@ from ratelimitbackend import admin
from django.conf.urls.static import static
import django.contrib.auth.views
from microsite_configuration import microsite
# Uncomment the next two lines to enable the admin: