refactor: convert course_module term to course_block

This commit is contained in:
0x29a
2022-10-27 03:24:30 +02:00
committed by Piotr Surowiec
parent d3fee38a37
commit 83396ffb07
62 changed files with 335 additions and 335 deletions

View File

@@ -111,9 +111,9 @@ class AdvancedCourseSettingsView(DeveloperErrorViewMixin, APIView):
course_key = CourseKey.from_string(course_id)
if not has_studio_read_access(request.user, course_key):
self.permission_denied(request)
course_module = modulestore().get_course(course_key)
course_block = modulestore().get_course(course_key)
return Response(CourseMetadata.fetch_all(
course_module,
course_block,
filter_fields=filter_query_data.cleaned_data['filter_fields'],
))
@@ -174,6 +174,6 @@ class AdvancedCourseSettingsView(DeveloperErrorViewMixin, APIView):
course_key = CourseKey.from_string(course_id)
if not has_studio_write_access(request.user, course_key):
self.permission_denied(request)
course_module = modulestore().get_course(course_key)
updated_data = update_course_advanced_settings(course_module, request.data, request.user)
course_block = modulestore().get_course(course_key)
updated_data = update_course_advanced_settings(course_block, request.data, request.user)
return Response(updated_data)

View File

@@ -81,8 +81,8 @@ class CourseTabListView(DeveloperErrorViewMixin, APIView):
if not has_studio_read_access(request.user, course_key):
self.permission_denied(request)
course_module = modulestore().get_course(course_key)
tabs_to_render = get_course_tabs(course_module, request.user)
course_block = modulestore().get_course(course_key)
tabs_to_render = get_course_tabs(course_block, request.user)
return Response(CourseTabSerializer(tabs_to_render, many=True).data)
@@ -147,12 +147,12 @@ class CourseTabSettingsView(DeveloperErrorViewMixin, APIView):
tab_id_locator = TabIDLocatorSerializer(data=request.query_params)
tab_id_locator.is_valid(raise_exception=True)
course_module = modulestore().get_course(course_key)
course_block = modulestore().get_course(course_key)
serializer = CourseTabUpdateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
edit_tab_handler(
course_module,
course_block,
{
"tab_id_locator": tab_id_locator.data,
**serializer.data,
@@ -216,11 +216,11 @@ class CourseTabReorderView(DeveloperErrorViewMixin, APIView):
if not has_studio_write_access(request.user, course_key):
self.permission_denied(request)
course_module = modulestore().get_course(course_key)
course_block = modulestore().get_course(course_key)
tab_id_locators = TabIDLocatorSerializer(data=request.data, many=True)
tab_id_locators.is_valid(raise_exception=True)
reorder_tabs_handler(
course_module,
course_block,
tab_id_locators.validated_data,
request.user,
)

View File

@@ -77,7 +77,7 @@ class ProctoringExamSettingsTestMixin():
response = self.make_request()
assert response.status_code == status.HTTP_403_FORBIDDEN
def test_404_no_course_module(self):
def test_404_no_course_block(self):
course_id = 'course-v1:edX+ToyX_Nonexistent_Course+Toy_Course'
self.client.login(username=self.global_staff, password=self.password)
response = self.make_request(course_id=course_id)

View File

@@ -92,8 +92,8 @@ class ProctoredExamSettingsView(APIView):
def get(self, request, course_id):
""" GET handler """
with modulestore().bulk_operations(CourseKey.from_string(course_id)):
course_module = self._get_and_validate_course_access(request.user, course_id)
course_metadata = CourseMetadata().fetch_all(course_module)
course_block = self._get_and_validate_course_access(request.user, course_id)
course_metadata = CourseMetadata().fetch_all(course_block)
proctored_exam_settings = self._get_proctored_exam_setting_values(course_metadata)
data = {}
@@ -123,8 +123,8 @@ class ProctoredExamSettingsView(APIView):
return Response(status=status.HTTP_403_FORBIDDEN)
with modulestore().bulk_operations(CourseKey.from_string(course_id)):
course_module = self._get_and_validate_course_access(request.user, course_id)
course_metadata = CourseMetadata().fetch_all(course_module)
course_block = self._get_and_validate_course_access(request.user, course_id)
course_metadata = CourseMetadata().fetch_all(course_block)
models_to_update = {}
for setting_key, value in exam_config.data.items():
@@ -133,9 +133,9 @@ class ProctoredExamSettingsView(APIView):
models_to_update[setting_key] = copy.deepcopy(model)
models_to_update[setting_key]['value'] = value
# validate data formats and update the course module object
# validate data formats and update the course block object
is_valid, errors, updated_data = CourseMetadata.validate_and_update_from_json(
course_module,
course_block,
models_to_update,
user=request.user,
)
@@ -148,7 +148,7 @@ class ProctoredExamSettingsView(APIView):
)
# save to mongo
modulestore().update_item(course_module, request.user.id)
modulestore().update_item(course_block, request.user.id)
# merge updated settings with all existing settings.
# do this because fields that could not be modified are excluded from the result
@@ -171,14 +171,14 @@ class ProctoredExamSettingsView(APIView):
"""
Check if course_id exists and is accessible by the user.
Returns a course_module object
Returns a course_block object
"""
course_key = CourseKey.from_string(course_id)
course_module = get_course_and_check_access(course_key, user)
course_block = get_course_and_check_access(course_key, user)
if not course_module:
if not course_block:
raise NotFound(
f'Course with course_id {course_id} does not exist.'
)
return course_module
return course_block

View File

@@ -167,7 +167,7 @@ def rerun_course(source_course_key_string, destination_course_key_string, user_i
# cleanup any remnants of the course
modulestore().delete_course(destination_course_key, user_id)
except ItemNotFoundError:
# it's possible there was an error even before the course module was created
# it's possible there was an error even before the course block was created
pass
return "exception: " + str(exc)
@@ -335,13 +335,13 @@ def export_olx(self, user_id, course_key_string, language):
return
def create_export_tarball(course_module, course_key, context, status=None):
def create_export_tarball(course_block, course_key, context, status=None):
"""
Generates the export tarball, or returns None if there was an error.
Updates the context with any error information if applicable.
"""
name = course_module.url_name
name = course_block.url_name
export_file = NamedTemporaryFile(prefix=name + '.', suffix=".tar.gz") # lint-amnesty, pylint: disable=consider-using-with
root_dir = path(mkdtemp())
@@ -349,7 +349,7 @@ def create_export_tarball(course_module, course_key, context, status=None):
if isinstance(course_key, LibraryLocator):
export_library_to_xml(modulestore(), contentstore(), course_key, root_dir, name)
else:
export_course_to_xml(modulestore(), contentstore(), course_module.id, root_dir, name)
export_course_to_xml(modulestore(), contentstore(), course_block.id, root_dir, name)
if status:
status.set_state('Compressing')

View File

@@ -348,7 +348,7 @@ class ImportRequiredTestCases(ContentStoreTestCase):
# check for policy.json
self.assertTrue(filesystem.exists('policy.json'))
# compare what's on disk to what we have in the course module
# compare what's on disk to what we have in the course block
with filesystem.open('policy.json', 'r') as course_policy:
on_disk = loads(course_policy.read())
self.assertIn('course/2012_Fall', on_disk)
@@ -1195,8 +1195,8 @@ class ContentStoreTest(ContentStoreTestCase):
"""Test new course creation and verify default language"""
test_course_data = self.assert_created_course()
course_id = _get_course_id(self.store, test_course_data)
course_module = self.store.get_course(course_id)
self.assertEqual(course_module.language, 'hr')
course_block = self.store.get_course(course_id)
self.assertEqual(course_block.language, 'hr')
def test_create_course_with_dots(self):
"""Test new course creation with dots in the name"""
@@ -1617,12 +1617,12 @@ class ContentStoreTest(ContentStoreTestCase):
#
# first check PDF textbooks, to make sure the url paths got updated
course_module = self.store.get_course(target_id)
course_block = self.store.get_course(target_id)
self.assertEqual(len(course_module.pdf_textbooks), 1)
self.assertEqual(len(course_module.pdf_textbooks[0]["chapters"]), 2)
self.assertEqual(course_module.pdf_textbooks[0]["chapters"][0]["url"], '/static/Chapter1.pdf')
self.assertEqual(course_module.pdf_textbooks[0]["chapters"][1]["url"], '/static/Chapter2.pdf')
self.assertEqual(len(course_block.pdf_textbooks), 1)
self.assertEqual(len(course_block.pdf_textbooks[0]["chapters"]), 2)
self.assertEqual(course_block.pdf_textbooks[0]["chapters"][0]["url"], '/static/Chapter1.pdf')
self.assertEqual(course_block.pdf_textbooks[0]["chapters"][1]["url"], '/static/Chapter2.pdf')
def test_import_into_new_course_id_wiki_slug_renamespacing(self):
# If reimporting into the same course do not change the wiki_slug.
@@ -1634,14 +1634,14 @@ class ContentStoreTest(ContentStoreTestCase):
'run': target_id.run
}
_create_course(self, target_id, course_data)
course_module = self.store.get_course(target_id)
course_module.wiki_slug = 'toy'
course_module.save()
course_block = self.store.get_course(target_id)
course_block.wiki_slug = 'toy'
course_block.save()
# Import a course with wiki_slug == location.course
import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['toy'], target_id=target_id)
course_module = self.store.get_course(target_id)
self.assertEqual(course_module.wiki_slug, 'toy')
course_block = self.store.get_course(target_id)
self.assertEqual(course_block.wiki_slug, 'toy')
# But change the wiki_slug if it is a different course.
target_id = self.store.make_course_key('MITx', '111', '2013_Spring')
@@ -1655,13 +1655,13 @@ class ContentStoreTest(ContentStoreTestCase):
# Import a course with wiki_slug == location.course
import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['toy'], target_id=target_id)
course_module = self.store.get_course(target_id)
self.assertEqual(course_module.wiki_slug, 'MITx.111.2013_Spring')
course_block = self.store.get_course(target_id)
self.assertEqual(course_block.wiki_slug, 'MITx.111.2013_Spring')
# Now try importing a course with wiki_slug == '{0}.{1}.{2}'.format(location.org, location.course, location.run)
import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['two_toys'], target_id=target_id)
course_module = self.store.get_course(target_id)
self.assertEqual(course_module.wiki_slug, 'MITx.111.2013_Spring')
course_block = self.store.get_course(target_id)
self.assertEqual(course_block.wiki_slug, 'MITx.111.2013_Spring')
def test_import_metadata_with_attempts_empty_string(self):
import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['simple'], create_if_not_present=True)
@@ -1797,8 +1797,8 @@ class ContentStoreTest(ContentStoreTestCase):
course_key = _get_course_id(self.store, self.course_data)
_create_course(self, course_key, self.course_data)
course_module = self.store.get_course(course_key)
self.assertEqual(course_module.wiki_slug, 'MITx.111.2013_Spring')
course_block = self.store.get_course(course_key)
self.assertEqual(course_block.wiki_slug, 'MITx.111.2013_Spring')
def test_course_handler_with_invalid_course_key_string(self):
"""Test viewing the course overview page with invalid course id"""

