Files
edx-platform/lms/djangoapps/courseware/transformers/grades.py
2016-05-26 16:15:34 -04:00

103 lines
3.6 KiB
Python

"""
Grades Transformer
"""
from django.test.client import RequestFactory
from openedx.core.lib.block_structure.transformer import BlockStructureTransformer
from openedx.core.djangoapps.util.user_utils import SystemUser
from .. import module_render
from courseware.model_data import FieldDataCache
class GradesTransformer(BlockStructureTransformer):
"""
The GradesTransformer collects grading information and stores it on
the block structure.
No runtime transformations are performed.
The following values are stored as xblock_fields on their respective blocks in the
block structure:
due: (datetime) when the problem is due.
format: (string) what type of problem it is
graded: (boolean)
has_score: (boolean)
weight: (numeric)
Additionally, the following value is calculated and stored as a transformer_block_field
for each block:
max_score: (numeric)
"""
VERSION = 1
FIELDS_TO_COLLECT = [u'due', u'format', u'graded', u'has_score', u'weight']
@classmethod
def name(cls):
"""
Unique identifier for the transformer's class;
same identifier used in setup.py.
"""
return u'grades'
@classmethod
def collect(cls, block_structure):
"""
Collects any information that's necessary to execute this
transformer's transform method.
"""
block_structure.request_xblock_fields(*cls.FIELDS_TO_COLLECT)
cls._collect_max_scores(block_structure)
def transform(self, block_structure, usage_context):
"""
Perform no transformations.
"""
pass
@classmethod
def _collect_max_scores(cls, block_structure):
"""
Collect the `max_score` for every block in the provided `block_structure`.
"""
for module in cls._iter_scorable_xmodules(block_structure):
cls._collect_max_score(block_structure, module)
@classmethod
def _collect_max_score(cls, block_structure, module):
"""
Collect the `max_score` from the given module, storing it as a
`transformer_block_field` associated with the `GradesTransformer`.
"""
score = module.max_score()
block_structure.set_transformer_block_field(module.location, cls, 'max_score', score)
@staticmethod
def _iter_scorable_xmodules(block_structure):
"""
Loop through all the blocks locators in the block structure, and retrieve
the module (XModule or XBlock) associated with that locator.
For implementation reasons, we need to pull the max_score from the
XModule, even though the data is not user specific. Here we bind the
data to a SystemUser.
"""
request = RequestFactory().get('/dummy-collect-max-grades')
user = SystemUser()
request.user = user
request.session = {}
root_block = block_structure.get_xblock(block_structure.root_block_usage_key)
course_key = block_structure.root_block_usage_key.course_key
cache = FieldDataCache.cache_for_descriptor_descendents(
course_id=course_key,
user=request.user,
descriptor=root_block,
descriptor_filter=lambda descriptor: descriptor.has_score,
)
for block_locator in block_structure.post_order_traversal():
block = block_structure.get_xblock(block_locator)
if getattr(block, 'has_score', False):
module = module_render.get_module_for_descriptor(user, request, block, cache, course_key)
yield module