Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: make xmodule & openedx independent of code in cms #27874

Merged
merged 3 commits into from
Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions cms/djangoapps/contentstore/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

COURSE_ALREADY_EXIST = _('Aborting import because a course with this id: {} already exists.')
COURSE_PERMISSION_DENIED = _('Permission denied. You do not have write access to this course.')
ERROR_WHILE_READING = _('Error while reading {}. Check file for XML errors.')
FAILED_TO_IMPORT_MODULE = _('Failed to import module: {} at location: {}')
FILE_MISSING = _('Could not find the {0} file in the package.')
FILE_NOT_FOUND = _('Uploaded Tar file not found. Try again.')
INVALID_FILE_TYPE = _('We only support uploading a .tar.gz file.')
Expand Down
30 changes: 0 additions & 30 deletions cms/djangoapps/contentstore/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,15 @@
"""
A common module for managing exceptions. Helps to avoid circular references
"""
from .errors import ERROR_WHILE_READING, FAILED_TO_IMPORT_MODULE


class CourseImportException(Exception):
"""Base exception class for course import workflows."""

def __init__(self):
super().__init__(self.description) # pylint: disable=no-member


class ErrorReadingFileException(CourseImportException):
"""
Raised when error occurs while trying to read a file.
"""

def __init__(self, filename, **kwargs):
self.description = ERROR_WHILE_READING.format(filename)
super().__init__(**kwargs)


class ModuleFailedToImport(CourseImportException):
"""
Raised when a module is failed to import.
"""

def __init__(self, display_name, location, **kwargs):
self.description = FAILED_TO_IMPORT_MODULE.format(display_name, location)
super().__init__(**kwargs)


class AssetNotFoundException(Exception):
"""
Raised when asset not found
"""
pass # lint-amnesty, pylint: disable=unnecessary-pass


class AssetSizeTooLargeException(Exception):
"""
Raised when the size of an uploaded asset exceeds the maximum size limit.
"""
pass # lint-amnesty, pylint: disable=unnecessary-pass
9 changes: 9 additions & 0 deletions cms/djangoapps/contentstore/signals/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ def listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=
update_search_index.delay(course_key_str, datetime.now(UTC).isoformat())


@receiver(SignalHandler.course_deleted)
def listen_for_course_delete(sender, course_key, **kwargs): # pylint: disable=unused-argument
"""
Catches the signal that a course has been deleted
and removes its entry from the Course About Search index.
"""
CourseAboutSearchIndexer.remove_deleted_items(course_key)


@receiver(SignalHandler.library_updated)
def listen_for_library_update(sender, library_key, **kwargs): # pylint: disable=unused-argument
"""
Expand Down
3 changes: 1 addition & 2 deletions cms/djangoapps/contentstore/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import DuplicateCourseError, InvalidProctoringProvider, ItemNotFoundError
from xmodule.modulestore.xml_exporter import export_course_to_xml, export_library_to_xml
from xmodule.modulestore.xml_importer import import_course_from_xml, import_library_from_xml
from xmodule.modulestore.xml_importer import CourseImportException, import_course_from_xml, import_library_from_xml

from .exceptions import CourseImportException
from .outlines import update_outline_from_modulestore
from .outlines_regenerate import CourseOutlineRegenerate
from .toggles import bypass_olx_failure_enabled
Expand Down
9 changes: 7 additions & 2 deletions cms/djangoapps/contentstore/views/tests/test_import_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from user_tasks.models import UserTaskStatus

from cms.djangoapps.contentstore import errors as import_error
from cms.djangoapps.contentstore.exceptions import ErrorReadingFileException, ModuleFailedToImport
from cms.djangoapps.contentstore.storage import course_import_export_storage
from cms.djangoapps.contentstore.tests.test_libraries import LibraryTestCase
from cms.djangoapps.contentstore.tests.utils import CourseTestCase
Expand All @@ -45,7 +44,13 @@
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, LibraryFactory
from xmodule.modulestore.tests.utils import SPLIT_MODULESTORE_SETUP, TEST_DATA_DIR, MongoContentstoreBuilder
from xmodule.modulestore.xml_exporter import export_course_to_xml, export_library_to_xml
from xmodule.modulestore.xml_importer import CourseImportManager, import_course_from_xml, import_library_from_xml
from xmodule.modulestore.xml_importer import (
CourseImportManager,
ErrorReadingFileException,
import_course_from_xml,
import_library_from_xml,
ModuleFailedToImport,
)

TASK_LOGGER = 'cms.djangoapps.contentstore.tasks.LOGGER'
TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
Expand Down
3 changes: 1 addition & 2 deletions common/lib/xmodule/xmodule/library_sourced_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from webob import Response
from web_fragments.fragment import Fragment

from cms.lib.xblock.runtime import handler_url
from xmodule.studio_editable import StudioEditableBlock as EditableChildrenMixin
from xmodule.validation import StudioValidation, StudioValidationMessage

Expand Down Expand Up @@ -78,7 +77,7 @@ def studio_view(self, context):
)
fragment.content = loader.render_django_template('templates/library-sourced-block-studio-view.html', {
'react_content': react_content,
'save_url': handler_url(self, 'submit_studio_edits'),
'save_url': self.runtime.handler_url(self, 'submit_studio_edits'),
})

fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/library_source_block.js'))
Expand Down
35 changes: 34 additions & 1 deletion common/lib/xmodule/xmodule/modulestore/xml_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from abc import abstractmethod

import xblock
from django.utils.translation import ugettext as _
from lxml import etree
from opaque_keys.edx.keys import UsageKey
from opaque_keys.edx.locator import LibraryLocator
Expand All @@ -37,7 +38,6 @@
from xblock.fields import Reference, ReferenceList, ReferenceValueDict, Scope
from xblock.runtime import DictKeyValueStore, KvsFieldData

from cms.djangoapps.contentstore.exceptions import ErrorReadingFileException, ModuleFailedToImport
from common.djangoapps.util.monitoring import monitor_import_failure
from xmodule.assetstore import AssetMetadata
from xmodule.contentstore.content import StaticContent
Expand All @@ -61,6 +61,39 @@
DEFAULT_STATIC_CONTENT_SUBDIR = 'static'


class CourseImportException(Exception):
"""
Base exception class for course import workflows.
"""

def __init__(self):
super().__init__(self.description) # pylint: disable=no-member


class ErrorReadingFileException(CourseImportException):
"""
Raised when error occurs while trying to read a file.
"""

MESSAGE_TEMPLATE = _('Error while reading {}. Check file for XML errors.')

def __init__(self, filename, **kwargs):
self.description = self.MESSAGE_TEMPLATE.format(filename)
super().__init__(**kwargs)


class ModuleFailedToImport(CourseImportException):
"""
Raised when a module is failed to import.
"""

MESSAGE_TEMPLATE = _('Failed to import module: {} at location: {}')

def __init__(self, display_name, location, **kwargs):
self.description = self.MESSAGE_TEMPLATE.format(display_name, location)
super().__init__(**kwargs)


class LocationMixin(XBlockMixin):
"""
Adds a `location` property to an :class:`XBlock` so it is more compatible
Expand Down
4 changes: 0 additions & 4 deletions openedx/core/djangoapps/content/course_overviews/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ def _listen_for_course_delete(sender, course_key, **kwargs): # pylint: disable=
invalidates the corresponding CourseOverview cache entry if one exists.
"""
CourseOverview.objects.filter(id=course_key).delete()
# import CourseAboutSearchIndexer inline due to cyclic import
from cms.djangoapps.contentstore.courseware_index import CourseAboutSearchIndexer
# Delete course entry from Course About Search_index
CourseAboutSearchIndexer.remove_deleted_items(course_key)


def _check_for_course_changes(previous_course_overview, updated_course_overview):
Expand Down