feat: remove usage of LmsModuleSystem and PreviewModuleSystem
This commit is contained in:
committed by
Agrendalath
parent
017f8469de
commit
18fea868a9
@@ -41,8 +41,7 @@ from openedx.core.lib.xblock_utils import (
|
||||
request_token,
|
||||
wrap_fragment,
|
||||
wrap_xblock,
|
||||
wrap_xblock_aside,
|
||||
xblock_local_resource_url
|
||||
wrap_xblock_aside
|
||||
)
|
||||
|
||||
from ..utils import get_visibility_partition_info
|
||||
@@ -94,61 +93,144 @@ def preview_handler(request, usage_key_string, handler, suffix=''):
|
||||
return webob_to_django_response(resp)
|
||||
|
||||
|
||||
def handler_url(block, handler_name, suffix='', query='', thirdparty=False):
|
||||
"""
|
||||
Handler URL function for Preview
|
||||
"""
|
||||
return reverse('preview_handler', kwargs={
|
||||
'usage_key_string': str(block.scope_ids.usage_id),
|
||||
'handler': handler_name,
|
||||
'suffix': suffix,
|
||||
}) + '?' + query
|
||||
|
||||
|
||||
def preview_applicable_aside_types(block, applicable_aside_types=None):
|
||||
"""
|
||||
Remove acid_aside and honor the config record
|
||||
"""
|
||||
if not StudioConfig.asides_enabled(block.scope_ids.block_type):
|
||||
return []
|
||||
|
||||
# TODO: aside_type != 'acid_aside' check should be removed once AcidBlock is only installed during tests
|
||||
# (see https://openedx.atlassian.net/browse/TE-811)
|
||||
return [
|
||||
aside_type
|
||||
for aside_type in applicable_aside_types(block)
|
||||
if aside_type != 'acid_aside'
|
||||
]
|
||||
|
||||
|
||||
def render_child_placeholder(block, view_name, context, wrap_xblock=None):
|
||||
"""
|
||||
Renders a placeholder XBlock.
|
||||
"""
|
||||
return wrap_xblock(block, view_name, Fragment(), context)
|
||||
|
||||
|
||||
def preview_layout_asides(block, context, frag, view_name, aside_frag_fns, wrap_aside=None):
|
||||
position_for_asides = '<!-- footer for xblock_aside -->'
|
||||
result = Fragment()
|
||||
result.add_fragment_resources(frag)
|
||||
|
||||
for aside, aside_fn in aside_frag_fns:
|
||||
aside_frag = aside_fn(block, context)
|
||||
if aside_frag.content != '':
|
||||
aside_frag_wrapped = wrap_aside(block, aside, view_name, aside_frag, context)
|
||||
aside.save()
|
||||
result.add_fragment_resources(aside_frag_wrapped)
|
||||
replacement = position_for_asides + aside_frag_wrapped.content
|
||||
frag.content = frag.content.replace(position_for_asides, replacement)
|
||||
|
||||
result.add_content(frag.content)
|
||||
return result
|
||||
|
||||
|
||||
class PreviewModuleSystem(DescriptorSystem): # pylint: disable=abstract-method
|
||||
"""
|
||||
An XModule ModuleSystem for use in Studio previews
|
||||
"""
|
||||
# xblocks can check for this attribute during rendering to determine if
|
||||
# they are being rendered for preview (i.e. in Studio)
|
||||
is_author_mode = True
|
||||
#######################
|
||||
#######################
|
||||
## Set directly to system below
|
||||
#######################
|
||||
#######################
|
||||
# is_author_mode = True
|
||||
|
||||
def handler_url(self, block, handler_name, suffix='', query='', thirdparty=False):
|
||||
return reverse('preview_handler', kwargs={
|
||||
'usage_key_string': str(block.scope_ids.usage_id),
|
||||
'handler': handler_name,
|
||||
'suffix': suffix,
|
||||
}) + '?' + query
|
||||
#######################
|
||||
#######################
|
||||
## Implemented as handler_url above
|
||||
#######################
|
||||
#######################
|
||||
# def handler_url(self, block, handler_name, suffix='', query='', thirdparty=False):
|
||||
# return reverse('preview_handler', kwargs={
|
||||
# 'usage_key_string': str(block.scope_ids.usage_id),
|
||||
# 'handler': handler_name,
|
||||
# 'suffix': suffix,
|
||||
# }) + '?' + query
|
||||
|
||||
def local_resource_url(self, block, uri):
|
||||
return xblock_local_resource_url(block, uri)
|
||||
#######################
|
||||
#######################
|
||||
## Being monkey patched in Descriptor system from cms.djangoapps.xblock_config.apps.py
|
||||
#######################
|
||||
#######################
|
||||
# def local_resource_url(self, block, uri):
|
||||
# return xblock_local_resource_url(block, uri)
|
||||
|
||||
def applicable_aside_types(self, block):
|
||||
"""
|
||||
Remove acid_aside and honor the config record
|
||||
"""
|
||||
if not StudioConfig.asides_enabled(block.scope_ids.block_type):
|
||||
return []
|
||||
#######################
|
||||
#######################
|
||||
## Implemented as preview_applicable_aside_types above
|
||||
#######################
|
||||
#######################
|
||||
# def applicable_aside_types(self, block):
|
||||
# """
|
||||
# Remove acid_aside and honor the config record
|
||||
# """
|
||||
# if not StudioConfig.asides_enabled(block.scope_ids.block_type):
|
||||
# return []
|
||||
|
||||
# TODO: aside_type != 'acid_aside' check should be removed once AcidBlock is only installed during tests
|
||||
# (see https://openedx.atlassian.net/browse/TE-811)
|
||||
return [
|
||||
aside_type
|
||||
for aside_type in super().applicable_aside_types(block)
|
||||
if aside_type != 'acid_aside'
|
||||
]
|
||||
# # TODO: aside_type != 'acid_aside' check should be removed once AcidBlock is only installed during tests
|
||||
# # (see https://openedx.atlassian.net/browse/TE-811)
|
||||
# return [
|
||||
# aside_type
|
||||
# for aside_type in super().applicable_aside_types(block)
|
||||
# if aside_type != 'acid_aside'
|
||||
# ]
|
||||
|
||||
def render_child_placeholder(self, block, view_name, context):
|
||||
"""
|
||||
Renders a placeholder XBlock.
|
||||
"""
|
||||
return self.wrap_xblock(block, view_name, Fragment(), context)
|
||||
#######################
|
||||
#######################
|
||||
## Implemented as render_child_placeholder above
|
||||
#######################
|
||||
#######################
|
||||
# def render_child_placeholder(self, block, view_name, context):
|
||||
# """
|
||||
# Renders a placeholder XBlock.
|
||||
# """
|
||||
# return self.wrap_xblock(block, view_name, Fragment(), context)
|
||||
|
||||
def layout_asides(self, block, context, frag, view_name, aside_frag_fns):
|
||||
position_for_asides = '<!-- footer for xblock_aside -->'
|
||||
result = Fragment()
|
||||
result.add_fragment_resources(frag)
|
||||
|
||||
#######################
|
||||
#######################
|
||||
## Implemented as preview_layout_asides above
|
||||
#######################
|
||||
#######################
|
||||
# def layout_asides(self, block, context, frag, view_name, aside_frag_fns):
|
||||
# position_for_asides = '<!-- footer for xblock_aside -->'
|
||||
# result = Fragment()
|
||||
# result.add_fragment_resources(frag)
|
||||
|
||||
for aside, aside_fn in aside_frag_fns:
|
||||
aside_frag = aside_fn(block, context)
|
||||
if aside_frag.content != '':
|
||||
aside_frag_wrapped = self.wrap_aside(block, aside, view_name, aside_frag, context)
|
||||
aside.save()
|
||||
result.add_fragment_resources(aside_frag_wrapped)
|
||||
replacement = position_for_asides + aside_frag_wrapped.content
|
||||
frag.content = frag.content.replace(position_for_asides, replacement)
|
||||
# for aside, aside_fn in aside_frag_fns:
|
||||
# aside_frag = aside_fn(block, context)
|
||||
# if aside_frag.content != '':
|
||||
# aside_frag_wrapped = self.wrap_aside(block, aside, view_name, aside_frag, context)
|
||||
# aside.save()
|
||||
# result.add_fragment_resources(aside_frag_wrapped)
|
||||
# replacement = position_for_asides + aside_frag_wrapped.content
|
||||
# frag.content = frag.content.replace(position_for_asides, replacement)
|
||||
|
||||
result.add_content(frag.content)
|
||||
return result
|
||||
# result.add_content(frag.content)
|
||||
# return result
|
||||
|
||||
|
||||
def _preview_module_system(request, descriptor, field_data):
|
||||
@@ -206,35 +288,74 @@ def _preview_module_system(request, descriptor, field_data):
|
||||
else:
|
||||
preview_anonymous_user_id = anonymous_id_for_user(request.user, course_id)
|
||||
|
||||
return PreviewModuleSystem(
|
||||
load_item=descriptor._runtime.load_item,
|
||||
resources_fs=descriptor._runtime.resources_fs,
|
||||
error_tracker=descriptor._runtime.error_tracker,
|
||||
get_block=partial(_load_preview_block, request),
|
||||
mixins=settings.XBLOCK_MIXINS,
|
||||
services={
|
||||
"field-data": field_data,
|
||||
"i18n": XBlockI18nService,
|
||||
'mako': mako_service,
|
||||
"settings": SettingsService(),
|
||||
"user": DjangoXBlockUserService(
|
||||
request.user,
|
||||
user_role=get_user_role(request.user, course_id),
|
||||
anonymous_user_id=preview_anonymous_user_id,
|
||||
),
|
||||
"partitions": StudioPartitionService(course_id=course_id),
|
||||
"teams_configuration": TeamsConfigurationService(),
|
||||
"sandbox": SandboxService(contentstore=contentstore, course_id=course_id),
|
||||
"cache": CacheService(cache),
|
||||
'replace_urls': replace_url_service
|
||||
}
|
||||
|
||||
# Set up functions to modify the fragment produced by student_view
|
||||
wrappers=wrappers,
|
||||
wrappers_asides=wrappers_asides,
|
||||
# Get the raw DescriptorSystem, not the CombinedSystem
|
||||
descriptor_runtime=descriptor._runtime, # pylint: disable=protected-access
|
||||
services={
|
||||
"field-data": field_data,
|
||||
"i18n": XBlockI18nService,
|
||||
'mako': mako_service,
|
||||
"settings": SettingsService(),
|
||||
"user": DjangoXBlockUserService(
|
||||
request.user,
|
||||
user_role=get_user_role(request.user, course_id),
|
||||
anonymous_user_id=preview_anonymous_user_id,
|
||||
),
|
||||
"partitions": StudioPartitionService(course_id=course_id),
|
||||
"teams_configuration": TeamsConfigurationService(),
|
||||
"sandbox": SandboxService(contentstore=contentstore, course_id=course_id),
|
||||
"cache": CacheService(cache),
|
||||
'replace_urls': replace_url_service
|
||||
},
|
||||
# system = PreviewModuleSystem(
|
||||
# load_item=descriptor._runtime.load_item,
|
||||
# resources_fs=descriptor._runtime.resources_fs,
|
||||
# error_tracker=descriptor._runtime.error_tracker,
|
||||
# # get_module=partial(_load_preview_module, request),
|
||||
# # mixins=settings.XBLOCK_MIXINS,
|
||||
|
||||
# # Set up functions to modify the fragment produced by student_view
|
||||
# # wrappers=wrappers,
|
||||
# # wrappers_asides=wrappers_asides,
|
||||
# # Get the raw DescriptorSystem, not the CombinedSystem
|
||||
# # descriptor_runtime=descriptor._runtime, # pylint: disable=protected-access
|
||||
# # services={
|
||||
# # "field-data": field_data,
|
||||
# # "i18n": ModuleI18nService,
|
||||
# # 'mako': mako_service,
|
||||
# # "settings": SettingsService(),
|
||||
# # "user": DjangoXBlockUserService(
|
||||
# # request.user,
|
||||
# # user_role=get_user_role(request.user, course_id),
|
||||
# # anonymous_user_id=preview_anonymous_user_id,
|
||||
# # ),
|
||||
# # "partitions": StudioPartitionService(course_id=course_id),
|
||||
# # "teams_configuration": TeamsConfigurationService(),
|
||||
# # "sandbox": SandboxService(contentstore=contentstore, course_id=course_id),
|
||||
# # "cache": CacheService(cache),
|
||||
# # 'replace_urls': replace_url_service
|
||||
# # },
|
||||
# )
|
||||
|
||||
descriptor._runtime.get_block = partial(_load_preview_block, request),
|
||||
descriptor._runtime.mixins = settings.XBLOCK_MIXINS
|
||||
|
||||
# Set up functions to modify the fragment produced by student_view
|
||||
descriptor._runtime.wrappers = wrappers
|
||||
descriptor._runtime.wrappers_asides=wrappers_asides
|
||||
descriptor._runtime._services.update(services)
|
||||
|
||||
descriptor._runtime.is_author_mode = True
|
||||
descriptor._runtime.handler_url_override = handler_url
|
||||
descriptor._runtime.applicable_aside_types_override = preview_applicable_aside_types
|
||||
descriptor._runtime.render_child_placeholder = partial(
|
||||
render_child_placeholder,
|
||||
wrap_xblock = descriptor._runtime.wrap_xblock
|
||||
)
|
||||
descriptor._runtime.layout_asides_override = partial(
|
||||
preview_layout_asides,
|
||||
wrap_aside = descriptor._runtime.wrap_aside
|
||||
)
|
||||
|
||||
return descriptor._runtime
|
||||
|
||||
|
||||
class StudioPartitionService(PartitionService):
|
||||
|
||||
@@ -67,7 +67,7 @@ from lms.djangoapps.courseware.field_overrides import OverrideFieldData
|
||||
from lms.djangoapps.courseware.services import UserStateService
|
||||
from lms.djangoapps.grades.api import GradesUtilService
|
||||
from lms.djangoapps.lms_xblock.field_data import LmsFieldData
|
||||
from lms.djangoapps.lms_xblock.runtime import LmsModuleSystem, UserTagsService
|
||||
from lms.djangoapps.lms_xblock.runtime import UserTagsService, lms_wrappers_aside, lms_applicable_aside_types
|
||||
from lms.djangoapps.verify_student.services import XBlockVerificationService
|
||||
from openedx.core.djangoapps.bookmarks.api import BookmarksService
|
||||
from openedx.core.djangoapps.crawlers.models import CrawlersConfig
|
||||
@@ -587,50 +587,94 @@ def get_module_system_for_user(
|
||||
|
||||
store = modulestore()
|
||||
|
||||
system = LmsModuleSystem(
|
||||
load_item=descriptor._runtime.load_item,
|
||||
resources_fs=descriptor._runtime.resources_fs,
|
||||
error_tracker=descriptor._runtime.error_tracker,
|
||||
get_block=inner_get_block,
|
||||
# TODO: When we merge the descriptor and module systems, we can stop reaching into the mixologist (cpennington)
|
||||
mixins=descriptor.runtime.mixologist._mixins, # pylint: disable=protected-access
|
||||
wrappers=block_wrappers,
|
||||
services={
|
||||
'fs': FSService(),
|
||||
'field-data': field_data,
|
||||
'mako': mako_service,
|
||||
'user': user_service,
|
||||
'verification': XBlockVerificationService(),
|
||||
'proctoring': ProctoringService(),
|
||||
'milestones': milestones_helpers.get_service(),
|
||||
'credit': CreditService(),
|
||||
'bookmarks': BookmarksService(user=user),
|
||||
'gating': GatingService(),
|
||||
'grade_utils': GradesUtilService(course_id=course_id),
|
||||
'user_state': UserStateService(),
|
||||
'content_type_gating': ContentTypeGatingService(),
|
||||
'cache': CacheService(cache),
|
||||
'sandbox': SandboxService(contentstore=contentstore, course_id=course_id),
|
||||
'xqueue': xqueue_service,
|
||||
'replace_urls': replace_url_service,
|
||||
'rebind_user': rebind_user_service,
|
||||
'completion': CompletionService(user=user, context_key=course_id)
|
||||
if user and user.is_authenticated
|
||||
else None,
|
||||
'i18n': XBlockI18nService,
|
||||
'library_tools': LibraryToolsService(store, user_id=user.id if user else None),
|
||||
'partitions': PartitionService(course_id=course_id, cache=DEFAULT_REQUEST_CACHE.data),
|
||||
'settings': SettingsService(),
|
||||
'user_tags': UserTagsService(user=user, course_id=course_id),
|
||||
'badging': BadgingService(course_id=course_id, modulestore=store) if badges_enabled() else None,
|
||||
'teams': TeamsService(),
|
||||
'teams_configuration': TeamsConfigurationService(),
|
||||
'call_to_action': CallToActionService(),
|
||||
'publish': EventPublishingService(user, course_id, track_function),
|
||||
},
|
||||
descriptor_runtime=descriptor._runtime, # pylint: disable=protected-access
|
||||
request_token=request_token,
|
||||
)
|
||||
services={
|
||||
'fs': FSService(),
|
||||
'field-data': field_data,
|
||||
'mako': mako_service,
|
||||
'user': user_service,
|
||||
'verification': XBlockVerificationService(),
|
||||
'proctoring': ProctoringService(),
|
||||
'milestones': milestones_helpers.get_service(),
|
||||
'credit': CreditService(),
|
||||
'bookmarks': BookmarksService(user=user),
|
||||
'gating': GatingService(),
|
||||
'grade_utils': GradesUtilService(course_id=course_id),
|
||||
'user_state': UserStateService(),
|
||||
'content_type_gating': ContentTypeGatingService(),
|
||||
'cache': CacheService(cache),
|
||||
'sandbox': SandboxService(contentstore=contentstore, course_id=course_id),
|
||||
'xqueue': xqueue_service,
|
||||
'replace_urls': replace_url_service,
|
||||
'rebind_user': rebind_user_service,
|
||||
'completion': CompletionService(user=user, context_key=course_id)
|
||||
if user and user.is_authenticated
|
||||
else None,
|
||||
'i18n': XBlockI18nService,
|
||||
'library_tools': LibraryToolsService(store, user_id=user.id if user else None),
|
||||
'partitions': PartitionService(course_id=course_id, cache=DEFAULT_REQUEST_CACHE.data),
|
||||
'settings': SettingsService(),
|
||||
'user_tags': UserTagsService(user=user, course_id=course_id),
|
||||
'badging': BadgingService(course_id=course_id, modulestore=store) if badges_enabled() else None,
|
||||
'teams': TeamsService(),
|
||||
'teams_configuration': TeamsConfigurationService(),
|
||||
'call_to_action': CallToActionService(),
|
||||
'publish': EventPublishingService(user, course_id, track_function),
|
||||
}
|
||||
|
||||
|
||||
# system = LmsModuleSystem(
|
||||
# load_item=descriptor._runtime.load_item,
|
||||
# resources_fs=descriptor._runtime.resources_fs,
|
||||
# error_tracker=descriptor._runtime.error_tracker,
|
||||
# # get_module=inner_get_module,
|
||||
# # TODO: When we merge the descriptor and module systems, we can stop reaching into the mixologist (cpennington)
|
||||
# # mixins=descriptor.runtime.mixologist._mixins, # pylint: disable=protected-access
|
||||
# # wrappers=block_wrappers,
|
||||
# # services={
|
||||
# # 'fs': FSService(),
|
||||
# # 'field-data': field_data,
|
||||
# # 'mako': mako_service,
|
||||
# # 'user': user_service,
|
||||
# # 'verification': XBlockVerificationService(),
|
||||
# # 'proctoring': ProctoringService(),
|
||||
# # 'milestones': milestones_helpers.get_service(),
|
||||
# # 'credit': CreditService(),
|
||||
# # 'bookmarks': BookmarksService(user=user),
|
||||
# # 'gating': GatingService(),
|
||||
# # 'grade_utils': GradesUtilService(course_id=course_id),
|
||||
# # 'user_state': UserStateService(),
|
||||
# # 'content_type_gating': ContentTypeGatingService(),
|
||||
# # 'cache': CacheService(cache),
|
||||
# # 'sandbox': SandboxService(contentstore=contentstore, course_id=course_id),
|
||||
# # 'xqueue': xqueue_service,
|
||||
# # 'replace_urls': replace_url_service,
|
||||
# # 'rebind_user': rebind_user_service,
|
||||
# # 'completion': CompletionService(user=user, context_key=course_id)
|
||||
# # if user and user.is_authenticated
|
||||
# # else None,
|
||||
# # 'i18n': ModuleI18nService,
|
||||
# # 'library_tools': LibraryToolsService(store, user_id=user.id if user else None),
|
||||
# # 'partitions': PartitionService(course_id=course_id, cache=DEFAULT_REQUEST_CACHE.data),
|
||||
# # 'settings': SettingsService(),
|
||||
# # 'user_tags': UserTagsService(user=user, course_id=course_id),
|
||||
# # 'badging': BadgingService(course_id=course_id, modulestore=store) if badges_enabled() else None,
|
||||
# # 'teams': TeamsService(),
|
||||
# # 'teams_configuration': TeamsConfigurationService(),
|
||||
# # 'call_to_action': CallToActionService(),
|
||||
# # 'publish': EventPublishingService(user, course_id, track_function),
|
||||
# # },
|
||||
# # descriptor_runtime=descriptor._runtime, # pylint: disable=protected-access
|
||||
# # request_token=request_token,
|
||||
# )
|
||||
|
||||
descriptor._runtime.get_block = inner_get_block
|
||||
descriptor._runtime.mixins = descriptor.runtime.mixologist._mixins
|
||||
descriptor._runtime.wrappers = block_wrappers
|
||||
descriptor._runtime._services.update(services)
|
||||
descriptor._runtime.request_token = request_token
|
||||
|
||||
descriptor._runtime.wrap_asides_override = lms_wrappers_aside
|
||||
descriptor._runtime.applicable_aside_types_override = lms_applicable_aside_types
|
||||
|
||||
# pass position specified in URL to module through ModuleSystem
|
||||
if position is not None:
|
||||
@@ -640,14 +684,14 @@ def get_module_system_for_user(
|
||||
log.exception('Non-integer %r passed as position.', position)
|
||||
position = None
|
||||
|
||||
system.set('position', position)
|
||||
descriptor._runtime.set('position', position)
|
||||
|
||||
system.set('user_is_staff', user_is_staff)
|
||||
system.set('user_is_admin', bool(has_access(user, 'staff', 'global')))
|
||||
system.set('user_is_beta_tester', CourseBetaTesterRole(course_id).has_user(user))
|
||||
system.set('days_early_for_beta', descriptor.days_early_for_beta)
|
||||
descriptor._runtime.set('user_is_staff', user_is_staff)
|
||||
descriptor._runtime.set('user_is_admin', bool(has_access(user, 'staff', 'global')))
|
||||
descriptor._runtime.set('user_is_beta_tester', CourseBetaTesterRole(course_id).has_user(user))
|
||||
descriptor._runtime.set('days_early_for_beta', descriptor.days_early_for_beta)
|
||||
|
||||
return system, field_data
|
||||
return descriptor._runtime, field_data
|
||||
|
||||
|
||||
# TODO: Find all the places that this method is called and figure out how to
|
||||
|
||||
@@ -72,6 +72,64 @@ def local_resource_url(block, uri):
|
||||
return xblock_local_resource_url(block, uri)
|
||||
|
||||
|
||||
def lms_wrappers_aside(block, aside, view, frag, context, request_token=None):
|
||||
"""
|
||||
Creates a div which identifies the aside, points to the original block,
|
||||
and writes out the json_init_args into a script tag.
|
||||
|
||||
The default implementation creates a frag to wraps frag w/ a div identifying the xblock. If you have
|
||||
javascript, you'll need to override this impl
|
||||
"""
|
||||
if not frag.content:
|
||||
return frag
|
||||
|
||||
runtime_class = 'LmsRuntime'
|
||||
extra_data = {
|
||||
'block-id': quote_slashes(str(block.scope_ids.usage_id)),
|
||||
'course-id': quote_slashes(str(block.scope_ids.usage_id.context_key)),
|
||||
'url-selector': 'asideBaseUrl',
|
||||
'runtime-class': runtime_class,
|
||||
}
|
||||
if request_token:
|
||||
extra_data['request-token'] = request_token
|
||||
|
||||
return wrap_xblock_aside(
|
||||
runtime_class,
|
||||
aside,
|
||||
view,
|
||||
frag,
|
||||
context,
|
||||
usage_id_serializer=str,
|
||||
request_token=request_token,
|
||||
extra_data=extra_data,
|
||||
)
|
||||
|
||||
|
||||
def lms_applicable_aside_types(block, applicable_aside_types=None):
|
||||
"""
|
||||
Return all of the asides which might be decorating this `block`.
|
||||
|
||||
Arguments:
|
||||
block (:class:`.XBlock`): The block to render retrieve asides for.
|
||||
"""
|
||||
|
||||
config = XBlockAsidesConfig.current()
|
||||
|
||||
if not config.enabled:
|
||||
return []
|
||||
|
||||
if block.scope_ids.block_type in config.disabled_blocks.split():
|
||||
return []
|
||||
|
||||
# TODO: aside_type != 'acid_aside' check should be removed once AcidBlock is only installed during tests
|
||||
# (see https://openedx.atlassian.net/browse/TE-811)
|
||||
return [
|
||||
aside_type
|
||||
for aside_type in applicable_aside_types(block)
|
||||
if aside_type != 'acid_aside'
|
||||
]
|
||||
|
||||
|
||||
class UserTagsService:
|
||||
"""
|
||||
A runtime class that provides an interface to the user service. It handles filling in
|
||||
@@ -121,85 +179,114 @@ class LmsModuleSystem(DescriptorSystem): # pylint: disable=abstract-method
|
||||
ModuleSystem specialized to the LMS
|
||||
"""
|
||||
def __init__(self, **kwargs):
|
||||
self.request_token = kwargs.pop('request_token', None)
|
||||
#######################
|
||||
#######################
|
||||
## Set Directly from module_render
|
||||
#######################
|
||||
#######################
|
||||
# self.request_token = kwargs.pop('request_token', None)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def handler_url(self, *args, **kwargs): # lint-amnesty, pylint: disable=signature-differs
|
||||
"""
|
||||
Implement the XBlock runtime handler_url interface.
|
||||
#######################
|
||||
#######################
|
||||
## Being monkey patched in Descriptor system from lms.djangoapps.lms_xblock.apps.py
|
||||
#######################
|
||||
#######################
|
||||
|
||||
This is mostly just proxying to the module level `handler_url` function
|
||||
defined higher up in this file.
|
||||
# def handler_url(self, *args, **kwargs): # lint-amnesty, pylint: disable=signature-differs
|
||||
# """
|
||||
# Implement the XBlock runtime handler_url interface.
|
||||
|
||||
We're doing this indirection because the module level `handler_url`
|
||||
logic is also needed by the `DescriptorSystem`. The particular
|
||||
`handler_url` that a `DescriptorSystem` needs will be different when
|
||||
running an LMS process or a CMS/Studio process. That's accomplished by
|
||||
monkey-patching a global. It's a long story, but please know that you
|
||||
can't just refactor and fold that logic into here without breaking
|
||||
things.
|
||||
# This is mostly just proxying to the module level `handler_url` function
|
||||
# defined higher up in this file.
|
||||
|
||||
https://openedx.atlassian.net/wiki/display/PLAT/Convert+from+Storage-centric+runtimes+to+Application-centric+runtimes
|
||||
# We're doing this indirection because the module level `handler_url`
|
||||
# logic is also needed by the `DescriptorSystem`. The particular
|
||||
# `handler_url` that a `DescriptorSystem` needs will be different when
|
||||
# running an LMS process or a CMS/Studio process. That's accomplished by
|
||||
# monkey-patching a global. It's a long story, but please know that you
|
||||
# can't just refactor and fold that logic into here without breaking
|
||||
# things.
|
||||
|
||||
See :method:`xblock.runtime:Runtime.handler_url`
|
||||
"""
|
||||
return handler_url(*args, **kwargs)
|
||||
# https://openedx.atlassian.net/wiki/display/PLAT/Convert+from+Storage-centric+runtimes+to+Application-centric+runtimes
|
||||
|
||||
def local_resource_url(self, *args, **kwargs):
|
||||
return local_resource_url(*args, **kwargs)
|
||||
# See :method:`xblock.runtime:Runtime.handler_url`
|
||||
# """
|
||||
# return handler_url(*args, **kwargs)
|
||||
|
||||
def wrap_aside(self, block, aside, view, frag, context):
|
||||
"""
|
||||
Creates a div which identifies the aside, points to the original block,
|
||||
and writes out the json_init_args into a script tag.
|
||||
#######################
|
||||
#######################
|
||||
## Being monkey patched in Descriptor system from lms.djangoapps.lms_xblock.apps.py
|
||||
#######################
|
||||
#######################
|
||||
|
||||
The default implementation creates a frag to wraps frag w/ a div identifying the xblock. If you have
|
||||
javascript, you'll need to override this impl
|
||||
"""
|
||||
if not frag.content:
|
||||
return frag
|
||||
# def local_resource_url(self, *args, **kwargs):
|
||||
# return local_resource_url(*args, **kwargs)
|
||||
|
||||
runtime_class = 'LmsRuntime'
|
||||
extra_data = {
|
||||
'block-id': quote_slashes(str(block.scope_ids.usage_id)),
|
||||
'course-id': quote_slashes(str(block.course_id)),
|
||||
'url-selector': 'asideBaseUrl',
|
||||
'runtime-class': runtime_class,
|
||||
}
|
||||
if self.request_token:
|
||||
extra_data['request-token'] = self.request_token
|
||||
#######################
|
||||
#######################
|
||||
## Implemented as lms_wrappers_aside above
|
||||
#######################
|
||||
#######################
|
||||
|
||||
return wrap_xblock_aside(
|
||||
runtime_class,
|
||||
aside,
|
||||
view,
|
||||
frag,
|
||||
context,
|
||||
usage_id_serializer=str,
|
||||
request_token=self.request_token,
|
||||
extra_data=extra_data,
|
||||
)
|
||||
# def wrap_aside(self, block, aside, view, frag, context):
|
||||
# """
|
||||
# Creates a div which identifies the aside, points to the original block,
|
||||
# and writes out the json_init_args into a script tag.
|
||||
|
||||
def applicable_aside_types(self, block):
|
||||
"""
|
||||
Return all of the asides which might be decorating this `block`.
|
||||
# The default implementation creates a frag to wraps frag w/ a div identifying the xblock. If you have
|
||||
# javascript, you'll need to override this impl
|
||||
# """
|
||||
# if not frag.content:
|
||||
# return frag
|
||||
|
||||
Arguments:
|
||||
block (:class:`.XBlock`): The block to render retrieve asides for.
|
||||
"""
|
||||
# runtime_class = 'LmsRuntime'
|
||||
# extra_data = {
|
||||
# 'block-id': quote_slashes(str(block.scope_ids.usage_id)),
|
||||
# 'course-id': quote_slashes(str(block.course_id)),
|
||||
# 'url-selector': 'asideBaseUrl',
|
||||
# 'runtime-class': runtime_class,
|
||||
# }
|
||||
# if self.request_token:
|
||||
# extra_data['request-token'] = self.request_token
|
||||
|
||||
config = XBlockAsidesConfig.current()
|
||||
# return wrap_xblock_aside(
|
||||
# runtime_class,
|
||||
# aside,
|
||||
# view,
|
||||
# frag,
|
||||
# context,
|
||||
# usage_id_serializer=str,
|
||||
# request_token=self.request_token,
|
||||
# extra_data=extra_data,
|
||||
# )
|
||||
|
||||
if not config.enabled:
|
||||
return []
|
||||
#######################
|
||||
#######################
|
||||
## Implemented as lms_applicable_aside_types above
|
||||
#######################
|
||||
#######################
|
||||
|
||||
if block.scope_ids.block_type in config.disabled_blocks.split():
|
||||
return []
|
||||
# def applicable_aside_types(self, block):
|
||||
# """
|
||||
# Return all of the asides which might be decorating this `block`.
|
||||
|
||||
# TODO: aside_type != 'acid_aside' check should be removed once AcidBlock is only installed during tests
|
||||
# (see https://openedx.atlassian.net/browse/TE-811)
|
||||
return [
|
||||
aside_type
|
||||
for aside_type in super().applicable_aside_types(block)
|
||||
if aside_type != 'acid_aside'
|
||||
]
|
||||
# Arguments:
|
||||
# block (:class:`.XBlock`): The block to render retrieve asides for.
|
||||
# """
|
||||
|
||||
# config = XBlockAsidesConfig.current()
|
||||
|
||||
# if not config.enabled:
|
||||
# return []
|
||||
|
||||
# if block.scope_ids.block_type in config.disabled_blocks.split():
|
||||
# return []
|
||||
|
||||
# # TODO: aside_type != 'acid_aside' check should be removed once AcidBlock is only installed during tests
|
||||
# # (see https://openedx.atlassian.net/browse/TE-811)
|
||||
# return [
|
||||
# aside_type
|
||||
# for aside_type in super().applicable_aside_types(block)
|
||||
# if aside_type != 'acid_aside'
|
||||
# ]
|
||||
|
||||
@@ -1420,17 +1420,8 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, ModuleSystemSh
|
||||
"""
|
||||
Base class for :class:`Runtime`s to be used with :class:`XModuleDescriptor`s
|
||||
"""
|
||||
|
||||
def get(self, attr):
|
||||
""" provide uniform access to attributes (like etree)."""
|
||||
return self.__dict__.get(attr)
|
||||
|
||||
def set(self, attr, val):
|
||||
"""provide uniform access to attributes (like etree)"""
|
||||
self.__dict__[attr] = val
|
||||
|
||||
def __init__(
|
||||
self, load_item, resources_fs, error_tracker, descriptor_runtime=None, get_policy=None, disabled_xblock_types=lambda: [], get_module=None, **kwargs
|
||||
self, load_item, resources_fs, error_tracker, get_policy=None, disabled_xblock_types=lambda: [], get_module=None, **kwargs
|
||||
):
|
||||
"""
|
||||
load_item: Takes a Location and returns an XModuleDescriptor
|
||||
@@ -1467,7 +1458,10 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, ModuleSystemSh
|
||||
|
||||
self.disabled_xblock_types = disabled_xblock_types
|
||||
self.get_module = get_module
|
||||
self.descriptor_runtime = descriptor_runtime
|
||||
# self.handler_url_override = None
|
||||
# self.applicable_aside_types_override = None
|
||||
# self.wrap_asides_override = None
|
||||
# self.layout_asides_override = None
|
||||
|
||||
def get(self, attr):
|
||||
""" provide uniform access to attributes (like etree)."""
|
||||
@@ -1479,11 +1473,10 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, ModuleSystemSh
|
||||
|
||||
def get_block(self, usage_id, for_parent=None):
|
||||
"""See documentation for `xblock.runtime:Runtime.get_block`"""
|
||||
block = self.load_item(usage_id, for_parent=for_parent)
|
||||
if self.get_module:
|
||||
# return self.get_module(block)
|
||||
return self.get_module(self.descriptor_runtime.get_block(usage_id, for_parent=for_parent))
|
||||
|
||||
return self.load_item(usage_id, for_parent=for_parent)
|
||||
return self.get_module(block)
|
||||
return block
|
||||
|
||||
def load_block_type(self, block_type):
|
||||
"""
|
||||
@@ -1522,6 +1515,8 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, ModuleSystemSh
|
||||
# This means that LMS/CMS don't have a way to define a subclass of DescriptorSystem
|
||||
# that implements the correct handler url. So, for now, instead, we will reference a
|
||||
# global function that the application can override.
|
||||
if getattr(self, 'handler_url_override', None):
|
||||
return self.handler_url_override(block, handler_name, suffix, query, thirdparty)
|
||||
return descriptor_global_handler_url(block, handler_name, suffix, query, thirdparty)
|
||||
|
||||
def local_resource_url(self, block, uri):
|
||||
@@ -1538,6 +1533,9 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, ModuleSystemSh
|
||||
"""
|
||||
See :meth:`xblock.runtime.Runtime:applicable_aside_types` for documentation.
|
||||
"""
|
||||
if getattr(self, 'applicable_aside_types_override', None):
|
||||
return self.applicable_aside_types_override(block, applicable_aside_types=super().applicable_aside_types)
|
||||
|
||||
potential_set = set(super().applicable_aside_types(block))
|
||||
if getattr(block, 'xmodule_runtime', None) is not None:
|
||||
if hasattr(block.xmodule_runtime, 'applicable_aside_types'):
|
||||
@@ -1586,6 +1584,16 @@ class DescriptorSystem(MetricsMixin, ConfigurableFragmentWrapper, ModuleSystemSh
|
||||
return service(block)
|
||||
return service
|
||||
|
||||
def wrap_aside(self, block, aside, view, frag, context):
|
||||
if getattr(self, 'wrap_asides_override', None):
|
||||
return self.wrap_asides_override(block, aside, view, frag, context, request_token=self.request_token)
|
||||
return super().wrap_aside(block, aside, view, frag, context)
|
||||
|
||||
def layout_asides(self, block, context, frag, view_name, aside_frag_fns):
|
||||
if getattr(self, 'layout_asides_override', None):
|
||||
return self.layout_asides_override(block, context, frag, view_name, aside_frag_fns)
|
||||
return super().layout_asides(block, context, frag, view_name, aside_frag_fns)
|
||||
|
||||
|
||||
class XMLParsingSystem(DescriptorSystem): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring
|
||||
def __init__(self, process_xml, **kwargs):
|
||||
@@ -1702,6 +1710,7 @@ class XMLParsingSystem(DescriptorSystem): # lint-amnesty, pylint: disable=abstr
|
||||
field_value[key] = self._make_usage_key(course_key, subvalue)
|
||||
setattr(xblock, field.name, field_value)
|
||||
|
||||
|
||||
class CombinedSystem:
|
||||
"""
|
||||
This class is a shim to allow both pure XBlocks and XModuleDescriptors
|
||||
|
||||
Reference in New Issue
Block a user