Beispiel #1
0
def __add_merge_review(pgroup_uid, user_uid, text_values):
    """
    Adds a row in the ReviewMerge table as well as the values, if not none

    :param pgroup_uid: ID of the selected PremiseGroup
    :param user_uid: ID of the user
    :param text_values: text values or None, if you want to merge the premisegroup itself
    :return: None
    """
    logger(
        'FlagingHelper',
        'Flag pgroup {} by user {} for merging with additional values: {}'.
        format(pgroup_uid, user_uid, text_values))
    review_merge = ReviewMerge(detector=user_uid, premisegroup=pgroup_uid)
    DBDiscussionSession.add(review_merge)
    DBDiscussionSession.flush()

    if text_values:
        DBDiscussionSession.add_all([
            ReviewMergeValues(review=review_merge.uid, content=value)
            for value in text_values
        ])
        DBDiscussionSession.flush()

    transaction.commit()
def set_statements_as_new_premisegroup(statements: List[Statement],
                                       db_user: User, db_issue: Issue):
    """
    Set the given statements together as new premise group

    :param statements: [Statement]
    :param db_user: User
    :param db_issue: Issue
    :return: PremiseGroup.uid
    """
    LOG.debug("User: %s, statement: %s, issue: %s", db_user.uid,
              [s.uid for s in statements], db_issue.uid)
    # check for duplicate
    all_groups = []
    for statement in statements:
        # get the premise
        db_premise = DBDiscussionSession.query(Premise).filter_by(
            statement_uid=statement.uid).first()
        if db_premise:
            # getting all groups, where the premise is member
            db_premisegroup = DBDiscussionSession.query(Premise).filter_by(
                premisegroup_uid=db_premise.premisegroup_uid).all()
            groups = set()
            for group in db_premisegroup:
                groups.add(group.premisegroup_uid)
            all_groups.append(groups)
    # if every set in this array has one common member, they are all in the same group
    if len(all_groups) > 0:
        intersec = set.intersection(*all_groups)
        for group in intersec:
            db_premise = DBDiscussionSession.query(Premise).filter_by(
                premisegroup_uid=group).all()
            if len(db_premise) == len(statements):
                return DBDiscussionSession.query(PremiseGroup).get(group)

    premise_group = PremiseGroup(author=db_user.uid)
    DBDiscussionSession.add(premise_group)
    DBDiscussionSession.flush()

    premise_list = []
    for statement in statements:
        premise = Premise(premisesgroup=premise_group.uid,
                          statement=statement.uid,
                          is_negated=False,
                          author=db_user.uid,
                          issue=db_issue.uid)
        premise_list.append(premise)

    DBDiscussionSession.add_all(premise_list)
    DBDiscussionSession.flush()

    db_premisegroup = DBDiscussionSession.query(PremiseGroup).filter_by(
        author_uid=db_user.uid).order_by(PremiseGroup.uid.desc()).first()

    return db_premisegroup
Beispiel #3
0
def set_new_undermine_or_support_for_pgroup(premisegroup_uid: int,
                                            current_argument: Argument,
                                            is_supportive: bool, db_user: User,
                                            db_issue: Issue):
    """
    Inserts a new undermine or support with the given parameters.

    :param premisegroup_uid: premisegroup_uid
    :param current_argument: Argument
    :param is_supportive: Boolean
    :param db_user: User
    :param issue: Issue.uid
    :return: Argument, Boolean if the argument is a duplicate
    """
    already_in = []

    # all premises out of current pgroup
    db_premises = DBDiscussionSession.query(Premise).filter_by(
        premisegroup_uid=current_argument.premisegroup_uid).all()
    for premise in db_premises:
        new_arguments = []
        db_arguments = get_enabled_arguments_as_query()
        db_argument = db_arguments.filter(
            Argument.premisegroup_uid == premisegroup_uid,
            Argument.is_supportive == True,
            Argument.conclusion_uid == premise.statement_uid).first()
        if db_argument:
            continue

        db_tmp = DBDiscussionSession.query(Premise).filter_by(
            premisegroup_uid=premisegroup_uid).all()
        if any([p.statement_uid == premise.statement_uid for p in db_tmp]):
            return False

        new_arguments.append(
            Argument(premisegroup=premisegroup_uid,
                     is_supportive=is_supportive,
                     author=db_user.uid,
                     issue=db_issue.uid,
                     conclusion=premise.statement_uid))

        if len(new_arguments) > 0:
            DBDiscussionSession.add_all(new_arguments)
            DBDiscussionSession.flush()
            transaction.commit()

            already_in += new_arguments

    rnd = random.randint(0, len(already_in) - 1)
    return already_in[rnd]
