Create an automatic grade management app for Tenhou private room with LINE bot and Python Part 2

Introduction

Thing you want to do

スクリーンショット 2020-06-07 1.06.59.png

Creating a tabulation app

Graphing program

# coding:utf-8

import numpy as np 
#import pandas as pd
import re
import matplotlib.pyplot as plt

def graph_plot(tip):
    f = open('log.txt')
    lines = f.readlines() #Read everything up to the end of the file line by line(Newline character is also included)
    f.close()
    pointsA   = [0] #Mr. A
    pointsB   = [0] #Mr. B
    pointsC   = [0] #Mr. C
    pointsD   = [0] #Mr. D
    
    pointSumA = [0] # 
    pointSumB = [0] # 
    pointSumC = [0] # 
    pointSumD = [0] # 
    
    tipA   = [0] # 
    tipB   = [0] # 
    tipC   = [0] # 
    tipD   = [0] # 
    
    tipSumA = [0] # 
    tipSumB = [0] # 
    tipSumC = [0] # 
    tipSumD = [0] # 
    
    LIST = []

    for line in lines[1:]:
        if len(line) > 10: #Skip strange lines
            roomid  = line.split("|")[0]
            time    = line.split("|")[1]
            rools   = line.split("|")[2]
            players = line.split("|")[3]
            #Without congratulations
            if tip == False:
                l = re.split('[ ()]', players)
                LIST.append([l[1],float(l[2].replace("+",""))])
                LIST.append([l[4],float(l[5].replace("+",""))])
                LIST.append([l[7],float(l[8].replace("+",""))])
            #If there is a celebration
            if tip == True:
                l = re.split('[ (,)]', players)
                print(l)
                LIST.append([l[1],float(l[2].replace("+","")),float(l[3].replace("+","").replace("Sheet",""))])
                LIST.append([l[5],float(l[6].replace("+","")),float(l[7].replace("+","").replace("Sheet",""))])
                LIST.append([l[9],float(l[10].replace("+","")),float(l[11].replace("+","").replace("Sheet",""))])

    # print(LIST)
    for i,data in enumerate(LIST):
        player  = data[0]
        point   = data[1]
        if tip == True:
            tips    = data[2]
        if player == "Mr. A":
            pointsA.append(point)
            pointSumA.append(pointSumA[-1]+point)
            if tip == True:
                tipA.append(tips)
                tipSumA.append(tipSumA[-1]+tips)
        elif player == "Mr. B":
            pointsB.append(point)
            pointSumB.append(pointSumB[-1]+point)
            if tip == True:
                tipB.append(tips)
                tipSumB.append(tipSumB[-1]+tips)
        elif player == "Mr. C":
            pointsC.append(point)
            pointSumC.append(pointSumC[-1]+point)
            if tip == True:
                tipC.append(tips)
                tipSumC.append(tipSumC[-1]+tips)
        elif player == "Mr. D":
            pointsD.append(point)
            pointSumD.append(pointSumD[-1]+point)
            if tip == True:
                tipD.append(tips)
                tipSumD.append(tipSumD[-1]+tips)
        
    xA = [i for i in range(len(pointsA))]
    xB = [i for i in range(len(pointsB))]
    xC = [i for i in range(len(pointsC))]
    xD = [i for i in range(len(pointsD))]
    

    plt.clf()

    plt.plot(xA,pointSumA,label="Mr. A")
    plt.plot(xB,pointSumB,label="Mr. B")
    plt.plot(xC,pointSumC,label="Mr. C")
    plt.plot(xD,pointSumD,label="Mr. D")
    
    plt.legend()
    plt.savefig("graph_1.png ")

    plt.clf()
    plt.plot(xA,tipSumA,label="Mr. A")
    plt.plot(xB,tipSumB,label="Mr. B")
    plt.plot(xC,tipSumC,label="Mr. C")
    plt.plot(xD,tipSumD,label="Mr. D")
    
    plt.legend()
    plt.savefig("graph_2.png ")



if __name__ == "__main__":
    graph_plot(tip=True)

graph.png

Request response (LINE bot API)

Preamble part


# -*- coding: utf-8 -*-

#  Licensed under the Apache License, Version 2.0 (the "License"); you may
#  not use this file except in compliance with the License. You may obtain
#  a copy of the License at
#
#       https://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#  License for the specific language governing permissions and limitations
#  under the License.

'''
## references
1. Line Bot API
* [official-python](https://github.com/line/line-bot-sdk-python/blob/master/README.rst_)
* https://keinumata.hatenablog.com/entry/2018/05/08/122348
* [bottun](https://qiita.com/shimayu22/items/c599a94dfa39c6466dfa)
* [](https://dev.classmethod.jp/etc/line-messaging-api-action-object/)
* [Evacuation site LINE bot](https://qiita.com/lovemysoul/items/5ad818220d65b74351a5)
This site is really easy to understand. God.

2. DB,SQL
* https://baku1101.hatenablog.com/entry/2019/04/15/185003
* https://qiita.com/jacob_327/items/ec7d2223010ad4a0dd38

3. Python x S3(AWS)
* https://www.casleyconsulting.co.jp/blog/engineer/2861/

4. Heroku
* [Setting environment variables](https://qiita.com/colorrabbit/items/18db3c97734f32ebdfde)
* [Heroku x Linebot API](https://miyabi-lab.space/blog/21)


'''

