Exemple #1
0
def review_content(request):
    """
    View configuration for the review content.

    :param request: current request of the server
    :return: dictionary with title and project name as well as a value, weather the user is logged in
    """
    logger('review_content', 'def {}'.format(request.matchdict))
    ui_locales = get_language_from_cookie(request)
    _tn = Translator(ui_locales)

    subpage_name = request.matchdict['queue']
    nickname = request.authenticated_userid
    session = request.session
    application_url = request.application_url
    subpage_dict = review_page_helper.get_subpage_elements_for(
        nickname, session, application_url, subpage_name, _tn)
    request.session.update(subpage_dict['session'])
    if not subpage_dict['elements'] and not subpage_dict[
            'has_access'] and not subpage_dict['no_arguments_to_review']:
        logger('review_content', 'subpage error', error=True)
        raise HTTPNotFound()

    title = _tn.get(_.review)
    if subpage_name in review_queue_helper.title_mapping:
        title = _tn.get(review_queue_helper.title_mapping[subpage_name])

    prep_dict = __main_dict(request, title)
    prep_dict.update({
        'extras': request.decorated['extras'],
        'subpage': subpage_dict,
        'lock_time': review_queue_helper.max_lock_time_in_sec
    })
    return prep_dict
def __check_for_empty_fields(title: str, info: str, long_info: str,
                             request: dict) -> dict:
    """
    This method checks if there is a empty field in the data of the new issue.
    It also creates a error-message with the empty fields.

    :param title: The title of the new issue
    :param info: The info of the new issue
    :param long_info: The long info of the new issue
    :param request: The request with the data of the new issue
    :return: a dict with a boolean which tells if there is any empty field and a equivalent error-message.
    """
    _tn = Translator(get_language_from_cookie(request))
    error = _tn.get(_.newIssueErrorMsg) + ': '

    title_is_empty = title.strip() == ''
    info_is_empty = info.strip() == ''
    long_info_is_emtpy = long_info.strip() == ''

    if title_is_empty:
        error = error + _tn.get(_.newIssueTitle) + ', '
    if info_is_empty:
        error = error + _tn.get(_.newIssueInfo) + ', '
    if long_info_is_emtpy:
        error = error + _tn.get(_.newIssueLongInfo) + ', '

    return {
        "contains_empty_field": title_is_empty or info_is_empty
        or long_info_is_emtpy,
        "error": error[:-2]
    }
def valid_conclusion(request):
    """
    Given a conclusion id, query the object from the database and return it in the request.

    :param request:
    :return:
    """
    conclusion_id = request.json_body.get('conclusion_id')
    issue = request.validated.get('issue')
    _tn = Translator(get_language_from_cookie(request))

    if not issue:
        find_issue_in_request = issue_handler.get_issue_id(request)
        if find_issue_in_request:
            issue = DBDiscussionSession.query(Issue).get(
                issue_handler.get_issue_id(request))
        else:
            add_error(request, 'Issue is missing', _tn.get(_.issueNotFound))
            return False

    if conclusion_id and isinstance(conclusion_id, int):
        db_statement2issue = DBDiscussionSession.query(
            StatementToIssue).filter(
                StatementToIssue.issue_uid == issue.uid,
                StatementToIssue.statement_uid == conclusion_id).first()
        if db_statement2issue:
            db_conclusion = DBDiscussionSession.query(Statement).filter_by(
                uid=conclusion_id, is_disabled=False).first()
            if db_conclusion:
                request.validated['conclusion'] = db_conclusion
                return True

    add_error(request, 'Conclusion id is missing',
              _tn.get(_.conclusionIsMissing))
    return False
Exemple #4
0
    def get_dict_for_jump(self, uid) -> dict:
        """
        Prepares the discussion dict with all bubbles for the jump step

        :param uid: Argument.uid
        :return: dict()
        """
        logger('DictionaryHelper', 'argument ' + str(uid))
        _tn = Translator(self.lang)
        argument_text = get_text_for_argument_uid(uid,
                                                  colored_position=True,
                                                  with_html_tag=True,
                                                  attack_type='jump')
        bubbles_array = history_helper.create_bubbles_from_history(
            self.history, self.nickname, self.lang, self.slug)

        coming_from_jump = False
        if self.history:
            splitted_history = self.history.split('-')
            coming_from_jump = '/jump' in self.history[:-1] if len(
                splitted_history) > 0 else False
        intro = (_tn.get(_.canYouBeMorePrecise) +
                 '<br><br>') if coming_from_jump else ''

        db_argument = DBDiscussionSession.query(Argument).get(uid)
        if db_argument.conclusion_uid is not None:
            intro += _tn.get(_.whatDoYouThinkArgument).strip() + ': '
        else:
            bind = ', ' if self.lang == 'de' else ' '
            intro += _tn.get(_.whatDoYouThinkAboutThat) + bind + _tn.get(
                _.that) + ' '

        offset = len('</' + tag_type +
                     '>') if argument_text.endswith('</' + tag_type +
                                                    '>') else 1
        while argument_text[:-offset].endswith(('.', '?', '!')):
            argument_text = argument_text[:-offset -
                                          1] + argument_text[-offset:]

        text = intro + argument_text + '?'
        bubble = create_speechbubble_dict(BubbleTypes.SYSTEM,
                                          content=text,
                                          omit_bubble_url=True,
                                          lang=self.lang,
                                          uid='question-bubble-{}'.format(uid),
                                          is_markable=True)
        bubbles_array.append(bubble)

        # add statements of discussion to report them
        statement_list = self.__get_all_statement_texts_by_argument(
            db_argument)

        return {
            'bubbles': bubbles_array,
            'add_premise_text': '',
            'save_statement_url': '',
            'mode': '',
            'extras': statement_list,
            'broke_limit': self.broke_limit
        }
