Пример #1
0
def webhook():
    data = request.get_json()
    request_id = str(uuid4())
    # insert_user_request(request_id, str(data))

    if data["object"] == "page":

        for entry in data["entry"]:
            if 'messaging' in entry:
                for messaging_event in entry["messaging"]:
                    if messaging_event.get("message"):
                        sender_id = messaging_event["sender"]["id"]
                        # recipient_id = messaging_event["recipient"]["id"]
                        log(messaging_event)
                        if 'text' in messaging_event["message"]:
                            message_text = messaging_event["message"]["text"]
                            if is_keyword_query(message_text):
                                handle_keyword(sender_id, message_text)
                            else:
                                handle_message(message_text, sender_id,
                                               request_id)
                    if messaging_event.get(
                            "delivery"):  # delivery confirmation
                        pass

                    if messaging_event.get("optin"):  # optin confirmation
                        pass

                    if messaging_event.get("postback"):
                        sender_id = messaging_event["sender"]["id"]
                        insert_user_answer(request_id, str(messaging_event))
                        handle_postback(messaging_event, sender_id, request_id)

    return "ok", 200
Пример #2
0
def update_answer(response_id, values):
    try:
        with db_connection.cursor() as cursor:
            sql = 'UPDATE answer_provided SET answer_id = %s, is_correct = %s WHERE id = %s'
            cursor.execute(sql,
                           (values.answer_id, values.is_correct, response_id))
        db_connection.commit()
    except:
        log('Error! update user answer {}'.format(response_id))
Пример #3
0
def top_topics_flow(sender_id):
    top_topics = top_two_scoring_topics(sender_id)
    log(top_topics)
    if top_topics:
        send_text_message(
            sender_id, 'Your strengths are {}'.format(', '.join(top_topics)))
    else:
        send_text_message(sender_id,
                          'Please solve more questions to use this feature')
Пример #4
0
def insert_user_question(response_id, sender_id, question):
    try:
        with db_connection.cursor() as cursor:
            sql = 'INSERT INTO questions_given (id, sender_id, question_id) VALUES (%s, %s, %s)'
            question_id = parse_question(question)
            cursor.execute(sql, (response_id, sender_id, question_id))
        db_connection.commit()
    except:
        log('Error! insert user question {}'.format(question))
Пример #5
0
def insert_user_request(request_id, request):
    try:
        with db_connection.cursor() as cursor:
            sql = 'INSERT INTO user_request (id, sender_id, query) VALUES (%s, %s, %s)'
            values = parse_request_data(request)
            if values:
                cursor.execute(sql, (request_id, values.id, values.query))
                db_connection.commit()
    except:
        log('Error! insert user request {}'.format(request))
Пример #6
0
def insert_user_answer(response_id, answer):
    try:
        log('insert user {}'.format(answer))
        values = parse_answer(answer)
        if is_answer_there(values.question_request_id):
            update_answer(get_response_id(values.question_request_id), values)
        else:
            insert_answer(response_id, values)
    except:
        log('Error! insert user answer {}'.format(answer))
Пример #7
0
def send(data):
    params = {"access_token": os.environ["PAGE_ACCESS_TOKEN"]}
    headers = {"Content-Type": "application/json"}
    r = requests.post("https://graph.facebook.com/v2.6/me/messages",
                      params=params,
                      headers=headers,
                      data=data)
    if r.status_code != 200:
        log(r.status_code)
        log(r.text)
Пример #8
0
def execute_sql(query, *args):
    db_connection = DBConnection.Instance().get_connection()
    try:
        cursor = db_connection.cursor()
        cursor.execute(query, args)
    except:
        db_connection.close()
        cursor = db_connection.cursor()
        cursor.execute(query)
        log("error! execute sql {}".format(query))
    return cursor
Пример #9
0
def study_flow(sender_id, response, request_id):
    topic = response[RESULT][PARAMETERS][TOPICS]
    if topic != 'default_topic':
        send_text_message(sender_id, response[RESULT][FULFILLMENT][SPEECH])
    else:
        topic = ''
        send_text_message(sender_id, "Sure! Let's start with this:")
    log("TOPIC: {}".format(topic))
    question = question_from_topic(topic)
    options = options_and_answer(question[ID])
    send_question(sender_id, request_id, question, options, topic=topic)
