def does_location_exist(course_id, location):
    """
    Checks to see if a valid module exists at a given location (ie has not been deleted)
    course_id - string course id
    location - string location
    """
    try:
        search.path_to_location(modulestore(), course_id, location)
        return True
    except ItemNotFoundError:
        #If the problem cannot be found at the location received from the grading controller server, it has been deleted by the course author.
        return False
Example #2
0
    def location(self):
        """
        Blend "location" property into the resultset, so that the path to the found component can be shown within the UI
        """
        # TODO: update whern changes to "cohorted-courseware" branch are merged in
        (course_key, chapter, section, position) = path_to_location(self.get_module_store(), self.get_usage_key())

        def get_display_name(item_key):
            """ gets display name from object's key """
            item = self.get_item(item_key)
            display_name = getattr(item, "display_name", None)
            return display_name if display_name else UNNAMED_MODULE_NAME

        def get_position_name(section, position):
            """ helper to fetch name corresponding to the position therein """
            if position:
                section_item = self.get_item(course_key.make_usage_key("sequential", section))
                if section_item.has_children and len(section_item.children) >= position:
                    return get_display_name(section_item.children[position - 1])
            return None

        location_description = []
        if chapter:
            location_description.append(get_display_name(course_key.make_usage_key("chapter", chapter)))
        if section:
            location_description.append(get_display_name(course_key.make_usage_key("sequential", section)))
        if position:
            # We're only wanting to show the first vertical, so we use the
            # navigation_index function to display the same location to which one
            # would be sent if navigating
            location_description.append(get_position_name(section, navigation_index(position)))

        return location_description
Example #3
0
def find_peer_grading_module(course):
    """
    Given a course, finds the first peer grading module in it.
    @param course: A course object.
    @return: boolean found_module, string problem_url
    """

    # Reverse the base course url.
    base_course_url = reverse("courses")
    found_module = False
    problem_url = ""

    # Get the peer grading modules currently in the course.  Explicitly specify the course id to avoid issues with different runs.
    items = modulestore().get_items(course.id, category="peergrading")
    # See if any of the modules are centralized modules (ie display info from multiple problems)
    items = [i for i in items if not getattr(i, "use_for_single_location", True)]
    # Loop through all potential peer grading modules, and find the first one that has a path to it.
    for item in items:
        # Generate a url for the first module and redirect the user to it.
        try:
            problem_url_parts = search.path_to_location(modulestore(), item.location)
        except NoPathToItem:
            # In the case of nopathtoitem, the peer grading module that was found is in an invalid state, and
            # can no longer be accessed.  Log an informational message, but this will not impact normal behavior.
            log.info(
                u"Invalid peer grading module location {0} in course {1}.  This module may need to be removed.".format(
                    item_location, course.id
                )
            )
            continue
        problem_url = generate_problem_url(problem_url_parts, base_course_url)
        found_module = True

    return found_module, problem_url
Example #4
0
def find_peer_grading_module(course):
    """
    Given a course, finds the first peer grading module in it.
    @param course: A course object.
    @return: boolean found_module, string problem_url
    """

    # Reverse the base course url.
    base_course_url = reverse('courses')
    found_module = False
    problem_url = ""

    # Get the course id and split it.
    peer_grading_query = course.location.replace(category='peergrading', name=None)
    # Get the peer grading modules currently in the course.  Explicitly specify the course id to avoid issues with different runs.
    items = modulestore().get_items(peer_grading_query, course_id=course.id)
    #See if any of the modules are centralized modules (ie display info from multiple problems)
    items = [i for i in items if not getattr(i, "use_for_single_location", True)]
    # Loop through all potential peer grading modules, and find the first one that has a path to it.
    for item in items:
        item_location = item.location
        # Generate a url for the first module and redirect the user to it.
        try:
            problem_url_parts = search.path_to_location(modulestore(), course.id, item_location)
        except NoPathToItem:
            # In the case of nopathtoitem, the peer grading module that was found is in an invalid state, and
            # can no longer be accessed.  Log an informational message, but this will not impact normal behavior.
            log.info(u"Invalid peer grading module location {0} in course {1}.  This module may need to be removed.".format(item_location, course.id))
            continue
        problem_url = generate_problem_url(problem_url_parts, base_course_url)
        found_module = True

    return found_module, problem_url
Example #5
0
def jump_to(_request, course_id, location):
    """
    Show the page that contains a specific location.

    If the location is invalid or not in any class, return a 404.

    Otherwise, delegates to the index view to figure out whether this user
    has access, and what they should see.
    """
    try:
        course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
        usage_key = course_key.make_usage_key_from_deprecated_string(location)
    except InvalidKeyError:
        raise Http404(u"Invalid course_key or usage_key")
    try:
        (course_key, chapter, section, position) = path_to_location(modulestore(), usage_key)
    except ItemNotFoundError:
        raise Http404(u"No data at this location: {0}".format(usage_key))
    except NoPathToItem:
        raise Http404(u"This location is not in any class: {0}".format(usage_key))

    # choose the appropriate view (and provide the necessary args) based on the
    # args provided by the redirect.
    # Rely on index to do all error handling and access control.
    if chapter is None:
        return redirect('courseware', course_id=course_key.to_deprecated_string())
    elif section is None:
        return redirect('courseware_chapter', course_id=course_key.to_deprecated_string(), chapter=chapter)
    elif position is None:
        return redirect('courseware_section', course_id=course_key.to_deprecated_string(), chapter=chapter, section=section)
    else:
        return redirect('courseware_position', course_id=course_key.to_deprecated_string(), chapter=chapter, section=section, position=position)
Example #6
0
def _get_legacy_courseware_url(
    usage_key: UsageKey,
    request: Optional[HttpRequest] = None,
) -> str:
    """
    Return the URL to Legacy (LMS-rendered) courseware content.

    Raises:
        * ItemNotFoundError if no data at the usage_key.
        * NoPathToItem if location not in any class.
    """
    (course_key, chapter, section, vertical_unused, position,
     final_target_id) = path_to_location(modulestore(), usage_key, request)

    # choose the appropriate view (and provide the necessary args) based on the
    # args provided by the redirect.
    # Rely on index to do all error handling and access control.
    if chapter is None:
        redirect_url = reverse('courseware', args=(str(course_key), ))
    elif section is None:
        redirect_url = reverse('courseware_chapter',
                               args=(str(course_key), chapter))
    elif position is None:
        redirect_url = reverse('courseware_section',
                               args=(str(course_key), chapter, section))
    else:
        # Here we use the navigation_index from the position returned from
        # path_to_location - we can only navigate to the topmost vertical at the
        # moment
        redirect_url = reverse('courseware_position',
                               args=(str(course_key), chapter, section,
                                     navigation_index(position)))
    redirect_url += "?{}".format(
        urlencode({'activate_block_id': str(final_target_id)}))
    return redirect_url
    def location(self):
        """
        Blend "location" property into the resultset, so that the path to the found component can be shown within the UI
        """
        # TODO: update whern changes to "cohorted-courseware" branch are merged in
        (course_key, chapter, section,
         position) = path_to_location(self.get_module_store(),
                                      self.get_usage_key())

        def get_display_name(category, item_id):
            """ helper to get display name from object """
            item = self.get_item(course_key.make_usage_key(category, item_id))
            return getattr(item, "display_name", None)

        def get_position_name(section, position):
            """ helper to fetch name corresponding to the position therein """
            pos = int(position)
            section_item = self.get_item(
                course_key.make_usage_key("sequential", section))
            if section_item.has_children and len(section_item.children) >= pos:
                item = self.get_item(section_item.children[pos - 1])
                return getattr(item, "display_name", None)
            return None

        location_description = []
        if chapter:
            location_description.append(get_display_name("chapter", chapter))
        if section:
            location_description.append(get_display_name(
                "sequential", section))
        if position:
            location_description.append(get_position_name(section, position))

        return location_description
Example #8
0
    def add_problem_data(self, base_course_url):
        """
        Add metadata to problems.
        @param base_course_url: the base url for any course.  Can get with reverse('course')
        @return: A list of valid problems in the course and their appended data.
        """
        # Our list of valid problems.
        valid_problems = []

        if not self.success or not isinstance(self.problem_list, list):
            log.error("Called add_problem_data without a valid problem list" + self.course_error_ending)
            return valid_problems

        # Iterate through all of our problems and add data.
        for problem in self.problem_list:
            try:
                # Try to load the problem.
                problem_url_parts = search.path_to_location(modulestore(), self.course_id, problem['location'])
            except (ItemNotFoundError, NoPathToItem):
                # If the problem cannot be found at the location received from the grading controller server,
                # it has been deleted by the course author. We should not display it.
                error_message = "Could not find module for course {0} at location {1}".format(self.course_id,
                                                                                              problem['location'])
                log.error(error_message)
                continue

            # Get the problem url in the courseware.
            problem_url = generate_problem_url(problem_url_parts, base_course_url)

            # Map the grader name from ORA to a human readable version.
            grader_type_display_name = GRADER_DISPLAY_NAMES.get(problem['grader_type'], "edX Assessment")
            problem['actual_url'] = problem_url
            problem['grader_type_display_name'] = grader_type_display_name
            valid_problems.append(problem)
        return valid_problems
    def location(self):
        """
        Blend "location" property into the resultset, so that the path to the found component can be shown within the UI
        """
        # TODO: update whern changes to "cohorted-courseware" branch are merged in
        (course_key, chapter, section, position) = path_to_location(self.get_module_store(), self.get_usage_key())

        def get_display_name(item_key):
            """ gets display name from object's key """
            item = self.get_item(item_key)
            display_name = getattr(item, "display_name", None)
            return display_name if display_name else UNNAMED_MODULE_NAME

        def get_position_name(section, position):
            """ helper to fetch name corresponding to the position therein """
            pos = int(position)
            section_item = self.get_item(course_key.make_usage_key("sequential", section))
            if section_item.has_children and len(section_item.children) >= pos:
                return get_display_name(section_item.children[pos - 1])
            return None

        location_description = []
        if chapter:
            location_description.append(get_display_name(course_key.make_usage_key("chapter", chapter)))
        if section:
            location_description.append(get_display_name(course_key.make_usage_key("sequential", section)))
        if position:
            location_description.append(get_position_name(section, position))

        return location_description
Example #10
0
def find_peer_grading_module(course):
    """
    Given a course, finds the first peer grading module in it.
    @param course: A course object.
    @return: boolean found_module, string problem_url
    """
    #Reverse the base course url
    base_course_url = reverse('courses')
    found_module = False
    problem_url = ""

    #Get the course id and split it
    course_id_parts = course.id.split("/")
    log.info("COURSE ID PARTS")
    log.info(course_id_parts)
    #Get the peer grading modules currently in the course.  Explicitly specify the course id to avoid issues with different runs.
    items = modulestore().get_items(
        ['i4x', course_id_parts[0], course_id_parts[1], 'peergrading', None],
        course_id=course.id)
    #See if any of the modules are centralized modules (ie display info from multiple problems)
    items = [
        i for i in items if not getattr(i, "use_for_single_location", True)
    ]
    #Get the first one
    if len(items) > 0:
        item_location = items[0].location
        #Generate a url for the first module and redirect the user to it
        problem_url_parts = search.path_to_location(modulestore(), course.id,
                                                    item_location)
        problem_url = generate_problem_url(problem_url_parts, base_course_url)
        found_module = True

    return found_module, problem_url
Example #11
0
    def add_problem_data(self, base_course_url):
        """
        Add metadata to problems.
        @param base_course_url: the base url for any course.  Can get with reverse('course')
        @return: A list of valid problems in the course and their appended data.
        """
        # Our list of valid problems.
        valid_problems = []

        if not self.success or not isinstance(self.problem_list, list):
            log.error("Called add_problem_data without a valid problem list" + self.course_error_ending)
            return valid_problems

        # Iterate through all of our problems and add data.
        for problem in self.problem_list:
            try:
                # Try to load the problem.
                problem_url_parts = search.path_to_location(modulestore(), self.course_id, problem['location'])
            except (ItemNotFoundError, NoPathToItem):
                # If the problem cannot be found at the location received from the grading controller server,
                # it has been deleted by the course author. We should not display it.
                error_message = "Could not find module for course {0} at location {1}".format(self.course_id,
                                                                                              problem['location'])
                log.error(error_message)
                continue

            # Get the problem url in the courseware.
            problem_url = generate_problem_url(problem_url_parts, base_course_url)

            # Map the grader name from ORA to a human readable version.
            grader_type_display_name = GRADER_DISPLAY_NAMES.get(problem['grader_type'], "edX Assessment")
            problem['actual_url'] = problem_url
            problem['grader_type_display_name'] = grader_type_display_name
            valid_problems.append(problem)
        return valid_problems
Example #12
0
def jump_to(request, course_id, location):
    """
    Show the page that contains a specific location.

    If the location is invalid or not in any class, return a 404.

    Otherwise, delegates to the index view to figure out whether this user
    has access, and what they should see.
    """
    # Complain if the location isn't valid
    try:
        location = Location(location)
    except InvalidLocationError:
        raise Http404("Invalid location")

    # Complain if there's not data for this location
    try:
        (course_id, chapter, section, position) = path_to_location(modulestore(), course_id, location)
    except ItemNotFoundError:
        raise Http404("No data at this location: {0}".format(location))
    except NoPathToItem:
        raise Http404("This location is not in any class: {0}".format(location))

    # choose the appropriate view (and provide the necessary args) based on the
    # args provided by the redirect.
    # Rely on index to do all error handling and access control.
    if chapter is None:
        return redirect("courseware", course_id=course_id)
    elif section is None:
        return redirect("courseware_chapter", course_id=course_id, chapter=chapter)
    elif position is None:
        return redirect("courseware_section", course_id=course_id, chapter=chapter, section=section)
    else:
        return redirect("courseware_position", course_id=course_id, chapter=chapter, section=section, position=position)
