86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
"""
|
|
Score rendering when submission is evaluated for external grader and has been saved successfully
|
|
"""
|
|
|
|
import logging
|
|
from functools import partial
|
|
|
|
from django.http import Http404
|
|
from edx_when.field_data import DateLookupFieldData
|
|
from opaque_keys.edx.keys import CourseKey, UsageKey
|
|
from xblock.runtime import KvsFieldData
|
|
|
|
from common.djangoapps.student.models import AnonymousUserId
|
|
from lms.djangoapps.courseware.block_render import prepare_runtime_for_user
|
|
from lms.djangoapps.courseware.field_overrides import OverrideFieldData
|
|
from lms.djangoapps.courseware.model_data import DjangoKeyValueStore, FieldDataCache
|
|
from lms.djangoapps.lms_xblock.field_data import LmsFieldData
|
|
from xmodule.modulestore.django import modulestore
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
def load_xblock_for_external_grader(
|
|
user_id: str,
|
|
course_key: CourseKey,
|
|
usage_key: UsageKey,
|
|
course=None,
|
|
):
|
|
"""
|
|
Load a single XBlock for external grading without user access checks.
|
|
"""
|
|
|
|
user = AnonymousUserId.objects.get(anonymous_user_id=user_id).user
|
|
|
|
# pylint: disable=broad-exception-caught
|
|
try:
|
|
block = modulestore().get_item(usage_key)
|
|
except Exception as e:
|
|
log.exception("Could not find block %s in modulestore: %s", usage_key, e)
|
|
raise Http404(f"Module {usage_key} was not found") from e
|
|
|
|
field_data_cache = FieldDataCache.cache_for_block_descendents(course_key, user, block, depth=0)
|
|
|
|
student_kvs = DjangoKeyValueStore(field_data_cache)
|
|
student_data = KvsFieldData(student_kvs)
|
|
|
|
instance = get_block_for_descriptor_without_access_check(
|
|
user=user, block=block, student_data=student_data, course_key=course_key, course=course
|
|
)
|
|
|
|
if instance is None:
|
|
msg = f"Could not bind XBlock instance for usage key: {usage_key}"
|
|
log.error(msg)
|
|
raise Http404(msg)
|
|
|
|
return instance
|
|
|
|
|
|
def get_block_for_descriptor_without_access_check(user, block, student_data, course_key, course=None):
|
|
"""
|
|
Modified version of get_block_for_descriptor that skips access checks for system operations.
|
|
"""
|
|
|
|
prepare_runtime_for_user(
|
|
user=user,
|
|
student_data=student_data,
|
|
runtime=block.runtime,
|
|
course_id=course_key,
|
|
course=course,
|
|
track_function=lambda event_type, event: None,
|
|
request_token="external-grader-token",
|
|
position=None,
|
|
wrap_xblock_display=True,
|
|
)
|
|
|
|
block.bind_for_student(
|
|
user.id,
|
|
[
|
|
partial(DateLookupFieldData, course_id=course_key, user=user),
|
|
partial(OverrideFieldData.wrap, user, course),
|
|
partial(LmsFieldData, student_data=student_data),
|
|
],
|
|
)
|
|
|
|
return block
|