def _user(self, user_id):
        log.info("_user: starting for userid " + pformat(user_id))
        course_key = SlashSeparatedCourseKey.from_deprecated_string(
            self.course_id)
        course_block = StudentModule.objects.all().filter(
            student_id=user_id, course_id=course_key, max_grade__isnull=False)
        course_grade = []

        for n in course_block:
            try:
                q = {}
                usage_key = n.module_state_key
                block_name = get_blocks(self.request,
                                        usage_key,
                                        depth='all',
                                        requested_fields=['display_name'])
                root = block_name['root']
                display_name = block_name['blocks'][root]['display_name']
                q['earned'] = n.grade
                q['possible'] = n.max_grade
                q['display_name'] = display_name
                q['root'] = root
                course_grade.append(q)
            except:
                pass

        return course_grade
Example #2
0
def _assert_block_is_gated(block, is_gated, user, course, request_factory, has_upgrade_link=True):
    """
    Asserts that a block in a specific course is gated for a specific user
    Arguments:
        block: some sort of xblock descriptor, must implement .scope_ids.usage_id
        is_gated (bool): if True, this user is expected to be gated from this block
        user (int): user
        course_id (CourseLocator): id of course
    """
    checkout_link = '#' if has_upgrade_link else None
    for content_getter in (_get_content_from_fragment, _get_content_from_lms_index):
        with patch.object(ContentTypeGatingPartition, '_get_checkout_link', return_value=checkout_link):
            content = content_getter(block, user.id, course, request_factory)
        if is_gated:
            assert 'content-paywall' in content
            if has_upgrade_link:
                assert 'certA_1' in content
            else:
                assert 'certA_1' not in content
        else:
            assert 'content-paywall' not in content

    fake_request = request_factory.get('')
    with patch('lms.djangoapps.course_api.blocks.api.is_request_from_mobile_app', return_value=True):
        blocks = get_blocks(fake_request, course.location, user=user)
        course_api_block = blocks['blocks'][str(block.location)]
        if is_gated:
            assert 'authorization_denial_reason' in course_api_block
        else:
            assert 'authorization_denial_reason' not in course_api_block
Example #3
0
    def _course_blocks_grade(self):

        data = json.loads(self.request.body)
        data_id = data.get('data_id')
        course_block = StudentModule.objects.raw(
            "SELECT id,AVG(grade) AS moyenne,count(id) AS total,MAX(max_grade) AS max_grade,course_id,module_id FROM courseware_studentmodule WHERE course_id = %s AND max_grade IS NOT NULL AND grade <= max_grade GROUP BY module_id",
            [self.course_id])
        course_grade = {}
        for n in course_block:
            usage_key = n.module_state_key
            block_view = BlocksView()
            try:
                block_name = get_blocks(self.request,
                                        usage_key,
                                        depth='all',
                                        requested_fields=['display_name'])
                root = block_name['root']
                for z in data_id:
                    if root in z.get('id'):
                        if not root in course_grade:
                            course_grade[root] = {}
                            course_grade[root]['moyenne'] = n.moyenne
                            course_grade[root]['total'] = n.total
                            course_grade[root]['max_grade'] = n.max_grade
                            course_grade[root]['course_id'] = str(n.course_id)
                            course_grade[root]['module_id'] = str(
                                n.module_state_key)
                            course_grade[root]['display_name'] = block_name[
                                'blocks'][root]['display_name']
                            course_grade[root]['vertical_name'] = z.get(
                                'title')

            except:
                pass
        return course_grade
Example #4
0
    def get_course_structure(self):
        blocks_overviews = []
        course_usage_key = modulestore().make_course_usage_key(self.course_key)
        blocks = get_blocks(self.request,
                            course_usage_key,
                            depth='all',
                            requested_fields=['display_name', 'children'])
        root = blocks['root']
        try:
            children = blocks['blocks'][root]['children']
            for z in children:
                q = {}
                child = blocks['blocks'][z]
                q['display_name'] = child['display_name']
                q['id'] = child['id']
                try:
                    sub_section = child['children']
                    q['children'] = []
                    for s in sub_section:
                        sub_ = blocks['blocks'][s]
                        a = {}
                        a['id'] = sub_['id']
                        a['display_name'] = sub_['display_name']
                        vertical = sub_['children']
                        try:
                            a['children'] = []
                            for v in vertical:
                                unit = blocks['blocks'][v]
                                w = {}
                                w['id'] = unit['id']
                                w['display_name'] = unit['display_name']
                                try:
                                    w['children'] = unit['children']
                                except:
                                    w['children'] = []
                                a['children'].append(w)
                        except:
                            a['children'] = []
                        q['children'].append(a)
                except:
                    q['children'] = []
                blocks_overviews.append(q)
        except:
            children = ''

        return blocks_overviews
def set_initial_progress(request, course_key):
    course_usage_key = modulestore().make_course_usage_key(course_key)
    root = course_usage_key.to_deprecated_string()

    block_fields = ['type', 'display_name', 'children']
    course_struct = get_blocks(request,
                               course_usage_key,
                               request.user,
                               'all',
                               requested_fields=block_fields)

    default_progress_dict = get_default_course_progress(
        course_struct.get('blocks', []), root)
    default_progress_json = json.dumps(default_progress_dict)
    student_course_progress = StudentCourseProgress.objects.create(
        student=request.user,
        course_id=course_key,
        progress_json=default_progress_json,
    )

    return student_course_progress.progress
    def handle(self, *args, **options):

        def get_detail(course_key, attribute):
            usage_key = course_key.make_usage_key('about', attribute)
            try:
                value = modulestore().get_item(usage_key).data
            except ItemNotFoundError:
                value = None
            return value

        def iso_date(thing):
            if isinstance(thing, datetime.datetime):
                return thing.isoformat()
            return thing

        exclusion_list = []
        inclusion_list = []

        if options['exclude_file']:
            try:
                with open(options['exclude_file'],'rb') as exclusion_file:
                    data = exclusion_file.readlines()
                exclusion_list = [x.strip() for x in data]
            except IOError:
                raise CommandError("Could not read exclusion list from '{0}'".format(options['exclude_file']))

        if options['include_file']:
            try:
                with open(options['include_file'],'rb') as inclusion_file:
                    data = inclusion_file.readlines()
                inclusion_list = [x.strip() for x in data]
            except IOError:
                raise CommandError("Could not read inclusion list from '{0}'".format(options['include_file']))

        store = modulestore()
        epoch = int(time.time())
        blob = {
            'epoch': epoch,
            'courses': [],
        }

        # For course TOC we need a user and a request. Find the first superuser defined,
        # that will be our user.
        request_user = User.objects.filter(is_superuser=True).first()
        factory = RequestFactory()

        for course in store.get_courses():

            course_id_string = course.id.to_deprecated_string()

            if options['single_course']:
                if course_id_string not in [options['single_course'].strip()]:
                    continue
            elif inclusion_list:
                if not course_id_string in inclusion_list:
                    continue
            elif exclusion_list:
                if course_id_string in exclusion_list:
                    continue

            print "Processing {}".format(course_id_string)

            students = CourseEnrollment.objects.users_enrolled_in(course.id)

            # The method of getting a table of contents for a course is quite obtuse.
            # We have to go all the way to simulating a request.

            request = factory.get('/')
            request.user = request_user

            raw_blocks = get_blocks(request, store.make_course_usage_key(course.id), request_user, 
                                requested_fields=['id', 'type', 'display_name', 'children', 'lms_web_url'])

            # We got the block structure. Now we need to massage it so we get the proper jump urls without site domain.
            # Because on the test server the site domain is wrong.
            blocks = {}
            for block_key, block in raw_blocks['blocks'].items():
                try:
                    direct_url = '/courses/' + block.get('lms_web_url').split('/courses/')[1]
                except IndexError:
                    direct_url = ''
                blocks[block_key] = {
                    'id': block.get('id', ''),
                    'display_name': block.get('display_name', ''),
                    'type': block.get('type', ''),
                    'children_ids': block.get('children', []),
                    'url': direct_url
                }

            # Then we need to recursively stitch it into a tree.
            # We're only interested in three layers of the hierarchy for now: 'course', 'chapter', 'sequential', 'vertical'.
            # Everything else is the individual blocks and problems we don't care about right now.

            INTERESTING_BLOCKS = ['course', 'chapter', 'sequential', 'vertical']

            def _get_children(parent):
                children = [blocks.get(n) for n in parent['children_ids'] if blocks.get(n)] # and blocks.get(n)['type'] in INTERESTING_BLOCKS]
                for child in children:
                    child['children'] = _get_children(child)
                parent['children'] = children
                del parent['children_ids']
                return children

            block_tree = _get_children(blocks[raw_blocks['root']])

            course_block = {
              'id': course_id_string,
              'meta_data': {
                'about': {
                    'display_name': course.display_name,
                    'media': {
                        'course_image': course_image_url(course),
                    }
                },
                'block_tree': block_tree,
                # Yes, I'm duplicating them for now, because the about section is shot.
                'display_name': course.display_name,
                'banner': course_image_url(course),
                'id_org': course.org,
                'id_number': course.number,
                'graded': course.graded,
                'hidden': course.visible_to_staff_only,
                'ispublic': not (course.visible_to_staff_only or False), # course.ispublic was removed in dogwood.
                'grading_policy': course.grading_policy,
                'advanced_modules': course.advanced_modules,
                'lowest_passing_grade': course.lowest_passing_grade,
                'start': iso_date(course.start),
                'advertised_start': iso_date(course.advertised_start),
                'end': iso_date(course.end),
                'enrollment_end': iso_date(course.enrollment_end),
                'enrollment_start': iso_date(course.enrollment_start),
                'has_started': course.has_started(),
                'has_ended': course.has_ended(),
                'overview': get_detail(course.id,'overview'),
                'short_description': get_detail(course.id,'short_description'),
                'pre_requisite_courses': get_detail(course.id,'pre_requisite_courses'),
                'video': get_detail(course.id,'video'),
              },
              'students': [x.username for x in students],
              'global_anonymous_id': { x.username:anonymous_id_for_user(x, None) for x in students },
              'local_anonymous_id': { x.username:anonymous_id_for_user(x, course.id) for x in students },
            }

            if not options['meta_only']:
                blob['grading_data_epoch'] = epoch
                course_block['grading_data'] = []
                # Grab grades for all students that have ever had anything to do with the course.
                graded_students = User.objects.filter(pk__in=CourseEnrollment.objects.filter(course_id=course.id).values_list('user',flat=True))
                print "{0} graded students in course {1}".format(graded_students.count(),course_id_string)
                if graded_students.count():
                    for student, gradeset, error_message \
                        in iterate_grades_for(course.id, graded_students):
                        if gradeset:
                            course_block['grading_data'].append({
                                'username': student.username,
                                'grades': gradeset,
                            })
                        else:
                            print error_message

            blob['courses'].append(course_block)
        if options['output']:
            # Ensure the dump is atomic.
            with tempfile.NamedTemporaryFile('w', dir=os.path.dirname(options['output']), delete=False) as output_file:
                json.dump(blob, output_file, default=json_util.default)
                tempname = output_file.name
            os.rename(tempname, options['output'])
        else:
            print "Blob output:"
            print json.dumps(blob, indent=2, ensure_ascii=False, default=json_util.default)
    def get_titles(self):
        log.info("get_titles: Starting to get titles")
        if self.course_key is None:
            self.course_key = SlashSeparatedCourseKey.from_deprecated_string(
                self.course_id)

    #get all course structure
        course_usage_key = modulestore().make_course_usage_key(self.course_key)
        blocks = get_blocks(self.request,
                            course_usage_key,
                            depth='all',
                            requested_fields=['display_name', 'children'])
        _root = blocks['root']
        blocks_overviews = []
        log.info("get_titles: Got course structure")
        #return unit title and component root
        try:
            children = blocks['blocks'][_root]['children']
            for z in children:
                child = blocks['blocks'][z]
                try:
                    sub_section = child['children']
                    for s in sub_section:
                        sub_ = blocks['blocks'][s]
                        vertical = sub_['children']
                        try:
                            for v in vertical:
                                unit = blocks['blocks'][v]
                                w = {}
                                w['id'] = unit['id']
                                w['display_name'] = unit['display_name']
                                try:
                                    w['children'] = unit['children']
                                except:
                                    pass
                                blocks_overviews.append(w)
                        except:
                            pass
                except:
                    pass
        except:
            pass
        log.info("get_titles: Got unit titles and component root")
        ## GET ALL SCORED XBLOCKS FOR WHICH THERE EXISTS AT LEAST ONE ENTRY IN STUDENTMODULE
        studentmodule = StudentModule.objects.raw(
            "SELECT id,course_id,module_id FROM courseware_studentmodule WHERE course_id = %s AND max_grade IS NOT NULL AND grade <= max_grade GROUP BY module_id ORDER BY created",
            [self.course_id])

        title = []

        for n in studentmodule:
            try:
                usage_key = n.module_state_key
                _current = get_blocks(self.request,
                                      usage_key,
                                      depth='all',
                                      requested_fields=['display_name'])
                root = _current['root']

                unit_name = ''

                for over in blocks_overviews:
                    if str(root) in over.get('children'):
                        unit_name = over.get('display_name')

                q = {
                    "title": _current['blocks'][root]['display_name'],
                    "root": root,
                    'unit': unit_name
                }
                title.append(q)
            except:
                pass

        log.info("get_titles: All titles fetched")
        return title
Example #8
0
    def _dashboard_username(self):

        context = {
            "course_id": self.course_id,
            "username": self.username,
            "user_id": '',
            "course_grade": [],
            "user_info": '',
        }

        try:
            # get users info
            users = User.objects.get(username=self.username)
            # get user id
            user_id = users.id
            # get course_key from url's param
            course_key = SlashSeparatedCourseKey.from_deprecated_string(
                self.course_id)
            # get course from course_key
            course = get_course_by_id(course_key)
            # get all courses block of the site
            course_block = StudentModule.objects.all().filter(
                student_id=user_id,
                course_id=course_key,
                max_grade__isnull=False)
            # var of grades / course_structure
            course_grade = []
            # get course_users_info
            course_user_info = CourseGradeFactory().create(users, course)
            # user info responses
            user_info = [{
                'Grade': str(course_user_info.percent * 100) + '%'
            }, {
                'First_name': users.first_name
            }, {
                'Last_name': users.last_name
            }, {
                'Email': users.email
            }]

            for n in course_block:
                q = {}
                usage_key = n.module_state_key
                block_view = BlocksView()
                block_name = get_blocks(self.request,
                                        usage_key,
                                        depth='all',
                                        requested_fields=['display_name'])
                root = block_name['root']
                display_name = block_name['blocks'][root]['display_name']
                q['earned'] = n.grade
                q['possible'] = n.max_grade
                q['display_name'] = display_name
                q['root'] = root
                course_grade.append(q)

            context["user_id"] = user_id
            context["course_grade"] = course_grade
            context["user_info"] = user_info

        except:
            pass

        return context
def update_course_progress(request, course_key, module_type, usage_keys):
    """
    Description: To calculate and update the course progress
    for specified student and course.

    Arguments:
        request: HTTPRequest obj
        course_key: SlashSeparatedCourseKey instance, identifying the course
        instance: progress affecting xblock module
        module_type: type of the xblock i.e. problem, video etc.
        usage_keys: list of usage key instances

    Notes:
        For each Block traversed, the following is verified and
        the block is excluded when not accessible by the user.
            1. Block is not visible_to_staff_only
            2. The Block has been released
            3. The cohort affiliation of the Block matches the requested user's cohort

    Author: Naresh Makwana
    """
    # Initialization
    student = request.user
    course_struct = {}
    root = None
    course_progress = {}
    chapter_wise_progress = OrderedDict()

    # Get course structure
    course_usage_key = modulestore().make_course_usage_key(course_key)
    root = course_usage_key.to_deprecated_string()

    block_fields = ['type', 'display_name', 'children']
    course_struct = get_blocks(request, course_usage_key, request.user, 'all', requested_fields=block_fields)

    # get course progress object
    try:
        student_course_progress = StudentCourseProgress.objects.get(student=student.id, course_id=course_key)
    except StudentCourseProgress.DoesNotExist:
        default_progress_dict = get_default_course_progress( course_struct.get('blocks', []), root )
        default_progress_json = json.dumps(default_progress_dict)
        student_course_progress = StudentCourseProgress.objects.create(
            student=student,
            course_id=course_key,
            progress_json=default_progress_json,
        )


    # Get course progress dict
    progress = student_course_progress.progress

    # To have proper sync with blocks and stored progress
    new_progress = {}
    default_progress_dict = get_default_course_progress( course_struct.get('blocks', []), root )
    for default_block_id, default_block in default_progress_dict.items():
        progress_block = progress.get(default_block_id, {})
        stored_progress = progress_block.get('progress', 0)
        default_block.update({'progress': stored_progress})
        new_progress.update({default_block_id: default_block})
    progress = new_progress

    # increase progress if attempted or graded and not already updated
    updated_units = []
    for usage_key in usage_keys:
        usage_id = usage_key.to_deprecated_string()
        current_progress = progress.get(usage_id, {}).get('progress')
        if current_progress != 100:
            progress[usage_id]['progress'] = 100
            updated_units.append(progress[usage_id]['parent'])

    # update unit progress
    if updated_units:
        update_unit_progress(progress, list(set(updated_units)) )

    student_course_progress.progress_json = json.dumps(progress)
    student_course_progress.overall_progress = progress[root]['progress']
    student_course_progress.save()
