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
14dc3ce8
Commit
14dc3ce8
authored
Jul 30, 2014
by
Julia Hansbrough
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'release'
parents
7796ece7
079808ee
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
59 additions
and
244 deletions
+59
-244
common/djangoapps/student/models.py
+1
-16
common/lib/xmodule/xmodule/js/src/capa/display.coffee
+1
-2
common/lib/xmodule/xmodule/js/src/sequence/display.coffee
+3
-5
common/static/js/spec/utility_spec.js
+0
-23
common/static/js/src/utility.js
+2
-126
lms/djangoapps/analytics/__init__.py
+0
-0
lms/djangoapps/analytics/basic.py
+0
-0
lms/djangoapps/analytics/csvs.py
+0
-0
lms/djangoapps/analytics/distributions.py
+0
-0
lms/djangoapps/analytics/management/__init__.py
+0
-0
lms/djangoapps/analytics/management/commands/__init__.py
+0
-0
lms/djangoapps/analytics/tests/__init__.py
+0
-0
lms/djangoapps/analytics/tests/test_basic.py
+1
-1
lms/djangoapps/analytics/tests/test_csvs.py
+1
-1
lms/djangoapps/analytics/tests/test_distributions.py
+1
-1
lms/djangoapps/class_dashboard/dashboard_data.py
+1
-1
lms/djangoapps/instructor/views/api.py
+13
-13
lms/envs/dev.py
+4
-3
lms/startup.py
+0
-6
lms/static/coffee/src/instructor_dashboard_tracking.coffee
+1
-2
lms/templates/login.html
+5
-5
lms/templates/main.html
+2
-2
lms/templates/register.html
+1
-1
lms/templates/widgets/segment-io.html
+21
-33
lms/urls.py
+1
-0
requirements/edx/base.txt
+0
-3
No files found.
common/djangoapps/student/models.py
View file @
14dc3ce8
...
...
@@ -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
)
...
...
common/lib/xmodule/xmodule/js/src/capa/display.coffee
View file @
14dc3ce8
...
...
@@ -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
...
...
common/lib/xmodule/xmodule/js/src/sequence/display.coffee
View file @
14dc3ce8
...
...
@@ -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
...
...
common/static/js/spec/utility_spec.js
View file @
14dc3ce8
...
...
@@ -16,26 +16,3 @@ describe('utility.rewriteStaticLinks', function () {
).
toBe
(
'<img src="http://www.mysite.org/static/foo.x"/>'
)
});
});
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'
}));
});
});
common/static/js/src/utility.js
View file @
14dc3ce8
...
...
@@ -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
lms/djangoapps/
instructor_
analytics/__init__.py
→
lms/djangoapps/analytics/__init__.py
View file @
14dc3ce8
File moved
lms/djangoapps/
instructor_
analytics/basic.py
→
lms/djangoapps/analytics/basic.py
View file @
14dc3ce8
File moved
lms/djangoapps/
instructor_
analytics/csvs.py
→
lms/djangoapps/analytics/csvs.py
View file @
14dc3ce8
File moved
lms/djangoapps/
instructor_
analytics/distributions.py
→
lms/djangoapps/analytics/distributions.py
View file @
14dc3ce8
File moved
lms/djangoapps/
instructor_
analytics/management/__init__.py
→
lms/djangoapps/analytics/management/__init__.py
View file @
14dc3ce8
File moved
lms/djangoapps/
instructor_
analytics/management/commands/__init__.py
→
lms/djangoapps/analytics/management/commands/__init__.py
View file @
14dc3ce8
File moved
lms/djangoapps/
instructor_
analytics/tests/__init__.py
→
lms/djangoapps/analytics/tests/__init__.py
View file @
14dc3ce8
File moved
lms/djangoapps/
instructor_
analytics/tests/test_basic.py
→
lms/djangoapps/analytics/tests/test_basic.py
View file @
14dc3ce8
...
...
@@ -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
):
...
...
lms/djangoapps/
instructor_
analytics/tests/test_csvs.py
→
lms/djangoapps/analytics/tests/test_csvs.py
View file @
14dc3ce8
...
...
@@ -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
):
...
...
lms/djangoapps/
instructor_
analytics/tests/test_distributions.py
→
lms/djangoapps/analytics/tests/test_distributions.py
View file @
14dc3ce8
...
...
@@ -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
):
...
...
lms/djangoapps/class_dashboard/dashboard_data.py
View file @
14dc3ce8
...
...
@@ -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
...
...
lms/djangoapps/instructor/views/api.py
View file @
14dc3ce8
...
...
@@ -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
,
...
...
lms/envs/dev.py
View file @
14dc3ce8
...
...
@@ -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 ###########################
...
...
lms/startup.py
View file @
14dc3ce8
...
...
@@ -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
():
"""
...
...
lms/static/coffee/src/instructor_dashboard_tracking.coffee
View file @
14dc3ce8
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
()
lms/templates/login.html
View file @
14dc3ce8
...
...
@@ -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
)
{
...
...
lms/templates/main.html
View file @
14dc3ce8
...
...
@@ -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>
...
...
lms/templates/register.html
View file @
14dc3ce8
...
...
@@ -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
)
{
...
...
lms/templates/widgets/segment-io.html
View file @
14dc3ce8
% 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:
...
...
lms/urls.py
View file @
14dc3ce8
...
...
@@ -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:
...
...
requirements/edx/base.txt
View file @
14dc3ce8
...
...
@@ -128,9 +128,6 @@ splinter==0.5.4
testtools==0.9.34
flaky==0.2.0
# Used for Segment.io analytics
analytics-python==0.4.4
git+https://github.com/mfogel/django-settings-context-processor.git
# django-cas version 2.0.3 with patch to be compatible with django 1.4
...
...
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