Пример #1
0
    def is_correct_replier(self, bot, message):
        question_replier = QuestionReplier.get_by_message_id(
            self._session, message.id)
        # get repliers in this level
        filtered_question_repliers = [
            x for x in question_replier.question.question_repliers
            if x.replier.level_id == question_replier.replier.level_id
        ]

        # set status to replying if message is sent without clicking the buttom
        # (has refused or still in knowledge validation)
        if all(x.reply_status_id == 1 or x.reply_status_id == 2
               for x in filtered_question_repliers):
            self.set_status_for_repliers(filtered_question_repliers,
                                         question_replier)
            self._session.flush()

        if question_replier.reply_status_id != 3:
            slack_user_id = question_replier.message.slack_user_id
            replier = Replier.get_replier_by_slack_id(self._session,
                                                      slack_user_id)
            channel_id = replier.channel_id
            if question_replier.reply_status_id == 6:
                bot.post_message(channel_id, GAVE_UP_RESPONDING_MESSAGE,
                                 question_replier.message.slack_message_id)
            else:
                bot.post_message(channel_id,
                                 ANOTHER_REPLIER_ANSWERING_QUESTION,
                                 question_replier.message.slack_message_id)
            return False
        # if question_replier.reply_status_id == 3
        return True
Пример #2
0
    def validation_keep_answering_or_not(self, action):
        """If the replier wants to keep answering the question"""
        if action.value == 'no':
            message = Message.get_message(self._session, action.message_id,
                                          action.slack_user_id)
            question_replier = QuestionReplier.get_by_message_id(
                self._session, message.id)
            question_replier.reply_status_id = 6
            self._session.add(question_replier)

            channel_id, message_id, replier_question_id = self.get_expert_info_to_reply(
                message)
            channel_id_student, _, _ = self.get_user_info_to_reply(message)
            self.delete_previous_scheduled_messages(action.bot, channel_id,
                                                    replier_question_id, 1)
            self.delete_previous_scheduled_messages(action.bot, channel_id,
                                                    replier_question_id, 2)
            self.delete_previous_scheduled_messages(action.bot,
                                                    channel_id_student,
                                                    replier_question_id, 4)

            # send question to another level since the replier doesn't want to keep answering
            filtered_question_repliers = [x for x in question_replier.question.question_repliers \
                                    if x.replier.level_id == question_replier.replier.level_id]
            for qr in filtered_question_repliers:
                self.delete_previous_scheduled_messages(
                    action.bot, qr.replier.channel_id, qr.id, 3)
            self.go_to_next_level(action)
Пример #3
0
 def get_question_id_message(self, message):
     if message.is_replier_message:
         question_replier = QuestionReplier.get_by_message_id(
             self._session, message.id)
         question = Question.get_question_id(self._session,
                                             question_replier.question_id)
     else:
         question = Question.get_question(self._session, message.id)
     return question.id
Пример #4
0
    def _is_resolved(self, message):
        """Check whether the question has been marked as resolved or not"""
        if message.is_replier_message:
            question_replier = QuestionReplier.get_by_message_id(
                self._session, message.id)
            question_is_resolved = question_replier.question.is_resolved
        else:
            question = Question.get_question(self._session, message.id)
            question_is_resolved = question.is_resolved

        return question_is_resolved
Пример #5
0
    def add_question_replier_to_db(self, question, question_replier):
        """Add just a question replier to database.

        :type question: Question
        :type question_replier: tuple[Replier, str]

        :rtype: QuestionReplier
        """
        day = datetime.now().strftime("%d/%m/%Y, %H:%M:%S")
        message = Message(slack_user_id=question_replier[0].slack_id,
                          slack_message_id=question_replier[1],
                          is_replier_message=True,
                          date=day)
        new_question = QuestionReplier(reply_status_id=1)
        new_question.replier = question_replier[0]
        new_question.message = message
        new_question.question = question

        self._session.add_all([message, new_question])
        return new_question
Пример #6
0
 def get_expert_info_to_reply(self, message):
     if message.is_replier_message:
         question_replier = QuestionReplier.get_by_message_id(
             self._session, message.id)
     else:
         question = Question.get_question(self._session, message.id)
         question_replier = next((x for x in question.question_repliers
                                  if x.reply_status_id == 3))
     user_id = question_replier.message.slack_user_id
     message_id = question_replier.message.slack_message_id
     channel_id = question_replier.replier.channel_id
     return channel_id, message_id, question_replier.id
