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}
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 }
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')
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
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
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)() })
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
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
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
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()
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)
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
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
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
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)
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)