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
1b651dab
Commit
1b651dab
authored
Jun 11, 2014
by
Justin Riley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
code clean-up
* pep8/pyflakes fixes * removed old code
parent
00a934a3
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
58 additions
and
70 deletions
+58
-70
common/lib/xmodule/xmodule/proctor_module.py
+58
-70
No files found.
common/lib/xmodule/xmodule/proctor_module.py
View file @
1b651dab
...
@@ -13,6 +13,7 @@ from xblock.fragment import Fragment
...
@@ -13,6 +13,7 @@ from xblock.fragment import Fragment
log
=
logging
.
getLogger
(
'mitx.'
+
__name__
)
log
=
logging
.
getLogger
(
'mitx.'
+
__name__
)
class
ProctorPanel
(
object
):
class
ProctorPanel
(
object
):
'''
'''
Interface to proctor panel system, which determines if a given proctored item
Interface to proctor panel system, which determines if a given proctored item
...
@@ -26,7 +27,6 @@ class ProctorPanel(object):
...
@@ -26,7 +27,6 @@ class ProctorPanel(object):
'username' : 'lms',
'username' : 'lms',
'password' : 'abcd',
'password' : 'abcd',
}
}
'''
'''
def
__init__
(
self
,
user
,
proc_url
,
proc_user
,
proc_pass
,
procset_name
):
def
__init__
(
self
,
user
,
proc_url
,
proc_user
,
proc_pass
,
procset_name
):
self
.
proc_url
=
proc_url
self
.
proc_url
=
proc_url
...
@@ -37,55 +37,57 @@ class ProctorPanel(object):
...
@@ -37,55 +37,57 @@ class ProctorPanel(object):
self
.
user
=
user
self
.
user
=
user
def
is_released
(
self
):
def
is_released
(
self
):
#url = '{2}/cmd/status/{0}/{1}'.format(self.user.id, self.procset_name, self.proc_url)
url
=
'{1}/cmd/status/{0}'
.
format
(
self
.
user
.
id
,
self
.
proc_url
)
url
=
'{1}/cmd/status/{0}'
.
format
(
self
.
user
.
id
,
self
.
proc_url
)
log
.
info
(
'ProctorPanel url={0}'
.
format
(
url
))
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
,
auth
=
(
self
.
proc_user
,
self
.
proc_pass
)
auth
=
(
self
.
proc_user
,
self
.
proc_pass
),
ret
=
self
.
ses
.
get
(
url
,
verify
=
False
,
auth
=
auth
,
params
=
{
'problem'
:
self
.
procset_name
})
params
=
{
'problem'
:
self
.
procset_name
})
try
:
try
:
retdat
=
ret
.
json
()
retdat
=
ret
.
json
()
except
Exception
:
except
Exception
:
log
.
error
(
'bad return from proctor panel: ret.content={0}'
.
format
(
ret
.
content
))
log
.
error
(
'bad return from proctor panel: '
'ret.content={0}'
.
format
(
ret
.
content
))
retdat
=
{}
retdat
=
{}
log
.
info
(
'ProctorPanel retdat={0}'
.
format
(
retdat
))
log
.
info
(
'ProctorPanel retdat={0}'
.
format
(
retdat
))
enabled
=
retdat
.
get
(
'enabled'
,
False
)
enabled
=
retdat
.
get
(
'enabled'
,
False
)
return
enabled
return
enabled
class
ProctorFields
(
object
):
class
ProctorFields
(
object
):
#display_name = String(
# display_name = String(
# display_name="Display Name",
# display_name="Display Name",
# help="This name appears in the grades progress page",
# help="This name appears in the grades progress page",
# scope=Scope.settings,
# scope=Scope.settings,
# default="Proctored Module"
# default="Proctored Module"
#)
# )
procset_name
=
String
(
help
=
"Name of this proctored set"
,
scope
=
Scope
.
settings
)
procset_name
=
String
(
help
=
"Name of this proctored set"
,
staff_release
=
Boolean
(
help
=
"True if staff forced release independent of proctor panel"
,
scope
=
Scope
.
settings
)
default
=
False
,
scope
=
Scope
.
user_state
)
staff_release
=
Boolean
(
help
=
"True if staff forced release independent "
proctor_url
=
String
(
help
=
"URL of proctor server"
,
scope
=
Scope
.
settings
)
"of proctor panel"
,
default
=
False
,
scope
=
Scope
.
user_state
)
proctor_url
=
String
(
help
=
"proctor server URL"
,
scope
=
Scope
.
settings
)
proctor_user
=
String
(
help
=
"proctor server username"
,
scope
=
Scope
.
settings
)
proctor_user
=
String
(
help
=
"proctor server username"
,
scope
=
Scope
.
settings
)
proctor_password
=
String
(
help
=
"proctor server password"
,
scope
=
Scope
.
settings
)
proctor_password
=
String
(
help
=
"proctor server password"
,
scope
=
Scope
.
settings
)
class
ProctorModule
(
ProctorFields
,
XModule
):
class
ProctorModule
(
ProctorFields
,
XModule
):
"""
"""
Releases modules for viewing depending on proctor panel.
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,
The proctor panel is a separate application which knows the mapping between
and whether a given problem should be released for access by that student or not.
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.
The idea is that a course staff member is proctoring an exam provided in
After the staff member verifies a student's identity, the staff member releases the exam
the edX system. After the staff member verifies a student's identity, the
to the student, via the proctor panel. Once the student is done, or the elapsed time
staff member releases the exam to the student, via the proctor panel. Once
runs out, exam access closes.
the student is done, or the elapsed time runs out, exam access closes.
Example:
<proctor procset_name="Proctored Exam 1">
<sequential url_name="exam1" />
</proctor>
Example:
<proctor procset_name="Proctored Exam 1">
<sequential url_name="exam1" />
</proctor>
"""
"""
js
=
{
js
=
{
...
@@ -107,24 +109,25 @@ class ProctorModule(ProctorFields, XModule):
...
@@ -107,24 +109,25 @@ class ProctorModule(ProctorFields, XModule):
user
=
self
.
runtime
.
get_real_user
(
self
.
runtime
.
anonymous_student_id
)
user
=
self
.
runtime
.
get_real_user
(
self
.
runtime
.
anonymous_student_id
)
self
.
pp
=
ProctorPanel
(
user
,
self
.
proctor_url
,
self
.
proctor_user
,
self
.
pp
=
ProctorPanel
(
user
,
self
.
proctor_url
,
self
.
proctor_user
,
self
.
proctor_password
,
self
.
procset_name
)
self
.
proctor_password
,
self
.
procset_name
)
self
.
child_descriptor
=
self
.
descriptor
.
get_children
()[
0
]
self
.
child_descriptor
=
self
.
descriptor
.
get_children
()[
0
]
log
.
debug
(
"children of proctor module (should be only 1):
%
s"
,
self
.
get_children
())
log
.
debug
(
"proctor module children (should only be 1):
%
s"
,
self
.
get_children
())
self
.
child
=
self
.
get_children
()[
0
]
self
.
child
=
self
.
get_children
()[
0
]
log
.
info
(
'Proctor module child={0}'
.
format
(
self
.
child
))
log
.
info
(
'Proctor module child={0}'
.
format
(
self
.
child
))
log
.
info
(
'Proctor module child display_name={0}'
.
format
(
self
.
child
.
display_name
))
log
.
info
(
'Proctor module child display_name={0}'
.
format
(
self
.
child
.
display_name
))
# TODO: This attr is read-only now - need to figure out if/why this is
# TODO: This attr is read-only now - need to figure out if/why this is
# needed and find a fix if necessary (disabling doesnt appear to break
# needed and find a fix if necessary (disabling doesnt appear to break
# anything)
# anything)
#self.display_name = self.child.display_name
# self.display_name = self.child.display_name
def
is_released
(
self
):
def
is_released
(
self
):
released
=
None
if
self
.
staff_release
:
if
self
.
staff_release
:
return
True
released
=
True
return
self
.
pp
.
is_released
()
else
:
released
=
self
.
pp
.
is_released
()
log
.
info
(
"is_released:
%
s"
%
released
)
return
released
def
get_child_descriptors
(
self
):
def
get_child_descriptors
(
self
):
"""
"""
...
@@ -132,40 +135,35 @@ class ProctorModule(ProctorFields, XModule):
...
@@ -132,40 +135,35 @@ class ProctorModule(ProctorFields, XModule):
"""
"""
return
[
self
.
child_descriptor
]
return
[
self
.
child_descriptor
]
def
not_released_html
(
self
):
def
not_released_html
(
self
):
return
Fragment
(
self
.
runtime
.
render_template
(
'proctor_release.html'
,
{
return
Fragment
(
self
.
runtime
.
render_template
(
'proctor_release.html'
,
{
'element_id'
:
self
.
location
.
html_id
(),
'element_id'
:
self
.
location
.
html_id
(),
'id'
:
self
.
id
,
'id'
:
self
.
id
,
'name'
:
self
.
display_name
or
self
.
procset_name
,
'name'
:
self
.
display_name
or
self
.
procset_name
,
'pp'
:
self
.
pp
,
'pp'
:
self
.
pp
,
'location'
:
self
.
location
,
'location'
:
self
.
location
,
'ajax_url'
:
self
.
runtime
.
ajax_url
,
'ajax_url'
:
self
.
runtime
.
ajax_url
,
'is_staff'
:
self
.
runtime
.
user_is_staff
,
'is_staff'
:
self
.
runtime
.
user_is_staff
,
}))
}))
def
student_view
(
self
,
context
):
def
student_view
(
self
,
context
):
if
not
self
.
is_released
():
# check for release each time we do get_html()
if
not
self
.
is_released
():
# check each time we do get_html()
log
.
info
(
'is_released False'
)
return
self
.
not_released_html
()
return
self
.
not_released_html
()
# return "<div>%s not yet released</div>" % self.display_name
log
.
info
(
'is_released True'
)
# for sequential module, just return HTML (no ajax container)
# for sequential module, just return HTML (no ajax container)
if
self
.
child
.
category
in
[
'sequential'
,
'videosequence'
,
'problemset'
,
'randomize'
]:
categories
=
[
'sequential'
,
'videosequence'
,
'problemset'
,
'randomize'
]
if
self
.
child
.
category
in
categories
:
html
=
self
.
child
.
render
(
'student_view'
,
context
)
html
=
self
.
child
.
render
(
'student_view'
,
context
)
if
self
.
staff_release
:
if
self
.
staff_release
:
dishtml
=
self
.
runtime
.
render_template
(
'proctor_disable.html'
,
{
dishtml
=
self
.
runtime
.
render_template
(
'proctor_disable.html'
,
{
'element_id'
:
self
.
location
.
html_id
(),
'element_id'
:
self
.
location
.
html_id
(),
'is_staff'
:
self
.
runtime
.
user_is_staff
,
'is_staff'
:
self
.
runtime
.
user_is_staff
,
'ajax_url'
:
self
.
runtime
.
ajax_url
,
'ajax_url'
:
self
.
runtime
.
ajax_url
,
})
})
html
.
content
=
dishtml
+
html
.
content
html
.
content
=
dishtml
+
html
.
content
return
html
return
html
# return ajax container, so that we can dynamically check for
#
return ajax container, so that we can dynamically check for
is_released changing
# is_released changing
return
Fragment
(
self
.
runtime
.
render_template
(
'conditional_ajax.html'
,
{
return
Fragment
(
self
.
runtime
.
render_template
(
'conditional_ajax.html'
,
{
'element_id'
:
self
.
location
.
html_id
(),
'element_id'
:
self
.
location
.
html_id
(),
'id'
:
self
.
id
,
'id'
:
self
.
id
,
...
@@ -173,29 +171,20 @@ class ProctorModule(ProctorFields, XModule):
...
@@ -173,29 +171,20 @@ class ProctorModule(ProctorFields, XModule):
'depends'
:
''
,
'depends'
:
''
,
}))
}))
def
handle_ajax
(
self
,
_dispatch
,
_data
):
def
handle_ajax
(
self
,
_dispatch
,
_data
):
if
self
.
runtime
.
user_is_staff
and
_dispatch
==
'release'
:
if
self
.
runtime
.
user_is_staff
and
_dispatch
==
'release'
:
self
.
staff_release
=
True
self
.
staff_release
=
True
# return '<html><head><META HTTP-EQUIV="refresh" CONTENT="15"></head><body>Release successful</body></html>'
return
json
.
dumps
({
'html'
:
'staff_release successful'
})
return
json
.
dumps
({
'html'
:
'staff_release successful'
})
if
self
.
runtime
.
user_is_staff
and
_dispatch
==
'disable'
:
if
self
.
runtime
.
user_is_staff
and
_dispatch
==
'disable'
:
self
.
staff_release
=
False
self
.
staff_release
=
False
return
json
.
dumps
({
'html'
:
'staff_disable successful'
})
return
json
.
dumps
({
'html'
:
'staff_disable successful'
})
# return '<html><head><META HTTP-EQUIV="refresh" CONTENT="15"></head><body>Disable successful</body></html>'
if
not
self
.
is_released
():
# check for release each time we do get_html()
if
not
self
.
is_released
():
# check each time we do get_html()
log
.
info
(
'is_released False'
)
# html = "<div>%s not yet released</div>" % self.display_name
html
=
self
.
not_released_html
()
html
=
self
.
not_released_html
()
return
json
.
dumps
({
'html'
:
[
html
],
'message'
:
bool
(
True
)})
return
json
.
dumps
({
'html'
:
[
html
],
'message'
:
bool
(
True
)})
html
=
[
child
.
get_html
()
for
child
in
self
.
get_display_items
()]
html
=
[
child
.
get_html
()
for
child
in
self
.
get_display_items
()]
log
.
info
(
'is_released True'
)
return
json
.
dumps
({
'html'
:
html
})
return
json
.
dumps
({
'html'
:
html
})
def
get_icon_class
(
self
):
def
get_icon_class
(
self
):
return
self
.
child
.
get_icon_class
()
if
self
.
child
else
'other'
return
self
.
child
.
get_icon_class
()
if
self
.
child
else
'other'
...
@@ -206,7 +195,6 @@ class ProctorDescriptor(ProctorFields, SequenceDescriptor):
...
@@ -206,7 +195,6 @@ class ProctorDescriptor(ProctorFields, SequenceDescriptor):
filename_extension
=
"xml"
filename_extension
=
"xml"
def
definition_to_xml
(
self
,
resource_fs
):
def
definition_to_xml
(
self
,
resource_fs
):
xml_object
=
etree
.
Element
(
'proctor'
)
xml_object
=
etree
.
Element
(
'proctor'
)
...
...
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