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
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]
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
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()
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
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
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()
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()
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()