def test_get_attack_for_argument_with_restrictive_arguments(self): attack_uid, key = attacks.get_attack_for_argument( argument_uid=42, restrictive_attacks=None, restrictive_arg_uids=[40], last_attack=None, history='42/rebut/39-42/undermine/44') self.assertEqual(attack_uid, 43) self.assertEqual(key, Relations.UNDERCUT) attack_uid, key = attacks.get_attack_for_argument( argument_uid=42, restrictive_attacks=None, restrictive_arg_uids=[40], last_attack=None, history='42/rebut/39-42/undercut/43') self.assertEqual(attack_uid, 44) self.assertEqual(key, Relations.UNDERMINE) attack_uid, key = attacks.get_attack_for_argument( argument_uid=42, restrictive_attacks=None, restrictive_arg_uids=[40], last_attack=None, history='42/undercut/43-42/undermine/44') self.assertEqual(attack_uid, 39) self.assertEqual(key, Relations.REBUT)
def __get_url_for_support(self, attack, _um, db_user_argument, db_sys_argument): """ Returns url to support an argument :param attack: String :param _um: UrlManager :param db_user_argument: Argument :param db_sys_argument: Argument :return: String """ attacking_arg_uids = get_all_attacking_arg_uids_from_history(self.path) restriction_on_attacks = Relations.REBUT if attack == Relations.UNDERCUT else None # if the user did rebutted A with B, the system shall not rebut B with A history = '{}/rebut/{}'.format( db_sys_argument.uid, db_user_argument.uid) if attack == Relations.REBUT else '' arg_id_sys, sys_attack = attacks.get_attack_for_argument( db_sys_argument.uid, restrictive_arg_uids=attacking_arg_uids, restrictive_attacks=[restriction_on_attacks], history=history) if sys_attack == Relations.REBUT and attack == Relations.UNDERCUT: # case: system makes an undercut and the user supports this new attack can be an rebut, so another # undercut for the users argument therefore now the users opinion is the new undercut (e.g. rebut) # because he supported it! url = _um.get_url_for_reaction_on_argument( arg_id_sys, sys_attack, db_sys_argument.argument_uid) else: url = _um.get_url_for_reaction_on_argument(db_sys_argument.uid, sys_attack, arg_id_sys) return url
def __get_choose_array_for_pgroup(self, is_argument: bool, is_supportive: bool, conclusion_uid: int, argument_uid: int, db_user: User, group_id: int, _um: UrlManager): db_premises = DBDiscussionSession.query(Premise).filter_by(premisegroup_uid=group_id).all() premise_array = [] for premise in db_premises: text = premise.get_text() premise_array.append({'title': text, 'id': premise.statement_uid}) if db_user and db_user.nickname != nick_of_anonymous_user: # add seen by if the statement is visible add_seen_statement(premise.statement_uid, db_user) # get attack for each premise, so the urls will be unique db_argument = DBDiscussionSession.query(Argument).filter(Argument.premisegroup_uid == group_id, Argument.is_supportive == is_supportive) if conclusion_uid and not is_argument: db_argument = db_argument.filter_by(conclusion_uid=conclusion_uid).first() else: db_argument = db_argument.filter_by(argument_uid=argument_uid).first() if not db_argument: return None attacking_arg_uids = get_all_attacking_arg_uids_from_history(self.path) arg_id_sys, attack = attacks.get_attack_for_argument(db_argument.uid, restrictive_arg_uids=attacking_arg_uids) url = _um.get_url_for_reaction_on_argument(db_argument.uid, attack, arg_id_sys) if is_argument: is_author = is_author_of_argument(db_user, argument_uid) else: is_author = is_author_of_statement(db_user, conclusion_uid) return self.__create_answer_dict(str(db_argument.uid), premise_array, 'choose', url, is_markable=True, is_editable=True, is_author=is_author)
def test_get_attack_for_argument_with_undercut_restriction(self): attack_uid, key = attacks.get_attack_for_argument( argument_uid=42, restrictive_attacks=[Relations.UNDERCUT], restrictive_arg_uids=[40], last_attack=None, history='42/rebut/39-42/undermine/44') self.assertIsNone(attack_uid) self.assertIsNone(key)
def __get_dont_know_item_for_support(argument_uid, _um): """ Returns a random support url :param argument_uid: Argument.uid :param _um: UrlManager :return: String """ arg_id_sys, sys_attack = attacks.get_attack_for_argument(argument_uid) url = _um.get_url_for_reaction_on_argument(argument_uid, sys_attack, arg_id_sys) return url
def __get_url_for_jump_array(self, slug, arg_uid): """ Returns urls for the answers to jump to an argument :param slug: String :param arg_uid: Argument.uid :return: dict() """ db_argument = DBDiscussionSession.query(Argument).get(arg_uid) _um = UrlManager(slug, history=self.path) db_premises = DBDiscussionSession.query(Premise).filter_by( premisegroup_uid=db_argument.premisegroup_uid).all() forbidden_attacks = attacks.get_forbidden_attacks_based_on_history(self.path) db_undercutted_arg = None len_undercut = 0 if db_argument.argument_uid is not None: db_undercutted_arg = DBDiscussionSession.query(Argument).get(db_argument.argument_uid) len_undercut = 1 if db_undercutted_arg.argument_uid is None else 2 arg_id_sys, sys_attack = attacks.get_attack_for_argument(db_argument.uid, redirected_from_jump=True, restrictive_arg_uids=forbidden_attacks) url0 = _um.get_url_for_reaction_on_argument(db_argument.uid, sys_attack, arg_id_sys) if len_undercut == 0: url1 = _um.get_url_for_justifying_statement(db_argument.conclusion_uid, Attitudes.AGREE) url2 = _um.get_url_for_justifying_argument(db_argument.uid, Attitudes.AGREE, Relations.UNDERCUT) url3 = _um.get_url_for_justifying_statement(db_argument.conclusion_uid, Attitudes.DISAGREE) if len(db_premises) == 1: url4 = _um.get_url_for_justifying_statement(db_premises[0].statement_uid, Attitudes.DISAGREE) else: url4 = _um.get_url_for_justifying_argument(db_argument.uid, Attitudes.DISAGREE, Relations.UNDERMINE) elif len_undercut == 1: url1 = None url2 = _um.get_url_for_justifying_argument(db_argument.uid, Attitudes.AGREE, Relations.UNDERCUT) url3 = _um.get_url_for_jump(db_undercutted_arg.uid) if len(db_premises) == 1: url4 = _um.get_url_for_justifying_statement(db_premises[0].statement_uid, Attitudes.DISAGREE) else: url4 = _um.get_url_for_justifying_argument(db_argument.uid, Attitudes.DISAGREE, Relations.UNDERMINE) else: url1 = None url2 = None url3 = _um.get_url_for_jump(db_undercutted_arg.uid) if len(db_premises) == 1: url4 = _um.get_url_for_justifying_statement(db_premises[0].statement_uid, Attitudes.DISAGREE) else: url4 = _um.get_url_for_justifying_argument(db_argument.uid, Attitudes.DISAGREE, Relations.UNDERMINE) return [url0, url1, url2, url3, url4]
def get_array_for_reaction(self, argument_uid_sys, argument_uid_user, is_supportive, attack, gender): """ Prepares the dict with all items for the argumentation window. :param argument_uid_sys: Argument.uid :param argument_uid_user: Argument.uid :param is_supportive: Boolean :param attack: String :param gender: Gender of the author of the attack :return: """ LOG.debug("Entering get_array_for_reaction") slug = self.db_issue.slug db_sys_argument = DBDiscussionSession.query(Argument).get(argument_uid_sys) db_user_argument = DBDiscussionSession.query(Argument).get(argument_uid_user) statements_array = [] if not db_sys_argument or not db_user_argument: return {'elements': statements_array, 'extras': {'cropped_list': False}} rel_dict = get_relation_text_dict_with_substitution(self.lang, True, attack_type=attack, gender=gender) mode = Attitudes.AGREE if is_supportive else Attitudes.DISAGREE _um = UrlManager(slug, history=self.path) relations = [relation for relation in Relations] for relation in relations: url = self.__get_url_based_on_relation(relation, attack, _um, mode, db_user_argument, db_sys_argument) d = {'title': rel_dict[relation.value + '_text'], 'id': relation.value} tmp = self.__create_answer_dict(relation.value, [d], relation.value, url) statements_array.append(tmp) # last item is the change attack button or step back, if we have bno other attack attacking_arg_uids = get_all_attacking_arg_uids_from_history(self.path) attacking_arg_uids.append(argument_uid_sys) arg_id_sys, new_attack = attacks.get_attack_for_argument(argument_uid_user, restrictive_arg_uids=attacking_arg_uids, history=self.path) if not new_attack: url = _um.get_last_valid_url_before_reaction() relation = 'step_back' else: relation = 'no_opinion' url = _um.get_url_for_reaction_on_argument(argument_uid_user, new_attack, arg_id_sys) statements_array.append( self.__create_answer_dict(relation, [{'title': rel_dict[relation + '_text'], 'id': relation}], relation, url)) return {'elements': statements_array, 'extras': {'cropped_list': False}}
def get_url_for_new_argument(self, new_argument_uids: list) -> str: """ Returns url for the reaction on a new argument :param new_argument_uids: List of Argument.uid :return: String """ new_argument_uid = random.choice(new_argument_uids) # TODO eliminate random attacking_arg_uids = get_all_attacking_arg_uids_from_history(self.history) arg_id_sys, attack = attacks.get_attack_for_argument(new_argument_uid, restrictive_arg_uids=attacking_arg_uids) if not arg_id_sys: url = self.get_url_for_discussion_finish(new_argument_uid) else: url = self.get_url_for_reaction_on_argument(new_argument_uid, attack, arg_id_sys) return url
def __get_statement_array_for_justify_argument(self, argument_uid, attack_type, db_user, history, argument, uids, _um): if db_user and db_user.nickname != nick_of_anonymous_user: # add seen by if the statement is visible add_seen_argument(argument_uid, db_user) # get all premises in this group db_premises = DBDiscussionSession.query(Premise).filter_by( premisegroup_uid=argument.premisegroup_uid).all() premises_array = [] for premise in db_premises: text = premise.get_text() premises_array.append({ 'id': premise.statement_uid, 'title': text }) # for each justifying premise, we need a new confrontation: (restriction is based on fix #38) is_undermine = Relations.UNDERMINE if attack_type == Relations.UNDERMINE else None attacking_arg_uids = get_all_attacking_arg_uids_from_history(self.path) arg_id_sys, attack = attacks.get_attack_for_argument(argument.uid, last_attack=is_undermine, restrictive_arg_uids=attacking_arg_uids, history=self.path) the_other_one = True url = '' # with a chance of 50% or at the end we will seed the new "support step" if not attack: new_arg = get_another_argument_with_same_conclusion(argument.uid, history) the_other_one = new_arg is None if new_arg: the_other_one = False url = _um.get_url_for_support_each_other(argument.uid, new_arg.uid) if the_other_one: url = _um.get_url_for_reaction_on_argument(argument.uid, attack, arg_id_sys) return self.__create_answer_dict(argument.uid, premises_array, 'justify', url, is_markable=True, is_editable=not EditQueue().is_arguments_premise_in_edit_queue(argument), is_author=is_author_of_argument(db_user, argument.uid), is_visible=argument.uid in uids, attack_url=_um.get_url_for_jump(argument.uid))
def __get_statement_array_for_justify_statement(self, db_user, history, argument, uids, _tn, _um): if db_user and argument.uid in uids: # add seen by if the statement is visible add_seen_argument(argument.uid, db_user) # get all premises in the premisegroup of this argument db_premises = DBDiscussionSession.query(Premise).filter_by( premisegroup_uid=argument.premisegroup_uid).all() premise_array = [] for premise in db_premises: text = premise.get_text() premise_array.append({'title': text, 'id': premise.statement_uid}) # filter forbidden attacks forbidden_attacks = attacks.get_forbidden_attacks_based_on_history(self.path) # get attack for each premise, so the urls will be unique arg_id_sys, attack = attacks.get_attack_for_argument(argument.uid, history=self.path, restrictive_arg_uids=forbidden_attacks) already_used = 'reaction/' + str(argument.uid) + '/' in self.path additional_text = '(' + _tn.get(_.youUsedThisEarlier) + ')' url = _um.get_url_for_discussion_finish( argument.uid) # finish the discussion if D-BAS can't find something to talk about if attack: # if there is an attack get the url to a reaction url = _um.get_url_for_reaction_on_argument(argument.uid, attack.value, arg_id_sys) else: # if there is no attack, search for an argument to ask the user about new_arg = get_another_argument_with_same_conclusion(argument.uid, history) if new_arg: # if one is found: get the url url = _um.get_url_for_support_each_other(argument.uid, new_arg.uid) return self.__create_answer_dict(str(argument.uid), premise_array, 'justify', url, already_used=already_used, already_used_text=additional_text, is_editable=not EditQueue().is_arguments_premise_in_edit_queue(argument), is_markable=True, is_author=is_author_of_argument(db_user, argument.uid), is_visible=argument.uid in uids, attack_url=_um.get_url_for_jump(argument.uid))
def test_get_attack_for_argument(self): results = { None: None, 39: Relations.REBUT, 44: Relations.UNDERMINE, 43: Relations.UNDERCUT } restriction_on_args = [40] db_all: List[Argument] = DBDiscussionSession.query(Argument).all() for arg in db_all: arg.set_disabled(False) transaction.commit() for i in range(0, 4): attack_uid, key = attacks.get_attack_for_argument( argument_uid=42, restrictive_attacks=None, restrictive_arg_uids=restriction_on_args, last_attack=None, history='') self.assertEqual(key, results[attack_uid]) restriction_on_args.append(attack_uid)
def get_array_for_choosing(self, argument_or_statement_id, pgroup_ids, is_argument, is_supportive, nickname): """ Prepares the dict with all items for the choosing an premise, when the user inserted more than one new premise. :param argument_or_statement_id: Argument.uid or Statement.uid :param pgroup_ids: PremiseGroups.uid :param is_argument: Boolean :param is_supportive: Boolean :param nickname: :return: dict() """ logger('ItemDictHelper', 'def') statements_array = [] slug = self.db_issue.slug _um = UrlManager(slug, history=self.path) conclusion_uid = argument_or_statement_id if not is_argument else None argument_uid = argument_or_statement_id if is_argument else None db_user = DBDiscussionSession.query(User).filter_by( nickname=nickname).first() for group_id in pgroup_ids: db_premises = DBDiscussionSession.query(Premise).filter_by( premisegroup_uid=group_id).all() premise_array = [] for premise in db_premises: text = premise.get_text() premise_array.append({ 'title': text, 'id': premise.statement_uid }) if db_user and db_user.nickname != nick_of_anonymous_user: # add seen by if the statement is visible add_seen_statement(premise.statement_uid, db_user) # get attack for each premise, so the urls will be unique db_argument = DBDiscussionSession.query(Argument).filter( Argument.premisegroup_uid == group_id, Argument.is_supportive == is_supportive) if conclusion_uid and not is_argument: db_argument = db_argument.filter_by( conclusion_uid=conclusion_uid).first() else: db_argument = db_argument.filter_by( argument_uid=argument_uid).first() if not db_argument: print(group_id) return { 'elements': statements_array, 'extras': { 'cropped_list': False } } attacking_arg_uids = get_all_attacking_arg_uids_from_history( self.path) arg_id_sys, attack = attacks.get_attack_for_argument( db_argument.uid, restrictive_arg_uids=attacking_arg_uids) url = _um.get_url_for_reaction_on_argument(db_argument.uid, attack, arg_id_sys) if is_argument: is_author = is_author_of_argument(db_user, argument_uid) else: is_author = is_author_of_statement(db_user, conclusion_uid) statements_array.append( self.__create_answer_dict(str(db_argument.uid), premise_array, 'choose', url, is_markable=True, is_editable=True, is_author=is_author)) return { 'elements': statements_array, 'extras': { 'cropped_list': False } }
def get_array_for_justify_argument(self, argument_uid, attack_type, db_user, history): """ Prepares the dict with all items for a step in discussion, where the user justifies his attack she has done. :param argument_uid: Argument.uid :param attack_type: String :param db_user: :param history: :return: """ logger('ItemDictHelper', 'def: arg {}, attack {}'.format(argument_uid, attack_type)) statements_array = [] _tn = Translator(self.lang) slug = self.db_issue.slug # description in docs: dbas/logic db_arguments = self.__get_arguments_based_on_attack( attack_type, argument_uid) uids = [argument.uid for argument in db_arguments if db_arguments] _um = UrlManager(slug, history=self.path) for argument in db_arguments: if db_user and db_user.nickname != nick_of_anonymous_user: # add seen by if the statement is visible add_seen_argument(argument_uid, db_user) # get all premises in this group db_premises = DBDiscussionSession.query(Premise).filter_by( premisegroup_uid=argument.premisegroup_uid).all() premises_array = [] for premise in db_premises: text = premise.get_text() premises_array.append({ 'id': premise.statement_uid, 'title': text }) # for each justifying premise, we need a new confrontation: (restriction is based on fix #38) is_undermine = Relations.UNDERMINE if attack_type == Relations.UNDERMINE else None attacking_arg_uids = get_all_attacking_arg_uids_from_history( self.path) arg_id_sys, attack = attacks.get_attack_for_argument( argument.uid, last_attack=is_undermine, restrictive_arg_uids=attacking_arg_uids, history=self.path) the_other_one = True url = '' # with a chance of 50% or at the end we will seed the new "support step" if not attack: new_arg = get_another_argument_with_same_conclusion( argument.uid, history) the_other_one = new_arg is None if new_arg: the_other_one = False url = _um.get_url_for_support_each_other( argument.uid, new_arg.uid) if the_other_one: url = _um.get_url_for_reaction_on_argument( argument.uid, attack, arg_id_sys) statements_array.append( self.__create_answer_dict( argument.uid, premises_array, 'justify', url, is_markable=True, is_editable=not is_arguments_premise_in_edit_queue( argument), is_author=is_author_of_argument(db_user, argument.uid), is_visible=argument.uid in uids, attack_url=_um.get_url_for_jump(argument.uid))) shuffle_list_by_user(db_user, statements_array) if not self.issue_read_only: if db_user and db_user.nickname != nick_of_anonymous_user: text = _tn.get(_.newPremiseRadioButtonText) if len(statements_array) == 0: text = _tn.get(_.newPremiseRadioButtonTextAsFirstOne) a_dict = self.__create_answer_dict('justify_premise', [{ 'id': '0', 'title': text }], 'justify', 'add') statements_array.append(a_dict) else: # elif len(statements_array) == 1: a_dict = self.__create_answer_dict( 'login', [{ 'id': '0', 'title': _tn.get(_.onlyOneItem) }], 'justify', 'login') statements_array.append(a_dict) return { 'elements': statements_array, 'extras': { 'cropped_list': len(uids) < len(db_arguments) } }
def get_array_for_justify_statement(self, db_statement: Statement, db_user: User, is_supportive: bool, history): """ Prepares the dict with all items for the third step in discussion, where the user justifies his position. :param db_statement: Statement :param db_user: User :param is_supportive: Boolean :param history: history :return: """ logger('ItemDictHelper', 'def') statements_array = [] _tn = Translator(self.lang) slug = self.db_issue.slug db_arguments: List[Argument] = attacks.get_arguments_by_conclusion( db_statement.uid, is_supportive) uids: List[int] = [ argument.uid for argument in db_arguments if db_arguments ] _um = UrlManager(slug, history=self.path) for argument in db_arguments: if db_user and argument.uid in uids: # add seen by if the statement is visible add_seen_argument(argument.uid, db_user) # get all premises in the premisegroup of this argument db_premises = DBDiscussionSession.query(Premise).filter_by( premisegroup_uid=argument.premisegroup_uid).all() premise_array = [] for premise in db_premises: text = premise.get_text() premise_array.append({ 'title': text, 'id': premise.statement_uid }) # filter forbidden attacks forbidden_attacks = attacks.get_forbidden_attacks_based_on_history( self.path) # get attack for each premise, so the urls will be unique arg_id_sys, attack = attacks.get_attack_for_argument( argument.uid, history=self.path, restrictive_arg_uids=forbidden_attacks) already_used = 'reaction/' + str(argument.uid) + '/' in self.path additional_text = '(' + _tn.get(_.youUsedThisEarlier) + ')' new_arg = None url = None if not attack: new_arg = get_another_argument_with_same_conclusion( argument.uid, history) if new_arg: url = _um.get_url_for_support_each_other( argument.uid, new_arg.uid) if attack or new_arg is None or url is None: url = _um.get_url_for_reaction_on_argument( argument.uid, attack.value, arg_id_sys) statements_array.append( self.__create_answer_dict( str(argument.uid), premise_array, 'justify', url, already_used=already_used, already_used_text=additional_text, is_editable=not is_arguments_premise_in_edit_queue( argument), is_markable=True, is_author=is_author_of_argument(db_user, argument.uid), is_visible=argument.uid in uids, attack_url=_um.get_url_for_jump(argument.uid))) shuffle_list_by_user(db_user, statements_array) if not self.issue_read_only: if db_user and db_user.nickname != nick_of_anonymous_user: statements_array.append( self.__create_answer_dict( 'start_premise', [{ 'title': _tn.get(_.newPremiseRadioButtonText), 'id': 0 }], 'justify', 'add')) else: statements_array.append( self.__create_answer_dict( 'login', [{ 'id': '0', 'title': _tn.get(_.onlyOneItem) }], 'justify', 'login')) return { 'elements': statements_array, 'extras': { 'cropped_list': len(uids) < len(db_arguments) } }