# system
import os
import sys
import datetime
from argparse import ArgumentParser

# Web FlameWork
from flask import Flask, request, abort

# Line API
from linebot import (
    LineBotApi, WebhookHandler
    )
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent,
    PostbackEvent, 
    TextMessage, 
    TextSendMessage,
    ButtonsTemplate,
    URIAction,
    PostbackAction,
    MessageAction,
    ImageSendMessage,
    ConfirmTemplate,
    TemplateSendMessage,
    QuickReply,
    QuickReplyButton
)



# DF,Graph,etc
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np 
import re #Regular expressions

import pprint

#I don't need Google Drive because I don't use it
# Google Drive API
# import os
# import pprint

# AWS
import boto3

Create an instance


# Flask Web App Instance
app = Flask(__name__)


# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)
if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)


# PREPARE LINE messaging API Instance
line_bot_api = LineBotApi(channel_access_token)
handler = WebhookHandler(channel_secret)

# AWS Instance
aws_s3_bucket = os.environ['AWS_BUCKET']
s3 = boto3.resource("s3")
bucket = s3.Bucket(aws_s3_bucket)
s3_client = boto3.client('s3')

Request response processing part




'''
Response processing during the following actions
'''

@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']
    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)
    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)
    return 'OK'

#

Response to message event

@handler.add(MessageEvent, message=TextMessage)
def message_text(event):
    '''
Processing when a text message is sent
    '''
    try:
        message = event.message.text
        if message.count("Aragaki Yui") != 0:   
            text = "plotting...\n"
            line_bot_api.reply_message(
                event.reply_token,
                ImageSendMessage(
                    original_content_url = "https://orionfdn.org/wp-content/uploads/2018/12/WS000011-69.jpg ",
                    preview_image_url    = "https://orionfdn.org/wp-content/uploads/2018/12/WS000011-69.jpg "
                )
            )
        
        # Graph Plot
        elif message.count("Graph") != 0:
            # import download4
            # import graph

            line_bot_api.reply_message(
                    event.reply_token,
                    TextSendMessage(
                        text="Which do you like?",
                        quick_reply=QuickReply(
                            items=[
                                QuickReplyButton(
                                    action=PostbackAction(
                                        label="point",       #Characters to be displayed on the button
                                        text="Show the score transition",  #Characters to send as text
                                        data="request_point"     # Postback
                                    )
                                ),
                                QuickReplyButton(
                                    action=PostbackAction(
                                        label="Tip",
                                        text="Show the tip transition",
                                        data="request_tip"
                                    )
                                )
                            ]
                        )
                    )
                )


             

        # Summary
        elif message.count("Shukei") != 0:
            line_bot_api.reply_message(
                    event.reply_token,
                    TextSendMessage(
                        text="Which do you like?",
                        quick_reply=QuickReply(
                            items=[
                                QuickReplyButton(
                                    action=PostbackAction(
                                        label="Income and expenditure",       #Characters to be displayed on the button
                                        text="Show your balance",  #Characters to send as text
                                        data="request_sum"     # Postback
                                    )
                                ),
                                QuickReplyButton(
                                    action=PostbackAction(
                                        label="Order of arrival",
                                        text="Show the order of arrival",
                                        data="request_rank"
                                    )
                                ),
                                QuickReplyButton(
                                    action=PostbackAction(
                                        label="team",
                                        text="Show your team results",
                                        data="request_team"
                                    )
                                ),
                                QuickReplyButton(
                                    action=PostbackAction(
                                        label="Today",
                                        text="Show today's results",
                                        data="request_today"
                                    )
                                )
                            ]
                        )
                    )
                )

        #bonus
        elif message.count("Moge") != 0:
            line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text = "Jonga")
            )

        elif message.count("Daa") != 0:
           line_bot_api.reply_message(
                event.reply_token,
                ImageSendMessage(
                    original_content_url = "http://attrip.jp/wp-content/uploads/2013/07/20130716-130424.jpg ",
                    preview_image_url    = "http://attrip.jp/wp-content/uploads/2013/07/20130716-130424.jpg "
                )
            )

        elif message.count("Britain") != 0:
            line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text = "England")
            )

    


    except:
        import traceback
        print("errrrrrrrrrror")
        traceback.print_exc()
        

