refactor: rename descriptor -> block within cms
Co-authored-by: Agrendalath <piotr@surowiec.it>
This commit is contained in:
committed by
Agrendalath
parent
a2f1ad1f11
commit
ce13cd540a
@@ -25,21 +25,21 @@ class CourseGradingModel:
|
||||
"""
|
||||
# Within this class, allow access to protected members of client classes.
|
||||
# This comes up when accessing kvs data and caches during kvs saves and modulestore writes.
|
||||
def __init__(self, course_descriptor):
|
||||
def __init__(self, course):
|
||||
self.graders = [
|
||||
CourseGradingModel.jsonize_grader(i, grader) for i, grader in enumerate(course_descriptor.raw_grader)
|
||||
CourseGradingModel.jsonize_grader(i, grader) for i, grader in enumerate(course.raw_grader)
|
||||
] # weights transformed to ints [0..100]
|
||||
self.grade_cutoffs = course_descriptor.grade_cutoffs
|
||||
self.grace_period = CourseGradingModel.convert_set_grace_period(course_descriptor)
|
||||
self.minimum_grade_credit = course_descriptor.minimum_grade_credit
|
||||
self.grade_cutoffs = course.grade_cutoffs
|
||||
self.grace_period = CourseGradingModel.convert_set_grace_period(course)
|
||||
self.minimum_grade_credit = course.minimum_grade_credit
|
||||
|
||||
@classmethod
|
||||
def fetch(cls, course_key):
|
||||
"""
|
||||
Fetch the course grading policy for the given course from persistence and return a CourseGradingModel.
|
||||
"""
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
model = cls(descriptor)
|
||||
course = modulestore().get_course(course_key)
|
||||
model = cls(course)
|
||||
return model
|
||||
|
||||
@staticmethod
|
||||
@@ -48,10 +48,10 @@ class CourseGradingModel:
|
||||
Fetch the course's nth grader
|
||||
Returns an empty dict if there's no such grader.
|
||||
"""
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
course = modulestore().get_course(course_key)
|
||||
index = int(index)
|
||||
if len(descriptor.raw_grader) > index:
|
||||
return CourseGradingModel.jsonize_grader(index, descriptor.raw_grader[index])
|
||||
if len(course.raw_grader) > index:
|
||||
return CourseGradingModel.jsonize_grader(index, course.raw_grader[index])
|
||||
|
||||
# return empty model
|
||||
else:
|
||||
@@ -69,27 +69,27 @@ class CourseGradingModel:
|
||||
Decode the json into CourseGradingModel and save any changes. Returns the modified model.
|
||||
Probably not the usual path for updates as it's too coarse grained.
|
||||
"""
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
previous_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy))
|
||||
course = modulestore().get_course(course_key)
|
||||
previous_grading_policy_hash = str(hash_grading_policy(course.grading_policy))
|
||||
|
||||
graders_parsed = [CourseGradingModel.parse_grader(jsonele) for jsonele in jsondict['graders']]
|
||||
fire_signal = CourseGradingModel.must_fire_grading_event_and_signal(
|
||||
course_key,
|
||||
graders_parsed,
|
||||
descriptor,
|
||||
course,
|
||||
jsondict
|
||||
)
|
||||
descriptor.raw_grader = graders_parsed
|
||||
descriptor.grade_cutoffs = jsondict['grade_cutoffs']
|
||||
course.raw_grader = graders_parsed
|
||||
course.grade_cutoffs = jsondict['grade_cutoffs']
|
||||
|
||||
modulestore().update_item(descriptor, user.id)
|
||||
modulestore().update_item(course, user.id)
|
||||
|
||||
CourseGradingModel.update_grace_period_from_json(course_key, jsondict['grace_period'], user)
|
||||
|
||||
CourseGradingModel.update_minimum_grade_credit_from_json(course_key, jsondict['minimum_grade_credit'], user)
|
||||
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
new_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy))
|
||||
course = modulestore().get_course(course_key)
|
||||
new_grading_policy_hash = str(hash_grading_policy(course.grading_policy))
|
||||
log.info(
|
||||
"Updated course grading policy for course %s from %s to %s. fire_signal = %s",
|
||||
str(course_key),
|
||||
@@ -153,28 +153,28 @@ class CourseGradingModel:
|
||||
Create or update the grader of the given type (string key) for the given course. Returns the modified
|
||||
grader which is a full model on the client but not on the server (just a dict)
|
||||
"""
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
previous_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy))
|
||||
course = modulestore().get_course(course_key)
|
||||
previous_grading_policy_hash = str(hash_grading_policy(course.grading_policy))
|
||||
|
||||
# parse removes the id; so, grab it before parse
|
||||
index = int(grader.get('id', len(descriptor.raw_grader)))
|
||||
index = int(grader.get('id', len(course.raw_grader)))
|
||||
grader = CourseGradingModel.parse_grader(grader)
|
||||
|
||||
fire_signal = True
|
||||
if index < len(descriptor.raw_grader):
|
||||
if index < len(course.raw_grader):
|
||||
fire_signal = CourseGradingModel.must_fire_grading_event_and_signal_single_grader(
|
||||
course_key,
|
||||
grader,
|
||||
descriptor.raw_grader[index]
|
||||
course.raw_grader[index]
|
||||
)
|
||||
descriptor.raw_grader[index] = grader
|
||||
course.raw_grader[index] = grader
|
||||
else:
|
||||
descriptor.raw_grader.append(grader)
|
||||
course.raw_grader.append(grader)
|
||||
|
||||
modulestore().update_item(descriptor, user.id)
|
||||
modulestore().update_item(course, user.id)
|
||||
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
new_grading_policy_hash = str(hash_grading_policy(descriptor.grading_policy))
|
||||
course = modulestore().get_course(course_key)
|
||||
new_grading_policy_hash = str(hash_grading_policy(course.grading_policy))
|
||||
log.info(
|
||||
"Updated grader for course %s. Grading policy has changed from %s to %s. fire_signal = %s",
|
||||
str(course_key),
|
||||
@@ -185,7 +185,7 @@ class CourseGradingModel:
|
||||
if fire_signal:
|
||||
_grading_event_and_signal(course_key, user.id)
|
||||
|
||||
return CourseGradingModel.jsonize_grader(index, descriptor.raw_grader[index])
|
||||
return CourseGradingModel.jsonize_grader(index, course.raw_grader[index])
|
||||
|
||||
@staticmethod
|
||||
def update_cutoffs_from_json(course_key, cutoffs, user):
|
||||
@@ -193,10 +193,10 @@ class CourseGradingModel:
|
||||
Create or update the grade cutoffs for the given course. Returns sent in cutoffs (ie., no extra
|
||||
db fetch).
|
||||
"""
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
descriptor.grade_cutoffs = cutoffs
|
||||
course = modulestore().get_course(course_key)
|
||||
course.grade_cutoffs = cutoffs
|
||||
|
||||
modulestore().update_item(descriptor, user.id)
|
||||
modulestore().update_item(course, user.id)
|
||||
_grading_event_and_signal(course_key, user.id)
|
||||
return cutoffs
|
||||
|
||||
@@ -207,7 +207,7 @@ class CourseGradingModel:
|
||||
grace_period entry in an enclosing dict. It is also safe to call this method with a value of
|
||||
None for graceperiodjson.
|
||||
"""
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
course = modulestore().get_course(course_key)
|
||||
|
||||
# Before a graceperiod has ever been created, it will be None (once it has been
|
||||
# created, it cannot be set back to None).
|
||||
@@ -216,9 +216,9 @@ class CourseGradingModel:
|
||||
graceperiodjson = graceperiodjson['grace_period']
|
||||
|
||||
grace_timedelta = timedelta(**graceperiodjson)
|
||||
descriptor.graceperiod = grace_timedelta
|
||||
course.graceperiod = grace_timedelta
|
||||
|
||||
modulestore().update_item(descriptor, user.id)
|
||||
modulestore().update_item(course, user.id)
|
||||
|
||||
@staticmethod
|
||||
def update_minimum_grade_credit_from_json(course_key, minimum_grade_credit, user):
|
||||
@@ -230,29 +230,29 @@ class CourseGradingModel:
|
||||
user(User): The user object
|
||||
|
||||
"""
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
course = modulestore().get_course(course_key)
|
||||
|
||||
# 'minimum_grade_credit' cannot be set to None
|
||||
if minimum_grade_credit is not None:
|
||||
minimum_grade_credit = minimum_grade_credit # lint-amnesty, pylint: disable=self-assigning-variable
|
||||
|
||||
descriptor.minimum_grade_credit = minimum_grade_credit
|
||||
modulestore().update_item(descriptor, user.id)
|
||||
course.minimum_grade_credit = minimum_grade_credit
|
||||
modulestore().update_item(course, user.id)
|
||||
|
||||
@staticmethod
|
||||
def delete_grader(course_key, index, user):
|
||||
"""
|
||||
Delete the grader of the given type from the given course.
|
||||
"""
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
course = modulestore().get_course(course_key)
|
||||
|
||||
index = int(index)
|
||||
if index < len(descriptor.raw_grader):
|
||||
del descriptor.raw_grader[index]
|
||||
if index < len(course.raw_grader):
|
||||
del course.raw_grader[index]
|
||||
# force propagation to definition
|
||||
descriptor.raw_grader = descriptor.raw_grader
|
||||
course.raw_grader = course.raw_grader
|
||||
|
||||
modulestore().update_item(descriptor, user.id)
|
||||
modulestore().update_item(course, user.id)
|
||||
_grading_event_and_signal(course_key, user.id)
|
||||
|
||||
@staticmethod
|
||||
@@ -260,37 +260,37 @@ class CourseGradingModel:
|
||||
"""
|
||||
Delete the course's grace period.
|
||||
"""
|
||||
descriptor = modulestore().get_course(course_key)
|
||||
course = modulestore().get_course(course_key)
|
||||
|
||||
del descriptor.graceperiod
|
||||
del course.graceperiod
|
||||
|
||||
modulestore().update_item(descriptor, user.id)
|
||||
modulestore().update_item(course, user.id)
|
||||
|
||||
@staticmethod
|
||||
def get_section_grader_type(location):
|
||||
descriptor = modulestore().get_item(location)
|
||||
block = modulestore().get_item(location)
|
||||
return {
|
||||
"graderType": descriptor.format if descriptor.format is not None else 'notgraded',
|
||||
"graderType": block.format if block.format is not None else 'notgraded',
|
||||
"location": str(location),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def update_section_grader_type(descriptor, grader_type, user): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
def update_section_grader_type(block, grader_type, user): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
if grader_type is not None and grader_type != 'notgraded':
|
||||
descriptor.format = grader_type
|
||||
descriptor.graded = True
|
||||
block.format = grader_type
|
||||
block.graded = True
|
||||
else:
|
||||
del descriptor.format
|
||||
del descriptor.graded
|
||||
del block.format
|
||||
del block.graded
|
||||
|
||||
modulestore().update_item(descriptor, user.id)
|
||||
_grading_event_and_signal(descriptor.location.course_key, user.id)
|
||||
modulestore().update_item(block, user.id)
|
||||
_grading_event_and_signal(block.location.course_key, user.id)
|
||||
return {'graderType': grader_type}
|
||||
|
||||
@staticmethod
|
||||
def convert_set_grace_period(descriptor): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
def convert_set_grace_period(course): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
# 5 hours 59 minutes 59 seconds => converted to iso format
|
||||
rawgrace = descriptor.graceperiod
|
||||
rawgrace = course.graceperiod
|
||||
if rawgrace:
|
||||
hours_from_days = rawgrace.days * 24
|
||||
seconds = rawgrace.seconds
|
||||
|
||||
@@ -155,14 +155,14 @@ class CourseMetadata:
|
||||
return exclude_list
|
||||
|
||||
@classmethod
|
||||
def fetch(cls, descriptor, filter_fields=None):
|
||||
def fetch(cls, block, filter_fields=None):
|
||||
"""
|
||||
Fetch the key:value editable course details for the given course from
|
||||
persistence and return a CourseMetadata model.
|
||||
"""
|
||||
result = {}
|
||||
metadata = cls.fetch_all(descriptor, filter_fields=filter_fields)
|
||||
exclude_list_of_fields = cls.get_exclude_list_of_fields(descriptor.id)
|
||||
metadata = cls.fetch_all(block, filter_fields=filter_fields)
|
||||
exclude_list_of_fields = cls.get_exclude_list_of_fields(block.id)
|
||||
|
||||
for key, value in metadata.items():
|
||||
if key in exclude_list_of_fields:
|
||||
@@ -171,12 +171,12 @@ class CourseMetadata:
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def fetch_all(cls, descriptor, filter_fields=None):
|
||||
def fetch_all(cls, block, filter_fields=None):
|
||||
"""
|
||||
Fetches all key:value pairs from persistence and returns a CourseMetadata model.
|
||||
"""
|
||||
result = {}
|
||||
for field in descriptor.fields.values():
|
||||
for field in block.fields.values():
|
||||
if field.scope != Scope.settings:
|
||||
continue
|
||||
|
||||
@@ -189,7 +189,7 @@ class CourseMetadata:
|
||||
field_help = field_help.format(**help_args)
|
||||
|
||||
result[field.name] = {
|
||||
'value': field.read_json(descriptor),
|
||||
'value': field.read_json(block),
|
||||
'display_name': _(field.display_name), # lint-amnesty, pylint: disable=translation-of-non-string
|
||||
'help': field_help,
|
||||
'deprecated': field.runtime_options.get('deprecated', False),
|
||||
@@ -198,13 +198,13 @@ class CourseMetadata:
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def update_from_json(cls, descriptor, jsondict, user, filter_tabs=True):
|
||||
def update_from_json(cls, block, jsondict, user, filter_tabs=True):
|
||||
"""
|
||||
Decode the json into CourseMetadata and save any changed attrs to the db.
|
||||
|
||||
Ensures none of the fields are in the exclude list.
|
||||
"""
|
||||
exclude_list_of_fields = cls.get_exclude_list_of_fields(descriptor.id)
|
||||
exclude_list_of_fields = cls.get_exclude_list_of_fields(block.id)
|
||||
# Don't filter on the tab attribute if filter_tabs is False.
|
||||
if not filter_tabs:
|
||||
exclude_list_of_fields.remove("tabs")
|
||||
@@ -218,16 +218,16 @@ class CourseMetadata:
|
||||
continue
|
||||
try:
|
||||
val = model['value']
|
||||
if hasattr(descriptor, key) and getattr(descriptor, key) != val:
|
||||
key_values[key] = descriptor.fields[key].from_json(val)
|
||||
if hasattr(block, key) and getattr(block, key) != val:
|
||||
key_values[key] = block.fields[key].from_json(val)
|
||||
except (TypeError, ValueError) as err:
|
||||
raise ValueError(_("Incorrect format for field '{name}'. {detailed_message}").format( # lint-amnesty, pylint: disable=raise-missing-from
|
||||
name=model['display_name'], detailed_message=str(err)))
|
||||
|
||||
return cls.update_from_dict(key_values, descriptor, user)
|
||||
return cls.update_from_dict(key_values, block, user)
|
||||
|
||||
@classmethod
|
||||
def validate_and_update_from_json(cls, descriptor, jsondict, user, filter_tabs=True):
|
||||
def validate_and_update_from_json(cls, block, jsondict, user, filter_tabs=True):
|
||||
"""
|
||||
Validate the values in the json dict (validated by xblock fields from_json method)
|
||||
|
||||
@@ -240,7 +240,7 @@ class CourseMetadata:
|
||||
errors: list of error objects
|
||||
result: the updated course metadata or None if error
|
||||
"""
|
||||
exclude_list_of_fields = cls.get_exclude_list_of_fields(descriptor.id)
|
||||
exclude_list_of_fields = cls.get_exclude_list_of_fields(block.id)
|
||||
|
||||
if not filter_tabs:
|
||||
exclude_list_of_fields.remove("tabs")
|
||||
@@ -254,8 +254,8 @@ class CourseMetadata:
|
||||
for key, model in filtered_dict.items():
|
||||
try:
|
||||
val = model['value']
|
||||
if hasattr(descriptor, key) and getattr(descriptor, key) != val:
|
||||
key_values[key] = descriptor.fields[key].from_json(val)
|
||||
if hasattr(block, key) and getattr(block, key) != val:
|
||||
key_values[key] = block.fields[key].from_json(val)
|
||||
except (TypeError, ValueError, ValidationError) as err:
|
||||
did_validate = False
|
||||
errors.append({'key': key, 'message': str(err), 'model': model})
|
||||
@@ -264,7 +264,7 @@ class CourseMetadata:
|
||||
# Because we cannot pass course context to the exception, we need to check if the LTI provider
|
||||
# should actually be available to the course
|
||||
err_message = str(err)
|
||||
if not exams_ida_enabled(descriptor.id):
|
||||
if not exams_ida_enabled(block.id):
|
||||
available_providers = get_available_providers()
|
||||
available_providers.remove('lti_external')
|
||||
err_message = str(InvalidProctoringProvider(val, available_providers))
|
||||
@@ -277,29 +277,29 @@ class CourseMetadata:
|
||||
errors = errors + team_setting_errors
|
||||
did_validate = False
|
||||
|
||||
proctoring_errors = cls.validate_proctoring_settings(descriptor, filtered_dict, user)
|
||||
proctoring_errors = cls.validate_proctoring_settings(block, filtered_dict, user)
|
||||
if proctoring_errors:
|
||||
errors = errors + proctoring_errors
|
||||
did_validate = False
|
||||
|
||||
# If did validate, go ahead and update the metadata
|
||||
if did_validate:
|
||||
updated_data = cls.update_from_dict(key_values, descriptor, user, save=False)
|
||||
updated_data = cls.update_from_dict(key_values, block, user, save=False)
|
||||
|
||||
return did_validate, errors, updated_data
|
||||
|
||||
@classmethod
|
||||
def update_from_dict(cls, key_values, descriptor, user, save=True):
|
||||
def update_from_dict(cls, key_values, block, user, save=True):
|
||||
"""
|
||||
Update metadata descriptor from key_values. Saves to modulestore if save is true.
|
||||
Update metadata from key_values. Saves to modulestore if save is true.
|
||||
"""
|
||||
for key, value in key_values.items():
|
||||
setattr(descriptor, key, value)
|
||||
setattr(block, key, value)
|
||||
|
||||
if save and key_values:
|
||||
modulestore().update_item(descriptor, user.id)
|
||||
modulestore().update_item(block, user.id)
|
||||
|
||||
return cls.fetch(descriptor)
|
||||
return cls.fetch(block)
|
||||
|
||||
@classmethod
|
||||
def validate_team_settings(cls, settings_dict):
|
||||
@@ -397,7 +397,7 @@ class CourseMetadata:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def validate_proctoring_settings(cls, descriptor, settings_dict, user):
|
||||
def validate_proctoring_settings(cls, block, settings_dict, user):
|
||||
"""
|
||||
Verify proctoring settings
|
||||
|
||||
@@ -412,9 +412,9 @@ class CourseMetadata:
|
||||
if (
|
||||
not user.is_staff and
|
||||
cls._has_requested_proctoring_provider_changed(
|
||||
descriptor.proctoring_provider, proctoring_provider_model.get('value')
|
||||
block.proctoring_provider, proctoring_provider_model.get('value')
|
||||
) and
|
||||
datetime.now(pytz.UTC) > descriptor.start
|
||||
datetime.now(pytz.UTC) > block.start
|
||||
):
|
||||
message = (
|
||||
'The proctoring provider cannot be modified after a course has started.'
|
||||
@@ -426,7 +426,7 @@ class CourseMetadata:
|
||||
# should only be allowed if the exams IDA is enabled for a course
|
||||
available_providers = get_available_providers()
|
||||
updated_provider = settings_dict.get('proctoring_provider', {}).get('value')
|
||||
if updated_provider == 'lti_external' and not exams_ida_enabled(descriptor.id):
|
||||
if updated_provider == 'lti_external' and not exams_ida_enabled(block.id):
|
||||
available_providers.remove('lti_external')
|
||||
error = InvalidProctoringProvider('lti_external', available_providers)
|
||||
errors.append({'key': 'proctoring_provider', 'message': str(error), 'model': proctoring_provider_model})
|
||||
@@ -435,7 +435,7 @@ class CourseMetadata:
|
||||
if enable_proctoring_model:
|
||||
enable_proctoring = enable_proctoring_model.get('value')
|
||||
else:
|
||||
enable_proctoring = descriptor.enable_proctored_exams
|
||||
enable_proctoring = block.enable_proctored_exams
|
||||
|
||||
if enable_proctoring:
|
||||
# Require a valid escalation email if Proctortrack is chosen as the proctoring provider
|
||||
@@ -443,12 +443,12 @@ class CourseMetadata:
|
||||
if escalation_email_model:
|
||||
escalation_email = escalation_email_model.get('value')
|
||||
else:
|
||||
escalation_email = descriptor.proctoring_escalation_email
|
||||
escalation_email = block.proctoring_escalation_email
|
||||
|
||||
if proctoring_provider_model:
|
||||
proctoring_provider = proctoring_provider_model.get('value')
|
||||
else:
|
||||
proctoring_provider = descriptor.proctoring_provider
|
||||
proctoring_provider = block.proctoring_provider
|
||||
|
||||
missing_escalation_email_msg = 'Provider \'{provider}\' requires an exam escalation contact.'
|
||||
if proctoring_provider_model and proctoring_provider == 'proctortrack':
|
||||
@@ -477,7 +477,7 @@ class CourseMetadata:
|
||||
if zendesk_ticket_model:
|
||||
create_zendesk_tickets = zendesk_ticket_model.get('value')
|
||||
else:
|
||||
create_zendesk_tickets = descriptor.create_zendesk_tickets
|
||||
create_zendesk_tickets = block.create_zendesk_tickets
|
||||
|
||||
if (
|
||||
(proctoring_provider == 'proctortrack' and create_zendesk_tickets)
|
||||
@@ -489,7 +489,7 @@ class CourseMetadata:
|
||||
'should be updated for this course.'.format(
|
||||
ticket_value=create_zendesk_tickets,
|
||||
provider=proctoring_provider,
|
||||
course_id=descriptor.id
|
||||
course_id=block.id
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user