Пример #10
0
def insert_answer(response_id, values):
    try:
        with db_connection.cursor() as cursor:
            sql = 'INSERT INTO answer_provided (id, sender_id, question_id, answer_id, is_correct, test_id, question_request_id) VALUES (%s, %s, %s, %s, %s, %s, %s)'
            cursor.execute(sql,
                           (response_id, values.sender_id, values.question_id,
                            values.answer_id, values.is_correct,
                            values.test_id, values.question_request_id))
        db_connection.commit()
    except:
        log('Error! insert user answer {}'.format(response_id))
Пример #11
0
def handle_postback(event, sender_id, request_id):
    log(event)
    if 'postback' in event and 'payload' in event['postback']:
        payload = event['postback']['payload']
        payload = ast.literal_eval(payload)
        if 'type' in payload and payload['type'] == 'num_questions':
            handle_new_test(payload, sender_id, request_id)
        elif 'test' in payload and payload['test'] is True:
            handle_test(payload, sender_id, request_id)
        elif 'first_message' in payload:
            handle_first_message(sender_id)
        else:
            handle_question(payload, sender_id)
Пример #12
0
def insert_user_response(response_id, response):
    try:
        with db_connection.cursor() as cursor:
            sql_to_request = 'UPDATE user_request SET intent = %s, entities = %s WHERE id=%s'
            values = parse_response_data(response)
            cursor.execute(sql_to_request,
                           (values.intent, values.entities, response_id))
            sql_to_response = 'INSERT INTO user_response (id, sender_id, response) VALUES (%s, %s, %s)'
            cursor.execute(sql_to_response,
                           (response_id, values.sender_id, values.response))
        db_connection.commit()
    except:
        log('Error! insert user response {}'.format(response))
Пример #13
0
def questions_answered(sender_id, num):
    try:
        sql = "select count(*) from answer_provided where time_asked \
            BETWEEN (select CURRENT_TIMESTAMP + interval '-%s' day) \
            AND (select CURRENT_TIMESTAMP) \
            AND sender_id = %s"

        cursor = execute_sql(sql, num, sender_id)
        response = cursor.fetchone()['count(*)']
        cursor.close()
        return response
    except:
        log('error! questions answered')
        return None
Пример #14
0
def questions_grouped_by_date_eternity(sender_id):
    try:
        sql = "select DATE(time_asked) AS ForDate, count(*) \
                from answer_provided \
                where sender_id = %s \
                GROUP BY ForDate"

        cursor = execute_sql(sql, sender_id)
        response = cursor.fetchall()
        cursor.close()
        return response
    except:
        log('error! questions group by date')
        return None
Пример #15
0
def score_in_given_topic(sender_id, topic):
    try:
        sql = "select count(*) \
            from answer_provided a join questions_question q \
            on q.id = a.question_id \
            where a.is_correct = 1 \
            AND q.topic = %s AND a.sender_id = %s"

        cursor = execute_sql(sql, topic, sender_id)
        response = cursor.fetchone()['count(*)']
        cursor.close()
        return response
    except:
        log('error! score in a given topic')
        return None
Пример #16
0
def scores_in_topics(sender_id):
    try:
        sql = "select count(*), q.topic \
                from answer_provided a join questions_question q \
                on q.id = a.question_id \
                where a.is_correct = 1 AND a.sender_id = %s \
                GROUP BY q.topic \
                ORDER BY count(*) DESC"

        cursor = execute_sql(sql, sender_id)
        response = cursor.fetchall()
        cursor.close()
        return response
    except:
        log('error! scores in topics')
        return None
Пример #17
0
def call_bar_plot(question_count, correct_count, file_id, title,
                  question_color):
    try:
        x_axis = [
            item['ForDate'].strftime('%m/%d/%Y') for item in question_count
        ]
        y_axis_1 = [item['count(*)'] for item in question_count]
        y_axis_2 = [item['count(*)'] for item in correct_count]
        x_axis = x_axis if len(x_axis) > 0 else [0]
        y_axis_1 = y_axis_1 if len(y_axis_1) > 0 else [0]
        y_axis_2 = y_axis_2 if len(y_axis_2) > 0 else [0]
        answered_vs_correct_plot(file_id, title, question_color, x_axis,
                                 y_axis_1, y_axis_2)
        return True
    except:
        log('unable to plot')
        return False
Пример #18
0
def get_solution_gifs(question):
    API = get_wolfram_key()
    client = wolframalpha.Client(API)
    gifs = []
    try:
        result = client.query(question)
        if not result or not result.pods:
            return None
        for item in result.pods:
            if 'subpod' in item and isinstance(item['subpod'], list):
                for i in item['subpod']:
                    gifs.append(i['img']['@src'])
            elif 'subpod' in item and isinstance(item['subpod'], dict):
                gifs.append(item['subpod']['img']['@src'])
        return gifs
    except:
        log('unable to parse wolfram result')
