Esempio n. 1
0
def mobi_toc_for_course(user, request, course):

    course_module = get_module_for_descriptor(user, request, course, '', course.id)
    if course_module is None:
        return None
    chapters = list()
    for chapter in course_module.get_display_items():
        sections = list()
        for section in chapter.get_display_items():
            units = list()
            i = 0
            for unit in section.get_display_items():
                i = i + 1
                units.append({'display_name': unit.display_name_with_default,
                              'location': i,
                              'type': unit.get_icon_class()})
            sections.append({'display_name': section.display_name_with_default,
                             'url_name': section.url_name,
                             'format': section.format if section.format is not None else '',
                             'due': get_extended_due_date(section),
                             'graded': section.graded,
                             'units': units
                            })
        chapters.append({'display_name': chapter.display_name_with_default,
                         'url_name': chapter.url_name,
                         'sections': sections,})
    return chapters
Esempio n. 2
0
def toc_for_course(user, request, course, active_chapter, active_section, field_data_cache):
    """
    Create a table of contents from the module store

    Return format:
    [ {'display_name': name, 'url_name': url_name,
       'sections': SECTIONS, 'active': bool}, ... ]

    where SECTIONS is a list
    [ {'display_name': name, 'url_name': url_name,
       'format': format, 'due': due, 'active' : bool, 'graded': bool}, ...]

    active is set for the section and chapter corresponding to the passed
    parameters, which are expected to be url_names of the chapter+section.
    Everything else comes from the xml, or defaults to "".

    chapters with name 'hidden' are skipped.

    NOTE: assumes that if we got this far, user has access to course.  Returns
    None if this is not the case.

    field_data_cache must include data from the course module and 2 levels of its descendents
    """

    course_module = get_module_for_descriptor(user, request, course, field_data_cache, course.id)
    if course_module is None:
        return None

    chapters = list()
    for chapter in course_module.get_display_items():
        if chapter.hide_from_toc:
            continue

        sections = list()
        for section in chapter.get_display_items():

            active = chapter.url_name == active_chapter and section.url_name == active_section

            if not section.hide_from_toc:
                sections.append(
                    {
                        "display_name": section.display_name_with_default,
                        "url_name": section.url_name,
                        "format": section.format if section.format is not None else "",
                        "due": get_extended_due_date(section),
                        "active": active,
                        "graded": section.graded,
                    }
                )

        chapters.append(
            {
                "display_name": chapter.display_name_with_default,
                "url_name": chapter.url_name,
                "sections": sections,
                "active": chapter.url_name == active_chapter,
            }
        )
    return chapters
Esempio n. 3
0
    def past_due(self):
        """Returns True if the assignment is past due"""
        due = get_extended_due_date(self)

        if due is not None:
            return _now() > due
        else:
            return False
Esempio n. 4
0
	def past_due(self):
		"""Returns True if the assignment is past due"""
		due = get_extended_due_date(self)

		if due is not None:
			return _now() > due
		else:
			return False
Esempio n. 5
0
 def past_due(self):
     """
         Проверка, истекла ли дата для выполнения задания.
         """
     due = get_extended_due_date(self)
     if due is not None:
         if _now() > due:
             return False
 def _allow_checking(self, dt):
     # HTML Academy возращает время по МСК без указания таймзоны, поэтому приведём руками
     tz = pytz.timezone('Europe/Moscow')
     dt = tz.localize(dt.replace(tzinfo=None))
     due = get_extended_due_date(self)
     if due is not None:
         return dt < due
     return True
 def _past_due(self):
     """
     Return whether due date has passed.
     """
     due = get_extended_due_date(self)
     if due is not None:
         return self._now() > due
     return False
Esempio n. 8
0
 def past_due(self):
     """
     Return whether due date has passed.
     """
     due = get_extended_due_date(self)
     if due is not None:
         return _now() > due
     return False
Esempio n. 9
0
 def passed_due(self):
     """
     Return true if the due date has passed.
     """
     now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
     due = get_extended_due_date(self)
     if due is not None:
         return now > due
     return False
Esempio n. 10
0
 def past_due(self):
         """
         Проверка, истекла ли дата для выполнения задания.
         """
         due = get_extended_due_date(self)
         if due is not None:
             if _now() > due:
                 return False
         return True
Esempio n. 11
0
        def get_student_data(module):
            """
			Packages data from a student module for display to staff.
			"""
            state = json.loads(module.state)
            instructor = self.is_instructor()
            score = state.get('score')
            approved = state.get('score_approved')
            submitted = state.get('is_submitted')
            submission_time = state.get('submission_time')

            #can a grade be entered
            due = get_extended_due_date(self)
            may_grade = (instructor or not approved)
            if due is not None:
                may_grade = may_grade and (submitted or (due < _now()))

            uploaded = []
            if (state.get('is_submitted')):
                for sha1, metadata in get_file_metadata(
                        state.get("uploaded_files")).iteritems():
                    uploaded.append({
                        "sha1": sha1,
                        "filename": metadata.filename,
                        "timestamp": metadata.timestamp
                    })

            annotated = []
            for sha1, metadata in get_file_metadata(
                    state.get("annotated_files")).iteritems():
                annotated.append({
                    "sha1": sha1,
                    "filename": metadata.filename,
                    "timestamp": metadata.timestamp
                })

            return {
                'module_id': module.id,
                'username': module.student.username,
                'fullname': module.student.profile.name,
                'uploaded': uploaded,
                'annotated': annotated,
                'timestamp': state.get("uploaded_files_last_timestamp"),
                'published': state.get("score_published"),
                'score': score,
                'approved': approved,
                'needs_approval': instructor and score is not None
                and not approved,
                'may_grade': may_grade,
                'comment': state.get("comment", ''),
                'submitted': submitted,
                'submission_time': submission_time
            }