Exemple #5
0
def flag_statement_for_merge_or_split(key: str, pgroup: PremiseGroup,
                                      text_values: list(), db_user: User,
                                      tn: Translator) -> dict():
    """
    Flags a statement for a merge or split event

    :param key: either 'split' or 'merge'
    :param pgroup_uid: ID of the selected PremiseGroup
    :param text_values: text values
    :param nickname: Users nickname
    :return: success, info, error
    """
    logger(
        'FlagingHelper',
        'Flag statements in pgroup {} for a {} with values {}'.format(
            pgroup.uid, key, text_values))
    # was this already flagged?
    flag_status = __get_flag_status(None, None, pgroup.uid, db_user.uid)
    if flag_status:
        logger('FlagingHelper', 'already flagged')
        return {
            'success':
            '',
            'info':
            tn.get(_.alreadyFlaggedByYou if flag_status ==
                   'user' else _.alreadyFlaggedByOthers)
        }

    if key is 'merge':
        __add_merge_review(pgroup.uid, db_user.uid, text_values)
    elif key is 'split':
        __add_split_review(pgroup.uid, db_user.uid, text_values)

    return {'success': tn.get(_.thxForFlagText), 'info': ''}
Exemple #6
0
def flag_element(uid: int, reason: Union[key_duplicate, key_optimization, ReviewDeleteReasons], db_user: User,
                 is_argument: bool, ui_locales: str, extra_uid=None) -> dict:
    """
    Flags an given argument based on the reason which was sent by the author. This argument will be enqueued
    for a review process.

    :param uid: Uid of the argument/statement, which should be flagged
    :param reason: String which describes the reason
    :param db_user: User
    :param is_argument: Boolean
    :param ui_locales: ui_locales
    :param extra_uid: Uid of the argument/statement, which should be flagged
    :return: success, info, error
    """
    tn = Translator(ui_locales)

    argument_uid = uid if is_argument else None
    statement_uid = uid if not is_argument else None

    # was this already flagged?
    flag_status = QueueAdapter(db_user=db_user).element_in_queue(argument_uid=argument_uid,
                                                                 statement_uid=statement_uid,
                                                                 premisegroup_uid=None)
    if flag_status:
        LOG.debug("Already flagged by %s", flag_status)
        if flag_status == FlaggedBy.user:
            info = tn.get(_.alreadyFlaggedByYou)
        else:
            info = tn.get(_.alreadyFlaggedByOthers)
        return {'success': '', 'info': info}

    return __add_flag(reason, argument_uid, statement_uid, extra_uid, db_user, tn)
def set_statement(text: str, db_user: User, is_position: bool,
                  db_issue: Issue) -> Tuple[Statement, bool]:
    """
    Saves statement for user

    :param text: given statement
    :param db_user: User of given user
    :param is_position: if it is a start statement
    :param db_issue: Issue
    :return: Statement, is_duplicate or -1, False on error
    """

    LOG.debug("User_id: %s, text: %s, issue: %s", db_user.uid, text,
              db_issue.uid)

    # escaping and cleaning
    text = escape_string(' '.join(text.strip().split()))
    _tn = Translator(db_issue.lang)
    if text.startswith(_tn.get(_.because).lower() + ' '):
        text = text[len(_tn.get(_.because) + ' '):]
    while text.endswith(('.', '?', '!', ',')):
        text = text[:-1]

    # check, if the text already exists
    db_dupl = __check_duplicate(db_issue, text)
    if db_dupl:
        return db_dupl, True

    db_statement = __add_statement(is_position)
    __add_textversion(text, db_user.uid, db_statement.uid)
    __add_statement2issue(db_statement.uid, db_issue.uid)

    return db_statement, False
Exemple #8
0
def valid_notification_recipient(request):
    """
    Recipients must exist, author and recipient must be different users.

    :param request:
    :return:
    """
    _tn = Translator(get_language_from_cookie(request))
    if not valid_user(request):
        add_error(request, 'Not logged in', _tn.get(_.notLoggedIn))
        return False

    db_author = request.validated["user"]
    recipient_nickname = str(request.json_body.get('recipient')).replace(
        '%20', ' ')
    db_recipient = get_user_by_private_or_public_nickname(recipient_nickname)

    if not db_recipient or recipient_nickname == 'admin' or recipient_nickname == nick_of_anonymous_user:
        add_error(request, 'Recipient not found', _tn.get(_.recipientNotFound))
        return False
    elif db_author and db_author.uid == db_recipient.uid:
        add_error(request, 'Author and Recipient are the same user',
                  _tn.get(_.senderReceiverSame))
        return False
    else:
        request.validated["recipient"] = db_recipient
        return True
