def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user): """ Invoke an XBlock handler, either authenticated or not. """ location = unquote_slashes(usage_id) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({"success": error_msg})) try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format(course_id=course_id, location=location) ) raise Http404 field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course_id, user, descriptor) instance = get_module(user, request, location, field_data_cache, course_id, grade_bucket_type="ajax") if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module %s for user %s -- access denied?", location, user) raise Http404 req = django_to_webob_request(request) try: resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={"success": err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def parse_sources(xml_element): """ Parse xml_element 'sources' attr and return a list of location strings. """ result = [] sources = xml_element.get('sources') if sources: locations = [location.strip() for location in sources.split(';')] for location in locations: if Location.is_valid(location): # Check valid location url. result.append(location) return result
def parse_sources(xml_element, system, return_descriptor=False): """Parse xml_element 'sources' attr and: if return_descriptor=True - return list of descriptors if return_descriptor=False - return list of locations """ result = [] sources = xml_element.get('sources') if sources: locations = [location.strip() for location in sources.split(';')] for location in locations: if Location.is_valid(location): # Check valid location url. try: if return_descriptor: descriptor = system.load_item(location) result.append(descriptor) else: result.append(location) except ItemNotFoundError: msg = "Invalid module by location." log.exception(msg) system.error_tracker(msg) return result
def modx_dispatch(request, dispatch, location, course_id): ''' Generic view for extensions. This is where AJAX calls go. Arguments: - request -- the django request. - dispatch -- the command string to pass through to the module's handle_ajax call (e.g. 'problem_reset'). If this string contains '?', only pass through the part before the first '?'. - location -- the module location. Used to look up the XModule instance - course_id -- defines the course context for this request. Raises PermissionDenied if the user is not logged in. Raises Http404 if the location and course_id do not identify a valid module, the module is not accessible by the user, or the module raises NotFoundError. If the module raises any other error, it will escape this function. ''' # ''' (fix emacs broken parsing) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") if not request.user.is_authenticated(): raise PermissionDenied # Get the submitted data data = request.POST.copy() # Get and check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({'success': error_msg})) for key in files: # Merge files into to data dictionary data[key] = files.getlist(key) try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format( course_id=course_id, location=location)) raise Http404 field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, request.user, descriptor) instance = get_module(request.user, request, location, field_data_cache, course_id, grade_bucket_type='ajax') if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module {0} for user {1}--access denied?".format( location, request.user)) raise Http404 # Let the module handle the AJAX try: ajax_return = instance.handle_ajax(dispatch, data) # Save any fields that have changed to the underlying KeyValueStore instance.save() # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except: log.exception("error processing ajax call") raise # Return whatever the module wanted to return to the client/caller return HttpResponse(ajax_return)
def modx_dispatch(request, dispatch, location, course_id): ''' Generic view for extensions. This is where AJAX calls go. Arguments: - request -- the django request. - dispatch -- the command string to pass through to the module's handle_ajax call (e.g. 'problem_reset'). If this string contains '?', only pass through the part before the first '?'. - location -- the module location. Used to look up the XModule instance - course_id -- defines the course context for this request. Raises PermissionDenied if the user is not logged in. Raises Http404 if the location and course_id do not identify a valid module, the module is not accessible by the user, or the module raises NotFoundError. If the module raises any other error, it will escape this function. ''' # ''' (fix emacs broken parsing) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") if not request.user.is_authenticated(): raise PermissionDenied # Get the submitted data data = request.POST.copy() # Get and check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({'success': error_msg})) for key in files: # Merge files into to data dictionary data[key] = files.getlist(key) try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format( course_id=course_id, location=location ) ) raise Http404 field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, request.user, descriptor ) instance = get_module(request.user, request, location, field_data_cache, course_id, grade_bucket_type='ajax') if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module {0} for user {1}--access denied?".format(location, request.user)) raise Http404 # Let the module handle the AJAX try: ajax_return = instance.handle_ajax(dispatch, data) # Save any fields that have changed to the underlying KeyValueStore instance.save() # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except: log.exception("error processing ajax call") raise # Return whatever the module wanted to return to the client/caller return HttpResponse(ajax_return)
def test_is_valid(self, loc): self.assertTrue(Location.is_valid(loc))
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user): """ Invoke an XBlock handler, either authenticated or not. """ location = unquote_slashes(usage_id) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({'success': error_msg})) try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format( course_id=course_id, location=location)) raise Http404 field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, user, descriptor) instance = get_module(user, request, location, field_data_cache, course_id, grade_bucket_type='ajax') if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module %s for user %s -- access denied?", location, user) raise Http404 req = django_to_webob_request(request) try: resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def test_is_valid(): for v in valid: assert_equals(Location.is_valid(v), True) for v in invalid: assert_equals(Location.is_valid(v), False)
def test_is_invalid(self, loc): self.assertFalse(Location.is_valid(loc))
def handle_xblock_callback(request, course_id, usage_id, handler, suffix=None): """ Generic view for extensions. This is where AJAX calls go. Arguments: - request -- the django request. - location -- the module location. Used to look up the XModule instance - course_id -- defines the course context for this request. Raises PermissionDenied if the user is not logged in. Raises Http404 if the location and course_id do not identify a valid module, the module is not accessible by the user, or the module raises NotFoundError. If the module raises any other error, it will escape this function. """ location = unquote_slashes(usage_id) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") if not request.user.is_authenticated(): raise PermissionDenied # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({'success': error_msg})) try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format( course_id=course_id, location=location ) ) raise Http404 field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, request.user, descriptor ) instance = get_module(request.user, request, location, field_data_cache, course_id, grade_bucket_type='ajax') if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module %s for user %s -- access denied?", location, request.user) raise Http404 req = django_to_webob_request(request) try: resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def modx_dispatch(request, dispatch, location, course_id): ''' Generic view for extensions. This is where AJAX calls go. Arguments: - request -- the django request. - dispatch -- the command string to pass through to the module's handle_ajax call (e.g. 'problem_reset'). If this string contains '?', only pass through the part before the first '?'. - location -- the module location. Used to look up the XModule instance - course_id -- defines the course context for this request. Raises PermissionDenied if the user is not logged in. Raises Http404 if the location and course_id do not identify a valid module, the module is not accessible by the user, or the module raises NotFoundError. If the module raises any other error, it will escape this function. ''' # ''' (fix emacs broken parsing) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") if not request.user.is_authenticated(): raise PermissionDenied # Check for submitted files and basic file size checks p = request.POST.copy() if request.FILES: for fileinput_id in request.FILES.keys(): inputfiles = request.FILES.getlist(fileinput_id) if len(inputfiles) > settings.MAX_FILEUPLOADS_PER_INPUT: too_many_files_msg = 'Submission aborted! Maximum %d files may be submitted at once' %\ settings.MAX_FILEUPLOADS_PER_INPUT return HttpResponse(json.dumps({'success': too_many_files_msg})) for inputfile in inputfiles: if inputfile.size > settings.STUDENT_FILEUPLOAD_MAX_SIZE: # Bytes file_too_big_msg = 'Submission aborted! Your file "%s" is too large (max size: %d MB)' %\ (inputfile.name, settings.STUDENT_FILEUPLOAD_MAX_SIZE / (1000 ** 2)) return HttpResponse( json.dumps({'success': file_too_big_msg})) p[fileinput_id] = inputfiles try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format( course_id=course_id, location=location)) raise Http404 model_data_cache = ModelDataCache.cache_for_descriptor_descendents( course_id, request.user, descriptor) instance = get_module(request.user, request, location, model_data_cache, course_id, grade_bucket_type='ajax') if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module {0} for user {1}--access denied?".format( location, request.user)) raise Http404 # Let the module handle the AJAX try: ajax_return = instance.handle_ajax(dispatch, p) # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we respond with 400 except ProcessingError: log.warning("Module encountered an error while prcessing AJAX call", exc_info=True) return HttpResponseBadRequest() # If any other error occurred, re-raise it to trigger a 500 response except: log.exception("error processing ajax call") raise # Return whatever the module wanted to return to the client/caller return HttpResponse(ajax_return)
def modx_dispatch(request, dispatch, location, course_id): """ Generic view for extensions. This is where AJAX calls go. Arguments: - request -- the django request. - dispatch -- the command string to pass through to the module's handle_ajax call (e.g. 'problem_reset'). If this string contains '?', only pass through the part before the first '?'. - location -- the module location. Used to look up the XModule instance - course_id -- defines the course context for this request. Raises PermissionDenied if the user is not logged in. Raises Http404 if the location and course_id do not identify a valid module, the module is not accessible by the user, or the module raises NotFoundError. If the module raises any other error, it will escape this function. """ # ''' (fix emacs broken parsing) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") if not request.user.is_authenticated(): raise PermissionDenied # Get the submitted data data = request.POST.copy() # Get and check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({"success": error_msg})) for key in files: # Merge files into to data dictionary data[key] = files.getlist(key) # @begin:dispatch poll_compare request # @data:2013-11-20 data_data = request.POST.get("data", None) if not data_data is None: data["data"] = request.POST.get("data", None) return modx_dispatch_pollCompate(request=request, course_id=course_id, user=request.user, data=data) # @end try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format(course_id=course_id, location=location) ) raise Http404 field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course_id, request.user, descriptor) instance = get_module(request.user, request, location, field_data_cache, course_id, grade_bucket_type="ajax") if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module {0} for user {1}--access denied?".format(location, request.user)) raise Http404 # Let the module handle the AJAX try: ajax_return = instance.handle_ajax(dispatch, data) # @begin:complete_course_survey # @data:2013-12-13 try: if hasattr(instance, "complete_survey") and dispatch == "problem_check": if instance.complete_survey and dispatch == "problem_check": student = request.user course_descriptor = get_course_by_id(course_id) field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, student, course_descriptor, depth=None ) course_instance = get_module( student, request, course_descriptor.location, field_data_cache, course_id, grade_bucket_type="ajax", ) percent = grade(student, request, course_descriptor, field_data_cache)["percent"] ajax_return_json = json.loads(ajax_return) if ajax_return_json["success"] == u"correct": completed_course_prompt = "<p style='color:red'>Congratulations on completing this course! You can access your certificate and completed course on your dashboard.</p>" # @begin:Use dynamic score to judge that if you pass the subject. # @data:2015-11-19 uncompleted_course_prompt = ( "<p style='color:red'>This course requires a passing score of " + str(int(course_descriptor.grade_cutoffs["Pass"] * 100)) + " percent or higher. Please reference your scores in "My Progress" to retake or complete the assignments.</p>" ) if percent >= course_descriptor.grade_cutoffs["Pass"]: # 0.85 # @end course_instance.complete_course = True course_instance.complete_date = datetime.now(UTC()) ajax_return_json["contents"] = completed_course_prompt + ajax_return_json["contents"] instance.save() # True North Logic integration if tnl_course(student, course_id): domain = tnl_domain_from_user(student) tnl_instance = TNLInstance(domain) tnl_instance.register_completion(student, course_id, percent) else: course_instance.complete_course = False course_instance.complete_date = datetime.fromtimestamp(0, UTC()) ajax_return_json["contents"] = uncompleted_course_prompt + ajax_return_json["contents"] ajax_return = json.dumps(ajax_return_json) else: course_instance.complete_course = False course_instance.complete_date = datetime.fromtimestamp(0, UTC()) instance.save() course_instance.save() else: # Save any fields that have changed to the underlying KeyValueStore instance.save() else: instance.save() except ItemNotFoundError: instance.save() # @end # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={"success": err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except: log.exception("error processing ajax call") raise # Return whatever the module wanted to return to the client/caller return HttpResponse(ajax_return)
def modx_dispatch(request, dispatch, location, course_id): ''' Generic view for extensions. This is where AJAX calls go. Arguments: - request -- the django request. - dispatch -- the command string to pass through to the module's handle_ajax call (e.g. 'problem_reset'). If this string contains '?', only pass through the part before the first '?'. - location -- the module location. Used to look up the XModule instance - course_id -- defines the course context for this request. Raises PermissionDenied if the user is not logged in. Raises Http404 if the location and course_id do not identify a valid module, the module is not accessible by the user, or the module raises NotFoundError. If the module raises any other error, it will escape this function. ''' # ''' (fix emacs broken parsing) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") if not request.user.is_authenticated(): raise PermissionDenied # Check for submitted files and basic file size checks p = request.POST.copy() if request.FILES: for fileinput_id in request.FILES.keys(): inputfiles = request.FILES.getlist(fileinput_id) if len(inputfiles) > settings.MAX_FILEUPLOADS_PER_INPUT: too_many_files_msg = 'Submission aborted! Maximum %d files may be submitted at once' %\ settings.MAX_FILEUPLOADS_PER_INPUT return HttpResponse(json.dumps({'success': too_many_files_msg})) for inputfile in inputfiles: if inputfile.size > settings.STUDENT_FILEUPLOAD_MAX_SIZE: # Bytes file_too_big_msg = 'Submission aborted! Your file "%s" is too large (max size: %d MB)' %\ (inputfile.name, settings.STUDENT_FILEUPLOAD_MAX_SIZE / ( 1000 ** 2)) return HttpResponse(json.dumps({'success': file_too_big_msg})) p[fileinput_id] = inputfiles try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format( course_id=course_id, location=location ) ) raise Http404 model_data_cache = ModelDataCache.cache_for_descriptor_descendents( course_id, request.user, descriptor) instance = get_module(request.user, request, location, model_data_cache, course_id, grade_bucket_type='ajax') if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module {0} for user {1}--access denied?".format( location, request.user)) raise Http404 # Let the module handle the AJAX try: ajax_return = instance.handle_ajax(dispatch, p) # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we respond with 400 except ProcessingError: log.warning("Module encountered an error while prcessing AJAX call", exc_info=True) return HttpResponseBadRequest() # If any other error occurred, re-raise it to trigger a 500 response except: log.exception("error processing ajax call") raise # Return whatever the module wanted to return to the client/caller return HttpResponse(ajax_return)