Ejemplo n.º 1
0
def get_admin_details(admin):
    """
    Returns the admin name, permission (ADG Admin or BU Admin) and business line in case of BU Admin.

    Arguments:
        admin (User): admin for which the details are to be fetched

    Returns:
        dict: dictionary containing admin details
    """
    name = admin.profile.name
    image = get_profile_image_urls_for_user(admin).get('medium')

    if is_superuser_or_adg_admin(admin):
        permission = Text(_('{name}, {span_start}ADG Admin{span_end}')).format(
            name=name,
            span_start=HTML(SPAN_START),
            span_end=HTML(SPAN_END),
        )
    else:
        business_unit = BusinessLine.business_lines_for_user(
            admin).first().display_title
        permission = Text(
            _('{name}, {span_start}BU Admin of {business_unit}{span_end}')
        ).format(
            name=name,
            span_start=HTML(SPAN_START),
            business_unit=business_unit,
            span_end=HTML(SPAN_END),
        )

    return {'image': image, 'permission': permission}
Ejemplo n.º 2
0
 def to_representation(self, value):
     pimage_url = get_profile_image_urls_for_user(value)
     return {
         "id": value.id,
         "profile_image_url": pimage_url['small'],
         "username": value.username
     }
Ejemplo n.º 3
0
 def _user_image_url(self):
     """Returns an image url for representing the learner in the chat"""
     user_service = self.runtime.service(self, 'user')
     user = user_service.get_current_user()
     username = user.opt_attrs.get('edx-platform.username')
     current_user = User.objects.get(username=username)  # pylint: disable=no-member
     urls = get_profile_image_urls_for_user(current_user)
     return urls.get('large')
Ejemplo n.º 4
0
def test_dashboard_view_context_data(user_with_profile, courses, webinar,
                                     mocker, request):
    """
    Test dashboard page context data
    """
    mocker.patch(
        'openedx.adg.lms.student.views.DashboardView.get_filtered_enrolled_courses'
    )
    mocker.patch('openedx.adg.lms.student.views.get_course_by_id',
                 return_value=courses['test_course1'])
    mocker.patch('openedx.adg.lms.student.views.reverse',
                 return_value='/account/settings')

    dashboard_request = request
    user_with_profile.is_active = False
    dashboard_request.user = user_with_profile

    CourseEnrollment.enroll(user=user_with_profile,
                            course_key=courses['test_course1'].id)
    CourseEnrollment.enroll(user=user_with_profile,
                            course_key=courses['test_course2'].id)

    PersistentCourseGrade.update_or_create(
        user_id=user_with_profile.id,
        course_id=courses['test_course1'].id,
        percent_grade=0.8,
        passed=True)

    WebinarRegistrationFactory(email=user_with_profile.email,
                               webinar=webinar,
                               is_registered=True)

    GeneratedCertificateFactory(user=user_with_profile,
                                course_id=courses['test_course1'].id,
                                status=CertificateStatuses.downloadable)

    context_data = DashboardView(request=dashboard_request).get_context_data()

    assert 'user' in context_data
    assert 'user_profile' in context_data
    assert 'profile_image_url' in context_data
    assert 'edit_account_link' in context_data
    assert 'application_link' in context_data
    assert 'courses' in context_data
    assert 'courses_filter_options' in context_data
    assert 'courses_filter' in context_data
    assert 'webinars' in context_data
    assert 'webinars_filter_options' in context_data
    assert 'webinars_filter' in context_data
    assert 'certificates' in context_data
    assert 'activate_account_message' in context_data
    assert 'account_activation_messages' in context_data
    assert context_data[
        'profile_image_url'] == get_profile_image_urls_for_user(
            user_with_profile)['full']
    assert context_data['edit_account_link'] == '/account/settings'
    assert context_data['user'] == user_with_profile
    assert len(context_data['webinars']) == 1
