Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove score page #408

Merged
merged 5 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions common/lib/xmodule/xmodule/course_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -681,10 +681,10 @@ class CourseFields: # lint-amnesty, pylint: disable=missing-class-docstring
# until we get grade integration set up.
# Explicit comparison to True because we always want to return a bool.
hide_progress_tab = Boolean(
display_name=_("Hide Progress Tab"),
help=_("Allows hiding of the progress tab."),
display_name=_("Hide Score Tab"),
help=_("Allows hiding of the score tab."),
scope=Scope.settings,
deprecated=True
default=True
)

display_organization = String(
Expand Down
25 changes: 25 additions & 0 deletions openedx/features/wikimedia_features/progress_tab/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
Progress Tab App Config
"""
from django.apps import AppConfig
from edx_django_utils.plugins import PluginURLs, PluginSettings
from openedx.core.djangoapps.plugins.constants import ProjectType, SettingsType


class ProgressTabConfig(AppConfig):
name = 'openedx.features.wikimedia_features.progress_tab'

plugin_app = {
PluginURLs.CONFIG: {
ProjectType.LMS: {
PluginURLs.NAMESPACE: 'progress_tab',
PluginURLs.REGEX: '^progress_tab/',
PluginURLs.RELATIVE_PATH: 'urls',
},
},
PluginSettings.CONFIG: {
ProjectType.LMS: {
SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: 'settings.common'},
},
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

"""Settings"""


def plugin_settings(settings):
"""
Required Common settings
"""
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from django.conf import settings
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_noop

Expand All @@ -10,11 +9,13 @@ class WikimediaProgressTab(TabFragmentViewMixin, EnrolledTab):
type = 'wikimedia_progress_tab'
title = ugettext_noop('Progress')
priority = None
fragment_view_name = 'openedx.features.wikimedia_features.wikimedia_general.views.WikimediaProgressFragmentView'
fragment_view_name = 'openedx.features.wikimedia_features.progress_tab.views.WikimediaProgressFragmentView'
is_hideable = False
is_default = True
body_class = 'wikimedia_progress'

@classmethod
def is_enabled(cls, course, user=None):
if not super().is_enabled(course, user=user):
return False
return True
13 changes: 13 additions & 0 deletions openedx/features/wikimedia_features/progress_tab/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django.conf.urls import url, include

from .views import WikimediaProgressFragmentView

app_name = 'progress_tab'

urlpatterns = [
url(
r'progress_fragment_view$',
WikimediaProgressFragmentView.as_view(),
name='progress_fragment_view'
),
]
139 changes: 139 additions & 0 deletions openedx/features/wikimedia_features/progress_tab/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
from opaque_keys.edx.keys import CourseKey
from django.template.loader import render_to_string
from web_fragments.fragment import Fragment
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
from completion.models import BlockCompletion
from openedx.features.course_experience.utils import get_course_outline_block_tree
from lms.djangoapps.courseware.courses import get_course_blocks_completion_summary, get_course_with_access
from lms.djangoapps.courseware.views.views import get_cert_data
from lms.djangoapps.grades.api import CourseGradeFactory
from common.djangoapps.student.models import CourseEnrollment

class WikimediaProgressFragmentView(EdxFragmentView):
"""
View to render Wikimedia course progress tab
"""
def _get_grade_dict(self, course_grade):
"""
Extract grade dict in following format from edX grade classes for subsections and problem components.
{
"subsection1_block_id": {
"score": 1/2,
"graded": True
},
"problem1_block_id": {
"score": 1/1,
"graded": True
},
"problem2_block_id": {
"score": 0/1,
"graded": True
}
}
"""
data = {}
if not course_grade:
return data

for chapter in course_grade.chapter_grades.values():
subsections = chapter.get('sections', [])
for subsection in subsections:
subsection_grade = subsection.graded_total
subsection_score = "-"
if subsection_grade and subsection_grade.possible:
subsection_score = "{}/{}".format(round(subsection_grade.earned), round(subsection_grade.possible))
data.update({str(subsection.location): {
'score': subsection_score,
'graded': subsection_grade.graded
}})
for problem_location, problem_grade in subsection.problem_scores.items():
data.update({str(problem_location): {
'score': "{}/{}".format(round(problem_grade.earned), round(problem_grade.possible)),
'graded': problem_grade.graded,
}})
return data

def _update_context_with_score_and_progress(self, block, grade_dict):
"""
Update given block dict with grade and progress percentage info.
"""
if not block:
return

block_grade_data = grade_dict.get(block.get('id'))
if block_grade_data:
block.update(block_grade_data)

progress = 0
unit_count = 0
children = block.get('children', [])
if not len(children):
# Mark Excluded xblocks as completed
if block.get('type') in ['discussion']:
block.update({'complete': True, 'is_excluded_block': True})

if block.get('complete'):
progress = 100

# handle case of empty sections/subsections/units
if block.get('type') not in ['course', 'chapter', 'vertical', 'sequential']:
unit_count = 1

block.update({
'progress': progress,
'unit_count': unit_count,
})

for child in children:
self._update_context_with_score_and_progress(child, grade_dict)
if not child.get('is_excluded_block', False):
progress += child.get('progress', 0) * child.get('unit_count', 0)
unit_count += child.get('unit_count', 0)

if children and unit_count:
block.update({
'progress': round(progress/unit_count, 1),
'unit_count': unit_count
})

def render_to_fragment(self, request, course_id=None, **kwargs):
"""
Render wikimedia course progress to a fragment.
Args:
request: The Django request.
course_id: The id of the course in question.

Returns:
Fragment: The fragment representing the Wikimedia course progress
"""
course_key = CourseKey.from_string(course_id)
user = request.user
show_score_tab = False
cert_data = None
enrollment_mode, _ = CourseEnrollment.enrollment_mode_for_user(user, course_key)

try:
course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)
if hasattr(course, 'enable_score_tab_on_progress_page'):
show_score_tab = course.enable_score_tab_on_progress_page
course_grade = CourseGradeFactory().read(user, course)
grade_dict = self._get_grade_dict(course_grade)
cert_data = get_cert_data(user, course, enrollment_mode, course_grade)
except Exception as err:
grade_dict = {}

course_outline_context = get_course_outline_block_tree(request, course_id, user)
self._update_context_with_score_and_progress(course_outline_context, grade_dict)
html = render_to_string(
"wikimedia_general/wikimedia_progress_fragment.html",
{
"course_id": course_id,
"data": course_outline_context,
"show_score_tab": show_score_tab,
"certificate_data": cert_data,
},
)

fragment = Fragment(html)
self.add_fragment_resource_urls(fragment)
return fragment
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,50 @@
<%namespace name='static' file='../static_content.html'/>

<%!
from django.urls import reverse
from django.utils.translation import ugettext as _
from lms.djangoapps.certificates.data import CertificateStatuses
%>

<%block name="js_extra">
<script type="text/javascript" src="${static.url('js/courseware/certificates_api.js')}"></script>
</%block>

<div class="progress-content page-content-container">

<div class="page-content">
<div class="page-content-main" id="main-progress">
<div class="wrapper-msg wrapper-auto-cert">
<div id="errors-info" class="errors-info"></div>
<%block name="certificate_block">
%if certificate_data:
<div class="auto-cert-message" id="course-success">
<div class="has-actions container">
<% post_url = reverse('generate_user_cert', args=[course_id]) %>
<div class="row">
<div class="col col-md-6 col-lg-8">
<div class="msg-content">
<h3 class="hd hd-4 title">${_(certificate_data.title)}</h3>
<p class="copy">${_(certificate_data.msg)}</p>
</div>
</div>
<div class="col col-md-6 col-lg-4">
<div class="msg-actions">
%if certificate_data.cert_web_view_url:
<a class="btn btn-primary" href="${certificate_data.cert_web_view_url}" rel="noopener" target="_blank">${_("View Certificate")} <span class="sr">${_("Opens in a new browser window")}</span></a>
%elif certificate_data.cert_status == CertificateStatuses.downloadable and certificate_data.download_url:
<a class="btn btn-primary" href="${certificate_data.download_url}" rel="noopener" target="_blank">${_("Download Your Certificate")} <span class="sr">${_("Opens in a new browser window")}</span></a>
%elif certificate_data.cert_status == CertificateStatuses.requesting:
<button class="btn btn-primary generate_certs" data-endpoint="${post_url}" id="btn_generate_cert">${_('Request Certificate')}</button>
%endif
</div>
</div>
</div>
</div>
</div>
%endif
</%block>
</div>
% for section in data.get('children', []):
<div class="card section">
<div class="card-body">
Expand Down
7 changes: 0 additions & 7 deletions openedx/features/wikimedia_features/wikimedia_general/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,9 @@
"""
from django.conf.urls import url, include

from .views import WikimediaProgressFragmentView

app_name = 'wikimedia_general'

urlpatterns = [
url(
r'progress_fragment_view$',
WikimediaProgressFragmentView.as_view(),
name='progress_fragment_view'
),
url(
r'^api/v0/',
include('openedx.features.wikimedia_features.wikimedia_general.api.v0.urls', namespace='general_api_v0')
Expand Down
Loading