Response to the Postback event.

  1. Download the log file from Dropbox with `download4.download ("/logvol2.txt "," log.txt ")`.
  2. Plot the graph with `` `graph.graph_plot (tip = True) ```.
  3. Upload the graph file to S3 with `bucket.upload_file ("test.png "," test.png ")`.
  4. `` `s3_image_url ... (Omitted below) Get the URL of the file uploaded by ```.
  5. Finally, use ```ImageSendMessage () `` `to return the graph image to the user.



@handler.add(PostbackEvent)
def handle_postback(event):
    '''
What happens when there is a PostBack action
    '''
    import download4
    import summary
    import graph

    postbackdata = event.postback.data
    if postbackdata == "request_point":
        download4.download("/logvol2.txt","log.txt")
        graph.graph_plot(tip=True)
        bucket.upload_file("test.png ", "test.png ")
        s3_image_url = s3_client.generate_presigned_url(
            ClientMethod = 'get_object',
            Params       = {'Bucket': aws_s3_bucket, 'Key': "test.png "},
            ExpiresIn    = 600,
            HttpMethod   = 'GET'
        )

        line_bot_api.reply_message(
            event.reply_token,
            ImageSendMessage(
                original_content_url = s3_image_url,
                preview_image_url    = s3_image_url,
            )
        )
        download4.upload("test.png ","/graph.png ")  

    if postbackdata == "request_tip":
        download4.download("/logvol2.txt","log.txt")
        graph.graph_plot(tip=True)
        bucket.upload_file("test2.png ", "test2.png ")
        s3_image_url = s3_client.generate_presigned_url(
            ClientMethod = 'get_object',
            Params       = {'Bucket': aws_s3_bucket, 'Key': "test2.png "},
            ExpiresIn    = 600,
            HttpMethod   = 'GET'
        )

        line_bot_api.reply_message(
            event.reply_token,
            ImageSendMessage(
                original_content_url = s3_image_url,
                preview_image_url    = s3_image_url,
            )
        )
        download4.upload("test2.png ","/graph2.png ")    


    elif postbackdata == "request_sum":
        import download4
        import summary
        download4.download("/logvol2.txt","log.txt")
        summary.sumup(tip=True)

        with open('summary.txt') as f:
            lines = f.readlines()
        text = ""
        for line in lines:
            text += "{}\n".format(line)
        line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text = text)
        )
        download4.upload("summary.txt","/summary.txt")  
    
    elif postbackdata == "request_today":
        import download4
        import summary
        download4.download("/todays_score.txt","todays_log.txt")
        summary.today(tip=True)

        with open('todays_summary.txt') as f:
            lines = f.readlines()
        text = ""
        for line in lines:
            text += "{}\n".format(line)
        line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text = text)
        )
        download4.upload("todays_summary.txt","/todays_summary.txt")  

    elif postbackdata == "request_rank":
        import download4
        import summary
        download4.download("/logvol2.txt","log.txt")
        summary.sumup(tip=True)

        with open('rank.txt') as f:
            lines = f.readlines()
        text = ""
        for line in lines:
            text += "{}\n".format(line)
        line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text = text)
        )
        download4.upload("rank.txt","/rank.txt")  

    elif postbackdata == "request_team":
        import download4
        import summary
        download4.download("/logvol2.txt","log.txt")
        summary.sumup(tip=True)

        with open('team.txt') as f:
            lines = f.readlines()
        text = ""
        for line in lines:
            text += "{}\n".format(line)
        line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text = text)
        )
        download4.upload("team.txt","/team.txt")  
    


if __name__ == "__main__":
    print("hello")
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)

Deploy to Heroku all at once

in conclusion

p.s.

Recommended Posts

Create an automatic grade management app for Tenhou private room with LINE bot and Python Part 1
Create an automatic grade management app for Tenhou private room with LINE bot and Python Part 2
Create an automatic grade management app for Tenhou private room with LINE bot and Python Part ③
Create a LINE BOT with Minette for Python
LINE BOT (Messaging API) development with API Gateway and Lambda (Python) [Part 2]
Create an English word app with python
Create an app that guesses students with python
Let's make an app that can search similar images with Python and Flask Part1
Let's make an app that can search similar images with Python and Flask Part2
I made a LINE BOT with Python and Heroku
[LINE Messaging API] Create parrot return BOT with Python
Create a machine learning app with ABEJA Platform + LINE Bot
Create an LCD (16x2) game with Raspberry Pi and Python
Create a Twitter BOT with the GoogleAppEngine SDK for Python
Create a striped illusion with gamma correction for Python3 and openCV3
[LINE Messaging API] Create a BOT that connects with someone with Python
FX automatic trading system made with python and genetic algorithm Part 1
An app for smart people and smart people
Explanation of creating an application for displaying images and drawing with Python
FM modulation and demodulation with Python Part 3
Python installation and package management with pip
Quickly create an excel file with Python #python
Create and decrypt Caesar cipher with python
[Python] [LINE Bot] Create a parrot return LINE Bot
FM modulation and demodulation with Python Part 2
[Python] Quickly create an API with Flask
[LINE WORKS version Trello Bot] How to create a private talk room including a talk bot