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
ae439310
Commit
ae439310
authored
Dec 25, 2015
by
lenacom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New optional parameters for course blocks API: lti_url, block_types
parent
46533015
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
52 additions
and
10 deletions
+52
-10
lms/djangoapps/course_api/blocks/api.py
+13
-0
lms/djangoapps/course_api/blocks/forms.py
+2
-0
lms/djangoapps/course_api/blocks/serializers.py
+7
-1
lms/djangoapps/course_api/blocks/tests/test_api.py
+14
-2
lms/djangoapps/course_api/blocks/tests/test_forms.py
+1
-0
lms/djangoapps/course_api/blocks/tests/test_serializers.py
+2
-3
lms/djangoapps/course_api/blocks/views.py
+12
-3
openedx/core/lib/block_structure/block_structure.py
+1
-1
No files found.
lms/djangoapps/course_api/blocks/api.py
View file @
ae439310
...
...
@@ -20,6 +20,7 @@ def get_blocks(
block_counts
=
None
,
student_view_data
=
None
,
return_type
=
'dict'
,
block_types
=
None
):
"""
Return a serialized representation of the course blocks.
...
...
@@ -61,6 +62,18 @@ def get_blocks(
# transform
blocks
=
get_course_blocks
(
user
,
usage_key
,
transformers
)
# filter blocks by types
if
block_types
and
len
(
block_types
)
==
0
:
block_types
=
None
if
block_types
:
block_keys_to_remove
=
[]
for
block_key
in
blocks
:
block_type
=
blocks
.
get_xblock_field
(
block_key
,
'category'
)
if
not
block_type
in
block_types
:
block_keys_to_remove
.
append
(
block_key
)
for
block_key
in
block_keys_to_remove
:
blocks
.
remove_block
(
block_key
,
True
)
# serialize
serializer_context
=
{
'request'
:
request
,
...
...
lms/djangoapps/course_api/blocks/forms.py
View file @
ae439310
...
...
@@ -31,6 +31,7 @@ class BlockListGetForm(Form):
student_view_data
=
MultiValueField
(
required
=
False
)
usage_key
=
CharField
(
required
=
True
)
username
=
CharField
(
required
=
False
)
block_types
=
MultiValueField
(
required
=
False
)
def
clean_depth
(
self
):
"""
...
...
@@ -88,6 +89,7 @@ class BlockListGetForm(Form):
'student_view_data'
,
'block_counts'
,
'nav_depth'
,
'block_types'
,
]
for
additional_field
in
additional_requested_fields
:
field_value
=
cleaned_data
.
get
(
additional_field
)
...
...
lms/djangoapps/course_api/blocks/serializers.py
View file @
ae439310
...
...
@@ -44,6 +44,13 @@ class BlockSerializer(serializers.Serializer): # pylint: disable=abstract-metho
),
}
if
'lti_url'
in
self
.
context
[
'requested_fields'
]:
data
[
'lti_url'
]
=
reverse
(
'lti_provider_launch'
,
kwargs
=
{
'course_id'
:
unicode
(
block_key
.
course_key
),
'usage_id'
:
unicode
(
block_key
)},
request
=
self
.
context
[
'request'
],
)
# add additional requested fields that are supported by the various transformers
for
supported_field
in
SUPPORTED_FIELDS
:
if
supported_field
.
requested_field_name
in
self
.
context
[
'requested_fields'
]:
...
...
@@ -70,7 +77,6 @@ class BlockDictSerializer(serializers.Serializer): # pylint: disable=abstract-m
Serializer that formats a BlockStructure object to a dictionary, rather
than a list, of blocks
"""
root
=
serializers
.
CharField
(
source
=
'root_block_usage_key'
)
blocks
=
serializers
.
SerializerMethodField
()
def
get_blocks
(
self
,
structure
):
...
...
lms/djangoapps/course_api/blocks/tests/test_api.py
View file @
ae439310
...
...
@@ -35,7 +35,6 @@ class TestGetBlocks(EnableTransformerRegistryMixin, SharedModuleStoreTestCase):
def
test_basic
(
self
):
blocks
=
get_blocks
(
self
.
request
,
self
.
course
.
location
,
self
.
user
)
self
.
assertEquals
(
blocks
[
'root'
],
unicode
(
self
.
course
.
location
))
# subtract for (1) the orphaned course About block and (2) the hidden Html block
self
.
assertEquals
(
len
(
blocks
[
'blocks'
]),
len
(
self
.
store
.
get_items
(
self
.
course
.
id
))
-
2
)
...
...
@@ -63,7 +62,6 @@ class TestGetBlocks(EnableTransformerRegistryMixin, SharedModuleStoreTestCase):
sequential_block
=
self
.
store
.
get_item
(
self
.
course
.
id
.
make_usage_key
(
'sequential'
,
'sequential_y1'
))
blocks
=
get_blocks
(
self
.
request
,
sequential_block
.
location
,
self
.
user
)
self
.
assertEquals
(
blocks
[
'root'
],
unicode
(
sequential_block
.
location
))
self
.
assertEquals
(
len
(
blocks
[
'blocks'
]),
5
)
for
block_type
,
block_name
,
is_inside_of_structure
in
(
...
...
@@ -77,3 +75,17 @@ class TestGetBlocks(EnableTransformerRegistryMixin, SharedModuleStoreTestCase):
self
.
assertIn
(
unicode
(
block
.
location
),
blocks
[
'blocks'
])
else
:
self
.
assertNotIn
(
unicode
(
block
.
location
),
blocks
[
'blocks'
])
def
test_filtering_by_block_types
(
self
):
sequential_block
=
self
.
store
.
get_item
(
self
.
course
.
id
.
make_usage_key
(
'sequential'
,
'sequential_y1'
))
block_types
=
[
'problem'
]
blocks
=
get_blocks
(
self
.
request
,
sequential_block
.
location
,
self
.
user
,
block_types
=
block_types
)
for
block_type
,
block_name
in
(
(
'problem'
,
'problem_y1a_1'
),
(
'problem'
,
'problem_y1a_2'
),
(
'problem'
,
'problem_y1a_3'
),
):
block
=
self
.
store
.
get_item
(
self
.
course
.
id
.
make_usage_key
(
block_type
,
block_name
))
self
.
assertIn
(
unicode
(
block
.
location
),
blocks
[
'blocks'
])
lms/djangoapps/course_api/blocks/tests/test_forms.py
View file @
ae439310
...
...
@@ -60,6 +60,7 @@ class TestBlockListGetForm(EnableTransformerRegistryMixin, FormTestMixin, Shared
'usage_key'
:
usage_key
,
'username'
:
self
.
student
.
username
,
'user'
:
self
.
student
,
'block_types'
:
set
(),
}
def
assert_raises_permission_denied
(
self
):
...
...
lms/djangoapps/course_api/blocks/tests/test_serializers.py
View file @
ae439310
...
...
@@ -70,6 +70,7 @@ class TestBlockSerializerBase(EnableTransformerRegistryMixin, SharedModuleStoreT
'block_counts'
,
'student_view_data'
,
'student_view_multi_device'
,
'lti_url'
,
])
def
assert_extended_block
(
self
,
serialized_block
):
...
...
@@ -81,6 +82,7 @@ class TestBlockSerializerBase(EnableTransformerRegistryMixin, SharedModuleStoreT
'id'
,
'type'
,
'lms_web_url'
,
'student_view_url'
,
'display_name'
,
'graded'
,
'block_counts'
,
'student_view_multi_device'
,
'lti_url'
,
},
set
(
serialized_block
.
iterkeys
()),
)
...
...
@@ -136,9 +138,6 @@ class TestBlockDictSerializer(TestBlockSerializerBase):
def
test_basic
(
self
):
serializer
=
self
.
create_serializer
()
# verify root
self
.
assertEquals
(
serializer
.
data
[
'root'
],
unicode
(
self
.
block_structure
.
root_block_usage_key
))
# verify blocks
for
block_key_string
,
serialized_block
in
serializer
.
data
[
'blocks'
]
.
iteritems
():
self
.
assertEquals
(
serialized_block
[
'id'
],
block_key_string
)
...
...
lms/djangoapps/course_api/blocks/views.py
View file @
ae439310
...
...
@@ -30,9 +30,10 @@ class BlocksView(DeveloperErrorViewMixin, ListAPIView):
GET /api/courses/v1/blocks/<usage_id>/?
username=anjali
&depth=all
&requested_fields=graded,format,student_view_multi_device
&requested_fields=graded,format,student_view_multi_device
,lti_url
&block_counts=video
&student_view_data=video
&block_types=problem,html
**Parameters**:
...
...
@@ -85,6 +86,11 @@ class BlocksView(DeveloperErrorViewMixin, ListAPIView):
Example: return_type=dict
* block_types: (list) Requested types of blocks. Possible values include sequential,
vertical, html, problem, video, and discussion.
Example: block_types=vertical,html
**Response Values**
The following fields are returned with a successful response.
...
...
@@ -147,6 +153,7 @@ class BlocksView(DeveloperErrorViewMixin, ListAPIView):
if the student_view_url and the student_view_data fields are not
supported.
* lti_url: The block URL for an LTI consumer.
"""
def
list
(
self
,
request
,
usage_key_string
):
# pylint: disable=arguments-differ
...
...
@@ -177,7 +184,8 @@ class BlocksView(DeveloperErrorViewMixin, ListAPIView):
params
.
cleaned_data
[
'requested_fields'
],
params
.
cleaned_data
.
get
(
'block_counts'
,
[]),
params
.
cleaned_data
.
get
(
'student_view_data'
,
[]),
params
.
cleaned_data
[
'return_type'
]
params
.
cleaned_data
[
'return_type'
],
params
.
cleaned_data
.
get
(
'block_types'
,
None
),
)
)
except
ItemNotFoundError
as
exception
:
...
...
@@ -198,9 +206,10 @@ class BlocksInCourseView(BlocksView):
GET /api/courses/v1/blocks/?course_id=<course_id>
&username=anjali
&depth=all
&requested_fields=graded,format,student_view_multi_device
&requested_fields=graded,format,student_view_multi_device
,lti_url
&block_counts=video
&student_view_data=video
&block_types=problem,html
**Parameters**:
...
...
openedx/core/lib/block_structure/block_structure.py
View file @
ae439310
...
...
@@ -70,7 +70,7 @@ class BlockStructure(object):
traversal since it's the more common case and we currently
need to support DAGs.
"""
return
self
.
topological_traversal
()
return
self
.
get_block_keys
()
#--- Block structure relation methods ---#
...
...
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