Example #13
0
    def get(self, request, course_key_string, *args, **kwargs):
        """
        Return response to a GET request.
        """
        course_id = CourseKey.from_string(course_key_string)
        resp = {
            'block_id': None,
            'section_id': None,
            'unit_id': None,
        }

        try:
            block_key = get_key_to_last_completed_block(
                request.user, course_id)
            path = path_to_location(modulestore(),
                                    block_key,
                                    request,
                                    full_path=True)
            resp['section_id'] = str(path[2])
            resp['unit_id'] = str(path[3])
            resp['block_id'] = str(block_key)

        except UnavailableCompletionData:
            pass

        return Response(resp)
Example #14
0
def jump_to(request, course_id, location):
    """
    Show the page that contains a specific location.

    If the location is invalid or not in any class, return a 404.

    Otherwise, delegates to the index view to figure out whether this user
    has access, and what they should see.
    """
    try:
        course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
        usage_key = course_key.make_usage_key_from_deprecated_string(location)
    except InvalidKeyError:
        raise Http404(u"Invalid course_key or usage_key")
    try:
        (course_key, chapter, section, position) = path_to_location(modulestore(), usage_key)
    except ItemNotFoundError:
        raise Http404(u"No data at this location: {0}".format(usage_key))
    except NoPathToItem:
        raise Http404(u"This location is not in any class: {0}".format(usage_key))

    # choose the appropriate view (and provide the necessary args) based on the
    # args provided by the redirect.
    # Rely on index to do all error handling and access control.
    if chapter is None:
        return redirect('courseware', course_id=course_key.to_deprecated_string())
    elif section is None:
        return redirect('courseware_chapter', course_id=course_key.to_deprecated_string(), chapter=chapter)
    elif position is None:
        return redirect('courseware_section', course_id=course_key.to_deprecated_string(), chapter=chapter, section=section)
    else:
        return redirect('courseware_position', course_id=course_key.to_deprecated_string(), chapter=chapter, section=section, position=position)
Example #15
0
    def get(self, request, course_key_string, *args, **kwargs):  # lint-amnesty, pylint: disable=unused-argument
        """
        Return response to a GET request.
        """
        course_id = CourseKey.from_string(course_key_string)
        resp = {
            'block_id': None,
            'section_id': None,
            'unit_id': None,
        }

        try:
            block_key = get_key_to_last_completed_block(
                request.user, course_id)
            path = path_to_location(modulestore(),
                                    block_key,
                                    request,
                                    full_path=True)
            resp['section_id'] = str(path[2])
            resp['unit_id'] = str(path[3])
            resp['block_id'] = str(block_key)

        except (ItemNotFoundError, NoPathToItem, UnavailableCompletionData):
            pass  # leaving all the IDs as None indicates a redirect to the first unit in the course, as a backup

        return Response(resp)
Example #16
0
def jump_to(request, course_id, location):
    """
    Show the page that contains a specific location.

    If the location is invalid or not in any class, return a 404.

    Otherwise, delegates to the index view to figure out whether this user
    has access, and what they should see.
    """
    # Complain if the location isn't valid
    try:
        location = Location(location)
    except InvalidLocationError:
        raise Http404("Invalid location")

    # Complain if there's not data for this location
    try:
        (course_id, chapter, section, position) = path_to_location(modulestore(), course_id, location)
    except ItemNotFoundError:
        raise Http404(u"No data at this location: {0}".format(location))
    except NoPathToItem:
        raise Http404(u"This location is not in any class: {0}".format(location))

    # choose the appropriate view (and provide the necessary args) based on the
    # args provided by the redirect.
    # Rely on index to do all error handling and access control.
    if chapter is None:
        return redirect('courseware', course_id=course_id)
    elif section is None:
        return redirect('courseware_chapter', course_id=course_id, chapter=chapter)
    elif position is None:
        return redirect('courseware_section', course_id=course_id, chapter=chapter, section=section)
    else:
        return redirect('courseware_position', course_id=course_id, chapter=chapter, section=section, position=position)
Example #17
0
def _get_new_courseware_url(
    usage_key: UsageKey,
    request: Optional[HttpRequest] = None,
) -> str:
    """
    Return the URL to the "new" (Learning Micro-Frontend) experience for a given block.

    Raises:
        * ItemNotFoundError if no data at the `usage_key`.
        * NoPathToItem if we cannot build a path to the `usage_key`.
    """
    course_key = usage_key.course_key.replace(version_guid=None, branch=None)
    path = path_to_location(modulestore(), usage_key, request, full_path=True)
    if len(path) <= 1:
        # Course-run-level block:
        # We have no Sequence or Unit to return.
        sequence_key, unit_key = None, None
    elif len(path) == 2:
        # Section-level (ie chapter) block:
        # The Section is the Sequence. We have no Unit to return.
        sequence_key, unit_key = path[1], None
    elif len(path) == 3:
        # Subsection-level block:
        # The Subsection is the Sequence. We still have no Unit to return.
        sequence_key, unit_key = path[2], None
    else:
        # Unit-level (or lower) block:
        # The Subsection is the Sequence, and the next level down is the Unit.
        sequence_key, unit_key = path[2], path[3]
    return make_learning_mfe_courseware_url(
        course_key=course_key,
        sequence_key=sequence_key,
        unit_key=unit_key,
    )
Example #18
0
def find_peer_grading_module(course):
    """
    Given a course, finds the first peer grading module in it.
    @param course: A course object.
    @return: boolean found_module, string problem_url
    """
    #Reverse the base course url
    base_course_url = reverse('courses')
    found_module = False
    problem_url = ""

    #Get the course id and split it
    course_id_parts = course.id.split("/")
    log.info("COURSE ID PARTS")
    log.info(course_id_parts)
    #Get the peer grading modules currently in the course.  Explicitly specify the course id to avoid issues with different runs.
    items = modulestore().get_items(['i4x', course_id_parts[0], course_id_parts[1], 'peergrading', None],
                                    course_id=course.id)
    #See if any of the modules are centralized modules (ie display info from multiple problems)
    items = [i for i in items if not getattr(i, "use_for_single_location", True)]
    #Get the first one
    if len(items) > 0:
        item_location = items[0].location
        #Generate a url for the first module and redirect the user to it
        problem_url_parts = search.path_to_location(modulestore(), course.id, item_location)
        problem_url = generate_problem_url(problem_url_parts, base_course_url)
        found_module = True

    return found_module, problem_url
