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
276c6e91
Commit
276c6e91
authored
Feb 06, 2014
by
cahrens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Store locations in ReferenceLists so they can be converted to locators.
STUD-1027
parent
25c0776c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
71 additions
and
39 deletions
+71
-39
common/lib/xmodule/xmodule/conditional_module.py
+48
-29
common/lib/xmodule/xmodule/tests/test_export.py
+1
-0
common/test/data/conditional/conditional/condone.xml
+4
-3
common/test/data/conditional/course.xml
+15
-7
common/test/data/conditional/html/congrats.xml
+3
-0
No files found.
common/lib/xmodule/xmodule/conditional_module.py
View file @
276c6e91
...
...
@@ -11,7 +11,7 @@ from pkg_resources import resource_string
from
xmodule.x_module
import
XModule
from
xmodule.modulestore
import
Location
from
xmodule.seq_module
import
SequenceDescriptor
from
xblock.fields
import
Scope
,
List
from
xblock.fields
import
Scope
,
Reference
List
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
...
...
@@ -20,7 +20,8 @@ log = logging.getLogger('edx.' + __name__)
class
ConditionalFields
(
object
):
has_children
=
True
show_tag_list
=
List
(
help
=
"List of urls of children that are references to external modules"
,
scope
=
Scope
.
content
)
show_tag_list
=
ReferenceList
(
help
=
"List of urls of children that are references to external modules"
,
scope
=
Scope
.
content
)
sources_list
=
ReferenceList
(
help
=
"List of sources upon which this module is conditional"
,
scope
=
Scope
.
content
)
class
ConditionalModule
(
ConditionalFields
,
XModule
):
...
...
@@ -184,37 +185,45 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor):
has_score
=
False
@staticmethod
def
parse_sources
(
xml_element
,
system
,
return_descriptor
=
False
):
"""Parse xml_element 'sources' attr and:
if return_descriptor=True - return list of descriptors
if return_descriptor=False - return list of locations
def
__init__
(
self
,
*
args
,
**
kwargs
):
"""
Create an instance of the conditional module.
"""
super
(
ConditionalDescriptor
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
# Convert sources xml_attribute to a ReferenceList field type so Location/Locator
# substitution can be done.
if
not
self
.
sources_list
:
if
'sources'
in
self
.
xml_attributes
and
isinstance
(
self
.
xml_attributes
[
'sources'
],
basestring
):
sources
=
ConditionalDescriptor
.
parse_sources
(
self
.
xml_attributes
)
self
.
sources_list
=
sources
@staticmethod
def
parse_sources
(
xml_element
):
""" Parse xml_element 'sources' attr and return a list of location strings. """
result
=
[]
sources
=
xml_element
.
get
(
'sources'
)
if
sources
:
locations
=
[
location
.
strip
()
for
location
in
sources
.
split
(
';'
)]
for
location
in
locations
:
if
Location
.
is_valid
(
location
):
# Check valid location url.
location
=
Location
(
location
)
try
:
if
return_descriptor
:
descriptor
=
system
.
load_item
(
location
)
result
.
append
(
descriptor
)
else
:
result
.
append
(
location
)
except
ItemNotFoundError
:
msg
=
"Invalid module by location."
log
.
exception
(
msg
)
system
.
error_tracker
(
msg
)
result
.
append
(
location
)
return
result
def
get_required_module_descriptors
(
self
):
"""Returns a list of XModuleDescri
tp
or instances upon
"""Returns a list of XModuleDescri
pt
or instances upon
which this module depends.
"""
return
ConditionalDescriptor
.
parse_sources
(
self
.
xml_attributes
,
self
.
system
,
True
)
descriptors
=
[]
for
location
in
self
.
sources_list
:
try
:
descriptor
=
self
.
system
.
load_item
(
Location
(
location
))
descriptors
.
append
(
descriptor
)
except
ItemNotFoundError
:
msg
=
"Invalid module by location."
log
.
exception
(
msg
)
self
.
system
.
error_tracker
(
msg
)
return
descriptors
@classmethod
def
definition_from_xml
(
cls
,
xml_object
,
system
):
...
...
@@ -222,9 +231,10 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor):
show_tag_list
=
[]
for
child
in
xml_object
:
if
child
.
tag
==
'show'
:
locations
=
ConditionalDescriptor
.
parse_sources
(
child
,
system
)
children
.
extend
(
locations
)
show_tag_list
.
extend
(
location
.
url
()
for
location
in
locations
)
# pylint: disable=no-member
locations
=
ConditionalDescriptor
.
parse_sources
(
child
)
for
location
in
locations
:
children
.
append
(
Location
(
location
))
show_tag_list
.
append
(
location
)
else
:
try
:
descriptor
=
system
.
process_xml
(
etree
.
tostring
(
child
))
...
...
@@ -236,13 +246,22 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor):
return
{
'show_tag_list'
:
show_tag_list
},
children
def
definition_to_xml
(
self
,
resource_fs
):
def
to_string
(
string_list
):
""" Convert List of strings to a single string with "; " as the separator. """
return
"; "
.
join
(
string_list
)
xml_object
=
etree
.
Element
(
self
.
_tag_name
)
for
child
in
self
.
get_children
():
location
=
str
(
child
.
location
)
if
location
in
self
.
show_tag_list
:
show_str
=
u'<{tag_name} sources="{sources}" />'
.
format
(
tag_name
=
'show'
,
sources
=
location
)
xml_object
.
append
(
etree
.
fromstring
(
show_str
))
else
:
if
location
not
in
self
.
show_tag_list
:
self
.
runtime
.
add_block_as_child_node
(
child
,
xml_object
)
if
self
.
show_tag_list
:
show_str
=
u'<{tag_name} sources="{sources}" />'
.
format
(
tag_name
=
'show'
,
sources
=
to_string
(
self
.
show_tag_list
))
xml_object
.
append
(
etree
.
fromstring
(
show_str
))
# Overwrite the original sources attribute with the value from sources_list, as
# Locations may have been changed to Locators.
self
.
xml_attributes
[
'sources'
]
=
to_string
(
self
.
sources_list
)
return
xml_object
common/lib/xmodule/xmodule/tests/test_export.py
View file @
276c6e91
...
...
@@ -78,6 +78,7 @@ class RoundTripTestCase(unittest.TestCase):
"toy"
,
"simple"
,
"conditional_and_poll"
,
"conditional"
,
"self_assessment"
,
"graphic_slider_tool"
,
"test_exam_registration"
,
...
...
common/test/data/conditional/conditional/condone.xml
View file @
276c6e91
<conditional
condition=
"require_attempted"
required=
"problem/choiceprob"
>
<html
url_name=
"secret_page"
/>
</conditional>
<conditional
correct=
"True"
sources=
"i4x://edX/cond_test/problem/choiceprob"
>
<html>
Conditionally shown page
</html>
<show
sources=
"i4x://edX/cond_test/html/congrats; i4x://edX/cond_test/html/secret_page"
/>
</conditional>
common/test/data/conditional/course.xml
View file @
276c6e91
<course
name=
"Conditional Course"
org=
"edX"
course=
"cond_test"
graceperiod=
"1 day 5 hours 59 minutes 59 seconds"
slug=
"2012_Fall"
start=
"2015-07-17T12:00"
>
<chapter
name=
"Problems with Condition"
>
<sequential>
<problem
url_name=
"choiceprob"
/>
<conditional
url_name=
"condone"
/>
</sequential>
</chapter>
<course
name=
"Conditional Course"
org=
"edX"
course=
"cond_test"
graceperiod=
"1 day 5 hours 59 minutes 59 seconds"
slug=
"2012_Fall"
start=
"2012-07-17T12:00"
>
<chapter
name=
"Problems with Condition"
>
<!-- In order for the conditional to reference modules via "show",
they must be defined elsewhere in the course. Therefore, add them to a
non-released sequential. -->
<sequential
start=
"2080-07-17T12:00"
>
<html
url_name=
"congrats"
/>
<html
url_name=
"secret_page"
/>
</sequential>
<sequential>
<problem
url_name=
"choiceprob"
/>
<conditional
url_name=
"condone"
/>
</sequential>
</chapter>
</course>
common/test/data/conditional/html/congrats.xml
0 → 100644
View file @
276c6e91
<html
display_name=
"Congrats"
>
<p>
Congrats-- you answered the problem correctly!
</p>
</html>
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