Exemple #9
0
def flag_statement_for_merge_or_split(key: str, pgroup: PremiseGroup, text_values: list, db_user: User,
                                      tn: Translator) -> dict:
    """
    Flags a statement for a merge or split event. On split, the statement of the pgroup will be splitted into the
    given text_values. On merge the statements of the pgroup will be connected by an and.

    :param key: either 'split' or 'merge'
    :param pgroup: ID of the selected PremiseGroup
    :param text_values: text values
    :param db_user: current user
    :param tn: The translator used
    :return: success, info
    """
    LOG.debug("Flag statements in pgroup %s for a %s with values %s", pgroup.uid, key, text_values)
    # was this already flagged?
    flag_status = QueueAdapter(db_user=db_user).element_in_queue(argument_uid=None,
                                                                 statement_uid=None,
                                                                 premisegroup_uid=pgroup.uid)
    if flag_status:
        LOG.debug("Already flagged")
        if flag_status == FlaggedBy.user:
            info = tn.get(_.alreadyFlaggedByYou)
        else:
            info = tn.get(_.alreadyFlaggedByOthers)
        return {'success': '', 'info': info}

    if key is key_merge:
        __add_merge_review(pgroup.uid, db_user.uid, text_values)
    elif key is key_split:
        __add_split_review(pgroup.uid, db_user.uid, text_values)

    success = tn.get(_.thxForFlagText)
    return {'success': success, 'info': ''}
    def get_dict_for_dont_know_reaction(self, uid, nickname) -> dict:
        """
        Prepares the discussion dict with all bubbles for the third step,
        where an supportive argument will be presented.

        :param uid: Argument.uid
        :param nickname:
        :return: dict()
        """
        LOG.debug("Entering get_dict_for_dont_know_reaction")
        _tn = Translator(self.lang)
        bubbles_array = history_handler.create_bubbles(self.history,
                                                       self.nickname,
                                                       self.lang, self.slug)
        add_premise_text = ''
        save_statement_url = 'set_new_start_statement'
        gender = ''
        b = '<' + tag_type + '>'
        e = '</' + tag_type + '>'
        statement_list = list()

        if int(uid) != 0:
            text = get_text_for_argument_uid(uid,
                                             rearrange_intro=True,
                                             attack_type='dont_know',
                                             with_html_tag=True,
                                             start_with_intro=True)
            db_argument = DBDiscussionSession.query(Argument).get(uid)
            if not db_argument:
                text = ''
            data = get_name_link_of_arguments_author(db_argument, nickname)
            gender = data['gender']
            if data['is_valid']:
                intro = data['link'] + ' ' + b + _tn.get(_.thinksThat) + e
            else:
                intro = b + _tn.get(_.otherParticipantsThinkThat) + e
            sys_text = intro + ' ' + start_with_small(text) + '. '
            sys_text += '<br><br> ' + b + _tn.get(
                _.whatDoYouThinkAboutThat) + '?' + e
            bubble_sys = create_speechbubble_dict(BubbleTypes.SYSTEM,
                                                  is_markable=True,
                                                  uid=uid,
                                                  content=sys_text,
                                                  other_author=data['user'])
            if not bubbles_already_last_in_list(bubbles_array, bubble_sys):
                bubbles_array.append(bubble_sys)

            # add statements of discussion to report them
            statement_list = self.__get_all_statement_texts_by_argument(
                db_argument)

        return {
            'bubbles': bubbles_array,
            'add_premise_text': add_premise_text,
            'save_statement_url': save_statement_url,
            'mode': '',
            'extras': statement_list,
            'gender': gender,
            'broke_limit': self.broke_limit
        }
    def get_dict_for_start(self, position_count):
        """
        Prepares the discussion dict with all bubbles for the first step in discussion,
        where the user chooses a position.

        :position_count: int
        :return: dict()
        """
        LOG.debug("At_start with positions: %s", position_count)
        _tn = Translator(self.lang)
        add_premise_text = _tn.get(_.whatIsYourIdea)
        intro = _tn.get(_.initialPositionInterest) + ' ...'
        save_statement_url = 'set_new_start_premise'

        start_bubble = create_speechbubble_dict(BubbleTypes.USER,
                                                uid='start',
                                                content=intro,
                                                omit_bubble_url=True,
                                                lang=self.lang)
        bubbles_array = [] if position_count == 1 else [start_bubble]

        return {
            'bubbles': bubbles_array,
            'add_premise_text': add_premise_text,
            'save_statement_url': save_statement_url,
            'mode': '',
            'broke_limit': self.broke_limit
        }
    def __get_dict_for_argumentation_end(self, argument_uid: int,
                                         user_changed_opinion: bool,
                                         db_user: User) -> dict:
        """
        Returns a special dict() when the discussion ends during an argumentation

        :param argument_uid: Argument.uid
        :param user_changed_opinion:  Boolean
        :param db_user: User
        :return: String, String, String
        """
        nickname = db_user.nickname if db_user and db_user.nickname != nick_of_anonymous_user else None
        _tn = Translator(self.lang)
        text = get_text_for_argument_uid(
            argument_uid,
            user_changed_opinion=user_changed_opinion,
            minimize_on_undercut=True,
            nickname=nickname)
        user_text = start_with_capital(text)
        sys_text = _tn.get(_.otherParticipantsDontHaveCounterForThat) + '.'
        trophy = '<i class="fa fa-trophy" aria-hidden="true"></i>'
        mid_text = '{} {} {} <br>{}'.format(
            trophy, _tn.get(_.congratulation), trophy,
            _tn.get(_.discussionCongratulationEnd))

        if nickname is not None:
            mid_text += _tn.get(_.discussionEndLinkTextWithQueueLoggedIn)
        else:
            mid_text += _tn.get(_.discussionEndLinkTextWithQueueNotLoggedIn)

        return {'user': user_text, 'mid': mid_text, 'sys': sys_text}
