/
githubmirror
/
oppia
Обзор
Документация
Войти
/
githubmirror
/
oppia
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
core/controllers/subtopic_viewer.py
160 строк
6 KB
Kartik Suryavanshi
[GSoC 2026] M2.1 - Fix part of #19614: Backend changes needed for learner side (#26604)
25 июл 2026, 10:11
Не верифицирован
25 июл 2026, 10:11
42ee2c8
Код
Авторство
О чём код?
# Copyright 2019 The Oppia Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS-IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Controllers for the subtopic viewer page.""" from __future__ import annotations from core import feature_flag_list, feconf from core.constants import constants from core.controllers import acl_decorators, base from core.domain import ( feature_flag_services, skill_fetchers, study_guide_services, subtopic_page_domain, subtopic_page_services, topic_fetchers, ) from typing import Dict, List, Optional, TypedDict class SubtopicPageDataHandlerNormalizedRequestDict(TypedDict): """Dict representation of SubtopicPageDataHandler's normalized_request dictionary. """ skill_ids: Optional[List[str]] class SubtopicPageDataHandler( base.BaseHandler[ Dict[str, str], SubtopicPageDataHandlerNormalizedRequestDict ] ): """Manages the data that needs to be displayed to a learner on the subtopic page. """ GET_HANDLER_ERROR_RETURN_TYPE = feconf.HANDLER_TYPE_JSON URL_PATH_ARGS_SCHEMAS = { 'classroom_url_fragment': constants.SCHEMA_FOR_CLASSROOM_URL_FRAGMENTS, 'topic_url_fragment': constants.SCHEMA_FOR_TOPIC_URL_FRAGMENTS, 'subtopic_url_fragment': { 'schema': { 'type': 'basestring', 'validators': [ { 'id': 'is_regex_matched', 'regex_pattern': constants.VALID_URL_FRAGMENT_REGEX, }, { 'id': 'has_length_at_most', 'max_value': constants.MAX_CHARS_IN_SUBTOPIC_URL_FRAGMENT, }, ], } }, } HANDLER_ARGS_SCHEMAS = { 'GET': { 'skill_ids': { 'schema': { 'type': 'custom', 'obj_type': 'JsonEncodedInString', }, 'default_value': None, }, } } @acl_decorators.can_access_subtopic_viewer_page def get(self, topic_name: str, subtopic_id: int) -> None: """Handles GET requests. Args: topic_name: str. The name of the topic that the subtopic is present in. subtopic_id: str. The id of the subtopic, which is an integer in string form. """ subtopic_id = int(subtopic_id) topic = topic_fetchers.get_topic_by_name(topic_name) next_subtopic_dict = None prev_subtopic_dict = None index = topic.get_subtopic_index(subtopic_id) subtopic_title = topic.subtopics[index].title if index != len(topic.subtopics) - 1: next_subtopic_dict = topic.subtopics[index + 1].to_dict() # Checking greater than 1 here, since otherwise the only # subtopic page of the topic would always link to itself at the # bottom of the subtopic page which isn't expected. elif len(topic.subtopics) > 1: prev_subtopic_dict = topic.subtopics[index - 1].to_dict() study_guide_sections_dicts_list = [] subtopic_page_contents_dict: ( subtopic_page_domain.SubtopicPageContentsDict ) = { 'subtitled_html': {'content_id': '', 'html': ''}, 'recorded_voiceovers': {'voiceovers_mapping': {}}, 'written_translations': {'translations_mapping': {}}, } assert self.normalized_request is not None skill_ids = self.normalized_request.get('skill_ids') if skill_ids is not None: if not isinstance(skill_ids, list) or not all( isinstance(skill_id, str) for skill_id in skill_ids ): raise self.InvalidInputException('Invalid skill IDs') try: skill_fetchers.get_multi_skills(skill_ids) except Exception as e: raise self.NotFoundException(e) if feature_flag_services.is_feature_flag_enabled( feature_flag_list.FeatureNames.SHOW_RESTRUCTURED_STUDY_GUIDES.value, self.user_id, ): study_guide_sections = ( study_guide_services.get_study_guide_sections_by_id( topic.id, subtopic_id ) ) for section in study_guide_sections: study_guide_sections_dicts_list.append(section.to_dict()) else: subtopic_page_contents = ( subtopic_page_services.get_subtopic_page_contents_by_id( topic.id, subtopic_id ) ) subtopic_page_contents_dict = subtopic_page_contents.to_dict() self.values.update( { 'topic_id': topic.id, 'topic_name': topic.name, 'sections': study_guide_sections_dicts_list, 'page_contents': subtopic_page_contents_dict, 'subtopic_title': subtopic_title, 'current_subtopic_id': subtopic_id, 'next_subtopic_dict': next_subtopic_dict, 'prev_subtopic_dict': prev_subtopic_dict, 'skill_ids': skill_ids, } ) self.render_json(self.values)