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
9fdbdd3b
Commit
9fdbdd3b
authored
May 30, 2012
by
Calen Pennington
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #71 from MITx/pmitros/modular-refactor
Pmitros/modular refactor
parents
b3f02811
2c2072da
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
99 additions
and
35 deletions
+99
-35
djangoapps/courseware/capa/responsetypes.py
+8
-11
djangoapps/courseware/content_parser.py
+1
-0
djangoapps/courseware/modules/seq_module.py
+6
-3
djangoapps/courseware/modules/vertical_module.py
+1
-1
djangoapps/courseware/modules/x_module.py
+65
-13
djangoapps/courseware/views.py
+17
-6
templates/seq_module.js
+1
-1
No files found.
djangoapps/courseware/capa/responsetypes.py
View file @
9fdbdd3b
...
@@ -66,10 +66,8 @@ class GenericResponse(object):
...
@@ -66,10 +66,8 @@ class GenericResponse(object):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
class
MultipleChoiceResponse
(
GenericResponse
):
class
MultipleChoiceResponse
(
GenericResponse
):
'''
# TODO: handle direction and randomize
Example:
snippets
=
[{
'snippet'
:
'''<multiplechoiceresponse direction="vertical" randomize="yes">
<multiplechoiceresponse direction="vertical" randomize="yes">
<choicegroup type="MultipleChoice">
<choicegroup type="MultipleChoice">
<choice location="random" correct="false"><span>`a+b`<br/></span></choice>
<choice location="random" correct="false"><span>`a+b`<br/></span></choice>
<choice location="random" correct="true"><span><math>a+b^2</math><br/></span></choice>
<choice location="random" correct="true"><span><math>a+b^2</math><br/></span></choice>
...
@@ -77,10 +75,7 @@ class MultipleChoiceResponse(GenericResponse):
...
@@ -77,10 +75,7 @@ class MultipleChoiceResponse(GenericResponse):
<choice location="bottom" correct="false"><math>a+b+d</math></choice>
<choice location="bottom" correct="false"><math>a+b+d</math></choice>
</choicegroup>
</choicegroup>
</multiplechoiceresponse>
</multiplechoiceresponse>
'''
}]
TODO: handle direction and randomize
'''
def
__init__
(
self
,
xml
,
context
,
system
=
None
):
def
__init__
(
self
,
xml
,
context
,
system
=
None
):
self
.
xml
=
xml
self
.
xml
=
xml
self
.
correct_choices
=
xml
.
xpath
(
'//*[@id=$id]//choice[@correct="true"]'
,
self
.
correct_choices
=
xml
.
xpath
(
'//*[@id=$id]//choice[@correct="true"]'
,
...
@@ -218,8 +213,9 @@ class NumericalResponse(GenericResponse):
...
@@ -218,8 +213,9 @@ class NumericalResponse(GenericResponse):
class
CustomResponse
(
GenericResponse
):
class
CustomResponse
(
GenericResponse
):
'''
'''
Custom response. The python code to be run should be in <answer>...</answer>. Example:
Custom response. The python code to be run should be in <answer>...</answer>. Example:
'''
<customresponse>
snippets
=
[{
'snippet'
:
'''
<customresponse>
<startouttext/>
<startouttext/>
<br/>
<br/>
Suppose that
\
(I(t)
\
) rises from
\
(0
\
) to
\
(I_S
\
) at a time
\
(t_0
\n
eq 0
\
)
Suppose that
\
(I(t)
\
) rises from
\
(0
\
) to
\
(I_S
\
) at a time
\
(t_0
\n
eq 0
\
)
...
@@ -237,9 +233,10 @@ class CustomResponse(GenericResponse):
...
@@ -237,9 +233,10 @@ class CustomResponse(GenericResponse):
if not(r=="IS*u(t-t0)"):
if not(r=="IS*u(t-t0)"):
correct[0] ='incorrect'
correct[0] ='incorrect'
</answer>
</answer>
</customresponse>
</customresponse>
'''
}]
Alternatively, the check function can be defined in <script>...</script> Example:
'''Footnote: the check function can also be defined in <script>...</script> Example:
<script type="loncapa/python"><![CDATA[
<script type="loncapa/python"><![CDATA[
...
...
djangoapps/courseware/content_parser.py
View file @
9fdbdd3b
...
@@ -218,6 +218,7 @@ def section_file(user, section, coursename=None, dironly=False):
...
@@ -218,6 +218,7 @@ def section_file(user, section, coursename=None, dironly=False):
Given a user and the name of a section, return that section.
Given a user and the name of a section, return that section.
This is done specific to each course.
This is done specific to each course.
If dironly=True then return the sections directory.
If dironly=True then return the sections directory.
TODO: This is a bit weird; dironly should be scrapped.
'''
'''
filename
=
section
+
".xml"
filename
=
section
+
".xml"
...
...
djangoapps/courseware/modules/seq_module.py
View file @
9fdbdd3b
...
@@ -20,7 +20,9 @@ class Module(XModule):
...
@@ -20,7 +20,9 @@ class Module(XModule):
@classmethod
@classmethod
def
get_xml_tags
(
c
):
def
get_xml_tags
(
c
):
return
[
"sequential"
,
'tab'
]
obsolete_tags
=
[
"sequential"
,
'tab'
]
modern_tags
=
[
"videosequence"
]
return
obsolete_tags
+
modern_tags
def
get_html
(
self
):
def
get_html
(
self
):
self
.
render
()
self
.
render
()
...
@@ -81,7 +83,8 @@ class Module(XModule):
...
@@ -81,7 +83,8 @@ class Module(XModule):
params
=
{
'items'
:
self
.
contents
,
params
=
{
'items'
:
self
.
contents
,
'id'
:
self
.
item_id
,
'id'
:
self
.
item_id
,
'position'
:
self
.
position
,
'position'
:
self
.
position
,
'titles'
:
self
.
titles
}
'titles'
:
self
.
titles
,
'tag'
:
self
.
xmltree
.
tag
}
# TODO/BUG: Destroy JavaScript should only be called for the active view
# TODO/BUG: Destroy JavaScript should only be called for the active view
# This calls it for all the views
# This calls it for all the views
...
@@ -90,7 +93,7 @@ class Module(XModule):
...
@@ -90,7 +93,7 @@ class Module(XModule):
# IDs to sequences.
# IDs to sequences.
destroy_js
=
""
.
join
([
e
[
'destroy_js'
]
for
e
in
self
.
contents
if
'destroy_js'
in
e
])
destroy_js
=
""
.
join
([
e
[
'destroy_js'
]
for
e
in
self
.
contents
if
'destroy_js'
in
e
])
if
self
.
xmltree
.
tag
==
'sequential'
:
if
self
.
xmltree
.
tag
in
[
'sequential'
,
'videosequence'
]
:
self
.
init_js
=
js
+
render_to_string
(
'seq_module.js'
,
params
)
self
.
init_js
=
js
+
render_to_string
(
'seq_module.js'
,
params
)
self
.
destroy_js
=
destroy_js
self
.
destroy_js
=
destroy_js
self
.
content
=
render_to_string
(
'seq_module.html'
,
params
)
self
.
content
=
render_to_string
(
'seq_module.html'
,
params
)
...
...
djangoapps/courseware/modules/vertical_module.py
View file @
9fdbdd3b
...
@@ -13,7 +13,7 @@ class Module(XModule):
...
@@ -13,7 +13,7 @@ class Module(XModule):
@classmethod
@classmethod
def
get_xml_tags
(
c
):
def
get_xml_tags
(
c
):
return
[
"vertical"
]
return
[
"vertical"
,
"problemset"
]
def
get_html
(
self
):
def
get_html
(
self
):
return
render_to_string
(
'vert_module.html'
,{
'items'
:
self
.
contents
})
return
render_to_string
(
'vert_module.html'
,{
'items'
:
self
.
contents
})
...
...
djangoapps/courseware/modules/x_module.py
View file @
9fdbdd3b
...
@@ -17,6 +17,39 @@ class XModule(object):
...
@@ -17,6 +17,39 @@ class XModule(object):
''' Tags in the courseware file guaranteed to correspond to the module '''
''' Tags in the courseware file guaranteed to correspond to the module '''
return
[]
return
[]
@classmethod
def
get_usage_tags
(
c
):
''' We should convert to a real module system
For now, this tells us whether we use this as an xmodule, a CAPA response type
or a CAPA input type '''
return
[
'xmodule'
]
def
__init__
(
self
,
system
=
None
,
xml
=
None
,
item_id
=
None
,
json
=
None
,
track_url
=
None
,
state
=
None
):
''' In most cases, you must pass state or xml'''
if
not
item_id
:
raise
ValueError
(
"Missing Index"
)
if
not
xml
and
not
json
:
raise
ValueError
(
"xml or json required"
)
if
not
system
:
raise
ValueError
(
"System context required"
)
self
.
xml
=
xml
self
.
json
=
json
self
.
item_id
=
item_id
self
.
state
=
state
if
system
:
## These are temporary; we really should go
## through self.system.
self
.
ajax_url
=
system
.
ajax_url
self
.
tracker
=
system
.
track_function
self
.
filestore
=
system
.
filestore
self
.
render_function
=
system
.
render_function
self
.
system
=
system
### Functions used in the LMS
def
get_completion
(
self
):
def
get_completion
(
self
):
''' This is mostly unimplemented.
''' This is mostly unimplemented.
It gives a progress indication -- e.g. 30 minutes of 1.5 hours watched. 3 of 5 problems done, etc. '''
It gives a progress indication -- e.g. 30 minutes of 1.5 hours watched. 3 of 5 problems done, etc. '''
...
@@ -45,6 +78,12 @@ class XModule(object):
...
@@ -45,6 +78,12 @@ class XModule(object):
'''
'''
return
"Unimplemented"
return
"Unimplemented"
# TODO:
# def get_header_js(self):
# ''' Filename of common js that needs to be included in the header
# '''
# raise NotImplementedError
def
get_init_js
(
self
):
def
get_init_js
(
self
):
''' JavaScript code to be run when problem is shown. Be aware
''' JavaScript code to be run when problem is shown. Be aware
that this may happen several times on the same page
that this may happen several times on the same page
...
@@ -63,17 +102,30 @@ class XModule(object):
...
@@ -63,17 +102,30 @@ class XModule(object):
get is a dictionary-like object '''
get is a dictionary-like object '''
return
""
return
""
def
__init__
(
self
,
system
,
xml
,
item_id
,
track_url
=
None
,
state
=
None
):
### Functions used in the CMS
''' In most cases, you must pass state or xml'''
def
get_xml
(
self
):
self
.
xml
=
xml
''' For conversions between JSON and legacy XML representations.
self
.
item_id
=
item_id
'''
self
.
state
=
state
if
self
.
xml
:
return
self
.
xml
else
:
raise
NotImplementedError
if
system
:
def
get_json
(
self
):
## These are temporary; we really should go
''' For conversions between JSON and legacy XML representations.
## through self.system.
'''
self
.
ajax_url
=
system
.
ajax_url
if
self
.
json
:
self
.
tracker
=
system
.
track_function
raise
NotImplementedError
self
.
filestore
=
system
.
filestore
return
self
.
json
# TODO: Return context as well -- files, etc.
self
.
render_function
=
system
.
render_function
else
:
self
.
system
=
system
raise
NotImplementedError
def
handle_cms_json
(
self
):
raise
NotImplementedError
def
render
(
self
,
size
):
''' Size: [thumbnail, small, full]
Small ==> what we drag around
Full ==> what we edit
'''
raise
NotImplementedError
djangoapps/courseware/views.py
View file @
9fdbdd3b
...
@@ -60,7 +60,6 @@ def profile(request, student_id = None):
...
@@ -60,7 +60,6 @@ def profile(request, student_id = None):
if
student_id
==
None
:
if
student_id
==
None
:
student
=
request
.
user
student
=
request
.
user
else
:
else
:
print
content_parser
.
user_groups
(
request
.
user
)
if
'course_admin'
not
in
content_parser
.
user_groups
(
request
.
user
):
if
'course_admin'
not
in
content_parser
.
user_groups
(
request
.
user
):
raise
Http404
raise
Http404
student
=
User
.
objects
.
get
(
id
=
int
(
student_id
))
student
=
User
.
objects
.
get
(
id
=
int
(
student_id
))
...
@@ -184,16 +183,28 @@ def index(request, course=None, chapter="Using the System", section="Hints"):
...
@@ -184,16 +183,28 @@ def index(request, course=None, chapter="Using the System", section="Hints"):
log
.
exception
(
"Unable to parse courseware xml"
)
log
.
exception
(
"Unable to parse courseware xml"
)
return
render_to_response
(
'courseware-error.html'
,
{})
return
render_to_response
(
'courseware-error.html'
,
{})
dom_module
=
dom
.
xpath
(
"//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]/*[1]"
,
#dom_module = dom.xpath("//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]/*[1]",
dom_module
=
dom
.
xpath
(
"//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]"
,
course
=
course
,
chapter
=
chapter
,
section
=
section
)
course
=
course
,
chapter
=
chapter
,
section
=
section
)
#print "DM", dom_module
if
len
(
dom_module
)
==
0
:
if
len
(
dom_module
)
==
0
:
module_wrapper
=
None
else
:
module_wrapper
=
dom_module
[
0
]
if
module_wrapper
==
None
:
module
=
None
module
=
None
elif
module_wrapper
.
get
(
"src"
):
module
=
content_parser
.
section_file
(
user
=
user
,
section
=
module_wrapper
.
get
(
"src"
),
coursename
=
course
)
else
:
else
:
module
=
dom_module
[
0
]
module
=
etree
.
XML
(
etree
.
tostring
(
module_wrapper
[
0
]))
# Copy the element out of the tree
module_ids
=
dom
.
xpath
(
"//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]//@id"
,
module_ids
=
[]
course
=
course
,
chapter
=
chapter
,
section
=
section
)
if
module
:
module_ids
=
module
.
xpath
(
"//@id"
,
course
=
course
,
chapter
=
chapter
,
section
=
section
)
if
user
.
is_authenticated
():
if
user
.
is_authenticated
():
module_object_preload
=
list
(
StudentModule
.
objects
.
filter
(
student
=
user
,
module_object_preload
=
list
(
StudentModule
.
objects
.
filter
(
student
=
user
,
...
@@ -305,7 +316,7 @@ def quickedit(request, id=None):
...
@@ -305,7 +316,7 @@ def quickedit(request, id=None):
Maybe this should be moved into capa/views.py
Maybe this should be moved into capa/views.py
Or this should take a "module" argument, and the quickedit moved into capa_module.
Or this should take a "module" argument, and the quickedit moved into capa_module.
'''
'''
print
"WARNING: UNDEPLOYABLE CODE. FOR DEV USE ONLY."
print
"WARNING: UNDEPLOYABLE CODE. FOR
CONTENT
DEV USE ONLY."
print
"In deployed use, this will only edit on one server"
print
"In deployed use, this will only edit on one server"
print
"We need a setting to disable for production where there is"
print
"We need a setting to disable for production where there is"
print
"a load balanacer"
print
"a load balanacer"
...
...
templates/seq_module.js
View file @
9fdbdd3b
...
@@ -53,7 +53,7 @@ function disablePrev() {
...
@@ -53,7 +53,7 @@ function disablePrev() {
function
$
{
id
}
goto
(
i
)
{
function
$
{
id
}
goto
(
i
)
{
log_event
(
"seq_goto"
,
{
'old'
:
$
{
id
}
loc
,
'new'
:
i
,
'id'
:
'${id}'
});
log_event
(
"seq_goto"
,
{
'old'
:
$
{
id
}
loc
,
'new'
:
i
,
'id'
:
'${id}'
});
postJSON
(
'${ MITX_ROOT_URL }/modx/
sequential
/${ id }/goto_position'
,
postJSON
(
'${ MITX_ROOT_URL }/modx/
${tag}
/${ id }/goto_position'
,
{
'position'
:
i
});
{
'position'
:
i
});
if
(
$
{
id
}
loc
!=-
1
)
if
(
$
{
id
}
loc
!=-
1
)
...
...
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