Example #10
0
    def handle(self, *args, **options):
        def get_detail(course_key, attribute):
            usage_key = course_key.make_usage_key('about', attribute)
            try:
                value = modulestore().get_item(usage_key).data
            except ItemNotFoundError:
                value = None
            return value

        def iso_date(thing):
            if isinstance(thing, datetime.datetime):
                return thing.isoformat()
            return thing

        exclusion_list = []
        inclusion_list = []

        if options['exclude_file']:
            try:
                with open(options['exclude_file'], 'rb') as exclusion_file:
                    data = exclusion_file.readlines()
                exclusion_list = [x.strip() for x in data]
            except IOError:
                raise CommandError(
                    "Could not read exclusion list from '{0}'".format(
                        options['exclude_file']))

        if options['include_file']:
            try:
                with open(options['include_file'], 'rb') as inclusion_file:
                    data = inclusion_file.readlines()
                inclusion_list = [x.strip() for x in data]
            except IOError:
                raise CommandError(
                    "Could not read inclusion list from '{0}'".format(
                        options['include_file']))

        store = modulestore()
        epoch = int(time.time())
        blob = {
            'epoch': epoch,
            'courses': [],
        }

        # For course TOC we need a user and a request. Find the first superuser defined,
        # that will be our user.
        request_user = User.objects.filter(is_superuser=True).first()
        factory = RequestFactory()

        for course in store.get_courses():

            course_id_string = course.id.to_deprecated_string()

            if options['single_course']:
                if course_id_string not in [options['single_course'].strip()]:
                    continue
            elif inclusion_list:
                if not course_id_string in inclusion_list:
                    continue
            elif exclusion_list:
                if course_id_string in exclusion_list:
                    continue

            print "Processing {}".format(course_id_string)

            students = CourseEnrollment.objects.users_enrolled_in(course.id)

            # The method of getting a table of contents for a course is quite obtuse.
            # We have to go all the way to simulating a request.

            request = factory.get('/')
            request.user = request_user

            raw_blocks = get_blocks(request,
                                    store.make_course_usage_key(course.id),
                                    request_user,
                                    requested_fields=[
                                        'id', 'type', 'display_name',
                                        'children', 'lms_web_url'
                                    ])

            # We got the block structure. Now we need to massage it so we get the proper jump urls without site domain.
            # Because on the test server the site domain is wrong.
            blocks = {}
            for block_key, block in raw_blocks['blocks'].items():
                try:
                    direct_url = '/courses/' + block.get('lms_web_url').split(
                        '/courses/')[1]
                except IndexError:
                    direct_url = ''
                blocks[block_key] = {
                    'id': block.get('id', ''),
                    'display_name': block.get('display_name', ''),
                    'type': block.get('type', ''),
                    'children_ids': block.get('children', []),
                    'url': direct_url
                }

            # Then we need to recursively stitch it into a tree.
            # We're only interested in three layers of the hierarchy for now: 'course', 'chapter', 'sequential', 'vertical'.
            # Everything else is the individual blocks and problems we don't care about right now.

            INTERESTING_BLOCKS = [
                'course', 'chapter', 'sequential', 'vertical'
            ]

            def _get_children(parent):
                children = [
                    blocks.get(n) for n in parent['children_ids']
                    if blocks.get(n)
                ]  # and blocks.get(n)['type'] in INTERESTING_BLOCKS]
                for child in children:
                    child['children'] = _get_children(child)
                parent['children'] = children
                del parent['children_ids']
                return children

            block_tree = _get_children(blocks[raw_blocks['root']])

            course_block = {
                'id': course_id_string,
                'meta_data': {
                    'about': {
                        'display_name': course.display_name,
                        'media': {
                            'course_image': course_image_url(course),
                        }
                    },
                    'block_tree':
                    block_tree,
                    # Yes, I'm duplicating them for now, because the about section is shot.
                    'display_name':
                    course.display_name,
                    'banner':
                    course_image_url(course),
                    'id_org':
                    course.org,
                    'id_number':
                    course.number,
                    'graded':
                    course.graded,
                    'hidden':
                    course.visible_to_staff_only,
                    'ispublic':
                    not (course.visible_to_staff_only
                         or False),  # course.ispublic was removed in dogwood.
                    'grading_policy':
                    course.grading_policy,
                    'advanced_modules':
                    course.advanced_modules,
                    'lowest_passing_grade':
                    course.lowest_passing_grade,
                    'start':
                    iso_date(course.start),
                    'advertised_start':
                    iso_date(course.advertised_start),
                    'end':
                    iso_date(course.end),
                    'enrollment_end':
                    iso_date(course.enrollment_end),
                    'enrollment_start':
                    iso_date(course.enrollment_start),
                    'has_started':
                    course.has_started(),
                    'has_ended':
                    course.has_ended(),
                    'overview':
                    get_detail(course.id, 'overview'),
                    'short_description':
                    get_detail(course.id, 'short_description'),
                    'pre_requisite_courses':
                    get_detail(course.id, 'pre_requisite_courses'),
                    'video':
                    get_detail(course.id, 'video'),
                },
                'students': [x.username for x in students],
                'global_anonymous_id':
                {x.username: anonymous_id_for_user(x, None)
                 for x in students},
                'local_anonymous_id': {
                    x.username: anonymous_id_for_user(x, course.id)
                    for x in students
                },
            }

            if not options['meta_only']:
                blob['grading_data_epoch'] = epoch
                course_block['grading_data'] = []
                # Grab grades for all students that have ever had anything to do with the course.
                graded_students = User.objects.filter(
                    pk__in=CourseEnrollment.objects.filter(
                        course_id=course.id).values_list('user', flat=True))
                print "{0} graded students in course {1}".format(
                    graded_students.count(), course_id_string)
                if graded_students.count():
                    for student, gradeset, error_message \
                        in iterate_grades_for(course.id, graded_students):
                        if gradeset:
                            course_block['grading_data'].append({
                                'username':
                                student.username,
                                'grades':
                                gradeset,
                            })
                        else:
                            print error_message

            blob['courses'].append(course_block)
        if options['output']:
            # Ensure the dump is atomic.
            with tempfile.NamedTemporaryFile('w',
                                             dir=os.path.dirname(
                                                 options['output']),
                                             delete=False) as output_file:
                json.dump(blob, output_file, default=json_util.default)
                tempname = output_file.name
            os.rename(tempname, options['output'])
        else:
            print "Blob output:"
            print json.dumps(blob,
                             indent=2,
                             ensure_ascii=False,
                             default=json_util.default)