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
ac23149f
Commit
ac23149f
authored
Oct 01, 2013
by
Ned Batchelder
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1100 from edx/ned/new-xml
New XML infrastructure for XBlocks
parents
e73bc906
0bb11335
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
130 additions
and
113 deletions
+130
-113
common/lib/xmodule/setup.py
+47
-44
common/lib/xmodule/xmodule/error_module.py
+2
-2
common/lib/xmodule/xmodule/modulestore/mongo/base.py
+3
-4
common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py
+1
-1
common/lib/xmodule/xmodule/modulestore/xml.py
+41
-8
common/lib/xmodule/xmodule/tests/test_editing_module.py
+1
-1
common/lib/xmodule/xmodule/tests/test_video.py
+1
-1
common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py
+2
-2
common/lib/xmodule/xmodule/tests/test_xml_module.py
+1
-1
common/lib/xmodule/xmodule/tests/xml/__init__.py
+6
-5
common/lib/xmodule/xmodule/video_module.py
+2
-3
common/lib/xmodule/xmodule/x_module.py
+19
-35
common/lib/xmodule/xmodule/xml_module.py
+3
-5
requirements/edx/github.txt
+1
-1
No files found.
common/lib/xmodule/setup.py
View file @
ac23149f
from
setuptools
import
setup
,
find_packages
from
setuptools
import
setup
,
find_packages
XMODULES
=
[
"abtest = xmodule.abtest_module:ABTestDescriptor"
,
"book = xmodule.backcompat_module:TranslateCustomTagDescriptor"
,
"chapter = xmodule.seq_module:SequenceDescriptor"
,
"combinedopenended = xmodule.combined_open_ended_module:CombinedOpenEndedDescriptor"
,
"conditional = xmodule.conditional_module:ConditionalDescriptor"
,
"course = xmodule.course_module:CourseDescriptor"
,
"customtag = xmodule.template_module:CustomTagDescriptor"
,
"discuss = xmodule.backcompat_module:TranslateCustomTagDescriptor"
,
"html = xmodule.html_module:HtmlDescriptor"
,
"image = xmodule.backcompat_module:TranslateCustomTagDescriptor"
,
"error = xmodule.error_module:ErrorDescriptor"
,
"peergrading = xmodule.peer_grading_module:PeerGradingDescriptor"
,
"poll_question = xmodule.poll_module:PollDescriptor"
,
"problem = xmodule.capa_module:CapaDescriptor"
,
"problemset = xmodule.seq_module:SequenceDescriptor"
,
"randomize = xmodule.randomize_module:RandomizeDescriptor"
,
"section = xmodule.backcompat_module:SemanticSectionDescriptor"
,
"sequential = xmodule.seq_module:SequenceDescriptor"
,
"slides = xmodule.backcompat_module:TranslateCustomTagDescriptor"
,
"timelimit = xmodule.timelimit_module:TimeLimitDescriptor"
,
"vertical = xmodule.vertical_module:VerticalDescriptor"
,
"video = xmodule.video_module:VideoDescriptor"
,
"videoalpha = xmodule.video_module:VideoDescriptor"
,
"videodev = xmodule.backcompat_module:TranslateCustomTagDescriptor"
,
"videosequence = xmodule.seq_module:SequenceDescriptor"
,
"discussion = xmodule.discussion_module:DiscussionDescriptor"
,
"course_info = xmodule.html_module:CourseInfoDescriptor"
,
"static_tab = xmodule.html_module:StaticTabDescriptor"
,
"custom_tag_template = xmodule.raw_module:RawDescriptor"
,
"about = xmodule.html_module:AboutDescriptor"
,
"wrapper = xmodule.wrapper_module:WrapperDescriptor"
,
"graphical_slider_tool = xmodule.gst_module:GraphicalSliderToolDescriptor"
,
"annotatable = xmodule.annotatable_module:AnnotatableDescriptor"
,
"foldit = xmodule.foldit_module:FolditDescriptor"
,
"word_cloud = xmodule.word_cloud_module:WordCloudDescriptor"
,
"hidden = xmodule.hidden_module:HiddenDescriptor"
,
"raw = xmodule.raw_module:RawDescriptor"
,
"crowdsource_hinter = xmodule.crowdsource_hinter:CrowdsourceHinterDescriptor"
,
"lti = xmodule.lti_module:LTIModuleDescriptor"
,
]
setup
(
setup
(
name
=
"XModule"
,
name
=
"XModule"
,
version
=
"0.1"
,
version
=
"0.1"
,
...
@@ -11,55 +53,16 @@ setup(
...
@@ -11,55 +53,16 @@ setup(
'path.py'
,
'path.py'
,
],
],
package_data
=
{
package_data
=
{
'xmodule'
:
[
'js/module/*'
]
'xmodule'
:
[
'js/module/*'
]
,
},
},
# See http://guide.python-distribute.org/creation.html#entry-points
# See http://guide.python-distribute.org/creation.html#entry-points
# for a description of entry_points
# for a description of entry_points
entry_points
=
{
entry_points
=
{
'xmodule.v1'
:
[
'xblock.v1'
:
XMODULES
,
"abtest = xmodule.abtest_module:ABTestDescriptor"
,
'xmodule.v1'
:
XMODULES
,
"book = xmodule.backcompat_module:TranslateCustomTagDescriptor"
,
"chapter = xmodule.seq_module:SequenceDescriptor"
,
"combinedopenended = xmodule.combined_open_ended_module:CombinedOpenEndedDescriptor"
,
"conditional = xmodule.conditional_module:ConditionalDescriptor"
,
"course = xmodule.course_module:CourseDescriptor"
,
"customtag = xmodule.template_module:CustomTagDescriptor"
,
"discuss = xmodule.backcompat_module:TranslateCustomTagDescriptor"
,
"html = xmodule.html_module:HtmlDescriptor"
,
"image = xmodule.backcompat_module:TranslateCustomTagDescriptor"
,
"error = xmodule.error_module:ErrorDescriptor"
,
"peergrading = xmodule.peer_grading_module:PeerGradingDescriptor"
,
"poll_question = xmodule.poll_module:PollDescriptor"
,
"problem = xmodule.capa_module:CapaDescriptor"
,
"problemset = xmodule.seq_module:SequenceDescriptor"
,
"randomize = xmodule.randomize_module:RandomizeDescriptor"
,
"section = xmodule.backcompat_module:SemanticSectionDescriptor"
,
"sequential = xmodule.seq_module:SequenceDescriptor"
,
"slides = xmodule.backcompat_module:TranslateCustomTagDescriptor"
,
"timelimit = xmodule.timelimit_module:TimeLimitDescriptor"
,
"vertical = xmodule.vertical_module:VerticalDescriptor"
,
"video = xmodule.video_module:VideoDescriptor"
,
"videoalpha = xmodule.video_module:VideoDescriptor"
,
"videodev = xmodule.backcompat_module:TranslateCustomTagDescriptor"
,
"videosequence = xmodule.seq_module:SequenceDescriptor"
,
"discussion = xmodule.discussion_module:DiscussionDescriptor"
,
"course_info = xmodule.html_module:CourseInfoDescriptor"
,
"static_tab = xmodule.html_module:StaticTabDescriptor"
,
"custom_tag_template = xmodule.raw_module:RawDescriptor"
,
"about = xmodule.html_module:AboutDescriptor"
,
"wrapper = xmodule.wrapper_module:WrapperDescriptor"
,
"graphical_slider_tool = xmodule.gst_module:GraphicalSliderToolDescriptor"
,
"annotatable = xmodule.annotatable_module:AnnotatableDescriptor"
,
"foldit = xmodule.foldit_module:FolditDescriptor"
,
"word_cloud = xmodule.word_cloud_module:WordCloudDescriptor"
,
"hidden = xmodule.hidden_module:HiddenDescriptor"
,
"raw = xmodule.raw_module:RawDescriptor"
,
"crowdsource_hinter = xmodule.crowdsource_hinter:CrowdsourceHinterDescriptor"
,
"lti = xmodule.lti_module:LTIModuleDescriptor"
],
'console_scripts'
:
[
'console_scripts'
:
[
'xmodule_assets = xmodule.static_content:main'
,
'xmodule_assets = xmodule.static_content:main'
,
]
]
,
}
}
,
)
)
common/lib/xmodule/xmodule/error_module.py
View file @
ac23149f
...
@@ -105,10 +105,10 @@ class ErrorDescriptor(ErrorFields, XModuleDescriptor):
...
@@ -105,10 +105,10 @@ class ErrorDescriptor(ErrorFields, XModuleDescriptor):
})
})
return
system
.
construct_xblock_from_class
(
return
system
.
construct_xblock_from_class
(
cls
,
cls
,
field_data
,
# The error module doesn't use scoped data, and thus doesn't need
# The error module doesn't use scoped data, and thus doesn't need
# real scope keys
# real scope keys
ScopeIds
(
'error'
,
None
,
location
,
location
)
ScopeIds
(
'error'
,
None
,
location
,
location
),
field_data
,
)
)
def
get_context
(
self
):
def
get_context
(
self
):
...
...
common/lib/xmodule/xmodule/modulestore/mongo/base.py
View file @
ac23149f
...
@@ -193,7 +193,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
...
@@ -193,7 +193,7 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
field_data
=
DbModel
(
kvs
)
field_data
=
DbModel
(
kvs
)
scope_ids
=
ScopeIds
(
None
,
category
,
location
,
location
)
scope_ids
=
ScopeIds
(
None
,
category
,
location
,
location
)
module
=
self
.
construct_xblock_from_class
(
class_
,
field_data
,
scope_ids
)
module
=
self
.
construct_xblock_from_class
(
class_
,
scope_ids
,
field_data
)
if
self
.
cached_metadata
is
not
None
:
if
self
.
cached_metadata
is
not
None
:
# parent container pointers don't differentiate between draft and non-draft
# parent container pointers don't differentiate between draft and non-draft
# so when we do the lookup, we should do so with a non-draft location
# so when we do the lookup, we should do so with a non-draft location
...
@@ -621,12 +621,11 @@ class MongoModuleStore(ModuleStoreBase):
...
@@ -621,12 +621,11 @@ class MongoModuleStore(ModuleStoreBase):
dbmodel
=
self
.
_create_new_field_data
(
location
.
category
,
location
,
definition_data
,
metadata
)
dbmodel
=
self
.
_create_new_field_data
(
location
.
category
,
location
,
definition_data
,
metadata
)
xmodule
=
system
.
construct_xblock_from_class
(
xmodule
=
system
.
construct_xblock_from_class
(
xblock_class
,
xblock_class
,
dbmodel
,
# We're loading a descriptor, so student_id is meaningless
# We're loading a descriptor, so student_id is meaningless
# We also don't have separate notions of definition and usage ids yet,
# We also don't have separate notions of definition and usage ids yet,
# so we use the location for both.
# so we use the location for both.
ScopeIds
(
None
,
location
.
category
,
location
,
location
)
ScopeIds
(
None
,
location
.
category
,
location
,
location
),
dbmodel
,
)
)
# decache any pending field settings from init
# decache any pending field settings from init
xmodule
.
save
()
xmodule
.
save
()
...
...
common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py
View file @
ac23149f
...
@@ -111,8 +111,8 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
...
@@ -111,8 +111,8 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
try
:
try
:
module
=
self
.
construct_xblock_from_class
(
module
=
self
.
construct_xblock_from_class
(
class_
,
class_
,
ScopeIds
(
None
,
json_data
.
get
(
'category'
),
definition_id
,
block_locator
),
field_data
,
field_data
,
ScopeIds
(
None
,
json_data
.
get
(
'category'
),
definition_id
,
block_locator
)
)
)
except
Exception
:
except
Exception
:
log
.
warning
(
"Failed to load descriptor"
,
exc_info
=
True
)
log
.
warning
(
"Failed to load descriptor"
,
exc_info
=
True
)
...
...
common/lib/xmodule/xmodule/modulestore/xml.py
View file @
ac23149f
...
@@ -17,9 +17,10 @@ from xmodule.error_module import ErrorDescriptor
...
@@ -17,9 +17,10 @@ from xmodule.error_module import ErrorDescriptor
from
xmodule.errortracker
import
make_error_tracker
,
exc_info_to_str
from
xmodule.errortracker
import
make_error_tracker
,
exc_info_to_str
from
xmodule.course_module
import
CourseDescriptor
from
xmodule.course_module
import
CourseDescriptor
from
xmodule.mako_module
import
MakoDescriptorSystem
from
xmodule.mako_module
import
MakoDescriptorSystem
from
xmodule.x_module
import
XM
oduleDescriptor
,
XMLParsingSystem
from
xmodule.x_module
import
XM
LParsingSystem
,
XModuleDescriptor
from
xmodule.html_module
import
HtmlDescriptor
from
xmodule.html_module
import
HtmlDescriptor
from
xblock.core
import
XBlock
from
xblock.fields
import
ScopeIds
from
xblock.fields
import
ScopeIds
from
xblock.field_data
import
DictFieldData
from
xblock.field_data
import
DictFieldData
...
@@ -63,7 +64,7 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
...
@@ -63,7 +64,7 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
self
.
load_error_modules
=
load_error_modules
self
.
load_error_modules
=
load_error_modules
def
process_xml
(
xml
):
def
process_xml
(
xml
):
"""Takes an xml string, and returns a X
ModuleDescriptor
created from
"""Takes an xml string, and returns a X
Block
created from
that xml.
that xml.
"""
"""
...
@@ -163,7 +164,7 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
...
@@ -163,7 +164,7 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
make_name_unique
(
xml_data
)
make_name_unique
(
xml_data
)
descriptor
=
XModuleDescriptor
.
load
_from_xml
(
descriptor
=
create_block
_from_xml
(
etree
.
tostring
(
xml_data
,
encoding
=
'unicode'
),
self
,
self
.
org
,
etree
.
tostring
(
xml_data
,
encoding
=
'unicode'
),
self
,
self
.
org
,
self
.
course
,
xmlstore
.
default_class
)
self
.
course
,
xmlstore
.
default_class
)
except
Exception
as
err
:
except
Exception
as
err
:
...
@@ -219,6 +220,38 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
...
@@ -219,6 +220,38 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
)
)
def
create_block_from_xml
(
xml_data
,
system
,
org
=
None
,
course
=
None
,
default_class
=
None
):
"""
Create an XBlock instance from XML data.
`xml_data' is a string containing valid xml.
`system` is an XMLParsingSystem.
`org` and `course` are optional strings that will be used in the generated
block's url identifiers.
`default_class` is the class to instantiate of the XML indicates a class
that can't be loaded.
Returns the fully instantiated XBlock.
"""
node
=
etree
.
fromstring
(
xml_data
)
raw_class
=
XModuleDescriptor
.
load_class
(
node
.
tag
,
default_class
)
xblock_class
=
system
.
mixologist
.
mix
(
raw_class
)
# leave next line commented out - useful for low-level debugging
# log.debug('[create_block_from_xml] tag=%s, class=%s' % (node.tag, xblock_class))
url_name
=
node
.
get
(
'url_name'
,
node
.
get
(
'slug'
))
location
=
Location
(
'i4x'
,
org
,
course
,
node
.
tag
,
url_name
)
scope_ids
=
ScopeIds
(
None
,
location
.
category
,
location
,
location
)
xblock
=
xblock_class
.
parse_xml
(
node
,
system
,
scope_ids
)
return
xblock
class
ParentTracker
(
object
):
class
ParentTracker
(
object
):
"""A simple class to factor out the logic for tracking location parent pointers."""
"""A simple class to factor out the logic for tracking location parent pointers."""
def
__init__
(
self
):
def
__init__
(
self
):
...
@@ -278,8 +311,8 @@ class XMLModuleStore(ModuleStoreBase):
...
@@ -278,8 +311,8 @@ class XMLModuleStore(ModuleStoreBase):
super
(
XMLModuleStore
,
self
)
.
__init__
(
**
kwargs
)
super
(
XMLModuleStore
,
self
)
.
__init__
(
**
kwargs
)
self
.
data_dir
=
path
(
data_dir
)
self
.
data_dir
=
path
(
data_dir
)
self
.
modules
=
defaultdict
(
dict
)
# course_id -> dict(location -> X
ModuleDescriptor
)
self
.
modules
=
defaultdict
(
dict
)
# course_id -> dict(location -> X
Block
)
self
.
courses
=
{}
# course_dir -> X
ModuleDescriptor
for the course
self
.
courses
=
{}
# course_dir -> X
Block
for the course
self
.
errored_courses
=
{}
# course_dir -> errorlog, for dirs that failed to load
self
.
errored_courses
=
{}
# course_dir -> errorlog, for dirs that failed to load
self
.
load_error_modules
=
load_error_modules
self
.
load_error_modules
=
load_error_modules
...
@@ -477,11 +510,11 @@ class XMLModuleStore(ModuleStoreBase):
...
@@ -477,11 +510,11 @@ class XMLModuleStore(ModuleStoreBase):
loc
=
Location
(
'i4x'
,
course_descriptor
.
location
.
org
,
course_descriptor
.
location
.
course
,
category
,
slug
)
loc
=
Location
(
'i4x'
,
course_descriptor
.
location
.
org
,
course_descriptor
.
location
.
course
,
category
,
slug
)
module
=
system
.
construct_xblock_from_class
(
module
=
system
.
construct_xblock_from_class
(
HtmlDescriptor
,
HtmlDescriptor
,
DictFieldData
({
'data'
:
html
,
'location'
:
loc
,
'category'
:
category
}),
# We're loading a descriptor, so student_id is meaningless
# We're loading a descriptor, so student_id is meaningless
# We also don't have separate notions of definition and usage ids yet,
# We also don't have separate notions of definition and usage ids yet,
# so we use the location for both
# so we use the location for both
ScopeIds
(
None
,
category
,
loc
,
loc
),
ScopeIds
(
None
,
category
,
loc
,
loc
),
DictFieldData
({
'data'
:
html
,
'location'
:
loc
,
'category'
:
category
}),
)
)
# VS[compat]:
# VS[compat]:
# Hack because we need to pull in the 'display_name' for static tabs (because we need to edit them)
# Hack because we need to pull in the 'display_name' for static tabs (because we need to edit them)
...
@@ -500,7 +533,7 @@ class XMLModuleStore(ModuleStoreBase):
...
@@ -500,7 +533,7 @@ class XMLModuleStore(ModuleStoreBase):
def
get_instance
(
self
,
course_id
,
location
,
depth
=
0
):
def
get_instance
(
self
,
course_id
,
location
,
depth
=
0
):
"""
"""
Returns an X
ModuleDescriptor
instance for the item at
Returns an X
Block
instance for the item at
location, with the policy for course_id. (In case two xml
location, with the policy for course_id. (In case two xml
dirs have different content at the same location, return the
dirs have different content at the same location, return the
one for this course_id.)
one for this course_id.)
...
@@ -528,7 +561,7 @@ class XMLModuleStore(ModuleStoreBase):
...
@@ -528,7 +561,7 @@ class XMLModuleStore(ModuleStoreBase):
def
get_item
(
self
,
location
,
depth
=
0
):
def
get_item
(
self
,
location
,
depth
=
0
):
"""
"""
Returns an X
ModuleDescriptor
instance for the item at location.
Returns an X
Block
instance for the item at location.
If any segment of the location is None except revision, raises
If any segment of the location is None except revision, raises
xmodule.modulestore.exceptions.InsufficientSpecificationError
xmodule.modulestore.exceptions.InsufficientSpecificationError
...
...
common/lib/xmodule/xmodule/tests/test_editing_module.py
View file @
ac23149f
...
@@ -46,8 +46,8 @@ class TabsEditingDescriptorTestCase(unittest.TestCase):
...
@@ -46,8 +46,8 @@ class TabsEditingDescriptorTestCase(unittest.TestCase):
TabsEditingDescriptor
.
tabs
=
self
.
tabs
TabsEditingDescriptor
.
tabs
=
self
.
tabs
self
.
descriptor
=
system
.
construct_xblock_from_class
(
self
.
descriptor
=
system
.
construct_xblock_from_class
(
TabsEditingDescriptor
,
TabsEditingDescriptor
,
field_data
=
DictFieldData
({}),
scope_ids
=
ScopeIds
(
None
,
None
,
None
,
None
),
scope_ids
=
ScopeIds
(
None
,
None
,
None
,
None
),
field_data
=
DictFieldData
({}),
)
)
def
test_get_css
(
self
):
def
test_get_css
(
self
):
...
...
common/lib/xmodule/xmodule/tests/test_video.py
View file @
ac23149f
...
@@ -133,8 +133,8 @@ class VideoDescriptorTest(unittest.TestCase):
...
@@ -133,8 +133,8 @@ class VideoDescriptorTest(unittest.TestCase):
system
=
get_test_descriptor_system
()
system
=
get_test_descriptor_system
()
self
.
descriptor
=
system
.
construct_xblock_from_class
(
self
.
descriptor
=
system
.
construct_xblock_from_class
(
VideoDescriptor
,
VideoDescriptor
,
field_data
=
DictFieldData
({}),
scope_ids
=
ScopeIds
(
None
,
None
,
None
,
None
),
scope_ids
=
ScopeIds
(
None
,
None
,
None
,
None
),
field_data
=
DictFieldData
({}),
)
)
def
test_get_context
(
self
):
def
test_get_context
(
self
):
...
...
common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py
View file @
ac23149f
...
@@ -87,8 +87,8 @@ class TestXBlockWrapper(object):
...
@@ -87,8 +87,8 @@ class TestXBlockWrapper(object):
runtime
.
render_template
=
lambda
*
args
,
**
kwargs
:
u'{!r}, {!r}'
.
format
(
args
,
kwargs
)
runtime
.
render_template
=
lambda
*
args
,
**
kwargs
:
u'{!r}, {!r}'
.
format
(
args
,
kwargs
)
return
runtime
.
construct_xblock_from_class
(
return
runtime
.
construct_xblock_from_class
(
descriptor_cls
,
descriptor_cls
,
ScopeIds
(
None
,
descriptor_cls
.
__name__
,
location
,
location
),
DictFieldData
({}),
DictFieldData
({}),
ScopeIds
(
None
,
descriptor_cls
.
__name__
,
location
,
location
)
)
)
def
leaf_module
(
self
,
descriptor_cls
):
def
leaf_module
(
self
,
descriptor_cls
):
...
@@ -109,10 +109,10 @@ class TestXBlockWrapper(object):
...
@@ -109,10 +109,10 @@ class TestXBlockWrapper(object):
runtime
.
render_template
=
lambda
*
args
,
**
kwargs
:
u'{!r}, {!r}'
.
format
(
args
,
kwargs
)
runtime
.
render_template
=
lambda
*
args
,
**
kwargs
:
u'{!r}, {!r}'
.
format
(
args
,
kwargs
)
return
runtime
.
construct_xblock_from_class
(
return
runtime
.
construct_xblock_from_class
(
descriptor_cls
,
descriptor_cls
,
ScopeIds
(
None
,
descriptor_cls
.
__name__
,
location
,
location
),
DictFieldData
({
DictFieldData
({
'children'
:
range
(
3
)
'children'
:
range
(
3
)
}),
}),
ScopeIds
(
None
,
descriptor_cls
.
__name__
,
location
,
location
)
)
)
def
container_module
(
self
,
descriptor_cls
,
depth
):
def
container_module
(
self
,
descriptor_cls
,
depth
):
...
...
common/lib/xmodule/xmodule/tests/test_xml_module.py
View file @
ac23149f
...
@@ -166,8 +166,8 @@ class EditableMetadataFieldsTest(unittest.TestCase):
...
@@ -166,8 +166,8 @@ class EditableMetadataFieldsTest(unittest.TestCase):
runtime
=
get_test_descriptor_system
()
runtime
=
get_test_descriptor_system
()
return
runtime
.
construct_xblock_from_class
(
return
runtime
.
construct_xblock_from_class
(
XmlDescriptor
,
XmlDescriptor
,
scope_ids
=
Mock
(),
field_data
=
field_data
,
field_data
=
field_data
,
scope_ids
=
Mock
()
)
.
editable_metadata_fields
)
.
editable_metadata_fields
def
get_descriptor
(
self
,
field_data
):
def
get_descriptor
(
self
,
field_data
):
...
...
common/lib/xmodule/xmodule/tests/xml/__init__.py
View file @
ac23149f
...
@@ -4,8 +4,9 @@ Xml parsing tests for XModules
...
@@ -4,8 +4,9 @@ Xml parsing tests for XModules
import
pprint
import
pprint
from
mock
import
Mock
from
mock
import
Mock
from
xmodule.x_module
import
XMLParsingSystem
,
XModuleDescriptor
from
xmodule.x_module
import
XMLParsingSystem
from
xmodule.mako_module
import
MakoDescriptorSystem
from
xmodule.mako_module
import
MakoDescriptorSystem
from
xmodule.modulestore.xml
import
create_block_from_xml
class
InMemorySystem
(
XMLParsingSystem
,
MakoDescriptorSystem
):
# pylint: disable=abstract-method
class
InMemorySystem
(
XMLParsingSystem
,
MakoDescriptorSystem
):
# pylint: disable=abstract-method
...
@@ -28,8 +29,8 @@ class InMemorySystem(XMLParsingSystem, MakoDescriptorSystem): # pylint: disable
...
@@ -28,8 +29,8 @@ class InMemorySystem(XMLParsingSystem, MakoDescriptorSystem): # pylint: disable
)
)
def
process_xml
(
self
,
xml
):
# pylint: disable=method-hidden
def
process_xml
(
self
,
xml
):
# pylint: disable=method-hidden
"""Parse `xml` as an X
ModuleDescriptor
, and add it to `self._descriptors`"""
"""Parse `xml` as an X
Block
, and add it to `self._descriptors`"""
descriptor
=
XModuleDescriptor
.
load
_from_xml
(
xml
,
self
,
self
.
org
,
self
.
course
,
self
.
default_class
)
descriptor
=
create_block
_from_xml
(
xml
,
self
,
self
.
org
,
self
.
course
,
self
.
default_class
)
self
.
_descriptors
[
descriptor
.
location
.
url
()]
=
descriptor
self
.
_descriptors
[
descriptor
.
location
.
url
()]
=
descriptor
return
descriptor
return
descriptor
...
@@ -39,8 +40,8 @@ class InMemorySystem(XMLParsingSystem, MakoDescriptorSystem): # pylint: disable
...
@@ -39,8 +40,8 @@ class InMemorySystem(XMLParsingSystem, MakoDescriptorSystem): # pylint: disable
class
XModuleXmlImportTest
(
object
):
class
XModuleXmlImportTest
(
object
):
"""Base class for tests that use basic
`XModuleDescriptor.load_from_xml` xml
parsing"""
"""Base class for tests that use basic
XML
parsing"""
def
process_xml
(
self
,
xml_import_data
):
def
process_xml
(
self
,
xml_import_data
):
"""Use the `xml_import_data` to import an :class:`X
ModuleDescriptor` from xml
"""
"""Use the `xml_import_data` to import an :class:`X
Block` from XML.
"""
system
=
InMemorySystem
(
xml_import_data
)
system
=
InMemorySystem
(
xml_import_data
)
return
system
.
process_xml
(
xml_import_data
.
xml_string
)
return
system
.
process_xml
(
xml_import_data
.
xml_string
)
common/lib/xmodule/xmodule/video_module.py
View file @
ac23149f
...
@@ -247,12 +247,11 @@ class VideoDescriptor(VideoFields, TabsEditingDescriptor, EmptyDataRawDescriptor
...
@@ -247,12 +247,11 @@ class VideoDescriptor(VideoFields, TabsEditingDescriptor, EmptyDataRawDescriptor
field_data
=
DbModel
(
kvs
)
field_data
=
DbModel
(
kvs
)
video
=
system
.
construct_xblock_from_class
(
video
=
system
.
construct_xblock_from_class
(
cls
,
cls
,
field_data
,
# We're loading a descriptor, so student_id is meaningless
# We're loading a descriptor, so student_id is meaningless
# We also don't have separate notions of definition and usage ids yet,
# We also don't have separate notions of definition and usage ids yet,
# so we use the location for both
# so we use the location for both
ScopeIds
(
None
,
location
.
category
,
location
,
location
)
ScopeIds
(
None
,
location
.
category
,
location
,
location
),
field_data
,
)
)
return
video
return
video
...
...
common/lib/xmodule/xmodule/x_module.py
View file @
ac23149f
...
@@ -502,8 +502,8 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
...
@@ -502,8 +502,8 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
module
=
system
.
construct_xblock_from_class
(
module
=
system
.
construct_xblock_from_class
(
self
.
module_class
,
self
.
module_class
,
descriptor
=
self
,
descriptor
=
self
,
field_data
=
system
.
xmodule_field_data
(
self
),
scope_ids
=
self
.
scope_ids
,
scope_ids
=
self
.
scope_ids
,
field_data
=
system
.
xmodule_field_data
(
self
),
)
)
module
.
save
()
module
.
save
()
return
module
return
module
...
@@ -524,38 +524,21 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
...
@@ -524,38 +524,21 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
return
cls
.
metadata_translations
.
get
(
key
,
key
)
return
cls
.
metadata_translations
.
get
(
key
,
key
)
# ================================= XML PARSING ============================
# ================================= XML PARSING ============================
@staticmethod
@classmethod
def
load_from_xml
(
xml_data
,
def
parse_xml
(
cls
,
node
,
runtime
,
keys
):
system
,
org
=
None
,
course
=
None
,
default_class
=
None
):
"""
"""
This method instantiates the correct subclass of XModuleDescriptor based
Interpret the parsed XML in `node`, creating an XModuleDescriptor.
on the contents of xml_data.
xml_data must be a string containing valid xml
system is an XMLParsingSystem
org and course are optional strings that will be used in the generated
module's url identifiers
"""
"""
class_
=
system
.
mixologist
.
mix
(
XModuleDescriptor
.
load_class
(
xml
=
etree
.
tostring
(
node
)
etree
.
fromstring
(
xml_data
)
.
tag
,
# TODO: change from_xml to not take org and course, it can use self.system.
default_class
block
=
cls
.
from_xml
(
xml
,
runtime
,
runtime
.
org
,
runtime
.
course
)
))
return
block
# leave next line, commented out - useful for low-level debugging
# log.debug('[XModuleDescriptor.load_from_xml] tag=%s, class_=%s' % (
# etree.fromstring(xml_data).tag,class_))
return
class_
.
from_xml
(
xml_data
,
system
,
org
,
course
)
@classmethod
@classmethod
def
from_xml
(
cls
,
xml_data
,
system
,
org
=
None
,
course
=
None
):
def
from_xml
(
cls
,
xml_data
,
system
,
org
=
None
,
course
=
None
):
"""
"""
Creates an instance of this descriptor from the supplied xml_data.
Creates an instance of this descriptor from the supplied xml_data.
This may be overridden by subclasses
This may be overridden by subclasses
.
xml_data: A string of xml that will be translated into data and children
xml_data: A string of xml that will be translated into data and children
for this module
for this module
...
@@ -565,13 +548,12 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
...
@@ -565,13 +548,12 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
org and course are optional strings that will be used in the generated
org and course are optional strings that will be used in the generated
module's url identifiers
module's url identifiers
"""
"""
raise
NotImplementedError
(
raise
NotImplementedError
(
'Modules must implement from_xml to be parsable from xml'
)
'Modules must implement from_xml to be parsable from xml'
)
def
export_to_xml
(
self
,
resource_fs
):
def
export_to_xml
(
self
,
resource_fs
):
"""
"""
Returns an xml string representing this module, and all modules
Returns an xml string representing this module, and all modules
underneath it. May also write required resources out to resource_fs
underneath it. May also write required resources out to resource_fs
.
Assumes that modules have single parentage (that no module appears twice
Assumes that modules have single parentage (that no module appears twice
in the same course), and that it is thus safe to nest modules as xml
in the same course), and that it is thus safe to nest modules as xml
...
@@ -581,8 +563,7 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
...
@@ -581,8 +563,7 @@ class XModuleDescriptor(XModuleMixin, HTMLSnippet, ResourceTemplates, XBlock):
XModuleDescriptor using the from_xml method with the same system, org,
XModuleDescriptor using the from_xml method with the same system, org,
and course
and course
"""
"""
raise
NotImplementedError
(
raise
NotImplementedError
(
'Modules must implement export_to_xml to enable xml export'
)
'Modules must implement export_to_xml to enable xml export'
)
# =============================== BUILTIN METHODS ==========================
# =============================== BUILTIN METHODS ==========================
def
__eq__
(
self
,
other
):
def
__eq__
(
self
,
other
):
...
@@ -715,7 +696,9 @@ class DescriptorSystem(Runtime):
...
@@ -715,7 +696,9 @@ class DescriptorSystem(Runtime):
that you're about to re-raise---let the caller track them.
that you're about to re-raise---let the caller track them.
"""
"""
super
(
DescriptorSystem
,
self
)
.
__init__
(
**
kwargs
)
# Right now, usage_store is unused, and field_data is always supplanted
# with an explicit field_data during construct_xblock, so None's suffice.
super
(
DescriptorSystem
,
self
)
.
__init__
(
usage_store
=
None
,
field_data
=
None
,
**
kwargs
)
self
.
load_item
=
load_item
self
.
load_item
=
load_item
self
.
resources_fs
=
resources_fs
self
.
resources_fs
=
resources_fs
...
@@ -756,8 +739,6 @@ class DescriptorSystem(Runtime):
...
@@ -756,8 +739,6 @@ class DescriptorSystem(Runtime):
class
XMLParsingSystem
(
DescriptorSystem
):
class
XMLParsingSystem
(
DescriptorSystem
):
def
__init__
(
self
,
process_xml
,
policy
,
**
kwargs
):
def
__init__
(
self
,
process_xml
,
policy
,
**
kwargs
):
"""
"""
load_item, resources_fs, error_tracker: see DescriptorSystem
policy: a policy dictionary for overriding xml metadata
policy: a policy dictionary for overriding xml metadata
process_xml: Takes an xml string, and returns a XModuleDescriptor
process_xml: Takes an xml string, and returns a XModuleDescriptor
...
@@ -839,7 +820,10 @@ class ModuleSystem(Runtime):
...
@@ -839,7 +820,10 @@ class ModuleSystem(Runtime):
not to allow the execution of unsafe, unsandboxed code.
not to allow the execution of unsafe, unsandboxed code.
"""
"""
super
(
ModuleSystem
,
self
)
.
__init__
(
**
kwargs
)
# Right now, usage_store is unused, and field_data is always supplanted
# with an explicit field_data during construct_xblock, so None's suffice.
super
(
ModuleSystem
,
self
)
.
__init__
(
usage_store
=
None
,
field_data
=
None
,
**
kwargs
)
self
.
ajax_url
=
ajax_url
self
.
ajax_url
=
ajax_url
self
.
xqueue
=
xqueue
self
.
xqueue
=
xqueue
...
...
common/lib/xmodule/xmodule/xml_module.py
View file @
ac23149f
...
@@ -217,8 +217,7 @@ class XmlDescriptor(XModuleDescriptor):
...
@@ -217,8 +217,7 @@ class XmlDescriptor(XModuleDescriptor):
# give the class a chance to fix it up. The file will be written out
# give the class a chance to fix it up. The file will be written out
# again in the correct format. This should go away once the CMS is
# again in the correct format. This should go away once the CMS is
# online and has imported all current (fall 2012) courses from xml
# online and has imported all current (fall 2012) courses from xml
if
not
system
.
resources_fs
.
exists
(
filepath
)
and
hasattr
(
if
not
system
.
resources_fs
.
exists
(
filepath
)
and
hasattr
(
cls
,
'backcompat_paths'
):
cls
,
'backcompat_paths'
):
candidates
=
cls
.
backcompat_paths
(
filepath
)
candidates
=
cls
.
backcompat_paths
(
filepath
)
for
candidate
in
candidates
:
for
candidate
in
candidates
:
if
system
.
resources_fs
.
exists
(
candidate
):
if
system
.
resources_fs
.
exists
(
candidate
):
...
@@ -339,12 +338,11 @@ class XmlDescriptor(XModuleDescriptor):
...
@@ -339,12 +338,11 @@ class XmlDescriptor(XModuleDescriptor):
return
system
.
construct_xblock_from_class
(
return
system
.
construct_xblock_from_class
(
cls
,
cls
,
field_data
,
# We're loading a descriptor, so student_id is meaningless
# We're loading a descriptor, so student_id is meaningless
# We also don't have separate notions of definition and usage ids yet,
# We also don't have separate notions of definition and usage ids yet,
# so we use the location for both
# so we use the location for both
ScopeIds
(
None
,
location
.
category
,
location
,
location
)
ScopeIds
(
None
,
location
.
category
,
location
,
location
),
field_data
,
)
)
@classmethod
@classmethod
...
...
requirements/edx/github.txt
View file @
ac23149f
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
-e git+https://github.com/eventbrite/zendesk.git@d53fe0e81b623f084e91776bcf6369f8b7b63879#egg=zendesk
-e git+https://github.com/eventbrite/zendesk.git@d53fe0e81b623f084e91776bcf6369f8b7b63879#egg=zendesk
# Our libraries:
# Our libraries:
-e git+https://github.com/edx/XBlock.git@
a8de02c0
#egg=XBlock
-e git+https://github.com/edx/XBlock.git@
8a66ca3
#egg=XBlock
-e git+https://github.com/edx/codejail.git@0a1b468#egg=codejail
-e git+https://github.com/edx/codejail.git@0a1b468#egg=codejail
-e git+https://github.com/edx/diff-cover.git@v0.2.4#egg=diff_cover
-e git+https://github.com/edx/diff-cover.git@v0.2.4#egg=diff_cover
-e git+https://github.com/edx/js-test-tool.git@v0.0.7#egg=js_test_tool
-e git+https://github.com/edx/js-test-tool.git@v0.0.7#egg=js_test_tool
...
...
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