diff --git a/common/lib/xmodule/xmodule/modulestore/search.py b/common/lib/xmodule/xmodule/modulestore/search.py index bc0e0de8932..314f0427d58 100644 --- a/common/lib/xmodule/xmodule/modulestore/search.py +++ b/common/lib/xmodule/xmodule/modulestore/search.py @@ -8,6 +8,7 @@ from lms.djangoapps.courseware.masquerade import MASQUERADE_SETTINGS_KEY from student.roles import GlobalStaff from .exceptions import ItemNotFoundError, NoPathToItem +from opaque_keys.edx.keys import CourseKey, UsageKey LOGGER = getLogger(__name__) @@ -81,13 +82,46 @@ def find_path_to_course(): newpath = (next_usage, path) queue.append((parent, newpath)) + def find_updated_path_to_course(usage_key): + course_id = "course-v1:{}+{}+".format(usage_key.org, usage_key.course) + updated_modules = request.user.courseenrollment_set.filter(course__id__startswith=course_id) + if updated_modules: + course_key = CourseKey.from_string(updated_modules[0].course_id) + usage_key = usage_key.replace(course_key=course_key) + + queue = [(usage_key, ())] + while len(queue) > 0: + (next_usage, path) = queue.pop() # Takes from the end + + parent = modulestore.get_parent_location(next_usage) + + if next_usage.block_type == "course": + path = (next_usage, path) + return flatten(path) + elif parent is None: + return None + + # otherwise, add parent locations at the end + newpath = (next_usage, path) + queue.append((parent, newpath)) + else: + return None + + with modulestore.bulk_operations(usage_key.course_key): if not modulestore.has_item(usage_key): - raise ItemNotFoundError(usage_key) + course_id = "course-v1:{}+{}+".format(usage_key.org, usage_key.course) + updated_modules = request.user.courseenrollment_set.filter(course__id__startswith=course_id) + if updated_modules: + usage_key = usage_key.replace(course_key=updated_modules[0].course_id) + else: + raise ItemNotFoundError(usage_key) path = find_path_to_course() if path is None: - raise NoPathToItem(usage_key) + path = find_updated_path_to_course(usage_key) + if path is None: + raise NoPathToItem(usage_key) if full_path: return path diff --git a/lms/djangoapps/ci_program/views.py b/lms/djangoapps/ci_program/views.py index fff83d8ae6f..edffd8e2c47 100644 --- a/lms/djangoapps/ci_program/views.py +++ b/lms/djangoapps/ci_program/views.py @@ -43,7 +43,7 @@ def show_program_bookmarks(request, program_name): program = Program.objects.get(marketing_slug=program_name) bookmarks = Bookmark.objects.filter( - course_key__in=program.get_course_locators(), +# course_key__in=program.get_course_locators(), user=request.user) page_data = bookmarks[(page - 1) * page_size: page * page_size] diff --git a/lms/djangoapps/courseware/views/index.py b/lms/djangoapps/courseware/views/index.py index d13fdd3c9dc..60ee9c001df 100644 --- a/lms/djangoapps/courseware/views/index.py +++ b/lms/djangoapps/courseware/views/index.py @@ -31,6 +31,7 @@ from lms.djangoapps.experiments.utils import get_experiment_user_metadata_context from lms.djangoapps.gating.api import get_entrance_exam_score_ratio, get_entrance_exam_usage_key from lms.djangoapps.grades.api import CourseGradeFactory +from lms.djangoapps.courseware.courseware_access_exception import CoursewareAccessException from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.crawlers.models import CrawlersConfig from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY @@ -134,19 +135,36 @@ def get(self, request, course_id, chapter=None, section=None, position=None): self.course = None self.url = request.path + def _redirect_if_course_updated(): + course_id = "course-v1:{}+{}+".format(self.course_key.org, self.course_key.course) + updated_modules = request.user.courseenrollment_set.filter(course__id__startswith=course_id) + if updated_modules: + course_id = updated_modules[0].course_id + if chapter and section and position: + redirect_url = reverse("courseware_position", args=(course_id, chapter, section, position)) + elif chapter and section: + redirect_url = reverse("courseware_section", args=(course_id, chapter, section)) + elif chapter: + redirect_url = reverse("courseware_chapter", args=(course_id, chapter)) + else: + redirect_url = reverse("courseware", args=(course_id,)) + raise Redirect(redirect_url) + try: set_custom_metrics_for_course_key(self.course_key) self._clean_position() with modulestore().bulk_operations(self.course_key): - self.view = STUDENT_VIEW + try: + self.course = get_course_with_access( + request.user, 'load', self.course_key, + depth=CONTENT_DEPTH, + check_if_enrolled=True, + check_if_authenticated=True + ) + except Http404 as nfe: + _redirect_if_course_updated() - self.course = get_course_with_access( - request.user, 'load', self.course_key, - depth=CONTENT_DEPTH, - check_if_enrolled=True, - check_if_authenticated=True - ) self.course_overview = CourseOverview.get_from_id(self.course.id) self.is_staff = has_access(request.user, 'staff', self.course) @@ -163,6 +181,11 @@ def get(self, request, course_id, chapter=None, section=None, position=None): self._setup_masquerade_for_effective_user() return self.render(request) + except CourseAccessRedirect as exception: # pylint: disable=broad-except + return CourseTabView.handle_exceptions(request, self.course_key, self.course, exception) + except CoursewareAccessException as exception: # pylint: disable=broad-except + _redirect_if_course_updated() + return CourseTabView.handle_exceptions(request, self.course_key, self.course, exception) except Exception as exception: # pylint: disable=broad-except return CourseTabView.handle_exceptions(request, self.course_key, self.course, exception)