Example #19
0
    def test_path_to_location_for_orphan_chapter(self, module_store):
        r"""
        Make sure that path_to_location works with a component having multiple chapter parents,
        from which one of them is orphan

         course
            |
        chapter   chapter
           |         |
        vertical  vertical
              \    /
               html

        """
        # Get a course with orphan modules
        course = self.create_course_with_orphans(module_store)
        orphan_chapter = self.store.get_item(BlockUsageLocator(course.id, 'chapter', 'OrphanChapter'))
        chapter1 = self.store.get_item(BlockUsageLocator(course.id, 'chapter', 'Chapter1'))
        vertical1 = self.store.get_item(BlockUsageLocator(course.id, 'vertical', 'Vertical1'))

        # Verify `OrhanChapter` is an orphan
        self.assertIn(orphan_chapter.location, self.store.get_orphans(course.id))

        # Create a vertical (`Vertical0`) in orphan chapter (`OrphanChapter`).
        # OrphanChapter -> Vertical0
        vertical0 = self.store.create_child(self.user.id, orphan_chapter.location, 'vertical', "Vertical0")
        self.store.publish(vertical0.location, self.user.id)

        # Create a component in `Vertical0`
        # OrphanChapter -> Vertical0 -> Html
        html = self.store.create_child(self.user.id, vertical0.location, 'html', "HTML0")
        self.store.publish(html.location, self.user.id)

        # Verify chapter1 is parent of vertical1.
        vertical1_parent = self.store.get_parent_location(vertical1.location)
        self.assertEqual(unicode(vertical1_parent), unicode(chapter1.location))

        # Make `Vertical1` the parent of `HTML0`. So `HTML0` will have to parents (`Vertical0` & `Vertical1`)
        vertical1.children.append(html.location)
        self.store.update_item(vertical1, self.user.id)

        # Get parent location & verify its either of the two verticals. As both parents are non-orphan,
        # alphabetically least is returned
        html_parent = self.store.get_parent_location(html.location)
        self.assertEquals(unicode(html_parent), unicode(vertical1.location))

        # verify path_to_location returns a expected path
        path = path_to_location(self.store, html.location)
        expected_path = (
            course.id,
            chapter1.location.block_id,
            vertical1.location.block_id,
            html.location.block_id,
            "",
            path[-1]
        )
        self.assertIsNotNone(path)
        self.assertEqual(len(path), 6)
        self.assertEqual(path, expected_path)
Example #20
0
    def test_path_to_location_for_orphan_chapter(self, module_store):
        r"""
        Make sure that path_to_location works with a component having multiple chapter parents,
        from which one of them is orphan

         course
            |
        chapter   chapter
           |         |
        vertical  vertical
              \    /
               html

        """
        # Get a course with orphan modules
        course = self.create_course_with_orphans(module_store)
        orphan_chapter = self.store.get_item(BlockUsageLocator(course.id, 'chapter', 'OrphanChapter'))
        chapter1 = self.store.get_item(BlockUsageLocator(course.id, 'chapter', 'Chapter1'))
        vertical1 = self.store.get_item(BlockUsageLocator(course.id, 'vertical', 'Vertical1'))

        # Verify `OrhanChapter` is an orphan
        self.assertIn(orphan_chapter.location, self.store.get_orphans(course.id))

        # Create a vertical (`Vertical0`) in orphan chapter (`OrphanChapter`).
        # OrphanChapter -> Vertical0
        vertical0 = self.store.create_child(self.user.id, orphan_chapter.location, 'vertical', "Vertical0")
        self.store.publish(vertical0.location, self.user.id)

        # Create a component in `Vertical0`
        # OrphanChapter -> Vertical0 -> Html
        html = self.store.create_child(self.user.id, vertical0.location, 'html', "HTML0")
        self.store.publish(html.location, self.user.id)

        # Verify chapter1 is parent of vertical1.
        vertical1_parent = self.store.get_parent_location(vertical1.location)
        self.assertEqual(six.text_type(vertical1_parent), six.text_type(chapter1.location))

        # Make `Vertical1` the parent of `HTML0`. So `HTML0` will have to parents (`Vertical0` & `Vertical1`)
        vertical1.children.append(html.location)
        self.store.update_item(vertical1, self.user.id)

        # Get parent location & verify its either of the two verticals. As both parents are non-orphan,
        # alphabetically least is returned
        html_parent = self.store.get_parent_location(html.location)
        self.assertEquals(six.text_type(html_parent), six.text_type(vertical1.location))

        # verify path_to_location returns a expected path
        path = path_to_location(self.store, html.location)
        expected_path = (
            course.id,
            chapter1.location.block_id,
            vertical1.location.block_id,
            html.location.block_id,
            "",
            path[-1]
        )
        self.assertIsNotNone(path)
        self.assertEqual(len(path), 6)
        self.assertEqual(path, expected_path)
def get_chapter_from_location(usage_id, course_key):
    """ hawthorn backend """
    usage_key = UsageKey.from_string(
        unquote_slashes(usage_id)).map_into_course(course_key)
    if usage_key:
        path = search.path_to_location(modulestore(), usage_key)
        chapter = path[
            1]  # 1 is the position where path_to_location returns the chapter
        return chapter
    return None
Example #22
0
def does_location_exist(usage_key):
    """
    Checks to see if a valid module exists at a given location (ie has not been deleted)
    course_id - string course id
    location - string location
    """
    try:
        search.path_to_location(modulestore(), usage_key)
        return True
    except ItemNotFoundError:
        # If the problem cannot be found at the location received from the grading controller server,
        # it has been deleted by the course author.
        return False
    except NoPathToItem:
        # If the problem can be found, but there is no path to it, then we assume it is a draft.
        # Log a warning in any case.
        log.warn("Got an unexpected NoPathToItem error in staff grading with location %s. "
                 "This is ok if it is a draft; ensure that the location is valid.", usage_key)
        return False
Example #23
0
def does_location_exist(course_id, location):
    """
    Checks to see if a valid module exists at a given location (ie has not been deleted)
    course_id - string course id
    location - string location
    """
    try:
        search.path_to_location(modulestore(), course_id, location)
        return True
    except ItemNotFoundError:
        # If the problem cannot be found at the location received from the grading controller server,
        # it has been deleted by the course author.
        return False
    except NoPathToItem:
        # If the problem can be found, but there is no path to it, then we assume it is a draft.
        # Log a warning if the problem is not a draft (location does not end in "draft").
        if not location.endswith("draft"):
            log.warn(("Got an unexpected NoPathToItem error in staff grading with a non-draft location {0}. "
                      "Ensure that the location is valid.").format(location))
        return False
Example #24
0
def does_location_exist(course_id, location):
    """
    Checks to see if a valid module exists at a given location (ie has not been deleted)
    course_id - string course id
    location - string location
    """
    try:
        search.path_to_location(modulestore(), course_id, location)
        return True
    except ItemNotFoundError:
        # If the problem cannot be found at the location received from the grading controller server,
        # it has been deleted by the course author.
        return False
    except NoPathToItem:
        # If the problem can be found, but there is no path to it, then we assume it is a draft.
        # Log a warning if the problem is not a draft (location does not end in "draft").
        if not location.endswith("draft"):
            log.warn(("Got an unexpected NoPathToItem error in staff grading with a non-draft location {0}. "
                      "Ensure that the location is valid.").format(location))
        return False