def __check_for_duplicated_field(title: str, info: str, long_info: str,
                                 request: dict) -> dict:
    """
    This method checks if there is a duplication in any field of the new issue.
    It also creates a error-message with the fields which are containing the duplication.

    :param title: The title of the new issue
    :param info: The info of the new issue
    :param long_info: The long info of the new issue
    :param request: The request with the data of the new issue
    :return: a dict with a boolean which tells if there is any duplicated field and a equivalent error-message.
    """
    _tn = Translator(get_language_from_cookie(request))
    error = _tn.get(_.duplicate) + ': '

    title_is_duplicate = DBDiscussionSession.query(Issue).filter_by(
        title=title).all()
    info_is_duplicate = DBDiscussionSession.query(Issue).filter_by(
        info=info).all()
    long_info_is_duplicate = DBDiscussionSession.query(Issue).filter_by(
        long_info=long_info).all()

    if title_is_duplicate:
        error = error + _tn.get(_.newIssueTitle) + ', '
    if info_is_duplicate:
        error = error + _tn.get(_.newIssueInfo) + ', '
    if long_info_is_duplicate:
        error = error + _tn.get(_.newIssueLongInfo) + ', '

    return {
        "contains_duplicated_field": title_is_duplicate or info_is_duplicate
        or long_info_is_duplicate,
        "error": error[:-2]
    }
Exemple #14
0
def __add_flag(reason: Union[key_duplicate, key_optimization, ReviewDeleteReasons], argument_uid: Union[int, None],
               statement_uid: Optional[int], extra_uid: Optional[int], db_user: User, tn: Translator) -> dict:
    """

    :param reason:
    :param argument_uid:
    :param statement_uid:
    :param extra_uid:
    :param db_user:
    :param tn:
    :return:
    """
    reason_val = reason.value if isinstance(reason, ReviewDeleteReasons) else reason
    db_del_reason = DBDiscussionSession.query(ReviewDeleteReason).filter_by(reason=reason_val).first()
    if db_del_reason:
        __add_delete_review(argument_uid, statement_uid, db_user.uid, db_del_reason.uid)

    elif reason_val == key_optimization:
        __add_optimization_review(argument_uid, statement_uid, db_user.uid)

    elif reason_val == key_duplicate:
        if statement_uid == extra_uid:
            LOG.debug("uid Error")
            return {'success': '', 'info': tn.get(_.internalKeyError)}
        __add_duplication_review(statement_uid, extra_uid, db_user.uid)

    return {'success': tn.get(_.thxForFlagText), 'info': ''}
Exemple #15
0
def __get_text_for_click_and_mark_count(db_user: User, is_user: bool, argument_uid: int, statement_uid: int,
                                        speech: dict, lang: str):
    """
    Build text for a bubble, how many other participants have the same interest?

    :param nickname: User.nickname
    :param is_user: boolean
    :param argument_uid: Argument.uid
    :param statement_uid: Statement.uid
    :param speech: dict()
    :param lang: ui_locales
    :return: [String]
    """
    if not db_user:
        db_user = DBDiscussionSession.query(User).filter_by(nickname=nick_of_anonymous_user).first()
    db_clicks, db_marks = __get_clicks_and_marks(argument_uid, statement_uid, db_user)

    _t = Translator(lang)
    speech['votecounts'] = len(db_clicks) if db_clicks else 0
    if db_marks:
        speech['votecounts'] += len(db_marks)

    votecount_keys = defaultdict(lambda: "{} {}.".format(speech['votecounts'], _t.get(_.voteCountTextMore)))

    if is_user and db_user.gender == 'm':
        gender_key = _.voteCountTextFirstM
    elif is_user and db_user.gender == 'f':
        gender_key = _.voteCountTextFirstF
    else:
        gender_key = _.voteCountTextFirst

    votecount_keys[0] = '{}.'.format(_t.get(gender_key))
    votecount_keys[1] = _t.get(_.voteCountTextOneOther) + '.'

    return votecount_keys
Exemple #16
0
def __get_bubble_from_dont_know_step(step: str, db_user: User, lang: str) -> List[dict]:
    """
    Creates bubbles for the don't-know-reaction for a statement.

    :param step: String
    :param db_user: User
    :param lang: ui_locales
    :return: [dict()]
    """
    steps = step.split('/')
    uid = int(steps[1])

    text = get_text_for_argument_uid(uid, rearrange_intro=True, attack_type='dont_know', with_html_tag=False,
                                     start_with_intro=True)
    db_argument = DBDiscussionSession.query(Argument).get(uid)
    if not db_argument:
        text = ''

    from dbas.strings.text_generator import get_name_link_of_arguments_author
    _tn = Translator(lang)

    data = get_name_link_of_arguments_author(db_argument, db_user.nickname, False)
    if data['is_valid']:
        intro = data['link'] + ' ' + _tn.get(_.thinksThat)
    else:
        intro = _tn.get(_.otherParticipantsThinkThat)
    sys_text = intro + ' ' + start_with_small(text) + '. '
    sys_text += '<br><br>' + _tn.get(_.whatDoYouThinkAboutThat) + '?'
    sys_bubble = create_speechbubble_dict(BubbleTypes.SYSTEM, content=sys_text, db_user=db_user,
                                          other_author=data['user'])

    text = _tn.get(_.showMeAnArgumentFor) + (' ' if lang == 'de' else ': ') + get_text_for_conclusion(db_argument)
    user_bubble = create_speechbubble_dict(BubbleTypes.USER, content=text, db_user=db_user)

    return [user_bubble, sys_bubble]
Exemple #17
0
def set_new_user(mailer: Mailer, user_data: Dict[str, Any], password: str,
                 _tn: Translator) -> Dict[str, Any]:
    """
    Public interface for creating a new user.

    :param mailer: The mailer used to send Emails to the new user.
    :param user_data: Dictionary containing user information.
    :param password: The desired password to be set. (un-hashed)
    :param _tn: The translator object to be used for messaging.
    :return: A dictionary containing whether the operation was a success, an optional error message and the newly
        created user if the transaction was successful.
    """
    # copy the dict to not change the mutable structure
    temporary_user = dict(user_data)
    db_group = DBDiscussionSession.query(Group).filter_by(name='users').first()

    # does the group exists?
    if not db_group:
        LOG.debug("Internal error occurred")
        return {
            'success': False,
            'error': _tn.get(Keywords.errorTryLateOrContant),
            'user': None
        }

    if DBDiscussionSession.query(User).filter(
            User.nickname == temporary_user['nickname']).first():
        LOG.debug("User already exists")
        return {
            'success': False,
            'error': _tn.get(Keywords.nickIsTaken),
            'user': None
        }

    temporary_user['password'] = password
    temporary_user['db_group_uid'] = db_group.uid

    success, info, db_new_user = __create_new_user(temporary_user,
                                                   _tn.get_lang())

    if db_new_user:
        # sending an email and message
        subject = _tn.get(Keywords.accountRegistration)
        body = _tn.get(Keywords.accountWasRegistered).format(
            temporary_user['firstname'], temporary_user['lastname'],
            temporary_user['email'])
        send_mail(mailer, subject, body, temporary_user['email'],
                  _tn.get_lang())
        send_welcome_notification(db_new_user.uid, _tn)

        LOG.debug("Set new user in db")
        return {'success': success, 'error': '', 'user': db_new_user}

    LOG.debug("New user not found in db")
    return {
        'success': False,
        'error': _tn.get(Keywords.errorTryLateOrContant),
        'user': None
    }
Exemple #18
0
    def test_get(self):
        trans_fr = Translator('fr')
        trans_de = Translator('de')
        trans_en = Translator('en')

        self.assertIn('haben eine', trans_de.get(_.forgotInputRadio))
        self.assertIn('forgot to', trans_en.get(_.forgotInputRadio))
        self.assertIn('forgot to', trans_fr.get(_.forgotInputRadio))
Exemple #19
0
def send_mail(mailer, subject, body, recipient, lang):
    """
    Try except block for sending an email

    :param mailer: current mailer
    :param subject: subject text of the mail
    :param body: body text of the mail
    :param recipient: recipient of the mail
    :param lang: current language
    :return: duple with boolean for sent message, message-string
    """
    logger('email_helper',
           'sending mail with subject \'' + subject + '\' to ' + recipient)
    _t = Translator(lang)
    if not mailer:
        logger('email_helper', 'mailer is none', error=True)
        return False, _t.get(_.internalKeyError)

    send_message = False
    body = body + '\n\n---\n' + _t.get(_.emailBodyText).format(
        get_global_url())
    sender = os.environ.get("MAIL_DEFAULT__SENDER", None)
    message = Message(subject=subject,
                      sender=sender,
                      recipients=[recipient],
                      body=body)

    # try sending an catching errors
    try:
        from threading import Thread
        t = Thread(target=__thread_to_send_mail,
                   args=(
                       mailer,
                       message,
                       recipient,
                       body,
                   ))
        t.start()
        send_message = True
        message = _t.get(_.emailWasSent)
    except smtplib.SMTPConnectError as exception:
        code = str(exception.smtp_code)
        error = str(exception.smtp_error)
        logger('email_helper',
               'exception smtplib.SMTPConnectError smtp code / error ' + code +
               '/' + error,
               error=True)
        message = _t.get(_.emailWasNotSent)
    except socket_error as serr:
        logger('email_helper',
               'socket error while sending ' + str(serr),
               error=True)
        message = _t.get(_.emailWasNotSent)

    return send_message, message
Exemple #20
0
    def prepare_item_dict_for_attitude(self, statement_uid):
        """
        Prepares the dict with all items for the second step in discussion, where the user chooses her attitude.

        :param statement_uid: Statement.uid
        :return:
        """
        logger('ItemDictHelper', 'def')
        _tn = Translator(self.lang)

        slug = DBDiscussionSession.query(Issue).get(self.db_issue.uid).slug
        statements_array = []

        _um = UrlManager(slug, history=self.path)

        db_arguments = DBDiscussionSession.query(Argument).filter(
            Argument.conclusion_uid == statement_uid,
            Argument.is_supportive == True).all()
        uid = random.choice(db_arguments).uid if len(db_arguments) > 0 else 0

        title_t = _tn.get(_.iAgreeWithInColor) + '.'
        title_f = _tn.get(_.iDisagreeWithInColor) + '.'
        title_d = _tn.get(_.iHaveNoOpinionYetInColor) + '.'
        url_t = _um.get_url_for_justifying_statement(statement_uid,
                                                     Attitudes.AGREE.value)
        url_f = _um.get_url_for_justifying_statement(statement_uid,
                                                     Attitudes.DISAGREE.value)
        url_d = _um.get_url_for_justifying_statement(uid,
                                                     Attitudes.DONT_KNOW.value)
        d_t = self.__create_answer_dict(Attitudes.AGREE.value,
                                        [{
                                            'title': title_t,
                                            'id': Attitudes.AGREE.value
                                        }], Attitudes.AGREE.value, url_t)
        d_f = self.__create_answer_dict(Attitudes.DISAGREE.value,
                                        [{
                                            'title': title_f,
                                            'id': Attitudes.DISAGREE.value
                                        }], Attitudes.DISAGREE.value, url_f)
        d_d = self.__create_answer_dict(Attitudes.DONT_KNOW.value,
                                        [{
                                            'title': title_d,
                                            'id': Attitudes.DONT_KNOW.value
                                        }], Attitudes.DONT_KNOW.value, url_d)
        statements_array.append(d_t)
        statements_array.append(d_f)
        statements_array.append(d_d)

        return {
            'elements': statements_array,
            'extras': {
                'cropped_list': False
            }
        }
Exemple #21
0
def __build_single_argument_for_en(_t: Translator, sb: str, se: str,
                                   you_have_the_opinion_that: str,
                                   marked_element, conclusion: str,
                                   premises: str, argument: Argument):
    tmp = sb + ' ' + _t.get(_.isNotRight).lower() + se + ', ' + _t.get(
        _.because).lower() + ' '
    text = (you_have_the_opinion_that +
            ' ' if marked_element else '') + conclusion + ' '
    text += _t.get(_.because).lower() if argument.is_supportive else tmp
    text += ' ' + premises
    return text
Exemple #22
0
def __create_new_user(user,
                      ui_locales,
                      oauth_provider='',
                      oauth_provider_id=''):
    """
    Insert a new user row

    :param user: dict with every information for a user needed
    :param ui_locales: Language.ui_locales
    :param oauth_provider: String
    :param oauth_provider_id: String
    :return: String, String, User
    """
    success = ''
    info = ''

    _t = Translator(ui_locales)
    # creating a new user with hashed password
    LOG.debug("Adding user %s", user['nickname'])
    hashed_password = password_handler.get_hashed_password(user['password'])
    newuser = User(firstname=user['firstname'],
                   surname=user['lastname'],
                   email=user['email'],
                   nickname=user['nickname'],
                   password=hashed_password,
                   gender=user['gender'],
                   group_uid=user['db_group_uid'],
                   oauth_provider=oauth_provider,
                   oauth_provider_id=oauth_provider_id)
    DBDiscussionSession.add(newuser)
    transaction.commit()
    db_user = DBDiscussionSession.query(User).filter_by(
        nickname=user['nickname']).first()
    settings = Settings(author_uid=db_user.uid,
                        send_mails=False,
                        send_notifications=True,
                        should_show_public_nickname=True)
    DBDiscussionSession.add(settings)
    transaction.commit()

    # sanity check, whether the user exists
    db_user = DBDiscussionSession.query(User).filter_by(
        nickname=user['nickname']).first()
    if db_user:
        LOG.debug("New data was added with uid %s", db_user.uid)
        success = _t.get(_.accountWasAdded).format(user['nickname'])

    else:
        LOG.debug("New data was not added")
        info = _t.get(_.accoutErrorTryLateOrContant)

    return success, info, db_user
Exemple #23
0
def register_user_with_json_data(data, lang, mailer: Mailer):
    """
    Consume the ajax data for an login attempt

    :param data: validated params of webserver's request
    :param lang: language
    :param mailer: Mailer
    :return: Boolean, String, User
    """
    _tn = Translator(lang)
    success = ''

    firstname = escape_string(data.get('firstname', ''))
    lastname = escape_string(data.get('lastname', ''))
    nickname = escape_string(data.get('nickname', ''))
    email = escape_string(data.get('email', ''))
    gender = escape_string(data.get('gender', ""))
    password = escape_string(data.get('password', ''))
    passwordconfirm = escape_string(data.get('passwordconfirm', ''))
    db_new_user = None

    msg = __check_login_params(firstname, lastname, nickname, email, password,
                               passwordconfirm)
    if msg:
        return success, _tn.get(msg), db_new_user

    # getting the authors group
    db_group = DBDiscussionSession.query(Group).filter_by(name="users").first()

    # does the group exists?
    if not db_group:
        msg = _tn.get(_.errorTryLateOrContant)
        LOG.debug("Error occured")
        return success, msg, db_new_user

    user_data = {
        'firstname': firstname,
        'lastname': lastname,
        'nickname': nickname,
        'gender': gender,
        'email': email
    }
    ret_dict = user.set_new_user(mailer, user_data, password, _tn)
    success = ret_dict['success']
    error = ret_dict['error']
    db_new_user = ret_dict['user']

    msg = error
    if success:
        msg = _tn.get(_.accountWasAdded).format(nickname)

    return success, msg, db_new_user