Esempio n. 12
0
def toc_for_course(user, request, course, active_chapter, active_section, field_data_cache):
    '''
    Create a table of contents from the module store

    Return format:
    [ {'display_name': name, 'url_name': url_name,
       'sections': SECTIONS, 'active': bool}, ... ]

    where SECTIONS is a list
    [ {'display_name': name, 'url_name': url_name,
       'format': format, 'due': due, 'active' : bool, 'graded': bool}, ...]

    active is set for the section and chapter corresponding to the passed
    parameters, which are expected to be url_names of the chapter+section.
    Everything else comes from the xml, or defaults to "".

    chapters with name 'hidden' are skipped.

    NOTE: assumes that if we got this far, user has access to course.  Returns
    None if this is not the case.

    field_data_cache must include data from the course module and 2 levels of its descendents
    '''

    course_module = get_module_for_descriptor(user, request, course, field_data_cache, course.id)
    if course_module is None:
        return None

    chapters = list()
    for chapter in course_module.get_display_items():
        if chapter.hide_from_toc:
            continue

        sections = list()
        for section in chapter.get_display_items():

            active = (chapter.url_name == active_chapter and
                      section.url_name == active_section)

            if not section.hide_from_toc:
                sections.append({'display_name': section.display_name_with_default,
                                 'url_name': section.url_name,
                                 'format': section.format if section.format is not None else '',
                                 'due': get_extended_due_date(section),
                                 'active': active,
                                 'graded': section.graded,
                                 })

        chapters.append({'display_name': chapter.display_name_with_default,
                         'url_name': chapter.url_name,
                         'sections': sections,
                         'active': chapter.url_name == active_chapter})
    return chapters
Esempio n. 13
0
def mobi_toc_for_course(user, request, course, active_chapter=None, active_section=None, field_data_cache=None):

    course_module = get_module_for_descriptor(user, request, course, field_data_cache, course.id)
    if course_module is None:
        return None
    show_url = list()
    chapters = list()
    for chapter in course_module.get_display_items():
        chapter_descriptor = course.get_child_by(lambda m: m.url_name == chapter.url_name)
        chapter_module = course_module.get_child_by(lambda m: m.url_name == chapter.url_name)
        sections = list()
        for section in chapter_module.get_display_items():
            i = 0
            section_descriptor = chapter_descriptor.get_child_by(lambda m: m.url_name == section.url_name)

            section_descriptor = modulestore().get_instance(course.id, section_descriptor.location, depth=None)

            section_field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
                course.id, user, section_descriptor, depth=None)

            section_module = get_module_for_descriptor(request.user,
                request,
                section_descriptor,
                section_field_data_cache,
                course.id,
                i
            )

            units = list()
            for unit in section_module.get_display_items():
                for child in unit.get_display_items():
                    if child.get_icon_class()=='video':
                        if child.source:
                            show_url.append(child.source)
                        elif child.html5_sources:
                            show_url.append(child.html5_sources[0])
                units.append({'display_name': unit.display_name_with_default,
                              'location': i,
                              'type': unit.get_icon_class()})
            sections.append({'display_name': section.display_name_with_default,
                             'url_name': section.url_name,
                             'format': section.format if section.format is not None else '',
                             'due': get_extended_due_date(section),
                             'active': False,
                             'graded': section.graded,
                             'units': units
                            })
        chapters.append({'display_name': chapter.display_name_with_default,
                         'url_name': chapter.url_name,
                         'sections': sections,
                         'show_url': show_url})
    return chapters
Esempio n. 14
0
		def get_student_data(module):
			"""
			Packages data from a student module for display to staff.
			"""
			state = json.loads(module.state)
			instructor = self.is_instructor()
			score = state.get('score')
			approved = state.get('score_approved')
			submitted = state.get('is_submitted')
			submission_time = state.get('submission_time')

			#can a grade be entered
			due = get_extended_due_date(self)
			may_grade = (instructor or not approved) 
			if due is not None:
				may_grade = may_grade and (submitted or (due < _now())) 

			uploaded = []
			if (state.get('is_submitted')):
				for sha1, metadata in get_file_metadata(state.get("uploaded_files")).iteritems():
					uploaded.append({
						"sha1":      sha1, 
						"filename":  metadata.filename,
						"timestamp": metadata.timestamp
					})

			annotated = []
			for sha1, metadata in get_file_metadata(state.get("annotated_files")).iteritems():
				annotated.append({
					"sha1":      sha1, 
					"filename":  metadata.filename,
					"timestamp": metadata.timestamp
				})

			return {
				'module_id':       module.id,
				'username':        module.student.username,
				'fullname':        module.student.profile.name,
				'uploaded':        uploaded,
				'annotated':       annotated,
				'timestamp':       state.get("uploaded_files_last_timestamp"),
				'published':       state.get("score_published"),
				'score':           score,
				'approved':        approved,
				'needs_approval':  instructor and score is not None
								   and not approved,
				'may_grade':       may_grade,
				'comment':         state.get("comment", ''),

				'submitted':       submitted,
				'submission_time': submission_time
			}
