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
260dc84f
Commit
260dc84f
authored
Apr 12, 2013
by
Christina Roberts
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1854 from MITx/fix/cdodge/violation-fixes
violation fixes
parents
c0b32caa
3ca2bf46
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
99 additions
and
124 deletions
+99
-124
cms/djangoapps/contentstore/course_info_model.py
+1
-2
cms/djangoapps/contentstore/module_info_model.py
+0
-1
cms/djangoapps/contentstore/utils.py
+6
-6
cms/djangoapps/contentstore/views.py
+0
-0
cms/djangoapps/models/settings/course_details.py
+0
-1
cms/djangoapps/models/settings/course_grading.py
+9
-15
cms/djangoapps/models/settings/course_metadata.py
+11
-5
cms/envs/aws.py
+1
-2
cms/envs/common.py
+1
-1
common/lib/xmodule/xmodule/abtest_module.py
+1
-1
common/lib/xmodule/xmodule/annotatable_module.py
+1
-3
common/lib/xmodule/xmodule/combined_open_ended_module.py
+5
-5
common/lib/xmodule/xmodule/conditional_module.py
+7
-10
common/lib/xmodule/xmodule/contentstore/content.py
+5
-5
common/lib/xmodule/xmodule/contentstore/django.py
+0
-1
common/lib/xmodule/xmodule/contentstore/mongo.py
+6
-6
common/lib/xmodule/xmodule/course_module.py
+1
-9
common/lib/xmodule/xmodule/discussion_module.py
+4
-6
common/lib/xmodule/xmodule/error_module.py
+2
-2
common/lib/xmodule/xmodule/exceptions.py
+2
-0
common/lib/xmodule/xmodule/fields.py
+2
-0
common/lib/xmodule/xmodule/foldit_module.py
+2
-3
common/lib/xmodule/xmodule/modulestore/django.py
+1
-2
common/lib/xmodule/xmodule/modulestore/inheritance.py
+2
-1
common/lib/xmodule/xmodule/modulestore/mongo.py
+10
-11
common/lib/xmodule/xmodule/modulestore/search.py
+2
-2
common/lib/xmodule/xmodule/modulestore/store_utilities.py
+9
-10
common/lib/xmodule/xmodule/modulestore/xml.py
+6
-13
common/lib/xmodule/xmodule/modulestore/xml_importer.py
+1
-1
common/lib/xmodule/xmodule/util/decorators.py
+1
-0
No files found.
cms/djangoapps/contentstore/course_info_model.py
View file @
260dc84f
...
...
@@ -97,8 +97,7 @@ def update_course_updates(location, update, passed_id=None):
if
(
len
(
new_html_parsed
)
==
1
):
content
=
new_html_parsed
[
0
]
.
tail
else
:
content
=
"
\n
"
.
join
([
html
.
tostring
(
ele
)
for
ele
in
new_html_parsed
[
1
:]])
content
=
"
\n
"
.
join
([
html
.
tostring
(
ele
)
for
ele
in
new_html_parsed
[
1
:]])
return
{
"id"
:
passed_id
,
"date"
:
update
[
'date'
],
...
...
cms/djangoapps/contentstore/module_info_model.py
View file @
260dc84f
from
static_replace
import
replace_static_urls
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore
import
Location
from
django.http
import
Http404
def
get_module_info
(
store
,
location
,
parent_location
=
None
,
rewrite_static_links
=
False
):
...
...
cms/djangoapps/contentstore/utils.py
View file @
260dc84f
import
logging
from
django.conf
import
settings
from
xmodule.modulestore
import
Location
from
xmodule.modulestore.django
import
modulestore
...
...
@@ -9,7 +8,7 @@ import copy
DIRECT_ONLY_CATEGORIES
=
[
'course'
,
'chapter'
,
'sequential'
,
'about'
,
'static_tab'
,
'course_info'
]
#In order to instantiate an open ended tab automatically, need to have this data
OPEN_ENDED_PANEL
=
{
"name"
:
"Open Ended Panel"
,
"type"
:
"open_ended"
}
OPEN_ENDED_PANEL
=
{
"name"
:
"Open Ended Panel"
,
"type"
:
"open_ended"
}
def
get_modulestore
(
location
):
...
...
@@ -87,11 +86,10 @@ def get_lms_link_for_item(location, preview=False, course_id=None):
if
settings
.
LMS_BASE
is
not
None
:
if
preview
:
lms_base
=
settings
.
MITX_FEATURES
.
get
(
'PREVIEW_LMS_BASE'
,
'preview.'
+
settings
.
LMS_BASE
)
lms_base
=
settings
.
MITX_FEATURES
.
get
(
'PREVIEW_LMS_BASE'
,
'preview.'
+
settings
.
LMS_BASE
)
else
:
lms_base
=
settings
.
LMS_BASE
lms_link
=
"//{lms_base}/courses/{course_id}/jump_to/{location}"
.
format
(
lms_base
=
lms_base
,
course_id
=
course_id
,
...
...
@@ -193,6 +191,7 @@ class CoursePageNames:
CourseOutline
=
"course_index"
Checklists
=
"checklists"
def
add_open_ended_panel_tab
(
course
):
"""
Used to add the open ended panel tab to a course if it does not exist.
...
...
@@ -209,6 +208,7 @@ def add_open_ended_panel_tab(course):
changed
=
True
return
changed
,
course_tabs
def
remove_open_ended_panel_tab
(
course
):
"""
Used to remove the open ended panel tab from a course if it exists.
...
...
@@ -221,6 +221,6 @@ def remove_open_ended_panel_tab(course):
#Check to see if open ended panel is defined in the course
if
OPEN_ENDED_PANEL
in
course_tabs
:
#Add panel to the tabs if it is not defined
course_tabs
=
[
ct
for
ct
in
course_tabs
if
ct
!=
OPEN_ENDED_PANEL
]
course_tabs
=
[
ct
for
ct
in
course_tabs
if
ct
!=
OPEN_ENDED_PANEL
]
changed
=
True
return
changed
,
course_tabs
cms/djangoapps/contentstore/views.py
View file @
260dc84f
This diff is collapsed.
Click to expand it.
cms/djangoapps/models/settings/course_details.py
View file @
260dc84f
...
...
@@ -174,7 +174,6 @@ class CourseDetails(object):
return
result
# TODO move to a more general util? Is there a better way to do the isinstance model check?
class
CourseSettingsEncoder
(
json
.
JSONEncoder
):
def
default
(
self
,
obj
):
...
...
cms/djangoapps/models/settings/course_grading.py
View file @
260dc84f
...
...
@@ -45,14 +45,13 @@ class CourseGradingModel(object):
# return empty model
else
:
return
{
"id"
:
index
,
return
{
"id"
:
index
,
"type"
:
""
,
"min_count"
:
0
,
"drop_count"
:
0
,
"short_label"
:
None
,
"weight"
:
0
}
}
@staticmethod
def
fetch_cutoffs
(
course_location
):
...
...
@@ -95,7 +94,6 @@ class CourseGradingModel(object):
return
CourseGradingModel
.
fetch
(
course_location
)
@staticmethod
def
update_grader_from_json
(
course_location
,
grader
):
"""
...
...
@@ -137,7 +135,6 @@ class CourseGradingModel(object):
return
cutoffs
@staticmethod
def
update_grace_period_from_json
(
course_location
,
graceperiodjson
):
"""
...
...
@@ -210,8 +207,7 @@ class CourseGradingModel(object):
location
=
Location
(
location
)
descriptor
=
get_modulestore
(
location
)
.
get_item
(
location
)
return
{
"graderType"
:
descriptor
.
lms
.
format
if
descriptor
.
lms
.
format
is
not
None
else
'Not Graded'
,
return
{
"graderType"
:
descriptor
.
lms
.
format
if
descriptor
.
lms
.
format
is
not
None
else
'Not Graded'
,
"location"
:
location
,
"id"
:
99
# just an arbitrary value to
}
...
...
@@ -231,7 +227,6 @@ class CourseGradingModel(object):
get_modulestore
(
location
)
.
update_metadata
(
location
,
descriptor
.
_model_data
.
_kvs
.
_metadata
)
@staticmethod
def
convert_set_grace_period
(
descriptor
):
# 5 hours 59 minutes 59 seconds => converted to iso format
...
...
@@ -262,13 +257,12 @@ class CourseGradingModel(object):
@staticmethod
def
parse_grader
(
json_grader
):
# manual to clear out kruft
result
=
{
"type"
:
json_grader
[
"type"
],
"min_count"
:
int
(
json_grader
.
get
(
'min_count'
,
0
)),
"drop_count"
:
int
(
json_grader
.
get
(
'drop_count'
,
0
)),
"short_label"
:
json_grader
.
get
(
'short_label'
,
None
),
"weight"
:
float
(
json_grader
.
get
(
'weight'
,
0
))
/
100.0
}
result
=
{
"type"
:
json_grader
[
"type"
],
"min_count"
:
int
(
json_grader
.
get
(
'min_count'
,
0
)),
"drop_count"
:
int
(
json_grader
.
get
(
'drop_count'
,
0
)),
"short_label"
:
json_grader
.
get
(
'short_label'
,
None
),
"weight"
:
float
(
json_grader
.
get
(
'weight'
,
0
))
/
100.0
}
return
result
...
...
cms/djangoapps/models/settings/course_metadata.py
View file @
260dc84f
...
...
@@ -6,6 +6,7 @@ from xblock.core import Scope
from
xmodule.course_module
import
CourseDescriptor
import
copy
class
CourseMetadata
(
object
):
'''
For CRUD operations on metadata fields which do not have specific editors
...
...
@@ -13,8 +14,13 @@ class CourseMetadata(object):
The objects have no predefined attrs but instead are obj encodings of the
editable metadata.
'''
FILTERED_LIST
=
XModuleDescriptor
.
system_metadata_fields
+
[
'start'
,
'end'
,
'enrollment_start'
,
'enrollment_end'
,
'tabs'
,
'graceperiod'
,
'checklists'
]
FILTERED_LIST
=
XModuleDescriptor
.
system_metadata_fields
+
[
'start'
,
'end'
,
'enrollment_start'
,
'enrollment_end'
,
'tabs'
,
'graceperiod'
,
'checklists'
]
@classmethod
def
fetch
(
cls
,
course_location
):
...
...
@@ -48,7 +54,7 @@ class CourseMetadata(object):
descriptor
=
get_modulestore
(
course_location
)
.
get_item
(
course_location
)
dirty
=
False
#Copy the filtered list to avoid permanently changing the class attribute
filtered_list
=
copy
.
copy
(
cls
.
FILTERED_LIST
)
#Don't filter on the tab attribute if filter_tabs is False
...
...
@@ -71,7 +77,7 @@ class CourseMetadata(object):
if
dirty
:
get_modulestore
(
course_location
)
.
update_metadata
(
course_location
,
own_metadata
(
descriptor
))
own_metadata
(
descriptor
))
# Could just generate and return a course obj w/o doing any db reads,
# but I put the reads in as a means to confirm it persisted correctly
...
...
@@ -92,6 +98,6 @@ class CourseMetadata(object):
delattr
(
descriptor
.
lms
,
key
)
get_modulestore
(
course_location
)
.
update_metadata
(
course_location
,
own_metadata
(
descriptor
))
own_metadata
(
descriptor
))
return
cls
.
fetch
(
course_location
)
cms/envs/aws.py
View file @
260dc84f
...
...
@@ -67,4 +67,4 @@ MODULESTORE = AUTH_TOKENS['MODULESTORE']
CONTENTSTORE
=
AUTH_TOKENS
[
'CONTENTSTORE'
]
# Datadog for events!
DATADOG_API
=
AUTH_TOKENS
.
get
(
"DATADOG_API"
)
\ No newline at end of file
DATADOG_API
=
AUTH_TOKENS
.
get
(
"DATADOG_API"
)
cms/envs/common.py
View file @
260dc84f
...
...
@@ -167,7 +167,7 @@ STATICFILES_DIRS = [
PROJECT_ROOT
/
"static"
,
# This is how you would use the textbook images locally
#
("book", ENV_ROOT / "book_images")
# ("book", ENV_ROOT / "book_images")
]
# Locale/Internationalization
...
...
common/lib/xmodule/xmodule/abtest_module.py
View file @
260dc84f
...
...
@@ -6,7 +6,7 @@ from xmodule.x_module import XModule
from
xmodule.raw_module
import
RawDescriptor
from
xmodule.xml_module
import
XmlDescriptor
from
xmodule.exceptions
import
InvalidDefinitionError
from
xblock.core
import
String
,
Scope
,
Object
,
BlockScope
from
xblock.core
import
String
,
Scope
,
Object
DEFAULT
=
"_DEFAULT_GROUP"
...
...
common/lib/xmodule/xmodule/annotatable_module.py
View file @
260dc84f
import
logging
from
lxml
import
etree
from
pkg_resources
import
resource_string
,
resource_listdir
from
pkg_resources
import
resource_string
from
xmodule.x_module
import
XModule
from
xmodule.raw_module
import
RawDescriptor
from
xmodule.contentstore.content
import
StaticContent
from
xblock.core
import
Scope
,
String
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -25,7 +24,6 @@ class AnnotatableModule(AnnotatableFields, XModule):
css
=
{
'scss'
:
[
resource_string
(
__name__
,
'css/annotatable/display.scss'
)]}
icon_class
=
'annotatable'
def
__init__
(
self
,
*
args
,
**
kwargs
):
XModule
.
__init__
(
self
,
*
args
,
**
kwargs
)
...
...
common/lib/xmodule/xmodule/combined_open_ended_module.py
View file @
260dc84f
...
...
@@ -106,10 +106,10 @@ class CombinedOpenEndedModule(CombinedOpenEndedFields, XModule):
icon_class
=
'problem'
js
=
{
'coffee'
:
[
resource_string
(
__name__
,
'js/src/combinedopenended/display.coffee'
),
resource_string
(
__name__
,
'js/src/collapsible.coffee'
),
resource_string
(
__name__
,
'js/src/javascript_loader.coffee'
),
]}
[
resource_string
(
__name__
,
'js/src/combinedopenended/display.coffee'
),
resource_string
(
__name__
,
'js/src/collapsible.coffee'
),
resource_string
(
__name__
,
'js/src/javascript_loader.coffee'
),
]}
js_module_name
=
"CombinedOpenEnded"
css
=
{
'scss'
:
[
resource_string
(
__name__
,
'css/combinedopenended/display.scss'
)]}
...
...
@@ -219,5 +219,5 @@ class CombinedOpenEndedDescriptor(CombinedOpenEndedFields, RawDescriptor):
stores_state
=
True
has_score
=
True
always_recalculate_grades
=
True
always_recalculate_grades
=
True
template_dir_name
=
"combinedopenended"
common/lib/xmodule/xmodule/conditional_module.py
View file @
260dc84f
...
...
@@ -10,7 +10,7 @@ from pkg_resources import resource_string
from
xmodule.x_module
import
XModule
from
xmodule.modulestore
import
Location
from
xmodule.seq_module
import
SequenceDescriptor
from
xblock.core
import
S
tring
,
S
cope
,
List
from
xblock.core
import
Scope
,
List
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
...
...
@@ -60,8 +60,7 @@ class ConditionalModule(ConditionalFields, XModule):
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'
)]}
...
...
@@ -82,12 +81,11 @@ class ConditionalModule(ConditionalFields, XModule):
xml_value
=
self
.
descriptor
.
xml_attributes
.
get
(
xml_attr
)
if
xml_value
:
return
xml_value
,
attr_name
raise
Exception
(
'Error in conditional module: unknown condition "
%
s"'
%
xml_attr
)
raise
Exception
(
'Error in conditional module: unknown condition "
%
s"'
%
xml_attr
)
def
is_condition_satisfied
(
self
):
self
.
required_modules
=
[
self
.
system
.
get_module
(
descriptor
)
for
descriptor
in
self
.
descriptor
.
get_required_module_descriptors
()]
descriptor
in
self
.
descriptor
.
get_required_module_descriptors
()]
xml_value
,
attr_name
=
self
.
_get_condition
()
...
...
@@ -111,7 +109,7 @@ class ConditionalModule(ConditionalFields, XModule):
def
get_html
(
self
):
# Calculate html ids of dependencies
self
.
required_html_ids
=
[
descriptor
.
location
.
html_id
()
for
descriptor
in
self
.
descriptor
.
get_required_module_descriptors
()]
descriptor
in
self
.
descriptor
.
get_required_module_descriptors
()]
return
self
.
system
.
render_template
(
'conditional_ajax.html'
,
{
'element_id'
:
self
.
location
.
html_id
(),
...
...
@@ -130,7 +128,7 @@ class ConditionalModule(ConditionalFields, XModule):
context
=
{
'module'
:
self
,
'message'
:
message
}
html
=
self
.
system
.
render_template
(
'conditional_module.html'
,
context
)
context
)
return
json
.
dumps
({
'html'
:
[
html
],
'message'
:
bool
(
message
)})
html
=
[
child
.
get_html
()
for
child
in
self
.
get_display_items
()]
...
...
@@ -145,7 +143,7 @@ class ConditionalModule(ConditionalFields, XModule):
class_priority
=
[
'video'
,
'problem'
]
child_classes
=
[
self
.
system
.
get_module
(
child_descriptor
)
.
get_icon_class
()
for
child_descriptor
in
self
.
descriptor
.
get_children
()]
for
child_descriptor
in
self
.
descriptor
.
get_children
()]
for
c
in
class_priority
:
if
c
in
child_classes
:
new_class
=
c
...
...
@@ -163,7 +161,6 @@ class ConditionalDescriptor(ConditionalFields, SequenceDescriptor):
stores_state
=
True
has_score
=
False
@staticmethod
def
parse_sources
(
xml_element
,
system
,
return_descriptor
=
False
):
"""Parse xml_element 'sources' attr and:
...
...
common/lib/xmodule/xmodule/contentstore/content.py
View file @
260dc84f
...
...
@@ -9,6 +9,7 @@ import StringIO
from
xmodule.modulestore
import
Location
from
.django
import
contentstore
# to install PIL on MacOSX: 'easy_install http://dist.repoze.org/PIL-1.1.6.tar.gz'
from
PIL
import
Image
...
...
@@ -59,8 +60,9 @@ class StaticContent(object):
@staticmethod
def
get_id_from_location
(
location
):
return
{
'tag'
:
location
.
tag
,
'org'
:
location
.
org
,
'course'
:
location
.
course
,
'category'
:
location
.
category
,
'name'
:
location
.
name
,
'revision'
:
location
.
revision
}
'category'
:
location
.
category
,
'name'
:
location
.
name
,
'revision'
:
location
.
revision
}
@staticmethod
def
get_location_from_path
(
path
):
# remove leading / character if it is there one
...
...
@@ -79,8 +81,6 @@ class StaticContent(object):
return
StaticContent
.
get_url_path_from_location
(
loc
)
class
ContentStore
(
object
):
'''
Abstraction for all ContentStore providers (e.g. MongoDB)
...
...
@@ -119,7 +119,7 @@ class ContentStore(object):
thumbnail_name
=
StaticContent
.
generate_thumbnail_name
(
content
.
location
.
name
)
thumbnail_file_location
=
StaticContent
.
compute_location
(
content
.
location
.
org
,
content
.
location
.
course
,
thumbnail_name
,
is_thumbnail
=
True
)
thumbnail_name
,
is_thumbnail
=
True
)
# if we're uploading an image, then let's generate a thumbnail so that we can
# serve it up when needed without having to rescale on the fly
...
...
common/lib/xmodule/xmodule/contentstore/django.py
View file @
260dc84f
from
__future__
import
absolute_import
from
importlib
import
import_module
from
os
import
environ
from
django.conf
import
settings
...
...
common/lib/xmodule/xmodule/contentstore/mongo.py
View file @
260dc84f
...
...
@@ -6,7 +6,6 @@ from gridfs.errors import NoFile
from
xmodule.modulestore.mongo
import
location_to_query
,
Location
from
xmodule.contentstore.content
import
XASSET_LOCATION_TAG
import
sys
import
logging
from
.content
import
StaticContent
,
ContentStore
...
...
@@ -26,7 +25,6 @@ class MongoContentStore(ContentStore):
self
.
fs
=
gridfs
.
GridFS
(
_db
)
self
.
fs_files
=
_db
[
"fs.files"
]
# the underlying collection GridFS uses
def
save
(
self
,
content
):
id
=
content
.
get_id
()
...
...
@@ -34,7 +32,8 @@ class MongoContentStore(ContentStore):
self
.
delete
(
id
)
with
self
.
fs
.
new_file
(
_id
=
id
,
filename
=
content
.
get_url_path
(),
content_type
=
content
.
content_type
,
displayname
=
content
.
name
,
thumbnail_location
=
content
.
thumbnail_location
,
import_path
=
content
.
import_path
)
as
fp
:
displayname
=
content
.
name
,
thumbnail_location
=
content
.
thumbnail_location
,
import_path
=
content
.
import_path
)
as
fp
:
fp
.
write
(
content
.
data
)
...
...
@@ -49,8 +48,9 @@ class MongoContentStore(ContentStore):
try
:
with
self
.
fs
.
get
(
id
)
as
fp
:
return
StaticContent
(
location
,
fp
.
displayname
,
fp
.
content_type
,
fp
.
read
(),
fp
.
uploadDate
,
thumbnail_location
=
fp
.
thumbnail_location
if
hasattr
(
fp
,
'thumbnail_location'
)
else
None
,
import_path
=
fp
.
import_path
if
hasattr
(
fp
,
'import_path'
)
else
None
)
fp
.
uploadDate
,
thumbnail_location
=
fp
.
thumbnail_location
if
hasattr
(
fp
,
'thumbnail_location'
)
else
None
,
import_path
=
fp
.
import_path
if
hasattr
(
fp
,
'import_path'
)
else
None
)
except
NoFile
:
raise
NotFoundError
()
...
...
@@ -102,7 +102,7 @@ class MongoContentStore(ContentStore):
]
'''
course_filter
=
Location
(
XASSET_LOCATION_TAG
,
category
=
"asset"
if
not
get_thumbnails
else
"thumbnail"
,
course
=
location
.
course
,
org
=
location
.
org
)
course
=
location
.
course
,
org
=
location
.
org
)
# 'borrow' the function 'location_to_query' from the Mongo modulestore implementation
items
=
self
.
fs_files
.
find
(
location_to_query
(
course_filter
))
return
list
(
items
)
common/lib/xmodule/xmodule/course_module.py
View file @
260dc84f
...
...
@@ -211,7 +211,6 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
template_dir_name
=
'course'
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
CourseDescriptor
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
...
@@ -421,7 +420,6 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
policy
[
'GRADE_CUTOFFS'
]
=
value
self
.
grading_policy
=
policy
@property
def
lowest_passing_grade
(
self
):
return
min
(
self
.
_grading_policy
[
'GRADE_CUTOFFS'
]
.
values
())
...
...
@@ -460,7 +458,6 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
else
:
return
self
.
cohort_config
.
get
(
"auto_cohort_groups"
,
[])
@property
def
top_level_discussion_topic_ids
(
self
):
"""
...
...
@@ -469,7 +466,6 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
topics
=
self
.
discussion_topics
return
[
d
[
"id"
]
for
d
in
topics
.
values
()]
@property
def
cohorted_discussions
(
self
):
"""
...
...
@@ -483,8 +479,6 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
return
set
(
config
.
get
(
"cohorted_discussions"
,
[]))
@property
def
is_newish
(
self
):
"""
...
...
@@ -585,7 +579,6 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
yield
module_descriptor
for
c
in
self
.
get_children
():
sections
=
[]
for
s
in
c
.
get_children
():
if
s
.
lms
.
graded
:
xmoduledescriptors
=
list
(
yield_descriptor_descendents
(
s
))
...
...
@@ -601,8 +594,7 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
all_descriptors
.
append
(
s
)
return
{
'graded_sections'
:
graded_sections
,
'all_descriptors'
:
all_descriptors
,
}
'all_descriptors'
:
all_descriptors
,
}
@staticmethod
def
make_id
(
org
,
course
,
url_name
):
...
...
common/lib/xmodule/xmodule/discussion_module.py
View file @
260dc84f
from
lxml
import
etree
from
pkg_resources
import
resource_string
,
resource_listdir
from
pkg_resources
import
resource_string
from
xmodule.x_module
import
XModule
from
xmodule.raw_module
import
RawDescriptor
...
...
@@ -16,12 +15,11 @@ class DiscussionFields(object):
class
DiscussionModule
(
DiscussionFields
,
XModule
):
js
=
{
'coffee'
:
[
resource_string
(
__name__
,
'js/src/time.coffee'
),
resource_string
(
__name__
,
'js/src/discussion/display.coffee'
)]
}
[
resource_string
(
__name__
,
'js/src/time.coffee'
),
resource_string
(
__name__
,
'js/src/discussion/display.coffee'
)]
}
js_module_name
=
"InlineDiscussion"
def
get_html
(
self
):
context
=
{
'discussion_id'
:
self
.
discussion_id
,
...
...
common/lib/xmodule/xmodule/error_module.py
View file @
260dc84f
...
...
@@ -38,7 +38,7 @@ class ErrorModule(ErrorFields, XModule):
'staff_access'
:
True
,
'data'
:
self
.
contents
,
'error'
:
self
.
error_msg
,
})
})
class
NonStaffErrorModule
(
ErrorFields
,
XModule
):
...
...
@@ -51,7 +51,7 @@ class NonStaffErrorModule(ErrorFields, XModule):
'staff_access'
:
False
,
'data'
:
""
,
'error'
:
""
,
})
})
class
ErrorDescriptor
(
ErrorFields
,
JSONEditingDescriptor
):
...
...
common/lib/xmodule/xmodule/exceptions.py
View file @
260dc84f
class
InvalidDefinitionError
(
Exception
):
pass
class
NotFoundError
(
Exception
):
pass
class
ProcessingError
(
Exception
):
'''
An error occurred while processing a request to the XModule.
...
...
common/lib/xmodule/xmodule/fields.py
View file @
260dc84f
...
...
@@ -51,6 +51,8 @@ class Date(ModelType):
TIMEDELTA_REGEX
=
re
.
compile
(
r'^((?P<days>\d+?) day(?:s?))?(\s)?((?P<hours>\d+?) hour(?:s?))?(\s)?((?P<minutes>\d+?) minute(?:s)?)?(\s)?((?P<seconds>\d+?) second(?:s)?)?$'
)
class
Timedelta
(
ModelType
):
def
from_json
(
self
,
time_str
):
"""
...
...
common/lib/xmodule/xmodule/foldit_module.py
View file @
260dc84f
...
...
@@ -107,7 +107,7 @@ class FolditModule(FolditFields, XModule):
'show_leader'
:
showleader
,
'folditbasic'
:
self
.
get_basicpuzzles_html
(),
'folditchallenge'
:
self
.
get_challenge_html
()
}
}
return
self
.
system
.
render_template
(
'foldit.html'
,
context
)
...
...
@@ -124,7 +124,7 @@ class FolditModule(FolditFields, XModule):
'success'
:
self
.
is_complete
(),
'goal_level'
:
goal_level
,
'completed'
:
self
.
completed_puzzles
(),
}
}
return
self
.
system
.
render_template
(
'folditbasic.html'
,
context
)
def
get_challenge_html
(
self
):
...
...
@@ -149,7 +149,6 @@ class FolditModule(FolditFields, XModule):
return
1
class
FolditDescriptor
(
FolditFields
,
XmlDescriptor
,
EditingDescriptor
):
"""
Module for adding Foldit problems to courses
...
...
common/lib/xmodule/xmodule/modulestore/django.py
View file @
260dc84f
...
...
@@ -6,7 +6,6 @@ Passes settings.MODULESTORE as kwargs to MongoModuleStore
from
__future__
import
absolute_import
from
importlib
import
import_module
from
os
import
environ
from
django.conf
import
settings
...
...
@@ -38,7 +37,7 @@ def modulestore(name='default'):
for
key
in
FUNCTION_KEYS
:
if
key
in
options
:
options
[
key
]
=
load_function
(
options
[
key
])
_MODULESTORES
[
name
]
=
class_
(
**
options
)
...
...
common/lib/xmodule/xmodule/modulestore/inheritance.py
View file @
260dc84f
...
...
@@ -9,9 +9,10 @@ INHERITABLE_METADATA = (
# intended to be set per-course, but can be overridden in for specific
# elements. Can be a float.
'days_early_for_beta'
,
'giturl'
# for git edit link
'giturl'
# for git edit link
)
def
compute_inherited_metadata
(
descriptor
):
"""Given a descriptor, traverse all of its descendants and do metadata
inheritance. Should be called on a CourseDescriptor after importing a
...
...
common/lib/xmodule/xmodule/modulestore/mongo.py
View file @
260dc84f
...
...
@@ -7,7 +7,6 @@ from collections import namedtuple
from
fs.osfs
import
OSFS
from
itertools
import
repeat
from
path
import
path
from
datetime
import
datetime
from
operator
import
attrgetter
from
uuid
import
uuid4
...
...
@@ -31,11 +30,13 @@ log = logging.getLogger(__name__)
# there is only one revision for each item. Once we start versioning inside the CMS,
# that assumption will have to change
def
get_course_id_no_run
(
location
):
'''
'''
return
"/"
.
join
([
location
.
org
,
location
.
course
])
class
MongoKeyValueStore
(
KeyValueStore
):
"""
A KeyValueStore that maps keyed data access to one of the 3 data areas
...
...
@@ -130,8 +131,8 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
render_template: a function for rendering templates, as per
MakoDescriptorSystem
"""
super
(
CachingDescriptorSystem
,
self
)
.
__init__
(
self
.
load_item
,
resources_fs
,
error_tracker
,
render_template
)
super
(
CachingDescriptorSystem
,
self
)
.
__init__
(
self
.
load_item
,
resources_fs
,
error_tracker
,
render_template
)
self
.
modulestore
=
modulestore
self
.
module_data
=
module_data
self
.
default_class
=
default_class
...
...
@@ -140,7 +141,6 @@ class CachingDescriptorSystem(MakoDescriptorSystem):
self
.
course_id
=
None
self
.
cached_metadata
=
cached_metadata
def
load_item
(
self
,
location
):
"""
Return an XModule instance for the specified location
...
...
@@ -223,7 +223,7 @@ class MongoModuleStore(ModuleStoreBase):
def
__init__
(
self
,
host
,
db
,
collection
,
fs_root
,
render_template
,
port
=
27017
,
default_class
=
None
,
error_tracker
=
null_error_tracker
,
user
=
None
,
password
=
None
,
request_cache
=
None
,
user
=
None
,
password
=
None
,
request_cache
=
None
,
metadata_inheritance_cache_subsystem
=
None
,
**
kwargs
):
ModuleStoreBase
.
__init__
(
self
)
...
...
@@ -468,7 +468,7 @@ class MongoModuleStore(ModuleStoreBase):
# if we are loading a course object, if we're not prefetching children (depth != 0) then don't
# bother with the metadata inheritance
return
[
self
.
_load_item
(
item
,
data_cache
,
apply_cached_metadata
=
(
item
[
'location'
][
'category'
]
!=
'course'
or
depth
!=
0
))
for
item
in
items
]
apply_cached_metadata
=
(
item
[
'location'
][
'category'
]
!=
'course'
or
depth
!=
0
))
for
item
in
items
]
def
get_courses
(
self
):
'''
...
...
@@ -710,10 +710,9 @@ class MongoModuleStore(ModuleStoreBase):
course
.
tabs
=
[
tab
for
tab
in
existing_tabs
if
tab
.
get
(
'url_slug'
)
!=
location
.
name
]
self
.
update_metadata
(
course
.
location
,
own_metadata
(
course
))
self
.
collection
.
remove
({
'_id'
:
Location
(
location
)
.
dict
()},
# Must include this to avoid the django debug toolbar (which defines the deprecated "safe=False")
# from overriding our default value set in the init method.
safe
=
self
.
collection
.
safe
)
# Must include this to avoid the django debug toolbar (which defines the deprecated "safe=False")
# from overriding our default value set in the init method.
self
.
collection
.
remove
({
'_id'
:
Location
(
location
)
.
dict
()},
safe
=
self
.
collection
.
safe
)
# recompute (and update) the metadata inheritance tree which is cached
self
.
refresh_cached_metadata_inheritance_tree
(
Location
(
location
))
self
.
fire_updated_modulestore_signal
(
get_course_id_no_run
(
Location
(
location
)),
Location
(
location
))
...
...
@@ -724,7 +723,7 @@ class MongoModuleStore(ModuleStoreBase):
'''
location
=
Location
.
ensure_fully_specified
(
location
)
items
=
self
.
collection
.
find
({
'definition.children'
:
location
.
url
()},
{
'_id'
:
True
})
{
'_id'
:
True
})
return
[
i
[
'_id'
]
for
i
in
items
]
def
get_errored_courses
(
self
):
...
...
common/lib/xmodule/xmodule/modulestore/search.py
View file @
260dc84f
...
...
@@ -3,7 +3,7 @@ from itertools import repeat
from
xmodule.course_module
import
CourseDescriptor
from
.exceptions
import
(
ItemNotFoundError
,
NoPathToItem
)
from
.
import
ModuleStore
,
Location
from
.
import
Location
def
path_to_location
(
modulestore
,
course_id
,
location
):
...
...
@@ -106,7 +106,7 @@ def path_to_location(modulestore, course_id, location):
position_list
=
[]
for
path_index
in
range
(
2
,
n
-
1
):
category
=
path
[
path_index
]
.
category
if
category
==
'sequential'
or
category
==
'videosequence'
:
if
category
==
'sequential'
or
category
==
'videosequence'
:
section_desc
=
modulestore
.
get_instance
(
course_id
,
path
[
path_index
])
child_locs
=
[
c
.
location
for
c
in
section_desc
.
get_children
()]
# positions are 1-indexed, and should be strings to be consistent with
...
...
common/lib/xmodule/xmodule/modulestore/store_utilities.py
View file @
260dc84f
import
logging
from
xmodule.contentstore.content
import
StaticContent
from
xmodule.modulestore
import
Location
from
xmodule.modulestore.mongo
import
MongoModuleStore
...
...
@@ -33,11 +32,11 @@ def clone_course(modulestore, contentstore, source_location, dest_location, dele
if
original_loc
.
category
!=
'course'
:
module
.
location
=
module
.
location
.
_replace
(
tag
=
dest_location
.
tag
,
org
=
dest_location
.
org
,
course
=
dest_location
.
course
)
course
=
dest_location
.
course
)
else
:
# on the course module we also have to update the module name
module
.
location
=
module
.
location
.
_replace
(
tag
=
dest_location
.
tag
,
org
=
dest_location
.
org
,
course
=
dest_location
.
course
,
name
=
dest_location
.
name
)
course
=
dest_location
.
course
,
name
=
dest_location
.
name
)
print
"Cloning module {0} to {1}...."
.
format
(
original_loc
,
module
.
location
)
...
...
@@ -49,9 +48,9 @@ def clone_course(modulestore, contentstore, source_location, dest_location, dele
for
child_loc_url
in
module
.
children
:
child_loc
=
Location
(
child_loc_url
)
child_loc
=
child_loc
.
_replace
(
tag
=
dest_location
.
tag
,
org
=
dest_location
.
org
,
course
=
dest_location
.
course
tag
=
dest_location
.
tag
,
org
=
dest_location
.
org
,
course
=
dest_location
.
course
)
new_children
.
append
(
child_loc
.
url
())
...
...
@@ -67,7 +66,7 @@ def clone_course(modulestore, contentstore, source_location, dest_location, dele
thumb_loc
=
Location
(
thumb
[
"_id"
])
content
=
contentstore
.
find
(
thumb_loc
)
content
.
location
=
content
.
location
.
_replace
(
org
=
dest_location
.
org
,
course
=
dest_location
.
course
)
course
=
dest_location
.
course
)
print
"Cloning thumbnail {0} to {1}"
.
format
(
thumb_loc
,
content
.
location
)
...
...
@@ -80,12 +79,12 @@ def clone_course(modulestore, contentstore, source_location, dest_location, dele
asset_loc
=
Location
(
asset
[
"_id"
])
content
=
contentstore
.
find
(
asset_loc
)
content
.
location
=
content
.
location
.
_replace
(
org
=
dest_location
.
org
,
course
=
dest_location
.
course
)
course
=
dest_location
.
course
)
# be sure to update the pointer to the thumbnail
if
content
.
thumbnail_location
is
not
None
:
content
.
thumbnail_location
=
content
.
thumbnail_location
.
_replace
(
org
=
dest_location
.
org
,
course
=
dest_location
.
course
)
course
=
dest_location
.
course
)
print
"Cloning asset {0} to {1}"
.
format
(
asset_loc
,
content
.
location
)
...
...
@@ -94,7 +93,7 @@ def clone_course(modulestore, contentstore, source_location, dest_location, dele
return
True
def
delete_course
(
modulestore
,
contentstore
,
source_location
,
commit
=
False
):
def
delete_course
(
modulestore
,
contentstore
,
source_location
,
commit
=
False
):
# first check to see if the modulestore is Mongo backed
if
not
isinstance
(
modulestore
,
MongoModuleStore
):
raise
Exception
(
"Expected a MongoModuleStore in the runtime. Aborting...."
)
...
...
common/lib/xmodule/xmodule/modulestore/xml.py
View file @
260dc84f
...
...
@@ -75,7 +75,7 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
# tags that really need unique names--they store (or should store) state.
need_uniq_names
=
(
'problem'
,
'sequential'
,
'video'
,
'course'
,
'chapter'
,
'videosequence'
,
'poll_question'
,
'timelimit'
)
'videosequence'
,
'poll_question'
,
'timelimit'
)
attr
=
xml_data
.
attrib
tag
=
xml_data
.
tag
...
...
@@ -169,7 +169,6 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem):
# Didn't load properly. Fall back on loading as an error
# descriptor. This should never error due to formatting.
msg
=
"Error loading from xml. "
+
str
(
err
)[:
200
]
log
.
warning
(
msg
)
# Normally, we don't want lots of exception traces in our logs from common
...
...
@@ -367,7 +366,7 @@ class XMLModuleStore(ModuleStoreBase):
if
org
is
None
:
msg
=
(
"No 'org' attribute set for course in {dir}. "
"Using default 'edx'"
.
format
(
dir
=
course_dir
))
"Using default 'edx'"
.
format
(
dir
=
course_dir
))
log
.
warning
(
msg
)
tracker
(
msg
)
org
=
'edx'
...
...
@@ -376,10 +375,10 @@ class XMLModuleStore(ModuleStoreBase):
if
course
is
None
:
msg
=
(
"No 'course' attribute set for course in {dir}."
" Using default '{default}'"
.
format
(
dir
=
course_dir
,
default
=
course_dir
)
)
" Using default '{default}'"
.
format
(
dir
=
course_dir
,
default
=
course_dir
)
)
log
.
warning
(
msg
)
tracker
(
msg
)
course
=
course_dir
...
...
@@ -445,7 +444,6 @@ class XMLModuleStore(ModuleStoreBase):
log
.
debug
(
'========> Done with course import from {0}'
.
format
(
course_dir
))
return
course_descriptor
def
load_extra_content
(
self
,
system
,
course_descriptor
,
category
,
base_dir
,
course_dir
,
url_name
):
self
.
_load_extra_content
(
system
,
course_descriptor
,
category
,
base_dir
,
course_dir
)
...
...
@@ -453,7 +451,6 @@ class XMLModuleStore(ModuleStoreBase):
if
os
.
path
.
isdir
(
base_dir
/
url_name
):
self
.
_load_extra_content
(
system
,
course_descriptor
,
category
,
base_dir
/
url_name
,
course_dir
)
def
_load_extra_content
(
self
,
system
,
course_descriptor
,
category
,
path
,
course_dir
):
for
filepath
in
glob
.
glob
(
path
/
'*'
):
...
...
@@ -480,7 +477,6 @@ class XMLModuleStore(ModuleStoreBase):
logging
.
exception
(
"Failed to load {0}. Skipping... Exception: {1}"
.
format
(
filepath
,
str
(
e
)))
system
.
error_tracker
(
"ERROR: "
+
str
(
e
))
def
get_instance
(
self
,
course_id
,
location
,
depth
=
0
):
"""
Returns an XModuleDescriptor instance for the item at
...
...
@@ -542,7 +538,6 @@ class XMLModuleStore(ModuleStoreBase):
return
items
def
get_courses
(
self
,
depth
=
0
):
"""
Returns a list of course descriptors. If there were errors on loading,
...
...
@@ -567,7 +562,6 @@ class XMLModuleStore(ModuleStoreBase):
"""
raise
NotImplementedError
(
"XMLModuleStores are read-only"
)
def
update_children
(
self
,
location
,
children
):
"""
Set the children for the item specified by the location to
...
...
@@ -578,7 +572,6 @@ class XMLModuleStore(ModuleStoreBase):
"""
raise
NotImplementedError
(
"XMLModuleStores are read-only"
)
def
update_metadata
(
self
,
location
,
metadata
):
"""
Set the metadata for the item specified by the location to
...
...
common/lib/xmodule/xmodule/modulestore/xml_importer.py
View file @
260dc84f
...
...
@@ -316,7 +316,7 @@ def import_module(module, store, course_data_path, static_content_store, allow_n
# Note the dropped element closing tag. This causes the LMS to fail when rendering modules - that's
# no good, so we have to do this kludge
if
isinstance
(
module_data
,
str
)
or
isinstance
(
module_data
,
unicode
):
# some module 'data' fields are non strings which blows up the link traversal code
lxml_rewrite_links
(
module_data
,
lambda
link
:
verify_content_links
(
module
,
course_data_path
,
static_content_store
,
link
,
remap_dict
))
lxml_rewrite_links
(
module_data
,
lambda
link
:
verify_content_links
(
module
,
course_data_path
,
static_content_store
,
link
,
remap_dict
))
for
key
in
remap_dict
.
keys
():
module_data
=
module_data
.
replace
(
key
,
remap_dict
[
key
])
...
...
common/lib/xmodule/xmodule/util/decorators.py
View file @
260dc84f
...
...
@@ -28,6 +28,7 @@ def lazyproperty(fn):
"""
attr_name
=
'_lazy_'
+
fn
.
__name__
@property
def
_lazyprop
(
self
):
if
not
hasattr
(
self
,
attr_name
):
...
...
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