Exemple #24
0
    def test_get_text_for_add_premise_container(self):
        _t = Translator('en')

        for is_supportive in [True, False]:
            confrontation = start_with_capital(self.confrontation)
            undermine = _t.get(_.itIsFalseThat) + ' ' + self.premise
            support = _t.get(_.itIsTrueThat) if is_supportive else _t.get(
                _.itIsFalseThat)
            support += ' ' + self.conclusion + ' '
            support += _t.get(_.hold) if is_supportive else _t.get(
                _.doesNotHold)
            undercut = confrontation + ', ' + _t.get(
                _.butIDoNotBelieveCounterFor).format(self.conclusion)
            rebut = confrontation + ' '
            rebut += _t.get(_.iAcceptCounterThat) if is_supportive else _t.get(
                _.iAcceptArgumentThat)
            rebut += ' ' + self.conclusion

            results = {
                Relations.UNDERMINE: undermine + ' ...',
                Relations.SUPPORT: support + ' ...',
                Relations.UNDERCUT: undercut + ' ...',
                Relations.REBUT: rebut + ' ...',
                '': '',
            }

            for r in results:
                self.assertEqual(
                    results[r],
                    tg.get_text_for_add_premise_container(
                        'en', self.confrontation, self.premise, r,
                        self.conclusion, is_supportive))
Exemple #25
0
def send_mail(mailer, subject, body, recipient, lang):
    """
    Try except block for sending an email

    :param mailer: current mailer
    :param subject: subject text of the mail
    :param body: body text of the mail
    :param recipient: recipient of the mail
    :param lang: current language
    :return: duple with boolean for sent message, message-string
    """
    LOG.debug("Sending mail with subject '%s' to %s", subject, recipient)
    _t = Translator(lang)
    if not mailer:
        LOG.debug("Mailer is none")
        return False, _t.get(_.internalKeyError)

    send_message = False
    body = body + '\n\n---\n' + _t.get(_.emailBodyText).format(
        get_global_url())
    sender = os.environ.get("MAIL_DEFAULT__SENDER", None)
    message = Message(subject=subject,
                      sender=sender,
                      recipients=[recipient],
                      body=body)

    # try sending an catching errors
    try:
        t = Thread(target=__thread_to_send_mail,
                   args=(
                       mailer,
                       message,
                       recipient,
                       body,
                   ))
        t.start()
        send_message = True
        status_message = _t.get(_.emailWasSent)
    except smtplib.SMTPConnectError as exception:
        code = str(exception.smtp_code)
        error = str(exception.smtp_error)
        LOG.debug(
            "Exception smtplib.SMTPConnectionError smtp code / error %s / %s",
            code, error)
        status_message = _t.get(_.emailWasNotSent)
    except socket_error as serr:
        LOG.debug("Socker error while sending %s", serr)
        status_message = _t.get(_.emailWasNotSent)

    return send_message, status_message, message
def __set_min_length_error(request, min_length):
    """
    Add an error to the request due to too short statements text.

    :param request:
    :param min_length: minimum length of the statement
    :return:
    """
    _tn = Translator(get_language_from_cookie(request))
    a = _tn.get(_.notInsertedErrorBecauseEmpty)
    b = _tn.get(_.minLength)
    c = _tn.get(_.eachStatement)
    error_msg = '{} ({}: {} {})'.format(a, b, min_length, c)
    add_error(request, 'Text too short', error_msg)
Exemple #27
0
def send_add_argument_notification(url, attacked_argument_uid, user, mailer):
    """
    Sends an notification because an argument was added

    :param url: String
    :param attacked_argument_uid: Argument.uid
    :param user: User
    :param mailer: Instance of pyramid mailer
    :return:
    """
    # getting current argument, arguments author, current user and some settings
    db_argument = DBDiscussionSession.query(Argument).get(
        attacked_argument_uid)
    db_author = DBDiscussionSession.query(User).get(db_argument.author_uid)
    db_current_user = DBDiscussionSession.query(User).filter_by(
        nickname=user).first()
    if db_author == db_current_user:
        return None

    db_author_settings = db_author.settings
    user_lang = DBDiscussionSession.query(Language).get(
        db_author_settings.lang_uid).ui_locales

    # send notification via websocket to last author
    _t_user = Translator(user_lang)
    if db_author_settings.should_send_notifications:
        send_request_for_info_popup_to_socketio(db_author.nickname,
                                                _t_user.get(_.argumentAdded),
                                                url)

    # send mail to last author
    if db_author_settings.should_send_mails:
        email_helper.send_mail_due_to_added_text(user_lang, url, db_author,
                                                 mailer)

    # find admin
    db_admin = DBDiscussionSession.query(User).filter_by(
        nickname=nick_of_admin).first()

    topic = _t_user.get(_.argumentAdded)
    content = get_text_for_add_argument_message(db_author.firstname, user_lang,
                                                url, True)

    DBDiscussionSession.add(
        Message(from_author_uid=db_admin.uid,
                to_author_uid=db_author.uid,
                topic=topic,
                content=content,
                is_inbox=True))
    transaction.commit()