Ejemplo n.º 5
0
    def handle(self, *args, **options):  # pylint: disable=unused-argument
        program_director_roles = CourseAccessRole.objects.filter(
            role='ccx_coach').exclude(course_id__startswith='ccx-')

        for program_director_role in program_director_roles:
            user = program_director_role.user
            self.stdout.write(str(user))

            image_url = get_profile_image_urls_for_user(user)['full']
            self.stdout.write(image_url)

            image_file = None

            try:
                if 's3' in image_url:
                    file_data = urllib2.urlopen(image_url).read()
                else:
                    image_path = '/edx/var/edxapp' + image_url.split('?')[0]
                    file_data = open(image_path).read()

                image_file = ContentFile(file_data)
            except IOError:
                self.stdout.write('Image not found')

            try:
                affiliate, _ = AffiliateEntity.objects.get_or_create(
                    email=user.profile.public_email or user.email,
                    name=user.profile.affiliate_organization_name
                    or user.profile.name,
                    description=user.profile.description,
                    phone_number=user.profile.phone_number,
                    address=' '.join([
                        user.profile.mailing_address or '',
                        user.profile.secondary_address or ''
                    ]),
                    city=user.profile.city,
                    zipcode=user.profile.zipcode,
                    facebook=user.profile.facebook_link,
                    twitter=user.profile.twitter_link,
                    linkedin=user.profile.linkedin_link,
                    state=user.profile.state,
                    country=user.profile.country,
                )

                if image_file:
                    image_filename = image_url.split('/')[-1].split('?')[0]
                    affiliate.image.save(image_filename, image_file, save=True)

                AffiliateMembership.objects.get_or_create(affiliate=affiliate,
                                                          member=user,
                                                          role='staff')
            except IntegrityError:
                self.stdout.write('Duplicate entry.')

        self.stdout.write('Successfully migrated affiliate users')
    def _get_image_url(self, user):
        """
        """
        profile_image_url = get_profile_image_urls_for_user(user)["full"]

        if profile_image_url.startswith("http"):
            return profile_image_url

        base_url = settings.LMS_ROOT_URL
        image_url = "{}{}".format(base_url, profile_image_url)
        return image_url
Ejemplo n.º 7
0
    def _user_image_url(self, user):
        """Returns an image url for the current user"""
        from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_image_urls_for_user  # pylint: disable=relative-import
        profile_image_url = get_profile_image_urls_for_user(user)["full"]

        if profile_image_url.startswith("http"):
            return profile_image_url

        base_url = settings.LMS_ROOT_URL
        image_url = "{}{}".format(base_url, profile_image_url)
        return image_url
    def get_jwt_token(self, request, suffix=''):
        """Generate JWT token for SSO authorization"""
        annoto_auth = self.get_annoto_settings()
        if not annoto_auth:
            msg = self.i18n_service.gettext(
                'Annoto authorization is not provided in "LTI Passports".')
            return self._json_resp({'status': 'error', 'msg': msg})

        user = self._get_user()
        if not user:
            msg = self.i18n_service.gettext('Requested user does not exists.')
            return self._json_resp({'status': 'error', 'msg': msg})

        profile_name = hasattr(
            user, 'profile') and user.profile and user.profile.name
        name = profile_name or user.get_full_name() or user.username
        photo = self._build_absolute_uri(
            request,
            get_profile_image_urls_for_user(user)['small'])

        roles = user.courseaccessrole_set.filter(
            course_id=self.course_id).values_list('role', flat=True)

        if CourseStaffRole.ROLE in roles or GlobalStaff().has_user(user):
            scope = 'super-mod'
        elif CourseInstructorRole.ROLE in roles:
            scope = 'moderator'
        else:
            scope = 'user'

        payload = {
            'exp': int(time.time() + 60 * 20),
            'iss': annoto_auth['client_id'],
            'jti': user.id,
            'name': name,
            'email': user.email,
            'photoUrl': photo,
            'scope': scope
        }

        token = jwt.encode(payload,
                           annoto_auth['client_secret'],
                           algorithm='HS256')
        return self._json_resp({
            'status':
            'ok',
            'token':
            getattr(token, 'decode', lambda: token)()
        })
