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
bd822b9d
Commit
bd822b9d
authored
Feb 13, 2013
by
Calen Pennington
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix tests post-merge
parent
793bbfd3
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
107 additions
and
121 deletions
+107
-121
common/djangoapps/student/views.py
+26
-30
common/lib/xmodule/xmodule/combined_open_ended_module.py
+1
-1
common/lib/xmodule/xmodule/combined_open_ended_modulev1.py
+1
-1
common/lib/xmodule/xmodule/conditional_module.py
+6
-3
common/lib/xmodule/xmodule/course_module.py
+16
-28
common/lib/xmodule/xmodule/gst_module.py
+1
-1
common/lib/xmodule/xmodule/modulestore/xml.py
+3
-0
common/lib/xmodule/xmodule/modulestore/xml_importer.py
+2
-5
common/lib/xmodule/xmodule/open_ended_module.py
+1
-2
common/lib/xmodule/xmodule/peer_grading_module.py
+11
-18
common/lib/xmodule/xmodule/self_assessment_module.py
+4
-4
common/lib/xmodule/xmodule/tests/test_course_module.py
+7
-7
lms/djangoapps/courseware/access.py
+3
-3
lms/djangoapps/courseware/courses.py
+1
-1
lms/djangoapps/courseware/module_render.py
+5
-5
lms/djangoapps/courseware/tabs.py
+5
-2
lms/djangoapps/courseware/tests/tests.py
+2
-2
lms/djangoapps/courseware/views.py
+5
-1
lms/djangoapps/open_ended_grading/controller_query_service.py
+1
-1
lms/djangoapps/open_ended_grading/tests.py
+3
-3
lms/templates/course.html
+1
-1
lms/templates/courseware/progress.html
+2
-2
No files found.
common/djangoapps/student/views.py
View file @
bd822b9d
...
...
@@ -44,9 +44,8 @@ from collections import namedtuple
from
courseware.courses
import
get_courses
,
sort_by_announcement
from
courseware.access
import
has_access
from
courseware.models
import
StudentModuleCache
from
courseware.views
import
get_module_for_descriptor
,
jump_to
from
courseware.mod
ule_render
import
get_instance_modul
e
from
courseware.mod
el_data
import
ModelDataCach
e
from
statsd
import
statsd
...
...
@@ -1071,14 +1070,14 @@ def accept_name_change(request):
@csrf_exempt
def
test_center_login
(
request
):
# errors are returned by navigating to the error_url, adding a query parameter named "code"
# errors are returned by navigating to the error_url, adding a query parameter named "code"
# which contains the error code describing the exceptional condition.
def
makeErrorURL
(
error_url
,
error_code
):
log
.
error
(
"generating error URL with error code {}"
.
format
(
error_code
))
return
"{}?code={}"
.
format
(
error_url
,
error_code
);
# get provided error URL, which will be used as a known prefix for returning error messages to the
# Pearson shell.
# Pearson shell.
error_url
=
request
.
POST
.
get
(
"errorURL"
)
# TODO: check that the parameters have not been tampered with, by comparing the code provided by Pearson
...
...
@@ -1089,12 +1088,12 @@ def test_center_login(request):
# calculate SHA for query string
# TODO: figure out how to get the original query string, so we can hash it and compare.
if
'clientCandidateID'
not
in
request
.
POST
:
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"missingClientCandidateID"
));
client_candidate_id
=
request
.
POST
.
get
(
"clientCandidateID"
)
# TODO: check remaining parameters, and maybe at least log if they're not matching
# expected values....
# registration_id = request.POST.get("registrationID")
...
...
@@ -1108,12 +1107,12 @@ def test_center_login(request):
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"invalidClientCandidateID"
));
# find testcenter_registration that matches the provided exam code:
# Note that we could rely in future on either the registrationId or the exam code,
# or possibly both. But for now we know what to do with an ExamSeriesCode,
# Note that we could rely in future on either the registrationId or the exam code,
# or possibly both. But for now we know what to do with an ExamSeriesCode,
# while we currently have no record of RegistrationID values at all.
if
'vueExamSeriesCode'
not
in
request
.
POST
:
# we are not allowed to make up a new error code, according to Pearson,
# so instead of "missingExamSeriesCode", we use a valid one that is
# we are not allowed to make up a new error code, according to Pearson,
# so instead of "missingExamSeriesCode", we use a valid one that is
# inaccurate but at least distinct. (Sigh.)
log
.
error
(
"missing exam series code for cand ID {}"
.
format
(
client_candidate_id
))
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"missingPartnerID"
));
...
...
@@ -1127,11 +1126,11 @@ def test_center_login(request):
if
not
registrations
:
log
.
error
(
"not able to find exam registration for exam {} and cand ID {}"
.
format
(
exam_series_code
,
client_candidate_id
))
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"noTestsAssigned"
));
# TODO: figure out what to do if there are more than one registrations....
# for now, just take the first...
registration
=
registrations
[
0
]
course_id
=
registration
.
course_id
course
=
course_from_id
(
course_id
)
# assume it will be found....
if
not
course
:
...
...
@@ -1149,19 +1148,19 @@ def test_center_login(request):
if
not
timelimit_descriptor
:
log
.
error
(
"cand {} on exam {} for course {}: descriptor not found for location {}"
.
format
(
client_candidate_id
,
exam_series_code
,
course_id
,
location
))
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"missingClientProgram"
));
timelimit_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
course_id
,
testcenteruser
.
user
,
timelimit_descriptor
,
depth
=
None
)
timelimit_module
=
get_module_for_descriptor
(
request
.
user
,
request
,
timelimit_descriptor
,
timelimit_module_cache
=
ModelDataCache
.
cache_for_descriptor_descendents
(
course_id
,
testcenteruser
.
user
,
timelimit_descriptor
,
depth
=
None
)
timelimit_module
=
get_module_for_descriptor
(
request
.
user
,
request
,
timelimit_descriptor
,
timelimit_module_cache
,
course_id
,
position
=
None
)
if
not
timelimit_module
.
category
==
'timelimit'
:
log
.
error
(
"cand {} on exam {} for course {}: non-timelimit module at location {}"
.
format
(
client_candidate_id
,
exam_series_code
,
course_id
,
location
))
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"missingClientProgram"
));
if
timelimit_module
and
timelimit_module
.
has_ended
:
log
.
warning
(
"cand {} on exam {} for course {}: test already over at {}"
.
format
(
client_candidate_id
,
exam_series_code
,
course_id
,
timelimit_module
.
ending_at
))
return
HttpResponseRedirect
(
makeErrorURL
(
error_url
,
"allTestsTaken"
));
# check if we need to provide an accommodation:
time_accommodation_mapping
=
{
'ET12ET'
:
'ADDHALFTIME'
,
'ET30MN'
:
'ADD30MIN'
,
...
...
@@ -1174,27 +1173,24 @@ def test_center_login(request):
# special, hard-coded client ID used by Pearson shell for testing:
if
client_candidate_id
==
"edX003671291147"
:
time_accommodation_code
=
'TESTING'
if
time_accommodation_code
:
timelimit_module
.
accommodation_code
=
time_accommodation_code
instance_module
=
get_instance_module
(
course_id
,
testcenteruser
.
user
,
timelimit_module
,
timelimit_module_cache
)
instance_module
.
state
=
timelimit_module
.
get_instance_state
()
instance_module
.
save
()
log
.
info
(
"cand {} on exam {} for course {}: receiving accommodation {}"
.
format
(
client_candidate_id
,
exam_series_code
,
course_id
,
time_accommodation_code
))
# UGLY HACK!!!
# Login assumes that authentication has occurred, and that there is a
# Login assumes that authentication has occurred, and that there is a
# backend annotation on the user object, indicating which backend
# against which the user was authenticated. We're authenticating here
# against the registration entry, and assuming that the request given
# this information is correct, we allow the user to be logged in
# without a password. This could all be formalized in a backend object
# that does the above checking.
# that does the above checking.
# TODO: (brian) create a backend class to do this.
# testcenteruser.user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
testcenteruser
.
user
.
backend
=
"
%
s.
%
s"
%
(
"TestcenterAuthenticationModule"
,
"TestcenterAuthenticationClass"
)
# testcenteruser.user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
testcenteruser
.
user
.
backend
=
"
%
s.
%
s"
%
(
"TestcenterAuthenticationModule"
,
"TestcenterAuthenticationClass"
)
login
(
request
,
testcenteruser
.
user
)
# And start the test:
return
jump_to
(
request
,
course_id
,
location
)
...
...
common/lib/xmodule/xmodule/combined_open_ended_module.py
View file @
bd822b9d
...
...
@@ -190,7 +190,7 @@ class CombinedOpenEndedDescriptor(XmlDescriptor, EditingDescriptor):
}
"""
return
{
'xml_string'
:
etree
.
tostring
(
xml_object
),
'metadata'
:
xml_object
.
attrib
}
return
{
'xml_string'
:
etree
.
tostring
(
xml_object
),
'metadata'
:
xml_object
.
attrib
}
,
[]
def
definition_to_xml
(
self
,
resource_fs
):
...
...
common/lib/xmodule/xmodule/combined_open_ended_modulev1.py
View file @
bd822b9d
...
...
@@ -696,7 +696,7 @@ class CombinedOpenEndedV1Descriptor(XmlDescriptor, EditingDescriptor):
"""Assumes that xml_object has child k"""
return
xml_object
.
xpath
(
k
)[
0
]
return
{
'task_xml'
:
parse_task
(
'task'
),
'prompt'
:
parse
(
'prompt'
),
'rubric'
:
parse
(
'rubric'
)}
return
{
'task_xml'
:
parse_task
(
'task'
),
'prompt'
:
parse
(
'prompt'
),
'rubric'
:
parse
(
'rubric'
)}
,
[]
def
definition_to_xml
(
self
,
resource_fs
):
...
...
common/lib/xmodule/xmodule/conditional_module.py
View file @
bd822b9d
...
...
@@ -4,6 +4,7 @@ import logging
from
xmodule.x_module
import
XModule
from
xmodule.modulestore
import
Location
from
xmodule.seq_module
import
SequenceDescriptor
from
xblock.core
import
String
,
Scope
from
pkg_resources
import
resource_string
...
...
@@ -34,6 +35,7 @@ class ConditionalModule(XModule):
js_module_name
=
"Conditional"
css
=
{
'scss'
:
[
resource_string
(
__name__
,
'css/capa/display.scss'
)]}
condition
=
String
(
help
=
"Condition for this module"
,
default
=
''
,
scope
=
Scope
.
settings
)
def
__init__
(
self
,
system
,
location
,
definition
,
descriptor
,
instance_state
=
None
,
shared_state
=
None
,
**
kwargs
):
"""
...
...
@@ -44,7 +46,6 @@ class ConditionalModule(XModule):
"""
XModule
.
__init__
(
self
,
system
,
location
,
definition
,
descriptor
,
instance_state
,
shared_state
,
**
kwargs
)
self
.
contents
=
None
self
.
condition
=
self
.
metadata
.
get
(
'condition'
,
''
)
self
.
_get_required_modules
()
children
=
self
.
get_display_items
()
if
children
:
...
...
@@ -128,16 +129,18 @@ class ConditionalDescriptor(SequenceDescriptor):
stores_state
=
True
has_score
=
False
required
=
String
(
help
=
"List of required xmodule locations, separated by &"
,
default
=
''
,
scope
=
Scope
.
settings
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
ConditionalDescriptor
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
required_module_list
=
[
tuple
(
x
.
split
(
'/'
,
1
))
for
x
in
self
.
metadata
.
get
(
'required'
,
''
)
.
split
(
'&'
)]
required_module_list
=
[
tuple
(
x
.
split
(
'/'
,
1
))
for
x
in
self
.
required
.
split
(
'&'
)]
self
.
required_module_locations
=
[]
for
rm
in
required_module_list
:
try
:
(
tag
,
name
)
=
rm
except
Exception
as
err
:
msg
=
"Specification of required module in conditional is broken:
%
s"
%
self
.
metadata
.
get
(
'required'
)
msg
=
"Specification of required module in conditional is broken:
%
s"
%
self
.
required
log
.
warning
(
msg
)
self
.
system
.
error_tracker
(
msg
)
continue
...
...
common/lib/xmodule/xmodule/course_module.py
View file @
bd822b9d
...
...
@@ -169,6 +169,11 @@ class CourseDescriptor(SequenceDescriptor):
computed_default
=
lambda
c
:
{
'General'
:
{
'id'
:
c
.
location
.
html_id
()}},
)
testcenter_info
=
Object
(
help
=
"Dictionary of Test Center info"
,
scope
=
Scope
.
settings
)
announcement
=
Date
(
help
=
"Date this course is announced"
,
scope
=
Scope
.
settings
)
cohort_config
=
Object
(
help
=
"Dictionary defining cohort configuration"
,
scope
=
Scope
.
settings
)
is_new
=
Boolean
(
help
=
"Whether this course should be flagged as new"
,
scope
=
Scope
.
settings
)
no_grade
=
Boolean
(
help
=
"True if this course isn't graded"
,
default
=
False
,
scope
=
Scope
.
settings
)
disable_progress_graph
=
Boolean
(
help
=
"True if this course shouldn't display the progress graph"
,
default
=
False
,
scope
=
Scope
.
settings
)
has_children
=
True
info_sidebar_name
=
String
(
scope
=
Scope
.
settings
,
default
=
'Course Handouts'
)
...
...
@@ -410,26 +415,11 @@ class CourseDescriptor(SequenceDescriptor):
return
min
(
self
.
_grading_policy
[
'GRADE_CUTOFFS'
]
.
values
())
@property
def
tabs
(
self
):
"""
Return the tabs config, as a python object, or None if not specified.
"""
return
self
.
metadata
.
get
(
'tabs'
)
@tabs.setter
def
tabs
(
self
,
value
):
self
.
metadata
[
'tabs'
]
=
value
@property
def
show_calculator
(
self
):
return
self
.
metadata
.
get
(
"show_calculator"
,
None
)
==
"Yes"
@property
def
is_cohorted
(
self
):
"""
Return whether the course is cohorted.
"""
config
=
self
.
metadata
.
get
(
"cohort_config"
)
config
=
self
.
cohort_config
if
config
is
None
:
return
False
...
...
@@ -440,7 +430,7 @@ class CourseDescriptor(SequenceDescriptor):
"""
Return list of topic ids defined in course policy.
"""
topics
=
self
.
metadata
.
get
(
"discussion_topics"
,
{})
topics
=
self
.
discussion_topics
return
[
d
[
"id"
]
for
d
in
topics
.
values
()]
...
...
@@ -451,7 +441,7 @@ class CourseDescriptor(SequenceDescriptor):
the empty set. Note that all inline discussions are automatically
cohorted based on the course's is_cohorted setting.
"""
config
=
self
.
metadata
.
get
(
"cohort_config"
)
config
=
self
.
cohort_config
if
config
is
None
:
return
set
()
...
...
@@ -460,13 +450,13 @@ class CourseDescriptor(SequenceDescriptor):
@property
def
is_new
(
self
):
def
is_new
ish
(
self
):
"""
Returns if the course has been flagged as new
in the metadata
. If
Returns if the course has been flagged as new. If
there is no flag, return a heuristic value considering the
announcement and the start dates.
"""
flag
=
self
.
metadata
.
get
(
'is_new'
,
None
)
flag
=
self
.
is_new
if
flag
is
None
:
# Use a heuristic if the course has not been flagged
announcement
,
start
,
now
=
self
.
_sorting_dates
()
...
...
@@ -512,12 +502,10 @@ class CourseDescriptor(SequenceDescriptor):
def
to_datetime
(
timestamp
):
return
datetime
(
*
timestamp
[:
6
])
def
get_date
(
field
):
timetuple
=
self
.
_try_parse_time
(
field
)
return
to_datetime
(
timetuple
)
if
timetuple
else
None
announcement
=
get_date
(
'announcement'
)
start
=
get_date
(
'advertised_start'
)
or
to_datetime
(
self
.
start
)
announcement
=
self
.
announcement
if
announcement
is
not
None
:
announcement
=
to_datetime
(
announcement
)
start
=
self
.
advertised_start
or
to_datetime
(
self
.
start
)
now
=
to_datetime
(
time
.
gmtime
())
return
announcement
,
start
,
now
...
...
@@ -719,7 +707,7 @@ class CourseDescriptor(SequenceDescriptor):
def
get_test_center_exam
(
self
,
exam_series_code
):
exams
=
[
exam
for
exam
in
self
.
test_center_exams
if
exam
.
exam_series_code
==
exam_series_code
]
return
exams
[
0
]
if
len
(
exams
)
==
1
else
None
@property
def
title
(
self
):
return
self
.
display_name
...
...
common/lib/xmodule/xmodule/gst_module.py
View file @
bd822b9d
...
...
@@ -177,7 +177,7 @@ class GraphicalSliderToolDescriptor(MakoModuleDescriptor, XmlDescriptor):
return
{
'render'
:
parse
(
'render'
),
'configuration'
:
parse
(
'configuration'
)
}
}
,
[]
def
definition_to_xml
(
self
,
resource_fs
):
'''Return an xml element representing this definition.'''
...
...
common/lib/xmodule/xmodule/modulestore/xml.py
View file @
bd822b9d
...
...
@@ -456,6 +456,9 @@ class XMLModuleStore(ModuleStoreBase):
def
_load_extra_content
(
self
,
system
,
course_descriptor
,
category
,
path
,
course_dir
):
for
filepath
in
glob
.
glob
(
path
/
'*'
):
if
not
os
.
path
.
isfile
(
filepath
):
continue
with
open
(
filepath
)
as
f
:
try
:
html
=
f
.
read
()
.
decode
(
'utf-8'
)
...
...
common/lib/xmodule/xmodule/modulestore/xml_importer.py
View file @
bd822b9d
...
...
@@ -199,16 +199,13 @@ def import_from_xml(store, data_dir, course_dirs=None,
course_items
=
[]
for
course_id
in
module_store
.
modules
.
keys
():
course_data_path
=
None
course_location
=
None
# Import course modules first, because importing some of the children requires the course to exist
for
module
in
module_store
.
modules
[
course_id
]
.
itervalues
():
if
module
.
category
==
'course'
:
import_course_from_xml
(
store
,
static_content_store
,
course_data_path
,
data_dir
/
module
.
data_dir
,
module
,
target_location_namespace
,
verbose
=
verbose
...
...
@@ -220,7 +217,7 @@ def import_from_xml(store, data_dir, course_dirs=None,
import_module_from_xml
(
store
,
static_content_store
,
course_data_path
,
data_dir
/
module
.
data_dir
,
module
,
target_location_namespace
,
verbose
=
verbose
...
...
common/lib/xmodule/xmodule/open_ended_module.py
View file @
bd822b9d
...
...
@@ -20,7 +20,6 @@ import capa.xqueue_interface as xqueue_interface
from
pkg_resources
import
resource_string
from
.capa_module
import
only_one
,
ComplexEncoder
from
.editing_module
import
EditingDescriptor
from
.html_checker
import
check_html
from
progress
import
Progress
...
...
@@ -656,7 +655,7 @@ class OpenEndedDescriptor(XmlDescriptor, EditingDescriptor):
"""Assumes that xml_object has child k"""
return
xml_object
.
xpath
(
k
)[
0
]
return
{
'oeparam'
:
parse
(
'openendedparam'
)
,
}
return
{
'oeparam'
:
parse
(
'openendedparam'
)
},
[]
def
definition_to_xml
(
self
,
resource_fs
):
...
...
common/lib/xmodule/xmodule/peer_grading_module.py
View file @
bd822b9d
...
...
@@ -32,6 +32,7 @@ from .stringify import stringify_children
from
.x_module
import
XModule
from
.xml_module
import
XmlDescriptor
from
xmodule.modulestore
import
Location
from
xblock.core
import
Scope
,
Object
,
Integer
,
Boolean
,
String
from
peer_grading_service
import
peer_grading_service
,
GradingServiceError
...
...
@@ -56,32 +57,26 @@ class PeerGradingModule(XModule):
css
=
{
'scss'
:
[
resource_string
(
__name__
,
'css/combinedopenended/display.scss'
)]}
def
__init__
(
self
,
system
,
location
,
definition
,
descriptor
,
instance_state
=
None
,
shared_state
=
None
,
**
kwargs
):
XModule
.
__init__
(
self
,
system
,
location
,
definition
,
descriptor
,
instance_state
,
shared_state
,
**
kwargs
)
student_data_for_location
=
Object
(
scope
=
Scope
.
student_state
)
max_grade
=
Integer
(
default
=
MAX_SCORE
,
scope
=
Scope
.
student_state
)
use_for_single_location
=
Boolean
(
default
=
USE_FOR_SINGLE_LOCATION
,
scope
=
Scope
.
settings
)
is_graded
=
Boolean
(
default
=
IS_GRADED
,
scope
=
Scope
.
settings
)
link_to_location
=
String
(
default
=
LINK_TO_LOCATION
,
scope
=
Scope
.
settings
)
# Load instance state
if
instance_state
is
not
None
:
instance_state
=
json
.
loads
(
instance_state
)
else
:
instance_state
=
{}
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
PeerGradingModule
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
#We need to set the location here so the child modules can use it
system
.
set
(
'location'
,
location
)
self
.
system
=
system
self
.
system
.
set
(
'location'
,
self
.
location
)
self
.
peer_gs
=
peer_grading_service
(
self
.
system
)
self
.
use_for_single_location
=
self
.
metadata
.
get
(
'use_for_single_location'
,
USE_FOR_SINGLE_LOCATION
)
if
isinstance
(
self
.
use_for_single_location
,
basestring
):
self
.
use_for_single_location
=
(
self
.
use_for_single_location
in
TRUE_DICT
)
self
.
is_graded
=
self
.
metadata
.
get
(
'is_graded'
,
IS_GRADED
)
if
isinstance
(
self
.
is_graded
,
basestring
):
self
.
is_graded
=
(
self
.
is_graded
in
TRUE_DICT
)
self
.
link_to_location
=
self
.
metadata
.
get
(
'link_to_location'
,
USE_FOR_SINGLE_LOCATION
)
if
self
.
use_for_single_location
==
True
:
if
self
.
use_for_single_location
:
#This will raise an exception if the location is invalid
link_to_location_object
=
Location
(
self
.
link_to_location
)
...
...
@@ -89,8 +84,6 @@ class PeerGradingModule(XModule):
if
not
self
.
ajax_url
.
endswith
(
"/"
):
self
.
ajax_url
=
self
.
ajax_url
+
"/"
self
.
student_data_for_location
=
instance_state
.
get
(
'student_data_for_location'
,
{})
self
.
max_grade
=
instance_state
.
get
(
'max_grade'
,
MAX_SCORE
)
if
not
isinstance
(
self
.
max_grade
,
(
int
,
long
)):
#This could result in an exception, but not wrapping in a try catch block so it moves up the stack
self
.
max_grade
=
int
(
self
.
max_grade
)
...
...
@@ -521,7 +514,7 @@ class PeerGradingDescriptor(XmlDescriptor, EditingDescriptor):
"""Assumes that xml_object has child k"""
return
xml_object
.
xpath
(
k
)[
0
]
return
{}
return
{}
,
[]
def
definition_to_xml
(
self
,
resource_fs
):
...
...
common/lib/xmodule/xmodule/self_assessment_module.py
View file @
bd822b9d
...
...
@@ -58,10 +58,10 @@ class SelfAssessmentModule(openendedchild.OpenEndedChild):
# Used for progress / grading. Currently get credit just for
# completion (doesn't matter if you self-assessed correct/incorrect).
max_score
=
Integer
(
scope
=
Scope
.
settings
,
default
=
MAX_SCORE
)
max_score
=
Integer
(
scope
=
Scope
.
settings
,
default
=
openendedchild
.
MAX_SCORE
)
max_attempts
=
Integer
(
scope
=
Scope
.
settings
,
default
=
openendedchild
.
MAX_ATTEMPTS
)
attempts
=
Integer
(
scope
=
Scope
.
student_state
,
default
=
0
)
max_attempts
=
Integer
(
scope
=
Scope
.
settings
,
default
=
MAX_ATTEMPTS
)
rubric
=
String
(
scope
=
Scope
.
content
)
prompt
=
String
(
scope
=
Scope
.
content
)
submitmessage
=
String
(
scope
=
Scope
.
content
)
...
...
@@ -318,9 +318,9 @@ class SelfAssessmentDescriptor(XmlDescriptor, EditingDescriptor):
# Used for progress / grading. Currently get credit just for
# completion (doesn't matter if you self-assessed correct/incorrect).
max_score
=
Integer
(
scope
=
Scope
.
settings
,
default
=
MAX_SCORE
)
max_score
=
Integer
(
scope
=
Scope
.
settings
,
default
=
openendedchild
.
MAX_SCORE
)
max_attempts
=
Integer
(
scope
=
Scope
.
settings
,
default
=
MAX_ATTEMPTS
)
max_attempts
=
Integer
(
scope
=
Scope
.
settings
,
default
=
openendedchild
.
MAX_ATTEMPTS
)
rubric
=
String
(
scope
=
Scope
.
content
)
prompt
=
String
(
scope
=
Scope
.
content
)
submitmessage
=
String
(
scope
=
Scope
.
content
)
...
...
common/lib/xmodule/xmodule/tests/test_course_module.py
View file @
bd822b9d
...
...
@@ -94,26 +94,26 @@ class IsNewCourseTestCase(unittest.TestCase):
@patch
(
'xmodule.course_module.time.gmtime'
)
def
test_is_new
(
self
,
gmtime_mock
):
def
test_is_new
ish
(
self
,
gmtime_mock
):
gmtime_mock
.
return_value
=
NOW
descriptor
=
self
.
get_dummy_course
(
start
=
'2012-12-02T12:00'
,
is_new
=
True
)
assert
(
descriptor
.
is_new
is
True
)
assert
(
descriptor
.
is_new
ish
is
True
)
descriptor
=
self
.
get_dummy_course
(
start
=
'2013-02-02T12:00'
,
is_new
=
False
)
assert
(
descriptor
.
is_new
is
False
)
descriptor
=
self
.
get_dummy_course
(
start
=
'2013-02-02T12:00'
,
is_new
=
True
)
assert
(
descriptor
.
is_new
is
True
)
assert
(
descriptor
.
is_new
ish
is
True
)
descriptor
=
self
.
get_dummy_course
(
start
=
'2013-01-15T12:00'
)
assert
(
descriptor
.
is_new
is
True
)
assert
(
descriptor
.
is_new
ish
is
True
)
descriptor
=
self
.
get_dummy_course
(
start
=
'2013-03-00T12:00'
)
assert
(
descriptor
.
is_new
is
True
)
assert
(
descriptor
.
is_new
ish
is
True
)
descriptor
=
self
.
get_dummy_course
(
start
=
'2012-10-15T12:00'
)
assert
(
descriptor
.
is_new
is
False
)
assert
(
descriptor
.
is_new
ish
is
False
)
descriptor
=
self
.
get_dummy_course
(
start
=
'2012-12-31T12:00'
)
assert
(
descriptor
.
is_new
is
True
)
assert
(
descriptor
.
is_new
ish
is
True
)
lms/djangoapps/courseware/access.py
View file @
bd822b9d
...
...
@@ -442,7 +442,7 @@ def _adjust_start_date_for_beta_testers(user, descriptor):
NOTE: If testing manually, make sure MITX_FEATURES['DISABLE_START_DATES'] = False
in envs/dev.py!
"""
if
descriptor
.
days_early_for_beta
is
None
:
if
descriptor
.
lms
.
days_early_for_beta
is
None
:
# bail early if no beta testing is set up
return
descriptor
.
lms
.
start
...
...
@@ -456,12 +456,12 @@ def _adjust_start_date_for_beta_testers(user, descriptor):
# (fun fact: datetime(*a_time_struct[:6]) is the beautiful syntax for
# converting time_structs into datetimes)
start_as_datetime
=
datetime
(
*
descriptor
.
lms
.
start
[:
6
])
delta
=
timedelta
(
descriptor
.
days_early_for_beta
)
delta
=
timedelta
(
descriptor
.
lms
.
days_early_for_beta
)
effective
=
start_as_datetime
-
delta
# ...and back to time_struct
return
effective
.
timetuple
()
return
descriptor
.
start
return
descriptor
.
lms
.
start
def
_has_instructor_access_to_location
(
user
,
location
,
course_context
=
None
):
...
...
lms/djangoapps/courseware/courses.py
View file @
bd822b9d
...
...
@@ -89,7 +89,7 @@ def course_image_url(course):
"""Try to look up the image url for the course. If it's not found,
log an error and return the dead link"""
if
isinstance
(
modulestore
(),
XMLModuleStore
):
return
'/static/'
+
course
.
metadata
[
'data_dir'
]
+
"/images/course_image.jpg"
return
'/static/'
+
course
.
data_dir
+
"/images/course_image.jpg"
else
:
loc
=
course
.
location
.
_replace
(
tag
=
'c4x'
,
category
=
'asset'
,
name
=
'images_course_image.jpg'
)
path
=
StaticContent
.
get_url_path_from_location
(
loc
)
...
...
lms/djangoapps/courseware/module_render.py
View file @
bd822b9d
...
...
@@ -145,7 +145,7 @@ def get_module(user, request, location, model_data_cache, course_id,
location
=
Location
(
location
)
descriptor
=
modulestore
()
.
get_instance
(
course_id
,
location
,
depth
=
depth
)
return
get_module_for_descriptor
(
user
,
request
,
descriptor
,
model_data_cache
,
course_id
,
position
=
position
,
not_found_ok
=
not_found_ok
,
position
=
position
,
wrap_xmodule_display
=
wrap_xmodule_display
,
grade_bucket_type
=
grade_bucket_type
)
except
ItemNotFoundError
:
...
...
@@ -205,14 +205,14 @@ def get_module_for_descriptor(user, request, descriptor, model_data_cache, cours
Delegate to get_module. It does an access check, so may return None
"""
return
get_module_for_descriptor
(
user
,
request
,
descriptor
,
student_module
_cache
,
course_id
,
position
)
model_data
_cache
,
course_id
,
position
)
def
xblock_model_data
(
descriptor
):
return
DbModel
(
LmsKeyValueStore
(
descriptor
.
_model_data
,
model_data_cache
),
descriptor
.
module_class
,
user
.
id
,
LmsUsage
(
location
,
location
)
LmsUsage
(
descriptor
.
location
,
descriptor
.
location
)
)
def
publish
(
event
):
...
...
@@ -260,7 +260,7 @@ def get_module_for_descriptor(user, request, descriptor, model_data_cache, cours
# by the replace_static_urls code below
replace_urls
=
partial
(
static_replace
.
replace_static_urls
,
data_directory
=
descriptor
.
metadata
.
get
(
'data_dir'
,
''
)
,
data_directory
=
descriptor
.
data_dir
,
course_namespace
=
descriptor
.
location
.
_replace
(
category
=
None
,
name
=
None
),
),
node_path
=
settings
.
NODE_PATH
,
...
...
@@ -282,7 +282,7 @@ def get_module_for_descriptor(user, request, descriptor, model_data_cache, cours
log
.
exception
(
"Error creating module from descriptor {0}"
.
format
(
descriptor
))
# make an ErrorDescriptor -- assuming that the descriptor's system is ok
if
has_access
(
user
,
location
,
'staff'
,
course_id
):
if
has_access
(
user
,
descriptor
.
location
,
'staff'
,
course_id
):
err_descriptor_class
=
ErrorDescriptor
else
:
err_descriptor_class
=
NonStaffErrorDescriptor
...
...
lms/djangoapps/courseware/tabs.py
View file @
bd822b9d
...
...
@@ -28,6 +28,7 @@ from xmodule.modulestore.django import modulestore
from
xmodule.modulestore.xml
import
XMLModuleStore
from
xmodule.x_module
import
XModule
from
student.models
import
unique_id_for_user
from
courseware.model_data
import
ModelDataCache
from
open_ended_grading
import
open_ended_notifications
...
...
@@ -321,10 +322,12 @@ def get_static_tab_by_slug(course, tab_slug):
return
None
def
get_static_tab_contents
(
request
,
c
ache
,
c
ourse
,
tab
):
def
get_static_tab_contents
(
request
,
course
,
tab
):
loc
=
Location
(
course
.
location
.
tag
,
course
.
location
.
org
,
course
.
location
.
course
,
'static_tab'
,
tab
[
'url_slug'
])
tab_module
=
get_module
(
request
.
user
,
request
,
loc
,
cache
,
course
.
id
)
model_data_cache
=
ModelDataCache
.
cache_for_descriptor_descendents
(
course
.
id
,
request
.
user
,
modulestore
()
.
get_instance
(
course
.
id
,
loc
),
depth
=
0
)
tab_module
=
get_module
(
request
.
user
,
request
,
loc
,
model_data_cache
,
course
.
id
)
logging
.
debug
(
'course_module = {0}'
.
format
(
tab_module
))
...
...
lms/djangoapps/courseware/tests/tests.py
View file @
bd822b9d
...
...
@@ -742,11 +742,11 @@ class TestViewAuth(PageLoader):
yesterday
=
time
.
time
()
-
24
*
3600
# toy course's hasn't started
self
.
toy
.
metadata
[
'start'
]
=
stringify_time
(
time
.
gmtime
(
tomorrow
)
)
self
.
toy
.
lms
.
start
=
time
.
gmtime
(
tomorrow
)
self
.
assertFalse
(
self
.
toy
.
has_started
())
# but should be accessible for beta testers
self
.
toy
.
days_early_for_beta
=
2
self
.
toy
.
lms
.
days_early_for_beta
=
2
# student user shouldn't see it
student_user
=
user
(
self
.
student
)
...
...
lms/djangoapps/courseware/views.py
View file @
bd822b9d
...
...
@@ -443,7 +443,11 @@ def static_tab(request, course_id, tab_slug):
if
tab
is
None
:
raise
Http404
contents
=
tabs
.
get_static_tab_contents
(
request
,
None
,
course
,
tab
)
contents
=
tabs
.
get_static_tab_contents
(
request
,
course
,
tab
)
if
contents
is
None
:
raise
Http404
...
...
lms/djangoapps/open_ended_grading/controller_query_service.py
View file @
bd822b9d
...
...
@@ -18,7 +18,7 @@ class ControllerQueryService(GradingService):
Interface to staff grading backend.
"""
def
__init__
(
self
,
config
):
config
[
'system'
]
=
ModuleSystem
(
None
,
None
,
None
,
render_to_string
,
None
)
config
[
'system'
]
=
ModuleSystem
(
None
,
None
,
None
,
render_to_string
,
None
,
None
)
super
(
ControllerQueryService
,
self
)
.
__init__
(
config
)
self
.
check_eta_url
=
self
.
url
+
'/get_submission_eta/'
self
.
is_unique_url
=
self
.
url
+
'/is_name_unique/'
...
...
lms/djangoapps/open_ended_grading/tests.py
View file @
bd822b9d
...
...
@@ -143,10 +143,10 @@ class TestPeerGradingService(ct.PageLoader):
location
=
"i4x://edX/toy/peergrading/init"
self
.
mock_service
=
peer_grading_service
.
MockPeerGradingService
()
self
.
system
=
ModuleSystem
(
location
,
None
,
None
,
render_to_string
,
None
)
self
.
descriptor
=
peer_grading_module
.
PeerGradingDescriptor
(
self
.
system
)
self
.
system
=
ModuleSystem
(
location
,
None
,
None
,
render_to_string
,
None
,
None
)
self
.
descriptor
=
peer_grading_module
.
PeerGradingDescriptor
(
self
.
system
,
location
,
{}
)
self
.
peer_module
=
peer_grading_module
.
PeerGradingModule
(
self
.
system
,
location
,
"<peergrading/>"
,
self
.
descriptor
)
self
.
peer_module
=
peer_grading_module
.
PeerGradingModule
(
self
.
system
,
location
,
self
.
descriptor
,
{}
)
self
.
peer_module
.
peer_gs
=
self
.
mock_service
self
.
logout
()
...
...
lms/templates/course.html
View file @
bd822b9d
...
...
@@ -5,7 +5,7 @@
%
>
<
%
page
args=
"course"
/>
<article
id=
"${course.id}"
class=
"course"
>
%if course.is_new:
%if course.is_new
ish
:
<span
class=
"status"
>
New
</span>
%endif
<a
href=
"${reverse('about_course', args=[course.id])}"
>
...
...
lms/templates/courseware/progress.html
View file @
bd822b9d
...
...
@@ -18,7 +18,7 @@
<script
type=
"text/javascript"
src=
"${static.url('js/vendor/flot/jquery.flot.stack.js')}"
></script>
<script
type=
"text/javascript"
src=
"${static.url('js/vendor/flot/jquery.flot.symbol.js')}"
></script>
<script>
$
{
progress_graph
.
body
(
grade_summary
,
course
.
grade_cutoffs
,
"grade-detail-graph"
,
not
course
.
metadata
.
get
(
"no_grade"
,
False
),
not
course
.
metadata
.
get
(
"no_grade"
,
False
)
)}
$
{
progress_graph
.
body
(
grade_summary
,
course
.
grade_cutoffs
,
"grade-detail-graph"
,
not
course
.
no_grade
,
not
course
.
no_grade
)}
</script>
</
%
block>
...
...
@@ -32,7 +32,7 @@ ${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph",
<h1>
Course Progress
</h1>
</header>
%if not course.
metadata.get('disable_progress_graph',False)
:
%if not course.
disable_progress_graph
:
<div
id=
"grade-detail-graph"
></div>
%endif
...
...
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