Example #25
0
def does_location_exist(usage_key):
    """
    Checks to see if a valid module exists at a given location (ie has not been deleted)
    course_id - string course id
    location - string location
    """
    try:
        search.path_to_location(modulestore(), usage_key)
        return True
    except ItemNotFoundError:
        # If the problem cannot be found at the location received from the grading controller server,
        # it has been deleted by the course author.
        return False
    except NoPathToItem:
        # If the problem can be found, but there is no path to it, then we assume it is a draft.
        # Log a warning in any case.
        log.warn(
            "Got an unexpected NoPathToItem error in staff grading with location %s. "
            "This is ok if it is a draft; ensure that the location is valid.",
            usage_key)
        return False
Example #26
0
    def test_path_to_location_for_orphan_vertical(self, module_store):
        r"""
        Make sure that path_to_location works with a component having multiple vertical parents,
        from which one of them is orphan.

         course
            |
         chapter
           |
         vertical vertical
            \     /
              html
        """
        # Get a course with orphan modules
        course = self.create_course_with_orphans(module_store)

        # Fetch the required course components.
        vertical1 = self.store.get_item(
            BlockUsageLocator(course.id, 'vertical', 'Vertical1'))
        chapter1 = self.store.get_item(
            BlockUsageLocator(course.id, 'chapter', 'Chapter1'))
        orphan_vertical = self.store.get_item(
            BlockUsageLocator(course.id, 'vertical', 'OrphanVert'))
        multi_parent_html = self.store.get_item(
            BlockUsageLocator(course.id, 'html', 'multi_parent_html'))

        # Verify `OrphanVert` is an orphan
        self.assertIn(orphan_vertical.location,
                      self.store.get_orphans(course.id))

        # Verify `multi_parent_html` is child of both `Vertical1` and `OrphanVert`
        self.assertIn(multi_parent_html.location, orphan_vertical.children)
        self.assertIn(multi_parent_html.location, vertical1.children)

        # HTML component has `vertical1` as its parent.
        html_parent = self.store.get_parent_location(
            multi_parent_html.location)
        self.assertNotEqual(six.text_type(html_parent),
                            six.text_type(orphan_vertical.location))
        self.assertEqual(six.text_type(html_parent),
                         six.text_type(vertical1.location))

        # Get path of the `multi_parent_html` & verify path_to_location returns a expected path
        path = path_to_location(self.store, multi_parent_html.location)
        expected_path = (course.id, chapter1.location.block_id,
                         vertical1.location.block_id,
                         multi_parent_html.location.block_id, "", path[-1])
        self.assertIsNotNone(path)
        self.assertEqual(len(path), 6)
        self.assertEqual(path, expected_path)
Example #27
0
def check_path_to_location(modulestore):
    """
    Make sure that path_to_location works: should be passed a modulestore
    with the toy and simple courses loaded.
    """
    course_id = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")

    should_work = (
        (course_id.make_usage_key('video', 'Welcome'),
         (course_id, "Overview", "Welcome", None)),
        (course_id.make_usage_key('chapter', 'Overview'),
         (course_id, "Overview", None, None)),
    )

    for location, expected in should_work:
        assert_equals(path_to_location(modulestore, location), expected)

    not_found = (
        course_id.make_usage_key('video', 'WelcomeX'),
        course_id.make_usage_key('course', 'NotHome'),
    )
    for location in not_found:
        with assert_raises(ItemNotFoundError):
            path_to_location(modulestore, location)
def check_path_to_location(modulestore):
    """
    Make sure that path_to_location works: should be passed a modulestore
    with the toy and simple courses loaded.
    """
    course_id = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")

    should_work = (
        (course_id.make_usage_key('video', 'Welcome'), (course_id, "Overview",
                                                        "Welcome", None)),
        (course_id.make_usage_key('chapter', 'Overview'),
         (course_id, "Overview", None, None)),
    )

    for location, expected in should_work:
        assert_equals(path_to_location(modulestore, location), expected)

    not_found = (
        course_id.make_usage_key('video', 'WelcomeX'),
        course_id.make_usage_key('course', 'NotHome'),
    )
    for location in not_found:
        with assert_raises(ItemNotFoundError):
            path_to_location(modulestore, location)
Example #29
0
def get_redirect_url(course_key, usage_key, child=None):
    """ Returns the redirect url back to courseware

    Args:
        course_id(str): Course Id string
        location(str): The location id of course component
        child(str): Optional child parameter to pass to the URL

    Raises:
        ItemNotFoundError if no data at the location or NoPathToItem if location not in any class

    Returns:
        Redirect url string
    """

    (
        course_key, chapter, section, vertical_unused,
        position, final_target_id
    ) = path_to_location(modulestore(), usage_key)

    # choose the appropriate view (and provide the necessary args) based on the
    # args provided by the redirect.
    # Rely on index to do all error handling and access control.
    if chapter is None:
        redirect_url = reverse('courseware', args=(unicode(course_key), ))
    elif section is None:
        redirect_url = reverse('courseware_chapter', args=(unicode(course_key), chapter))
    elif position is None:
        redirect_url = reverse(
            'courseware_section',
            args=(unicode(course_key), chapter, section)
        )
    else:
        # Here we use the navigation_index from the position returned from
        # path_to_location - we can only navigate to the topmost vertical at the
        # moment

        redirect_url = reverse(
            'courseware_position',
            args=(unicode(course_key), chapter, section, navigation_index(position))
        )

    redirect_url += "?{}".format(urlencode({'activate_block_id': unicode(final_target_id)}))

    if child:
        redirect_url += "&child={}".format(child)

    return redirect_url
Example #30
0
    def test_path_to_location_for_orphan_vertical(self, module_store):
        r"""
        Make sure that path_to_location works with a component having multiple vertical parents,
        from which one of them is orphan.

         course
            |
         chapter
           |
         vertical vertical
            \     /
              html
        """
        # Get a course with orphan modules
        course = self.create_course_with_orphans(module_store)

        # Fetch the required course components.
        vertical1 = self.store.get_item(BlockUsageLocator(course.id, 'vertical', 'Vertical1'))
        chapter1 = self.store.get_item(BlockUsageLocator(course.id, 'chapter', 'Chapter1'))
        orphan_vertical = self.store.get_item(BlockUsageLocator(course.id, 'vertical', 'OrphanVert'))
        multi_parent_html = self.store.get_item(BlockUsageLocator(course.id, 'html', 'multi_parent_html'))

        # Verify `OrphanVert` is an orphan
        self.assertIn(orphan_vertical.location, self.store.get_orphans(course.id))

        # Verify `multi_parent_html` is child of both `Vertical1` and `OrphanVert`
        self.assertIn(multi_parent_html.location, orphan_vertical.children)
        self.assertIn(multi_parent_html.location, vertical1.children)

        # HTML component has `vertical1` as its parent.
        html_parent = self.store.get_parent_location(multi_parent_html.location)
        self.assertNotEqual(unicode(html_parent), unicode(orphan_vertical.location))
        self.assertEqual(unicode(html_parent), unicode(vertical1.location))

        # Get path of the `multi_parent_html` & verify path_to_location returns a expected path
        path = path_to_location(self.store, multi_parent_html.location)
        expected_path = (
            course.id,
            chapter1.location.block_id,
            vertical1.location.block_id,
            multi_parent_html.location.block_id,
            "",
            path[-1]
        )
        self.assertIsNotNone(path)
        self.assertEqual(len(path), 6)
        self.assertEqual(path, expected_path)
Example #31
0
def get_redirect_url(course_key, usage_key, child=None):
    """ Returns the redirect url back to courseware

    Args:
        course_id(str): Course Id string
        location(str): The location id of course component
        child(str): Optional child parameter to pass to the URL

    Raises:
        ItemNotFoundError if no data at the location or NoPathToItem if location not in any class

    Returns:
        Redirect url string
    """

    (course_key, chapter, section, vertical_unused, position,
     final_target_id) = path_to_location(modulestore(), usage_key)

    # choose the appropriate view (and provide the necessary args) based on the
    # args provided by the redirect.
    # Rely on index to do all error handling and access control.
    if chapter is None:
        redirect_url = reverse('courseware', args=(unicode(course_key), ))
    elif section is None:
        redirect_url = reverse('courseware_chapter',
                               args=(unicode(course_key), chapter))
    elif position is None:
        redirect_url = reverse('courseware_section',
                               args=(unicode(course_key), chapter, section))
    else:
        # Here we use the navigation_index from the position returned from
        # path_to_location - we can only navigate to the topmost vertical at the
        # moment

        redirect_url = reverse('courseware_position',
                               args=(unicode(course_key), chapter, section,
                                     navigation_index(position)))

    redirect_url += "?{}".format(
        urlencode({'activate_block_id': unicode(final_target_id)}))

    if child:
        redirect_url += "&child={}".format(child)

    return redirect_url
Example #32
0
def get_redirect_url(course_key, usage_key, unified_course_view=False):
    """ Returns the redirect url back to courseware

    Args:
        course_id(str): Course Id string
        location(str): The location id of course component
        unified_course_view (bool): temporary parameter while this feature is behind a waffle flag.
            Is the unified_course_view waffle flag on?

    Raises:
        ItemNotFoundError if no data at the location or NoPathToItem if location not in any class

    Returns:
        Redirect url string
    """
    if usage_key.block_type == 'course' and unified_course_view:
        return reverse('openedx.course_experience.course_home',
                       args=[unicode(course_key)])

    (course_key, chapter, section, vertical_unused, position,
     final_target_id) = path_to_location(modulestore(), usage_key)

    # choose the appropriate view (and provide the necessary args) based on the
    # args provided by the redirect.
    # Rely on index to do all error handling and access control.
    if chapter is None:
        redirect_url = reverse('courseware', args=(unicode(course_key), ))
    elif section is None:
        redirect_url = reverse('courseware_chapter',
                               args=(unicode(course_key), chapter))
    elif position is None:
        redirect_url = reverse('courseware_section',
                               args=(unicode(course_key), chapter, section))
    else:
        # Here we use the navigation_index from the position returned from
        # path_to_location - we can only navigate to the topmost vertical at the
        # moment
        redirect_url = reverse('courseware_position',
                               args=(unicode(course_key), chapter, section,
                                     navigation_index(position)))
    redirect_url += "?{}".format(
        urlencode({'activate_block_id': unicode(final_target_id)}))
    return redirect_url
Example #33
0
def check_path_to_location(modulestore):
    '''Make sure that path_to_location works: should be passed a modulestore
    with the toy and simple courses loaded.'''
    should_work = (
        ("i4x://edX/toy/video/Welcome",
         ("edX/toy/2012_Fall", "Overview", "Welcome", None)),
        ("i4x://edX/toy/chapter/Overview",
         ("edX/toy/2012_Fall", "Overview", None, None)),
    )
    course_id = "edX/toy/2012_Fall"

    for location, expected in should_work:
        assert_equals(path_to_location(modulestore, course_id, location), expected)

    not_found = (
        "i4x://edX/toy/video/WelcomeX", "i4x://edX/toy/course/NotHome"
    )
    for location in not_found:
        assert_raises(ItemNotFoundError, path_to_location, modulestore, course_id, location)
Example #34
0
def get_legacy_courseware_url(course_key, usage_key, request=None):
    """
    Return a str with the URL for the specified legacy (LMS-rendered) coursweare content.

    Args:
        course_id(str): Course Id string
        usage_key(str): The location id of course component

    Raises:
        ItemNotFoundError if no data at the location or NoPathToItem if location not in any class

    Returns:
        Redirect url string
    """

    (course_key, chapter, section, vertical_unused, position,
     final_target_id) = path_to_location(modulestore(), usage_key, request)

    # choose the appropriate view (and provide the necessary args) based on the
    # args provided by the redirect.
    # Rely on index to do all error handling and access control.
    if chapter is None:
        redirect_url = reverse('courseware',
                               args=(six.text_type(course_key), ))
    elif section is None:
        redirect_url = reverse('courseware_chapter',
                               args=(six.text_type(course_key), chapter))
    elif position is None:
        redirect_url = reverse('courseware_section',
                               args=(six.text_type(course_key), chapter,
                                     section))
    else:
        # Here we use the navigation_index from the position returned from
        # path_to_location - we can only navigate to the topmost vertical at the
        # moment
        redirect_url = reverse('courseware_position',
                               args=(six.text_type(course_key), chapter,
                                     section, navigation_index(position)))
    redirect_url += "?{}".format(
        urlencode({'activate_block_id': six.text_type(final_target_id)}))
    return redirect_url
Example #35
0
    def get_path(usage_key):
        """
        Returns data for the path to the block in the course graph.

        Note: In case of multiple paths to the block from the course
        root, this function returns a path arbitrarily but consistently,
        depending on the modulestore. In the future, we may want to
        extend it to check which of the paths, the user has access to
        and return its data.

        Arguments:
            block (XBlock): The block whose path is required.

        Returns:
            list of PathItems
        """
        with modulestore().bulk_operations(usage_key.course_key):
            try:
                path = search.path_to_location(modulestore(),
                                               usage_key,
                                               full_path=True)
            except ItemNotFoundError:
                log.error(u'Block with usage_key: %s not found.', usage_key)
                return []
            except NoPathToItem:
                log.error(u'No path to block with usage_key: %s.', usage_key)
                return []

            path_data = []
            for ancestor_usage_key in path:
                if ancestor_usage_key != usage_key and ancestor_usage_key.block_type != 'course':  # pylint: disable=no-member
                    try:
                        block = modulestore().get_item(ancestor_usage_key)
                    except ItemNotFoundError:
                        return []  # No valid path can be found.

                    path_data.append(
                        PathItem(usage_key=block.location,
                                 display_name=block.display_name))

        return path_data