Ejemplo n.º 9
0
def _get_user_info_cookie_data(request, user):
    """ Returns information that will populate the user info cookie. """

    # Set a cookie with user info.  This can be used by external sites
    # to customize content based on user information.  Currently,
    # we include information that's used to customize the "account"
    # links in the header of subdomain sites (such as the marketing site).
    header_urls = {'logout': reverse('logout')}

    # Unfortunately, this app is currently used by both the LMS and Studio login pages.
    # If we're in Studio, we won't be able to reverse the account/profile URLs.
    # To handle this, we don't add the URLs if we can't reverse them.
    # External sites will need to have fallback mechanisms to handle this case
    # (most likely just hiding the links).
    try:
        header_urls['account_settings'] = reverse('account_settings')
        header_urls['learner_profile'] = reverse(
            'learner_profile', kwargs={'username': user.username})
    except NoReverseMatch:
        pass

    # Add 'resume course' last completed block
    try:
        header_urls['resume_block'] = retrieve_last_sitewide_block_completed(
            user)
    except User.DoesNotExist:
        pass

    # Convert relative URL paths to absolute URIs
    for url_name, url_path in six.iteritems(header_urls):
        header_urls[url_name] = request.build_absolute_uri(url_path)

    profile_image_url = get_profile_image_urls_for_user(user)['medium']

    user_info = {
        'version':
        settings.EDXMKTG_USER_INFO_COOKIE_VERSION,
        'username':
        user.username,
        'header_urls':
        header_urls,
        'enrollmentStatusHash':
        CourseEnrollment.generate_enrollment_status_hash(user),
        'profile_image_url':
        profile_image_url
    }

    return user_info
Ejemplo n.º 10
0
def _get_user_info_cookie_data(request, user):
    """ Returns information that will populate the user info cookie. """

    # Set a cookie with user info.  This can be used by external sites
    # to customize content based on user information.  Currently,
    # we include information that's used to customize the "account"
    # links in the header of subdomain sites (such as the marketing site).
    header_urls = {'logout': reverse('logout')}

    # Unfortunately, this app is currently used by both the LMS and Studio login pages.
    # If we're in Studio, we won't be able to reverse the account/profile URLs.
    # To handle this, we don't add the URLs if we can't reverse them.
    # External sites will need to have fallback mechanisms to handle this case
    # (most likely just hiding the links).
    try:
        header_urls['account_settings'] = reverse('account_settings')
        header_urls['learner_profile'] = reverse(
            'learner_profile', kwargs={'username': user.username})
    except NoReverseMatch:
        pass

    # Add 'resume course' last completed block
    try:
        header_urls['resume_block'] = retrieve_last_sitewide_block_completed(
            user)
    except User.DoesNotExist:
        pass

    header_urls = _convert_to_absolute_uris(request, header_urls)

    image_urls = {}
    try:
        image_urls = get_profile_image_urls_for_user(user)
    except UserProfile.DoesNotExist:
        pass

    image_urls = _convert_to_absolute_uris(request, image_urls)

    user_info = {
        'version': settings.EDXMKTG_USER_INFO_COOKIE_VERSION,
        'username': user.username,
        'email': user.email,
        'header_urls': header_urls,
        'user_image_urls': image_urls,
    }

    return user_info
Ejemplo n.º 11
0
    def get_context_data(self, **kwargs):
        """
        Add the context regarding social auth providers to the view
        """
        context = super(AccountView, self).get_context_data(**kwargs)

        user = self.request.user
        providers_context_data = self.get_social_oauth_providers_data()
        profile_image = get_profile_image_urls_for_user(user).get('full')

        context.update({
            'password_change_request':
            reverse('password_reset'),
            'account_delete_url':
            reverse('deactivate_logout'),
            'profile_image':
            profile_image,
            'is_user_under_age':
            user.profile.year_of_birth
            and user.profile.age < settings.PARENTAL_CONSENT_AGE_LIMIT,
            **providers_context_data,
            **account_settings_context(self.request)
        })
        return context
