Skip to content

Commit

Permalink
feat: add support for weight and points settings (#27)
Browse files Browse the repository at this point in the history
* feat: add support for weight and points settings
  • Loading branch information
Ian2012 committed Oct 11, 2023
1 parent 1e72a46 commit 9feaef9
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 3 deletions.
65 changes: 62 additions & 3 deletions h5pxblock/h5pxblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

from xblock.completable import CompletableXBlockMixin
from xblock.core import XBlock
from xblock.fields import Scope, String, Boolean, Integer, Dict, DateTime, UNIQUE_ID
from xblock.exceptions import JsonHandlerError
from xblock.fields import Float, Scope, String, Boolean, Integer, Dict, DateTime, UNIQUE_ID
from xblock.fragment import Fragment
from xblockutils.resources import ResourceLoader

Expand Down Expand Up @@ -109,6 +110,24 @@ class H5PPlayerXBlock(XBlock, CompletableXBlockMixin):
scope=Scope.user_state
)

weight = Float(
display_name=_("Problem Weight"),
help=_(
"Defines the number of points this problem is worth. If "
"the value is not set, the problem is worth one point."
),
values={"min": 0, "step": 0.1},
scope=Scope.settings,
default=1.0,
)

points = Integer(
display_name=_("Maximum score"),
help=_("Maximum grade score given to assignment by staff."),
default=100,
scope=Scope.settings,
)

h5p_content_meta = Dict(scope=Scope.content)
#has_author_view = True

Expand All @@ -134,6 +153,9 @@ def render_template(self, template_path, context):
context,
i18n_service=self.runtime.service(self, 'i18n'),
)

def max_score(self):
return self.points

@property
def store_content_on_local_fs(self):
Expand Down Expand Up @@ -173,6 +195,8 @@ def get_context_studio(self):
"show_fullscreen": self.fields["show_fullscreen"],
"is_scorable": self.fields["has_score"],
"save_freq": self.fields["save_freq"],
"weight": self.fields["weight"],
"points": self.fields["points"],
"h5p_xblock": self,
}

Expand Down Expand Up @@ -258,6 +282,9 @@ def studio_submit(self, request, suffix=""):
self.has_score = str2bool(request.params["is_scorable"])
self.save_freq = request.params["save_freq"]
self.icon_class = "problem" if self.has_score else "h5p"
points = request.params["points"]
weight = request.params["weight"]
self.points, self.weight = self.validate_score(points, weight)

if hasattr(request.params["h5p_content_bundle"], "file"):
h5p_package = request.params["h5p_content_bundle"].file
Expand Down Expand Up @@ -285,6 +312,33 @@ def studio_submit(self, request, suffix=""):
charset="utf8",
)

@staticmethod
def validate_score(points: int, weight: int) -> None:
"""
Validate a score.
Args:
score (int): The score to validate.
max_score (int): The maximum score.
"""
try:
points = int(points)
except ValueError as exc:
raise JsonHandlerError(400, "Points must be an integer") from exc

if points < 0:
raise JsonHandlerError(400, "Points must be a positive integer")

if weight:
try:
weight = float(weight)
except ValueError as exc:
raise JsonHandlerError(400, "Weight must be a decimal number") from exc
if weight < 0:
raise JsonHandlerError(400, "Weight must be a positive decimal number")

return points, weight

@XBlock.json_handler
def result_handler(self, data, suffix=''):
"""
Expand All @@ -298,9 +352,14 @@ def result_handler(self, data, suffix=''):
log.error("Error while marking completion %s", exp)

if self.has_score and data['result'] and data['result']['score']:
raw_score = data['result']['score']['raw']
max_score = data['result']['score']['max']
score = 0
if max_score:
score = raw_score/max_score * self.points
grade_dict = {
'value': data['result']['score']['raw'],
'max_value': data['result']['score']['max'],
'value': score,
'max_value': self.points,
'only_if_higher': True,
}
try:
Expand Down
14 changes: 14 additions & 0 deletions h5pxblock/static/html/studio.html
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,20 @@
</div>
<span class="tip setting-help">{% trans is_scorable.help %}</span>
</li>
<li class="field comp-setting-entry is-set scorable">
<div class="wrapper-comp-setting">
<label class="label setting-label" for="xb_weight">{% trans weight.display_name %}</label>
<input class="input setting-input" name="xb_weight" id="xb_weight" value="{{ h5p_xblock.weight }}" type="text" />
</div>
<span class="tip setting-help">{% trans weight.help %}</span>
</li>
<li class="field comp-setting-entry is-set scorable">
<div class="wrapper-comp-setting">
<label class="label setting-label" for="xb_points">{% trans points.display_name %}</label>
<input class="input setting-input" name="xb_points" id="xb_points" value="{{ h5p_xblock.points }}" type="text" />
</div>
<span class="tip setting-help">{% trans points.help %}</span>
</li>
<li class="field comp-setting-entry is-set">
<div class="wrapper-comp-setting">
<label class="label setting-label" for="xb_field_edit_save_freq">{% trans save_freq.display_name %}</label>
Expand Down
19 changes: 19 additions & 0 deletions h5pxblock/static/js/src/studio.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ function H5PStudioXBlock(runtime, element, args) {
)
});

if ($('#xb_field_edit_is_scorable').val() == '1'){
$(element).find('.scorable').show();
}else{
$(element).find('.scorable').hide();
}

$('#xb_field_edit_is_scorable').change(function() {
if($(this).val() == '1') {
$(element).find('.scorable').show();
}
else {
$(element).find('.scorable').hide();
}
});

$(element).find('.save-button').bind('click', function () {
var form_data = new FormData();
var h5p_content_bundle = $(element).find('#xb_h5p_file').prop('files')[0];
Expand All @@ -41,6 +56,8 @@ function H5PStudioXBlock(runtime, element, args) {
var is_scorable = $(element).find('#xb_field_edit_is_scorable').val();
var save_freq = $(element).find('#xb_field_edit_save_freq').val();
var h5_content_path = $(element).find('#xb_existing_content_path').val();
var weight = $(element).find('input[name=xb_weight]').val();
var points = $(element).find('input[name=xb_points]').val();

form_data.append('h5p_content_bundle', h5p_content_bundle);
form_data.append('display_name', display_name);
Expand All @@ -51,6 +68,8 @@ function H5PStudioXBlock(runtime, element, args) {
form_data.append('is_scorable', is_scorable);
form_data.append('save_freq', save_freq);
form_data.append('h5_content_path', h5_content_path);
form_data.append('weight', weight);
form_data.append('points', points);

if ('notify' in runtime) { //xblock workbench runtime does not have `notify` method
runtime.notify('save', { state: 'start' });
Expand Down

0 comments on commit 9feaef9

Please sign in to comment.