Esempio n. 15
0
    def get_student_context(self, user=None):

        parent = super(ScilabXBlock, self)
        if hasattr(parent, 'get_student_context'):
            context = parent.get_student_context(user)
        else:
            context = {}

        # TODO: Parents should declare what they provide for student context

        # Получение пользовательского контектса и отрендеренного фрагмента не
        # очень очевидно, так как собирается в обратном порядке. По хорошему,
        # нужно переписать это под ноль.
        # С связи с этим нельзя перезаписать текст задания (он устанавливается
        # контекстом выше). Именно для этого мы заводим отдельный параметр в
        # в контексте здесь.
        context['need_generate'] = False
        pregenerated = None
        if self.need_generate:
            context['need_generate'] = True
            try:
                if self.pregenerated:
                    pregenerated = self.pregenerated.split("\n")
            except TypeError:
                pass

        context.update({
            'allow_submissions':
            True if (self.due is None) or
            (now() < get_extended_due_date(self)) else False,
            'task_status':
            self.queue_details.get('state', 'IDLE'),
            'pregenerated':
            pregenerated,
            'need_show_interface':
            self._is_studio() or not self.need_generate or self.pregenerated,
        })
        if self.message is not None:
            context.update(
                {'message': {
                    'text': self.message,
                    'type': 'info',
                }})

        if self._is_staff():
            context.update({
                'instructor_archive': self.instructor_archive_meta,
            })

        return context
    def __init__(self, *args, **kwargs):
        super(PeerGradingModule, self).__init__(*args, **kwargs)

        # Copy this to a new variable so that we can edit it if needed.
        # We need to edit it if the linked module cannot be found, so
        # we can revert to panel model.
        self.use_for_single_location_local = self.use_for_single_location

        # We need to set the location here so the child modules can use it.
        self.runtime.set('location', self.location)
        if (self.runtime.open_ended_grading_interface):
            self.peer_gs = PeerGradingService(
                self.system.open_ended_grading_interface,
                self.system.render_template)
        else:
            self.peer_gs = MockPeerGradingService()

        if self.use_for_single_location_local:
            linked_descriptors = self.descriptor.get_required_module_descriptors(
            )
            if len(linked_descriptors) == 0:
                error_msg = "Peer grading module {0} is trying to use single problem mode without "
                "a location specified.".format(self.location)
                log.error(error_msg)
                # Change module over to panel mode from single problem mode.
                self.use_for_single_location_local = False
            else:
                self.linked_problem = self.system.get_module(
                    linked_descriptors[0])

        try:
            self.timeinfo = TimeInfo(get_extended_due_date(self),
                                     self.graceperiod)
        except Exception:
            log.error(
                "Error parsing due date information in location {0}".format(
                    self.location))
            raise

        self.display_due_date = self.timeinfo.display_due_date

        try:
            self.student_data_for_location = json.loads(
                self.student_data_for_location)
        except Exception:  # pylint: disable=broad-except
            # OK with this broad exception because we just want to continue on any error
            pass
Esempio n. 17
0
    def past_due(self):
        """
        Return whether due date has passed.
        """
        due = get_extended_due_date(self)
        try:
            graceperiod = self.graceperiod
        except AttributeError:
            # graceperiod and due are defined in InheritanceMixin
            # It's used automatically in edX but the unit tests will need to mock it out
            graceperiod = None

        if graceperiod is not None and due:
            close_date = due + graceperiod
        else:
            close_date = due

        if close_date is not None:
            return utcnow() > close_date
        return False
Esempio n. 18
0
    def past_due(self):
        """
        Return whether due date has passed.
        """
        due = get_extended_due_date(self)
        try:
            graceperiod = self.graceperiod
        except AttributeError:
            # graceperiod and due are defined in InheritanceMixin
            # It's used automatically in edX but the unit tests will need to mock it out
            graceperiod = None

        if graceperiod is not None and due:
            close_date = due + graceperiod
        else:
            close_date = due

        if close_date is not None:
            return utcnow() > close_date
        return False
Esempio n. 19
0
    def expired_date(self):
        """
        Return whether due date has passed.
        """
        from xmodule.util.duedate import get_extended_due_date

        due = get_extended_due_date(self)
        try:
            graceperiod = self.graceperiod
        except AttributeError:
            # graceperiod and due are defined in InheritanceMixin
            # It's used automatically in edX but the unit tests will need to
            # mock it out
            graceperiod = None

        if graceperiod is not None and due:
            close_date = due + graceperiod
        else:
            close_date = due

        return close_date
Esempio n. 20
0
    def get_student_context(self, user=None):

        parent = super(ImageMagickXBlock, self)
        if hasattr(parent, 'get_student_context'):
            context = parent.get_student_context(user)
        else:
            context = {}

        context.update({
            'allow_submissions':
            True if (self.due is None) or
            (now() < get_extended_due_date(self)) else False,
            'task_status':
            self.queue_details.get('state', 'IDLE'),
            'need_show_interface':
            True or self._is_studio(),
            'latest_check':
            self.latest_check,
        })

        return context
    def __init__(self, *args, **kwargs):
        super(PeerGradingModule, self).__init__(*args, **kwargs)

        # Copy this to a new variable so that we can edit it if needed.
        # We need to edit it if the linked module cannot be found, so
        # we can revert to panel model.
        self.use_for_single_location_local = self.use_for_single_location

        # We need to set the location here so the child modules can use it.
        self.runtime.set('location', self.location)
        if (self.runtime.open_ended_grading_interface):
            self.peer_gs = PeerGradingService(self.system.open_ended_grading_interface, self.system.render_template)
        else:
            self.peer_gs = MockPeerGradingService()

        if self.use_for_single_location_local:
            linked_descriptors = self.descriptor.get_required_module_descriptors()
            if len(linked_descriptors) == 0:
                error_msg = "Peer grading module {0} is trying to use single problem mode without "
                "a location specified.".format(self.location)
                log.error(error_msg)
                # Change module over to panel mode from single problem mode.
                self.use_for_single_location_local = False
            else:
                self.linked_problem = self.system.get_module(linked_descriptors[0])

        try:
            self.timeinfo = TimeInfo(
                get_extended_due_date(self), self.graceperiod)
        except Exception:
            log.error("Error parsing due date information in location {0}".format(self.location))
            raise

        self.display_due_date = self.timeinfo.display_due_date

        try:
            self.student_data_for_location = json.loads(self.student_data_for_location)
        except Exception:  # pylint: disable=broad-except
            # OK with this broad exception because we just want to continue on any error
            pass
Esempio n. 22
0
    def get_student_context_base(self, user=None):
        due = get_extended_due_date(self)
        return {
            'meta': {
                'location': str(self.scope_ids.usage_id),
                'id': self.scope_ids.usage_id.block_id,
                'name': self.display_name,
                'text': self.description or "",
                'due': due.strftime('%d.%m.%Y %H:%M:%S') if due else None,
                'attempts': self.attempts,
            },
            'student_state': {
                'score': {
                    'earned': self.points * self.weight,
                    'max': self.weight,
                    'string': self._get_score_string(),
                },
                'is_staff': self._is_staff(),

                # This is probably studio, find out some more ways to determine this
                'is_studio': self._is_studio(),
            },
        }
    def peer_grading(self, _data=None):
        '''
        Show a peer grading interface
        '''

        # call problem list service
        success = False
        error_text = ""
        problem_list = []
        try:
            problem_list_json = self.peer_gs.get_problem_list(self.course_id, self.system.anonymous_student_id)
            problem_list_dict = problem_list_json
            success = problem_list_dict['success']
            if 'error' in problem_list_dict:
                error_text = problem_list_dict['error']

            problem_list = problem_list_dict['problem_list']

        except GradingServiceError:
            # This is a student_facing_error
            error_text = EXTERNAL_GRADER_NO_CONTACT_ERROR
            log.error(error_text)
            success = False
        # catch error if if the json loads fails
        except ValueError:
            # This is a student_facing_error
            error_text = "Could not get list of problems to peer grade.  Please notify course staff."
            log.error(error_text)
            success = False
        except Exception:
            log.exception("Could not contact peer grading service.")
            success = False

        good_problem_list = []
        for problem in problem_list:
            problem_location = Location(problem['location'])
            try:
                descriptor = self._find_corresponding_module_for_location(problem_location)
            except (NoPathToItem, ItemNotFoundError):
                continue
            if descriptor:
                problem['due'] = get_extended_due_date(descriptor)
                grace_period = descriptor.graceperiod
                try:
                    problem_timeinfo = TimeInfo(problem['due'], grace_period)
                except Exception:
                    log.error("Malformed due date or grace period string for location {0}".format(problem_location))
                    raise
                if self._closed(problem_timeinfo):
                    problem['closed'] = True
                else:
                    problem['closed'] = False
            else:
                # if we can't find the due date, assume that it doesn't have one
                problem['due'] = None
                problem['closed'] = False
            good_problem_list.append(problem)

        ajax_url = self.ajax_url
        html = self.system.render_template('peer_grading/peer_grading.html', {
            'course_id': self.course_id,
            'ajax_url': ajax_url,
            'success': success,
            'problem_list': good_problem_list,
            'error_text': error_text,
            # Checked above
            'staff_access': False,
            'use_single_location': self.use_for_single_location_local,
        })

        return html
Esempio n. 24
0
    def peer_grading(self, _data=None):
        '''
        Show a peer grading interface
        '''

        # call problem list service
        success = False
        error_text = ""
        problem_list = []
        try:
            problem_list_dict = self.peer_gs.get_problem_list(
                self.course_id, self.system.anonymous_student_id)
            success = problem_list_dict['success']
            if 'error' in problem_list_dict:
                error_text = problem_list_dict['error']

            problem_list = problem_list_dict['problem_list']

        except GradingServiceError:
            # This is a student_facing_error
            error_text = EXTERNAL_GRADER_NO_CONTACT_ERROR
            log.error(error_text)
            success = False
        # catch error if if the json loads fails
        except ValueError:
            # This is a student_facing_error
            error_text = "Could not get list of problems to peer grade.  Please notify course staff."
            log.error(error_text)
            success = False
        except Exception:
            log.exception("Could not contact peer grading service.")
            success = False

        good_problem_list = []
        for problem in problem_list:
            problem_location = Location(problem['location'])
            try:
                descriptor = self._find_corresponding_module_for_location(
                    problem_location)
            except (NoPathToItem, ItemNotFoundError):
                continue
            if descriptor:
                problem['due'] = get_extended_due_date(descriptor)
                grace_period = descriptor.graceperiod
                try:
                    problem_timeinfo = TimeInfo(problem['due'], grace_period)
                except Exception:
                    log.error(
                        "Malformed due date or grace period string for location {0}"
                        .format(problem_location))
                    raise
                if self._closed(problem_timeinfo):
                    problem['closed'] = True
                else:
                    problem['closed'] = False
            else:
                # if we can't find the due date, assume that it doesn't have one
                problem['due'] = None
                problem['closed'] = False
            good_problem_list.append(problem)

        ajax_url = self.ajax_url
        html = self.system.render_template(
            'peer_grading/peer_grading.html',
            {
                'course_id': self.course_id,
                'ajax_url': ajax_url,
                'success': success,
                'problem_list': good_problem_list,
                'error_text': error_text,
                # Checked above
                'staff_access': False,
                'use_single_location': self.use_for_single_location_local,
            })

        return html