Ejemplo n.º 12
0
def render_body(context,**pageargs):
    __M_caller = context.caller_stack._push_frame()
    try:
        __M_locals = __M_dict_builtin(pageargs=pageargs)
        getattr = context.get('getattr', UNDEFINED)
        request = context.get('request', UNDEFINED)
        user = context.get('user', UNDEFINED)
        self = context.get('self', UNDEFINED)
        __M_writer = context.writer()
        __M_writer(u'\n')
        __M_writer(u'\n\n')
        __M_writer(u'\n\n')

## This template should not use the target student's details when masquerading, see TNL-4895
        self.real_user = getattr(user, 'real_user', user)
        profile_image_url = get_profile_image_urls_for_user(self.real_user)['medium']
        username = self.real_user.username
        resume_block = retrieve_last_sitewide_block_completed(username)
        displayname = get_enterprise_learner_generic_name(request) or username
        
        
        __M_locals_builtin_stored = __M_locals_builtin()
        __M_locals.update(__M_dict_builtin([(__M_key, __M_locals_builtin_stored[__M_key]) for __M_key in ['username','resume_block','displayname','profile_image_url'] if __M_key in __M_locals_builtin_stored]))
        __M_writer(u'\n\n<div class="nav-item hidden-mobile nav-item-dashboard">\n    <a href="')
        __M_writer(filters.html_escape(filters.decode.utf8(reverse('dashboard'))))
        __M_writer(u'" class="menu-title">\n        <img class="user-image-frame" src="')
        __M_writer(filters.html_escape(filters.decode.utf8(profile_image_url)))
        __M_writer(u'" alt="">\n        <span class="sr-only">')
        __M_writer(filters.html_escape(filters.decode.utf8(_("Dashboard for:"))))
        __M_writer(u'</span>\n        <span class="username">')
        __M_writer(filters.html_escape(filters.decode.utf8(displayname)))
        __M_writer(u'</span>\n    </a>\n</div>\n<div class="nav-item hidden-mobile nav-item-dropdown" tabindex="-1">\n    <div class="toggle-user-dropdown" role="button" aria-label=')
        __M_writer(filters.html_escape(filters.decode.utf8(_("Options Menu"))))
        __M_writer(u' aria-expanded="false" tabindex="0" aria-controls="user-menu">\n        <span class="fa fa-caret-down" aria-hidden="true"></span>\n    </div>\n    <div class="dropdown-user-menu hidden" aria-label=')
        __M_writer(filters.html_escape(filters.decode.utf8(_("More Options"))))
        __M_writer(u' role="menu" id="user-menu" tabindex="-1">\n')
        if resume_block:
            __M_writer(u'            <div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="')
            __M_writer(filters.html_escape(filters.decode.utf8(resume_block)))
            __M_writer(u'" role="menuitem">')
            __M_writer(filters.html_escape(filters.decode.utf8(_("Resume your last course"))))
            __M_writer(u'</a></div>\n')
        __M_writer(u'        <div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="')
        __M_writer(filters.html_escape(filters.decode.utf8(reverse('dashboard'))))
        __M_writer(u'" role="menuitem">')
        __M_writer(filters.html_escape(filters.decode.utf8(_("Dashboard"))))
        __M_writer(u'</a></div>\n        <div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="')
        __M_writer(filters.html_escape(filters.decode.utf8(reverse('learner_profile', kwargs={'username': username}))))
        __M_writer(u'" role="menuitem">')
        __M_writer(filters.html_escape(filters.decode.utf8(_("Profile"))))
        __M_writer(u'</a></div>\n        <div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="')
        __M_writer(filters.html_escape(filters.decode.utf8(reverse('account_settings'))))
        __M_writer(u'" role="menuitem">')
        __M_writer(filters.html_escape(filters.decode.utf8(_("Account"))))
        __M_writer(u'</a></div>\n        <div class="mobile-nav-item dropdown-item dropdown-nav-item"><a href="')
        __M_writer(filters.html_escape(filters.decode.utf8(reverse('logout'))))
        __M_writer(u'" role="menuitem">')
        __M_writer(filters.html_escape(filters.decode.utf8(_("Sign Out"))))
        __M_writer(u'</a></div>\n    </div>\n</div>\n')
        return ''
    finally:
        context.caller_stack._pop_frame()