Пример #7
0
    def reply_question(self, event):
        """Handle messages that are sent to existing thread"""
        message = Message.get_message(self._session, event.thread_id,
                                      event.user)

        if self._is_resolved(message):
            self.send_closed_message(event, message)
            return

        if message.is_replier_message:
            question_replier = QuestionReplier.get_by_message_id(
                self._session, message_id=message.id)
            question = Question.get_question_id(
                self._session, question_id=question_replier.question_id)
            if not self.is_correct_replier(event.bot, message):
                return
            channel_id, message_id, replier_question_id = self.get_user_info_to_reply(
                message)
            self.delete_previous_scheduled_messages(event.bot, event.channel,
                                                    replier_question_id, 3)
            event.bot.delete_message_in_history(
                event.channel, event.thread_id, [
                    WANT_ANSWER_QUESTION, WANT_CONTINUE_RESPONDING,
                    M_ASKS_REPLIER_CLOSE_QUESTION
                ])
            attachments_type = ''
        else:
            question = Question.get_question(self._session,
                                             message_id=message.id)
            channel_id, message_id, _ = self.get_expert_info_to_reply(message)
            attachments_type = ATTACHMENTS_keep_answering_or_not
            event.bot.delete_message_in_history(event.channel, event.thread_id,
                                                [QUESTION_ANSWERED])
            message_txt = WANT_CONTINUE_RESPONDING

        # if this question has continous messages
        if question.new_message_user == 1:
            # add some text as alert in order to avoid this behaviour again
            event.bot.post_message(
                channel_id,
                USER_ALERT + question.message_text + '\n\n' + USER_ALERT_2,
                message_id, attachments_type)
            self._session.query(Question).filter_by(id=question.id).update(
                {'new_message_user': 0})

        event.bot.post_message(channel_id, event.message_text, message_id)
        if attachments_type != '':
            event.bot.post_message(channel_id, message_txt, message_id,
                                   attachments_type)
        self.handle_scheduled_message(event, message)
Пример #8
0
 def get_user_info_to_reply(self, message):
     if message.is_replier_message:
         question_replier = QuestionReplier.get_by_message_id(
             self._session, message.id)
         user_id = question_replier.question.message.slack_user_id
         message_id = question_replier.question.message.slack_message_id
         question_replier_id = question_replier.id
     else:
         question = Question.get_question(self._session, message.id)
         user_id = question.message.slack_user_id
         message_id = question.message.slack_message_id
         question_replier_id = None
     replier = Replier.get_replier_by_slack_id(self._session, user_id)
     channel_id = replier.channel_id
     return channel_id, message_id, question_replier_id
Пример #9
0
    def handle_scheduled_message(self, event, message):
        """Schedule messages to close question by inactivity"""
        channel_id, message_id, replier_question_id = self.get_expert_info_to_reply(
            message)
        question_replier = QuestionReplier.get_by_id(self._session,
                                                     replier_question_id)

        # get the students' info
        channel_id_student, message_id_student, _ = self.get_user_info_to_reply(
            message)

        # deleting previous scheduled messages
        self.delete_previous_scheduled_messages(event.bot, channel_id,
                                                replier_question_id, 1)
        self.delete_previous_scheduled_messages(event.bot, channel_id,
                                                replier_question_id, 2)
        self.delete_previous_scheduled_messages(event.bot, channel_id_student,
                                                replier_question_id, 4)

        # scheduling new messages
        sch_message_id = event.bot.schedule_message(
            channel_id,
            M_ASKS_REPLIER_CLOSE_QUESTION,
            TIMEOUT_CLOSE_QUESTION_REPLIER,
            message_id,
            attachments=ATTACHMENTS_close_question_validation)
        self.add_scheduled_message_to_db(sch_message_id, question_replier, 1)

        sch_message_id = event.bot.schedule_message(
            channel_id, M_VALIDATION_CLOSED_QUESTION,
            TIMEOUT_CLOSE_QUESTION_NOT_RESPONSE, message_id)
        self.add_scheduled_message_to_db(sch_message_id, question_replier, 2)

        sch_message_id = event.bot.schedule_message(
            channel_id_student,
            QUESTION_ANSWERED,
            TIMEOUT_CLOSE_QUESTION_STUDENT,
            message_id_student,
            attachments=ATTACHMENTS_answer_validation_after_reply)
        self.add_scheduled_message_to_db(sch_message_id, question_replier, 4)
