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
f5abef88
Commit
f5abef88
authored
Jul 07, 2014
by
Nimisha Asthagiri
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
LMS-2947 remove get_error_courses in Split.
LMS-2950 move delete_course to Mongo.
parent
545cfd84
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
104 additions
and
107 deletions
+104
-107
cms/djangoapps/contentstore/management/commands/clone_course.py
+2
-1
cms/djangoapps/contentstore/management/commands/delete_course.py
+4
-4
cms/djangoapps/contentstore/management/commands/import.py
+2
-2
cms/djangoapps/contentstore/tests/test_contentstore.py
+7
-8
cms/djangoapps/contentstore/tests/test_course_listing.py
+3
-3
cms/djangoapps/contentstore/tests/test_crud.py
+1
-1
cms/djangoapps/contentstore/tests/test_users_default_role.py
+3
-3
cms/djangoapps/contentstore/utils.py
+12
-16
cms/djangoapps/contentstore/views/tabs.py
+3
-2
common/djangoapps/student/tests/test_course_listing.py
+1
-1
common/lib/xmodule/xmodule/modulestore/__init__.py
+43
-1
common/lib/xmodule/xmodule/modulestore/mixed.py
+3
-16
common/lib/xmodule/xmodule/modulestore/mongo/base.py
+0
-9
common/lib/xmodule/xmodule/modulestore/mongo/draft.py
+12
-0
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
+5
-8
common/lib/xmodule/xmodule/modulestore/store_utilities.py
+0
-22
lms/djangoapps/dashboard/management/commands/tests/test_git_add_course.py
+2
-5
lms/djangoapps/dashboard/sysadmin.py
+1
-5
No files found.
cms/djangoapps/contentstore/management/commands/clone_course.py
View file @
f5abef88
...
@@ -7,6 +7,7 @@ from student.roles import CourseInstructorRole, CourseStaffRole
...
@@ -7,6 +7,7 @@ from student.roles import CourseInstructorRole, CourseStaffRole
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys
import
InvalidKeyError
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.modulestore
import
ModuleStoreEnum
#
#
...
@@ -38,7 +39,7 @@ class Command(BaseCommand):
...
@@ -38,7 +39,7 @@ class Command(BaseCommand):
print
(
"Cloning course {0} to {1}"
.
format
(
source_course_id
,
dest_course_id
))
print
(
"Cloning course {0} to {1}"
.
format
(
source_course_id
,
dest_course_id
))
with
mstore
.
bulk_write_operations
(
dest_course_id
):
with
mstore
.
bulk_write_operations
(
dest_course_id
):
if
mstore
.
clone_course
(
source_course_id
,
dest_course_id
,
None
):
if
mstore
.
clone_course
(
source_course_id
,
dest_course_id
,
ModuleStoreEnum
.
UserID
.
mgmt_command
):
print
(
"copying User permissions..."
)
print
(
"copying User permissions..."
)
# purposely avoids auth.add_user b/c it doesn't have a caller to authorize
# purposely avoids auth.add_user b/c it doesn't have a caller to authorize
CourseInstructorRole
(
dest_course_id
)
.
add_users
(
CourseInstructorRole
(
dest_course_id
)
.
add_users
(
...
...
cms/djangoapps/contentstore/management/commands/delete_course.py
View file @
f5abef88
...
@@ -7,7 +7,7 @@ from contentstore.utils import delete_course_and_groups
...
@@ -7,7 +7,7 @@ from contentstore.utils import delete_course_and_groups
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys
import
InvalidKeyError
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.modulestore
import
ModuleStoreEnum
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
help
=
'''Delete a MongoDB backed course'''
help
=
'''Delete a MongoDB backed course'''
...
@@ -28,6 +28,6 @@ class Command(BaseCommand):
...
@@ -28,6 +28,6 @@ class Command(BaseCommand):
if
commit
:
if
commit
:
print
(
'Actually going to delete the course from DB....'
)
print
(
'Actually going to delete the course from DB....'
)
if
query_yes_no
(
"Deleting course {0}. Confirm?"
.
format
(
course_key
),
default
=
"no"
):
if
query_yes_no
(
"Deleting course {0}. Confirm?"
.
format
(
course_key
),
default
=
"no"
):
if
query_yes_no
(
"Are you sure. This action cannot be undone!"
,
default
=
"no"
):
if
query_yes_no
(
"Are you sure. This action cannot be undone!"
,
default
=
"no"
):
delete_course_and_groups
(
course_key
,
commit
)
delete_course_and_groups
(
course_key
,
ModuleStoreEnum
.
UserID
.
mgmt_command
)
cms/djangoapps/contentstore/management/commands/import.py
View file @
f5abef88
...
@@ -8,6 +8,7 @@ from django_comment_common.utils import (seed_permissions_roles,
...
@@ -8,6 +8,7 @@ from django_comment_common.utils import (seed_permissions_roles,
from
xmodule.modulestore.xml_importer
import
import_from_xml
from
xmodule.modulestore.xml_importer
import
import_from_xml
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.contentstore.django
import
contentstore
from
xmodule.contentstore.django
import
contentstore
from
xmodule.modulestore
import
ModuleStoreEnum
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
...
@@ -37,10 +38,9 @@ class Command(BaseCommand):
...
@@ -37,10 +38,9 @@ class Command(BaseCommand):
data
=
data_dir
,
data
=
data_dir
,
courses
=
course_dirs
,
courses
=
course_dirs
,
dis
=
do_import_static
))
dis
=
do_import_static
))
mstore
=
modulestore
()
_
,
course_items
=
import_from_xml
(
_
,
course_items
=
import_from_xml
(
m
store
,
"**replace_user**"
,
data_dir
,
course_dirs
,
load_error_modules
=
False
,
m
odulestore
(),
ModuleStoreEnum
.
UserID
.
mgmt_command
,
data_dir
,
course_dirs
,
load_error_modules
=
False
,
static_content_store
=
contentstore
(),
verbose
=
True
,
static_content_store
=
contentstore
(),
verbose
=
True
,
do_import_static
=
do_import_static
,
do_import_static
=
do_import_static
,
create_new_course_if_not_present
=
True
,
create_new_course_if_not_present
=
True
,
...
...
cms/djangoapps/contentstore/tests/test_contentstore.py
View file @
f5abef88
...
@@ -30,7 +30,6 @@ from xmodule.modulestore.exceptions import ItemNotFoundError
...
@@ -30,7 +30,6 @@ from xmodule.modulestore.exceptions import ItemNotFoundError
from
xmodule.modulestore.inheritance
import
own_metadata
from
xmodule.modulestore.inheritance
import
own_metadata
from
opaque_keys.edx.keys
import
UsageKey
from
opaque_keys.edx.keys
import
UsageKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
,
AssetLocation
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
,
AssetLocation
from
xmodule.modulestore.store_utilities
import
delete_course
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
ItemFactory
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
ItemFactory
from
xmodule.modulestore.xml_exporter
import
export_to_xml
from
xmodule.modulestore.xml_exporter
import
export_to_xml
from
xmodule.modulestore.xml_importer
import
import_from_xml
,
perform_xlint
from
xmodule.modulestore.xml_importer
import
import_from_xml
,
perform_xlint
...
@@ -632,7 +631,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
...
@@ -632,7 +631,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
self
.
store
.
convert_to_draft
(
vertical
.
location
,
self
.
user
.
id
)
self
.
store
.
convert_to_draft
(
vertical
.
location
,
self
.
user
.
id
)
# delete the course
# delete the course
delete_course
(
self
.
store
,
content_store
,
course_id
,
commit
=
True
)
self
.
store
.
delete_course
(
course_id
,
self
.
user
.
id
)
# assert that there's absolutely no non-draft modules in the course
# assert that there's absolutely no non-draft modules in the course
# this should also include all draft items
# this should also include all draft items
...
@@ -697,7 +696,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
...
@@ -697,7 +696,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
self
.
assertEqual
(
on_disk
[
'course/2012_Fall'
],
own_metadata
(
course
))
self
.
assertEqual
(
on_disk
[
'course/2012_Fall'
],
own_metadata
(
course
))
# remove old course
# remove old course
delete_course
(
self
.
store
,
content_store
,
course_id
,
commit
=
True
)
self
.
store
.
delete_course
(
course_id
,
self
.
user
.
id
)
# reimport over old course
# reimport over old course
self
.
check_import
(
root_dir
,
content_store
,
course_id
)
self
.
check_import
(
root_dir
,
content_store
,
course_id
)
...
@@ -909,7 +908,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
...
@@ -909,7 +908,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
# Delete the course from module store and reimport it
# Delete the course from module store and reimport it
delete_course
(
self
.
store
,
content_store
,
course_id
,
commit
=
True
)
self
.
store
.
delete_course
(
course_id
,
self
.
user
.
id
)
import_from_xml
(
import_from_xml
(
self
.
store
,
self
.
user
.
id
,
root_dir
,
[
'test_export_no_content_store'
],
self
.
store
,
self
.
user
.
id
,
root_dir
,
[
'test_export_no_content_store'
],
...
@@ -997,7 +996,7 @@ class ContentStoreTest(ContentStoreTestCase):
...
@@ -997,7 +996,7 @@ class ContentStoreTest(ContentStoreTestCase):
test_course_data
=
self
.
assert_created_course
(
number_suffix
=
uuid4
()
.
hex
)
test_course_data
=
self
.
assert_created_course
(
number_suffix
=
uuid4
()
.
hex
)
course_id
=
_get_course_id
(
test_course_data
)
course_id
=
_get_course_id
(
test_course_data
)
self
.
assertTrue
(
are_permissions_roles_seeded
(
course_id
))
self
.
assertTrue
(
are_permissions_roles_seeded
(
course_id
))
delete_course_and_groups
(
course_id
,
commit
=
True
)
delete_course_and_groups
(
course_id
,
self
.
user
.
id
)
# should raise an exception for checking permissions on deleted course
# should raise an exception for checking permissions on deleted course
with
self
.
assertRaises
(
ItemNotFoundError
):
with
self
.
assertRaises
(
ItemNotFoundError
):
are_permissions_roles_seeded
(
course_id
)
are_permissions_roles_seeded
(
course_id
)
...
@@ -1009,7 +1008,7 @@ class ContentStoreTest(ContentStoreTestCase):
...
@@ -1009,7 +1008,7 @@ class ContentStoreTest(ContentStoreTestCase):
# unseed the forums for the first course
# unseed the forums for the first course
course_id
=
_get_course_id
(
test_course_data
)
course_id
=
_get_course_id
(
test_course_data
)
delete_course_and_groups
(
course_id
,
commit
=
True
)
delete_course_and_groups
(
course_id
,
self
.
user
.
id
)
# should raise an exception for checking permissions on deleted course
# should raise an exception for checking permissions on deleted course
with
self
.
assertRaises
(
ItemNotFoundError
):
with
self
.
assertRaises
(
ItemNotFoundError
):
are_permissions_roles_seeded
(
course_id
)
are_permissions_roles_seeded
(
course_id
)
...
@@ -1029,7 +1028,7 @@ class ContentStoreTest(ContentStoreTestCase):
...
@@ -1029,7 +1028,7 @@ class ContentStoreTest(ContentStoreTestCase):
self
.
assertTrue
(
CourseEnrollment
.
is_enrolled
(
self
.
user
,
course_id
))
self
.
assertTrue
(
CourseEnrollment
.
is_enrolled
(
self
.
user
,
course_id
))
self
.
assertTrue
(
self
.
user
.
roles
.
filter
(
name
=
"Student"
,
course_id
=
course_id
))
# pylint: disable=no-member
self
.
assertTrue
(
self
.
user
.
roles
.
filter
(
name
=
"Student"
,
course_id
=
course_id
))
# pylint: disable=no-member
delete_course_and_groups
(
course_id
,
commit
=
True
)
delete_course_and_groups
(
course_id
,
self
.
user
.
id
)
# check that user's enrollment for this course is not deleted
# check that user's enrollment for this course is not deleted
self
.
assertTrue
(
CourseEnrollment
.
is_enrolled
(
self
.
user
,
course_id
))
self
.
assertTrue
(
CourseEnrollment
.
is_enrolled
(
self
.
user
,
course_id
))
# check that user has form role "Student" for this course even after deleting it
# check that user has form role "Student" for this course even after deleting it
...
@@ -1051,7 +1050,7 @@ class ContentStoreTest(ContentStoreTestCase):
...
@@ -1051,7 +1050,7 @@ class ContentStoreTest(ContentStoreTestCase):
self
.
assertTrue
(
len
(
instructor_role
.
users_with_role
())
>
0
)
self
.
assertTrue
(
len
(
instructor_role
.
users_with_role
())
>
0
)
# Now delete course and check that user not in instructor groups of this course
# Now delete course and check that user not in instructor groups of this course
delete_course_and_groups
(
course_id
,
commit
=
True
)
delete_course_and_groups
(
course_id
,
self
.
user
.
id
)
# Update our cached user since its roles have changed
# Update our cached user since its roles have changed
self
.
user
=
User
.
objects
.
get_by_natural_key
(
self
.
user
.
natural_key
()[
0
])
self
.
user
=
User
.
objects
.
get_by_natural_key
(
self
.
user
.
natural_key
()[
0
])
...
...
cms/djangoapps/contentstore/tests/test_course_listing.py
View file @
f5abef88
...
@@ -145,7 +145,7 @@ class TestCourseListing(ModuleStoreTestCase):
...
@@ -145,7 +145,7 @@ class TestCourseListing(ModuleStoreTestCase):
self
.
assertEqual
(
courses_list
,
courses_list_by_groups
)
self
.
assertEqual
(
courses_list
,
courses_list_by_groups
)
# now delete this course and re-add user to instructor group of this course
# now delete this course and re-add user to instructor group of this course
delete_course_and_groups
(
course_key
,
commit
=
True
)
delete_course_and_groups
(
course_key
,
self
.
user
.
id
)
CourseInstructorRole
(
course_key
)
.
add_users
(
self
.
user
)
CourseInstructorRole
(
course_key
)
.
add_users
(
self
.
user
)
...
@@ -237,7 +237,7 @@ class TestCourseListing(ModuleStoreTestCase):
...
@@ -237,7 +237,7 @@ class TestCourseListing(ModuleStoreTestCase):
self
.
assertEqual
(
len
(
courses_list_by_groups
),
2
)
self
.
assertEqual
(
len
(
courses_list_by_groups
),
2
)
# now delete first course (course_location_caps) and check that it is no longer accessible
# now delete first course (course_location_caps) and check that it is no longer accessible
delete_course_and_groups
(
course_location_caps
,
commit
=
True
)
delete_course_and_groups
(
course_location_caps
,
self
.
user
.
id
)
# test that get courses through iterating all courses now returns one course
# test that get courses through iterating all courses now returns one course
courses_list
=
_accessible_courses_list
(
self
.
request
)
courses_list
=
_accessible_courses_list
(
self
.
request
)
...
@@ -269,7 +269,7 @@ class TestCourseListing(ModuleStoreTestCase):
...
@@ -269,7 +269,7 @@ class TestCourseListing(ModuleStoreTestCase):
course_location
=
SlashSeparatedCourseKey
(
'testOrg'
,
'doomedCourse'
,
'RunBabyRun'
)
course_location
=
SlashSeparatedCourseKey
(
'testOrg'
,
'doomedCourse'
,
'RunBabyRun'
)
self
.
_create_course_with_access_groups
(
course_location
,
self
.
user
)
self
.
_create_course_with_access_groups
(
course_location
,
self
.
user
)
store
.
delete_course
(
course_location
)
store
.
delete_course
(
course_location
,
self
.
user
.
id
)
course_location
=
SlashSeparatedCourseKey
(
'testOrg'
,
'erroredCourse'
,
'RunBabyRun'
)
course_location
=
SlashSeparatedCourseKey
(
'testOrg'
,
'erroredCourse'
,
'RunBabyRun'
)
course
=
self
.
_create_course_with_access_groups
(
course_location
,
self
.
user
)
course
=
self
.
_create_course_with_access_groups
(
course_location
,
self
.
user
)
...
...
cms/djangoapps/contentstore/tests/test_crud.py
View file @
f5abef88
...
@@ -162,7 +162,7 @@ class TemplateTests(unittest.TestCase):
...
@@ -162,7 +162,7 @@ class TemplateTests(unittest.TestCase):
self
.
assertIsInstance
(
self
.
split_store
.
get_course
(
id_locator
),
CourseDescriptor
)
self
.
assertIsInstance
(
self
.
split_store
.
get_course
(
id_locator
),
CourseDescriptor
)
# and by guid
# and by guid
self
.
assertIsInstance
(
self
.
split_store
.
get_item
(
guid_locator
),
CourseDescriptor
)
self
.
assertIsInstance
(
self
.
split_store
.
get_item
(
guid_locator
),
CourseDescriptor
)
self
.
split_store
.
delete_course
(
id_locator
)
self
.
split_store
.
delete_course
(
id_locator
,
ModuleStoreEnum
.
UserID
.
test
)
# test can no longer retrieve by id
# test can no longer retrieve by id
self
.
assertRaises
(
ItemNotFoundError
,
self
.
split_store
.
get_course
,
id_locator
)
self
.
assertRaises
(
ItemNotFoundError
,
self
.
split_store
.
get_course
,
id_locator
)
# but can by guid
# but can by guid
...
...
cms/djangoapps/contentstore/tests/test_users_default_role.py
View file @
f5abef88
...
@@ -62,7 +62,7 @@ class TestUsersDefaultRole(ModuleStoreTestCase):
...
@@ -62,7 +62,7 @@ class TestUsersDefaultRole(ModuleStoreTestCase):
# check that user has his default "Student" forum role for this course
# check that user has his default "Student" forum role for this course
self
.
assertTrue
(
self
.
user
.
roles
.
filter
(
name
=
"Student"
,
course_id
=
self
.
course_key
))
# pylint: disable=no-member
self
.
assertTrue
(
self
.
user
.
roles
.
filter
(
name
=
"Student"
,
course_id
=
self
.
course_key
))
# pylint: disable=no-member
delete_course_and_groups
(
self
.
course_key
,
commit
=
True
)
delete_course_and_groups
(
self
.
course_key
,
self
.
user
.
id
)
# check that user's enrollment for this course is not deleted
# check that user's enrollment for this course is not deleted
self
.
assertTrue
(
CourseEnrollment
.
is_enrolled
(
self
.
user
,
self
.
course_key
))
self
.
assertTrue
(
CourseEnrollment
.
is_enrolled
(
self
.
user
,
self
.
course_key
))
...
@@ -80,7 +80,7 @@ class TestUsersDefaultRole(ModuleStoreTestCase):
...
@@ -80,7 +80,7 @@ class TestUsersDefaultRole(ModuleStoreTestCase):
self
.
assertTrue
(
self
.
user
.
roles
.
filter
(
name
=
"Student"
,
course_id
=
self
.
course_key
))
# pylint: disable=no-member
self
.
assertTrue
(
self
.
user
.
roles
.
filter
(
name
=
"Student"
,
course_id
=
self
.
course_key
))
# pylint: disable=no-member
# delete this course and recreate this course with same user
# delete this course and recreate this course with same user
delete_course_and_groups
(
self
.
course_key
,
commit
=
True
)
delete_course_and_groups
(
self
.
course_key
,
self
.
user
.
id
)
resp
=
self
.
_create_course_with_given_location
(
self
.
course_key
)
resp
=
self
.
_create_course_with_given_location
(
self
.
course_key
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
...
@@ -98,7 +98,7 @@ class TestUsersDefaultRole(ModuleStoreTestCase):
...
@@ -98,7 +98,7 @@ class TestUsersDefaultRole(ModuleStoreTestCase):
# check that user has enrollment and his default "Student" forum role for this course
# check that user has enrollment and his default "Student" forum role for this course
self
.
assertTrue
(
CourseEnrollment
.
is_enrolled
(
self
.
user
,
self
.
course_key
))
self
.
assertTrue
(
CourseEnrollment
.
is_enrolled
(
self
.
user
,
self
.
course_key
))
# delete this course and recreate this course with same user
# delete this course and recreate this course with same user
delete_course_and_groups
(
self
.
course_key
,
commit
=
True
)
delete_course_and_groups
(
self
.
course_key
,
self
.
user
.
id
)
# now create same course with different name case ('uppercase')
# now create same course with different name case ('uppercase')
new_course_key
=
self
.
course_key
.
replace
(
course
=
self
.
course_key
.
course
.
upper
())
new_course_key
=
self
.
course_key
.
replace
(
course
=
self
.
course_key
.
course
.
upper
())
...
...
cms/djangoapps/contentstore/utils.py
View file @
f5abef88
...
@@ -11,12 +11,10 @@ from django.utils.translation import ugettext as _
...
@@ -11,12 +11,10 @@ from django.utils.translation import ugettext as _
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
xmodule.contentstore.content
import
StaticContent
from
xmodule.contentstore.content
import
StaticContent
from
xmodule.contentstore.django
import
contentstore
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
,
Location
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
,
Location
from
xmodule.modulestore.store_utilities
import
delete_course
from
student.roles
import
CourseInstructorRole
,
CourseStaffRole
from
student.roles
import
CourseInstructorRole
,
CourseStaffRole
...
@@ -28,27 +26,25 @@ NOTES_PANEL = {"name": _("My Notes"), "type": "notes"}
...
@@ -28,27 +26,25 @@ NOTES_PANEL = {"name": _("My Notes"), "type": "notes"}
EXTRA_TAB_PANELS
=
dict
([(
p
[
'type'
],
p
)
for
p
in
[
OPEN_ENDED_PANEL
,
NOTES_PANEL
]])
EXTRA_TAB_PANELS
=
dict
([(
p
[
'type'
],
p
)
for
p
in
[
OPEN_ENDED_PANEL
,
NOTES_PANEL
]])
def
delete_course_and_groups
(
course_id
,
commit
=
False
):
def
delete_course_and_groups
(
course_id
,
user_id
):
"""
"""
This deletes the courseware associated with a course_id as well as cleaning update_item
This deletes the courseware associated with a course_id as well as cleaning update_item
the various user table stuff (groups, permissions, etc.)
the various user table stuff (groups, permissions, etc.)
"""
"""
module_store
=
modulestore
()
module_store
=
modulestore
()
content_store
=
contentstore
()
with
module_store
.
bulk_write_operations
(
course_id
):
with
module_store
.
bulk_write_operations
(
course_id
):
if
delete_course
(
module_store
,
content_store
,
course_id
,
commit
):
module_store
.
delete_course
(
course_id
,
user_id
)
print
'removing User permissions from course....'
print
'removing User permissions from course....'
# in the django layer, we need to remove all the user permissions groups associated with this course
# in the django layer, we need to remove all the user permissions groups associated with this course
if
commit
:
try
:
try
:
staff_role
=
CourseStaffRole
(
course_id
)
staff_role
=
CourseStaffRole
(
course_id
)
staff_role
.
remove_users
(
*
staff_role
.
users_with_role
())
staff_role
.
remove_users
(
*
staff_role
.
users_with_role
())
instructor_role
=
CourseInstructorRole
(
course_id
)
instructor_role
=
CourseInstructorRole
(
course_id
)
instructor_role
.
remove_users
(
*
instructor_role
.
users_with_role
())
instructor_role
.
remove_users
(
*
instructor_role
.
users_with_role
())
except
Exception
as
err
:
except
Exception
as
err
:
log
.
error
(
"Error in deleting course groups for {0}: {1}"
.
format
(
course_id
,
err
))
log
.
error
(
"Error in deleting course groups for {0}: {1}"
.
format
(
course_id
,
err
))
def
get_lms_link_for_item
(
location
,
preview
=
False
):
def
get_lms_link_for_item
(
location
,
preview
=
False
):
...
...
cms/djangoapps/contentstore/views/tabs.py
View file @
f5abef88
...
@@ -12,6 +12,7 @@ from django_future.csrf import ensure_csrf_cookie
...
@@ -12,6 +12,7 @@ from django_future.csrf import ensure_csrf_cookie
from
django.views.decorators.http
import
require_http_methods
from
django.views.decorators.http
import
require_http_methods
from
edxmako.shortcuts
import
render_to_response
from
edxmako.shortcuts
import
render_to_response
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.tabs
import
CourseTabList
,
StaticTab
,
CourseTab
,
InvalidTabsException
from
xmodule.tabs
import
CourseTabList
,
StaticTab
,
CourseTab
,
InvalidTabsException
from
opaque_keys.edx.keys
import
CourseKey
,
UsageKey
from
opaque_keys.edx.keys
import
CourseKey
,
UsageKey
...
@@ -192,7 +193,7 @@ def primitive_delete(course, num):
...
@@ -192,7 +193,7 @@ def primitive_delete(course, num):
# Note for future implementations: if you delete a static_tab, then Chris Dodge
# Note for future implementations: if you delete a static_tab, then Chris Dodge
# points out that there's other stuff to delete beyond this element.
# points out that there's other stuff to delete beyond this element.
# This code happens to not delete static_tab so it doesn't come up.
# This code happens to not delete static_tab so it doesn't come up.
modulestore
()
.
update_item
(
course
,
'**replace_user**'
)
modulestore
()
.
update_item
(
course
,
ModuleStoreEnum
.
UserID
.
primitive_command
)
def
primitive_insert
(
course
,
num
,
tab_type
,
name
):
def
primitive_insert
(
course
,
num
,
tab_type
,
name
):
...
@@ -201,5 +202,5 @@ def primitive_insert(course, num, tab_type, name):
...
@@ -201,5 +202,5 @@ def primitive_insert(course, num, tab_type, name):
new_tab
=
CourseTab
.
from_json
({
u'type'
:
unicode
(
tab_type
),
u'name'
:
unicode
(
name
)})
new_tab
=
CourseTab
.
from_json
({
u'type'
:
unicode
(
tab_type
),
u'name'
:
unicode
(
name
)})
tabs
=
course
.
tabs
tabs
=
course
.
tabs
tabs
.
insert
(
num
,
new_tab
)
tabs
.
insert
(
num
,
new_tab
)
modulestore
()
.
update_item
(
course
,
'**replace_user**'
)
modulestore
()
.
update_item
(
course
,
ModuleStoreEnum
.
UserID
.
primitive_command
)
common/djangoapps/student/tests/test_course_listing.py
View file @
f5abef88
...
@@ -97,7 +97,7 @@ class TestCourseListing(ModuleStoreTestCase):
...
@@ -97,7 +97,7 @@ class TestCourseListing(ModuleStoreTestCase):
course_location
=
SlashSeparatedCourseKey
(
'testOrg'
,
'doomedCourse'
,
'RunBabyRun'
)
course_location
=
SlashSeparatedCourseKey
(
'testOrg'
,
'doomedCourse'
,
'RunBabyRun'
)
self
.
_create_course_with_access_groups
(
course_location
)
self
.
_create_course_with_access_groups
(
course_location
)
mongo_store
.
delete_course
(
course_location
)
mongo_store
.
delete_course
(
course_location
,
ModuleStoreEnum
.
UserID
.
test
)
course_location
=
SlashSeparatedCourseKey
(
'testOrg'
,
'erroredCourse'
,
'RunBabyRun'
)
course_location
=
SlashSeparatedCourseKey
(
'testOrg'
,
'erroredCourse'
,
'RunBabyRun'
)
course
=
self
.
_create_course_with_access_groups
(
course_location
)
course
=
self
.
_create_course_with_access_groups
(
course_location
)
...
...
common/lib/xmodule/xmodule/modulestore/__init__.py
View file @
f5abef88
...
@@ -72,6 +72,21 @@ class ModuleStoreEnum(object):
...
@@ -72,6 +72,21 @@ class ModuleStoreEnum(object):
draft
=
'draft-branch'
draft
=
'draft-branch'
published
=
'published-branch'
published
=
'published-branch'
class
UserID
(
object
):
"""
Values for user ID defaults
"""
# Note: we use negative values here to (try to) not conflict
# with user identifiers provided by an actual user service.
# user ID to use for all management commands
mgmt_command
=
-
1
# user ID to use for primitive commands
primitive_command
=
-
2
# user ID to use for tests that do not have a django user available
test
=
-
3
class
PublishState
(
object
):
class
PublishState
(
object
):
"""
"""
...
@@ -270,6 +285,18 @@ class ModuleStoreRead(object):
...
@@ -270,6 +285,18 @@ class ModuleStoreRead(object):
"""
"""
pass
pass
@abstractmethod
def
compute_publish_state
(
self
,
xblock
):
"""
Returns whether this xblock is draft, public, or private.
Returns:
PublishState.draft - content is in the process of being edited, but still has a previous
version deployed to LMS
PublishState.public - content is locked and deployed to LMS
PublishState.private - content is editable and not deployed to LMS
"""
pass
class
ModuleStoreWrite
(
ModuleStoreRead
):
class
ModuleStoreWrite
(
ModuleStoreRead
):
"""
"""
...
@@ -348,7 +375,7 @@ class ModuleStoreWrite(ModuleStoreRead):
...
@@ -348,7 +375,7 @@ class ModuleStoreWrite(ModuleStoreRead):
pass
pass
@abstractmethod
@abstractmethod
def
delete_course
(
self
,
course_key
,
user_id
=
None
):
def
delete_course
(
self
,
course_key
,
user_id
):
"""
"""
Deletes the course. It may be a soft or hard delete. It may or may not remove the xblock definitions
Deletes the course. It may be a soft or hard delete. It may or may not remove the xblock definitions
depending on the persistence layer and how tightly bound the xblocks are to the course.
depending on the persistence layer and how tightly bound the xblocks are to the course.
...
@@ -441,6 +468,12 @@ class ModuleStoreReadBase(ModuleStoreRead):
...
@@ -441,6 +468,12 @@ class ModuleStoreReadBase(ModuleStoreRead):
None
None
)
)
def
compute_publish_state
(
self
,
xblock
):
"""
Returns PublishState.public since this is a read-only store.
"""
return
PublishState
.
public
def
heartbeat
(
self
):
def
heartbeat
(
self
):
"""
"""
Is this modulestore ready?
Is this modulestore ready?
...
@@ -553,6 +586,15 @@ class ModuleStoreWriteBase(ModuleStoreReadBase, ModuleStoreWrite):
...
@@ -553,6 +586,15 @@ class ModuleStoreWriteBase(ModuleStoreReadBase, ModuleStoreWrite):
super
(
ModuleStoreWriteBase
,
self
)
.
clone_course
(
source_course_id
,
dest_course_id
,
user_id
)
super
(
ModuleStoreWriteBase
,
self
)
.
clone_course
(
source_course_id
,
dest_course_id
,
user_id
)
return
dest_course_id
return
dest_course_id
def
delete_course
(
self
,
course_key
,
user_id
):
"""
This base method just deletes the assets. The lower level impls must do the actual deleting of
content.
"""
# delete the assets
self
.
contentstore
.
delete_all_course_assets
(
course_key
)
super
(
ModuleStoreWriteBase
,
self
)
.
delete_course
(
course_key
,
user_id
)
@contextmanager
@contextmanager
def
bulk_write_operations
(
self
,
course_id
):
def
bulk_write_operations
(
self
,
course_id
):
"""
"""
...
...
common/lib/xmodule/xmodule/modulestore/mixed.py
View file @
f5abef88
...
@@ -229,16 +229,13 @@ class MixedModuleStore(ModuleStoreWriteBase):
...
@@ -229,16 +229,13 @@ class MixedModuleStore(ModuleStoreWriteBase):
store
=
self
.
_get_modulestore_for_courseid
(
course_id
)
store
=
self
.
_get_modulestore_for_courseid
(
course_id
)
return
store
.
has_course
(
course_id
,
ignore_case
)
return
store
.
has_course
(
course_id
,
ignore_case
)
def
delete_course
(
self
,
course_key
,
user_id
=
None
):
def
delete_course
(
self
,
course_key
,
user_id
):
"""
"""
See xmodule.modulestore.__init__.ModuleStoreWrite.delete_course
See xmodule.modulestore.__init__.ModuleStoreWrite.delete_course
"""
"""
assert
(
isinstance
(
course_key
,
CourseKey
))
assert
(
isinstance
(
course_key
,
CourseKey
))
store
=
self
.
_get_modulestore_for_courseid
(
course_key
)
store
=
self
.
_get_modulestore_for_courseid
(
course_key
)
if
hasattr
(
store
,
'delete_course'
):
return
store
.
delete_course
(
course_key
,
user_id
)
return
store
.
delete_course
(
course_key
,
user_id
)
else
:
raise
NotImplementedError
(
u"Cannot delete a course on store {}"
.
format
(
store
))
def
get_parent_location
(
self
,
location
,
**
kwargs
):
def
get_parent_location
(
self
,
location
,
**
kwargs
):
"""
"""
...
@@ -290,10 +287,6 @@ class MixedModuleStore(ModuleStoreWriteBase):
...
@@ -290,10 +287,6 @@ class MixedModuleStore(ModuleStoreWriteBase):
Returns: a CourseDescriptor
Returns: a CourseDescriptor
"""
"""
store
=
self
.
_get_modulestore_for_courseid
(
None
)
store
=
self
.
_get_modulestore_for_courseid
(
None
)
if
not
hasattr
(
store
,
'create_course'
):
raise
NotImplementedError
(
u"Cannot create a course on store {}"
.
format
(
store
))
return
store
.
create_course
(
org
,
offering
,
user_id
,
fields
,
**
kwargs
)
return
store
.
create_course
(
org
,
offering
,
user_id
,
fields
,
**
kwargs
)
def
clone_course
(
self
,
source_course_id
,
dest_course_id
,
user_id
):
def
clone_course
(
self
,
source_course_id
,
dest_course_id
,
user_id
):
...
@@ -456,13 +449,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
...
@@ -456,13 +449,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
"""
"""
course_id
=
xblock
.
scope_ids
.
usage_id
.
course_key
course_id
=
xblock
.
scope_ids
.
usage_id
.
course_key
store
=
self
.
_get_modulestore_for_courseid
(
course_id
)
store
=
self
.
_get_modulestore_for_courseid
(
course_id
)
if
hasattr
(
store
,
'compute_publish_state'
):
return
store
.
compute_publish_state
(
xblock
)
return
store
.
compute_publish_state
(
xblock
)
elif
hasattr
(
store
,
'publish'
):
raise
NotImplementedError
(
u"Cannot compute_publish_state on store {}"
.
format
(
store
))
else
:
# read-only store; so, everything's public
return
PublishState
.
public
def
publish
(
self
,
location
,
user_id
):
def
publish
(
self
,
location
,
user_id
):
"""
"""
...
...
common/lib/xmodule/xmodule/modulestore/mongo/base.py
View file @
f5abef88
...
@@ -892,15 +892,6 @@ class MongoModuleStore(ModuleStoreWriteBase):
...
@@ -892,15 +892,6 @@ class MongoModuleStore(ModuleStoreWriteBase):
return
course
return
course
def
delete_course
(
self
,
course_key
,
user_id
=
None
):
"""
The impl removes all of the db records for the course.
:param course_key:
:param user_id:
"""
course_query
=
self
.
_course_key_to_son
(
course_key
)
self
.
collection
.
remove
(
course_query
,
multi
=
True
)
def
create_xmodule
(
self
,
location
,
definition_data
=
None
,
metadata
=
None
,
runtime
=
None
,
fields
=
{}):
def
create_xmodule
(
self
,
location
,
definition_data
=
None
,
metadata
=
None
,
runtime
=
None
,
fields
=
{}):
"""
"""
Create the new xmodule but don't save it. Returns the new module.
Create the new xmodule but don't save it. Returns the new module.
...
...
common/lib/xmodule/xmodule/modulestore/mongo/draft.py
View file @
f5abef88
...
@@ -144,6 +144,18 @@ class DraftModuleStore(MongoModuleStore):
...
@@ -144,6 +144,18 @@ class DraftModuleStore(MongoModuleStore):
del
key
[
'_id.revision'
]
del
key
[
'_id.revision'
]
return
self
.
collection
.
find
(
key
)
.
count
()
>
0
return
self
.
collection
.
find
(
key
)
.
count
()
>
0
def
delete_course
(
self
,
course_key
,
user_id
):
"""
:param course_key: which course to delete
:param user_id: id of the user deleting the course
"""
# delete the assets
super
(
DraftModuleStore
,
self
)
.
delete_course
(
course_key
,
user_id
)
# delete all of the db records for the course
course_query
=
self
.
_course_key_to_son
(
course_key
)
self
.
collection
.
remove
(
course_query
,
multi
=
True
)
def
clone_course
(
self
,
source_course_id
,
dest_course_id
,
user_id
):
def
clone_course
(
self
,
source_course_id
,
dest_course_id
,
user_id
):
"""
"""
Only called if cloning within this store or if env doesn't set up mixed.
Only called if cloning within this store or if env doesn't set up mixed.
...
...
common/lib/xmodule/xmodule/modulestore/split_mongo/split.py
View file @
f5abef88
...
@@ -1380,7 +1380,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -1380,7 +1380,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
return
result
return
result
def
delete_course
(
self
,
course_key
,
user_id
=
None
):
def
delete_course
(
self
,
course_key
,
user_id
):
"""
"""
Remove the given course from the course index.
Remove the given course from the course index.
...
@@ -1395,6 +1395,10 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -1395,6 +1395,10 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
log
.
info
(
u"deleting course from split-mongo:
%
s"
,
course_key
)
log
.
info
(
u"deleting course from split-mongo:
%
s"
,
course_key
)
self
.
db_connection
.
delete_course_index
(
index
)
self
.
db_connection
.
delete_course_index
(
index
)
# We do NOT call the super class here since we need to keep the assets
# in case the course is later restored.
# super(SplitMongoModuleStore, self).delete_course(course_key, user_id)
def
revert_to_published
(
self
,
location
,
user_id
=
None
):
def
revert_to_published
(
self
,
location
,
user_id
=
None
):
"""
"""
Reverts an item to its last published version (recursively traversing all of its descendants).
Reverts an item to its last published version (recursively traversing all of its descendants).
...
@@ -1407,13 +1411,6 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
...
@@ -1407,13 +1411,6 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
"""
"""
raise
NotImplementedError
()
raise
NotImplementedError
()
def
get_errored_courses
(
self
):
"""
This function doesn't make sense for the mongo modulestore, as structures
are loaded on demand, rather than up front
"""
return
{}
def
inherit_settings
(
self
,
block_map
,
block_json
,
inheriting_settings
=
None
):
def
inherit_settings
(
self
,
block_map
,
block_json
,
inheriting_settings
=
None
):
"""
"""
Updates block_json with any inheritable setting set by an ancestor and recurses to children.
Updates block_json with any inheritable setting set by an ancestor and recurses to children.
...
...
common/lib/xmodule/xmodule/modulestore/store_utilities.py
View file @
f5abef88
...
@@ -85,25 +85,3 @@ def rewrite_nonportable_content_links(source_course_id, dest_course_id, text):
...
@@ -85,25 +85,3 @@ def rewrite_nonportable_content_links(source_course_id, dest_course_id, text):
logging
.
warning
(
"Error producing regex substitution
%
r for text =
%
r.
\n\n
Error msg =
%
s"
,
source_course_id
,
text
,
str
(
exc
))
logging
.
warning
(
"Error producing regex substitution
%
r for text =
%
r.
\n\n
Error msg =
%
s"
,
source_course_id
,
text
,
str
(
exc
))
return
text
return
text
def
delete_course
(
modulestore
,
contentstore
,
course_key
,
commit
=
False
):
"""
This method will actually do the work to delete all content in a course in a MongoDB backed
courseware store. BE VERY CAREFUL, this is not reversable.
"""
# check to see if the source course is actually there
if
not
modulestore
.
has_course
(
course_key
):
raise
Exception
(
"Cannot find a course at {0}. Aborting"
.
format
(
course_key
))
if
commit
:
print
"Deleting assets and thumbnails {}"
.
format
(
course_key
)
contentstore
.
delete_all_course_assets
(
course_key
)
# finally delete the course
print
"Deleting {0}..."
.
format
(
course_key
)
if
commit
:
modulestore
.
delete_course
(
course_key
,
'**replace-user**'
)
return
True
lms/djangoapps/dashboard/management/commands/tests/test_git_add_course.py
View file @
f5abef88
...
@@ -15,10 +15,9 @@ from django.core.management.base import CommandError
...
@@ -15,10 +15,9 @@ from django.core.management.base import CommandError
from
django.test.utils
import
override_settings
from
django.test.utils
import
override_settings
from
courseware.tests.tests
import
TEST_DATA_MONGO_MODULESTORE
from
courseware.tests.tests
import
TEST_DATA_MONGO_MODULESTORE
from
xmodule.
contentstore.django
import
contentstore
from
xmodule.
modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.modulestore.store_utilities
import
delete_course
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
import
dashboard.git_import
as
git_import
import
dashboard.git_import
as
git_import
from
dashboard.git_import
import
GitImportError
from
dashboard.git_import
import
GitImportError
...
@@ -161,9 +160,7 @@ class TestGitAddCourse(ModuleStoreTestCase):
...
@@ -161,9 +160,7 @@ class TestGitAddCourse(ModuleStoreTestCase):
self
.
TEST_BRANCH
)
self
.
TEST_BRANCH
)
# Delete to test branching back to master
# Delete to test branching back to master
delete_course
(
def_ms
,
contentstore
(),
def_ms
.
delete_course
(
self
.
TEST_BRANCH_COURSE
,
ModuleStoreEnum
.
UserID
.
test
)
self
.
TEST_BRANCH_COURSE
,
True
)
self
.
assertIsNone
(
def_ms
.
get_course
(
self
.
TEST_BRANCH_COURSE
))
self
.
assertIsNone
(
def_ms
.
get_course
(
self
.
TEST_BRANCH_COURSE
))
git_import
.
add_repo
(
self
.
TEST_REPO
,
git_import
.
add_repo
(
self
.
TEST_REPO
,
repo_dir
/
'edx4edx_lite'
,
repo_dir
/
'edx4edx_lite'
,
...
...
lms/djangoapps/dashboard/sysadmin.py
View file @
f5abef88
...
@@ -38,10 +38,8 @@ from external_auth.models import ExternalAuthMap
...
@@ -38,10 +38,8 @@ from external_auth.models import ExternalAuthMap
from
external_auth.views
import
generate_password
from
external_auth.views
import
generate_password
from
student.models
import
CourseEnrollment
,
UserProfile
,
Registration
from
student.models
import
CourseEnrollment
,
UserProfile
,
Registration
import
track.views
import
track.views
from
xmodule.contentstore.django
import
contentstore
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.store_utilities
import
delete_course
from
xmodule.modulestore.xml
import
XMLModuleStore
from
xmodule.modulestore.xml
import
XMLModuleStore
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
...
@@ -591,9 +589,7 @@ class Courses(SysadminDashboardView):
...
@@ -591,9 +589,7 @@ class Courses(SysadminDashboardView):
elif
course_found
and
not
is_xml_course
:
elif
course_found
and
not
is_xml_course
:
# delete course that is stored with mongodb backend
# delete course that is stored with mongodb backend
content_store
=
contentstore
()
self
.
def_ms
.
delete_course
(
course
.
id
,
request
.
user
.
id
)
commit
=
True
delete_course
(
self
.
def_ms
,
content_store
,
course
.
id
,
commit
)
# don't delete user permission groups, though
# don't delete user permission groups, though
self
.
msg
+=
\
self
.
msg
+=
\
u"<font color='red'>{0} {1} = {2} ({3})</font>"
.
format
(
u"<font color='red'>{0} {1} = {2} ({3})</font>"
.
format
(
...
...
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