Ejemplo n.º 13
0
    def get(self, request, course_id):
        """
        Displays the user's Learner Analytics for the specified course.

        Arguments:
            request: HTTP request
            course_id (unicode): course id
        """
        course_key = CourseKey.from_string(course_id)
        if not ENABLE_DASHBOARD_TAB.is_enabled(course_key):
            raise Http404

        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=True)
        course_url_name = default_course_url_name(course.id)
        course_url = reverse(course_url_name,
                             kwargs={'course_id': unicode(course.id)})

        grading_policy = course.grading_policy

        (grade_data, answered_percent) = self.get_grade_data(
            request.user, course_key, grading_policy['GRADE_CUTOFFS'])
        schedule_data = self.get_assignments_with_due_date(request, course_key)
        (grade_data, schedule_data) = self.sort_grade_and_schedule_data(
            grade_data, schedule_data)

        context = {
            'course':
            course,
            'course_url':
            course_url,
            'disable_courseware_js':
            True,
            'uses_pattern_library':
            True,
            'is_self_paced':
            course.self_paced,
            'is_verified':
            CourseEnrollment.is_enrolled_as_verified(request.user, course_key),
            'grading_policy':
            grading_policy,
            'assignment_grades':
            grade_data,
            'answered_percent':
            answered_percent,
            'assignment_schedule':
            schedule_data,
            'profile_image_urls':
            get_profile_image_urls_for_user(request.user, request),
            'discussion_info':
            self.get_discussion_data(request, course_key),
            'weekly_active_users':
            self.get_weekly_course_activity_count(course_key),
            'week_streak':
            self.consecutive_weeks_of_course_activity_for_user(
                request.user.username, course_key)
        }

        return render_to_response('learner_analytics/dashboard.html', context)
Ejemplo n.º 14
0
    def get_context_data(self, **kwargs):
        """
        Get context data to display on dashboard.

        Returns:
            context (Dict): Dict of data to be displayed on dashboard
        """
        context = super(DashboardView, self).get_context_data(**kwargs)

        certificates = self.get_certificates()
        user_preferences = get_user_preferences(self.request.user)
        pref_language = user_preferences.get('pref-lang')

        # Display activation message
        activate_account_message = ''
        if not self.request.user.is_active:
            platform_name = configuration_helpers.get_value(
                'platform_name',
                _(settings.PLATFORM_NAME)  # pylint: disable=translation-of-non-string
            )
            activation_email_support_link = configuration_helpers.get_value(
                'ACTIVATION_EMAIL_SUPPORT_LINK', settings.
                ACTIVATION_EMAIL_SUPPORT_LINK) or settings.SUPPORT_SITE_LINK

            activate_account_message = Text(
                _('Check your {email_start}{email}{email_end} inbox for an account activation link from {platform_name}. '
                  'If you need help, contact {link_start}{platform_name} Support{link_end}.'
                  )
            ).format(
                platform_name=platform_name,
                email_start=HTML('<strong>'),
                email_end=HTML('</strong>'),
                email=self.request.user.email,
                link_start=HTML(
                    "<a target='_blank' href='{activation_email_support_link}'>"
                ).format(
                    activation_email_support_link=activation_email_support_link,
                ),
                link_end=HTML('</a>'),
            )

        # Account activation message
        account_activation_messages = [
            message for message in messages.get_messages(self.request)
            if 'account-activation' in message.tags
        ]

        context.update({
            'user':
            self.request.user,
            'user_profile':
            self.request.user.profile,
            'profile_image_url':
            get_profile_image_urls_for_user(self.request.user).get('full'),
            'edit_account_link':
            reverse('adg_account_settings'),
            'application_link':
            reverse('application_hub'),
            'courses':
            self.get_filtered_enrolled_courses(),
            'courses_filter_options':
            self.courses_filter_options,
            'courses_filter':
            self.courses_filter,
            'webinars':
            self.get_filtered_webinars(),
            'webinars_filter_options':
            self.webinars_filter_options,
            'webinars_filter':
            self.webinars_filter,
            'certificates':
            certificates,
            'active_tab':
            self.active_tab,
            'pref_language_name':
            settings.LANGUAGE_DICT.get(pref_language),
            'activate_account_message':
            activate_account_message,
            'account_activation_messages':
            account_activation_messages,
        })

        return context
