Files
edx-platform/lms/djangoapps/course_blocks/transformers/hidden_content.py
Feanil Patel 9cf2f9f298 Run 2to3 -f future . -w
This will remove imports from __future__ that are no longer needed.

https://docs.python.org/3.5/library/2to3.html#2to3fixer-future
2019-12-30 10:35:30 -05:00

116 lines
3.9 KiB
Python

"""
Visibility Transformer implementation.
"""
from datetime import datetime
from pytz import utc
from openedx.core.djangoapps.content.block_structure.transformer import (
BlockStructureTransformer,
FilteringTransformerMixin
)
from xmodule.seq_module import SequenceModule
from .utils import collect_merged_boolean_field, collect_merged_date_field
MAXIMUM_DATE = utc.localize(datetime.max)
class HiddenContentTransformer(FilteringTransformerMixin, BlockStructureTransformer):
"""
A transformer that enforces the hide_after_due field on
blocks by removing children blocks from the block structure for
which the user does not have access. The due and hide_after_due
fields on a block is percolated down to its descendants, so that
all blocks enforce the hidden content settings from their ancestors.
For a block with multiple parents, access is denied only if
access is denied from all its parents.
Staff users are exempted from hidden content rules.
"""
WRITE_VERSION = 2
READ_VERSION = 2
MERGED_DUE_DATE = 'merged_due_date'
MERGED_HIDE_AFTER_DUE = 'merged_hide_after_due'
@classmethod
def name(cls):
"""
Unique identifier for the transformer's class;
same identifier used in setup.py.
"""
return "hidden_content"
@classmethod
def _get_merged_hide_after_due(cls, block_structure, block_key):
"""
Returns whether the block with the given block_key in the
given block_structure should be hidden after due date per
computed value from ancestry chain.
"""
return block_structure.get_transformer_block_field(
block_key, cls, cls.MERGED_HIDE_AFTER_DUE, False
)
@classmethod
def _get_merged_due_date(cls, block_structure, block_key):
"""
Returns the merged value for the start date for the block with
the given block_key in the given block_structure.
"""
return block_structure.get_transformer_block_field(
block_key, cls, cls.MERGED_DUE_DATE, False
)
@classmethod
def collect(cls, block_structure):
"""
Collects any information that's necessary to execute this
transformer's transform method.
"""
collect_merged_boolean_field(
block_structure,
transformer=cls,
xblock_field_name='hide_after_due',
merged_field_name=cls.MERGED_HIDE_AFTER_DUE,
)
collect_merged_date_field(
block_structure,
transformer=cls,
xblock_field_name='due',
merged_field_name=cls.MERGED_DUE_DATE,
default_date=MAXIMUM_DATE,
func_merge_parents=max,
func_merge_ancestors=min,
)
block_structure.request_xblock_fields(u'self_paced', u'end')
def transform_block_filters(self, usage_info, block_structure):
# Users with staff access bypass the Visibility check.
if usage_info.has_staff_access:
return [block_structure.create_universal_filter()]
return [
block_structure.create_removal_filter(
lambda block_key: self._is_block_hidden(block_structure, block_key),
),
]
def _is_block_hidden(self, block_structure, block_key):
"""
Returns whether the block with the given block_key should
be hidden, given the current time.
"""
hide_after_due = self._get_merged_hide_after_due(block_structure, block_key)
self_paced = block_structure[block_structure.root_block_usage_key].self_paced
if self_paced:
hidden_date = block_structure[block_structure.root_block_usage_key].end
else:
hidden_date = self._get_merged_due_date(block_structure, block_key)
return not SequenceModule.verify_current_content_visibility(hidden_date, hide_after_due)