def test_read(self): assert_equals( self.data['foo'], self.kvs.get(KeyValueStore.Key(Scope.content, None, None, 'foo'))) assert_equals( self.children, self.kvs.get( KeyValueStore.Key(Scope.children, None, None, 'children'))) assert_equals( self.metadata['meta'], self.kvs.get(KeyValueStore.Key(Scope.settings, None, None, 'meta'))) assert_equals( None, self.kvs.get(KeyValueStore.Key(Scope.parent, None, None, 'parent')))
def _update_last_visited_module_id(self, request, course, module_key, modification_date): """ Saves the module id if the found modification_date is less recent than the passed modification date """ field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) try: module_descriptor = modulestore().get_item(module_key) except ItemNotFoundError: return Response(errors.ERROR_INVALID_MODULE_ID, status=400) module = get_module_for_descriptor(request.user, request, module_descriptor, field_data_cache, course.id, course=course) if modification_date: key = KeyValueStore.Key(scope=Scope.user_state, user_id=request.user.id, block_scope_id=course.location, field_name='position') original_store_date = field_data_cache.last_modified(key) if original_store_date is not None and modification_date < original_store_date: # old modification date so skip update return self._get_course_info(request, course) save_positions_recursively_up(request.user, request, field_data_cache, module, course=course) return self._get_course_info(request, course)
def handle_grade_event(block, event_type, event): user_id = event.get('user_id', user.id) # Construct the key for the module key = KeyValueStore.Key( scope=Scope.user_state, user_id=user_id, block_scope_id=descriptor.location, field_name='grade' ) student_module = field_data_cache.find_or_create(key) # Update the grades student_module.grade = event.get('value') student_module.max_grade = event.get('max_value') # Save all changes to the underlying KeyValueStore student_module.save() # Bin score into range and increment stats score_bucket = get_score_bucket(student_module.grade, student_module.max_grade) course_id_dict = Location.parse_course_id(course_id) tags = [ u"org:{org}".format(**course_id_dict), u"course:{course}".format(**course_id_dict), u"run:{name}".format(**course_id_dict), u"score_bucket:{0}".format(score_bucket) ] if grade_bucket_type is not None: tags.append('type:%s' % grade_bucket_type) dog_stats_api.increment("lms.courseware.question_answered", tags=tags)
def publish(event): """A function that allows XModules to publish events. This only supports grade changes right now.""" if event.get('event_name') != 'grade': return # Construct the key for the module key = KeyValueStore.Key(scope=Scope.user_state, student_id=user.id, block_scope_id=descriptor.location, field_name='grade') student_module = field_data_cache.find_or_create(key) # Update the grades student_module.grade = event.get('value') student_module.max_grade = event.get('max_value') # Save all changes to the underlying KeyValueStore student_module.save() # Bin score into range and increment stats score_bucket = get_score_bucket(student_module.grade, student_module.max_grade) org, course_num, run = course_id.split("/") tags = [ "org:{0}".format(org), "course:{0}".format(course_num), "run:{0}".format(run), "score_bucket:{0}".format(score_bucket) ] if grade_bucket_type is not None: tags.append('type:%s' % grade_bucket_type) statsd.increment("lms.courseware.question_answered", tags=tags)
def setUp(self): super(TestKVStore, self).setUp() self.kvs = WorkbenchDjangoKeyValueStore() self.key = KeyValueStore.Key(scope=Scope.content, user_id="rusty", block_scope_id="my_scenario.my_block.d0", field_name="age")
def test_kv_store(): # Simple test to makes sure we can get things in and out kvs = WorkbenchDjangoKeyValueStore() key = KeyValueStore.Key(scope=Scope.content, user_id="rusty", block_scope_id="my_scenario.my_block.d0", field_name="age") assert_false(kvs.has(key)) kvs.set(key, 7) assert_true(kvs.has(key)) assert_equals(kvs.get(key), 7) kvs.delete(key) assert_false(kvs.has(key))
def handle_grade_event(block, event_type, event): # pylint: disable=unused-argument """ Manages the workflow for recording and updating of student module grade state """ user_id = event.get('user_id', user.id) # Construct the key for the module key = KeyValueStore.Key( scope=Scope.user_state, user_id=user_id, block_scope_id=descriptor.location, field_name='grade' ) student_module = field_data_cache.find_or_create(key) # Update the grades student_module.grade = event.get('value') student_module.max_grade = event.get('max_value') # Save all changes to the underlying KeyValueStore student_module.save() # Bin score into range and increment stats score_bucket = get_score_bucket(student_module.grade, student_module.max_grade) tags = [ u"org:{}".format(course_id.org), u"course:{}".format(course_id), u"score_bucket:{0}".format(score_bucket) ] if grade_bucket_type is not None: tags.append('type:%s' % grade_bucket_type) dog_stats_api.increment("lms.courseware.question_answered", tags=tags) # Cycle through the milestone fulfillment scenarios to see if any are now applicable # thanks to the updated grading information that was just submitted _fulfill_content_milestones( user, course_id, descriptor.location, )
def publish(block, event, custom_user=None): """A function that allows XModules to publish events. This only supports grade changes right now.""" if event.get('event_name') != 'grade': return if custom_user: user_id = custom_user.id else: user_id = user.id # Construct the key for the module key = KeyValueStore.Key( scope=Scope.user_state, user_id=user_id, block_scope_id=descriptor.location, field_name='grade' ) student_module = field_data_cache.find_or_create(key) # Update the grades student_module.grade = event.get('value') student_module.max_grade = event.get('max_value') # Save all changes to the underlying KeyValueStore student_module.save() # Bin score into range and increment stats score_bucket = get_score_bucket(student_module.grade, student_module.max_grade) course_id_dict = Location.parse_course_id(course_id) tags = [ u"org:{org}".format(**course_id_dict), u"course:{course}".format(**course_id_dict), u"run:{name}".format(**course_id_dict), u"score_bucket:{0}".format(score_bucket) ] if grade_bucket_type is not None: tags.append('type:%s' % grade_bucket_type) dog_stats_api.increment("lms.courseware.question_answered", tags=tags)
def get_key_value(scope, user_id, block_scope_id, field_name): """Gets the value, from `key_store`, of a Key with the given values.""" new_key = KeyValueStore.Key(scope, user_id, block_scope_id, field_name) return key_store.db_dict[new_key]
def test_delete(self): yield (self._check_delete_key_error, KeyValueStore.Key(Scope.content, None, None, 'foo')) yield (self._check_delete_default, KeyValueStore.Key(Scope.children, None, None, 'children'), []) yield (self._check_delete_key_error, KeyValueStore.Key(Scope.settings, None, None, 'meta'))
def test_write(self): yield (self._check_write, KeyValueStore.Key(Scope.content, None, None, 'foo'), 'new_data') yield (self._check_write, KeyValueStore.Key(Scope.children, None, None, 'children'), []) yield (self._check_write, KeyValueStore.Key(Scope.settings, None, None, 'meta'), 'new_settings')
def test_write_non_dict_data(self): self.kvs._data = 'xml_data' self._check_write(KeyValueStore.Key(Scope.content, None, None, 'data'), 'new_data')
def test_write_invalid_scope(self): for scope in (Scope.preferences, Scope.user_info, Scope.user_state): with assert_raises(InvalidScopeError): self.kvs.set(KeyValueStore.Key(scope, None, None, 'foo'), 'new_value')
def test_write(self): yield (self._check_write, KeyValueStore.Key(Scope.content, None, None, 'foo'), 'new_data') yield (self._check_write, KeyValueStore.Key(Scope.content, None, None, 'location'), Location('i4x://org/course/category/name@new_version')) yield (self._check_write, KeyValueStore.Key(Scope.children, None, None, 'children'), []) yield (self._check_write, KeyValueStore.Key(Scope.settings, None, None, 'meta'), 'new_settings')
def test_read_invalid_scope(self): for scope in (Scope.preferences, Scope.user_info, Scope.user_state): key = KeyValueStore.Key(scope, None, None, 'foo') with assert_raises(InvalidScopeError): self.kvs.get(key) assert_false(self.kvs.has(key))
def test_read_non_dict_data(self): self.kvs._data = 'xml_data' assert_equals( 'xml_data', self.kvs.get(KeyValueStore.Key(Scope.content, None, None, 'data')))
def test_read_non_dict_data(self): self.kvs = MongoKeyValueStore('xml_data', self.children, self.metadata) assert_equals( 'xml_data', self.kvs.get(KeyValueStore.Key(Scope.content, None, None, 'data')))
def test_delete_invalid_scope(self): for scope in (Scope.preferences, Scope.user_info, Scope.user_state, Scope.parent): with assert_raises(InvalidScopeError): self.kvs.delete(KeyValueStore.Key(scope, None, None, 'foo'))
def test_write_non_dict_data(self): self.kvs = MongoKeyValueStore('xml_data', self.children, self.metadata) self._check_write(KeyValueStore.Key(Scope.content, None, None, 'data'), 'new_data')