Ejemplo n.º 15
0
def user_profile(request, course_key, user_id):
    """
    Renders a response to display the user profile page (shown after clicking
    on a post author's username).
    """

    nr_transaction = newrelic.agent.current_transaction()

    #TODO: Allow sorting?
    course = get_course_with_access(request.user,
                                    'load',
                                    course_key,
                                    check_if_enrolled=True)
    try:
        query_params = {
            'page': request.GET.get('page', 1),
            'per_page':
            THREADS_PER_PAGE,  # more than threads_per_page to show more activities
        }

        try:
            group_id = get_group_id_for_comments_service(request, course_key)
        except ValueError:
            return HttpResponseBadRequest("Invalid group_id")
        if group_id is not None:
            query_params['group_id'] = group_id
            profiled_user = cc.User(id=user_id,
                                    course_id=course_key,
                                    group_id=group_id)
        else:
            profiled_user = cc.User(id=user_id, course_id=course_key)

        threads, page, num_pages = profiled_user.active_threads(query_params)
        query_params['page'] = page
        query_params['num_pages'] = num_pages
        user_info = cc.User.from_django_user(request.user).to_dict()

        with newrelic.agent.FunctionTrace(nr_transaction,
                                          "get_metadata_for_threads"):
            annotated_content_info = utils.get_metadata_for_threads(
                course_key, threads, request.user, user_info)

        is_staff = has_permission(request.user, 'openclose_thread', course.id)
        threads = [
            utils.prepare_content(thread, course_key, is_staff)
            for thread in threads
        ]
        if request.is_ajax():
            return utils.JsonResponse({
                'discussion_data':
                threads,
                'page':
                query_params['page'],
                'num_pages':
                query_params['num_pages'],
                'annotated_content_info':
                json.dumps(annotated_content_info),
            })
        else:
            django_user = User.objects.get(id=user_id)
            context = {
                'course':
                course,
                'user':
                request.user,
                'django_user':
                django_user,
                'profiled_user':
                profiled_user.to_dict(),
                'threads':
                json.dumps(threads),
                'user_info':
                json.dumps(user_info, default=lambda x: None),
                'annotated_content_info':
                json.dumps(annotated_content_info),
                'page':
                query_params['page'],
                'num_pages':
                query_params['num_pages'],
                'learner_profile_page_url':
                reverse('learner_profile',
                        kwargs={'username': django_user.username}),
                'profile_image_url':
                get_profile_image_urls_for_user(django_user)['large']
            }

            return render_to_response('discussion/user_profile.html', context)
    except User.DoesNotExist:
        raise Http404
