From f085e295baded8610515ed71e8f0af09a8e1dcb6 Mon Sep 17 00:00:00 2001 From: Haftamu Kebede <54979169+haftamuk@users.noreply.github.com> Date: Sat, 26 Jul 2025 18:04:10 +0300 Subject: [PATCH 1/2] Inspecting gating service at seq_block.py --- cms/djangoapps/contentstore/utils.py | 5 ++++- openedx/core/lib/gating/services.py | 13 +++++++++++++ xmodule/seq_block.py | 21 ++++++++++++++++++++- xmodule/xml_block.py | 24 +++++++++++++++++++++++- 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index 1ad400f3a5eb..9d454c49ea55 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -117,6 +117,8 @@ from .models import ComponentLink, ContainerLink +from openedx.core.lib.gating.services import GatingService + IMPORTABLE_FILE_TYPES = ('.tar.gz', '.zip') log = logging.getLogger(__name__) @@ -1311,7 +1313,8 @@ def load_services_for_studio(runtime, user): "settings": SettingsService(), "lti-configuration": ConfigurationService(CourseAllowPIISharingInLTIFlag), "teams_configuration": TeamsConfigurationService(), - "library_tools": LegacyLibraryToolsService(modulestore(), user.id) + "library_tools": LegacyLibraryToolsService(modulestore(), user.id), + 'gating': GatingService(), } runtime._services.update(services) # lint-amnesty, pylint: disable=protected-access diff --git a/openedx/core/lib/gating/services.py b/openedx/core/lib/gating/services.py index 901ee1ad9a1a..cd71951ed9bb 100644 --- a/openedx/core/lib/gating/services.py +++ b/openedx/core/lib/gating/services.py @@ -54,3 +54,16 @@ def is_gate_fulfilled(self, course_key, gating_content_key, user_id): Returns False otherwise """ return gating_api.is_gate_fulfilled(course_key, gating_content_key, user_id) + + def get_required_prereq_metadata(course_key, gated_content_key): + """ + Returns the prerequisite information of the provided subsection + + Arguments: + course_key (str|CourseKey): The course key + content_key (str|UsageKey): The content usage key + + Returns: + dict or None: The gating milestone dict or None + """ + return gating_api.get_required_content(course_key, gated_content_key) diff --git a/xmodule/seq_block.py b/xmodule/seq_block.py index f06d3030f5e9..f0121df431d8 100644 --- a/xmodule/seq_block.py +++ b/xmodule/seq_block.py @@ -41,7 +41,6 @@ from .x_module import AUTHOR_VIEW, PUBLIC_VIEW from .xml_block import XmlMixin - log = logging.getLogger(__name__) # HACK: This shouldn't be hard-coded to two types @@ -375,6 +374,26 @@ def get_metadata(self, view=STUDENT_VIEW, context=None): meta['navigation_disabled'] = self.is_sequence_navigation_disabled() return meta + def get_prereq_metadata(self, course_key, gated_content_key): + """ + Returns the prerequisite of this sequence if there is one. + + Arguments: + course_key (str|CourseKey): The course key + content_key (str|UsageKey): The content usage key + + Returns: + dict or None: The gating milestone dict or None + """ + logging.warning(f'INSPECTING-LOG get_prereq_metadata type is = %s', type(self)) + logging.warning(f'INSPECTING-LOG get_prereq_metadata vars is = %s', vars(self)) + + gating_service = self.runtime.service(self, 'gating') + if gating_service: + return gating_service.get_required_prereq_metadata(course_key, gated_content_key) + else: + return None + def is_sequence_navigation_disabled(self): """ Returns whether the navigation to other sequences is disabled. diff --git a/xmodule/xml_block.py b/xmodule/xml_block.py index 4093d982fa80..226266cbc054 100644 --- a/xmodule/xml_block.py +++ b/xmodule/xml_block.py @@ -12,13 +12,13 @@ from xblock.runtime import KvsFieldData from xmodule.modulestore import EdxJSONEncoder from xmodule.modulestore.inheritance import InheritanceKeyValueStore, own_metadata - log = logging.getLogger(__name__) # assume all XML files are persisted as utf-8. EDX_XML_PARSER = XMLParser(dtd_validation=False, load_dtd=False, remove_blank_text=True, encoding='utf-8') + def name_to_pathname(name): """ Convert a location name for use in a path: replace ':' with '/'. @@ -455,6 +455,28 @@ def add_xml_to_node(self, node): xml_object.tag = self.category node.tag = self.category + # Populate Prerequisite information of a sequential object + if self.category == 'sequential': + course_id = self.scope_ids.usage_id.context_key + content_id = self.location + logging.warning(f'INSPECTING-LOG self type is = %s', type(self)) + logging.warning(f'INSPECTING-LOG self vars is = %s', vars(self)) + + logging.warning(f'INSPECTING-LOG course_id is = %s', course_id) + logging.warning(f'INSPECTING-LOG content_id is = %s', content_id) + + milestone = self.get_prereq_metadata(course_id, content_id) + if milestone : + logging.warning(f'INSPECTING-LOG milestone type is = %s', type(milestone)) + logging.warning(f'INSPECTING-LOG milestone vars is = %s', vars(milestone)) + # xml_object.set('is_prereq', '') + # xml_object.set('prereq', '') + # xml_object.set('prereq_min_score', '') + # xml_object.set('prereq_min_completion', '') + else : + logging.warning(f'INSPECTING-LOG milestone is None= %s', (milestone)) + + # Add the non-inherited metadata for attr in sorted(own_metadata(self)): # don't want e.g. data_dir From 7baf233efbe26fc50ca06110111d126fbd052304 Mon Sep 17 00:00:00 2001 From: Haftamu Kebede <54979169+haftamuk@users.noreply.github.com> Date: Sat, 2 Aug 2025 04:01:18 +0300 Subject: [PATCH 2/2] Download Handout link in a video component initiates a direct download --- lms/templates/video.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/templates/video.html b/lms/templates/video.html index dbb487ba0e0b..a288b2c5a32e 100644 --- a/lms/templates/video.html +++ b/lms/templates/video.html @@ -154,7 +154,7 @@

${_('Transcripts')}

% if handout:

${_('Handouts')}

- ${_('Download Handout')} + ${_('Download Handout')}
% endif % if branding_info: