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
91f102c7
Commit
91f102c7
authored
Jun 30, 2014
by
Nimisha Asthagiri
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4232 from edx/nimisha/modulestore-enum-constants
ModulestoreEnum class.
parents
d6049239
8dca8053
Hide whitespace changes
Inline
Side-by-side
Showing
47 changed files
with
319 additions
and
306 deletions
+319
-306
cms/djangoapps/contentstore/management/commands/course_id_clash.py
+2
-2
cms/djangoapps/contentstore/management/commands/tests/test_migrate_to_split.py
+3
-3
cms/djangoapps/contentstore/tests/test_contentstore.py
+14
-12
cms/djangoapps/contentstore/tests/test_course_listing.py
+3
-3
cms/djangoapps/contentstore/tests/test_crud.py
+6
-6
cms/djangoapps/contentstore/views/item.py
+2
-2
cms/envs/common.py
+1
-1
common/djangoapps/static_replace/__init__.py
+4
-2
common/djangoapps/student/migrations/0036_access_roles_orgless.py
+3
-3
common/djangoapps/student/tests/test_course_listing.py
+2
-2
common/djangoapps/student/views.py
+2
-2
common/djangoapps/terrain/browser.py
+2
-2
common/djangoapps/terrain/course_helpers.py
+2
-2
common/djangoapps/xmodule_modifiers.py
+2
-2
common/lib/xmodule/xmodule/modulestore/__init__.py
+37
-30
common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py
+5
-3
common/lib/xmodule/xmodule/modulestore/mixed.py
+1
-5
common/lib/xmodule/xmodule/modulestore/mongo/base.py
+31
-28
common/lib/xmodule/xmodule/modulestore/mongo/draft.py
+69
-67
common/lib/xmodule/xmodule/modulestore/split_migrator.py
+4
-4
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
+13
-17
common/lib/xmodule/xmodule/modulestore/store_utilities.py
+3
-3
common/lib/xmodule/xmodule/modulestore/tests/django_utils.py
+2
-2
common/lib/xmodule/xmodule/modulestore/tests/persistent_factories.py
+4
-4
common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py
+25
-23
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
+15
-18
common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
+3
-3
common/lib/xmodule/xmodule/modulestore/tests/test_split_migrator.py
+2
-2
common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
+5
-1
common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py
+3
-3
common/lib/xmodule/xmodule/modulestore/tests/test_xml.py
+2
-2
common/lib/xmodule/xmodule/modulestore/xml.py
+6
-11
common/lib/xmodule/xmodule/modulestore/xml_exporter.py
+11
-6
common/lib/xmodule/xmodule/modulestore/xml_importer.py
+3
-3
lms/djangoapps/bulk_email/forms.py
+2
-2
lms/djangoapps/bulk_email/tests/test_forms.py
+2
-2
lms/djangoapps/courseware/courses.py
+4
-4
lms/djangoapps/courseware/tests/test_courses.py
+4
-4
lms/djangoapps/courseware/tests/test_lti_integration.py
+2
-2
lms/djangoapps/dashboard/sysadmin.py
+2
-2
lms/djangoapps/instructor/tests/test_legacy_email.py
+2
-2
lms/djangoapps/instructor/views/instructor_dashboard.py
+2
-2
lms/djangoapps/instructor/views/legacy.py
+2
-2
lms/djangoapps/instructor/views/tools.py
+2
-2
lms/envs/cms/dev.py
+1
-1
lms/envs/common.py
+1
-1
lms/envs/test.py
+1
-1
No files found.
cms/djangoapps/contentstore/management/commands/course_id_clash.py
View file @
91f102c7
...
...
@@ -3,7 +3,7 @@ Script for finding all courses whose org/name pairs == other courses when ignori
"""
from
django.core.management.base
import
BaseCommand
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore
import
M
ONGO_MODULESTORE_TYPE
from
xmodule.modulestore
import
M
oduleStoreEnum
#
...
...
@@ -16,7 +16,7 @@ class Command(BaseCommand):
help
=
'List all courses ids in the Mongo Modulestore which may collide when ignoring case'
def
handle
(
self
,
*
args
,
**
options
):
mstore
=
modulestore
()
.
_get_modulestore_by_type
(
M
ONGO_MODULESTORE_TYPE
)
# pylint: disable=protected-access
mstore
=
modulestore
()
.
_get_modulestore_by_type
(
M
oduleStoreEnum
.
Type
.
mongo
)
# pylint: disable=protected-access
if
hasattr
(
mstore
,
'collection'
):
map_fn
=
'''
function () {
...
...
cms/djangoapps/contentstore/management/commands/tests/test_migrate_to_split.py
View file @
91f102c7
...
...
@@ -6,7 +6,7 @@ import unittest
from
django.contrib.auth.models
import
User
from
django.core.management
import
CommandError
,
call_command
from
contentstore.management.commands.migrate_to_split
import
Command
from
xmodule.modulestore
import
SPLIT_MONGO_MODULESTORE_TYPE
,
REVISION_OPTION_PUBLISHED_ONLY
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.django
import
modulestore
,
clear_existing_modulestores
...
...
@@ -56,7 +56,7 @@ class TestMigrateToSplit(ModuleStoreTestCase):
password
=
'foo'
self
.
user
=
User
.
objects
.
create_user
(
uname
,
email
,
password
)
self
.
course
=
CourseFactory
()
self
.
addCleanup
(
ModuleStoreTestCase
.
drop_mongo_collections
,
SPLIT_MONGO_MODULESTORE_TYPE
)
self
.
addCleanup
(
ModuleStoreTestCase
.
drop_mongo_collections
,
ModuleStoreEnum
.
Type
.
split
)
self
.
addCleanup
(
clear_existing_modulestores
)
def
test_user_email
(
self
):
...
...
@@ -84,6 +84,6 @@ class TestMigrateToSplit(ModuleStoreTestCase):
str
(
self
.
user
.
id
),
"org.dept+name.run"
,
)
locator
=
CourseLocator
(
org
=
"org.dept"
,
offering
=
"name.run"
,
branch
=
REVISION_OPTION_PUBLISHED_ONLY
)
locator
=
CourseLocator
(
org
=
"org.dept"
,
offering
=
"name.run"
,
branch
=
ModuleStoreEnum
.
RevisionOption
.
published_only
)
course_from_split
=
modulestore
(
'split'
)
.
get_course
(
locator
)
self
.
assertIsNotNone
(
course_from_split
)
cms/djangoapps/contentstore/tests/test_contentstore.py
View file @
91f102c7
...
...
@@ -27,10 +27,8 @@ from xmodule.contentstore.content import StaticContent
from
xmodule.contentstore.django
import
contentstore
,
_CONTENTSTORE
from
xmodule.contentstore.utils
import
restore_asset_from_trashcan
,
empty_asset_trashcan
from
xmodule.exceptions
import
NotFoundError
,
InvalidVersionError
from
xmodule.modulestore
import
(
mongo
,
MONGO_MODULESTORE_TYPE
,
PublishState
,
REVISION_OPTION_PUBLISHED_ONLY
,
REVISION_OPTION_DRAFT_ONLY
,
KEY_REVISION_PUBLISHED
,
BRANCH_PUBLISHED_ONLY
)
from
xmodule.modulestore
import
mongo
,
PublishState
,
ModuleStoreEnum
from
xmodule.modulestore.mongo.base
import
MongoRevisionKey
from
xmodule.modulestore.mixed
import
store_branch_setting
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
...
...
@@ -204,13 +202,13 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
store
.
convert_to_draft
(
html_module_from_draft_store
.
location
,
self
.
user
.
id
)
# Query get_items() and find the html item. This should just return back a single item (not 2).
direct_store_items
=
store
.
get_items
(
course_key
,
revision
=
REVISION_OPTION_PUBLISHED_ONLY
)
direct_store_items
=
store
.
get_items
(
course_key
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
published_only
)
html_items_from_direct_store
=
[
item
for
item
in
direct_store_items
if
(
item
.
location
==
html_usage_key
)]
self
.
assertEqual
(
len
(
html_items_from_direct_store
),
1
)
self
.
assertFalse
(
getattr
(
html_items_from_direct_store
[
0
],
'is_draft'
,
False
))
# Fetch from the draft store.
draft_store_items
=
store
.
get_items
(
course_key
,
revision
=
REVISION_OPTION_DRAFT_ONLY
)
draft_store_items
=
store
.
get_items
(
course_key
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
)
html_items_from_draft_store
=
[
item
for
item
in
draft_store_items
if
(
item
.
location
==
html_usage_key
)]
self
.
assertEqual
(
len
(
html_items_from_draft_store
),
1
)
self
.
assertTrue
(
getattr
(
html_items_from_draft_store
[
0
],
'is_draft'
,
False
))
...
...
@@ -663,9 +661,9 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
clone_course
(
module_store
,
content_store
,
source_course_id
,
dest_course_id
,
self
.
user
.
id
)
# first assert that all draft content got cloned as well
draft_items
=
module_store
.
get_items
(
source_course_id
,
revision
=
REVISION_OPTION_DRAFT_ONLY
)
draft_items
=
module_store
.
get_items
(
source_course_id
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
)
self
.
assertGreater
(
len
(
draft_items
),
0
)
draft_clone_items
=
module_store
.
get_items
(
dest_course_id
,
revision
=
REVISION_OPTION_DRAFT_ONLY
)
draft_clone_items
=
module_store
.
get_items
(
dest_course_id
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
)
self
.
assertGreater
(
len
(
draft_clone_items
),
0
)
self
.
assertEqual
(
len
(
draft_items
),
len
(
draft_clone_items
))
...
...
@@ -868,7 +866,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
# add the new private and new public to list of children
sequential
=
module_store
.
get_item
(
course_id
.
make_usage_key
(
'sequential'
,
'vertical_sequential'
))
private_location_no_draft
=
private_vertical
.
location
.
replace
(
revision
=
KEY_REVISION_PUBLISHED
)
private_location_no_draft
=
private_vertical
.
location
.
replace
(
revision
=
MongoRevisionKey
.
published
)
sequential
.
children
.
append
(
private_location_no_draft
)
sequential
.
children
.
append
(
public_vertical_location
)
module_store
.
update_item
(
sequential
,
self
.
user
.
id
)
...
...
@@ -939,7 +937,11 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
target_course_id
=
course_id
,
)
items
=
module_store
.
get_items
(
course_id
,
category
=
'vertical'
,
revision
=
REVISION_OPTION_PUBLISHED_ONLY
)
items
=
module_store
.
get_items
(
course_id
,
category
=
'vertical'
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
published_only
)
self
.
_check_verticals
(
items
)
def
verify_item_publish_state
(
item
,
publish_state
):
...
...
@@ -1124,7 +1126,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
self
.
assertContains
(
resp
,
'/c4x/edX/toy/asset/handouts_sample_handout.txt'
)
def
test_prefetch_children
(
self
):
mongo_store
=
modulestore
()
.
_get_modulestore_by_type
(
M
ONGO_MODULESTORE_TYPE
)
mongo_store
=
modulestore
()
.
_get_modulestore_by_type
(
M
oduleStoreEnum
.
Type
.
mongo
)
import_from_xml
(
modulestore
(),
self
.
user
.
id
,
'common/test/data/'
,
[
'toy'
])
course_id
=
SlashSeparatedCourseKey
(
'edX'
,
'toy'
,
'2012_Fall'
)
...
...
@@ -1132,7 +1134,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
mongo_store
.
collection
.
find
=
wrapper
.
find
# set the branch to 'publish' in order to prevent extra lookups of draft versions
with
store_branch_setting
(
mongo_store
,
BRANCH_PUBLISHED_ONLY
):
with
store_branch_setting
(
mongo_store
,
ModuleStoreEnum
.
Branch
.
published_only
):
course
=
mongo_store
.
get_course
(
course_id
,
depth
=
2
)
# make sure we haven't done too many round trips to DB
...
...
cms/djangoapps/contentstore/tests/test_course_listing.py
View file @
91f102c7
...
...
@@ -17,7 +17,7 @@ from student.tests.factories import UserFactory
from
student.roles
import
CourseInstructorRole
,
CourseStaffRole
,
GlobalStaff
,
OrgStaffRole
,
OrgInstructorRole
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
check_mongo_calls
from
xmodule.modulestore
import
M
ONGO_MODULESTORE_TYPE
from
xmodule.modulestore
import
M
oduleStoreEnum
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.modulestore.django
import
modulestore
from
xmodule.error_module
import
ErrorDescriptor
...
...
@@ -199,7 +199,7 @@ class TestCourseListing(ModuleStoreTestCase):
self
.
assertGreaterEqual
(
iteration_over_courses_time_2
.
elapsed
,
iteration_over_groups_time_2
.
elapsed
)
# Now count the db queries
store
=
modulestore
()
.
_get_modulestore_by_type
(
M
ONGO_MODULESTORE_TYPE
)
store
=
modulestore
()
.
_get_modulestore_by_type
(
M
oduleStoreEnum
.
Type
.
mongo
)
with
check_mongo_calls
(
store
.
collection
,
USER_COURSES_COUNT
):
courses_list
=
_accessible_courses_list_from_groups
(
self
.
request
)
...
...
@@ -262,7 +262,7 @@ class TestCourseListing(ModuleStoreTestCase):
Create good courses, courses that won't load, and deleted courses which still have
roles. Test course listing.
"""
store
=
modulestore
()
.
_get_modulestore_by_type
(
M
ONGO_MODULESTORE_TYPE
)
store
=
modulestore
()
.
_get_modulestore_by_type
(
M
oduleStoreEnum
.
Type
.
mongo
)
course_location
=
SlashSeparatedCourseKey
(
'testOrg'
,
'testCourse'
,
'RunBabyRun'
)
self
.
_create_course_with_access_groups
(
course_location
,
self
.
user
)
...
...
cms/djangoapps/contentstore/tests/test_crud.py
View file @
91f102c7
import
unittest
from
xmodule
import
templates
from
xmodule.modulestore
import
SPLIT_MONGO_MODULESTORE_TYPE
,
BRANCH_NAME_DRAFT
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.tests
import
persistent_factories
from
xmodule.course_module
import
CourseDescriptor
from
xmodule.modulestore.django
import
modulestore
,
clear_existing_modulestores
,
_MIXED_MODULESTORE
,
\
...
...
@@ -21,9 +21,9 @@ class TemplateTests(unittest.TestCase):
def
setUp
(
self
):
clear_existing_modulestores
()
# redundant w/ cleanup but someone was getting errors
self
.
addCleanup
(
ModuleStoreTestCase
.
drop_mongo_collections
,
SPLIT_MONGO_MODULESTORE_TYPE
)
self
.
addCleanup
(
ModuleStoreTestCase
.
drop_mongo_collections
,
ModuleStoreEnum
.
Type
.
split
)
self
.
addCleanup
(
clear_existing_modulestores
)
self
.
split_store
=
modulestore
()
.
_get_modulestore_by_type
(
SPLIT_MONGO_MODULESTORE_TYPE
)
self
.
split_store
=
modulestore
()
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
split
)
def
test_get_templates
(
self
):
found
=
templates
.
all_templates
()
...
...
@@ -156,7 +156,7 @@ class TemplateTests(unittest.TestCase):
persistent_factories
.
ItemFactory
.
create
(
display_name
=
'chapter 1'
,
parent_location
=
test_course
.
location
)
id_locator
=
test_course
.
id
.
for_branch
(
BRANCH_NAME_DRAFT
)
id_locator
=
test_course
.
id
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
draft
)
guid_locator
=
test_course
.
location
.
course_agnostic
()
# verify it can be retrieved by id
self
.
assertIsInstance
(
self
.
split_store
.
get_course
(
id_locator
),
CourseDescriptor
)
...
...
@@ -241,7 +241,7 @@ class SplitAndLocMapperTests(unittest.TestCase):
mapper
=
loc_mapper
()
# instantiate mixed modulestore and thus split
split_store
=
modulestore
()
.
_get_modulestore_by_type
(
SPLIT_MONGO_MODULESTORE_TYPE
)
split_store
=
modulestore
()
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
split
)
# split must inject the same location mapper object since the mapper existed before it did
self
.
assertEqual
(
split_store
.
loc_mapper
,
mapper
)
...
...
@@ -254,7 +254,7 @@ class SplitAndLocMapperTests(unittest.TestCase):
self
.
assertIsNone
(
_loc_singleton
)
# instantiate split before location mapper
split_store
=
modulestore
()
.
_get_modulestore_by_type
(
SPLIT_MONGO_MODULESTORE_TYPE
)
split_store
=
modulestore
()
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
split
)
# split must have instantiated loc_mapper
mapper
=
loc_mapper
()
...
...
cms/djangoapps/contentstore/views/item.py
View file @
91f102c7
...
...
@@ -21,7 +21,7 @@ from xblock.fragment import Fragment
import
xmodule
from
xmodule.tabs
import
StaticTab
,
CourseTabList
from
xmodule.modulestore
import
PublishState
,
REVISION_OPTION_ALL
from
xmodule.modulestore
import
PublishState
,
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.draft
import
DIRECT_ONLY_CATEGORIES
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
,
InvalidLocationError
,
DuplicateItemError
...
...
@@ -527,7 +527,7 @@ def orphan_handler(request, course_key_string):
# get_orphans returns the deprecated string format w/o revision
usage_key
=
course_usage_key
.
make_usage_key_from_deprecated_string
(
itemloc
)
# need to delete all versions
store
.
delete_item
(
usage_key
,
request
.
user
.
id
,
revision
=
REVISION_OPTION_ALL
)
store
.
delete_item
(
usage_key
,
request
.
user
.
id
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
all
)
return
JsonResponse
({
'deleted'
:
items
})
else
:
raise
PermissionDenied
()
...
...
cms/envs/common.py
View file @
91f102c7
...
...
@@ -247,7 +247,7 @@ XBLOCK_MIXINS = (LmsBlockMixin, InheritanceMixin, XModuleMixin)
XBLOCK_SELECT_FUNCTION
=
prefer_xmodules
############################ Modulestore Configuration ################################
MODULESTORE_BRANCH
=
'draft'
MODULESTORE_BRANCH
=
'draft
-preferred
'
############################ DJANGO_BUILTINS ################################
# Change DEBUG/TEMPLATE_DEBUG in your environment settings files, not here
...
...
common/djangoapps/static_replace/__init__.py
View file @
91f102c7
...
...
@@ -6,7 +6,7 @@ from staticfiles import finders
from
django.conf
import
settings
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.contentstore.content
import
StaticContent
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -119,7 +119,9 @@ def replace_static_urls(text, data_directory, course_id=None, static_asset_path=
if
settings
.
DEBUG
and
finders
.
find
(
rest
,
True
):
return
original
# if we're running with a MongoBacked store course_namespace is not None, then use studio style urls
elif
(
not
static_asset_path
)
and
course_id
and
modulestore
()
.
get_modulestore_type
(
course_id
)
!=
XML_MODULESTORE_TYPE
:
elif
(
not
static_asset_path
)
\
and
course_id
\
and
modulestore
()
.
get_modulestore_type
(
course_id
)
!=
ModuleStoreEnum
.
Type
.
xml
:
# first look in the static file pipeline and see if we are trying to reference
# a piece of static content which is in the edx-platform repo (e.g. JS associated with an xmodule)
...
...
common/djangoapps/student/migrations/0036_access_roles_orgless.py
View file @
91f102c7
...
...
@@ -7,7 +7,7 @@ from opaque_keys import InvalidKeyError
import
logging
from
django.db.models.query_utils
import
Q
from
django.db.utils
import
IntegrityError
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
,
MONGO_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.mixed
import
MixedModuleStore
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -27,8 +27,8 @@ class Migration(DataMigration):
# Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..."
loc_map_collection
=
loc_mapper
()
.
location_map
mixed_ms
=
modulestore
()
xml_ms
=
mixed_ms
.
_get_modulestore_by_type
(
XML_MODULESTORE_TYPE
)
mongo_ms
=
mixed_ms
.
_get_modulestore_by_type
(
M
ONGO_MODULESTORE_TYPE
)
xml_ms
=
mixed_ms
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
xml
)
mongo_ms
=
mixed_ms
.
_get_modulestore_by_type
(
M
oduleStoreEnum
.
Type
.
mongo
)
query
=
Q
(
name__startswith
=
'staff'
)
|
Q
(
name__startswith
=
'instructor'
)
|
Q
(
name__startswith
=
'beta_testers'
)
for
group
in
orm
[
'auth.Group'
]
.
objects
.
filter
(
query
)
.
exclude
(
name__contains
=
"/"
)
.
all
():
...
...
common/djangoapps/student/tests/test_course_listing.py
View file @
91f102c7
...
...
@@ -6,7 +6,7 @@ from mock import patch, Mock
from
student.tests.factories
import
UserFactory
from
student.roles
import
GlobalStaff
from
xmodule.modulestore
import
M
ONGO_MODULESTORE_TYPE
from
xmodule.modulestore
import
M
oduleStoreEnum
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
...
...
@@ -90,7 +90,7 @@ class TestCourseListing(ModuleStoreTestCase):
Create good courses, courses that won't load, and deleted courses which still have
roles. Test course listing.
"""
mongo_store
=
modulestore
()
.
_get_modulestore_by_type
(
M
ONGO_MODULESTORE_TYPE
)
mongo_store
=
modulestore
()
.
_get_modulestore_by_type
(
M
oduleStoreEnum
.
Type
.
mongo
)
good_location
=
SlashSeparatedCourseKey
(
'testOrg'
,
'testCourse'
,
'RunBabyRun'
)
self
.
_create_course_with_access_groups
(
good_location
)
...
...
common/djangoapps/student/views.py
View file @
91f102c7
...
...
@@ -53,7 +53,7 @@ from dark_lang.models import DarkLangConfig
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.django
import
modulestore
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
collections
import
namedtuple
...
...
@@ -462,7 +462,7 @@ def dashboard(request):
show_email_settings_for
=
frozenset
(
course
.
id
for
course
,
_enrollment
in
course_enrollment_pairs
if
(
settings
.
FEATURES
[
'ENABLE_INSTRUCTOR_EMAIL'
]
and
modulestore
()
.
get_modulestore_type
(
course
.
id
)
!=
XML_MODULESTORE_TYPE
and
modulestore
()
.
get_modulestore_type
(
course
.
id
)
!=
ModuleStoreEnum
.
Type
.
xml
and
CourseAuthorization
.
instructor_email_enabled
(
course
.
id
)
)
)
...
...
common/djangoapps/terrain/browser.py
View file @
91f102c7
...
...
@@ -19,7 +19,7 @@ from json import dumps
from
pymongo
import
MongoClient
import
xmodule.modulestore.django
from
xmodule.contentstore.django
import
_CONTENTSTORE
from
xmodule.modulestore
import
M
ONGO_MODULESTORE_TYPE
from
xmodule.modulestore
import
M
oduleStoreEnum
# There is an import issue when using django-staticfiles with lettuce
# Lettuce assumes that we are using django.contrib.staticfiles,
...
...
@@ -190,7 +190,7 @@ def reset_databases(scenario):
mongo
.
drop_database
(
settings
.
CONTENTSTORE
[
'DOC_STORE_CONFIG'
][
'db'
])
_CONTENTSTORE
.
clear
()
modulestore
=
xmodule
.
modulestore
.
django
.
modulestore
()
.
_get_modulestore_by_type
(
M
ONGO_MODULESTORE_TYPE
)
modulestore
=
xmodule
.
modulestore
.
django
.
modulestore
()
.
_get_modulestore_by_type
(
M
oduleStoreEnum
.
Type
.
mongo
)
modulestore
.
collection
.
drop
()
xmodule
.
modulestore
.
django
.
clear_existing_modulestores
()
...
...
common/djangoapps/terrain/course_helpers.py
View file @
91f102c7
...
...
@@ -6,7 +6,7 @@ from lettuce import world
from
django.contrib.auth.models
import
User
,
Group
from
student.models
import
CourseEnrollment
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore
import
M
ONGO_MODULESTORE_TYPE
from
xmodule.modulestore
import
M
oduleStoreEnum
from
xmodule.contentstore.django
import
contentstore
...
...
@@ -72,6 +72,6 @@ def clear_courses():
# (though it shouldn't), do this manually
# from the bash shell to drop it:
# $ mongo test_xmodule --eval "db.dropDatabase()"
store
=
modulestore
()
.
_get_modulestore_by_type
(
M
ONGO_MODULESTORE_TYPE
)
store
=
modulestore
()
.
_get_modulestore_by_type
(
M
oduleStoreEnum
.
Type
.
mongo
)
store
.
collection
.
drop
()
contentstore
()
.
fs_files
.
drop
()
common/djangoapps/xmodule_modifiers.py
View file @
91f102c7
...
...
@@ -16,7 +16,7 @@ from xblock.fragment import Fragment
from
xmodule.seq_module
import
SequenceModule
from
xmodule.vertical_module
import
VerticalModule
from
xmodule.x_module
import
shim_xmodule_js
,
XModuleDescriptor
,
XModule
,
PREVIEW_VIEWS
,
STUDIO_VIEW
from
xmodule.modulestore
import
M
ONGO_MODULESTORE_TYPE
from
xmodule.modulestore
import
M
oduleStoreEnum
from
xmodule.modulestore.django
import
modulestore
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -169,7 +169,7 @@ def add_staff_markup(user, has_instructor_access, block, view, frag, context):
# TODO: make this more general, eg use an XModule attribute instead
if
isinstance
(
block
,
VerticalModule
)
and
(
not
context
or
not
context
.
get
(
'child_of_vertical'
,
False
)):
# check that the course is a mongo backed Studio course before doing work
is_mongo_course
=
modulestore
()
.
get_modulestore_type
(
block
.
location
.
course_key
)
==
M
ONGO_MODULESTORE_TYPE
is_mongo_course
=
modulestore
()
.
get_modulestore_type
(
block
.
location
.
course_key
)
==
M
oduleStoreEnum
.
Type
.
mongo
is_studio_course
=
block
.
course_edit_method
==
"Studio"
if
is_studio_course
and
is_mongo_course
:
...
...
common/lib/xmodule/xmodule/modulestore/__init__.py
View file @
91f102c7
...
...
@@ -25,44 +25,51 @@ from xblock.core import XBlock
log
=
logging
.
getLogger
(
'edx.modulestore'
)
# Modulestore Types
SPLIT_MONGO_MODULESTORE_TYPE
=
'split'
MONGO_MODULESTORE_TYPE
=
'mongo'
XML_MODULESTORE_TYPE
=
'xml'
# Key Revision constants to use for Location and Usage Keys
# Note: These values are persisted in the database, so should not be changed without migrations
KEY_REVISION_DRAFT
=
'draft'
KEY_REVISION_PUBLISHED
=
None
# Revision constants to use for Module Store operations
# Note: These values are passed into store APIs and only used at run time
# both DRAFT and PUBLISHED versions are queried, with preference to DRAFT versions
REVISION_OPTION_DRAFT_PREFERRED
=
'rev-opt-draft-preferred'
class
ModuleStoreEnum
(
object
):
"""
A class to encapsulate common constants that are used with the various modulestores.
"""
# only DRAFT versions are queried and no PUBLISHED versions
REVISION_OPTION_DRAFT_ONLY
=
'rev-opt-draft-only'
class
Type
(
object
):
"""
The various types of modulestores provided
"""
split
=
'split'
mongo
=
'mongo'
xml
=
'xml'
# # only PUBLISHED versions are queried and no DRAFT versions
REVISION_OPTION_PUBLISHED_ONLY
=
'rev-opt-published-only'
class
RevisionOption
(
object
):
"""
Revision constants to use for Module Store operations
Note: These values are passed into store APIs and only used at run time
"""
# both DRAFT and PUBLISHED versions are queried, with preference to DRAFT versions
draft_preferred
=
'rev-opt-draft-preferred'
# all revisions are queried
REVISION_OPTION_ALL
=
'rev-opt-all
'
# only DRAFT versions are queried and no PUBLISHED versions
draft_only
=
'rev-opt-draft-only
'
# # only PUBLISHED versions are queried and no DRAFT versions
published_only
=
'rev-opt-published-only'
# Branch constants to use for stores, such as Mongo, that have only 2 branches: DRAFT and PUBLISHED
# Note: These values are taken from server configuration settings, so should not be changed without alerting DevOps
BRANCH_DRAFT_PREFERRED
=
'draft'
BRANCH_PUBLISHED_ONLY
=
'published'
# all revisions are queried
all
=
'rev-opt-all'
class
Branch
(
object
):
"""
Branch constants to use for stores, such as Mongo, that have only 2 branches: DRAFT and PUBLISHED
Note: These values are taken from server configuration settings, so should not be changed without alerting DevOps
"""
draft_preferred
=
'draft-preferred'
published_only
=
'published-only'
# Branch constants to use for stores, such as Split, that have named branches
BRANCH_NAME_DRAFT
=
'draft'
BRANCH_NAME_PUBLISHED
=
'published'
class
BranchName
(
object
):
"""
Branch constants to use for stores, such as Split, that have named branches
"""
draft
=
'draft-branch'
published
=
'published-branch'
class
PublishState
(
object
):
...
...
common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py
View file @
91f102c7
...
...
@@ -7,7 +7,7 @@ import pymongo
import
bson.son
import
urllib
from
xmodule.modulestore
import
BRANCH_NAME_PUBLISHED
,
BRANCH_NAME_DRAFT
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.exceptions
import
InvalidLocationError
,
ItemNotFoundError
from
opaque_keys.edx.locator
import
BlockUsageLocator
,
CourseLocator
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
...
...
@@ -55,7 +55,9 @@ class LocMapperStore(object):
# location_map functions
def
create_map_entry
(
self
,
course_key
,
org
=
None
,
offering
=
None
,
draft_branch
=
BRANCH_NAME_DRAFT
,
prod_branch
=
BRANCH_NAME_PUBLISHED
,
block_map
=
None
):
draft_branch
=
ModuleStoreEnum
.
BranchName
.
draft
,
prod_branch
=
ModuleStoreEnum
.
BranchName
.
published
,
block_map
=
None
):
"""
Add a new entry to map this SlashSeparatedCourseKey to the new style CourseLocator.org & offering. If
org and offering are not provided, it defaults them based on course_key.
...
...
@@ -245,7 +247,7 @@ class LocMapperStore(object):
for
old_name
,
cat_to_usage
in
entry
[
'block_map'
]
.
iteritems
():
for
category
,
block_id
in
cat_to_usage
.
iteritems
():
# cache all entries and then figure out if we have the one we want
# Always return revision=
KEY_REVISION_PUBLISHED
because the
# Always return revision=
MongoRevisionKey.published
because the
# old draft module store wraps locations as draft before
# trying to access things.
location
=
old_course_id
.
make_usage_key
(
...
...
common/lib/xmodule/xmodule/modulestore/mixed.py
View file @
91f102c7
...
...
@@ -110,11 +110,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
def
_get_modulestore_by_type
(
self
,
modulestore_type
):
"""
This method should only really be used by tests and migration scripts when necessary.
Returns the module store as requested by type. The type can be:
SPLIT_MONGO_MODULESTORE_TYPE
MONGO_MODULESTORE_TYPE
XML_MODULESTORE_TYPE
Returns the module store as requested by type. The type can be a value from ModuleStoreEnum.Type.
"""
for
store
in
self
.
modulestores
:
if
store
.
get_modulestore_type
()
==
modulestore_type
:
...
...
common/lib/xmodule/xmodule/modulestore/mongo/base.py
View file @
91f102c7
...
...
@@ -33,11 +33,7 @@ from xblock.runtime import KvsFieldData
from
xblock.exceptions
import
InvalidScopeError
from
xblock.fields
import
Scope
,
ScopeIds
,
Reference
,
ReferenceList
,
ReferenceValueDict
from
xmodule.modulestore
import
(
ModuleStoreWriteBase
,
MONGO_MODULESTORE_TYPE
,
REVISION_OPTION_PUBLISHED_ONLY
,
REVISION_OPTION_DRAFT_PREFERRED
,
KEY_REVISION_DRAFT
,
KEY_REVISION_PUBLISHED
)
from
xmodule.modulestore
import
ModuleStoreWriteBase
,
ModuleStoreEnum
from
opaque_keys.edx.locations
import
Location
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
,
InvalidLocationError
,
ReferentialIntegrityError
from
xmodule.modulestore.inheritance
import
own_metadata
,
InheritanceMixin
,
inherit_metadata
,
InheritanceKeyValueStore
...
...
@@ -58,6 +54,15 @@ SORT_REVISION_FAVOR_DRAFT = ('_id.revision', pymongo.DESCENDING)
SORT_REVISION_FAVOR_PUBLISHED
=
(
'_id.revision'
,
pymongo
.
ASCENDING
)
class
MongoRevisionKey
(
object
):
"""
Key Revision constants to use for Location and Usage Keys in the Mongo modulestore
Note: These values are persisted in the database, so should not be changed without migrations
"""
draft
=
'draft'
published
=
None
class
InvalidWriteError
(
Exception
):
"""
Raised to indicate that writing to a particular key
...
...
@@ -303,14 +308,14 @@ def as_draft(location):
"""
if
location
.
category
in
DIRECT_ONLY_CATEGORIES
:
return
location
return
location
.
replace
(
revision
=
KEY_REVISION_DRAFT
)
return
location
.
replace
(
revision
=
MongoRevisionKey
.
draft
)
def
as_published
(
location
):
"""
Returns the Location that is the published version for `location`
"""
return
location
.
replace
(
revision
=
KEY_REVISION_PUBLISHED
)
return
location
.
replace
(
revision
=
MongoRevisionKey
.
published
)
class
MongoModuleStore
(
ModuleStoreWriteBase
):
...
...
@@ -744,7 +749,7 @@ class MongoModuleStore(ModuleStoreWriteBase):
for
key
in
(
'tag'
,
'org'
,
'course'
,
'category'
,
'name'
,
'revision'
)
])
def
get_items
(
self
,
course_id
,
settings
=
None
,
content
=
None
,
key_revision
=
KEY_REVISION_PUBLISHED
,
**
kwargs
):
def
get_items
(
self
,
course_id
,
settings
=
None
,
content
=
None
,
key_revision
=
MongoRevisionKey
.
published
,
**
kwargs
):
"""
Returns:
list of XModuleDescriptor instances for the matching items within the course with
...
...
@@ -763,10 +768,10 @@ class MongoModuleStore(ModuleStoreWriteBase):
content (dict): fields to look for which have content scope. Follows same syntax and
rules as kwargs below.
key_revision (str): the revision of the items you're looking for.
KEY_REVISION_DRAFT
- only returns drafts
KEY_REVISION_PUBLISHED
(equates to None) - only returns published
MongoRevisionKey.draft
- only returns drafts
MongoRevisionKey.published
(equates to None) - only returns published
If you want one of each matching xblock but preferring draft to published, call this same method
on the draft modulestore with
REVISION_OPTION_DRAFT_PREFERRED
.
on the draft modulestore with
ModuleStoreEnum.RevisionOption.draft_preferred
.
kwargs (key=value): what to look for within the course.
Common qualifiers are ``category`` or any field name. if the target field is a list,
then it searches for the given value in the list not list equivalence.
...
...
@@ -1003,7 +1008,7 @@ class MongoModuleStore(ModuleStoreWriteBase):
value
[
key
]
=
subvalue
.
to_deprecated_string
()
return
jsonfields
def
get_parent_location
(
self
,
location
,
revision
=
REVISION_OPTION_PUBLISHED_ONLY
,
**
kwargs
):
def
get_parent_location
(
self
,
location
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
published_only
,
**
kwargs
):
'''
Find the location that is the parent of this location in this course.
...
...
@@ -1011,21 +1016,24 @@ class MongoModuleStore(ModuleStoreWriteBase):
Args:
revision:
REVISION_OPTION_PUBLISHED_ONLY - return only the PUBLISHED parent if it exists, else returns None
REVISION_OPTION_DRAFT_PREFERRED - return either the DRAFT or PUBLISHED parent,
preferring DRAFT, if parent(s) exists,
else returns None
ModuleStoreEnum.RevisionOption.published_only
- return only the PUBLISHED parent if it exists, else returns None
ModuleStoreEnum.RevisionOption.draft_preferred
- return either the DRAFT or PUBLISHED parent,
preferring DRAFT, if parent(s) exists,
else returns None
'''
assert
location
.
revision
is
None
assert
revision
==
REVISION_OPTION_PUBLISHED_ONLY
or
revision
==
REVISION_OPTION_DRAFT_PREFERRED
assert
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
\
or
revision
==
ModuleStoreEnum
.
RevisionOption
.
draft_preferred
# create a query with tag, org, course, and the children field set to the given location
query
=
self
.
_course_key_to_son
(
location
.
course_key
)
query
[
'definition.children'
]
=
location
.
to_deprecated_string
()
# if only looking for the PUBLISHED parent, set the revision in the query to None
if
revision
==
REVISION_OPTION_PUBLISHED_ONLY
:
query
[
'_id.revision'
]
=
KEY_REVISION_PUBLISHED
if
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
query
[
'_id.revision'
]
=
MongoRevisionKey
.
published
# query the collection, sorting by DRAFT first
parents
=
self
.
collection
.
find
(
query
,
{
'_id'
:
True
},
sort
=
[
SORT_REVISION_FAVOR_DRAFT
])
...
...
@@ -1034,7 +1042,7 @@ class MongoModuleStore(ModuleStoreWriteBase):
# no parents were found
return
None
if
revision
==
REVISION_OPTION_PUBLISHED_ONLY
:
if
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
if
parents
.
count
()
>
1
:
# should never have multiple PUBLISHED parents
raise
ReferentialIntegrityError
(
...
...
@@ -1055,16 +1063,11 @@ class MongoModuleStore(ModuleStoreWriteBase):
def
get_modulestore_type
(
self
,
course_key
=
None
):
"""
Returns an enumeration-like type reflecting the type of this modulestore
The return can be one of:
"xml" (for XML based courses),
"mongo" for old-style MongoDB backed courses,
"split" for new-style split MongoDB backed courses.
Returns an enumeration-like type reflecting the type of this modulestore per ModuleStoreEnum.Type
Args:
course_key: just for signature compatibility
"""
return
M
ONGO_MODULESTORE_TYPE
return
M
oduleStoreEnum
.
Type
.
mongo
def
get_orphans
(
self
,
course_key
):
"""
...
...
@@ -1114,6 +1117,6 @@ class MongoModuleStore(ModuleStoreWriteBase):
Check that the db is reachable.
"""
if
self
.
database
.
connection
.
alive
():
return
{
M
ONGO_MODULESTORE_TYPE
:
True
}
return
{
M
oduleStoreEnum
.
Type
.
mongo
:
True
}
else
:
raise
HeartbeatFailure
(
"Can't connect to {}"
.
format
(
self
.
database
.
name
),
'mongo'
)
common/lib/xmodule/xmodule/modulestore/mongo/draft.py
View file @
91f102c7
...
...
@@ -9,15 +9,11 @@ and otherwise returns i4x://org/course/cat/name).
import
pymongo
from
xmodule.exceptions
import
InvalidVersionError
from
xmodule.modulestore
import
(
PublishState
,
REVISION_OPTION_DRAFT_PREFERRED
,
REVISION_OPTION_DRAFT_ONLY
,
REVISION_OPTION_PUBLISHED_ONLY
,
REVISION_OPTION_ALL
,
KEY_REVISION_PUBLISHED
,
KEY_REVISION_DRAFT
,
BRANCH_PUBLISHED_ONLY
,
BRANCH_DRAFT_PREFERRED
)
from
xmodule.modulestore
import
PublishState
,
ModuleStoreEnum
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
,
DuplicateItemError
,
InvalidBranchSetting
from
xmodule.modulestore.mongo.base
import
(
MongoModuleStore
,
as_draft
,
as_published
,
DIRECT_ONLY_CATEGORIES
,
SORT_REVISION_FAVOR_DRAFT
,
MongoModuleStore
,
MongoRevisionKey
,
as_draft
,
as_published
,
DIRECT_ONLY_CATEGORIES
,
SORT_REVISION_FAVOR_DRAFT
)
from
opaque_keys.edx.locations
import
Location
...
...
@@ -29,8 +25,8 @@ def wrap_draft(item):
Sets `item.is_draft` to `True` if the item is DRAFT, and `False` otherwise.
Sets the item's location to the non-draft location in either case.
"""
setattr
(
item
,
'is_draft'
,
item
.
location
.
revision
==
KEY_REVISION_DRAFT
)
item
.
location
=
item
.
location
.
replace
(
revision
=
KEY_REVISION_PUBLISHED
)
setattr
(
item
,
'is_draft'
,
item
.
location
.
revision
==
MongoRevisionKey
.
draft
)
item
.
location
=
item
.
location
.
replace
(
revision
=
MongoRevisionKey
.
published
)
return
item
...
...
@@ -51,7 +47,7 @@ class DraftModuleStore(MongoModuleStore):
branch_setting_func: a function that returns the branch setting to use for this store's operations
"""
super
(
DraftModuleStore
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
branch_setting_func
=
kwargs
.
pop
(
'branch_setting_func'
,
lambda
:
BRANCH_PUBLISHED_ONLY
)
self
.
branch_setting_func
=
kwargs
.
pop
(
'branch_setting_func'
,
lambda
:
ModuleStoreEnum
.
Branch
.
published_only
)
def
get_item
(
self
,
usage_key
,
depth
=
0
,
revision
=
None
):
"""
...
...
@@ -66,11 +62,11 @@ class DraftModuleStore(MongoModuleStore):
get_children() to cache. None indicates to cache all descendants.
revision:
REVISION_OPTION_PUBLISHED_ONLY
- returns only the published item.
REVISION_OPTION_DRAFT_ONLY
- returns only the draft item.
ModuleStoreEnum.RevisionOption.published_only
- returns only the published item.
ModuleStoreEnum.RevisionOption.draft_only
- returns only the draft item.
None - uses the branch setting as follows:
if branch setting is
BRANCH_PUBLISHED_ONLY
, returns only the published item.
if branch setting is
BRANCH_DRAFT_PREFERRED
, returns either draft or published item,
if branch setting is
ModuleStoreEnum.Branch.published_only
, returns only the published item.
if branch setting is
ModuleStoreEnum.Branch.draft_preferred
, returns either draft or published item,
preferring draft.
Note: If the item is in DIRECT_ONLY_CATEGORIES, then returns only the PUBLISHED
...
...
@@ -89,8 +85,8 @@ class DraftModuleStore(MongoModuleStore):
def
get_draft
():
return
wrap_draft
(
super
(
DraftModuleStore
,
self
)
.
get_item
(
as_draft
(
usage_key
),
depth
=
depth
))
# return the published version if
REVISION_OPTION_PUBLISHED_ONLY
is requested
if
revision
==
REVISION_OPTION_PUBLISHED_ONLY
:
# return the published version if
ModuleStoreEnum.RevisionOption.published_only
is requested
if
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
return
get_published
()
# if the item is direct-only, there can only be a published version
...
...
@@ -98,10 +94,10 @@ class DraftModuleStore(MongoModuleStore):
return
get_published
()
# return the draft version (without any fallback to PUBLISHED) if DRAFT-ONLY is requested
elif
revision
==
REVISION_OPTION_DRAFT_ONLY
:
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
draft_only
:
return
get_draft
()
elif
self
.
branch_setting_func
()
==
BRANCH_PUBLISHED_ONLY
:
elif
self
.
branch_setting_func
()
==
ModuleStoreEnum
.
Branch
.
published_only
:
return
get_published
()
else
:
...
...
@@ -120,11 +116,11 @@ class DraftModuleStore(MongoModuleStore):
Args:
revision:
REVISION_OPTION_PUBLISHED_ONLY
- checks for the published item only
REVISION_OPTION_DRAFT_ONLY
- checks for the draft item only
ModuleStoreEnum.RevisionOption.published_only
- checks for the published item only
ModuleStoreEnum.RevisionOption.draft_only
- checks for the draft item only
None - uses the branch setting, as follows:
if branch setting is
BRANCH_PUBLISHED_ONLY
, checks for the published item only
if branch setting is
BRANCH_DRAFT_PREFERRED
, checks whether draft or published item exists
if branch setting is
ModuleStoreEnum.Branch.published_only
, checks for the published item only
if branch setting is
ModuleStoreEnum.Branch.draft_preferred
, checks whether draft or published item exists
"""
def
has_published
():
return
super
(
DraftModuleStore
,
self
)
.
has_item
(
usage_key
)
...
...
@@ -132,9 +128,10 @@ class DraftModuleStore(MongoModuleStore):
def
has_draft
():
return
super
(
DraftModuleStore
,
self
)
.
has_item
(
as_draft
(
usage_key
))
if
revision
==
REVISION_OPTION_DRAFT_ONLY
:
if
revision
==
ModuleStoreEnum
.
RevisionOption
.
draft_only
:
return
has_draft
()
elif
revision
==
REVISION_OPTION_PUBLISHED_ONLY
or
self
.
branch_setting_func
()
==
BRANCH_PUBLISHED_ONLY
:
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
\
or
self
.
branch_setting_func
()
==
ModuleStoreEnum
.
Branch
.
published_only
:
return
has_published
()
else
:
key
=
usage_key
.
to_deprecated_son
(
prefix
=
'_id.'
)
...
...
@@ -150,9 +147,9 @@ class DraftModuleStore(MongoModuleStore):
Args:
location (UsageKey): assumes the location's revision is None; so, uses revision keyword solely
key_revision:
KEY_REVISION_DRAFT
- return only the draft parent
KEY_REVISION_PUBLISHED
- return only the published parent
REVISION_OPTION_ALL
- return both draft and published parents
MongoRevisionKey.draft
- return only the draft parent
MongoRevisionKey.published
- return only the published parent
ModuleStoreEnum.RevisionOption.all
- return both draft and published parents
"""
_verify_revision_is_published
(
location
)
...
...
@@ -168,8 +165,8 @@ class DraftModuleStore(MongoModuleStore):
Location
.
_from_deprecated_son
(
parent
[
'_id'
],
location
.
course_key
.
run
)
for
parent
in
parents
if
(
# return all versions of the parent if revision is
REVISION_OPTION_ALL
key_revision
==
REVISION_OPTION_ALL
or
# return all versions of the parent if revision is
ModuleStoreEnum.RevisionOption.all
key_revision
==
ModuleStoreEnum
.
RevisionOption
.
all
or
# return this parent if it's direct-only, regardless of which revision is requested
parent
[
'_id'
][
'category'
]
in
DIRECT_ONLY_CATEGORIES
or
# return this parent only if its revision matches the requested one
...
...
@@ -186,9 +183,11 @@ class DraftModuleStore(MongoModuleStore):
Args:
revision:
None - uses the branch setting for the revision
REVISION_OPTION_PUBLISHED_ONLY - return only the PUBLISHED parent if it exists, else returns None
REVISION_OPTION_DRAFT_PREFERRED - return either the DRAFT or PUBLISHED parent, preferring DRAFT, if parent(s) exists,
else returns None
ModuleStoreEnum.RevisionOption.published_only
- return only the PUBLISHED parent if it exists, else returns None
ModuleStoreEnum.RevisionOption.draft_preferred
- return either the DRAFT or PUBLISHED parent, preferring DRAFT, if parent(s) exists,
else returns None
If the draft has a different parent than the published, it returns only
the draft's parent. Because parents don't record their children's revisions, this
...
...
@@ -197,9 +196,9 @@ class DraftModuleStore(MongoModuleStore):
Only xml_exporter currently uses this argument. Others should avoid it.
'''
if
revision
is
None
:
revision
=
REVISION_OPTION_PUBLISHED_ONLY
\
if
self
.
branch_setting_func
()
==
BRANCH_PUBLISHED_ONLY
\
else
REVISION_OPTION_DRAFT_PREFERRED
revision
=
ModuleStoreEnum
.
RevisionOption
.
published_only
\
if
self
.
branch_setting_func
()
==
ModuleStoreEnum
.
Branch
.
published_only
\
else
ModuleStoreEnum
.
RevisionOption
.
draft_preferred
return
super
(
DraftModuleStore
,
self
)
.
get_parent_location
(
location
,
revision
,
**
kwargs
)
def
create_xmodule
(
self
,
location
,
definition_data
=
None
,
metadata
=
None
,
runtime
=
None
,
fields
=
{}):
...
...
@@ -213,7 +212,7 @@ class DraftModuleStore(MongoModuleStore):
:param runtime: if you already have an xmodule from the course, the xmodule.runtime value
:param fields: a dictionary of field names and values for the new xmodule
"""
self
.
_verify_branch_setting
(
BRANCH_DRAFT_PREFERRED
)
self
.
_verify_branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
)
if
location
.
category
not
in
DIRECT_ONLY_CATEGORIES
:
location
=
as_draft
(
location
)
...
...
@@ -236,12 +235,12 @@ class DraftModuleStore(MongoModuleStore):
settings: not used
content: not used
revision:
REVISION_OPTION_PUBLISHED_ONLY
- returns only Published items
REVISION_OPTION_DRAFT_ONLY
- returns only Draft items
ModuleStoreEnum.RevisionOption.published_only
- returns only Published items
ModuleStoreEnum.RevisionOption.draft_only
- returns only Draft items
None - uses the branch setting, as follows:
if the branch setting is
BRANCH_PUBLISHED_ONLY
,
if the branch setting is
ModuleStoreEnum.Branch.published_only
,
returns only Published items
if the branch setting is
BRANCH_DRAFT_PREFERRED
,
if the branch setting is
ModuleStoreEnum.Branch.draft_preferred
,
returns either Draft or Published, preferring Draft items.
kwargs (key=value): what to look for within the course.
Common qualifiers are ``category`` or any field name. if the target field is a list,
...
...
@@ -253,20 +252,21 @@ class DraftModuleStore(MongoModuleStore):
return
super
(
DraftModuleStore
,
self
)
.
get_items
(
course_key
,
key_revision
=
key_revision
,
**
kwargs
)
def
draft_items
():
return
[
wrap_draft
(
item
)
for
item
in
base_get_items
(
KEY_REVISION_DRAFT
)]
return
[
wrap_draft
(
item
)
for
item
in
base_get_items
(
MongoRevisionKey
.
draft
)]
def
published_items
(
draft_items
):
# filters out items that are not already in draft_items
draft_items_locations
=
{
item
.
location
for
item
in
draft_items
}
return
[
item
for
item
in
base_get_items
(
KEY_REVISION_PUBLISHED
)
base_get_items
(
MongoRevisionKey
.
published
)
if
item
.
location
not
in
draft_items_locations
]
if
revision
==
REVISION_OPTION_DRAFT_ONLY
:
if
revision
==
ModuleStoreEnum
.
RevisionOption
.
draft_only
:
return
draft_items
()
elif
revision
==
REVISION_OPTION_PUBLISHED_ONLY
or
self
.
branch_setting_func
()
==
BRANCH_PUBLISHED_ONLY
:
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
\
or
self
.
branch_setting_func
()
==
ModuleStoreEnum
.
Branch
.
published_only
:
return
published_items
([])
else
:
draft_items
=
draft_items
()
...
...
@@ -293,7 +293,7 @@ class DraftModuleStore(MongoModuleStore):
Internal method with additional internal parameters to convert a subtree to draft.
Args:
location: the location of the source (its revision must be
KEY_REVISION_PUBLISHED
)
location: the location of the source (its revision must be
MongoRevisionKey.published
)
user_id: the ID of the user doing the operation
delete_published (Boolean): intended for use by unpublish
ignore_if_draft(Boolean): for internal use only as part of depth first change
...
...
@@ -304,7 +304,7 @@ class DraftModuleStore(MongoModuleStore):
DuplicateItemError: if the source or any of its descendants already has a draft copy
"""
# verify input conditions
self
.
_verify_branch_setting
(
BRANCH_DRAFT_PREFERRED
)
self
.
_verify_branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
)
_verify_revision_is_published
(
location
)
# ensure we are not creating a DRAFT of an item that is direct-only
...
...
@@ -322,7 +322,7 @@ class DraftModuleStore(MongoModuleStore):
next_tier
.
append
(
child_loc
.
to_deprecated_son
())
# insert a new DRAFT version of the item
item
[
'_id'
][
'revision'
]
=
KEY_REVISION_DRAFT
item
[
'_id'
][
'revision'
]
=
MongoRevisionKey
.
draft
# ensure keys are in fixed and right order before inserting
item
[
'_id'
]
=
self
.
_id_dict_to_son
(
item
[
'_id'
])
try
:
...
...
@@ -334,7 +334,7 @@ class DraftModuleStore(MongoModuleStore):
# delete the old PUBLISHED version if requested
if
delete_published
:
item
[
'_id'
][
'revision'
]
=
KEY_REVISION_PUBLISHED
item
[
'_id'
][
'revision'
]
=
MongoRevisionKey
.
published
to_be_deleted
.
append
(
item
[
'_id'
])
return
next_tier
...
...
@@ -352,7 +352,7 @@ class DraftModuleStore(MongoModuleStore):
In addition to the superclass's behavior, this method converts the unit to draft if it's not
direct-only and not already draft.
"""
self
.
_verify_branch_setting
(
BRANCH_DRAFT_PREFERRED
)
self
.
_verify_branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
)
# if the xblock is direct-only, update the PUBLISHED version
if
xblock
.
location
.
category
in
DIRECT_ONLY_CATEGORIES
:
...
...
@@ -380,7 +380,7 @@ class DraftModuleStore(MongoModuleStore):
The method determines which revisions to delete. It disconnects and deletes the subtree.
In general, it assumes deletes only occur on drafts except for direct_only. The only exceptions
are internal calls like deleting orphans (during publishing as well as from delete_orphan view).
To indicate that all versions should be deleted, pass the keyword revision=
REVISION_OPTION_ALL
.
To indicate that all versions should be deleted, pass the keyword revision=
ModuleStoreEnum.RevisionOption.all
.
* Deleting a DIRECT_ONLY_CATEGORIES block, deletes both draft and published children and removes from parent.
* Deleting a specific version of block whose parent is of DIRECT_ONLY_CATEGORIES, only removes it from parent if
...
...
@@ -392,32 +392,34 @@ class DraftModuleStore(MongoModuleStore):
user_id: id of the user deleting the item
revision:
None - deletes the item and its subtree, and updates the parents per description above
REVISION_OPTION_PUBLISHED_ONLY
- removes only Published versions
REVISION_OPTION_ALL
- removes both Draft and Published parents
ModuleStoreEnum.RevisionOption.published_only
- removes only Published versions
ModuleStoreEnum.RevisionOption.all
- removes both Draft and Published parents
currently only provided by contentstore.views.item.orphan_handler
"""
self
.
_verify_branch_setting
(
BRANCH_DRAFT_PREFERRED
)
self
.
_verify_branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
)
_verify_revision_is_published
(
location
)
is_item_direct_only
=
location
.
category
in
DIRECT_ONLY_CATEGORIES
if
is_item_direct_only
or
revision
==
REVISION_OPTION_PUBLISHED_ONLY
:
parent_revision
=
KEY_REVISION_PUBLISHED
elif
revision
==
REVISION_OPTION_ALL
:
parent_revision
=
REVISION_OPTION_ALL
if
is_item_direct_only
or
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
parent_revision
=
MongoRevisionKey
.
published
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
all
:
parent_revision
=
ModuleStoreEnum
.
RevisionOption
.
all
else
:
parent_revision
=
KEY_REVISION_DRAFT
parent_revision
=
MongoRevisionKey
.
draft
# remove subtree from its parent
parent_locations
=
self
.
_get_raw_parent_locations
(
location
,
key_revision
=
parent_revision
)
# there could be 2 parents if
# Case 1: the draft item moved from one parent to another
# Case 2: revision==
REVISION_OPTION_ALL
and the single parent has 2 versions: draft and published
# Case 2: revision==
ModuleStoreEnum.RevisionOption.all
and the single parent has 2 versions: draft and published
for
parent_location
in
parent_locations
:
# don't remove from direct_only parent if other versions of this still exists
if
not
is_item_direct_only
and
parent_location
.
category
in
DIRECT_ONLY_CATEGORIES
:
# see if other version of root exists
alt_location
=
location
.
replace
(
revision
=
KEY_REVISION_PUBLISHED
if
location
.
revision
==
KEY_REVISION_DRAFT
else
KEY_REVISION_DRAFT
revision
=
MongoRevisionKey
.
published
if
location
.
revision
==
MongoRevisionKey
.
draft
else
MongoRevisionKey
.
draft
)
if
super
(
DraftModuleStore
,
self
)
.
has_item
(
alt_location
):
continue
...
...
@@ -427,9 +429,9 @@ class DraftModuleStore(MongoModuleStore):
parent_block
.
location
=
parent_location
# ensure the location is with the correct revision
self
.
update_item
(
parent_block
,
user_id
)
if
is_item_direct_only
or
revision
==
REVISION_OPTION_ALL
:
if
is_item_direct_only
or
revision
==
ModuleStoreEnum
.
RevisionOption
.
all
:
as_functions
=
[
as_draft
,
as_published
]
elif
revision
==
REVISION_OPTION_PUBLISHED_ONLY
:
elif
revision
==
ModuleStoreEnum
.
RevisionOption
.
published_only
:
as_functions
=
[
as_published
]
else
:
as_functions
=
[
as_draft
]
...
...
@@ -574,7 +576,7 @@ class DraftModuleStore(MongoModuleStore):
to_be_deleted
.
append
(
as_draft
(
item_location
)
.
to_deprecated_son
())
# verify input conditions
self
.
_verify_branch_setting
(
BRANCH_DRAFT_PREFERRED
)
self
.
_verify_branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
)
_verify_revision_is_published
(
location
)
_internal_depth_first
(
location
)
...
...
@@ -589,7 +591,7 @@ class DraftModuleStore(MongoModuleStore):
NOTE: unlike publish, this gives an error if called above the draftable level as it's intended
to remove things from the published version
"""
self
.
_verify_branch_setting
(
BRANCH_DRAFT_PREFERRED
)
self
.
_verify_branch_setting
(
ModuleStoreEnum
.
Branch
.
draft_preferred
)
return
self
.
_convert_to_draft
(
location
,
user_id
,
delete_published
=
True
)
def
_query_children_for_cache_children
(
self
,
course_key
,
items
):
...
...
@@ -600,7 +602,7 @@ class DraftModuleStore(MongoModuleStore):
for
non_draft
in
to_process_non_drafts
:
to_process_dict
[
Location
.
_from_deprecated_son
(
non_draft
[
"_id"
],
course_key
.
run
)]
=
non_draft
if
self
.
branch_setting_func
()
==
BRANCH_DRAFT_PREFERRED
:
if
self
.
branch_setting_func
()
==
ModuleStoreEnum
.
Branch
.
draft_preferred
:
# now query all draft content in another round-trip
query
=
[]
for
item
in
items
:
...
...
@@ -664,6 +666,6 @@ class DraftModuleStore(MongoModuleStore):
def
_verify_revision_is_published
(
location
):
"""
Asserts that the revision set on the given location is
KEY_REVISION_PUBLISHED
Asserts that the revision set on the given location is
MongoRevisionKey.published
"""
assert
location
.
revision
==
KEY_REVISION_PUBLISHED
assert
location
.
revision
==
MongoRevisionKey
.
published
common/lib/xmodule/xmodule/modulestore/split_migrator.py
View file @
91f102c7
...
...
@@ -7,7 +7,7 @@ In general, it's strategy is to treat the other modulestores as read-only and to
manipulate storage but use existing api's.
'''
from
xblock.fields
import
Reference
,
ReferenceList
,
ReferenceValueDict
from
xmodule.modulestore
import
BRANCH_NAME_DRAFT
,
BRANCH_NAME_PUBLISHED
,
REVISION_OPTION_DRAFT_ONLY
from
xmodule.modulestore
import
ModuleStoreEnum
class
SplitMigrator
(
object
):
...
...
@@ -85,7 +85,7 @@ class SplitMigrator(object):
# after done w/ published items, add version for DRAFT pointing to the published structure
index_info
=
self
.
split_modulestore
.
get_course_index_info
(
course_version_locator
)
versions
=
index_info
[
'versions'
]
versions
[
BRANCH_NAME_DRAFT
]
=
versions
[
BRANCH_NAME_PUBLISHED
]
versions
[
ModuleStoreEnum
.
BranchName
.
draft
]
=
versions
[
ModuleStoreEnum
.
BranchName
.
published
]
self
.
split_modulestore
.
update_course_index
(
index_info
)
# clean up orphans in published version: in old mongo, parents pointed to the union of their published and draft
...
...
@@ -98,11 +98,11 @@ class SplitMigrator(object):
"""
# each true update below will trigger a new version of the structure. We may want to just have one new version
# but that's for a later date.
new_draft_course_loc
=
published_course_key
.
for_branch
(
BRANCH_NAME_DRAFT
)
new_draft_course_loc
=
published_course_key
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
draft
)
# to prevent race conditions of grandchilden being added before their parents and thus having no parent to
# add to
awaiting_adoption
=
{}
for
module
in
self
.
draft_modulestore
.
get_items
(
course_key
,
revision
=
REVISION_OPTION_DRAFT_ONLY
):
for
module
in
self
.
draft_modulestore
.
get_items
(
course_key
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
):
new_locator
=
self
.
loc_mapper
.
translate_location
(
module
.
location
,
False
,
add_entry_if_missing
=
True
)
...
...
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
View file @
91f102c7
...
...
@@ -61,7 +61,7 @@ from opaque_keys.edx.locator import (
from
xmodule.modulestore.exceptions
import
InsufficientSpecificationError
,
VersionConflictError
,
DuplicateItemError
,
\
DuplicateCourseError
from
xmodule.modulestore
import
(
inheritance
,
ModuleStoreWriteBase
,
SPLIT_MONGO_MODULESTORE_TYPE
,
BRANCH_NAME_DRAFT
,
BRANCH_NAME_PUBLISHED
inheritance
,
ModuleStoreWriteBase
,
ModuleStoreEnum
)
from
..exceptions
import
ItemNotFoundError
...
...
@@ -296,7 +296,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
}
return
envelope
def
get_courses
(
self
,
branch
=
BRANCH_NAME_DRAFT
,
qualifiers
=
None
):
def
get_courses
(
self
,
branch
=
ModuleStoreEnum
.
BranchName
.
draft
,
qualifiers
=
None
):
'''
Returns a list of course descriptors matching any given qualifiers.
...
...
@@ -304,9 +304,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
legal query for mongo to use against the active_versions collection.
Note, this is to find the current head of the named branch type
(e.g.,
BRANCH_NAME_DRAFT
). To get specific versions via guid use get_course.
(e.g.,
ModuleStoreEnum.BranchName.draft
). To get specific versions via guid use get_course.
:param branch: the branch for which to return courses. Default value is
BRANCH_NAME_DRAFT
.
:param branch: the branch for which to return courses. Default value is
ModuleStoreEnum.BranchName.draft
.
:param qualifiers: an optional dict restricting which elements should match
'''
if
qualifiers
is
None
:
...
...
@@ -385,9 +385,9 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
:param usage_key: the block to check
:return: True if the draft and published versions differ
"""
draft
=
self
.
get_item
(
usage_key
.
for_branch
(
BRANCH_NAME_DRAFT
))
draft
=
self
.
get_item
(
usage_key
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
draft
))
try
:
published
=
self
.
get_item
(
usage_key
.
for_branch
(
BRANCH_NAME_PUBLISHED
))
published
=
self
.
get_item
(
usage_key
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
published
))
except
ItemNotFoundError
:
return
True
...
...
@@ -492,7 +492,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
def
get_orphans
(
self
,
course_key
):
"""
Return a
dict
of all of the orphans in the course.
Return a
n array
of all of the orphans in the course.
"""
detached_categories
=
[
name
for
name
,
__
in
XBlock
.
load_tagged_classes
(
"detached"
)]
course
=
self
.
_lookup_course
(
course_key
)
...
...
@@ -872,7 +872,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
def
create_course
(
self
,
org
,
offering
,
user_id
,
fields
=
None
,
master_branch
=
BRANCH_NAME_DRAFT
,
versions_dict
=
None
,
root_category
=
'course'
,
master_branch
=
ModuleStoreEnum
.
BranchName
.
draft
,
versions_dict
=
None
,
root_category
=
'course'
,
root_block_id
=
'course'
,
**
kwargs
):
"""
...
...
@@ -908,7 +908,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
master_branch: the tag (key) for the version name in the dict which is the DRAFT version. Not the actual
version guid, but what to call it.
versions_dict: the starting version ids where the keys are the tags such as DRAFT and
REVISION_OPTION_PUBLISHED_ONLY
versions_dict: the starting version ids where the keys are the tags such as DRAFT and
PUBLISHED
and the values are structure guids. If provided, the new course will reuse this version (unless you also
provide any fields overrides, see above). if not provided, will create a mostly empty course
structure with just a category course root xblock.
...
...
@@ -1298,7 +1298,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
self
.
_update_head
(
index_entry
,
destination_course
.
branch
,
destination_structure
[
'_id'
])
def
unpublish
(
self
,
location
,
user_id
):
published_location
=
location
.
replace
(
branch
=
REVISION_OPTION_PUBLISHED_ONLY
)
published_location
=
location
.
replace
(
branch
=
ModuleStoreEnum
.
BranchName
.
published
)
self
.
delete_item
(
published_location
,
user_id
)
def
update_course_index
(
self
,
updated_index_entry
):
...
...
@@ -1456,16 +1456,12 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
def
get_modulestore_type
(
self
,
course_key
=
None
):
"""
Returns an enumeration-like type reflecting the type of this modulestore
The return can be one of:
"xml" (for XML based courses),
"mongo" for old-style MongoDB backed courses,
"split" for new-style split MongoDB backed courses.
Returns an enumeration-like type reflecting the type of this modulestore, per ModuleStoreEnum.Type.
Args:
course_key: just for signature compatibility
"""
return
SPLIT_MONGO_MODULESTORE_TYPE
return
ModuleStoreEnum
.
Type
.
split
def
internal_clean_children
(
self
,
course_locator
):
"""
...
...
@@ -1797,7 +1793,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
"""
Check that the db is reachable.
"""
return
{
SPLIT_MONGO_MODULESTORE_TYPE
:
self
.
db_connection
.
heartbeat
()}
return
{
ModuleStoreEnum
.
Type
.
split
:
self
.
db_connection
.
heartbeat
()}
def
compute_publish_state
(
self
,
xblock
):
"""
...
...
common/lib/xmodule/xmodule/modulestore/store_utilities.py
View file @
91f102c7
...
...
@@ -2,7 +2,7 @@ import re
import
logging
from
xmodule.contentstore.content
import
StaticContent
from
xmodule.modulestore
import
REVISION_OPTION_PUBLISHED_ONLY
,
REVISION_OPTION_DRAFT_ONLY
from
xmodule.modulestore
import
ModuleStoreEnum
def
_prefix_only_url_replace_regex
(
prefix
):
...
...
@@ -136,12 +136,12 @@ def clone_course(modulestore, contentstore, source_course_id, dest_course_id, us
raise
Exception
(
"Cannot find a course at {0}. Aborting"
.
format
(
source_course_id
))
# Get all modules under this namespace which is (tag, org, course) tuple
modules
=
modulestore
.
get_items
(
source_course_id
,
revision
=
REVISION_OPTION_PUBLISHED_ONLY
)
modules
=
modulestore
.
get_items
(
source_course_id
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
published_only
)
_clone_modules
(
modulestore
,
modules
,
source_course_id
,
dest_course_id
,
user_id
)
course_location
=
dest_course_id
.
make_usage_key
(
'course'
,
dest_course_id
.
run
)
modulestore
.
publish
(
course_location
,
user_id
)
modules
=
modulestore
.
get_items
(
source_course_id
,
revision
=
REVISION_OPTION_DRAFT_ONLY
)
modules
=
modulestore
.
get_items
(
source_course_id
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
)
_clone_modules
(
modulestore
,
modules
,
source_course_id
,
dest_course_id
,
user_id
)
# now iterate through all of the assets and clone them
...
...
common/lib/xmodule/xmodule/modulestore/tests/django_utils.py
View file @
91f102c7
...
...
@@ -6,7 +6,7 @@ from uuid import uuid4
from
django.test
import
TestCase
from
xmodule.modulestore.django
import
(
modulestore
,
clear_existing_modulestores
,
loc_mapper
)
from
xmodule.modulestore
import
M
ONGO_MODULESTORE_TYPE
from
xmodule.modulestore
import
M
oduleStoreEnum
from
xmodule.contentstore.django
import
contentstore
...
...
@@ -142,7 +142,7 @@ class ModuleStoreTestCase(TestCase):
return
updated_course
@staticmethod
def
drop_mongo_collections
(
modulestore_type
=
M
ONGO_MODULESTORE_TYPE
):
def
drop_mongo_collections
(
modulestore_type
=
M
oduleStoreEnum
.
Type
.
mongo
):
"""
If using a Mongo-backed modulestore & contentstore, drop the collections.
"""
...
...
common/lib/xmodule/xmodule/modulestore/tests/persistent_factories.py
View file @
91f102c7
from
xmodule.modulestore
import
SPLIT_MONGO_MODULESTORE_TYPE
,
BRANCH_NAME_DRAFT
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.course_module
import
CourseDescriptor
from
xmodule.x_module
import
XModuleDescriptor
import
factory
...
...
@@ -15,7 +15,7 @@ class SplitFactory(factory.Factory):
# Delayed import so that we only depend on django if the caller
# hasn't provided their own modulestore
from
xmodule.modulestore.django
import
modulestore
return
modulestore
()
.
_get_modulestore_by_type
(
SPLIT_MONGO_MODULESTORE_TYPE
)
return
modulestore
()
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
split
)
class
PersistentCourseFactory
(
SplitFactory
):
...
...
@@ -25,7 +25,7 @@ class PersistentCourseFactory(SplitFactory):
keywords: any xblock field plus (note, the below are filtered out; so, if they
become legitimate xblock fields, they won't be settable via this factory)
* org: defaults to textX
* master_branch: (optional) defaults to
BRANCH_NAME_DRAFT
* master_branch: (optional) defaults to
ModuleStoreEnum.BranchName.draft
* user_id: (optional) defaults to 'test_user'
* display_name (xblock field): will default to 'Robot Super Course' unless provided
"""
...
...
@@ -34,7 +34,7 @@ class PersistentCourseFactory(SplitFactory):
# pylint: disable=W0613
@classmethod
def
_create
(
cls
,
target_class
,
offering
=
'999'
,
org
=
'testX'
,
user_id
=
'test_user'
,
master_branch
=
BRANCH_NAME_DRAFT
,
**
kwargs
):
master_branch
=
ModuleStoreEnum
.
BranchName
.
draft
,
**
kwargs
):
modulestore
=
kwargs
.
pop
(
'modulestore'
)
root_block_id
=
kwargs
.
pop
(
'root_block_id'
,
'course'
)
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py
View file @
91f102c7
...
...
@@ -5,7 +5,8 @@ import unittest
import
uuid
from
opaque_keys.edx.locations
import
Location
from
opaque_keys.edx.locator
import
BlockUsageLocator
,
CourseLocator
from
xmodule.modulestore
import
BRANCH_NAME_PUBLISHED
,
BRANCH_NAME_DRAFT
,
KEY_REVISION_PUBLISHED
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.mongo.base
import
MongoRevisionKey
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
,
InvalidLocationError
from
xmodule.modulestore.loc_mapper_store
import
LocMapperStore
from
mock
import
Mock
...
...
@@ -63,8 +64,8 @@ class TestLocationMapper(LocMapperSetupSansDjango):
self
.
assertIsNotNone
(
entry
,
"Didn't find entry"
)
self
.
assertEqual
(
entry
[
'org'
],
org
)
self
.
assertEqual
(
entry
[
'offering'
],
'{}.{}'
.
format
(
course1
,
run
))
self
.
assertEqual
(
entry
[
'draft_branch'
],
BRANCH_NAME_DRAFT
)
self
.
assertEqual
(
entry
[
'prod_branch'
],
BRANCH_NAME_PUBLISHED
)
self
.
assertEqual
(
entry
[
'draft_branch'
],
ModuleStoreEnum
.
BranchName
.
draft
)
self
.
assertEqual
(
entry
[
'prod_branch'
],
ModuleStoreEnum
.
BranchName
.
published
)
self
.
assertEqual
(
entry
[
'block_map'
],
{})
course2
=
'quux_course'
...
...
@@ -124,7 +125,7 @@ class TestLocationMapper(LocMapperSetupSansDjango):
"""
prob_locator
=
loc_mapper
()
.
translate_location
(
location
,
published
=
(
branch
==
BRANCH_NAME_PUBLISHED
),
published
=
(
branch
==
ModuleStoreEnum
.
BranchName
.
published
),
add_entry_if_missing
=
add_entry
)
self
.
assertEqual
(
prob_locator
.
org
,
org
)
...
...
@@ -134,7 +135,7 @@ class TestLocationMapper(LocMapperSetupSansDjango):
course_locator
=
loc_mapper
()
.
translate_location_to_course_locator
(
location
.
course_key
,
published
=
(
branch
==
BRANCH_NAME_PUBLISHED
),
published
=
(
branch
==
ModuleStoreEnum
.
BranchName
.
published
),
)
self
.
assertEqual
(
course_locator
.
org
,
org
)
self
.
assertEqual
(
course_locator
.
offering
,
offering
)
...
...
@@ -169,7 +170,8 @@ class TestLocationMapper(LocMapperSetupSansDjango):
)
test_problem_locn
=
Location
(
org
,
course
,
run
,
'problem'
,
'abc123'
)
self
.
translate_n_check
(
test_problem_locn
,
new_style_org
,
new_style_offering
,
'problem2'
,
BRANCH_NAME_PUBLISHED
)
self
.
translate_n_check
(
test_problem_locn
,
new_style_org
,
new_style_offering
,
'problem2'
,
ModuleStoreEnum
.
BranchName
.
published
)
# look for non-existent problem
with
self
.
assertRaises
(
ItemNotFoundError
):
loc_mapper
()
.
translate_location
(
...
...
@@ -184,7 +186,7 @@ class TestLocationMapper(LocMapperSetupSansDjango):
test_no_cat_locn
=
test_no_cat_locn
.
replace
(
name
=
'def456'
)
self
.
translate_n_check
(
test_no_cat_locn
,
new_style_org
,
new_style_offering
,
'problem4'
,
BRANCH_NAME_PUBLISHED
test_no_cat_locn
,
new_style_org
,
new_style_offering
,
'problem4'
,
ModuleStoreEnum
.
BranchName
.
published
)
# add a distractor course (note that abc123 has a different translation in this one)
...
...
@@ -203,12 +205,12 @@ class TestLocationMapper(LocMapperSetupSansDjango):
)
# test that old translation still works
self
.
translate_n_check
(
test_problem_locn
,
new_style_org
,
new_style_offering
,
'problem2'
,
BRANCH_NAME_PUBLISHED
test_problem_locn
,
new_style_org
,
new_style_offering
,
'problem2'
,
ModuleStoreEnum
.
BranchName
.
published
)
# and new returns new id
self
.
translate_n_check
(
test_problem_locn
.
replace
(
run
=
run
),
test_delta_new_org
,
test_delta_new_offering
,
'problem3'
,
BRANCH_NAME_PUBLISHED
'problem3'
,
ModuleStoreEnum
.
BranchName
.
published
)
def
test_translate_location_dwim
(
self
):
...
...
@@ -222,11 +224,11 @@ class TestLocationMapper(LocMapperSetupSansDjango):
problem_name
=
'abc123abc123abc123abc123abc123f9'
location
=
Location
(
org
,
course
,
run
,
'problem'
,
problem_name
)
new_offering
=
'{}.{}'
.
format
(
course
,
run
)
self
.
translate_n_check
(
location
,
org
,
new_offering
,
'problemabc'
,
BRANCH_NAME_PUBLISHED
,
True
)
self
.
translate_n_check
(
location
,
org
,
new_offering
,
'problemabc'
,
ModuleStoreEnum
.
BranchName
.
published
,
True
)
# create an entry w/o a guid name
other_location
=
Location
(
org
,
course
,
run
,
'chapter'
,
'intro'
)
self
.
translate_n_check
(
other_location
,
org
,
new_offering
,
'intro'
,
BRANCH_NAME_PUBLISHED
,
True
)
self
.
translate_n_check
(
other_location
,
org
,
new_offering
,
'intro'
,
ModuleStoreEnum
.
BranchName
.
published
,
True
)
# add a distractor course
delta_new_org
=
'{}.geek_dept'
.
format
(
org
)
...
...
@@ -238,7 +240,7 @@ class TestLocationMapper(LocMapperSetupSansDjango):
delta_new_org
,
delta_new_offering
,
block_map
=
{
problem_name
:
{
'problem'
:
'problem3'
}}
)
self
.
translate_n_check
(
location
,
org
,
new_offering
,
'problemabc'
,
BRANCH_NAME_PUBLISHED
,
True
)
self
.
translate_n_check
(
location
,
org
,
new_offering
,
'problemabc'
,
ModuleStoreEnum
.
BranchName
.
published
,
True
)
# add a new one to both courses (ensure name doesn't have same beginning)
new_prob_name
=
uuid
.
uuid4
()
.
hex
...
...
@@ -246,10 +248,10 @@ class TestLocationMapper(LocMapperSetupSansDjango):
new_prob_name
=
uuid
.
uuid4
()
.
hex
new_prob_locn
=
location
.
replace
(
name
=
new_prob_name
)
new_usage_id
=
'problem{}'
.
format
(
new_prob_name
[:
3
])
self
.
translate_n_check
(
new_prob_locn
,
org
,
new_offering
,
new_usage_id
,
BRANCH_NAME_PUBLISHED
,
True
)
self
.
translate_n_check
(
new_prob_locn
,
org
,
new_offering
,
new_usage_id
,
ModuleStoreEnum
.
BranchName
.
published
,
True
)
new_prob_locn
=
new_prob_locn
.
replace
(
run
=
run
)
self
.
translate_n_check
(
new_prob_locn
,
delta_new_org
,
delta_new_offering
,
new_usage_id
,
BRANCH_NAME_PUBLISHED
,
True
new_prob_locn
,
delta_new_org
,
delta_new_offering
,
new_usage_id
,
ModuleStoreEnum
.
BranchName
.
published
,
True
)
def
test_translate_locator
(
self
):
...
...
@@ -264,7 +266,7 @@ class TestLocationMapper(LocMapperSetupSansDjango):
new_style_offering
=
'{}.{}'
.
format
(
course
,
run
)
prob_course_key
=
CourseLocator
(
org
=
new_style_org
,
offering
=
new_style_offering
,
branch
=
BRANCH_NAME_PUBLISHED
,
branch
=
ModuleStoreEnum
.
BranchName
.
published
,
)
prob_locator
=
BlockUsageLocator
(
prob_course_key
,
...
...
@@ -286,22 +288,22 @@ class TestLocationMapper(LocMapperSetupSansDjango):
# only one course matches
prob_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator
)
# default branch
self
.
assertEqual
(
prob_location
,
Location
(
org
,
course
,
run
,
'problem'
,
'abc123'
,
KEY_REVISION_PUBLISHED
))
self
.
assertEqual
(
prob_location
,
Location
(
org
,
course
,
run
,
'problem'
,
'abc123'
,
MongoRevisionKey
.
published
))
# test get_course keyword
prob_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator
,
get_course
=
True
)
self
.
assertEqual
(
prob_location
,
SlashSeparatedCourseKey
(
org
,
course
,
run
))
# explicit branch
prob_locator
=
prob_locator
.
for_branch
(
BRANCH_NAME_DRAFT
)
prob_locator
=
prob_locator
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
draft
)
prob_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator
)
# Even though the problem was set as draft, we always return revision=
KEY_REVISION_PUBLISHED
to work
# Even though the problem was set as draft, we always return revision=
MongoRevisionKey.published
to work
# with old mongo/draft modulestores.
self
.
assertEqual
(
prob_location
,
Location
(
org
,
course
,
run
,
'problem'
,
'abc123'
,
KEY_REVISION_PUBLISHED
))
self
.
assertEqual
(
prob_location
,
Location
(
org
,
course
,
run
,
'problem'
,
'abc123'
,
MongoRevisionKey
.
published
))
prob_locator
=
BlockUsageLocator
(
prob_course_key
.
for_branch
(
'production'
),
block_type
=
'problem'
,
block_id
=
'problem2'
)
prob_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator
)
self
.
assertEqual
(
prob_location
,
Location
(
org
,
course
,
run
,
'problem'
,
'abc123'
,
KEY_REVISION_PUBLISHED
))
self
.
assertEqual
(
prob_location
,
Location
(
org
,
course
,
run
,
'problem'
,
'abc123'
,
MongoRevisionKey
.
published
))
# same for chapter except chapter cannot be draft in old system
chap_locator
=
BlockUsageLocator
(
prob_course_key
.
for_branch
(
'production'
),
...
...
@@ -310,7 +312,7 @@ class TestLocationMapper(LocMapperSetupSansDjango):
chap_location
=
loc_mapper
()
.
translate_locator_to_location
(
chap_locator
)
self
.
assertEqual
(
chap_location
,
Location
(
org
,
course
,
run
,
'chapter'
,
'48f23a10395384929234'
))
# explicit branch
chap_locator
=
chap_locator
.
for_branch
(
BRANCH_NAME_DRAFT
)
chap_locator
=
chap_locator
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
draft
)
chap_location
=
loc_mapper
()
.
translate_locator_to_location
(
chap_locator
)
self
.
assertEqual
(
chap_location
,
Location
(
org
,
course
,
run
,
'chapter'
,
'48f23a10395384929234'
))
chap_locator
=
BlockUsageLocator
(
...
...
@@ -321,7 +323,7 @@ class TestLocationMapper(LocMapperSetupSansDjango):
# look for non-existent problem
prob_locator2
=
BlockUsageLocator
(
prob_course_key
.
for_branch
(
BRANCH_NAME_DRAFT
),
prob_course_key
.
for_branch
(
ModuleStoreEnum
.
BranchName
.
draft
),
block_type
=
'problem'
,
block_id
=
'problem3'
)
prob_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator2
)
...
...
@@ -336,7 +338,7 @@ class TestLocationMapper(LocMapperSetupSansDjango):
block_map
=
{
'abc123'
:
{
'problem'
:
'problem3'
}}
)
prob_location
=
loc_mapper
()
.
translate_locator_to_location
(
prob_locator
)
self
.
assertEqual
(
prob_location
,
Location
(
org
,
course
,
run
,
'problem'
,
'abc123'
,
KEY_REVISION_PUBLISHED
))
self
.
assertEqual
(
prob_location
,
Location
(
org
,
course
,
run
,
'problem'
,
'abc123'
,
MongoRevisionKey
.
published
))
def
test_special_chars
(
self
):
"""
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py
View file @
91f102c7
...
...
@@ -7,10 +7,7 @@ from collections import namedtuple
from
xmodule.tests
import
DATA_DIR
from
opaque_keys.edx.locations
import
Location
from
xmodule.modulestore
import
(
MONGO_MODULESTORE_TYPE
,
SPLIT_MONGO_MODULESTORE_TYPE
,
XML_MODULESTORE_TYPE
,
REVISION_OPTION_DRAFT_PREFERRED
,
REVISION_OPTION_PUBLISHED_ONLY
,
BRANCH_DRAFT_PREFERRED
)
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
opaque_keys.edx.locator
import
BlockUsageLocator
,
CourseLocator
...
...
@@ -247,12 +244,12 @@ class TestMixedModuleStore(LocMapperSetupSansDjango):
"""
self
.
initdb
(
default_ms
)
self
.
assertEqual
(
self
.
store
.
get_modulestore_type
(
self
.
_course_key_from_string
(
self
.
XML_COURSEID1
)),
XML_MODULESTORE_TYPE
self
.
_course_key_from_string
(
self
.
XML_COURSEID1
)),
ModuleStoreEnum
.
Type
.
xml
)
self
.
assertEqual
(
self
.
store
.
get_modulestore_type
(
self
.
_course_key_from_string
(
self
.
XML_COURSEID2
)),
XML_MODULESTORE_TYPE
self
.
_course_key_from_string
(
self
.
XML_COURSEID2
)),
ModuleStoreEnum
.
Type
.
xml
)
mongo_ms_type
=
M
ONGO_MODULESTORE_TYPE
if
default_ms
==
'draft'
else
SPLIT_MONGO_MODULESTORE_TYPE
mongo_ms_type
=
M
oduleStoreEnum
.
Type
.
mongo
if
default_ms
==
'draft'
else
ModuleStoreEnum
.
Type
.
split
self
.
assertEqual
(
self
.
store
.
get_modulestore_type
(
self
.
_course_key_from_string
(
self
.
MONGO_COURSEID
)),
mongo_ms_type
)
...
...
@@ -352,7 +349,7 @@ class TestMixedModuleStore(LocMapperSetupSansDjango):
Test that the xml modulestore only loaded the courses from the maps.
"""
self
.
initdb
(
'draft'
)
xml_store
=
self
.
store
.
_get_modulestore_by_type
(
XML_MODULESTORE_TYPE
)
xml_store
=
self
.
store
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
xml
)
courses
=
xml_store
.
get_courses
()
self
.
assertEqual
(
len
(
courses
),
2
)
course_ids
=
[
course
.
id
for
course
in
courses
]
...
...
@@ -366,7 +363,7 @@ class TestMixedModuleStore(LocMapperSetupSansDjango):
Test that the xml modulestore doesn't allow write ops.
"""
self
.
initdb
(
'draft'
)
xml_store
=
self
.
store
.
_get_modulestore_by_type
(
XML_MODULESTORE_TYPE
)
xml_store
=
self
.
store
.
_get_modulestore_by_type
(
ModuleStoreEnum
.
Type
.
xml
)
# the important thing is not which exception it raises but that it raises an exception
with
self
.
assertRaises
(
AttributeError
):
xml_store
.
create_course
(
"org"
,
"course/run"
,
999
)
...
...
@@ -420,16 +417,16 @@ class TestMixedModuleStore(LocMapperSetupSansDjango):
self
.
verify_get_parent_locations_results
([
(
child_to_move
,
new_parent
,
None
),
(
child_to_move
,
new_parent
,
REVISION_OPTION_DRAFT_PREFERRED
),
(
child_to_move
,
old_parent
,
REVISION_OPTION_PUBLISHED_ONLY
),
(
child_to_move
,
new_parent
,
ModuleStoreEnum
.
RevisionOption
.
draft_preferred
),
(
child_to_move
,
old_parent
,
ModuleStoreEnum
.
RevisionOption
.
published_only
),
])
# publish the course again
self
.
store
.
publish
(
self
.
course
.
location
,
self
.
user_id
)
self
.
verify_get_parent_locations_results
([
(
child_to_move
,
new_parent
,
None
),
(
child_to_move
,
new_parent
,
REVISION_OPTION_DRAFT_PREFERRED
),
(
child_to_move
,
new_parent
,
REVISION_OPTION_PUBLISHED_ONLY
),
(
child_to_move
,
new_parent
,
ModuleStoreEnum
.
RevisionOption
.
draft_preferred
),
(
child_to_move
,
new_parent
,
ModuleStoreEnum
.
RevisionOption
.
published_only
),
])
@ddt.data
(
'draft'
)
...
...
@@ -451,16 +448,16 @@ class TestMixedModuleStore(LocMapperSetupSansDjango):
self
.
verify_get_parent_locations_results
([
(
child_to_delete
,
old_parent
,
None
),
# Note: The following could be an unexpected result, but we want to avoid an extra database call
(
child_to_delete
,
old_parent
,
REVISION_OPTION_DRAFT_PREFERRED
),
(
child_to_delete
,
old_parent
,
REVISION_OPTION_PUBLISHED_ONLY
),
(
child_to_delete
,
old_parent
,
ModuleStoreEnum
.
RevisionOption
.
draft_preferred
),
(
child_to_delete
,
old_parent
,
ModuleStoreEnum
.
RevisionOption
.
published_only
),
])
# publish the course again
self
.
store
.
publish
(
self
.
course
.
location
,
self
.
user_id
)
self
.
verify_get_parent_locations_results
([
(
child_to_delete
,
None
,
None
),
(
child_to_delete
,
None
,
REVISION_OPTION_DRAFT_PREFERRED
),
(
child_to_delete
,
None
,
REVISION_OPTION_PUBLISHED_ONLY
),
(
child_to_delete
,
None
,
ModuleStoreEnum
.
RevisionOption
.
draft_preferred
),
(
child_to_delete
,
None
,
ModuleStoreEnum
.
RevisionOption
.
published_only
),
])
@ddt.data
(
'draft'
,
'split'
)
...
...
@@ -529,6 +526,6 @@ def create_modulestore_instance(engine, doc_store_config, options, i18n_service=
return
class_
(
doc_store_config
=
doc_store_config
,
branch_setting_func
=
lambda
:
BRANCH_DRAFT_PREFERRED
,
branch_setting_func
=
lambda
:
ModuleStoreEnum
.
Branch
.
draft_preferred
,
**
options
)
common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py
View file @
91f102c7
...
...
@@ -20,7 +20,7 @@ from xblock.plugin import Plugin
from
xmodule.tests
import
DATA_DIR
from
opaque_keys.edx.locations
import
Location
from
xmodule.modulestore
import
M
ONGO_MODULESTORE_TYPE
,
BRANCH_DRAFT_PREFERRED
from
xmodule.modulestore
import
M
oduleStoreEnum
from
xmodule.modulestore.mongo
import
MongoModuleStore
,
MongoKeyValueStore
from
xmodule.modulestore.draft
import
DraftModuleStore
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
,
AssetLocation
...
...
@@ -103,7 +103,7 @@ class TestMongoModuleStore(unittest.TestCase):
draft_store
=
DraftModuleStore
(
doc_store_config
,
FS_ROOT
,
RENDER_TEMPLATE
,
default_class
=
DEFAULT_CLASS
,
branch_setting_func
=
lambda
:
BRANCH_DRAFT_PREFERRED
branch_setting_func
=
lambda
:
ModuleStoreEnum
.
Branch
.
draft_preferred
)
import_from_xml
(
draft_store
,
...
...
@@ -148,7 +148,7 @@ class TestMongoModuleStore(unittest.TestCase):
{
'host'
:
HOST
,
'db'
:
DB
,
'collection'
:
COLLECTION
},
FS_ROOT
,
RENDER_TEMPLATE
,
default_class
=
DEFAULT_CLASS
)
assert_equals
(
store
.
get_modulestore_type
(
''
),
M
ONGO_MODULESTORE_TYPE
)
assert_equals
(
store
.
get_modulestore_type
(
''
),
M
oduleStoreEnum
.
Type
.
mongo
)
def
test_get_courses
(
self
):
'''Make sure the course objects loaded properly'''
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_split_migrator.py
View file @
91f102c7
...
...
@@ -5,7 +5,7 @@ Tests for split_migrator
import
uuid
import
random
import
mock
from
xmodule.modulestore
import
KEY_REVISION_PUBLISHED
from
xmodule.modulestore
.mongo.base
import
MongoRevisionKey
from
xmodule.modulestore.loc_mapper_store
import
LocMapperStore
from
xmodule.modulestore.split_migrator
import
SplitMigrator
from
xmodule.modulestore.tests
import
test_location_mapper
...
...
@@ -178,7 +178,7 @@ class TestMigration(SplitWMongoCourseBoostrapper):
self
.
assertEqual
(
presplit_dag_root
.
location
,
self
.
loc_mapper
.
translate_locator_to_location
(
split_dag_root
.
location
)
.
replace
(
revision
=
KEY_REVISION_PUBLISHED
revision
=
MongoRevisionKey
.
published
)
)
# compare all fields but children
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py
View file @
91f102c7
...
...
@@ -11,7 +11,7 @@ import random
from
xblock.fields
import
Scope
from
xmodule.course_module
import
CourseDescriptor
from
xmodule.modulestore
import
BRANCH_NAME_PUBLISHED
,
BRANCH_NAME_DRAFT
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.exceptions
import
(
InsufficientSpecificationError
,
ItemNotFoundError
,
VersionConflictError
,
DuplicateItemError
,
DuplicateCourseError
)
from
opaque_keys.edx.locator
import
CourseLocator
,
BlockUsageLocator
,
VersionTree
,
LocalId
...
...
@@ -22,6 +22,10 @@ from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore
from
xmodule.modulestore.tests.test_modulestore
import
check_has_course_method
BRANCH_NAME_DRAFT
=
ModuleStoreEnum
.
BranchName
.
draft
BRANCH_NAME_PUBLISHED
=
ModuleStoreEnum
.
BranchName
.
published
class
SplitModuleTest
(
unittest
.
TestCase
):
'''
The base set of tests manually populates a db w/ courses which have
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py
View file @
91f102c7
...
...
@@ -9,7 +9,7 @@ from opaque_keys.edx.locator import CourseLocator, BlockUsageLocator
from
xmodule.modulestore.split_mongo.split
import
SplitMongoModuleStore
from
xmodule.modulestore.mongo
import
MongoModuleStore
,
DraftMongoModuleStore
from
xmodule.modulestore.mongo.draft
import
DIRECT_ONLY_CATEGORIES
from
xmodule.modulestore
import
BRANCH_DRAFT_PREFERRED
,
BRANCH_NAME_DRAFT
from
xmodule.modulestore
import
ModuleStoreEnum
from
mock
import
Mock
...
...
@@ -41,7 +41,7 @@ class SplitWMongoCourseBoostrapper(unittest.TestCase):
'xblock_mixins'
:
(
InheritanceMixin
,)
}
split_course_key
=
CourseLocator
(
'test_org'
,
'test_course.runid'
,
branch
=
BRANCH_NAME_DRAFT
)
split_course_key
=
CourseLocator
(
'test_org'
,
'test_course.runid'
,
branch
=
ModuleStoreEnum
.
BranchName
.
draft
)
def
setUp
(
self
):
self
.
db_config
[
'collection'
]
=
'modulestore{0}'
.
format
(
uuid
.
uuid4
()
.
hex
[:
5
])
...
...
@@ -56,7 +56,7 @@ class SplitWMongoCourseBoostrapper(unittest.TestCase):
self
.
addCleanup
(
self
.
tear_down_split
)
self
.
old_mongo
=
MongoModuleStore
(
self
.
db_config
,
**
self
.
modulestore_options
)
self
.
draft_mongo
=
DraftMongoModuleStore
(
self
.
db_config
,
branch_setting_func
=
lambda
:
BRANCH_DRAFT_PREFERRED
,
**
self
.
modulestore_options
self
.
db_config
,
branch_setting_func
=
lambda
:
ModuleStoreEnum
.
Branch
.
draft_preferred
,
**
self
.
modulestore_options
)
self
.
addCleanup
(
self
.
tear_down_mongo
)
self
.
old_course_key
=
None
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_xml.py
View file @
91f102c7
...
...
@@ -9,7 +9,7 @@ from mock import patch
from
xmodule.modulestore.xml
import
XMLModuleStore
from
opaque_keys.edx.locations
import
Location
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
.test_modulestore
import
check_path_to_location
from
xmodule.tests
import
DATA_DIR
...
...
@@ -43,7 +43,7 @@ class TestXMLModuleStore(unittest.TestCase):
def
test_xml_modulestore_type
(
self
):
store
=
XMLModuleStore
(
DATA_DIR
,
course_dirs
=
[
'toy'
,
'simple'
])
self
.
assertEqual
(
store
.
get_modulestore_type
(),
XML_MODULESTORE_TYPE
)
self
.
assertEqual
(
store
.
get_modulestore_type
(),
ModuleStoreEnum
.
Type
.
xml
)
def
test_unicode_chars_in_xml_content
(
self
):
# edX/full/6.002_Spring_2012 has non-ASCII chars, and during
...
...
common/lib/xmodule/xmodule/modulestore/xml.py
View file @
91f102c7
...
...
@@ -19,7 +19,7 @@ from xmodule.errortracker import make_error_tracker, exc_info_to_str
from
xmodule.mako_module
import
MakoDescriptorSystem
from
xmodule.x_module
import
XMLParsingSystem
,
policy_key
from
xmodule.modulestore.xml_exporter
import
DEFAULT_CONTENT_FIELDS
from
xmodule.modulestore
import
REVISION_OPTION_PUBLISHED_ONLY
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.tabs
import
CourseTabList
from
opaque_keys.edx.keys
import
UsageKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
...
...
@@ -27,7 +27,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from
xblock.field_data
import
DictFieldData
from
xblock.runtime
import
DictKeyValueStore
,
IdGenerator
from
.
import
ModuleStoreReadBase
,
Location
,
XML_MODULESTORE_TYPE
from
.
import
ModuleStoreReadBase
,
Location
,
ModuleStoreEnum
from
.exceptions
import
ItemNotFoundError
from
.inheritance
import
compute_inherited_metadata
,
inheriting_field_data
...
...
@@ -411,7 +411,7 @@ class XMLModuleStore(ModuleStoreReadBase):
self
.
i18n_service
=
i18n_service
# The XML Module Store is a read-only store and only handles published content
self
.
branch_setting_func
=
lambda
:
REVISION_OPTION_PUBLISHED_ONLY
self
.
branch_setting_func
=
lambda
:
ModuleStoreEnum
.
RevisionOption
.
published_only
# If we are specifically asked for missing courses, that should
# be an error. If we are asked for "all" courses, find the ones
...
...
@@ -800,16 +800,11 @@ class XMLModuleStore(ModuleStoreReadBase):
def
get_modulestore_type
(
self
,
course_key
=
None
):
"""
Returns an enumeration-like type reflecting the type of this modulestore
The return can be one of:
"xml" (for XML based courses),
"mongo" for old-style MongoDB backed courses,
"split" for new-style split MongoDB backed courses.
Returns an enumeration-like type reflecting the type of this modulestore, per ModuleStoreEnum.Type
Args:
course_key: just for signature compatibility
"""
return
XML_MODULESTORE_TYPE
return
ModuleStoreEnum
.
Type
.
xml
def
get_courses_for_wiki
(
self
,
wiki_slug
):
"""
...
...
@@ -827,5 +822,5 @@ class XMLModuleStore(ModuleStoreReadBase):
Returns the course count
"""
return
{
XML_MODULESTORE_TYPE
:
True
}
return
{
ModuleStoreEnum
.
Type
.
xml
:
True
}
common/lib/xmodule/xmodule/modulestore/xml_exporter.py
View file @
91f102c7
...
...
@@ -7,9 +7,7 @@ import lxml.etree
from
xblock.fields
import
Scope
from
xmodule.contentstore.content
import
StaticContent
from
xmodule.exceptions
import
NotFoundError
from
xmodule.modulestore
import
(
EdxJSONEncoder
,
BRANCH_PUBLISHED_ONLY
,
REVISION_OPTION_DRAFT_PREFERRED
,
REVISION_OPTION_DRAFT_ONLY
)
from
xmodule.modulestore
import
EdxJSONEncoder
,
ModuleStoreEnum
from
xmodule.modulestore.inheritance
import
own_metadata
from
xmodule.modulestore.mixed
import
store_branch_setting
from
fs.osfs
import
OSFS
...
...
@@ -47,7 +45,7 @@ def export_to_xml(modulestore, contentstore, course_key, root_dir, course_dir):
root
=
lxml
.
etree
.
Element
(
'unknown'
)
# export only the published content
with
store_branch_setting
(
course
.
runtime
.
modulestore
,
BRANCH_PUBLISHED_ONLY
):
with
store_branch_setting
(
course
.
runtime
.
modulestore
,
ModuleStoreEnum
.
Branch
.
published_only
):
course
.
add_xml_to_node
(
root
)
with
export_fs
.
open
(
'course.xml'
,
'w'
)
as
course_xml
:
...
...
@@ -107,11 +105,18 @@ def export_to_xml(modulestore, contentstore, course_key, root_dir, course_dir):
# should we change the application, then this assumption will no longer be valid
# NOTE: we need to explicitly implement the logic for setting the vertical's parent
# and index here since the XML modulestore cannot load draft modules
draft_verticals
=
modulestore
.
get_items
(
course_key
,
category
=
'vertical'
,
revision
=
REVISION_OPTION_DRAFT_ONLY
)
draft_verticals
=
modulestore
.
get_items
(
course_key
,
category
=
'vertical'
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_only
)
if
len
(
draft_verticals
)
>
0
:
draft_course_dir
=
export_fs
.
makeopendir
(
DRAFT_DIR
)
for
draft_vertical
in
draft_verticals
:
parent_loc
=
modulestore
.
get_parent_location
(
draft_vertical
.
location
,
revision
=
REVISION_OPTION_DRAFT_PREFERRED
)
parent_loc
=
modulestore
.
get_parent_location
(
draft_vertical
.
location
,
revision
=
ModuleStoreEnum
.
RevisionOption
.
draft_preferred
)
# Don't try to export orphaned items.
if
parent_loc
is
not
None
:
logging
.
debug
(
'parent_loc = {0}'
.
format
(
parent_loc
))
...
...
common/lib/xmodule/xmodule/modulestore/xml_importer.py
View file @
91f102c7
...
...
@@ -17,7 +17,7 @@ from .store_utilities import rewrite_nonportable_content_links
import
xblock
from
xmodule.tabs
import
CourseTabList
from
xmodule.modulestore.exceptions
import
InvalidLocationError
from
xmodule.modulestore
import
KEY_REVISION_PUBLISHED
,
KEY_REVISION_DRAFT
from
xmodule.modulestore
.mongo.base
import
MongoRevisionKey
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -505,14 +505,14 @@ def _import_course_draft(
# Update the module's location to DRAFT revision
# We need to call this method (instead of updating the location directly)
# to ensure that pure XBlock field data is updated correctly.
_update_module_location
(
module
,
module
.
location
.
replace
(
revision
=
KEY_REVISION_DRAFT
))
_update_module_location
(
module
,
module
.
location
.
replace
(
revision
=
MongoRevisionKey
.
draft
))
# make sure our parent has us in its list of children
# this is to make sure private only verticals show up
# in the list of children since they would have been
# filtered out from the non-draft store export
if
module
.
location
.
category
==
'vertical'
:
non_draft_location
=
module
.
location
.
replace
(
revision
=
KEY_REVISION_PUBLISHED
)
non_draft_location
=
module
.
location
.
replace
(
revision
=
MongoRevisionKey
.
published
)
sequential_url
=
module
.
xml_attributes
[
'parent_sequential_url'
]
index
=
int
(
module
.
xml_attributes
[
'index_in_children_list'
])
...
...
lms/djangoapps/bulk_email/forms.py
View file @
91f102c7
...
...
@@ -9,7 +9,7 @@ from django.core.exceptions import ValidationError
from
bulk_email.models
import
CourseEmailTemplate
,
COURSE_EMAIL_MESSAGE_BODY_TAG
,
CourseAuthorization
from
opaque_keys
import
InvalidKeyError
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
...
...
@@ -78,7 +78,7 @@ class CourseAuthorizationAdminForm(forms.ModelForm): # pylint: disable=R0924
raise
forms
.
ValidationError
(
msg
)
# Now, try and discern if it is a Studio course - HTML editor doesn't work with XML courses
is_studio_course
=
modulestore
()
.
get_modulestore_type
(
course_key
)
!=
XML_MODULESTORE_TYPE
is_studio_course
=
modulestore
()
.
get_modulestore_type
(
course_key
)
!=
ModuleStoreEnum
.
Type
.
xml
if
not
is_studio_course
:
msg
=
"Course Email feature is only available for courses authored in Studio. "
msg
+=
'"{0}" appears to be an XML backed course.'
.
format
(
course_key
.
to_deprecated_string
())
...
...
lms/djangoapps/bulk_email/tests/test_forms.py
View file @
91f102c7
...
...
@@ -11,7 +11,7 @@ from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
from
courseware.tests.modulestore_config
import
TEST_DATA_MIXED_MODULESTORE
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
mock
import
patch
...
...
@@ -132,7 +132,7 @@ class CourseAuthorizationXMLFormTest(ModuleStoreTestCase):
def
test_xml_course_authorization
(
self
):
course_id
=
SlashSeparatedCourseKey
(
'edX'
,
'toy'
,
'2012_Fall'
)
# Assert this is an XML course
self
.
assertEqual
(
modulestore
()
.
get_modulestore_type
(
course_id
),
XML_MODULESTORE_TYPE
)
self
.
assertEqual
(
modulestore
()
.
get_modulestore_type
(
course_id
),
ModuleStoreEnum
.
Type
.
xml
)
form_data
=
{
'course_id'
:
course_id
.
to_deprecated_string
(),
'email_enabled'
:
True
}
form
=
CourseAuthorizationAdminForm
(
data
=
form_data
)
...
...
lms/djangoapps/courseware/courses.py
View file @
91f102c7
...
...
@@ -8,13 +8,13 @@ from django.http import Http404
from
django.conf
import
settings
from
edxmako.shortcuts
import
render_to_string
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
opaque_keys.edx.keys
import
CourseKey
from
xmodule.modulestore.django
import
modulestore
from
xmodule.contentstore.content
import
StaticContent
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
static_replace
import
replace_static_urls
from
xmodule.modulestore
import
M
ONGO_MODULESTORE_TYPE
from
xmodule.modulestore
import
M
oduleStoreEnum
from
xmodule.x_module
import
STUDENT_VIEW
from
courseware.access
import
has_access
...
...
@@ -106,7 +106,7 @@ def get_opt_course_with_access(user, action, course_key):
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
course
.
static_asset_path
or
modulestore
()
.
get_modulestore_type
(
course
.
id
)
==
XML_MODULESTORE_TYPE
:
if
course
.
static_asset_path
or
modulestore
()
.
get_modulestore_type
(
course
.
id
)
==
ModuleStoreEnum
.
Type
.
xml
:
# If we are a static course with the course_image attribute
# set different than the default, return that path so that
# courses can use custom course image paths, otherwise just
...
...
@@ -369,7 +369,7 @@ def get_studio_url(course_key, page):
assert
(
isinstance
(
course_key
,
CourseKey
))
course
=
get_course_by_id
(
course_key
)
is_studio_course
=
course
.
course_edit_method
==
"Studio"
is_mongo_course
=
modulestore
()
.
get_modulestore_type
(
course_key
)
==
M
ONGO_MODULESTORE_TYPE
is_mongo_course
=
modulestore
()
.
get_modulestore_type
(
course_key
)
==
M
oduleStoreEnum
.
Type
.
mongo
studio_link
=
None
if
is_studio_course
and
is_mongo_course
:
studio_link
=
get_cms_course_link
(
course
,
page
)
...
...
lms/djangoapps/courseware/tests/test_courses.py
View file @
91f102c7
...
...
@@ -7,7 +7,7 @@ import mock
from
django.test.utils
import
override_settings
from
student.tests.factories
import
UserFactory
import
xmodule.modulestore.django
as
store_django
from
xmodule.modulestore
import
BRANCH_DRAFT_PREFERRED
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.tests.xml
import
factories
as
xml
...
...
@@ -62,18 +62,18 @@ class ModuleStoreBranchSettingTest(ModuleStoreTestCase):
mock
.
Mock
(
return_value
=
'preview.localhost'
)
)
@override_settings
(
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS
=
{
r'preview\.'
:
BRANCH_DRAFT_PREFERRED
},
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS
=
{
r'preview\.'
:
ModuleStoreEnum
.
Branch
.
draft_preferred
},
MODULESTORE_BRANCH
=
'fake_default_branch'
,
)
def
test_default_modulestore_preview_mapping
(
self
):
self
.
assertEqual
(
store_django
.
_get_modulestore_branch_setting
(),
BRANCH_DRAFT_PREFERRED
)
self
.
assertEqual
(
store_django
.
_get_modulestore_branch_setting
(),
ModuleStoreEnum
.
Branch
.
draft_preferred
)
@mock.patch
(
'xmodule.modulestore.django.get_current_request_hostname'
,
mock
.
Mock
(
return_value
=
'localhost'
)
)
@override_settings
(
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS
=
{
r'preview\.'
:
BRANCH_DRAFT_PREFERRED
},
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS
=
{
r'preview\.'
:
ModuleStoreEnum
.
Branch
.
draft_preferred
},
MODULESTORE_BRANCH
=
'fake_default_branch'
,
)
def
test_default_modulestore_branch_mapping
(
self
):
...
...
lms/djangoapps/courseware/tests/test_lti_integration.py
View file @
91f102c7
...
...
@@ -10,7 +10,7 @@ from django.test.utils import override_settings
from
django.core.urlresolvers
import
reverse
from
django.conf
import
settings
from
xmodule.modulestore
import
KEY_REVISION_DRAFT
from
xmodule.modulestore
.mongo.base
import
MongoRevisionKey
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
ItemFactory
from
xmodule.x_module
import
STUDENT_VIEW
...
...
@@ -160,7 +160,7 @@ class TestLTIModuleListing(ModuleStoreTestCase):
parent_location
=
self
.
section2
.
location
,
display_name
=
"lti draft"
,
category
=
"lti"
,
location
=
self
.
course
.
id
.
make_usage_key
(
'lti'
,
'lti_published'
)
.
replace
(
revision
=
KEY_REVISION_DRAFT
),
location
=
self
.
course
.
id
.
make_usage_key
(
'lti'
,
'lti_published'
)
.
replace
(
revision
=
MongoRevisionKey
.
draft
),
)
def
expected_handler_url
(
self
,
handler
):
...
...
lms/djangoapps/dashboard/sysadmin.py
View file @
91f102c7
...
...
@@ -39,7 +39,7 @@ from external_auth.views import generate_password
from
student.models
import
CourseEnrollment
,
UserProfile
,
Registration
import
track.views
from
xmodule.contentstore.django
import
contentstore
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.store_utilities
import
delete_course
from
xmodule.modulestore.xml
import
XMLModuleStore
...
...
@@ -573,7 +573,7 @@ class Courses(SysadminDashboardView):
escape
(
str
(
err
))
)
is_xml_course
=
(
modulestore
()
.
get_modulestore_type
(
course_key
)
==
XML_MODULESTORE_TYPE
)
is_xml_course
=
(
modulestore
()
.
get_modulestore_type
(
course_key
)
==
ModuleStoreEnum
.
Type
.
xml
)
if
course_found
and
is_xml_course
:
cdir
=
course
.
data_dir
self
.
def_ms
.
courses
.
pop
(
cdir
)
...
...
lms/djangoapps/instructor/tests/test_legacy_email.py
View file @
91f102c7
...
...
@@ -12,7 +12,7 @@ from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
from
student.tests.factories
import
AdminFactory
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
bulk_email.models
import
CourseAuthorization
...
...
@@ -103,7 +103,7 @@ class TestInstructorDashboardEmailView(ModuleStoreTestCase):
# in `instructor/views/legacy.py` is doing the correct thing.
with
patch
(
'xmodule.modulestore.mongo.base.MongoModuleStore.get_modulestore_type'
)
as
mock_modulestore
:
mock_modulestore
.
return_value
=
XML_MODULESTORE_TYPE
mock_modulestore
.
return_value
=
ModuleStoreEnum
.
Type
.
xml
# Assert that the URL for the email view is not in the response
response
=
self
.
client
.
get
(
self
.
url
)
...
...
lms/djangoapps/instructor/views/instructor_dashboard.py
View file @
91f102c7
...
...
@@ -15,7 +15,7 @@ from django.conf import settings
from
lms.lib.xblock.runtime
import
quote_slashes
from
xmodule_modifiers
import
wrap_xblock
from
xmodule.html_module
import
HtmlDescriptor
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
xblock.field_data
import
DictFieldData
from
xblock.fields
import
ScopeIds
...
...
@@ -37,7 +37,7 @@ def instructor_dashboard_2(request, course_id):
""" Display the instructor dashboard for a course. """
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course
=
get_course_by_id
(
course_key
,
depth
=
None
)
is_studio_course
=
(
modulestore
()
.
get_modulestore_type
(
course_key
)
!=
XML_MODULESTORE_TYPE
)
is_studio_course
=
(
modulestore
()
.
get_modulestore_type
(
course_key
)
!=
ModuleStoreEnum
.
Type
.
xml
)
access
=
{
'admin'
:
request
.
user
.
is_staff
,
...
...
lms/djangoapps/instructor/views/legacy.py
View file @
91f102c7
...
...
@@ -28,7 +28,7 @@ from django.utils import timezone
from
xmodule_modifiers
import
wrap_xblock
import
xmodule.graders
as
xmgraders
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
...
...
@@ -968,7 +968,7 @@ def instructor_dashboard(request, course_id):
instructor_tasks
=
None
# determine if this is a studio-backed course so we can provide a link to edit this course in studio
is_studio_course
=
modulestore
()
.
get_modulestore_type
(
course_key
)
!=
XML_MODULESTORE_TYPE
is_studio_course
=
modulestore
()
.
get_modulestore_type
(
course_key
)
!=
ModuleStoreEnum
.
Type
.
xml
studio_url
=
None
if
is_studio_course
:
studio_url
=
get_cms_course_link
(
course
)
...
...
lms/djangoapps/instructor/views/tools.py
View file @
91f102c7
...
...
@@ -12,7 +12,7 @@ from django.utils.translation import ugettext as _
from
courseware.models
import
StudentModule
from
xmodule.fields
import
Date
from
xmodule.modulestore
import
XML_MODULESTORE_TYPE
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
bulk_email.models
import
CourseAuthorization
...
...
@@ -59,7 +59,7 @@ def bulk_email_is_enabled_for_course(course_id):
"""
bulk_email_enabled_globally
=
(
settings
.
FEATURES
[
'ENABLE_INSTRUCTOR_EMAIL'
]
==
True
)
is_studio_course
=
(
modulestore
()
.
get_modulestore_type
(
course_id
)
!=
XML_MODULESTORE_TYPE
)
is_studio_course
=
(
modulestore
()
.
get_modulestore_type
(
course_id
)
!=
ModuleStoreEnum
.
Type
.
xml
)
bulk_email_enabled_for_course
=
CourseAuthorization
.
instructor_email_enabled
(
course_id
)
if
bulk_email_enabled_globally
and
is_studio_course
and
bulk_email_enabled_for_course
:
...
...
lms/envs/cms/dev.py
View file @
91f102c7
...
...
@@ -44,5 +44,5 @@ DEBUG_TOOLBAR_PANELS += (
# what the 'default' modulestore to use while processing the request
# for example 'preview.edx.org' should use the draft modulestore
HOSTNAME_MODULESTORE_DEFAULT_MAPPINGS
=
{
'preview
\
.'
:
'draft'
'preview
\
.'
:
'draft
-preferred
'
}
lms/envs/common.py
View file @
91f102c7
...
...
@@ -475,7 +475,7 @@ XBLOCK_SELECT_FUNCTION = prefer_xmodules
############# ModuleStore Configuration ##########
MODULESTORE_BRANCH
=
'published'
MODULESTORE_BRANCH
=
'published
-only
'
CONTENTSTORE
=
None
DOC_STORE_CONFIG
=
{
'host'
:
'localhost'
,
...
...
lms/envs/test.py
View file @
91f102c7
...
...
@@ -109,7 +109,7 @@ STATICFILES_DIRS += [
if
os
.
path
.
isdir
(
COMMON_TEST_DATA_ROOT
/
course_dir
)
]
MODULESTORE_BRANCH
=
'draft'
MODULESTORE_BRANCH
=
'draft
-preferred
'
update_module_store_settings
(
MODULESTORE
,
module_store_options
=
{
...
...
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