In the previous article, I was able to create an app that automatically records Tenhou's log file (format as shown below), so I want to get the aggregated information of that __log __.
Aggregated information is, for example, the accumulated points, accumulated chips, and changes in points of each player.
There is an official Aggregation Tool in Tenhou, but it is troublesome to copy and paste the log for frequent aggregation, so program it. I want to make it and count it automatically.
You only have to run the program every time you do it by yourself, but since mahjong friends can't basically program, I want to run it with a familiar interface so that everyone can see the aggregated information at any time __.
From the above motives, I decided to make an aggregation tool with python and make the interface LINE.
# 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)
# -*- 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
`LINE_CHANNEL_SECRET``` and
`LINE_CHANNEL_ACCESS_TOKENare read by
os.getenv```. I also referred to the above site for creating LINE bot channels. If you do this, you don't have to write information such as secrets directly in the code, so it seems to be good for security.
# 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')
'''
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'
#
`@ handler.add (MessageEvent, message = TextMessage)`
as shown below. I will.if
.@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()
`download4``` (previous article),
summary```, ``
graphof the self-made module group is
import```. Graph
is a module for creating a graph of the score transition and chip transition described earlier. Summary
is not written because it will be long, but basically it has the same configuration as graph
, and it is a module for calculating the order distribution and total score." request_point "
is explained.`download4.download ("/logvol2.txt "," log.txt ")`
.`bucket.upload_file ("test.png "," test.png ")`
.`TextSendMessage ()`
to send characters instead of images.
@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)
`graph.py``` for graph creation (the first one in the article),
summary.py``` for aggregation calculation (I have not written about the contents this time), LINE bot response All you have to do is deploy the part ``
tenhoulinebot.py``` (let's say) to Heroku.p.s.
Recommended Posts