def _update_last_visited_sequential(self, request, course, chapter_id, sequential_id, modification_date): ''' course -- xmodule ''' field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) try: chapter_descriptor = get_item(course.id, 'chapter', chapter_id) sequential_descriptor = get_item(course.id, 'sequential', sequential_id) except ItemNotFoundError: raise error.Error(status=status.HTTP_404_NOT_FOUND) course_descriptor = course course = get_module_for_descriptor( request.user, request, course_descriptor, field_data_cache, course.id) chapter = get_module_for_descriptor( request.user, request, chapter_descriptor, field_data_cache, course.id) sequential = get_module_for_descriptor( request.user, request, sequential_descriptor, field_data_cache, course.id) if modification_date: key = KeyValueStore.Key( scope=Scope.user_state, user_id=request.user.id, block_scope_id=course.location, field_name=None ) student_module = field_data_cache.find(key) if student_module: original_store_date = student_module.modified if modification_date < original_store_date: # old modification date so skip update return self._get_course_info(request, course) self.save_sequential_position(course, chapter, sequential) return self._get_course_info(request, course)
def test_rebinding_same_user(self, block_type): request = self.request_factory.get("") request.user = self.mock_user course = CourseFactory() descriptor = ItemFactory(category=block_type, parent=course) field_data_cache = FieldDataCache([self.toy_course, descriptor], self.toy_course.id, self.mock_user) render.get_module_for_descriptor(self.mock_user, request, descriptor, field_data_cache, self.toy_course.id) render.get_module_for_descriptor(self.mock_user, request, descriptor, field_data_cache, self.toy_course.id)
def test_rebinding_same_user(self, block_type): request = self.request_factory.get('') request.user = self.mock_user course = CourseFactory() descriptor = ItemFactory(category=block_type, parent=course) field_data_cache = FieldDataCache([self.toy_course, descriptor], self.toy_course.id, self.mock_user) render.get_module_for_descriptor(self.mock_user, request, descriptor, field_data_cache, self.toy_course.id) render.get_module_for_descriptor(self.mock_user, request, descriptor, field_data_cache, self.toy_course.id)
def create_module(descriptor): '''creates an XModule instance given a descriptor''' # TODO: We need the request to pass into here. If we could forego that, our arguments # would be simpler return get_module_for_descriptor( student, request, descriptor, field_data_cache, course.id, course=course )
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) if modification_date: key = KeyValueStore.Key( scope=Scope.user_state, user_id=request.user.id, block_scope_id=course.location, field_name=None ) student_module = field_data_cache.find(key) if student_module: original_store_date = student_module.modified if 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) return self._get_course_info(request, course)
def recurse_blocks_nav(self, request_info, result_data, block_info): """ A depth-first recursive function that supports calculation of both the list of blocks in the course and the navigation information up to the requested navigation_depth of the course. Arguments: request_info - Object encapsulating the request information. result_data - Running result data that is updated during the recursion. block_info - Information about the current block in the recursion. """ # bind user data to the block block_info.block = get_module_for_descriptor( request_info.request.user, request_info.request, block_info.block, request_info.field_data_cache, request_info.course.id, course=request_info.course ) # verify the user has access to this block if (block_info.block is None or not has_access( request_info.request.user, 'load', block_info.block, course_key=request_info.course.id )): return # add the block's value to the result result_data.blocks[unicode(block_info.block.location)] = block_info.value # descendants self.update_descendants(request_info, result_data, block_info) # children: recursively call the function for each of the children, while supporting dynamic children. if block_info.block.has_children: block_info.children = get_dynamic_descriptor_children(block_info.block, request_info.request.user.id) for child in block_info.children: self.recurse_blocks_nav( request_info, result_data, self.BlockInfo(child, request_info, parent_block_info=block_info) ) # block count self.update_block_count(request_info, result_data, block_info) # block JSON data self.add_block_json(request_info, block_info) # multi-device support if 'multi_device' in request_info.fields: block_info.value['multi_device'] = block_info.block.has_support( getattr(block_info.block, 'student_view', None), 'multi_device' ) # additional fields self.add_additional_fields(request_info, block_info)
def get_module_combinedopenended(request, course, location, isupload): location = course.location[0]+'://'+course.location[1]+'/'+course.location[2]+'/chapter/'+location section_descriptor = modulestore().get_instance(course.id, location, depth=None) field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id, request.user, section_descriptor, depth=None) descriptor = modulestore().get_instance_items(course.id, location,'combinedopenended',depth=None) content = [] for x in range(len(descriptor)): module = get_module_for_descriptor(request.user, request, descriptor[x][1], field_data_cache, course.id, position=None, wrap_xmodule_display=True, grade_bucket_type=None, static_asset_path='') con = module.runtime.render(module, None, 'student_view').content confirm = Get_confirm() confirm.feed(con) if confirm.score_urls[0] == 'correct' and confirm.state_urls[0] == 'done': #content.append(add_edit_tool(con,course,descriptor[x])) #import logging #log = logging.getLogger("tracking") #log.debug("descriptor_location===============================\n:"+str(con)+"\n===========================") #c_info = Get_combinedopenended_info() #c_info.feed(con) title, body = Get_combinedopenended_info(con) content.append(create_discussion(request, course, descriptor[x][1].location[4], location,{'title':title,'body':body})) return content
def edxnotes(request, course_id): """ Displays the EdxNotes page. """ course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, "load", course_key) if not is_feature_enabled(course): raise Http404 try: notes = get_notes(request.user, course) except EdxNotesServiceUnavailable: raise Http404 context = { "course": course, "search_endpoint": reverse("search_notes", kwargs={"course_id": course_id}), "notes": notes, "debug": json.dumps(settings.DEBUG), 'position': None, } if not notes: field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2 ) course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course_key) position = get_course_position(course_module) if position: context.update({ 'position': position, }) return render_to_response("edxnotes/edxnotes.html", context)
def test_repeated_course_module_instantiation(self, loops, default_store, course_depth): with modulestore().default_store(default_store): course = CourseFactory.create() chapter = ItemFactory(parent=course, category='chapter', graded=True) section = ItemFactory(parent=chapter, category='sequential') __ = ItemFactory(parent=section, category='problem') fake_request = self.factory.get( reverse('progress', kwargs={'course_id': unicode(course.id)}) ) course = modulestore().get_course(course.id, depth=course_depth) for _ in xrange(loops): field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, self.user, course, depth=course_depth ) course_module = get_module_for_descriptor( self.user, fake_request, course, field_data_cache, course.id, course=course ) for chapter in course_module.get_children(): for section in chapter.get_children(): for item in section.get_children(): self.assertTrue(item.graded)
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 = get_module_for_descriptor(user, request, block, cache, course_key) yield module
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 _fire_score_changed_for_block(course_id, student, block, module_state_key): """ Fires a SCORE_CHANGED event for the given module. The earned points are always zero. We must retrieve the possible points from the XModule, as noted below. """ if block and block.has_score: cache = FieldDataCache.cache_for_descriptor_descendents( course_id=course_id, user=student, descriptor=block, depth=0) # 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 the # current user. request = crum.get_current_request() module = get_module_for_descriptor(user=student, request=request, descriptor=block, field_data_cache=cache, course_key=course_id) max_score = module.max_score() if max_score is None: return else: points_earned, points_possible = weighted_score( 0, max_score, getattr(module, 'weight', None)) else: points_earned, points_possible = 0, 0 SCORE_CHANGED.send(sender=None, points_possible=points_possible, points_earned=points_earned, user=student, course_id=unicode(course_id), usage_id=unicode(module_state_key))
def prep_course_for_grading(course, request): """Set up course module for overrides to function properly""" field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id, request.user, course, depth=2) course = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id, course=course) course._field_data_cache = {} # pylint: disable=protected-access course.set_grading_policy(course.grading_policy)
def _last_visited_module_path(self, request, course): """ Returns the path from the last module visited by the current user in the given course up to the course module. If there is no such visit, the first item deep enough down the course tree is used. """ field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id, course=course) path = [course_module] chapter = get_current_child(course_module, min_depth=2) if chapter is not None: path.append(chapter) section = get_current_child(chapter, min_depth=1) if section is not None: path.append(section) path.reverse() return path
def save_positions_recursively_up(user, request, field_data_cache, xmodule, course=None): """ Recurses up the course tree starting from a leaf Saving the position property based on the previous node as it goes """ current_module = xmodule while current_module: parent_location = modulestore().get_parent_location( current_module.location) parent = None if parent_location: parent_descriptor = modulestore().get_item(parent_location) parent = get_module_for_descriptor( user, request, parent_descriptor, field_data_cache, current_module.location.course_key, course=course) if parent and hasattr(parent, 'position'): save_child_position(parent, current_module.location.name) current_module = parent
def get_last_accessed_courseware(course, request, user): """ Returns a tuple containing the courseware module (URL, id) that the user last accessed, or (None, None) if it cannot be found. """ # TODO: convert this method to use the Course Blocks API field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course_module = get_module_for_descriptor(user, request, course, field_data_cache, course.id, course=course) chapter_module = get_current_child(course_module) if chapter_module is not None: section_module = get_current_child(chapter_module) if section_module is not None: url = reverse('courseware_section', kwargs={ 'course_id': unicode(course.id), 'chapter': chapter_module.url_name, 'section': section_module.url_name }) return (url, section_module.url_name) return (None, None)
def test_repeated_course_module_instantiation(self, loops, default_store, course_depth): with modulestore().default_store(default_store): course = CourseFactory.create() chapter = ItemFactory(parent=course, category='chapter', graded=True) section = ItemFactory(parent=chapter, category='sequential') __ = ItemFactory(parent=section, category='problem') fake_request = self.factory.get( reverse('progress', kwargs={'course_id': six.text_type(course.id)})) course = modulestore().get_course(course.id, depth=course_depth) for _ in range(loops): field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, self.user, course, depth=course_depth) course_module = get_module_for_descriptor(self.user, fake_request, course, field_data_cache, course.id, course=course) for chapter in course_module.get_children(): for section in chapter.get_children(): for item in section.get_children(): self.assertTrue(item.graded)
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 = get_module_for_descriptor(user, request, block, cache, course_key) yield module
def edxnotes_visibility(request, course_id): """ Handle ajax call from "Show notes" checkbox. """ course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, "load", course_key) field_data_cache = FieldDataCache([course], course_key, request.user) course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course_key, course=course) if not is_feature_enabled(course, request.user): raise Http404 try: visibility = json.loads(request.body)["visibility"] course_module.edxnotes_visibility = visibility course_module.save() return JsonResponse(status=200) except (ValueError, KeyError): log.warning( "Could not decode request body as JSON and find a boolean visibility field: '%s'", request.body) return JsonResponseBadRequest()
def inner_get_module(descriptor): """ Delegate to get_module_for_descriptor (imported here to avoid circular reference) """ from courseware.module_render import get_module_for_descriptor field_data_cache = FieldDataCache([descriptor], course.id, request.user) return get_module_for_descriptor(request.user, request, descriptor, field_data_cache, course.id, course=course)
def get_discussion_context(request, course, location, parent_location,portfolio_user): section_descriptor = modulestore().get_instance(course.id, parent_location, depth=None) field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id, portfolio_user, section_descriptor, depth=None) descriptor = modulestore().get_item(location) module = get_module_for_descriptor(portfolio_user, request, descriptor, field_data_cache, course.id, position=None, wrap_xmodule_display=True, grade_bucket_type=None, static_asset_path='') return module.runtime.render(module, None, 'student_view').content
def _get_course_module(self): """ Returns the course module. """ field_data_cache = FieldDataCache([self.course], self.course.id, self.user) return get_module_for_descriptor(self.user, MagicMock(), self.course, field_data_cache, self.course.id)
def _get_course_module(self): """ Returns the course module. """ field_data_cache = FieldDataCache([self.course], self.course.id, self.user) return get_module_for_descriptor( self.user, MagicMock(), self.course, field_data_cache, self.course.id, course=self.course )
def get_course_content(request, user, course_key, course_descriptor): # pylint: disable=W0613 """ Returns course content """ field_data_cache = FieldDataCache([course_descriptor], course_key, user) course_content = module_render.get_module_for_descriptor( user, request, course_descriptor, field_data_cache, course_key) return course_content
def get_course_child_content(request, user, course_key, child_descriptor): """ Returns course child content """ field_data_cache = FieldDataCache([child_descriptor], course_key, user) child_content = module_render.get_module_for_descriptor( user, request, child_descriptor, field_data_cache, course_key) return child_content
def get_course_child_content(request, user, course_key, child_descriptor): field_data_cache = FieldDataCache([child_descriptor], course_key, user) child_content = module_render.get_module_for_descriptor( user, request, child_descriptor, field_data_cache, course_key) return child_content
def inner_get_module(descriptor): """ Delegate to get_module_for_descriptor (imported here to avoid circular reference) """ from courseware.module_render import get_module_for_descriptor field_data_cache = FieldDataCache([descriptor], course.id, request.user) return get_module_for_descriptor(request.user, request, descriptor, field_data_cache, course.id)
def prep_course_for_grading(course, request): """Set up course module for overrides to function properly""" field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course = get_module_for_descriptor( request.user, request, course, field_data_cache, course.id, course=course ) course._field_data_cache = {} # pylint: disable=protected-access course.set_grading_policy(course.grading_policy)
def create_module(descriptor): """ Factory method for creating and binding a module for the given descriptor. """ field_data_cache = FieldDataCache.cache_for_descriptor_descendents( self.course_id, self.request.user, descriptor, depth=0, ) return get_module_for_descriptor( self.request.user, self.request, descriptor, field_data_cache, self.course_id )
def test_changing_position_works(self): # Make a mock FieldDataCache for this course, so we can get the course module mock_field_data_cache = FieldDataCache([self.course], self.course.id, self.student) course = get_module_for_descriptor( self.student, MagicMock(name="request"), self.course, mock_field_data_cache, self.course.id ) # Now that we have the course, change the position and save, nothing should explode! course.position = 2 course.save()
def create_module(descriptor): '''creates an XModule instance given a descriptor''' # TODO: We need the request to pass into here. If we could forego that, our arguments # would be simpler return get_module_for_descriptor(student, request, descriptor, field_data_cache, course.id, course=course)
def ccx_grades_csv(request, course): """ Download grades as CSV. """ # Need course module for overrides to function properly field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id) ccx = get_ccx_for_coach(course, request.user) with ccx_context(ccx): # The grading policy for the MOOC is probably already cached. We need # to make sure we have the CCX grading policy loaded. course._field_data_cache = {} # pylint: disable=protected-access course.set_grading_policy(course.grading_policy) enrolled_students = User.objects.filter( ccxmembership__ccx=ccx, ccxmembership__active=1).order_by( 'username').select_related("profile") grades = iterate_grades_for(course, enrolled_students) header = None rows = [] for student, gradeset, __ in grades: if gradeset: # We were able to successfully grade this student for this # course. if not header: # Encode the header row in utf-8 encoding in case there are # unicode characters header = [ section['label'].encode('utf-8') for section in gradeset[u'section_breakdown'] ] rows.append(["id", "email", "username", "grade"] + header) percents = { section['label']: section.get('percent', 0.0) for section in gradeset[u'section_breakdown'] if 'label' in section } row_percents = [percents.get(label, 0.0) for label in header] rows.append([ student.id, student.email, student.username, gradeset['percent'] ] + row_percents) buf = StringIO() writer = csv.writer(buf) for row in rows: writer.writerow(row) return HttpResponse(buf.getvalue(), content_type='text/plain')
def test_changing_position_works(self): # Make a mock FieldDataCache for this course, so we can get the course module mock_field_data_cache = FieldDataCache([self.course], self.course.id, self.student) course = get_module_for_descriptor(self.student, MagicMock(name='request'), self.course, mock_field_data_cache, self.course.id) # Now that we have the course, change the position and save, nothing should explode! course.position = 2 course.save()
def _get_course_module(course_descriptor, user): # Fake a request to fool parts of the courseware that want to inspect it. request = get_request_or_stub() request.user = user # Now evil modulestore magic to inflate our descriptor with user state and # permissions checks. field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_descriptor.id, user, course_descriptor, depth=1, read_only=True, ) return get_module_for_descriptor( user, request, course_descriptor, field_data_cache, course_descriptor.id, course=course_descriptor, )
def inner_get_module(descriptor): """ Delegate to get_module_for_descriptor """ field_data_cache = FieldDataCache([descriptor], course.id, user) return get_module_for_descriptor( user, _get_mock_request(user), descriptor, field_data_cache, course.id, course=course )
def get_chaper_for_course(request, course, active_chapter): model_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course_module = get_module_for_descriptor(request.user, request, course, model_data_cache, course.id) if course_module is None: return None chapters = list() for chapter in course_module.get_display_items(): chapters.append({'display_name': chapter.display_name_with_default, 'url_name': chapter.url_name, 'active': chapter.url_name == active_chapter}) return chapters
def ccx_grades_csv(request, course): """ Download grades as CSV. """ # Need course module for overrides to function properly field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course = get_module_for_descriptor( request.user, request, course, field_data_cache, course.id) ccx = get_ccx_for_coach(course, request.user) with ccx_context(ccx): # The grading policy for the MOOC is probably already cached. We need # to make sure we have the CCX grading policy loaded. course._field_data_cache = {} # pylint: disable=protected-access course.set_grading_policy(course.grading_policy) enrolled_students = User.objects.filter( ccxmembership__ccx=ccx, ccxmembership__active=1 ).order_by('username').select_related("profile") grades = iterate_grades_for(course, enrolled_students) header = None rows = [] for student, gradeset, __ in grades: if gradeset: # We were able to successfully grade this student for this # course. if not header: # Encode the header row in utf-8 encoding in case there are # unicode characters header = [section['label'].encode('utf-8') for section in gradeset[u'section_breakdown']] rows.append(["id", "email", "username", "grade"] + header) percents = { section['label']: section.get('percent', 0.0) for section in gradeset[u'section_breakdown'] if 'label' in section } row_percents = [percents.get(label, 0.0) for label in header] rows.append([student.id, student.email, student.username, gradeset['percent']] + row_percents) buf = StringIO() writer = csv.writer(buf) for row in rows: writer.writerow(row) return HttpResponse(buf.getvalue(), content_type='text/plain')
def ccx_gradebook(request, course): """ Show the gradebook for this CCX. """ # Need course module for overrides to function properly field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id) ccx = get_ccx_for_coach(course, request.user) with ccx_context(ccx): # The grading policy for the MOOC is probably already cached. We need # to make sure we have the CCX grading policy loaded. course._field_data_cache = {} # pylint: disable=protected-access course.set_grading_policy(course.grading_policy) enrolled_students = User.objects.filter( ccxmembership__ccx=ccx, ccxmembership__active=1).order_by( 'username').select_related("profile") student_info = [{ 'username': student.username, 'id': student.id, 'email': student.email, 'grade_summary': student_grades(student, request, course), 'realname': student.profile.name, } for student in enrolled_students] return render_to_response( 'courseware/gradebook.html', { 'students': student_info, 'course': course, 'course_id': course.id, 'staff_access': request.user.is_staff, 'ordered_grades': sorted(course.grade_cutoffs.items(), key=lambda i: i[1], reverse=True), })
def edxnotes(request, course_id): """ Displays the EdxNotes page. Arguments: request: HTTP request object course_id: course id Returns: Rendered HTTP response. """ course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, "load", course_key) if not is_feature_enabled(course, request.user): raise Http404 notes_info = get_notes(request, course) has_notes = (len(notes_info.get('results')) > 0) context = { "course": course, "notes_endpoint": reverse("notes", kwargs={"course_id": course_id}), "notes": notes_info, "page_size": DEFAULT_PAGE_SIZE, "debug": settings.DEBUG, 'position': None, 'disabled_tabs': settings.NOTES_DISABLED_TABS, 'has_notes': has_notes, } if not has_notes: field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course_key, course=course) position = get_course_position(course_module) if position: context.update({ 'position': position, }) return render_to_response("edxnotes/edxnotes.html", context)
def get_section_id(request, course, discussion_id): with modulestore().bulk_operations(course.id): course_module = get_module_for_descriptor(request.user, request, course, None, course.id, course=course) for chapter in course_module.get_children(): for section in chapter.get_children(): for unit in section.get_children(): for vertical in unit.get_children(): if vertical.category == 'discussion': if vertical.discussion_id == discussion_id: section_id = section.url_name return section_id
def get_module_combinedopenended(request, course, location, isupload): location = course.location[0]+'://'+course.location[1]+'/'+course.location[2]+'/chapter/'+location section_descriptor = modulestore().get_instance(course.id, location, depth=None) field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id, request.user, section_descriptor, depth=None) descriptor = modulestore().get_instance_items(course.id, location,'combinedopenended',depth=None) content = [] for x in range(len(descriptor)): module = get_module_for_descriptor(request.user, request, descriptor[x], field_data_cache, course.id, position=None, wrap_xmodule_display=True, grade_bucket_type=None, static_asset_path='') con = module.runtime.render(module, None, 'student_view').content confirm = Get_confirm() confirm.feed(con) if confirm.score_urls[0] == 'correct' and confirm.state_urls[0] == 'done': content.append(add_edit_tool(con,course,descriptor[x])) return content
def _last_visited_module_id(self, request, course): """ Returns the id of the last module visited by the current user in the given course. If there is no such visit returns the default (the first item deep enough down the course tree) """ field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id) current = course_module child = current while child: child = get_current_child(current) if child: current = child return current
def edxnotes(request, course_id): """ Displays the EdxNotes page. Arguments: request: HTTP request object course_id: course id Returns: Rendered HTTP response. """ course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, "load", course_key) if not is_feature_enabled(course, request.user): raise Http404 notes_info = get_notes(request, course) has_notes = (len(notes_info.get('results')) > 0) context = { "course": course, "notes_endpoint": reverse("notes", kwargs={"course_id": course_id}), "notes": notes_info, "page_size": DEFAULT_PAGE_SIZE, "debug": settings.DEBUG, 'position': None, 'disabled_tabs': settings.NOTES_DISABLED_TABS, 'has_notes': has_notes, } if not has_notes: field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2 ) course_module = get_module_for_descriptor( request.user, request, course, field_data_cache, course_key, course=course ) position = get_course_position(course_module) if position: context.update({ 'position': position, }) return render_to_response("edxnotes/edxnotes.html", context)
def ccx_gradebook(request, course): """ Show the gradebook for this CCX. """ # Need course module for overrides to function properly field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id, request.user, course, depth=2) course = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id) ccx = get_ccx_for_coach(course, request.user) with ccx_context(ccx): # The grading policy for the MOOC is probably already cached. We need # to make sure we have the CCX grading policy loaded. course._field_data_cache = {} # pylint: disable=protected-access course.set_grading_policy(course.grading_policy) enrolled_students = ( User.objects.filter(ccxmembership__ccx=ccx, ccxmembership__active=1) .order_by("username") .select_related("profile") ) student_info = [ { "username": student.username, "id": student.id, "email": student.email, "grade_summary": student_grades(student, request, course), "realname": student.profile.name, } for student in enrolled_students ] return render_to_response( "courseware/gradebook.html", { "students": student_info, "course": course, "course_id": course.id, "staff_access": request.user.is_staff, "ordered_grades": sorted(course.grade_cutoffs.items(), key=lambda i: i[1], reverse=True), }, )
def _prefetch_and_bind_course(self): """ Prefetches all descendant data for the requested section and sets up the runtime, which binds the request user to the section. """ self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents( self.course_key, self.effective_user, self.course, depth=CONTENT_DEPTH, ) self.course = get_module_for_descriptor( self.effective_user, self.request, self.course, self.field_data_cache, self.course_key, course=self.course, )
def get_section_list(request,course_id,student_id): section_id_dict = {} commentable_id_list = [] try: course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) except Exception as e: return Resposne( data={ "Error": e.message }) course = get_course_by_id(course_key) with modulestore().bulk_operations(course.id): course_module = get_module_for_descriptor( request.user, request, course, None, course.id, course=course ) if course_module is None: return Response( data={ "Error":"User is not allowed to do the operation" }) student = User.objects.get(id=student_id) query_params = { "course_id":course_id, "user_id": student.id, } threads = Thread.search(query_params).collection for chapter in course_module.get_children(): for section in chapter.get_children(): for unit in section.get_children(): for vertical in unit.get_children(): if vertical.category == 'discussion': participated = False for thread in threads: if thread['commentable_id'] == vertical.discussion_id: participated = thread['username'] == student.username section_id_dict.update({chapter.url_name: participated}) return section_id_dict
def _last_visited_module_path(self, request, course): """ Returns the path from the last module visited by the current user in the given course up to the course module. If there is no such visit, the first item deep enough down the course tree is used. """ field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id) path = [course_module] chapter = get_current_child(course_module, min_depth=2) if chapter is not None: path.append(chapter) section = get_current_child(chapter, min_depth=1) if section is not None: path.append(section) path.reverse() return path
def _prefetch_and_bind_section(self): """ Prefetches all descendant data for the requested section and sets up the runtime, which binds the request user to the section. """ # Pre-fetch all descendant data self.section = modulestore().get_item(self.section.location, depth=None, lazy=False) self.field_data_cache.add_descriptor_descendents(self.section, depth=None) # Bind section to user self.section = get_module_for_descriptor( self.effective_user, self.request, self.section, self.field_data_cache, self.course_key, self.position, course=self.course, )
def _last_visited_module_path(self, request, course): """ Returns the path from the last module visited by the current user in the given course up to the course module. If there is no such visit, the first item deep enough down the course tree is used. """ field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, request.user, course, depth=2) course_module = get_module_for_descriptor(request.user, request, course, field_data_cache, course.id) current = course_module path = [] child = current while child: path.append(child) child = get_current_child(current) if child: current = child path.reverse() return path
def _fire_score_changed_for_block(course_id, student, block, module_state_key): """ Fires a PROBLEM_SCORE_CHANGED event for the given module. The earned points are always zero. We must retrieve the possible points from the XModule, as noted below. """ if block and block.has_score: cache = FieldDataCache.cache_for_descriptor_descendents( course_id=course_id, user=student, descriptor=block, depth=0 ) # 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 the # current user. request = crum.get_current_request() module = get_module_for_descriptor( user=student, request=request, descriptor=block, field_data_cache=cache, course_key=course_id ) max_score = module.max_score() if max_score is None: return else: points_earned, points_possible = weighted_score(0, max_score, getattr(module, 'weight', None)) else: points_earned, points_possible = 0, 0 PROBLEM_SCORE_CHANGED.send( sender=None, points_possible=points_possible, points_earned=points_earned, user_id=student.id, course_id=unicode(course_id), usage_id=unicode(module_state_key) )
def edxnotes_visibility(request, course_id): """ Handle ajax call from "Show notes" checkbox. """ course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, "load", course_key) field_data_cache = FieldDataCache([course], course_key, request.user) course_module = get_module_for_descriptor( request.user, request, course, field_data_cache, course_key, course=course ) if not is_feature_enabled(course): raise Http404 try: visibility = json.loads(request.body)["visibility"] course_module.edxnotes_visibility = visibility course_module.save() return JsonResponse(status=200) except (ValueError, KeyError): log.warning("Could not decode request body as JSON and find a boolean visibility field: '%s'", request.body) return JsonResponseBadRequest()
def get_units(chapter, section, position = None): chapter_descriptor = course.get_child_by(lambda m: m.location.name == chapter) section_descriptor = chapter_descriptor.get_child_by(lambda m: m.location.name == section) # cdodge: this looks silly, but let's refetch the section_descriptor with depth=None # which will prefetch the children more efficiently than doing a recursive load section_descriptor = modulestore().get_item(section_descriptor.location, depth = None) section_field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course_key, user, section_descriptor, depth = None) section_module = get_module_for_descriptor(request.user, request, section_descriptor, section_field_data_cache, course_key, position) if section_module is not None: units = [] for unit in section_module.get_display_items(): verticals = [] for vertical in unit.get_display_items(): if isinstance(vertical, VideoDescriptor): subtitles = vertical.transcripts.copy() if vertical.sub != "": subtitles.update({ 'en': sub }) verticals.append({ 'name': vertical.display_name, 'video_sources': vertical.html5_sources, 'subtitles': subtitles, 'type': 'video' }) else: verticals.append({ 'name': vertical.display_name, 'type': 'other' }) units.append({ 'name': unit.display_name, 'verticals': verticals }) return units else: return None
def progress_summary(student, request, course, field_data_cache=None, scores_client=None, grading_type='vertical'): """ This pulls a summary of all problems in the course. Returns - courseware_summary is a summary of all sections with problems in the course. It is organized as an array of chapters, each containing an array of sections, each containing an array of scores. This contains information for graded and ungraded problems, and is good for displaying a course summary with due dates, etc. Arguments: student: A User object for the student to grade course: A Descriptor containing the course to grade If the student does not have access to load the course module, this function will return None. """ with manual_transaction(): if field_data_cache is None: field_data_cache = field_data_cache_for_grading(course, student) if scores_client is None: scores_client = ScoresClient.from_field_data_cache(field_data_cache) course_module = get_module_for_descriptor( student, request, course, field_data_cache, course.id, course=course ) if not course_module: return None course_module = getattr(course_module, '_x_module', course_module) submissions_scores = sub_api.get_scores( course.id.to_deprecated_string(), anonymous_id_for_user(student, course.id) ) max_scores_cache = MaxScoresCache.create_for_course(course) # For the moment, we have to get scorable_locations from field_data_cache # and not from scores_client, because scores_client is ignorant of things # in the submissions API. As a further refactoring step, submissions should # be hidden behind the ScoresClient. max_scores_cache.fetch_from_remote(field_data_cache.scorable_locations) blocks_stack = [course_module] blocks_dict = {} while blocks_stack: curr_block = blocks_stack.pop() with manual_transaction(): # Skip if the block is hidden if curr_block.hide_from_toc: continue key = unicode(curr_block.scope_ids.usage_id) children = curr_block.get_display_items() if curr_block.category != grading_type else [] block = { 'display_name': curr_block.display_name_with_default, 'block_type': curr_block.category, 'url_name': curr_block.url_name, 'children': [unicode(child.scope_ids.usage_id) for child in children], } if curr_block.category == grading_type: graded = curr_block.graded scores = [] module_creator = curr_block.xmodule_runtime.get_module for module_descriptor in yield_dynamic_descriptor_descendants( curr_block, student.id, module_creator ): (correct, total) = get_score( student, module_descriptor, module_creator, scores_client, submissions_scores, max_scores_cache, ) if correct is None and total is None: continue scores.append( Score( correct, total, graded, module_descriptor.display_name_with_default, module_descriptor.location ) ) scores.reverse() total, _ = aggregate_scores(scores, curr_block.display_name_with_default) module_format = curr_block.format if curr_block.format is not None else '' block.update({ 'scores': scores, 'total': total, 'format': module_format, 'due': curr_block.due, 'graded': graded, }) blocks_dict[key] = block # Add this blocks children to the stack so that we can traverse them as well. blocks_stack.extend(children) max_scores_cache.push_to_remote() return { 'root': unicode(course.scope_ids.usage_id), 'blocks': blocks_dict, }