Exemple #28
0
def prepare_json_of_issue(db_issue: Issue, db_user: User) -> dict():
    """
    Prepares slug, info, argument count and the date of the issue as dict

    :param db_issue: Issue
    :param db_user: User
    :return: Issue-dict()
    """
    slug = slugify(db_issue.title)
    title = db_issue.title
    info = db_issue.info
    long_info = db_issue.long_info
    stat_count = get_number_of_statements(db_issue.uid)
    lang = db_issue.lang
    date_pretty = sql_timestamp_pretty_print(db_issue.date, lang)
    duration = (arrow.utcnow() - db_issue.date)
    days, seconds = duration.days, duration.seconds
    duration = ceil(days * 24 + seconds / 3600)
    date_ms = int(db_issue.date.format('X')) * 1000
    date = db_issue.date.format('DD.MM.YY')
    time = db_issue.date.format('HH:mm')

    db_issues = get_visible_issues_for_user_as_query(
        db_user.uid).filter(Issue.uid != db_issue.uid).all()
    all_array = [
        get_issue_dict_for(issue, db_issue.uid, lang) for issue in db_issues
    ]

    _t = Translator(lang)
    tooltip = _t.get(_.discussionInfoTooltipSg) if stat_count == 1 else _t.get(
        _.discussionInfoTooltipPl)
    tooltip = tooltip.format(date, time, stat_count)

    return {
        'slug': slug,
        'lang': lang,
        'info': info,
        'long_info': long_info,
        'title': title,
        'uid': db_issue.uid,
        'stat_count': stat_count,
        'date': date,
        'date_ms': date_ms,
        'date_pretty': date_pretty,
        'all': all_array,
        'tooltip': tooltip,
        'intro': _t.get(_.currentDiscussion),
        'duration': duration,
        'read_only': db_issue.is_read_only
    }
def __process_input_of_start_premises(premisegroups, db_conclusion: Statement,
                                      supportive, db_issue: Issue,
                                      db_user: User) -> Dict[str, Any]:
    """
    Inserts premises of groups as new arguments in dependence of the input parameters and returns a URL for forwarding.

    :param premisegroups: [[String, ..], ...]
    :param db_conclusion: Statement
    :param supportive: Boolean
    :param db_issue: Issue
    :param db_user: User
    :return: URL, [Statement.uid], String
    """
    LOG.debug(
        "Entering __process_input_of_start_premises with # of premisegroups: %s",
        len(premisegroups))
    _tn = Translator(db_issue.lang)

    # insert all premise groups into our database
    # all new arguments are collected in a list
    new_argument_uids = []
    new_statement_uids = [
    ]  # all statement uids are stored in this list to create the link to a possible reference
    if __is_conclusion_in_premisegroups(premisegroups, db_conclusion):
        return {
            'argument_uids': new_argument_uids,
            'statement_uids': new_statement_uids,
            'error': _tn.get(_.premiseAndConclusionAreEqual)
        }

    for premisegroup in premisegroups:  # premise groups is a list of lists
        new_argument, statement_uids = __create_argument_by_raw_input(
            db_user, premisegroup, db_conclusion, supportive, db_issue)

        new_argument_uids.append(new_argument.uid)
        new_statement_uids.append(statement_uids)

    error = None
    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)

    return {
        'argument_uids': new_argument_uids,
        'statement_uids': new_statement_uids,
        'error': error
    }
Exemple #30
0
    def get_queue_information(self, db_user: User, session: Session, application_url: str, translator: Translator):
        """
        Setup the subpage for the delete queue

        :param db_user: User
        :param session: session of current webserver request
        :param application_url: current url of the app
        :param translator: Translator
        :return: dict()
        """
        LOG.debug("Entering setup for subpage of deletion queue")
        all_rev_dict = get_all_allowed_reviews_for_user(session, f'already_seen_{self.key}', db_user, ReviewDelete,
                                                        LastReviewerDelete)

        rev_dict = get_base_subpage_dict(ReviewDelete, all_rev_dict['reviews'], all_rev_dict['already_seen_reviews'],
                                         all_rev_dict['first_time'], db_user, all_rev_dict['already_voted_reviews'])
        if not rev_dict['rnd_review']:
            return {
                'stats': None,
                'text': None,
                'reason': None,
                'issue_titles': None,
                'extra_info': None,
                'session': session
            }

        db_reason = DBDiscussionSession.query(ReviewDeleteReason).get(rev_dict['rnd_review'].reason_uid)
        stats = get_reporter_stats_for_review(rev_dict['rnd_review'], translator.get_lang(), application_url)

        reason = ''
        if db_reason.reason == 'offtopic':
            reason = translator.get(_.argumentFlaggedBecauseOfftopic)
        if db_reason.reason == 'spam':
            reason = translator.get(_.argumentFlaggedBecauseSpam)
        if db_reason.reason == 'harmful':
            reason = translator.get(_.argumentFlaggedBecauseHarmful)

        rev_dict['already_seen_reviews'].append(rev_dict['rnd_review'].uid)
        session[f'already_seen_{self.key}'] = rev_dict['already_seen_reviews']

        return {
            'stats': stats,
            'text': rev_dict['text'],
            'reason': reason,
            'issue_titles': rev_dict['issue_titles'],
            'extra_info': rev_dict['extra_info'],
            'session': session
        }