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
e7de06e3
Commit
e7de06e3
authored
Jul 04, 2013
by
ichuang
Committed by
Justin Riley
Jun 09, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new proctor module xblock
parent
91779d24
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
160 additions
and
0 deletions
+160
-0
common/lib/xmodule/setup.py
+1
-0
common/lib/xmodule/xmodule/proctor_module.py
+159
-0
No files found.
common/lib/xmodule/setup.py
View file @
e7de06e3
...
@@ -16,6 +16,7 @@ XMODULES = [
...
@@ -16,6 +16,7 @@ XMODULES = [
"poll_question = xmodule.poll_module:PollDescriptor"
,
"poll_question = xmodule.poll_module:PollDescriptor"
,
"problem = xmodule.capa_module:CapaDescriptor"
,
"problem = xmodule.capa_module:CapaDescriptor"
,
"problemset = xmodule.seq_module:SequenceDescriptor"
,
"problemset = xmodule.seq_module:SequenceDescriptor"
,
"proctor = xmodule.proctor_module:ProctorDescriptor"
,
"randomize = xmodule.randomize_module:RandomizeDescriptor"
,
"randomize = xmodule.randomize_module:RandomizeDescriptor"
,
"split_test = xmodule.split_test_module:SplitTestDescriptor"
,
"split_test = xmodule.split_test_module:SplitTestDescriptor"
,
"section = xmodule.backcompat_module:SemanticSectionDescriptor"
,
"section = xmodule.backcompat_module:SemanticSectionDescriptor"
,
...
...
common/lib/xmodule/xmodule/proctor_module.py
0 → 100644
View file @
e7de06e3
import
json
import
logging
import
random
import
requests
from
lxml
import
etree
from
pkg_resources
import
resource_string
from
django.conf
import
settings
from
xmodule.x_module
import
XModule
from
xmodule.seq_module
import
SequenceDescriptor
from
xblock.core
import
Integer
,
Scope
,
String
log
=
logging
.
getLogger
(
'mitx.'
+
__name__
)
class
ProctorPanel
(
object
):
'''
Interface to proctor panel system, which determines if a given proctored item
(specified by its procset_name) is released to a given student (specified by the
user_id).
'''
ProctorPanelServer
=
getattr
(
settings
,
'PROCTOR_PANEL_SERVER_URL'
,
'https://proctor.mitx.mit.edu'
)
def
__init__
(
self
,
user_id
,
procset_name
):
self
.
user_id
=
user_id
self
.
procset_name
=
procset_name
self
.
ses
=
requests
.
session
()
def
is_released
(
self
):
url
=
'{2}/cmd/status/{0}/{1}'
.
format
(
self
.
user_id
,
self
.
procset_name
,
self
.
ProctorPanelServer
)
log
.
info
(
'ProctorPanel url={0}'
.
format
(
url
))
#ret = self.ses.post(url, data={'userid' : self.user_id, 'urlname': self.procset_name}, verify=False)
ret
=
self
.
ses
.
get
(
url
,
verify
=
False
)
try
:
retdat
=
json
.
loads
(
ret
.
content
)
except
Exception
as
err
:
log
.
error
(
'bad return from proctor panel: ret.content={0}'
.
format
(
ret
.
content
))
retdat
=
{}
log
.
info
(
'ProctorPanel retdat={0}'
.
format
(
retdat
))
enabled
=
retdat
.
get
(
'enabled'
,
False
)
return
enabled
class
ProctorFields
(
object
):
username
=
String
(
help
=
"username of student"
,
scope
=
Scope
.
user_state
)
procset_name
=
String
(
help
=
"Name of this proctored set"
,
scope
=
Scope
.
settings
)
class
ProctorModule
(
ProctorFields
,
XModule
):
"""
Releases modules for viewing depending on proctor panel.
The proctor panel is a separate application which knows the mapping between user_id's and usernames,
and whether a given problem should be released for access by that student or not.
The idea is that a course staff member is proctoring an exam provided in the edX system.
After the staff member verifies a student's identity, the staff member releases the exam
to the student, via the proctor panel. Once the student is done, or the elapsed time
runs out, exam access closes.
Example:
<proctor procset_name="proctorset1">
<sequential url_name="exam1" />
</proctor>
"""
js
=
{
'coffee'
:
[
resource_string
(
__name__
,
'js/src/javascript_loader.coffee'
),
resource_string
(
__name__
,
'js/src/conditional/display.coffee'
),
resource_string
(
__name__
,
'js/src/collapsible.coffee'
),
]}
js_module_name
=
"Conditional"
css
=
{
'scss'
:
[
resource_string
(
__name__
,
'css/capa/display.scss'
)]}
def
__init__
(
self
,
*
args
,
**
kwargs
):
XModule
.
__init__
(
self
,
*
args
,
**
kwargs
)
# check proctor panel to see if this should be released
user_id
=
self
.
system
.
seed
self
.
pp
=
ProctorPanel
(
user_id
,
self
.
procset_name
)
self
.
child_descriptor
=
self
.
descriptor
.
get_children
()[
0
]
log
.
debug
(
"children of proctor module (should be only 1):
%
s"
,
self
.
get_children
())
self
.
child
=
self
.
get_children
()[
0
]
log
.
info
(
'Proctor module child={0}'
.
format
(
self
.
child
))
log
.
info
(
'Proctor module child display_name={0}'
.
format
(
self
.
child
.
display_name
))
self
.
display_name
=
self
.
child
.
display_name
def
get_child_descriptors
(
self
):
"""
For grading--return just the child.
"""
return
[
self
.
child_descriptor
]
def
get_html
(
self
):
if
not
self
.
pp
.
is_released
():
# check for release each time we do get_html()
log
.
info
(
'is_released False'
)
return
self
.
system
.
render_template
(
'proctor_release.html'
,
{
'element_id'
:
self
.
location
.
html_id
(),
'id'
:
self
.
id
,
'name'
:
self
.
display_name
,
'pp'
:
self
.
pp
,
})
# return "<div>%s not yet released</div>" % self.display_name
log
.
info
(
'is_released True'
)
# for sequential module, just return HTML (no ajax container)
if
self
.
child
.
category
in
[
'sequential'
,
'videosequence'
]:
return
self
.
child
.
get_html
()
# return ajax container, so that we can dynamically check for is_released changing
return
self
.
system
.
render_template
(
'conditional_ajax.html'
,
{
'element_id'
:
self
.
location
.
html_id
(),
'id'
:
self
.
id
,
'ajax_url'
:
self
.
system
.
ajax_url
,
'depends'
:
''
,
})
def
handle_ajax
(
self
,
_dispatch
,
_data
):
if
not
self
.
pp
.
is_released
():
# check for release each time we do get_html()
log
.
info
(
'is_released False'
)
html
=
"<div>
%
s not yet released</div>"
%
self
.
display_name
return
json
.
dumps
({
'html'
:
[
html
],
'message'
:
bool
(
True
)})
html
=
[
child
.
get_html
()
for
child
in
self
.
get_display_items
()]
log
.
info
(
'is_released True'
)
return
json
.
dumps
({
'html'
:
html
})
def
get_icon_class
(
self
):
return
self
.
child
.
get_icon_class
()
if
self
.
child
else
'other'
class
ProctorDescriptor
(
ProctorFields
,
SequenceDescriptor
):
# the editing interface can be the same as for sequences -- just a container
module_class
=
ProctorModule
filename_extension
=
"xml"
def
definition_to_xml
(
self
,
resource_fs
):
xml_object
=
etree
.
Element
(
'proctor'
)
for
child
in
self
.
get_children
():
xml_object
.
append
(
etree
.
fromstring
(
child
.
export_to_xml
(
resource_fs
)))
return
xml_object
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