From 91cb371de056f310ef8639f7a5c9ea1118aaa443 Mon Sep 17 00:00:00 2001 From: Braden MacDonald Date: Fri, 19 Dec 2014 14:16:24 -0800 Subject: [PATCH] Emit per-student library content events to the tracking log for analytics --- .../xmodule/xmodule/library_content_module.py | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/common/lib/xmodule/xmodule/library_content_module.py b/common/lib/xmodule/xmodule/library_content_module.py index e4c3252b37..78a8e0eecf 100644 --- a/common/lib/xmodule/xmodule/library_content_module.py +++ b/common/lib/xmodule/xmodule/library_content_module.py @@ -221,24 +221,50 @@ class LibraryContentModule(LibraryContentFields, XModule, StudioEditableModule): # Already done: return self._selected_set # pylint: disable=access-member-before-definition # 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: - selected -= (selected - valid_block_keys) + invalid_block_keys = (selected - valid_block_keys) + if invalid_block_keys: + selected -= invalid_block_keys + # 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), + "reason": "invalid", # Deleted from library or library being used has changed + }) # If max_count has been decreased, we may have to drop some previously selected blocks: + overlimit_block_keys = set() while len(selected) > self.max_count: - selected.pop() + overlimit_block_keys.add(selected.pop()) + if overlimit_block_keys: + # 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), + "reason": "overlimit", + }) # Do we have enough blocks now? num_to_add = self.max_count - len(selected) if num_to_add > 0: + added_block_keys = None # We need to select [more] blocks to display to this user: + pool = valid_block_keys - selected if self.mode == "random": - pool = valid_block_keys - selected num_to_add = min(len(pool), num_to_add) - selected |= set(random.sample(pool, num_to_add)) + added_block_keys = set(random.sample(pool, num_to_add)) # We now have the correct n random children to show for this user. else: raise NotImplementedError("Unsupported mode.") + selected |= added_block_keys + if added_block_keys: + # 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), + }) # Save our selections to the user state, to ensure consistency: self.selected = list(selected) # TODO: this doesn't save from the LMS "Progress" page. # Cache the results