View File

@@ -850,7 +850,7 @@ class TestLibrarySearchIndexer(MixedWithOptionsTestCase):
class GroupConfigurationSearchSplit(CourseTestCase, MixedWithOptionsTestCase):
"""
Tests indexing of content groups on course modules using split modulestore.
Tests indexing of content groups on course blocks using split modulestore.
"""
CREATE_USER = True
INDEX_NAME = CoursewareSearchIndexer.INDEX_NAME

View File

@@ -33,7 +33,7 @@ class TestExportGit(CourseTestCase):
Setup test course, user, and url.
"""
super().setUp()
self.course_module = modulestore().get_course(self.course.id)
self.course_block = modulestore().get_course(self.course.id)
self.test_url = reverse_course_url('export_git', self.course.id)
def make_bare_repo_with_course(self, repo_name):
@@ -55,8 +55,8 @@ class TestExportGit(CourseTestCase):
subprocess.check_output(['git', '--bare', 'init', ], cwd=bare_repo_dir)
self.populate_course()
self.course_module.giturl = f'file://{bare_repo_dir}'
modulestore().update_item(self.course_module, self.user.id)
self.course_block.giturl = f'file://{bare_repo_dir}'
modulestore().update_item(self.course_block, self.user.id)
def test_giturl_missing(self):
"""
@@ -81,8 +81,8 @@ class TestExportGit(CourseTestCase):
"""
Test failed course export response.
"""
self.course_module.giturl = 'foobar'
modulestore().update_item(self.course_module, self.user.id)
self.course_block.giturl = 'foobar'
modulestore().update_item(self.course_block, self.user.id)
response = self.client.get(f'{self.test_url}?action=push')
self.assertContains(response, 'Export Failed:')
@@ -91,8 +91,8 @@ class TestExportGit(CourseTestCase):
"""
Regression test for making sure errors are properly stringified
"""
self.course_module.giturl = 'foobar'
modulestore().update_item(self.course_module, self.user.id)
self.course_block.giturl = 'foobar'
modulestore().update_item(self.course_block, self.user.id)
response = self.client.get(f'{self.test_url}?action=push')
self.assertNotContains(response, 'django.utils.functional.__proxy__')
@@ -123,11 +123,11 @@ class TestExportGit(CourseTestCase):
repo_name = 'dirty_repo1'
self.make_bare_repo_with_course(repo_name)
git_export_utils.export_to_git(self.course.id,
self.course_module.giturl, self.user)
self.course_block.giturl, self.user)
# Make arbitrary change to course to make diff
self.course_module.matlab_api_key = 'something'
modulestore().update_item(self.course_module, self.user.id)
self.course_block.matlab_api_key = 'something'
modulestore().update_item(self.course_block, self.user.id)
# Touch a file in the directory, export again, and make sure
# the test file is gone
repo_dir = os.path.join(
@@ -138,5 +138,5 @@ class TestExportGit(CourseTestCase):
open(test_file, 'a').close()
self.assertTrue(os.path.isfile(test_file))
git_export_utils.export_to_git(self.course.id,
self.course_module.giturl, self.user)
self.course_block.giturl, self.user)
self.assertFalse(os.path.isfile(test_file))

View File

@@ -102,11 +102,11 @@ def _asset_index(request, course_key):
Supports start (0-based index into the list of assets) and max query parameters.
'''
course_module = modulestore().get_course(course_key)
course_block = modulestore().get_course(course_key)
return render_to_response('asset_index.html', {
'language_code': request.LANGUAGE_CODE,
'context_course': course_module,
'context_course': course_block,
'max_file_size_in_mbs': settings.MAX_ASSET_UPLOAD_FILE_SIZE_IN_MB,
'chunk_size_in_mbs': settings.UPLOAD_CHUNK_SIZE_IN_MB,
'max_file_size_redirect_url': settings.MAX_ASSET_UPLOAD_FILE_SIZE_URL,

View File

@@ -63,12 +63,12 @@ LOGGER = logging.getLogger(__name__)
def _get_course_and_check_access(course_key, user, depth=0):
"""
Internal method used to calculate and return the locator and
course module for the view functions in this file.
course block for the view functions in this file.
"""
if not has_studio_write_access(user, course_key):
raise PermissionDenied()
course_module = modulestore().get_course(course_key, depth=depth)
return course_module
course_block = modulestore().get_course(course_key, depth=depth)
return course_block
def _delete_asset(course_key, asset_key_string):

View File

@@ -27,9 +27,9 @@ def checklists_handler(request, course_key_string=None):
if not has_course_author_access(request.user, course_key):
raise PermissionDenied()
course_module = modulestore().get_course(course_key)
course_block = modulestore().get_course(course_key)
return render_to_response('checklists.html', {
'language_code': request.LANGUAGE_CODE,
'context_course': course_module,
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
'context_course': course_block,
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
})

View File

@@ -149,13 +149,13 @@ class AccessListFallback(Exception):
def get_course_and_check_access(course_key, user, depth=0):
"""
Function used to calculate and return the locator and course module
Function used to calculate and return the locator and course block
for the view functions in this file.
"""
if not has_studio_read_access(user, course_key):
raise PermissionDenied()
course_module = modulestore().get_course(course_key, depth=depth)
return course_module
course_block = modulestore().get_course(course_key, depth=depth)
return course_block
def reindex_course_and_check_access(course_key, user):
@@ -285,8 +285,8 @@ def course_handler(request, course_key_string=None):
if request.method == 'GET':
course_key = CourseKey.from_string(course_key_string)
with modulestore().bulk_operations(course_key):
course_module = get_course_and_check_access(course_key, request.user, depth=None)
return JsonResponse(_course_outline_json(request, course_module))
course_block = get_course_and_check_access(course_key, request.user, depth=None)
return JsonResponse(_course_outline_json(request, course_block))
elif request.method == 'POST': # not sure if this is only post. If one will have ids, it goes after access
return _create_or_rerun_course(request)
elif not has_studio_write_access(request.user, CourseKey.from_string(course_key_string)):
@@ -322,11 +322,11 @@ def course_rerun_handler(request, course_key_string):
raise PermissionDenied()
course_key = CourseKey.from_string(course_key_string)
with modulestore().bulk_operations(course_key):
course_module = get_course_and_check_access(course_key, request.user, depth=3)
course_block = get_course_and_check_access(course_key, request.user, depth=3)
if request.method == 'GET':
return render_to_response('course-create-rerun.html', {
'source_course_key': course_key,
'display_name': course_module.display_name,
'display_name': course_block.display_name,
'user': request.user,
'course_creator_status': _get_course_creator_status(request.user),
'allow_unicode_course_id': settings.FEATURES.get('ALLOW_UNICODE_COURSE_ID', False)
@@ -362,16 +362,16 @@ def course_search_index_handler(request, course_key_string):
}), content_type=content_type, status=200)
def _course_outline_json(request, course_module):
def _course_outline_json(request, course_block):
"""
Returns a JSON representation of the course module and recursively all of its children.
Returns a JSON representation of the course block and recursively all of its children.
"""
is_concise = request.GET.get('format') == 'concise'
include_children_predicate = lambda xblock: not xblock.category == 'vertical'
if is_concise:
include_children_predicate = lambda xblock: xblock.has_children
return create_xblock_info(
course_module,
course_block,
include_child_info=True,
course_outline=False if is_concise else True, # lint-amnesty, pylint: disable=simplifiable-if-expression
include_children_predicate=include_children_predicate,
@@ -640,12 +640,12 @@ def _get_rerun_link_for_item(course_key):
return reverse_course_url('course_rerun_handler', course_key)
def _deprecated_blocks_info(course_module, deprecated_block_types):
def _deprecated_blocks_info(course_block, deprecated_block_types):
"""
Returns deprecation information about `deprecated_block_types`
Arguments:
course_module (CourseBlock): course object
course_block (CourseBlock): course object
deprecated_block_types (list): list of deprecated blocks types
Returns:
@@ -656,14 +656,14 @@ def _deprecated_blocks_info(course_module, deprecated_block_types):
"""
data = {
'deprecated_enabled_block_types': [
block_type for block_type in course_module.advanced_modules if block_type in deprecated_block_types
block_type for block_type in course_block.advanced_modules if block_type in deprecated_block_types
],
'blocks': [],
'advance_settings_url': reverse_course_url('advanced_settings_handler', course_module.id)
'advance_settings_url': reverse_course_url('advanced_settings_handler', course_block.id)
}
deprecated_blocks = modulestore().get_items(
course_module.id,
course_block.id,
qualifiers={
'category': re.compile('^' + '$|^'.join(deprecated_block_types) + '$')
}
@@ -689,21 +689,21 @@ def course_index(request, course_key):
# A depth of None implies the whole course. The course outline needs this in order to compute has_changes.
# A unit may not have a draft version, but one of its components could, and hence the unit itself has changes.
with modulestore().bulk_operations(course_key):
course_module = get_course_and_check_access(course_key, request.user, depth=None)
if not course_module:
course_block = get_course_and_check_access(course_key, request.user, depth=None)
if not course_block:
raise Http404
lms_link = get_lms_link_for_item(course_module.location)
lms_link = get_lms_link_for_item(course_block.location)
reindex_link = None
if settings.FEATURES.get('ENABLE_COURSEWARE_INDEX', False):
if GlobalStaff().has_user(request.user):
reindex_link = f"/course/{str(course_key)}/search_reindex"
sections = course_module.get_children()
course_structure = _course_outline_json(request, course_module)
sections = course_block.get_children()
course_structure = _course_outline_json(request, course_block)
locator_to_show = request.GET.get('show', None)
course_release_date = (
get_default_time_display(course_module.start)
if course_module.start != DEFAULT_START_DATE
get_default_time_display(course_block.start)
if course_block.start != DEFAULT_START_DATE
else _("Set Date")
)
@@ -715,16 +715,16 @@ def course_index(request, course_key):
current_action = None
deprecated_block_names = [block.name for block in deprecated_xblocks()]
deprecated_blocks_info = _deprecated_blocks_info(course_module, deprecated_block_names)
deprecated_blocks_info = _deprecated_blocks_info(course_block, deprecated_block_names)
frontend_app_publisher_url = configuration_helpers.get_value_for_org(
course_module.location.org,
course_block.location.org,
'FRONTEND_APP_PUBLISHER_URL',
settings.FEATURES.get('FRONTEND_APP_PUBLISHER_URL', False)
)
# gather any errors in the currently stored proctoring settings.
advanced_dict = CourseMetadata.fetch(course_module)
proctoring_errors = CourseMetadata.validate_proctoring_settings(course_module, advanced_dict, request.user)
advanced_dict = CourseMetadata.fetch(course_block)
proctoring_errors = CourseMetadata.validate_proctoring_settings(course_block, advanced_dict, request.user)
configuration = DiscussionsConfiguration.get(course_key)
provider = configuration.provider_type
@@ -733,7 +733,7 @@ def course_index(request, course_key):
return render_to_response('course_outline.html', {
'language_code': request.LANGUAGE_CODE,
'context_course': course_module,
'context_course': course_block,
'lms_link': lms_link,
'sections': sections,
'course_structure': course_structure,
@@ -751,8 +751,8 @@ def course_index(request, course_key):
},
) if current_action else None,
'frontend_app_publisher_url': frontend_app_publisher_url,
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
'advance_settings_url': reverse_course_url('advanced_settings_handler', course_module.id),
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
'advance_settings_url': reverse_course_url('advanced_settings_handler', course_block.id),
'proctoring_errors': proctoring_errors,
})
@@ -1068,17 +1068,17 @@ def course_info_handler(request, course_key_string):
raise Http404 # lint-amnesty, pylint: disable=raise-missing-from
with modulestore().bulk_operations(course_key):
course_module = get_course_and_check_access(course_key, request.user)
if not course_module:
course_block = get_course_and_check_access(course_key, request.user)
if not course_block:
raise Http404
if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):
return render_to_response(
'course_info.html',
{
'context_course': course_module,
'context_course': course_block,
'updates_url': reverse_course_url('course_info_update_handler', course_key),
'handouts_locator': course_key.make_usage_key('course_info', 'handouts'),
'base_asset_url': StaticContent.get_base_url_path_for_course_assets(course_module.id),
'base_asset_url': StaticContent.get_base_url_path_for_course_assets(course_block.id),
}
)
else:
@@ -1153,24 +1153,24 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
course_key = CourseKey.from_string(course_key_string)
credit_eligibility_enabled = settings.FEATURES.get('ENABLE_CREDIT_ELIGIBILITY', False)
with modulestore().bulk_operations(course_key):
course_module = get_course_and_check_access(course_key, request.user)
course_block = get_course_and_check_access(course_key, request.user)
if 'text/html' in request.META.get('HTTP_ACCEPT', '') and request.method == 'GET':
upload_asset_url = reverse_course_url('assets_handler', course_key)
# see if the ORG of this course can be attributed to a defined configuration . In that case, the
# course about page should be editable in Studio
publisher_enabled = configuration_helpers.get_value_for_org(
course_module.location.org,
course_block.location.org,
'ENABLE_PUBLISHER',
settings.FEATURES.get('ENABLE_PUBLISHER', False)
)
marketing_enabled = configuration_helpers.get_value_for_org(
course_module.location.org,
course_block.location.org,
'ENABLE_MKTG_SITE',
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
)
enable_extended_course_details = configuration_helpers.get_value_for_org(
course_module.location.org,
course_block.location.org,
'ENABLE_EXTENDED_COURSE_DETAILS',
settings.FEATURES.get('ENABLE_EXTENDED_COURSE_DETAILS', False)
)
@@ -1178,7 +1178,7 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
about_page_editable = not publisher_enabled
enrollment_end_editable = GlobalStaff().has_user(request.user) or not publisher_enabled
short_description_editable = configuration_helpers.get_value_for_org(
course_module.location.org,
course_block.location.org,
'EDITABLE_SHORT_DESCRIPTION',
settings.FEATURES.get('EDITABLE_SHORT_DESCRIPTION', True)
)
@@ -1188,12 +1188,12 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
upgrade_deadline = (verified_mode and verified_mode.expiration_datetime and
verified_mode.expiration_datetime.isoformat())
settings_context = {
'context_course': course_module,
'context_course': course_block,
'course_locator': course_key,
'lms_link_for_about_page': get_link_for_about_page(course_module),
'course_image_url': course_image_url(course_module, 'course_image'),
'banner_image_url': course_image_url(course_module, 'banner_image'),
'video_thumbnail_image_url': course_image_url(course_module, 'video_thumbnail_image'),
'lms_link_for_about_page': get_link_for_about_page(course_block),
'course_image_url': course_image_url(course_block, 'course_image'),
'banner_image_url': course_image_url(course_block, 'banner_image'),
'video_thumbnail_image_url': course_image_url(course_block, 'video_thumbnail_image'),
'details_url': reverse_course_url('settings_handler', course_key),
'about_page_editable': about_page_editable,
'marketing_enabled': marketing_enabled,
@@ -1210,7 +1210,7 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
'is_entrance_exams_enabled': core_toggles.ENTRANCE_EXAMS.is_enabled(),
'enable_extended_course_details': enable_extended_course_details,
'upgrade_deadline': upgrade_deadline,
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
}
if is_prerequisite_courses_enabled():
courses, in_process_course_actions = get_courses_accessible_to_user(request)
@@ -1232,7 +1232,7 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
# if 'minimum_grade_credit' of a course is not set or 0 then
# show warning message to course author.
show_min_grade_warning = False if course_module.minimum_grade_credit > 0 else True # lint-amnesty, pylint: disable=simplifiable-if-expression
show_min_grade_warning = False if course_block.minimum_grade_credit > 0 else True # lint-amnesty, pylint: disable=simplifiable-if-expression
settings_context.update(
{
'is_credit_course': True,
@@ -1278,7 +1278,7 @@ def settings_handler(request, course_key_string): # lint-amnesty, pylint: disab
# We have to be careful that we're only executing the following logic if we actually
# need to create or delete an entrance exam from the specified course
if core_toggles.ENTRANCE_EXAMS.is_enabled():
course_entrance_exam_present = course_module.entrance_exam_enabled
course_entrance_exam_present = course_block.entrance_exam_enabled
entrance_exam_enabled = request.json.get('entrance_exam_enabled', '') == 'true'
ee_min_score_pct = request.json.get('entrance_exam_minimum_score_pct', None)
# If the entrance exam box on the settings screen has been checked...
@@ -1328,17 +1328,17 @@ def grading_handler(request, course_key_string, grader_index=None):
"""
course_key = CourseKey.from_string(course_key_string)
with modulestore().bulk_operations(course_key):
course_module = get_course_and_check_access(course_key, request.user)
course_block = get_course_and_check_access(course_key, request.user)
if 'text/html' in request.META.get('HTTP_ACCEPT', '') and request.method == 'GET':
course_details = CourseGradingModel.fetch(course_key)
return render_to_response('settings_graders.html', {
'context_course': course_module,
'context_course': course_block,
'course_locator': course_key,
'course_details': course_details,
'grading_url': reverse_course_url('grading_handler', course_key),
'is_credit_course': is_credit_course(course_key),
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
})
elif 'application/json' in request.META.get('HTTP_ACCEPT', ''):
if request.method == 'GET':
@@ -1371,7 +1371,7 @@ def grading_handler(request, course_key_string, grader_index=None):
return JsonResponse()
def _refresh_course_tabs(user: User, course_module: CourseBlock):
def _refresh_course_tabs(user: User, course_block: CourseBlock):
"""
Automatically adds/removes tabs if changes to the course require them.
@@ -1392,19 +1392,19 @@ def _refresh_course_tabs(user: User, course_module: CourseBlock):
elif not tab_enabled and has_tab:
tabs.remove(tab_panel)
course_tabs = copy.copy(course_module.tabs)
course_tabs = copy.copy(course_block.tabs)
# Additionally update any tabs that are provided by non-dynamic course views
for tab_type in CourseTabPluginManager.get_tab_types():
if not tab_type.is_dynamic and tab_type.is_default:
tab_enabled = tab_type.is_enabled(course_module, user=user)
tab_enabled = tab_type.is_enabled(course_block, user=user)
update_tab(course_tabs, tab_type, tab_enabled)
CourseTabList.validate_tabs(course_tabs)
# Save the tabs into the course if they have been changed
if course_tabs != course_module.tabs:
course_module.tabs = course_tabs
if course_tabs != course_block.tabs:
course_block.tabs = course_tabs
@login_required
@@ -1423,42 +1423,42 @@ def advanced_settings_handler(request, course_key_string):
"""
course_key = CourseKey.from_string(course_key_string)
with modulestore().bulk_operations(course_key):
course_module = get_course_and_check_access(course_key, request.user)
course_block = get_course_and_check_access(course_key, request.user)
advanced_dict = CourseMetadata.fetch(course_module)
advanced_dict = CourseMetadata.fetch(course_block)
if settings.FEATURES.get('DISABLE_MOBILE_COURSE_AVAILABLE', False):
advanced_dict.get('mobile_available')['deprecated'] = True
if 'text/html' in request.META.get('HTTP_ACCEPT', '') and request.method == 'GET':
publisher_enabled = configuration_helpers.get_value_for_org(
course_module.location.org,
course_block.location.org,
'ENABLE_PUBLISHER',
settings.FEATURES.get('ENABLE_PUBLISHER', False)
)
# gather any errors in the currently stored proctoring settings.
proctoring_errors = CourseMetadata.validate_proctoring_settings(course_module, advanced_dict, request.user)
proctoring_errors = CourseMetadata.validate_proctoring_settings(course_block, advanced_dict, request.user)
return render_to_response('settings_advanced.html', {
'context_course': course_module,
'context_course': course_block,
'advanced_dict': advanced_dict,
'advanced_settings_url': reverse_course_url('advanced_settings_handler', course_key),
'publisher_enabled': publisher_enabled,
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_module.id),
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
'proctoring_errors': proctoring_errors,
})
elif 'application/json' in request.META.get('HTTP_ACCEPT', ''):
if request.method == 'GET':
return JsonResponse(CourseMetadata.fetch(course_module))
return JsonResponse(CourseMetadata.fetch(course_block))
else:
try:
return JsonResponse(
update_course_advanced_settings(course_module, request.json, request.user)
update_course_advanced_settings(course_block, request.json, request.user)
)
except ValidationError as err:
return JsonResponseBadRequest(err.detail)
def update_course_advanced_settings(course_module: CourseBlock, data: Dict, user: User) -> Dict:
def update_course_advanced_settings(course_block: CourseBlock, data: Dict, user: User) -> Dict:
"""
Helper function to update course advanced settings from API data.
@@ -1466,7 +1466,7 @@ def update_course_advanced_settings(course_module: CourseBlock, data: Dict, user
it to the course advanced settings.
Args:
course_module (CourseBlock): The course run object on which to operate.
course_block (CourseBlock): The course run object on which to operate.
data (Dict): JSON data as found the ``request.data``
user (User): The user performing the operation
@@ -1474,10 +1474,10 @@ def update_course_advanced_settings(course_module: CourseBlock, data: Dict, user
Dict: The updated data after applying changes based on supplied data.
"""
try:
# validate data formats and update the course module.
# validate data formats and update the course block.
# Note: don't update mongo yet, but wait until after any tabs are changed
is_valid, errors, updated_data = CourseMetadata.validate_and_update_from_json(
course_module,
course_block,
data,
user=user,
)
@@ -1487,7 +1487,7 @@ def update_course_advanced_settings(course_module: CourseBlock, data: Dict, user
try:
# update the course tabs if required by any setting changes
_refresh_course_tabs(user, course_module)
_refresh_course_tabs(user, course_block)
except InvalidTabsException as err:
log.exception(str(err))
response_message = [
@@ -1499,7 +1499,7 @@ def update_course_advanced_settings(course_module: CourseBlock, data: Dict, user
raise ValidationError(response_message) from err
# now update mongo
modulestore().update_item(course_module, user.id)
modulestore().update_item(course_block, user.id)
return updated_data
@@ -1665,8 +1665,8 @@ def textbooks_detail_handler(request, course_key_string, textbook_id):
course_key = CourseKey.from_string(course_key_string)
store = modulestore()
with store.bulk_operations(course_key):
course_module = get_course_and_check_access(course_key, request.user)
matching_id = [tb for tb in course_module.pdf_textbooks
course_block = get_course_and_check_access(course_key, request.user)
matching_id = [tb for tb in course_block.pdf_textbooks
if str(tb.get("id")) == str(textbook_id)]
if matching_id:
textbook = matching_id[0]
@@ -1684,23 +1684,23 @@ def textbooks_detail_handler(request, course_key_string, textbook_id):
return JsonResponse({"error": str(err)}, status=400)
new_textbook["id"] = textbook_id
if textbook:
i = course_module.pdf_textbooks.index(textbook)
new_textbooks = course_module.pdf_textbooks[0:i]
i = course_block.pdf_textbooks.index(textbook)
new_textbooks = course_block.pdf_textbooks[0:i]
new_textbooks.append(new_textbook)
new_textbooks.extend(course_module.pdf_textbooks[i + 1:])
course_module.pdf_textbooks = new_textbooks
new_textbooks.extend(course_block.pdf_textbooks[i + 1:])
course_block.pdf_textbooks = new_textbooks
else:
course_module.pdf_textbooks.append(new_textbook)
store.update_item(course_module, request.user.id)
course_block.pdf_textbooks.append(new_textbook)
store.update_item(course_block, request.user.id)
return JsonResponse(new_textbook, status=201)
elif request.method == 'DELETE':
if not textbook:
return JsonResponse(status=404)
i = course_module.pdf_textbooks.index(textbook)
remaining_textbooks = course_module.pdf_textbooks[0:i]
remaining_textbooks.extend(course_module.pdf_textbooks[i + 1:])
course_module.pdf_textbooks = remaining_textbooks
store.update_item(course_module, request.user.id)
i = course_block.pdf_textbooks.index(textbook)
remaining_textbooks = course_block.pdf_textbooks[0:i]
remaining_textbooks.extend(course_block.pdf_textbooks[i + 1:])
course_block.pdf_textbooks = remaining_textbooks
store.update_item(course_block, request.user.id)
return JsonResponse()

View File

@@ -30,18 +30,18 @@ def export_git(request, course_key_string):
if not has_course_author_access(request.user, course_key):
raise PermissionDenied()
course_module = modulestore().get_course(course_key)
course_block = modulestore().get_course(course_key)
failed = False
log.debug('export_git course_module=%s', course_module)
log.debug('export_git course_block=%s', course_block)
msg = ""
if 'action' in request.GET and course_module.giturl:
if 'action' in request.GET and course_block.giturl:
if request.GET['action'] == 'push':
try:
git_export_utils.export_to_git(
course_module.id,
course_module.giturl,
course_block.id,
course_block.giturl,
request.user,
)
msg = _('Course successfully exported to git repository')
@@ -50,7 +50,7 @@ def export_git(request, course_key_string):
msg = str(ex)
return render_to_response('export_git.html', {
'context_course': course_module,
'context_course': course_block,
'msg': msg,
'failed': failed,
})

View File

@@ -254,7 +254,7 @@ def create_xblock(parent_locator, user, category, display_name, boilerplate=None
user
)
# VS[compat] cdodge: This is a hack because static_tabs also have references from the course module, so
# VS[compat] cdodge: This is a hack because static_tabs also have references from the course block, so
# if we add one then we need to also add it to the policy information (i.e. metadata)
# we should remove this once we can break this reference from the course to static tabs
if category == 'static_tab':

View File

@@ -979,7 +979,7 @@ def _delete_item(usage_key, user):
store = modulestore()
with store.bulk_operations(usage_key.course_key):
# VS[compat] cdodge: This is a hack because static_tabs also have references from the course module, so
# VS[compat] cdodge: This is a hack because static_tabs also have references from the course block, so
# if we add one then we need to also add it to the policy information (i.e. metadata)
# we should remove this once we can break this reference from the course to static tabs
if usage_key.block_type == 'static_tab':
@@ -1105,7 +1105,7 @@ def _get_gating_info(course, xblock):
info = {}
if xblock.category == 'sequential' and course.enable_subsection_gating:
if not hasattr(course, 'gating_prerequisites'):
# Cache gating prerequisites on course module so that we are not
# Cache gating prerequisites on course block so that we are not
# hitting the database for every xblock in the course
course.gating_prerequisites = gating_api.get_prerequisites(course.id)
info["is_prereq"] = gating_api.is_prerequisite(course.id, xblock.location)

View File

@@ -106,7 +106,7 @@ def update_tabs_handler(course_item: CourseBlock, tabs_data: Dict, user: User) -
Helper to handle updates to course tabs based on API data.
Args:
course_item (CourseBlock): Course module whose tabs need to be updated
course_item (CourseBlock): Course block whose tabs need to be updated
tabs_data (Dict): JSON formatted data for updating or reordering tabs.
user (User): The user performing the operation.
"""

View File

@@ -525,9 +525,9 @@ class TestCourseOutline(CourseTestCase):
self.assert_correct_json_response(child_response, is_concise)
def test_course_outline_initial_state(self):
course_module = modulestore().get_item(self.course.location)
course_block = modulestore().get_item(self.course.location)
course_structure = create_xblock_info(
course_module,
course_block,
include_child_info=True,
include_children_predicate=lambda xblock: not xblock.category == 'vertical'
)
@@ -543,7 +543,7 @@ class TestCourseOutline(CourseTestCase):
self.assertIn(str(self.sequential.location), expanded_locators)
self.assertIn(str(self.vertical.location), expanded_locators)
def _create_test_data(self, course_module, create_blocks=False, publish=True, block_types=None):
def _create_test_data(self, course_block, create_blocks=False, publish=True, block_types=None):
"""
Create data for test.
"""
@@ -558,7 +558,7 @@ class TestCourseOutline(CourseTestCase):
if not publish:
self.store.unpublish(self.vertical.location, self.user.id)
course_module.advanced_modules.extend(block_types)
course_block.advanced_modules.extend(block_types)
def _verify_deprecated_info(self, course_id, advanced_modules, info, deprecated_block_types):
"""
@@ -594,12 +594,12 @@ class TestCourseOutline(CourseTestCase):
"""
Verify deprecated warning info.
"""
course_module = modulestore().get_item(self.course.location)
self._create_test_data(course_module, create_blocks=True, block_types=block_types, publish=publish)
info = _deprecated_blocks_info(course_module, block_types)
course_block = modulestore().get_item(self.course.location)
self._create_test_data(course_block, create_blocks=True, block_types=block_types, publish=publish)
info = _deprecated_blocks_info(course_block, block_types)
self._verify_deprecated_info(
course_module.id,
course_module.advanced_modules,
course_block.id,
course_block.advanced_modules,
info,
block_types
)
@@ -611,17 +611,17 @@ class TestCourseOutline(CourseTestCase):
(["a", "b", "c"], ["d", "e", "f"])
)
@ddt.unpack
def test_verify_warn_only_on_enabled_modules(self, enabled_block_types, deprecated_block_types):
def test_verify_warn_only_on_enabled_blocks(self, enabled_block_types, deprecated_block_types):
"""
Verify that we only warn about block_types that are both deprecated and enabled.
"""
expected_block_types = list(set(enabled_block_types) & set(deprecated_block_types))
course_module = modulestore().get_item(self.course.location)
self._create_test_data(course_module, create_blocks=True, block_types=enabled_block_types)
info = _deprecated_blocks_info(course_module, deprecated_block_types)
course_block = modulestore().get_item(self.course.location)
self._create_test_data(course_block, create_blocks=True, block_types=enabled_block_types)
info = _deprecated_blocks_info(course_block, deprecated_block_types)
self._verify_deprecated_info(
course_module.id,
course_module.advanced_modules,
course_block.id,
course_block.advanced_modules,
info,
expected_block_types
)

View File

@@ -79,7 +79,7 @@ def _manage_users(request, course_key):
if not user_perms & STUDIO_VIEW_USERS:
raise PermissionDenied()
course_module = modulestore().get_course(course_key)
course_block = modulestore().get_course(course_key)
instructors = set(CourseInstructorRole(course_key).users_with_role())
# the page only lists staff and assumes they're a superset of instructors. Do a union to ensure.
staff = set(CourseStaffRole(course_key).users_with_role()).union(instructors)
@@ -91,7 +91,7 @@ def _manage_users(request, course_key):
formatted_users.append(user_with_role(user, 'staff'))
return render_to_response('manage_users.html', {
'context_course': course_module,
'context_course': course_block,
'show_transfer_ownership_hint': request.user in instructors and len(instructors) == 1,
'users': formatted_users,
'allow_actions': bool(user_perms & STUDIO_EDIT_ROLES),