Commit 3973317a by Braden MacDonald

Report the original LibraryUsageLocator in LMS analytics

parent 407265bc
......@@ -220,8 +220,11 @@ class LibraryContentModule(LibraryContentFields, XModule, StudioEditableModule):
if hasattr(self, "_selected_set"):
# Already done:
return self._selected_set # pylint: disable=access-member-before-definition
lib_tools = self.runtime.service(self, 'library_tools')
format_block_keys = lambda block_keys: lib_tools.create_block_analytics_summary(self.location.course_key, block_keys)
# Determine which of our children we will show:
jsonify_block_keys = lambda keys: [unicode(self.location.course_key.make_usage_key(*key)) for key in keys]
selected = set(tuple(k) for k in self.selected) # set of (block_type, block_id) tuples
valid_block_keys = set([(c.block_type, c.block_id) for c in self.children]) # pylint: disable=no-member
# Remove any selected blocks that are no longer valid:
......@@ -231,8 +234,9 @@ class LibraryContentModule(LibraryContentFields, XModule, StudioEditableModule):
# Publish an event for analytics purposes:
self.runtime.publish(self, "edx.librarycontentblock.content.removed", {
"location": unicode(self.location),
"blocks": jsonify_block_keys(invalid_block_keys),
"removed": format_block_keys(invalid_block_keys),
"reason": "invalid", # Deleted from library or library being used has changed
"result": format_block_keys(selected),
})
# If max_count has been decreased, we may have to drop some previously selected blocks:
overlimit_block_keys = set()
......@@ -242,8 +246,9 @@ class LibraryContentModule(LibraryContentFields, XModule, StudioEditableModule):
# Publish an event for analytics purposes:
self.runtime.publish(self, "edx.librarycontentblock.content.removed", {
"location": unicode(self.location),
"blocks": jsonify_block_keys(overlimit_block_keys),
"removed": format_block_keys(overlimit_block_keys),
"reason": "overlimit",
"result": format_block_keys(selected),
})
# Do we have enough blocks now?
num_to_add = self.max_count - len(selected)
......@@ -262,8 +267,8 @@ class LibraryContentModule(LibraryContentFields, XModule, StudioEditableModule):
# Publish an event for analytics purposes:
self.runtime.publish(self, "edx.librarycontentblock.content.assigned", {
"location": unicode(self.location),
"added": jsonify_block_keys(added_block_keys),
"result": jsonify_block_keys(selected),
"added": format_block_keys(added_block_keys),
"result": format_block_keys(selected),
})
# Save our selections to the user state, to ensure consistency:
self.selected = list(selected) # TODO: this doesn't save from the LMS "Progress" page.
......
......@@ -44,6 +44,44 @@ class LibraryToolsService(object):
return library.location.library_key.version_guid
return None
def create_block_analytics_summary(self, course_key, block_keys):
"""
Given a CourseKey and a list of (block_type, block_id) pairs,
prepare the JSON-ready metadata needed for analytics logging.
This is [
{"usage_key": x, "original_usage_key": y, "original_usage_version": z, "descendants": [...]}
]
where the main list contains all top-level blocks, and descendants contains a *flat* list of all
descendants of the top level blocks, if any.
"""
def summarize_block(usage_key):
""" Basic information about the given block """
orig_key, orig_version = self.store.get_block_original_usage(usage_key)
return {
"usage_key": unicode(usage_key),
"original_usage_key": unicode(orig_key) if orig_key else None,
"original_usage_version": unicode(orig_version) if orig_version else None,
}
result_json = []
for block_key in block_keys:
key = course_key.make_usage_key(*block_key)
info = summarize_block(key)
info['descendants'] = []
try:
block = self.store.get_item(key, depth=None) # Load the item and all descendants
children = list(getattr(block, "children", []))
while children:
child_key = children.pop()
child = self.store.get_item(child_key)
info['descendants'].append(summarize_block(child_key))
children.extend(getattr(child, "children", []))
except ItemNotFoundError:
pass # The block has been deleted
result_json.append(info)
return result_json
def _filter_child(self, usage_key, capa_type):
"""
Filters children by CAPA problem type, if configured
......
......@@ -10,6 +10,7 @@ from django.conf import settings
from lms.djangoapps.lms_xblock.models import XBlockAsidesConfig
from openedx.core.djangoapps.user_api.api import course_tag as user_course_tag_api
from xmodule.modulestore.django import modulestore
from xmodule.library_tools import LibraryToolsService
from xmodule.x_module import ModuleSystem
from xmodule.partitions.partitions_service import PartitionService
......@@ -199,6 +200,7 @@ class LmsModuleSystem(LmsHandlerUrls, ModuleSystem): # pylint: disable=abstract
course_id=kwargs.get('course_id'),
track_function=kwargs.get('track_function', None),
)
services['library_tools'] = LibraryToolsService(modulestore())
services['fs'] = xblock.reference.plugins.FSService()
self.request_token = kwargs.pop('request_token', None)
super(LmsModuleSystem, self).__init__(**kwargs)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment