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
c4804485
Commit
c4804485
authored
Oct 21, 2014
by
Zia Fazal
Committed by
Jonathan Piacenti
Aug 20, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ziafazal/api-added-participant-activity-to-metrics: added
active_users and users_enrolled metrics
parent
00008c06
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
31 additions
and
84 deletions
+31
-84
lms/djangoapps/api_manager/courses/tests.py
+10
-4
lms/djangoapps/api_manager/courses/views.py
+21
-80
No files found.
lms/djangoapps/api_manager/courses/tests.py
View file @
c4804485
...
...
@@ -2095,6 +2095,11 @@ class CoursesApiTests(ModuleStoreTestCase):
self
.
assertEqual
(
len
(
response
.
data
[
'modules_completed'
]),
5
)
total_modules_completed
=
sum
([
completed
[
1
]
for
completed
in
response
.
data
[
'modules_completed'
]])
self
.
assertEqual
(
total_modules_completed
,
4
)
self
.
assertEqual
(
len
(
response
.
data
[
'active_users'
]),
5
)
total_active
=
sum
([
active
[
1
]
for
active
in
response
.
data
[
'active_users'
]])
self
.
assertEqual
(
total_active
,
5
)
self
.
assertEqual
(
response
.
data
[
'users_enrolled'
][
0
][
1
],
25
)
# get modules completed for first 5 days
start_date
=
datetime
.
now
()
.
date
()
+
relativedelta
(
days
=-
USER_COUNT
)
...
...
@@ -2112,7 +2117,7 @@ class CoursesApiTests(ModuleStoreTestCase):
# metrics with weeks as interval
end_date
=
datetime
.
now
()
.
date
()
start_date
=
end_date
+
relativedelta
(
days
=-
10
)
start_date
=
end_date
+
relativedelta
(
weeks
=-
2
)
course_metrics_uri
=
'{}/{}/time-series-metrics/?start_date={}&end_date={}&'
\
'interval=weeks'
.
format
(
self
.
base_courses_uri
,
test_course_id
,
...
...
@@ -2121,9 +2126,9 @@ class CoursesApiTests(ModuleStoreTestCase):
response
=
self
.
do_get
(
course_metrics_uri
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
len
(
response
.
data
[
'users_not_started'
]),
2
)
self
.
assertEqual
(
len
(
response
.
data
[
'users_started'
]),
2
)
self
.
assertEqual
(
len
(
response
.
data
[
'users_completed'
]),
2
)
self
.
assert
Greater
Equal
(
len
(
response
.
data
[
'users_not_started'
]),
2
)
self
.
assert
Greater
Equal
(
len
(
response
.
data
[
'users_started'
]),
2
)
self
.
assert
Greater
Equal
(
len
(
response
.
data
[
'users_completed'
]),
2
)
# metrics with months as interval
start_date
=
end_date
+
relativedelta
(
months
=-
3
)
...
...
@@ -2157,6 +2162,7 @@ class CoursesApiTests(ModuleStoreTestCase):
response
=
self
.
do_get
(
course_metrics_uri
)
self
.
assertEqual
(
response
.
status_code
,
400
)
def
test_course_workgroups_list
(
self
):
projects_uri
=
self
.
base_projects_uri
data
=
{
...
...
lms/djangoapps/api_manager/courses/views.py
View file @
c4804485
...
...
@@ -5,6 +5,7 @@ import logging
import
itertools
from
lxml
import
etree
from
StringIO
import
StringIO
from
dateutil.relativedelta
import
relativedelta
from
django.conf
import
settings
from
django.contrib.auth.models
import
Group
,
User
...
...
@@ -1541,80 +1542,6 @@ class CoursesMetrics(SecureAPIView):
data
.
update
(
thread_stats
)
return
Response
(
data
,
status
=
status
.
HTTP_200_OK
)
class
CoursesTimeSeriesMetrics
(
SecureAPIView
):
"""
### The CoursesTimeSeriesMetrics view allows clients to retrieve a list of Metrics for the specified Course
in time series format.
- URI: ```/api/courses/{course_id}/time-series-metrics/?start_date={date}&end_date={date}&interval={interval}&organization={organization_id}```
- interval can be `days`, `weeks` or `months`
- GET: Returns a JSON representation with three metrics
{
"users_not_started": [[datetime-1, count-1], [datetime-2, count-2], ........ [datetime-n, count-n]],
"users_started": [[datetime-1, count-1], [datetime-2, count-2], ........ [datetime-n, count-n]],
"users_completed": [[datetime-1, count-1], [datetime-2, count-2], ........ [datetime-n, count-n]]
}
- metrics can be filtered by organization by adding organization parameter to GET request
### Use Cases/Notes:
* Example: Display number of users completed, started or not started in a given course for a given time period
"""
def
get
(
self
,
request
,
course_id
):
# pylint: disable=W0613
"""
GET /api/courses/{course_id}/time-series-metrics/
"""
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
start
=
request
.
QUERY_PARAMS
.
get
(
'start_date'
,
None
)
end
=
request
.
QUERY_PARAMS
.
get
(
'end_date'
,
None
)
interval
=
request
.
QUERY_PARAMS
.
get
(
'interval'
,
'days'
)
if
not
start
or
not
end
:
return
Response
({
"message"
:
_
(
"Both start_date and end_date parameters are required"
)}
,
status
=
status
.
HTTP_400_BAD_REQUEST
)
if
interval
not
in
[
'days'
,
'weeks'
,
'months'
]:
return
Response
({
"message"
:
_
(
"Interval parameter is not valid. It should be one of these "
"'days', 'weeks', 'months'"
)},
status
=
status
.
HTTP_400_BAD_REQUEST
)
start_dt
=
parse_datetime
(
start
)
end_dt
=
parse_datetime
(
end
)
course_key
=
get_course_key
(
course_id
)
exclude_users
=
_get_aggregate_exclusion_user_ids
(
course_key
)
grade_complete_match_range
=
getattr
(
settings
,
'GRADEBOOK_GRADE_COMPLETE_PROFORMA_MATCH_RANGE'
,
0.01
)
grades_qs
=
StudentGradebook
.
objects
.
filter
(
course_id__exact
=
course_key
,
user__is_active
=
True
)
.
\
exclude
(
user_id__in
=
exclude_users
)
grades_complete_qs
=
grades_qs
.
filter
(
proforma_grade__lte
=
F
(
'grade'
)
+
grade_complete_match_range
,
proforma_grade__gt
=
0
)
enrolled_qs
=
CourseEnrollment
.
objects
.
filter
(
course_id__exact
=
course_key
,
user__is_active
=
True
)
\
.
exclude
(
id__in
=
exclude_users
)
users_started_qs
=
StudentProgress
.
objects
.
filter
(
course_id__exact
=
course_key
,
user__is_active
=
True
)
\
.
exclude
(
user_id__in
=
exclude_users
)
organization
=
request
.
QUERY_PARAMS
.
get
(
'organization'
,
None
)
if
organization
:
enrolled_qs
=
enrolled_qs
.
filter
(
user__organizations
=
organization
)
grades_complete_qs
=
grades_complete_qs
.
filter
(
user__organizations
=
organization
)
users_started_qs
=
users_started_qs
.
filter
(
user__organizations
=
organization
)
total_enrolled
=
enrolled_qs
.
filter
(
created__lt
=
start_dt
)
.
count
()
total_started
=
users_started_qs
.
filter
(
created__lt
=
start_dt
)
.
count
()
enrolled_series
=
get_time_series_data
(
enrolled_qs
,
start_dt
,
end_dt
,
interval
=
interval
,
date_field
=
'created'
,
aggregate
=
Count
(
'id'
))
started_series
=
get_time_series_data
(
users_started_qs
,
start_dt
,
end_dt
,
interval
=
interval
,
date_field
=
'created'
,
aggregate
=
Count
(
'id'
))
completed_series
=
get_time_series_data
(
grades_complete_qs
,
start_dt
,
end_dt
,
interval
=
interval
,
date_field
=
'modified'
,
aggregate
=
Count
(
'id'
))
not_started_series
=
[]
for
enrolled
,
started
in
zip
(
enrolled_series
,
started_series
):
not_started_series
.
append
((
started
[
0
],
(
total_enrolled
+
enrolled
[
1
])
-
(
total_started
+
started
[
1
])))
total_started
+=
started
[
1
]
total_enrolled
+=
enrolled
[
1
]
data
=
{
'users_not_started'
:
not_started_series
,
'users_started'
:
started_series
,
'users_completed'
:
completed_series
}
return
Response
(
data
,
status
=
status
.
HTTP_200_OK
)
class
CoursesTimeSeriesMetrics
(
SecureAPIView
):
"""
...
...
@@ -1626,7 +1553,10 @@ class CoursesTimeSeriesMetrics(SecureAPIView):
{
"users_not_started": [[datetime-1, count-1], [datetime-2, count-2], ........ [datetime-n, count-n]],
"users_started": [[datetime-1, count-1], [datetime-2, count-2], ........ [datetime-n, count-n]],
"users_completed": [[datetime-1, count-1], [datetime-2, count-2], ........ [datetime-n, count-n]]
"users_completed": [[datetime-1, count-1], [datetime-2, count-2], ........ [datetime-n, count-n]],
"modules_completed": [[datetime-1, count-1], [datetime-2, count-2], ........ [datetime-n, count-n]]
"users_enrolled": [[datetime-1, count-1], [datetime-2, count-2], ........ [datetime-n, count-n]]
"active_users": [[datetime-1, count-1], [datetime-2, count-2], ........ [datetime-n, count-n]]
}
- metrics can be filtered by organization by adding organization parameter to GET request
### Use Cases/Notes:
...
...
@@ -1659,18 +1589,22 @@ class CoursesTimeSeriesMetrics(SecureAPIView):
grades_complete_qs
=
grades_qs
.
filter
(
proforma_grade__lte
=
F
(
'grade'
)
+
grade_complete_match_range
,
proforma_grade__gt
=
0
)
enrolled_qs
=
CourseEnrollment
.
objects
.
filter
(
course_id__exact
=
course_key
,
user__is_active
=
True
)
\
.
exclude
(
id__in
=
exclude_users
)
.
exclude
(
user_
id__in
=
exclude_users
)
users_started_qs
=
StudentProgressHistory
.
objects
.
filter
(
course_id__exact
=
course_key
,
user__is_active
=
True
)
\
.
exclude
(
user_id__in
=
exclude_users
)
modules_completed_qs
=
CourseModuleCompletion
.
get_actual_completions
()
.
filter
(
course_id__exact
=
course_key
,
user__is_active
=
True
)
\
.
exclude
(
id__in
=
exclude_users
)
.
exclude
(
user_id__in
=
exclude_users
)
active_users_qs
=
StudentModule
.
objects
.
filter
(
course_id__exact
=
course_key
,
student__is_active
=
True
)
\
.
exclude
(
student_id__in
=
exclude_users
)
organization
=
request
.
QUERY_PARAMS
.
get
(
'organization'
,
None
)
if
organization
:
enrolled_qs
=
enrolled_qs
.
filter
(
user__organizations
=
organization
)
grades_complete_qs
=
grades_complete_qs
.
filter
(
user__organizations
=
organization
)
users_started_qs
=
users_started_qs
.
filter
(
user__organizations
=
organization
)
modules_completed_qs
=
modules_completed_qs
.
filter
(
user__organizations
=
organization
)
active_users_qs
=
active_users_qs
.
filter
(
student__organizations
=
organization
)
total_enrolled
=
enrolled_qs
.
filter
(
created__lt
=
start_dt
)
.
count
()
total_started_count
=
users_started_qs
.
filter
(
created__lt
=
start_dt
)
.
aggregate
(
Count
(
'user'
,
distinct
=
True
))
...
...
@@ -1684,18 +1618,25 @@ class CoursesTimeSeriesMetrics(SecureAPIView):
date_field
=
'modified'
,
aggregate
=
Count
(
'id'
))
modules_completed_series
=
get_time_series_data
(
modules_completed_qs
,
start_dt
,
end_dt
,
interval
=
interval
,
date_field
=
'created'
,
aggregate
=
Count
(
'id'
))
not_started_series
=
[]
# active users are those who accessed course in last 24 hours
start_dt
=
start_dt
+
relativedelta
(
hours
=-
24
)
end_dt
=
end_dt
+
relativedelta
(
hours
=-
24
)
active_users_series
=
get_time_series_data
(
active_users_qs
,
start_dt
,
end_dt
,
interval
=
interval
,
date_field
=
'modified'
,
aggregate
=
Count
(
'student'
,
distinct
=
True
))
not_started_series
,
total_enrolled_series
=
[],
[]
for
enrolled
,
started
in
zip
(
enrolled_series
,
started_series
):
not_started_series
.
append
((
started
[
0
],
(
total_enrolled
+
enrolled
[
1
])
-
(
total_started
+
started
[
1
])))
total_started
+=
started
[
1
]
total_enrolled
+=
enrolled
[
1
]
total_enrolled_series
.
append
((
started
[
0
],
total_enrolled
))
data
=
{
'users_not_started'
:
not_started_series
,
'users_started'
:
started_series
,
'users_completed'
:
completed_series
,
'modules_completed'
:
modules_completed_series
'modules_completed'
:
modules_completed_series
,
'users_enrolled'
:
total_enrolled_series
,
'active_users'
:
active_users_series
}
return
Response
(
data
,
status
=
status
.
HTTP_200_OK
)
...
...
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