def get(self): """Handles GET requests.""" query_string = utils.unescape_encoded_uri_component( self.request.get('q')) # Remove all punctuation from the query string, and replace it with # spaces. See http://stackoverflow.com/a/266162 and # http://stackoverflow.com/a/11693937 remove_punctuation_map = dict( (ord(char), None) for char in string.punctuation) query_string = query_string.translate(remove_punctuation_map) if self.request.get('category'): query_string += ' category=%s' % self.request.get('category') if self.request.get('language_code'): query_string += ' language_code=%s' % self.request.get( 'language_code') search_cursor = self.request.get('cursor', None) explorations_list, new_search_cursor = get_matching_exploration_dicts( query_string, search_cursor) self.values.update({ 'explorations_list': explorations_list, 'search_cursor': new_search_cursor, }) self.render_json(self.values)
def get(self): """Handles GET requests.""" query_string = utils.unescape_encoded_uri_component( self.request.get('q')) # Remove all punctuation from the query string, and replace it with # spaces. See http://stackoverflow.com/a/266162 and # http://stackoverflow.com/a/11693937 remove_punctuation_map = dict( (ord(char), None) for char in string.punctuation) query_string = query_string.translate(remove_punctuation_map) if self.request.get('category'): query_string += ' category=%s' % self.request.get('category') if self.request.get('language_code'): query_string += ' language_code=%s' % self.request.get( 'language_code') search_cursor = self.request.get('cursor', None) activity_list, new_search_cursor = get_matching_activity_dicts( query_string, search_cursor) self.values.update({ 'activity_list': activity_list, 'search_cursor': new_search_cursor, }) self.render_json(self.values)
def get(self, exploration_id, escaped_state_name): """Handles GET requests.""" current_exploration = exp_fetchers.get_exploration_by_id( exploration_id) state_name = utils.unescape_encoded_uri_component(escaped_state_name) if state_name not in current_exploration.states: logging.exception('Could not find state: %s' % state_name) logging.exception('Available states: %s' % ( list(current_exploration.states.keys()))) raise self.PageNotFoundException # TODO(#11475): Return visualizations info based on Apache Beam job. self.render_json({'visualizations_info': []})
def get(self): """Handles GET requests.""" query_string = utils.unescape_encoded_uri_component( self.request.get('q')) # Remove all punctuation from the query string, and replace it with # spaces. See http://stackoverflow.com/a/266162 and # http://stackoverflow.com/a/11693937 remove_punctuation_map = dict( (ord(char), None) for char in string.punctuation) query_string = query_string.translate(remove_punctuation_map) # If there is a category parameter, it should be in the following form: # category=("Algebra" OR "Math") category_string = self.request.get('category', '') if category_string and ( not category_string.startswith('("') or not category_string.endswith('")')): raise self.InvalidInputException('Invalid search query.') # The 2 and -2 account for the '("" and '")' characters at the # beginning and end. categories = ( category_string[2:-2].split('" OR "') if category_string else []) # If there is a language code parameter, it should be in the following # form: # language_code=("en" OR "hi") language_code_string = self.request.get('language_code', '') if language_code_string and ( not language_code_string.startswith('("') or not language_code_string.endswith('")')): raise self.InvalidInputException('Invalid search query.') # The 2 and -2 account for the '("" and '")' characters at the # beginning and end. language_codes = ( language_code_string[2:-2].split('" OR "') if language_code_string else []) # TODO(#11314): Change 'cursor' to 'offset' here and in the frontend. search_offset = self.request.get('cursor', None) activity_list, new_search_offset = get_matching_activity_dicts( query_string, categories, language_codes, search_offset) self.values.update({ 'activity_list': activity_list, 'search_cursor': new_search_offset, }) self.render_json(self.values)
def test_editor(self, exploration_id, escaped_state_name=None, **kwargs): """Gets the user and exploration id if the user can edit it. Args: self: the handler instance exploration_id: the exploration id escaped_state_name: the URL-escaped state name, if it exists **kwargs: any other arguments passed to the handler Returns: The relevant handler, if the user is authorized to edit this exploration. Raises: self.PageNotFoundException: if no such exploration or state exists. self.UnauthorizedUserException: if the user exists but does not have the right credentials. """ if not self.user_id: self.redirect( current_user_services.create_login_url(self.request.uri)) return if self.username in config_domain.BANNED_USERNAMES.value: raise self.UnauthorizedUserException( 'You do not have the credentials to access this page.') try: exploration = exp_services.get_exploration_by_id(exploration_id) except: raise self.PageNotFoundException if not rights_manager.Actor(self.user_id).can_edit( feconf.ACTIVITY_TYPE_EXPLORATION, exploration_id): raise self.UnauthorizedUserException( 'You do not have the credentials to edit this exploration.', self.user_id) if not escaped_state_name: return handler(self, exploration_id, **kwargs) state_name = utils.unescape_encoded_uri_component(escaped_state_name) if state_name not in exploration.states: logging.error('Could not find state: %s' % state_name) logging.error('Available states: %s' % exploration.states.keys()) raise self.PageNotFoundException return handler(self, exploration_id, state_name, **kwargs)
def test_editor(self, exploration_id, escaped_state_name=None, **kwargs): """Gets the user and exploration id if the user can edit it. Args: self: the handler instance exploration_id: the exploration id escaped_state_name: the URL-escaped state name, if it exists **kwargs: any other arguments passed to the handler Returns: The relevant handler, if the user is authorized to edit this exploration. Raises: self.PageNotFoundException: if no such exploration or state exists. self.UnauthorizedUserException: if the user exists but does not have the right credentials. """ if not self.user_id: self.redirect(current_user_services.create_login_url( self.request.uri)) return if self.username in config_domain.BANNED_USERNAMES.value: raise self.UnauthorizedUserException( 'You do not have the credentials to access this page.') try: exploration = exp_services.get_exploration_by_id(exploration_id) except: raise self.PageNotFoundException if not rights_manager.Actor(self.user_id).can_edit( feconf.ACTIVITY_TYPE_EXPLORATION, exploration_id): raise self.UnauthorizedUserException( 'You do not have the credentials to edit this exploration.', self.user_id) if not escaped_state_name: return handler(self, exploration_id, **kwargs) state_name = utils.unescape_encoded_uri_component(escaped_state_name) if state_name not in exploration.states: logging.error('Could not find state: %s' % state_name) logging.error('Available states: %s' % exploration.states.keys()) raise self.PageNotFoundException return handler(self, exploration_id, state_name, **kwargs)
def get(self, exploration_id, escaped_state_name): """Handles GET requests.""" current_exploration = exp_fetchers.get_exploration_by_id( exploration_id) state_name = utils.unescape_encoded_uri_component(escaped_state_name) if state_name not in current_exploration.states: logging.error('Could not find state: %s' % state_name) logging.error('Available states: %s' % ( list(current_exploration.states.keys()))) raise self.PageNotFoundException self.render_json({ 'visualizations_info': stats_services.get_visualizations_info( current_exploration.id, state_name, current_exploration.states[state_name].interaction.id), })
def get(self, exploration_id, escaped_state_name): """Handles GET requests.""" try: exploration = exp_services.get_exploration_by_id(exploration_id) except: raise self.PageNotFoundException state_name = utils.unescape_encoded_uri_component(escaped_state_name) if state_name not in exploration.states: logging.error('Could not find state: %s' % state_name) logging.error('Available states: %s' % exploration.states.keys()) raise self.PageNotFoundException self.render_json({ 'rules_stats': stats_services.get_state_rules_stats(exploration_id, state_name) })
def get(self, exploration_id, escaped_state_name): """Handles GET requests.""" try: exploration = exp_services.get_exploration_by_id(exploration_id) except: raise self.PageNotFoundException state_name = utils.unescape_encoded_uri_component(escaped_state_name) if state_name not in exploration.states: logging.error('Could not find state: %s' % state_name) logging.error('Available states: %s' % exploration.states.keys()) raise self.PageNotFoundException self.render_json({ 'rules_stats': stats_services.get_state_rules_stats( exploration_id, state_name) })
def get(self, exploration_id, escaped_state_name): """Handles GET requests.""" try: exploration = exp_services.get_exploration_by_id(exploration_id) except: raise self.PageNotFoundException state_name = utils.unescape_encoded_uri_component(escaped_state_name) if state_name not in exploration.states: # If trying to access a non-existing state, there is no training # data associated with it. self.render_json({'unhandled_answers': []}) return state = exploration.states[state_name] # TODO(bhenning): Answers should be bound to a particular exploration # version or interaction ID. # TODO(bhenning): If the top 100 answers have already been classified, # then this handler will always return an empty list. # TODO(bhenning): This entire function will not work as expected until # the answers storage backend stores answers in a non-lossy way. # Currently, answers are stored as HTML strings and they are not able # to be converted back to the original objects they started as, so the # normalization calls in this function will not work correctly on those # strings. Once this happens, this handler should also be tested. # The total number of possible answers is 100 because it requests the # top 50 answers matched to the default rule and the top 50 answers # matched to the classifier individually. # TODO(sll): Functionality for retrieving untrained answers was removed # in PR 3489 due to infeasibility of the calculation approach. It needs # to be reinstated in the future so that the training interface can # function. submitted_answers = [] interaction = state.interaction unhandled_answers = [] if feconf.SHOW_TRAINABLE_UNRESOLVED_ANSWERS and interaction.id: interaction_instance = ( interaction_registry.Registry.get_interaction_by_id( interaction.id)) try: # Normalize the answers. for answer in submitted_answers: answer['answer'] = interaction_instance.normalize_answer( answer['answer']) trained_answers = set() for answer_group in interaction.answer_groups: trained_answers.update( interaction_instance.normalize_answer(trained) for trained in answer_group['training_data']) # Include all the answers which have been confirmed to be # associated with the default outcome. trained_answers.update( set( interaction_instance.normalize_answer(confirmed) for confirmed in interaction.confirmed_unclassified_answers)) unhandled_answers = [ answer for answer in submitted_answers if answer['answer'] not in trained_answers ] except Exception as e: logging.warning( 'Error loading untrained answers for interaction %s: %s.' % (interaction.id, e)) self.render_json({'unhandled_answers': unhandled_answers})
def get(self, exploration_id, escaped_state_name): """Handles GET requests.""" try: exploration = exp_services.get_exploration_by_id(exploration_id) except: raise self.PageNotFoundException state_name = utils.unescape_encoded_uri_component(escaped_state_name) if state_name not in exploration.states: # If trying to access a non-existing state, there is no training # data associated with it. self.render_json({'unhandled_answers': []}) return state = exploration.states[state_name] # TODO(bhenning): Answers should be bound to a particular exploration # version or interaction ID. # TODO(bhenning): If the top 100 answers have already been classified, # then this handler will always return an empty list. # TODO(bhenning): This entire function will not work as expected until # the answers storage backend stores answers in a non-lossy way. # Currently, answers are stored as HTML strings and they are not able # to be converted back to the original objects they started as, so the # normalization calls in this function will not work correctly on those # strings. Once this happens, this handler should also be tested. # The total number of possible answers is 100 because it requests the # top 50 answers matched to the default rule and the top 50 answers # matched to the classifier individually. answers = stats_services.get_top_state_rule_answers( exploration_id, state_name, [ exp_domain.DEFAULT_RULESPEC_STR, exp_domain.CLASSIFIER_RULESPEC_STR])[ :self.NUMBER_OF_TOP_ANSWERS_PER_RULE] interaction = state.interaction unhandled_answers = [] if feconf.SHOW_TRAINABLE_UNRESOLVED_ANSWERS and interaction.id: interaction_instance = ( interaction_registry.Registry.get_interaction_by_id( interaction.id)) try: # Normalize the answers. for answer in answers: answer['value'] = interaction_instance.normalize_answer( answer['value']) trained_answers = set() for answer_group in interaction.answer_groups: for rule_spec in answer_group.rule_specs: if (rule_spec.rule_type == exp_domain.CLASSIFIER_RULESPEC_STR): trained_answers.update( interaction_instance.normalize_answer(trained) for trained in rule_spec.inputs['training_data']) # Include all the answers which have been confirmed to be # associated with the default outcome. trained_answers.update(set( interaction_instance.normalize_answer(confirmed) for confirmed in interaction.confirmed_unclassified_answers)) unhandled_answers = [ answer for answer in answers if answer['value'] not in trained_answers ] except Exception as e: logging.warning( 'Error loading untrained answers for interaction %s: %s.' % (interaction.id, e)) self.render_json({ 'unhandled_answers': unhandled_answers })
def get(self, exploration_id, escaped_state_name): """Handles GET requests.""" try: exploration = exp_services.get_exploration_by_id(exploration_id) except: raise self.PageNotFoundException state_name = utils.unescape_encoded_uri_component(escaped_state_name) if state_name not in exploration.states: # If trying to access a non-existing state, there is no training # data associated with it. self.render_json({'unhandled_answers': []}) return state = exploration.states[state_name] # TODO(bhenning): Answers should be bound to a particular exploration # version or interaction ID. # TODO(bhenning): If the top 100 answers have already been classified, # then this handler will always return an empty list. # TODO(bhenning): This entire function will not work as expected until # the answers storage backend stores answers in a non-lossy way. # Currently, answers are stored as HTML strings and they are not able # to be converted back to the original objects they started as, so the # normalization calls in this function will not work correctly on those # strings. Once this happens, this handler should also be tested. # The total number of possible answers is 100 because it requests the # top 50 answers matched to the default rule and the top 50 answers # matched to a fuzzy rule individually. answers = stats_services.get_top_state_rule_answers( exploration_id, state_name, [exp_domain.DEFAULT_RULESPEC_STR, rule_domain.FUZZY_RULE_TYPE], self.NUMBER_OF_TOP_ANSWERS_PER_RULE) interaction = state.interaction unhandled_answers = [] if feconf.SHOW_TRAINABLE_UNRESOLVED_ANSWERS and interaction.id: interaction_instance = ( interaction_registry.Registry.get_interaction_by_id( interaction.id)) try: # Normalize the answers. for answer in answers: answer['value'] = interaction_instance.normalize_answer( answer['value']) trained_answers = set() for answer_group in interaction.answer_groups: for rule_spec in answer_group.rule_specs: if rule_spec.rule_type == rule_domain.FUZZY_RULE_TYPE: trained_answers.update( interaction_instance.normalize_answer(trained) for trained in rule_spec.inputs['training_data']) # Include all the answers which have been confirmed to be # associated with the default outcome. trained_answers.update( set( interaction_instance.normalize_answer(confirmed) for confirmed in interaction.confirmed_unclassified_answers)) unhandled_answers = [ answer for answer in answers if answer['value'] not in trained_answers ] except Exception as e: logging.warning( 'Error loading untrained answers for interaction %s: %s.' % (interaction.id, e)) self.render_json({'unhandled_answers': unhandled_answers})