Esempio n. 25
0
def _progress_summary(student, request, course):
    """
    Unwrapped version of "progress_summary".

    This pulls a summary of all problems in the course.

    Returns
    - courseware_summary is a summary of all sections with problems in the course.
    It is organized as an array of chapters, each containing an array of sections,
    each containing an array of scores. This contains information for graded and
    ungraded problems, and is good for displaying a course summary with due dates,
    etc.

    Arguments:
        student: A User object for the student to grade
        course: A Descriptor containing the course to grade

    If the student does not have access to load the course module, this function
    will return None.

    """
    with manual_transaction():
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, student, course, depth=None
        )
        # TODO: We need the request to pass into here. If we could
        # forego that, our arguments would be simpler
        course_module = get_module_for_descriptor(student, request, course, field_data_cache, course.id)
        if not course_module:
            # This student must not have access to the course.
            return None

    chapters = []
    # Don't include chapters that aren't displayable (e.g. due to error)
    for chapter_module in course_module.get_display_items():
        # Skip if the chapter is hidden
        if chapter_module.hide_from_toc:
            continue

        sections = []

        for section_module in chapter_module.get_display_items():
            # Skip if the section is hidden
            with manual_transaction():
                if section_module.hide_from_toc:
                    continue

                graded = section_module.graded
                scores = []

                module_creator = section_module.xmodule_runtime.get_module

                for module_descriptor in yield_dynamic_descriptor_descendents(section_module, module_creator):
                    course_id = course.id
                    (correct, total) = get_score(course_id, student, module_descriptor, module_creator)
                    if correct is None and total is None:
                        continue

                    scores.append(Score(correct, total, graded, module_descriptor.display_name_with_default))

                scores.reverse()
                section_total, _ = graders.aggregate_scores(
                    scores, section_module.display_name_with_default)

                module_format = section_module.format if section_module.format is not None else ''
                sections.append({
                    'display_name': section_module.display_name_with_default,
                    'url_name': section_module.url_name,
                    'scores': scores,
                    'section_total': section_total,
                    'format': module_format,
                    'due': get_extended_due_date(section_module),
                    'graded': graded,
                })

        chapters.append({
            'course': course.display_name_with_default,
            'display_name': chapter_module.display_name_with_default,
            'url_name': chapter_module.url_name,
            'sections': sections
        })

    return chapters
Esempio n. 26
0
def toc_for_course(request, course, active_chapter, active_section, field_data_cache):
    '''
    Create a table of contents from the module store

    Return format:
    [ {'display_name': name, 'url_name': url_name,
       'sections': SECTIONS, 'active': bool}, ... ]

    where SECTIONS is a list
    [ {'display_name': name, 'url_name': url_name,
       'format': format, 'due': due, 'active' : bool, 'graded': bool}, ...]

    active is set for the section and chapter corresponding to the passed
    parameters, which are expected to be url_names of the chapter+section.
    Everything else comes from the xml, or defaults to "".

    chapters with name 'hidden' are skipped.

    NOTE: assumes that if we got this far, user has access to course.  Returns
    None if this is not the case.

    field_data_cache must include data from the course module and 2 levels of its descendents
    '''

    with modulestore().bulk_operations(course.id):
        course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id)
        if course_module is None:
            return None

        toc_chapters = list()
        chapters = course_module.get_display_items()

        # See if the course is gated by one or more content milestones
        required_content = milestones_helpers.get_required_content(course, request.user)

        # The user may not actually have to complete the entrance exam, if one is required
        if not user_must_complete_entrance_exam(request, request.user, course):
            required_content = [content for content in required_content if not content == course.entrance_exam_id]

        for chapter in chapters:
            # Only show required content, if there is required content
            # chapter.hide_from_toc is read-only (boo)
            local_hide_from_toc = False
            if required_content:
                if unicode(chapter.location) not in required_content:
                    local_hide_from_toc = True

            # Skip the current chapter if a hide flag is tripped
            if chapter.hide_from_toc or local_hide_from_toc:
                continue

            sections = list()
            for section in chapter.get_display_items():

                active = (chapter.url_name == active_chapter and
                          section.url_name == active_section)

                if not section.hide_from_toc:
                    sections.append({'display_name': section.display_name_with_default,
                                     'url_name': section.url_name,
                                     'format': section.format if section.format is not None else '',
                                     'due': get_extended_due_date(section),
                                     'active': active,
                                     'graded': section.graded,
                                     })
            toc_chapters.append({
                'display_name': chapter.display_name_with_default,
                'url_name': chapter.url_name,
                'sections': sections,
                'active': chapter.url_name == active_chapter
            })
        return toc_chapters