Пример #10
0
    def handle_knowledge_validation(self, action):
        """If a replier wants or not to answer the first question"""
        message = Message.get_message(self._session, action.message_id,
                                      action.slack_user_id)
        question_replier = QuestionReplier.get_by_message_id(
            self._session, message.id)
        replier_level_id = question_replier.replier.level_id

        if question_replier.reply_status_id == 3:
            return

        all_question_repliers = question_replier.question.question_repliers
        filtered_question_repliers = [x for x in all_question_repliers \
                                      if x.replier.level_id == replier_level_id]

        # inform to a replier that another replier is already anwering the question
        if next(
            (x for x in filtered_question_repliers if x.reply_status_id == 3),
                None):
            action.bot.post_message(action.channel_id,
                                    ANOTHER_REPLIER_ANSWERING_QUESTION,
                                    action.message_id)
            return

        if action.value == 'yes':
            for qr in filtered_question_repliers:
                self.delete_previous_scheduled_messages(
                    action.bot, qr.replier.channel_id, qr.id, 3)
            self.set_status_for_repliers(filtered_question_repliers,
                                         question_replier)
            return

        if action.value == 'no':
            self.handle_no_knowledge_validation(action,
                                                filtered_question_repliers,
                                                question_replier)
Пример #11
0
    def go_to_next_level(self, event):
        """Prepares what is necessary to go up to the next level in 3 cases: 
        1. All users at some level ignore the question.
        2. All users at some level reject to answer.
        3. A replier stop answering.
        """
        try:  # case 1
            message = Message.get_message_by_thread(self._session,
                                                    event.thread_id)
            question_replier = QuestionReplier.get_by_message_id(
                self._session, message.id)
        except:
            try:
                # just for "action" on 'handle_knowledge_validation' and 'validation_keep_answering_or_not' (case 2 & 3)
                message = Message.get_message(self._session, event.message_id,
                                              event.slack_user_id)
                question_replier = QuestionReplier.get_by_message_id(
                    self._session, message.id)
            except:
                return
        level_id = question_replier.replier.level_id
        next_level_id = ReplierLevel.get_next_lvl_id(self._session,
                                                     level_id).next_level_id
        print("From level {} to {}. Number of Loop: {}".format(
            level_id, next_level_id,
            question_replier.question.number_of_loops))
        question_repliers = question_replier.question.question_repliers
        question_date = question_replier.question.message_date
        question_level_id = question_replier.question.level

        # validate if we are on the right level
        if level_id == question_level_id:
            # update question's level on db
            question_replier.question.level += 1
            # update status of repliers as "passou"
            for x in [
                    question_replier for question_replier in question_repliers
                    if question_replier.reply_status_id == 1
            ]:
                x.reply_status_id = 4

            # if there are not more repliers already
            if all(question_replier.reply_status_id != 3
                   for question_replier in question_repliers):
                original_message = question_replier.question.message
                history_text = self.save_message_history(event.bot,
                                                         question_replier.id,
                                                         next_level=True)

                # we are going to the next loop
                if next_level_id == 1:
                    print("Going to next loop...")
                    question_replier.question.number_of_loops += 1
                    question_replier.question.level = 1  # reset the level
                    # for more than 2 loops, send a message to monitors
                    if question_replier.question.number_of_loops > 2:
                        message_id_user = question_replier.question.message_id
                        message_user = Message.get_message_by_id(
                            self._session, message_id=message_id_user)
                        user = Replier.get_replier_by_slack_id(
                            self._session, slack_id=message_user.slack_user_id)
                        send_email(
                            '*****@*****.**',
                            'Dúvida do aluno: \n' +
                            question_replier.question.message_text + '\n\n' +
                            'Informações do aluno: \n' + 'Slack_id: ' +
                            user.slack_id + '\n' + 'E-mail: ' + user.email +
                            '\n' + 'Data e hora: ' + question_date + '\n',
                            'Dúvida não respondida - ExperIA - ' +
                            question_date)
                        self.save_message_history(event.bot,
                                                  question_replier.id)
                        return

                new_question_repliers = self.forward_first_message(
                    event.bot, history_text, next_level_id,
                    original_message.slack_user_id)

                db_question_repliers = self.add_question_repliers_to_db(
                    question_replier.question, new_question_repliers)

                self.time_to_level_up(event.bot, db_question_repliers)

                filtered_question_repliers = [x for x in question_repliers \
                                              if x.replier.level_id == question_replier.replier.level_id and \
                                                  x.replier.id != question_replier.replier.id]

                for qr in filtered_question_repliers:
                    event.bot.post_message(qr.replier.channel_id,
                                           M_EXPIRATION_TIME + ' ',
                                           qr.message.slack_message_id)
                    event.bot.delete_message_in_history(
                        qr.replier.channel_id, qr.message.slack_message_id,
                        [WANT_ANSWER_QUESTION])

            self._session.add_all(question_repliers)