Пример #19
0
def correct_questions_grouped_by_date_last_month(sender_id):
    try:
        sql = "select DATE(time_asked) AS ForDate, count(*) \
                from answer_provided \
                where time_asked \
                BETWEEN (select CURRENT_TIMESTAMP + interval '-30' day) \
                AND (select CURRENT_TIMESTAMP) AND is_correct = 1 AND \
                sender_id = %s\
                GROUP BY ForDate"

        cursor = execute_sql(sql, sender_id)
        response = cursor.fetchall()
        cursor.close()
        return response
    except:
        log('error! correct questions group by date')
        return None
Пример #20
0
def bottom_two_scoring_topics(sender_id):
    try:
        sql = "select count(*), q.topic \
            from answer_provided a join questions_question q \
            on q.id = a.question_id \
            where a.is_correct = 1 AND a.sender_id = %s \
            GROUP BY q.topic \
            ORDER BY count(*) \
            LIMIT 2"

        cursor = execute_sql(sql, sender_id)
        res = cursor.fetchall()
        res = [r['topic'] for r in res]
        cursor.close()
        return res
    except:
        log('error! bottom two scoring topics')
        return None
Пример #21
0
def scores_in_topics_plot(sender_id, file_id):
    try:
        data = scores_in_topics(sender_id)
        labels = [item['topic'] for item in data]
        sizes = [item['count(*)'] for item in data]
        labels = labels if len(labels) > 0 else [0]
        sizes = sizes if len(sizes) > 0 else [0]
        fig1, ax1 = plt.subplots()
        ax1.set_title('topic wise strengths')
        ax1.pie(sizes,
                labels=labels,
                autopct='%1.1f%%',
                shadow=True,
                startangle=90)
        ax1.axis('equal')
        plt.savefig(get_file_name(file_id))
        return True
    except:
        log('error! scores in topic')
        return False
Пример #22
0
def handle_message(message_text, sender_id, request_id, bing_search=False):
    response = APIAI.Instance().message_response(message_text, sender_id)
    intent = response[RESULT][METADATA][INTENT_NAME]
    log(response)
    if intent == DIAGNOSTIC_YES:
        diagnostic_yes_flow(sender_id, response, request_id)
    elif intent == STUDY:
        study_flow(sender_id, response, request_id)
    elif intent == GREETING:
        greeting_flow(sender_id, response)
    elif intent == DIAGNOSTIC_NO:
        diagnostic_no_flow(sender_id, response)
    elif intent == VIDEO_SEARCH:
        video_flow(sender_id, message_text)
    elif intent == TEST:
        test_start_flow(sender_id, response)
    elif intent == QUESTIONS_ANSWERED:
        questions_answered_flow(sender_id, response)
    elif intent == QUESTIONS_ANSWERED_CORRECTLY:
        questions_answered_correctly_flow(sender_id, response)
    elif intent == TOP_TOPICS:
        top_topics_flow(sender_id)
    elif intent == BOTTOM_TOPICS:
        bottom_topics_flow(sender_id)
    elif intent == PLOT_SCORES:
        plot_scores_flow(sender_id, response)
    elif intent == SCORES_IN_TOPICS:
        scores_in_topics_flow(sender_id)
    elif intent == PLOT_MENU:
        plot_menu_flow(sender_id)
    elif intent == DEFAULT:
        if not bing_search:
            corrected_sentence = BingSearcher().correct_spelling(message_text)
            handle_message(corrected_sentence,
                           sender_id,
                           request_id,
                           bing_search=True)
            return
        send_text_message(sender_id, response[RESULT][FULFILLMENT][SPEECH])
        send_helper_messages(sender_id)
Пример #23
0
def send_question(recipient_id, request_id, question, options, **kwargs):
    log(question)
    # insert_user_question(request_id, recipient_id, str(question))
    buttons = []
    question_request_id = str(uuid4())
    for option in options.options:
        payload = {
            'id': option['id'],
            'correct': options.correct,
            'qid': question['id'],
            'question_request_id': question_request_id,
        }
        payload.update(kwargs)
        payload = str(payload)
        button = {
            "type": "postback",
            "title": option['text'],
            "payload": payload,
        }
        buttons.append(button)
    data = json.dumps({
        "recipient": {
            "id": recipient_id
        },
        "message": {
            "attachment": {
                "type": "template",
                "payload": {
                    "template_type": "button",
                    "text": filter_question(question['question_text']),
                    "buttons": buttons,
                }
            }
        }
    })
    send(data)