Esempio n. 27
0
 def past_due(self):
     due = get_extended_due_date(self)
     if due is not None:
         return now() > due
     return False
Esempio n. 28
0
def _progress_summary(student, request, course):
    """
    Unwrapped version of "progress_summary".

    This pulls a summary of all problems in the course.

    Returns
    - courseware_summary is a summary of all sections with problems in the course.
    It is organized as an array of chapters, each containing an array of sections,
    each containing an array of scores. This contains information for graded and
    ungraded problems, and is good for displaying a course summary with due dates,
    etc.

    Arguments:
        student: A User object for the student to grade
        course: A Descriptor containing the course to grade

    If the student does not have access to load the course module, this function
    will return None.

    """
    with manual_transaction():
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, student, course, depth=None)
        # TODO: We need the request to pass into here. If we could
        # forego that, our arguments would be simpler
        course_module = get_module_for_descriptor(student, request, course,
                                                  field_data_cache, course.id)
        if not course_module:
            # This student must not have access to the course.
            return None

    chapters = []
    # Don't include chapters that aren't displayable (e.g. due to error)
    for chapter_module in course_module.get_display_items():
        # Skip if the chapter is hidden
        if chapter_module.hide_from_toc:
            continue

        sections = []

        for section_module in chapter_module.get_display_items():
            # Skip if the section is hidden
            with manual_transaction():
                if section_module.hide_from_toc:
                    continue

                graded = section_module.graded
                scores = []

                module_creator = section_module.xmodule_runtime.get_module

                for module_descriptor in yield_dynamic_descriptor_descendents(
                        section_module, module_creator):
                    course_id = course.id
                    (correct, total) = get_score(course_id, student,
                                                 module_descriptor,
                                                 module_creator)
                    if correct is None and total is None:
                        continue

                    scores.append(
                        Score(correct, total, graded,
                              module_descriptor.display_name_with_default))

                scores.reverse()
                section_total, _ = graders.aggregate_scores(
                    scores, section_module.display_name_with_default)

                module_format = section_module.format if section_module.format is not None else ''
                sections.append({
                    'display_name': section_module.display_name_with_default,
                    'url_name': section_module.url_name,
                    'scores': scores,
                    'section_total': section_total,
                    'format': module_format,
                    'due': get_extended_due_date(section_module),
                    'graded': graded,
                })

        chapters.append({
            'course': course.display_name_with_default,
            'display_name': chapter_module.display_name_with_default,
            'url_name': chapter_module.url_name,
            'sections': sections
        })

    return chapters
Esempio n. 29
0
    def __init__(self, system, location, definition, descriptor,
                 instance_state=None, shared_state=None, metadata=None, static_data=None, **kwargs):

        """
        Definition file should have one or many task blocks, a rubric block, and a prompt block.  See DEFAULT_DATA in combined_open_ended_module for a sample.

        """
        self.instance_state = instance_state
        self.display_name = instance_state.get('display_name', "Open Ended")

        # We need to set the location here so the child modules can use it
        system.set('location', location)
        self.system = system

        # Tells the system which xml definition to load
        self.current_task_number = instance_state.get('current_task_number', 0)
        # This loads the states of the individual children
        self.task_states = instance_state.get('task_states', [])
        #This gets any old task states that have been persisted after the instructor changed the tasks.
        self.old_task_states = instance_state.get('old_task_states', [])
        # Overall state of the combined open ended module
        self.state = instance_state.get('state', self.INITIAL)

        self.student_attempts = instance_state.get('student_attempts', 0)
        self.weight = instance_state.get('weight', 1)

        # Allow reset is true if student has failed the criteria to move to the next child task
        self.ready_to_reset = instance_state.get('ready_to_reset', False)
        self.max_attempts = instance_state.get('max_attempts', MAX_ATTEMPTS)
        self.is_scored = instance_state.get('graded', IS_SCORED) in TRUE_DICT
        self.accept_file_upload = instance_state.get('accept_file_upload', ACCEPT_FILE_UPLOAD) in TRUE_DICT
        self.skip_basic_checks = instance_state.get('skip_spelling_checks', SKIP_BASIC_CHECKS) in TRUE_DICT

        if system.open_ended_grading_interface:
            self.peer_gs = PeerGradingService(system.open_ended_grading_interface, system)
        else:
            self.peer_gs = MockPeerGradingService()

        self.required_peer_grading = instance_state.get('required_peer_grading', 3)
        self.peer_grader_count = instance_state.get('peer_grader_count', 3)
        self.min_to_calibrate = instance_state.get('min_to_calibrate', 3)
        self.max_to_calibrate = instance_state.get('max_to_calibrate', 6)
        self.peer_grade_finished_submissions_when_none_pending = instance_state.get(
            'peer_grade_finished_submissions_when_none_pending', False
        )

        due_date = get_extended_due_date(instance_state)
        grace_period_string = instance_state.get('graceperiod', None)
        try:
            self.timeinfo = TimeInfo(due_date, grace_period_string)
        except Exception:
            log.error("Error parsing due date information in location {0}".format(location))
            raise
        self.display_due_date = self.timeinfo.display_due_date

        self.rubric_renderer = CombinedOpenEndedRubric(system, True)
        rubric_string = stringify_children(definition['rubric'])
        self._max_score = self.rubric_renderer.check_if_rubric_is_parseable(rubric_string, location, MAX_SCORE_ALLOWED)

        # Static data is passed to the child modules to render
        self.static_data = {
            'max_score': self._max_score,
            'max_attempts': self.max_attempts,
            'prompt': definition['prompt'],
            'rubric': definition['rubric'],
            'display_name': self.display_name,
            'accept_file_upload': self.accept_file_upload,
            'close_date': self.timeinfo.close_date,
            's3_interface': self.system.s3_interface,
            'skip_basic_checks': self.skip_basic_checks,
            'control': {
                'required_peer_grading': self.required_peer_grading,
                'peer_grader_count': self.peer_grader_count,
                'min_to_calibrate': self.min_to_calibrate,
                'max_to_calibrate': self.max_to_calibrate,
                'peer_grade_finished_submissions_when_none_pending': (
                    self.peer_grade_finished_submissions_when_none_pending
                ),
            }
        }

        self.task_xml = definition['task_xml']
        self.location = location
        self.fix_invalid_state()
        self.setup_next_task()
