def _move_playthrough_to_correct_issue(self, playthrough, orig_playthrough): """Moves the updated playthrough to its correct issue in the unresolved issues list. Args: playthrough: Playthrough. The updated playthrough domain object. orig_playthrough: Playthrough. The original playthrough domain object which is in the now-incorrect issue list. """ did_move_playthrough_to_new_issue = False issue_index = self._find_matching_issue_in_exp_issues(playthrough) # Check whether the playthrough can be added to its new issue, # if not, it stays in its old issue. if issue_index is not None: issue = self.current_exp_issues.unresolved_issues[issue_index] if len(issue.playthrough_ids) < feconf.MAX_PLAYTHROUGHS_FOR_ISSUE: issue.playthrough_ids.append(self.current_playthrough_id) did_move_playthrough_to_new_issue = True else: issue = stats_domain.ExplorationIssue( playthrough.issue_type, playthrough.issue_customization_args, [self.current_playthrough_id], self.current_issue_schema_version, is_valid=True) self.current_exp_issues.unresolved_issues.append(issue) did_move_playthrough_to_new_issue = True # Now, remove the playthrough from its old issue. if did_move_playthrough_to_new_issue: orig_issue_index = self._find_matching_issue_in_exp_issues( orig_playthrough) if orig_issue_index is not None: self.current_exp_issues.unresolved_issues[ orig_issue_index].playthrough_ids.remove( self.current_playthrough_id)
def _get_corresponding_exp_issue( self, playthrough, exp_issues, issue_schema_version): """Returns the unique exploration issue model expected to own the given playthrough. If it does not exist yet, then it will be created. Args: playthrough: Playthrough. The playthrough domain object. exp_issues: ExplorationIssues. The exploration issues domain object which manages each individual exploration issue. issue_schema_version: int. The version of the issue schema. Returns: ExplorationIssue. The corresponding exploration issue. """ for issue in exp_issues.unresolved_issues: if issue.issue_type == playthrough.issue_type: issue_customization_args = issue.issue_customization_args identifying_arg = ( stats_models.CUSTOMIZATION_ARG_WHICH_IDENTIFIES_ISSUE[ issue.issue_type]) # NOTE TO DEVELOPERS: When identifying_arg is 'state_names', the # ordering of the list is important (i.e. [a, b, c] is different # from [b, c, a]). if (issue_customization_args[identifying_arg] == playthrough.issue_customization_args[identifying_arg]): return issue issue = stats_domain.ExplorationIssue( playthrough.issue_type, playthrough.issue_customization_args, [], issue_schema_version, is_valid=True) exp_issues.unresolved_issues.append(issue) return issue
def _require_exp_issue_dict_is_valid(self, exp_issue_dict): """Checks whether the exploration issue dict has the correct keys. Args: exp_issue_dict: dict. Dict representing an exploration issue. """ exp_issue_properties = [ 'issue_type', 'schema_version', 'issue_customization_args', 'is_valid' ] for exp_issue_property in exp_issue_properties: if exp_issue_property not in exp_issue_dict: raise self.InvalidInputException( '%s not in exploration issue dict.' % (exp_issue_property)) dummy_exp_issue = stats_domain.ExplorationIssue( exp_issue_dict['issue_type'], exp_issue_dict['issue_customization_args'], [], exp_issue_dict['schema_version'], exp_issue_dict['is_valid']) try: dummy_exp_issue.validate() except utils.ValidationError as e: raise self.InvalidInputException(e)
def post(self, exploration_id): """Handles POST requests. Appends to existing list of playthroughs or deletes it if already full. Args: exploration_id: str. The ID of the exploration. """ exp_issue_dict = self.payload.get('exp_issue_dict') self._require_exp_issue_dict_is_valid(exp_issue_dict) playthrough_data = self.payload.get('playthrough_data') self._require_playthrough_data_is_valid(playthrough_data) exp_issues_model = stats_models.ExplorationIssuesModel.get( exploration_id) exp_issues = stats_services.get_exp_issues_from_model(exp_issues_model) customization_args = exp_issue_dict['issue_customization_args'] issue_found = False for index, issue in enumerate(exp_issues.unresolved_issues): if issue.issue_type == exp_issue_dict['issue_type']: issue_customization_args = issue.issue_customization_args # In case issue_keyname is 'state_names', the ordering of the # list is important i.e. [a,b,c] is different from [b,c,a]. issue_keyname = stats_models.ISSUE_TYPE_KEYNAME_MAPPING[ issue.issue_type] if (issue_customization_args[issue_keyname] == customization_args[issue_keyname]): issue_found = True if (len(issue.playthrough_ids) < feconf.MAX_PLAYTHROUGHS_FOR_ISSUE): playthrough_id = stats_models.PlaythroughModel.create( playthrough_data['exp_id'], playthrough_data['exp_version'], playthrough_data['issue_type'], playthrough_data['issue_customization_args'], playthrough_data['playthrough_actions'], playthrough_data['is_valid']) exp_issues.unresolved_issues[ index].playthrough_ids.append(playthrough_id) break if not issue_found: playthrough_id = stats_models.PlaythroughModel.create( playthrough_data['exp_id'], playthrough_data['exp_version'], playthrough_data['issue_type'], playthrough_data['issue_customization_args'], playthrough_data['playthrough_actions'], playthrough_data['is_valid']) issue = stats_domain.ExplorationIssue( exp_issue_dict['issue_type'], exp_issue_dict['issue_customization_args'], [playthrough_id], exp_issue_dict['schema_version']) exp_issues.unresolved_issues.append(issue) stats_services.save_exp_issues_model_transactional(exp_issues) self.render_json({})
def _assign_playthrough_to_issue(self, playthrough): """Assigns newly created playthrough to its correct issue or makes a new issue. Args: playthrough: Playthrough. The playthrough domain object. Raises: Exception. Maximum playthroughs per issue reached. Returns: playthrough_id: int. The playthrough ID. """ # Find whether an issue already exists for the new playthrough. issue_index = self._find_matching_issue_in_exp_issues(playthrough) if issue_index is not None: issue = self.current_exp_issues.unresolved_issues[issue_index] if len(issue.playthrough_ids) < feconf.MAX_PLAYTHROUGHS_FOR_ISSUE: actions = [action.to_dict() for action in playthrough.actions] playthrough_id = stats_models.PlaythroughModel.create( playthrough.exp_id, playthrough.exp_version, playthrough.issue_type, playthrough.issue_customization_args, actions) issue.playthrough_ids.append(playthrough_id) else: raise Exception('Maximum playthroughs per issue reached.') else: actions = [action.to_dict() for action in playthrough.actions] playthrough_id = stats_models.PlaythroughModel.create( playthrough.exp_id, playthrough.exp_version, playthrough.issue_type, playthrough.issue_customization_args, actions) issue = stats_domain.ExplorationIssue( playthrough.issue_type, playthrough.issue_customization_args, [playthrough_id], self.current_issue_schema_version, is_valid=True) self.current_exp_issues.unresolved_issues.append(issue) return playthrough_id