Ejemplo n.º 16
0
def prepare_content(content,
                    course_key,
                    is_staff=False,
                    course_is_cohorted=None):
    """
    This function is used to pre-process thread and comment models in various
    ways before adding them to the HTTP response.  This includes fixing empty
    attribute fields, enforcing author anonymity, and enriching metadata around
    group ownership and response endorsement.

    @TODO: not all response pre-processing steps are currently integrated into
    this function.

    Arguments:
        content (dict): A thread or comment.
        course_key (CourseKey): The course key of the course.
        is_staff (bool): Whether the user is a staff member.
        course_is_cohorted (bool): Whether the course is cohorted.
    """
    fields = [
        'id', 'title', 'body', 'course_id', 'anonymous', 'anonymous_to_peers',
        'endorsed', 'parent_id', 'thread_id', 'votes', 'closed', 'created_at',
        'updated_at', 'depth', 'type', 'commentable_id', 'comments_count',
        'at_position_list', 'children', 'highlighted_title',
        'highlighted_body', 'courseware_title', 'courseware_url',
        'unread_comments_count', 'read', 'group_id', 'group_name', 'pinned',
        'abuse_flaggers', 'stats', 'resp_skip', 'resp_limit', 'resp_total',
        'thread_type', 'endorsed_responses', 'non_endorsed_responses',
        'non_endorsed_resp_total', 'endorsement', 'context', 'last_activity_at'
    ]

    if (content.get('anonymous') is False) and (
        (content.get('anonymous_to_peers') is False) or is_staff):
        fields += ['username', 'user_id']

    content = strip_none(extract(content, fields))

    if content.get("endorsement"):
        endorsement = content["endorsement"]
        endorser = None
        if endorsement["user_id"]:
            try:
                endorser = User.objects.get(pk=endorsement["user_id"])
            except User.DoesNotExist:
                log.error(
                    "User ID %s in endorsement for comment %s but not in our DB.",
                    content.get('user_id'), content.get('id'))

        # Only reveal endorser if requester can see author or if endorser is staff
        if (endorser and
            ("username" in fields
             or has_permission(endorser, "endorse_comment", course_key))):
            endorsement["username"] = endorser.username
        else:
            del endorsement["user_id"]

    if course_is_cohorted is None:
        course_is_cohorted = is_course_cohorted(course_key)

    for child_content_key in [
            "children", "endorsed_responses", "non_endorsed_responses"
    ]:
        if child_content_key in content:
            children = [
                prepare_content(child,
                                course_key,
                                is_staff,
                                course_is_cohorted=course_is_cohorted)
                for child in content[child_content_key]
            ]
            content[child_content_key] = children

    if course_is_cohorted:
        # Augment the specified thread info to include the group name if a group id is present.
        if content.get('group_id') is not None:
            content['group_name'] = get_cohort_by_id(
                course_key, content.get('group_id')).name
    else:
        # Remove any cohort information that might remain if the course had previously been cohorted.
        content.pop('group_id', None)

    # add user profile image if available
    profile_image_url = _get_default_profile_image_urls()['medium']
    if not content['anonymous']:
        lms_user = User.objects.get(username=content.get('username'))
        profile_image_url = get_profile_image_urls_for_user(lms_user)['medium']
    content.update({'profile_image_url': profile_image_url})

    return content
Ejemplo n.º 17
0
    def get(self, request, course_id):
        """
        Displays the user's Learner Analytics for the specified course.

        Arguments:
            request: HTTP request
            course_id (unicode): course id
        """
        course_key = CourseKey.from_string(course_id)
        if not ENABLE_DASHBOARD_TAB.is_enabled(course_key):
            raise Http404

        course = get_course_with_access(request.user,
                                        'load',
                                        course_key,
                                        check_if_enrolled=True)
        course_url_name = default_course_url_name(course.id)
        course_url = reverse(course_url_name,
                             kwargs={'course_id': unicode(course.id)})

        is_verified = CourseEnrollment.is_enrolled_as_verified(
            request.user, course_key)
        has_access = is_verified or request.user.is_staff

        enrollment = CourseEnrollment.get_enrollment(request.user, course_key)

        upgrade_price = None
        upgrade_url = None

        if enrollment and enrollment.upgrade_deadline:
            upgrade_url = EcommerceService().upgrade_url(
                request.user, course_key)
            upgrade_price = get_cosmetic_verified_display_price(course)

        context = {
            'upgrade_price': upgrade_price,
            'upgrade_link': upgrade_url,
            'course': course,
            'course_url': course_url,
            'disable_courseware_js': True,
            'uses_pattern_library': True,
            'is_self_paced': course.self_paced,
            'is_verified': is_verified,
            'has_access': has_access,
        }

        if (has_access):
            grading_policy = course.grading_policy

            (raw_grade_data, answered_percent,
             percent_grade) = self.get_grade_data(
                 request.user, course_key, grading_policy['GRADE_CUTOFFS'])
            raw_schedule_data = self.get_assignments_with_due_date(
                request, course_key)

            grade_data, schedule_data = self.sort_grade_and_schedule_data(
                raw_grade_data, raw_schedule_data)

            # TODO: LEARNER-3854: Fix hacked defaults with real error handling if implementing Learner Analytics.
            try:
                weekly_active_users = self.get_weekly_course_activity_count(
                    course_key)
                week_streak = self.consecutive_weeks_of_course_activity_for_user(
                    request.user.username, course_key)
            except Exception as e:
                logging.exception(e)
                weekly_active_users = 134
                week_streak = 1

            context.update({
                'grading_policy':
                grading_policy,
                'assignment_grades':
                grade_data,
                'answered_percent':
                answered_percent,
                'assignment_schedule':
                schedule_data,
                'assignment_schedule_raw':
                raw_schedule_data,
                'profile_image_urls':
                get_profile_image_urls_for_user(request.user, request),
                'discussion_info':
                self.get_discussion_data(request, course_key),
                'passing_grade':
                math.ceil(100 * course.lowest_passing_grade),
                'percent_grade':
                math.ceil(100 * percent_grade),
                'weekly_active_users':
                weekly_active_users,
                'week_streak':
                week_streak,
            })

        return render_to_response('learner_analytics/dashboard.html', context)