Beispiel #4
0
def send_notification(from_user, to_user, topic, content, mainpage):
    """
    Sends message to an user and places a copy in the outbox of current user. Returns the uid and timestamp

    :param from_user: User
    :param to_user: User
    :param topic: String
    :param content: String
    :param mainpage: String
    :return:
    """
    content = escape_string(content)
    notification_in = Message(from_author_uid=from_user.uid,
                              to_author_uid=to_user.uid,
                              topic=topic,
                              content=content,
                              is_inbox=True)
    notification_out = Message(from_author_uid=from_user.uid,
                               to_author_uid=to_user.uid,
                               topic=topic,
                               content=content,
                               is_inbox=False,
                               read=True)
    DBDiscussionSession.add_all([notification_in, notification_out])
    DBDiscussionSession.flush()
    transaction.commit()

    db_settings = to_user.settings
    if db_settings.should_send_notifications:
        user_lang = DBDiscussionSession.query(Language).get(
            db_settings.lang_uid).ui_locales
        _t_user = Translator(user_lang)
        send_request_for_info_popup_to_socketio(to_user.nickname,
                                                _t_user.get(_.newNotification),
                                                mainpage + '/notifications',
                                                increase_counter=True)

    db_inserted_notification = DBDiscussionSession.query(Message).filter(
        Message.from_author_uid == from_user.uid,
        Message.to_author_uid == to_user.uid, Message.topic == topic,
        Message.content == content,
        Message.is_inbox == True).order_by(Message.uid.desc()).first()

    return db_inserted_notification
Beispiel #5
0
def __add_split_review(pgroup_uid, user_uid, text_values):
    """
    Adds a row in the ReviewSplit table as well as the values, if not none

    :param pgroup_uid: ID of the selected PremiseGroup
    :param user_uid: ID of the user
    :param text_values: text values or None, if you want to split the premisegroup itself
    :return: None
    """
    LOG.debug("Flag pgroup %s by user %s for merging with additional values %s", pgroup_uid, user_uid, text_values)
    review_split = ReviewSplit(detector=user_uid, premisegroup=pgroup_uid)
    DBDiscussionSession.add(review_split)
    DBDiscussionSession.flush()

    if text_values:
        DBDiscussionSession.add_all(
            [ReviewSplitValues(review=review_split.uid, content=value) for value in text_values])
        DBDiscussionSession.flush()

    transaction.commit()
Beispiel #6
0
def set_statements_as_new_premisegroup(statements: List[Statement],
                                       db_user: User,
                                       db_issue: Issue) -> PremiseGroup:
    """
    Set the given statements together as new premise group

    Re-uses existing premise groups containing the same statements.

    :param statements: [Statement]
    :param db_user: User
    :param db_issue: Issue
    :return: PremiseGroup
    """
    LOG.debug("User: %s, statement: %s, issue: %s", db_user.uid,
              [s.uid for s in statements], db_issue.uid)
    # check for duplicate
    existing_premisegroup = find_existing_premisegroup(statements)
    if existing_premisegroup is not None:
        return existing_premisegroup

    premise_group = PremiseGroup(author=db_user.uid)
    DBDiscussionSession.add(premise_group)
    DBDiscussionSession.flush()

    premise_list = []
    for statement in statements:
        premise = Premise(premisesgroup=premise_group.uid,
                          statement=statement.uid,
                          is_negated=False,
                          author=db_user.uid,
                          issue=db_issue.uid)
        premise_list.append(premise)

    DBDiscussionSession.add_all(premise_list)
    DBDiscussionSession.flush()

    db_premisegroup = DBDiscussionSession.query(PremiseGroup).filter_by(
        author_uid=db_user.uid).order_by(PremiseGroup.uid.desc()).first()

    return db_premisegroup
Beispiel #7
0
def __process_input_premises_for_arguments_and_receive_url(
        langs: dict, arg_infos: dict, db_issue: Issue, db_user: User,
        mailer) -> Tuple[Optional[str], Optional[List[int]], str]:
    """
    Inserts given text in premisegroups as new arguments in dependence of the parameters and returns a URL

    :param langs: dict with default_locale_name and discussion_lang
    :param arg_infos: dict with arg_id, attack_type, premisegroups and the history
    :param db_issue: Issue
    :param db_user: User
    :return: URL, [Statement.uids], String
    """
    discussion_lang = langs['discussion_lang']
    arg_id: int = arg_infos['arg_id']
    attack_type: str = arg_infos['attack_type']
    premisegroups = arg_infos['premisegroups']
    history = arg_infos['history']

    LOG.debug("Count of new pgroups: %s", len(premisegroups))
    _tn = Translator(discussion_lang)

    slug = db_issue.slug
    error = ''

    # insert all premise groups into our database
    # all new arguments are collected in a list
    new_argument_uids = []
    for premisegroup in premisegroups:  # premise groups is a list of lists
        new_argument = insert_new_premises_for_argument(
            premisegroup, attack_type, arg_id, db_issue, db_user)
        if not isinstance(new_argument, Argument):  # break on error
            a = _tn.get(_.notInsertedErrorBecauseEmpty)
            b = _tn.get(_.minLength)
            c = environ.get('MIN_LENGTH_OF_STATEMENT', 10)
            d = _tn.get(_.eachStatement)
            if isinstance(new_argument, str):
                error = new_argument
            else:
                error = '{} ({}: {} {})'.format(a, b, c, d)
            return None, None, error

        new_argument_uids.append(new_argument.uid)

    statement_uids = []
    # @OPTIMIZE
    # Query all recently stored premises (internally: statements) and collect their ids
    # This is a bad workaround, let's just think about it in future.
    for uid in new_argument_uids:
        current_pgroup = DBDiscussionSession.query(Argument).get(
            uid).premisegroup_uid
        current_premises = DBDiscussionSession.query(Premise).filter_by(
            premisegroup_uid=current_pgroup).all()
        for premise in current_premises:
            statement_uids.append(premise.statement_uid)

    # #arguments=0: empty input
    # #arguments=1: deliver new url
    # #arguments>1: deliver url where the nickname has to choose between her inputs
    _um = url = UrlManager(slug, history)
    if len(new_argument_uids) == 0:
        a = _tn.get(_.notInsertedErrorBecauseEmpty)
        b = _tn.get(_.minLength)
        c = environ.get('MIN_LENGTH_OF_STATEMENT', 10)
        error = '{} ({}: {})'.format(a, b, c)

    elif len(new_argument_uids) == 1:
        url = _um.get_url_for_new_argument(new_argument_uids)

    else:
        url = __receive_url_for_processing_input_of_multiple_premises_for_arguments(
            new_argument_uids, _um)

    # send notifications and mails
    if len(new_argument_uids) > 0:
        # add marked arguments
        DBDiscussionSession.add_all([
            MarkedArgument(argument=uid, user=db_user.uid)
            for uid in new_argument_uids
        ])
        DBDiscussionSession.flush()
        transaction.commit()

        new_uid = random.choice(new_argument_uids)  # TODO eliminate random
        attack = get_relation_between_arguments(arg_id, new_uid)

        tmp_url = _um.get_url_for_reaction_on_argument(arg_id, attack, new_uid)

        nh.send_add_argument_notification(tmp_url, arg_id, db_user.nickname,
                                          mailer)

    return url, statement_uids, error
Beispiel #8
0
def __proposal_for_the_element(db_review, data, db_user):
    """
    Adds proposal for the ReviewEdit

    :param db_review: ReviewEdit
    :param data: String
    :param db_user: User
    :return: None
    """
    # sort the new edits by argument uid
    argument_dict, statement_dict = __prepare_dicts_for_proposals(data)

    logger(
        'review.opinions', 'detector {}, statements {}, arguments {}'.format(
            db_user.uid, statement_dict, argument_dict))

    # add reviews
    new_edits = list()
    for argument_uid in argument_dict:
        DBDiscussionSession.add(
            ReviewEdit(detector=db_user.uid, argument=argument_uid))
        DBDiscussionSession.flush()
        transaction.commit()
        db_review_edit = DBDiscussionSession.query(ReviewEdit).filter(
            ReviewEdit.detector_uid == db_user.uid,
            ReviewEdit.argument_uid == argument_uid).order_by(
                ReviewEdit.uid.desc()).first()
        logger(
            'review.opinions', 'New ReviewEdit with uid ' +
            str(db_review_edit.uid) + ' (argument)')

        for edit in argument_dict[argument_uid]:
            new_edits.append(
                ReviewEditValue(review_edit=db_review_edit.uid,
                                statement=edit['uid'],
                                typeof=edit['type'],
                                content=edit['val']))

    for statement_uid in statement_dict:
        DBDiscussionSession.add(
            ReviewEdit(detector=db_user.uid, statement=statement_uid))
        DBDiscussionSession.flush()
        transaction.commit()
        db_review_edit = DBDiscussionSession.query(ReviewEdit).filter(
            ReviewEdit.detector_uid == db_user.uid,
            ReviewEdit.statement_uid == statement_uid).order_by(
                ReviewEdit.uid.desc()).first()
        logger(
            'review.opinions', 'New ReviewEdit with uid ' +
            str(db_review_edit.uid) + ' (statement)')

        for edit in statement_dict[statement_uid]:
            new_edits.append(
                ReviewEditValue(review_edit=db_review_edit.uid,
                                statement=statement_uid,
                                typeof=edit['type'],
                                content=edit['val']))

    if len(new_edits) > 0:
        DBDiscussionSession.add_all(new_edits)

    # edit given, so this review is executed
    db_review.set_executed(True)
    db_review.update_timestamp()
    DBDiscussionSession.add(db_review)
    DBDiscussionSession.flush()
    transaction.commit()
Beispiel #9
0
    def __proposal_for_the_element(self, db_review: ReviewOptimization,
                                   data: dict, db_user: User):
        """
        Adds proposal for the ReviewEdit

        :param db_review: ReviewEdit
        :param data: dict
        :param db_user: User
        :return: None
        """
        # sort the new edits by argument uid
        argument_dict, statement_dict = self.__prepare_dicts_for_proposals(
            data)

        LOG.debug("Detector %s, statements %s, arguments %s", db_user.uid,
                  statement_dict, argument_dict)

        # add reviews
        new_edits = list()
        for argument_uid in argument_dict:
            DBDiscussionSession.add(
                ReviewEdit(detector=db_user.uid, argument=argument_uid))
            DBDiscussionSession.flush()
            transaction.commit()
            db_review_edit = DBDiscussionSession.query(ReviewEdit).filter(
                ReviewEdit.detector_uid == db_user.uid,
                ReviewEdit.argument_uid == argument_uid).order_by(
                    ReviewEdit.uid.desc()).first()
            LOG.debug("New ReviewEdit with uid %s (argument)",
                      db_review_edit.uid)

            for edit in argument_dict[argument_uid]:
                new_edits.append(
                    ReviewEditValue(review_edit=db_review_edit.uid,
                                    statement=edit['uid'],
                                    typeof=edit['type'],
                                    content=edit['val']))

        for statement_uid in statement_dict:
            DBDiscussionSession.add(
                ReviewEdit(detector=db_user.uid, statement=statement_uid))
            DBDiscussionSession.flush()
            transaction.commit()
            db_review_edit = DBDiscussionSession.query(ReviewEdit).filter(
                ReviewEdit.detector_uid == db_user.uid,
                ReviewEdit.statement_uid == statement_uid).order_by(
                    ReviewEdit.uid.desc()).first()
            LOG.debug("New ReviewEdit with uid %s (statement)",
                      db_review_edit.uid)

            for edit in statement_dict[statement_uid]:
                new_edits.append(
                    ReviewEditValue(review_edit=db_review_edit.uid,
                                    statement=statement_uid,
                                    typeof=edit['type'],
                                    content=edit['val']))

        if len(new_edits) > 0:
            DBDiscussionSession.add_all(new_edits)

        # edit given, so this review is executed
        db_review.set_executed(True)
        db_review.update_timestamp()
        DBDiscussionSession.add(db_review)
        DBDiscussionSession.flush()
        transaction.commit()
Beispiel #10
0
def send_edit_text_notification(db_user, textversion, path, mailer):
    """
    Sends an notification to the root-author and last author, when their text was edited.

    :param db_user: Current User
    :param textversion: new Textversion
    :param path: curren path
    :param mailer: Instance of pyramid mailer
    :return: None
    """
    all_textversions = DBDiscussionSession.query(TextVersion).filter_by(
        statement_uid=textversion.statement_uid).order_by(
            TextVersion.uid.desc()).all()  # TODO #432
    oem = all_textversions[-1]
    root_author = oem.author_uid
    new_author = textversion.author_uid
    last_author = all_textversions[-2].author_uid if len(
        all_textversions) > 1 else root_author
    settings_root_author = root_author.settings
    settings_last_author = last_author.settings

    # create content
    db_editor = DBDiscussionSession.query(User).get(new_author)
    db_settings = db_editor.settings
    editor_ui_locales = db_settings.lang

    # add some information for highlights
    if path is not None:
        path += '?edited_statement=' + str(textversion.statement_uid)

    if settings_root_author.should_send_mails is True \
            and root_author != db_user.uid \
            and path is not None:
        email_helper.send_mail_due_to_edit_text(textversion.statement_uid,
                                                root_author, db_editor, path,
                                                mailer)

    if new_author != last_author \
            and settings_last_author.should_send_mails is True \
            and new_author != db_user.uid \
            and path is not None:
        email_helper.send_mail_due_to_edit_text(textversion.statement_uid,
                                                last_author, db_editor, path,
                                                mailer)

    # check for different authors
    if root_author == new_author:
        return None

    # send notifications
    user_lang1 = DBDiscussionSession.query(Language).get(
        settings_root_author.lang_uid).ui_locales
    user_lang2 = DBDiscussionSession.query(Language).get(
        settings_last_author.lang_uid).ui_locales
    if settings_root_author.should_send_notifications \
            and root_author != db_user.uid:
        _t_user = Translator(user_lang1)
        db_root_author = DBDiscussionSession.query(User).get(root_author)
        send_request_for_info_popup_to_socketio(db_root_author.nickname,
                                                _t_user.get(_.textChange),
                                                path,
                                                increase_counter=True)

    if last_author != root_author \
            and last_author != new_author \
            and last_author != db_user.uid \
            and settings_last_author.should_send_notifications:
        _t_user = Translator(user_lang2)
        db_last_author = DBDiscussionSession.query(User).get(last_author)
        send_request_for_info_popup_to_socketio(db_last_author.nickname,
                                                _t_user.get(_.textChange),
                                                path,
                                                increase_counter=True)

    _t1 = Translator(user_lang1)
    topic1 = _t1.get(_.textversionChangedTopic)
    content1 = get_text_for_edit_text_message(editor_ui_locales,
                                              db_editor.public_nickname,
                                              textversion.content, oem.content,
                                              path)

    _t2 = Translator(user_lang2)
    topic2 = _t2.get(_.textversionChangedTopic)
    content2 = get_text_for_edit_text_message(editor_ui_locales,
                                              db_editor.public_nickname,
                                              textversion.content, oem.content,
                                              path)

    notifications = []
    if new_author != root_author:
        notifications.append(
            Message(from_author_uid=new_author,
                    to_author_uid=root_author,
                    topic=topic1,
                    content=content1,
                    is_inbox=True))
    if new_author != last_author:
        notifications.append(
            Message(from_author_uid=new_author,
                    to_author_uid=last_author,
                    topic=topic2,
                    content=content2,
                    is_inbox=True))
    if len(notifications) > 0:
        DBDiscussionSession.add_all(notifications)
        DBDiscussionSession.flush()