Esempio n. 30
0
def toc_for_course(request, course, active_chapter, active_section, field_data_cache):
    """
    Create a table of contents from the module store

    Return format:
    [ {'display_name': name, 'url_name': url_name,
       'sections': SECTIONS, 'active': bool}, ... ]

    where SECTIONS is a list
    [ {'display_name': name, 'url_name': url_name,
       'format': format, 'due': due, 'active' : bool, 'graded': bool}, ...]

    active is set for the section and chapter corresponding to the passed
    parameters, which are expected to be url_names of the chapter+section.
    Everything else comes from the xml, or defaults to "".

    chapters with name 'hidden' are skipped.

    NOTE: assumes that if we got this far, user has access to course.  Returns
    None if this is not the case.

    field_data_cache must include data from the course module and 2 levels of its descendents
    """

    with modulestore().bulk_operations(course.id):
        course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id)
        if course_module is None:
            return None

        # Check to see if the course is gated on required content (such as an Entrance Exam)
        required_content = _get_required_content(course, request.user)

        chapters = list()
        for chapter in course_module.get_display_items():
            # Only show required content, if there is required content
            # chapter.hide_from_toc is read-only (boo)
            local_hide_from_toc = False
            if len(required_content):
                if unicode(chapter.location) not in required_content:
                    local_hide_from_toc = True

            # Skip the current chapter if a hide flag is tripped
            if chapter.hide_from_toc or local_hide_from_toc:
                continue

            sections = list()
            for section in chapter.get_display_items():

                active = chapter.url_name == active_chapter and section.url_name == active_section

                if not section.hide_from_toc:
                    sections.append(
                        {
                            "display_name": section.display_name_with_default,
                            "url_name": section.url_name,
                            "format": section.format if section.format is not None else "",
                            "due": get_extended_due_date(section),
                            "active": active,
                            "graded": section.graded,
                        }
                    )
            chapters.append(
                {
                    "display_name": chapter.display_name_with_default,
                    "url_name": chapter.url_name,
                    "sections": sections,
                    "active": chapter.url_name == active_chapter,
                }
            )
        return chapters
 def _allow_checking_now(self):
     due = get_extended_due_date(self)
     if due is not None:
         return self._now() < due
     return True
Esempio n. 32
0
def _progress_summary(student, request, course):
    """
    Unwrapped version of "progress_summary".

    This pulls a summary of all problems in the course.

    Returns
    - courseware_summary is a summary of all sections with problems in the course.
    It is organized as an array of chapters, each containing an array of sections,
    each containing an array of scores. This contains information for graded and
    ungraded problems, and is good for displaying a course summary with due dates,
    etc.

    Arguments:
        student: A User object for the student to grade
        course: A Descriptor containing the course to grade

    If the student does not have access to load the course module, this function
    will return None.

    """
    with manual_transaction():
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, student, course, depth=None
        )
        # TODO: We need the request to pass into here. If we could
        # forego that, our arguments would be simpler
        course_module = get_module_for_descriptor(student, request, course, field_data_cache, course.id)
        if not course_module:
            # This student must not have access to the course.
            return None

    submissions_scores = sub_api.get_scores(course.id.to_deprecated_string(), anonymous_id_for_user(student, course.id))

    chapters = []
    # Don't include chapters that aren't displayable (e.g. due to error)
    for chapter_module in course_module.get_display_items():
        # Skip if the chapter is hidden
        if chapter_module.hide_from_toc:
            continue

        sections = []

        for section_module in chapter_module.get_display_items():
            # Skip if the section is hidden
            with manual_transaction():
                if section_module.hide_from_toc:
                    continue

                graded = section_module.graded
                scores = []

                module_creator = section_module.xmodule_runtime.get_module
                inforExerc = []

                # Adicionarei mais algumas informacoes para que seja possivel pegar o que foi digitado pelo aluno
                # A quantidade de tentativas, que opcao o usuario escolheu ou que informacao foi digitada


                for module_descriptor in yield_dynamic_descriptor_descendents(section_module, module_creator):
                    course_id = course.id
                    (correct, total) = get_score(
                        course_id, student, module_descriptor, module_creator, scores_cache=submissions_scores
                    )
                    tentativas, valorDigitado, idProblem = get_InforExerc(
                        course_id, student, module_descriptor
                    )



                    if correct is None and total is None:

                        continue
                    print "USUARIO: ", student
                    print "TENTATIVAS ", tentativas, " VALOR DIGITADO: ", valorDigitado
                    print "CORRECT: ", correct, " total ", total
                    print "IDPROBLEM: ", idProblem

                    vals=[]
                    vals.append(tentativas)
                    vals.append(valorDigitado)
                    vals.append(idProblem)

                    inforExerc.append(vals)



                    scores.append(Score(correct, total, graded, module_descriptor.display_name_with_default))

                scores.reverse()
                inforExerc.reverse()

                section_total, _ = graders.aggregate_scores(
                    scores, section_module.display_name_with_default)

                module_format = section_module.format if section_module.format is not None else ''
                sections.append({
                    'display_name': section_module.display_name_with_default,
                    'url_name': section_module.url_name,
                    'scores': scores,
                    'inforExerc': inforExerc,
                    'section_total': section_total,
                    'format': module_format,
                    'due': get_extended_due_date(section_module),
                    'graded': graded,
                })

        chapters.append({
            'course': course.display_name_with_default,
            'display_name': chapter_module.display_name_with_default,
            'url_name': chapter_module.url_name,
            'sections': sections
        })

    return chapters
    def __init__(self, system, location, definition, descriptor,
                 instance_state=None, shared_state=None, metadata=None, static_data=None, **kwargs):

        """
        Definition file should have one or many task blocks, a rubric block, and a prompt block.  See DEFAULT_DATA in combined_open_ended_module for a sample.

        """
        self.instance_state = instance_state
        self.display_name = instance_state.get('display_name', "Open Ended")

        # We need to set the location here so the child modules can use it
        system.set('location', location)
        self.system = system

        # Tells the system which xml definition to load
        self.current_task_number = instance_state.get('current_task_number', 0)
        # This loads the states of the individual children
        self.task_states = instance_state.get('task_states', [])
        #This gets any old task states that have been persisted after the instructor changed the tasks.
        self.old_task_states = instance_state.get('old_task_states', [])
        # Overall state of the combined open ended module
        self.state = instance_state.get('state', self.INITIAL)

        self.student_attempts = instance_state.get('student_attempts', 0)
        self.weight = instance_state.get('weight', 1)

        # Allow reset is true if student has failed the criteria to move to the next child task
        self.ready_to_reset = instance_state.get('ready_to_reset', False)
        self.max_attempts = instance_state.get('max_attempts', MAX_ATTEMPTS)
        self.is_scored = instance_state.get('graded', IS_SCORED) in TRUE_DICT
        self.accept_file_upload = instance_state.get('accept_file_upload', ACCEPT_FILE_UPLOAD) in TRUE_DICT
        self.skip_basic_checks = instance_state.get('skip_spelling_checks', SKIP_BASIC_CHECKS) in TRUE_DICT

        if system.open_ended_grading_interface:
            self.peer_gs = PeerGradingService(system.open_ended_grading_interface, system)
        else:
            self.peer_gs = MockPeerGradingService()

        self.required_peer_grading = instance_state.get('required_peer_grading', 3)
        self.peer_grader_count = instance_state.get('peer_grader_count', 3)
        self.min_to_calibrate = instance_state.get('min_to_calibrate', 3)
        self.max_to_calibrate = instance_state.get('max_to_calibrate', 6)
        self.peer_grade_finished_submissions_when_none_pending = instance_state.get(
            'peer_grade_finished_submissions_when_none_pending', False
        )

        due_date = get_extended_due_date(instance_state)
        grace_period_string = instance_state.get('graceperiod', None)
        try:
            self.timeinfo = TimeInfo(due_date, grace_period_string)
        except Exception:
            log.error("Error parsing due date information in location {0}".format(location))
            raise
        self.display_due_date = self.timeinfo.display_due_date

        self.rubric_renderer = CombinedOpenEndedRubric(system, True)
        rubric_string = stringify_children(definition['rubric'])
        self._max_score = self.rubric_renderer.check_if_rubric_is_parseable(rubric_string, location, MAX_SCORE_ALLOWED)

        # Static data is passed to the child modules to render
        self.static_data = {
            'max_score': self._max_score,
            'max_attempts': self.max_attempts,
            'prompt': definition['prompt'],
            'rubric': definition['rubric'],
            'display_name': self.display_name,
            'accept_file_upload': self.accept_file_upload,
            'close_date': self.timeinfo.close_date,
            's3_interface': self.system.s3_interface,
            'skip_basic_checks': self.skip_basic_checks,
            'control': {
                'required_peer_grading': self.required_peer_grading,
                'peer_grader_count': self.peer_grader_count,
                'min_to_calibrate': self.min_to_calibrate,
                'max_to_calibrate': self.max_to_calibrate,
                'peer_grade_finished_submissions_when_none_pending': (
                    self.peer_grade_finished_submissions_when_none_pending
                ),
            }
        }

        self.task_xml = definition['task_xml']
        self.location = location
        self.fix_invalid_state()
        self.setup_next_task()
Esempio n. 34
0
 def past_due(self):
     due = get_extended_due_date(self)
     if due is not None:
         return _now() > due
     return False