Example #36
0
    def get_path(usage_key):
        """
        Returns data for the path to the block in the course graph.

        Note: In case of multiple paths to the block from the course
        root, this function returns a path arbitrarily but consistently,
        depending on the modulestore. In the future, we may want to
        extend it to check which of the paths, the user has access to
        and return its data.

        Arguments:
            block (XBlock): The block whose path is required.

        Returns:
            list of PathItems
        """
        with modulestore().bulk_operations(usage_key.course_key):
            try:
                path = search.path_to_location(modulestore(), usage_key, full_path=True)
            except ItemNotFoundError:
                log.error(u'Block with usage_key: %s not found.', usage_key)
                return []
            except NoPathToItem:
                log.error(u'No path to block with usage_key: %s.', usage_key)
                return []

            path_data = []
            for ancestor_usage_key in path:
                if ancestor_usage_key != usage_key and ancestor_usage_key.block_type != 'course':  # pylint: disable=no-member
                    try:
                        block = modulestore().get_item(ancestor_usage_key)
                    except ItemNotFoundError:
                        return []  # No valid path can be found.

                    path_data.append(
                        PathItem(usage_key=block.location, display_name=block.display_name)
                    )

        return path_data
Example #37
0
def _get_sequence_and_unit_keys(
    usage_key: UsageKey,
    request: Optional[HttpRequest] = None,
) -> Tuple[Optional[UsageKey], Optional[UsageKey]]:
    """
    Find the sequence and unit containg a block within a course run.

    Performance consideration: Currently, this function incurs a modulestore query.

    Raises:
        * ItemNotFoundError if no data at the `usage_key`.
        * NoPathToItem if we cannot build a path to the `usage_key`.

    Returns: (sequence_key|None, unit_key|None)
    * sequence_key points to a Section (ie chapter) or Subsection (ie sequential).
    * unit_key points to  Unit (ie vertical).
    Either of these may be None if we are above that level in the course hierarchy.
    For example, if `usage_key` points to a Subsection, then unit_key will be None.
    """
    path = path_to_location(modulestore(), usage_key, request, full_path=True)
    if len(path) <= 1:
        # Course-run-level block:
        # We have no Sequence or Unit to return.
        return None, None
    elif len(path) == 2:
        # Section-level (ie chapter) block:
        # The Section is the Sequence. We have no Unit to return.
        return path[1], None
    elif len(path) == 3:
        # Subsection-level block:
        # The Subsection is the Sequence. We still have no Unit to return.
        return path[2], None
    else:
        # Unit-level (or lower) block:
        # The Subsection is the Sequence, and the next level down is the Unit.
        return path[2], path[3]
def staff_notification():
    """
    To send ORA statactics to staff users of course
    """
    try:
        course_data = CourseOverview.objects.all()
        for cid in course_data:
            assessment_data = AssessmentWorkflow.objects.filter(
                course_id=cid.id)
            item_data = []
            
            for sid in assessment_data:
                if not bool(staff.get_latest_staff_assessment(sid.submission_uuid)):
                    if sid.item_id not in item_data:
                        item_data.append(sid.item_id)
            # item_data = AssessmentWorkflow.objects.filter(
            #     course_id=cid.id).values_list('item_id', flat=True)
            # item_data = list(set(item_data))
            for iid in item_data:
                statistics = api.get_status_counts(cid.id, iid,
                                                   ["staff", "peer", "done",
                                                    "waiting"])
                modified_statistics = dict()
                for stat in statistics:
                    modified_statistics[stat.get('status')] = stat.get('count')

                statistics = modified_statistics

                if (( statistics['staff'] == 0 ) and ( statistics['peer'] == 0 ) and ( statistics['waiting'] == 0 )):
                    return
                    
                
                course_struct = None
                chapter_name = None
 
                try:
                    course_struct = CourseStructure.objects.get(course_id=cid.id)
                except Exception as e:
                    print "Unexpected error {0}".format(e)

                if course_struct:
                    block = json.loads(course_struct.structure_json)['blocks'][iid]
                    chapter_name = block['display_name']

                staff_users = CourseAccessRole.objects.filter(course_id=cid.id,
                                                              role='staff')
                try:
                    usage_key = UsageKey.from_string(iid).replace(course_key=cid.id)
                    (course_key, chapter, section, vertical_unused,
                    position, final_target_id
                    ) = path_to_location(modulestore(), usage_key)
                    current_site_domain = 'http://{0}'.format(settings.SITE_NAME)
                    courseware_url = current_site_domain+"/courses/"+str(cid.id)+"/courseware/"+chapter+"/"+section
                    for u in staff_users:
                        html_message = render_to_string('peer_grading/ora_report.html',
                                                        {'status_counts': modified_statistics,
                                                         'course': cid.display_name,
                                                         'chapter_name' : chapter_name,
                                                         'user': u.user,
                                                         'courseware_url':courseware_url
                                                         })
                        email = EmailMessage(
                            "LYNX Online-Training: Neue Aufgaben zur Bewertung", html_message,
                            to=[u.user.email])
                        email.send()
                        TASK_LOG.info("----------Email message sent to course admins----------")
                except Exception as e:
                    TASK_LOG.info("----------Inner Exception while sending staff notification----------")
                    import traceback
                    print traceback.format_exc()
                    print e,"Inner Exception<-------"
                    pass
    except Exception as e:
        import traceback
        print traceback.format_exc() 
        print e,"<--- Error"