Ejemplo n.º 18
0
    def get(self, request, course_id):
        """
        Displays the user's Learner Analytics for the specified course.

        Arguments:
            request: HTTP request
            course_id (unicode): course id
        """
        course_key = CourseKey.from_string(course_id)
        if not ENABLE_DASHBOARD_TAB.is_enabled(course_key):
            raise Http404

        course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)
        course_url_name = default_course_url_name(course.id)
        course_url = reverse(course_url_name, kwargs={'course_id': unicode(course.id)})

        is_verified = CourseEnrollment.is_enrolled_as_verified(request.user, course_key)
        has_access = is_verified or request.user.is_staff

        enrollment = CourseEnrollment.get_enrollment(request.user, course_key)

        upgrade_price = None
        upgrade_url = None

        if enrollment and enrollment.upgrade_deadline:
            upgrade_url = EcommerceService().upgrade_url(request.user, course_key)
            upgrade_price = get_cosmetic_verified_display_price(course)

        context = {
            'upgrade_price': upgrade_price,
            'upgrade_link': upgrade_url,
            'course': course,
            'course_url': course_url,
            'disable_courseware_js': True,
            'uses_pattern_library': True,
            'is_self_paced': course.self_paced,
            'is_verified': is_verified,
            'has_access': has_access,
        }

        if (has_access):
            grading_policy = course.grading_policy

            (raw_grade_data, answered_percent, percent_grade) = self.get_grade_data(request.user, course_key, grading_policy['GRADE_CUTOFFS'])
            raw_schedule_data = self.get_assignments_with_due_date(request, course_key)

            grade_data, schedule_data = self.sort_grade_and_schedule_data(raw_grade_data, raw_schedule_data)

            # TODO: LEARNER-3854: Fix hacked defaults with real error handling if implementing Learner Analytics.
            try:
                weekly_active_users = self.get_weekly_course_activity_count(course_key)
                week_streak = self.consecutive_weeks_of_course_activity_for_user(
                    request.user.username, course_key
                )
            except Exception as e:
                logging.exception(e)
                weekly_active_users = 134
                week_streak = 1

            context.update({
                'grading_policy': grading_policy,
                'assignment_grades': grade_data,
                'answered_percent': answered_percent,
                'assignment_schedule': schedule_data,
                'assignment_schedule_raw': raw_schedule_data,
                'profile_image_urls': get_profile_image_urls_for_user(request.user, request),
                'discussion_info': self.get_discussion_data(request, course_key),
                'passing_grade': math.ceil(100 * course.lowest_passing_grade),
                'percent_grade': math.ceil(100 * percent_grade),
                'weekly_active_users': weekly_active_users,
                'week_streak': week_streak,
            })

        return render_to_response('learner_analytics/dashboard.html', context)