Example #39
0
def student_problem_list(request, course_id):
    '''
    Show a student problem list to a student.  Fetch the list from the grading controller server, get some metadata,
    and then show it to the student.
    '''
    course = get_course_with_access(request.user, course_id, 'load')
    student_id = unique_id_for_user(request.user)

    # call problem list service
    success = False
    error_text = ""
    problem_list = []
    base_course_url = reverse('courses')
    list_to_remove = []

    try:
        #Get list of all open ended problems that the grading server knows about
        problem_list_json = controller_qs.get_grading_status_list(course_id, unique_id_for_user(request.user))
        problem_list_dict = json.loads(problem_list_json)
        success = problem_list_dict['success']
        if 'error' in problem_list_dict:
            error_text = problem_list_dict['error']
            problem_list = []
        else:
            problem_list = problem_list_dict['problem_list']

        #A list of problems to remove (problems that can't be found in the course)
        for i in xrange(0, len(problem_list)):
            try:
                #Try to load each problem in the courseware to get links to them
                problem_url_parts = search.path_to_location(modulestore(), course.id, problem_list[i]['location'])
            except ItemNotFoundError:
                #If the problem cannot be found at the location received from the grading controller server, it has been deleted by the course author.
                #Continue with the rest of the location to construct the list
                error_message = "Could not find module for course {0} at location {1}".format(course.id,
                                                                                              problem_list[i][
                                                                                                  'location'])
                log.error(error_message)
                #Mark the problem for removal from the list
                list_to_remove.append(i)
                continue
            problem_url = generate_problem_url(problem_url_parts, base_course_url)
            problem_list[i].update({'actual_url': problem_url})
            eta_available = problem_list[i]['eta_available']
            if isinstance(eta_available, basestring):
                eta_available = (eta_available.lower() == "true")

            eta_string = "N/A"
            if eta_available:
                try:
                    eta_string = convert_seconds_to_human_readable(int(problem_list[i]['eta']))
                except:
                    #This is a student_facing_error
                    eta_string = "Error getting ETA."
            problem_list[i].update({'eta_string': eta_string})

    except GradingServiceError:
        #This is a student_facing_error
        error_text = STUDENT_ERROR_MESSAGE
        #This is a dev facing error
        log.error("Problem contacting open ended grading service.")
        success = False
    # catch error if if the json loads fails
    except ValueError:
        #This is a student facing error
        error_text = STUDENT_ERROR_MESSAGE
        #This is a dev_facing_error
        log.error("Problem with results from external grading service for open ended.")
        success = False

    #Remove problems that cannot be found in the courseware from the list
    problem_list = [problem_list[i] for i in xrange(0, len(problem_list)) if i not in list_to_remove]
    ajax_url = _reverse_with_slash('open_ended_problems', course_id)

    return render_to_response('open_ended_problems/open_ended_problems.html', {
        'course': course,
        'course_id': course_id,
        'ajax_url': ajax_url,
        'success': success,
        'problem_list': problem_list,
        'error_text': error_text,
        # Checked above
        'staff_access': False, })
Example #40
0
def find_peer_grading_module(course, user):
    """
    Given a course, finds the first peer grading module in it.
    @param course: A course object.
    @return: boolean found_module, string problem_url
    """

    # Reverse the base course url.
    base_course_url = reverse('courses')
    found_module = False
    problem_url = ""

    print "user: "******"Userid: ", user.id

    # Get the peer grading modules currently in the course.  Explicitly specify the course id to avoid issues with different runs.
    items = modulestore().get_items(course.id, category='peergrading')
    # See if any of the modules are centralized modules (ie display info from multiple problems)
    items = [i for i in items if not getattr(i, "use_for_single_location", True)]
    # Loop through all potential peer grading modules, and find the first one that has a path to it.

    # Faz i nesmo esquema do conteudo do acordion do LMS
    i = 0
    while i < len(items):
        try:
            problem_url_parts = search.path_to_location(modulestore(), items[i].location)

        except NoPathToItem:
            # In the case of nopathtoitem, the peer grading module that was found is in an invalid state, and
            # can no longer be accessed.  Log an informational message, but this will not impact normal behavior.
            log.info(u"Invalid peer grading module location %s in course %s.  This module may need to be removed.", items[i].location, course.id)
            continue



        urlSection = generate_problem_url(problem_url_parts, base_course_url).split('courseware')[1].split('/')[1]
        print "Problem url parts: ", urlSection


        need = NeedThread(user, course)

        if need:
            mythread = CadVersao(urlSection, user)
            mythread.start()
            mythread.join()
            imprimir = mythread.getResult()
        else:
            imprimir = VerABprint(urlSection, user)


        if imprimir == False:
            del items[i]
        else:
            i+=1

            problem_url = generate_problem_url(problem_url_parts, base_course_url)

    for item in items:
        # Generate a url for the first module and redirect the user to it.
        try:
            problem_url_parts = search.path_to_location(modulestore(), item.location)
        except NoPathToItem:
            # In the case of nopathtoitem, the peer grading module that was found is in an invalid state, and
            # can no longer be accessed.  Log an informational message, but this will not impact normal behavior.
            log.info(u"Invalid peer grading module location %s in course %s.  This module may need to be removed.", item.location, course.id)
            continue
        problem_url = generate_problem_url(problem_url_parts, base_course_url)
        found_module = True

    return found_module, problem_url
Example #41
0
def student_problem_list(request, course_id):
    '''
    Show a student problem list to a student.  Fetch the list from the grading controller server, get some metadata,
    and then show it to the student.
    '''
    course = get_course_with_access(request.user, course_id, 'load')
    student_id = unique_id_for_user(request.user)

    # call problem list service
    success = False
    error_text = ""
    problem_list = []
    base_course_url = reverse('courses')
    list_to_remove = []

    try:
        #Get list of all open ended problems that the grading server knows about
        problem_list_json = controller_qs.get_grading_status_list(
            course_id, unique_id_for_user(request.user))
        problem_list_dict = json.loads(problem_list_json)
        success = problem_list_dict['success']
        if 'error' in problem_list_dict:
            error_text = problem_list_dict['error']
            problem_list = []
        else:
            problem_list = problem_list_dict['problem_list']

        #A list of problems to remove (problems that can't be found in the course)
        for i in xrange(0, len(problem_list)):
            try:
                #Try to load each problem in the courseware to get links to them
                problem_url_parts = search.path_to_location(
                    modulestore(), course.id, problem_list[i]['location'])
            except ItemNotFoundError:
                #If the problem cannot be found at the location received from the grading controller server, it has been deleted by the course author.
                #Continue with the rest of the location to construct the list
                error_message = "Could not find module for course {0} at location {1}".format(
                    course.id, problem_list[i]['location'])
                log.error(error_message)
                #Mark the problem for removal from the list
                list_to_remove.append(i)
                continue
            problem_url = generate_problem_url(problem_url_parts,
                                               base_course_url)
            problem_list[i].update({'actual_url': problem_url})
            eta_available = problem_list[i]['eta_available']
            if isinstance(eta_available, basestring):
                eta_available = (eta_available.lower() == "true")

            eta_string = "N/A"
            if eta_available:
                try:
                    eta_string = convert_seconds_to_human_readable(
                        int(problem_list[i]['eta']))
                except:
                    #This is a student_facing_error
                    eta_string = "Error getting ETA."
            problem_list[i].update({'eta_string': eta_string})

    except GradingServiceError:
        #This is a student_facing_error
        error_text = STUDENT_ERROR_MESSAGE
        #This is a dev facing error
        log.error("Problem contacting open ended grading service.")
        success = False
    # catch error if if the json loads fails
    except ValueError:
        #This is a student facing error
        error_text = STUDENT_ERROR_MESSAGE
        #This is a dev_facing_error
        log.error(
            "Problem with results from external grading service for open ended."
        )
        success = False

    #Remove problems that cannot be found in the courseware from the list
    problem_list = [
        problem_list[i] for i in xrange(0, len(problem_list))
        if i not in list_to_remove
    ]
    ajax_url = _reverse_with_slash('open_ended_problems', course_id)

    return render_to_response(
        'open_ended_problems/open_ended_problems.html',
        {
            'course': course,
            'course_id': course_id,
            'ajax_url': ajax_url,
            'success': success,
            'problem_list': problem_list,
            'error_text': error_text,
            # Checked above
            'staff_access': False,
        })