あみのろぐ

クソコードとゲームのことについて

paiza_runもどきを作ろうとした話

はい、というわけでね

機械学習の何かを作ろうと思ったんですがいまいちねえやる気がないんですよ

寒くてやる気が出ないおれ f:id:ima3no:20180208185341j:plain

それはさておき今回も前回に引き続いてTwitter関連のツールを作って遊んでみました。

初めに

paiza_runというTwitterソースコードをリプライとして送ると実行結果を返してくれるアカウントがあったのですが

R.I.P f:id:ima3no:20180208195712p:plain

なんか凍結してたので作ってみるか、と思って書いてみました。 実装の方法としてはとりあえず送られてきた内容をほかのファイルに書き出して実行結果をリプライするという内容で実装可能だと思ったのでそれっぽく書きました。(もっといい方法があれば教えてください。 何割かは昨日の記事に書いたソースをそのまま使ってます。

使ったもの

github.com

いつもの

ソース

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

import sys
import subprocess
import tweepy
import re

#いつものように取得したapiキーを入れる
consumer_key = ""
consumer_secret = ""
access_key = ""
access_secret = ""
TW_ID = "" #ここには返信を行うアカウントのIDを入れる
FILE_NAME = "run.py" #送信された内容を書き出すファイル名

#Oauth認証を行う
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
api = tweepy.API(auth)

class MyStreamListener(tweepy.StreamListener):
    def on_connect(self):
        print("接続しました")
        return

    def on_disconnect(self, notice):
        print('切断されました:' + str(notice.code))
        return

    def on_status(self, status):
        if str(status.in_reply_to_screen_name) == TW_ID: 
            TARGET_USER = status.user.screen_name
            text = status.text
            if text.find("python:"):
                print("Pythonの実行コードです")
                match = "@" + TW_ID + " python: #正規表現が理解できてないのでとりあえずごり押しで実装した、全角アットマークだと検知できない
                reply_tweet = text.replace(match,"")
                if make_file(reply_tweet):
                    run(TARGET_USER)
            else:
                print("それ以外のリプライです")
                return False

    def on_error(self, status_code):
        if status_code == 420:
            print("エラーが発生しました:" + str(status_code))
            return False

    def on_limit(self, track):
        print("API制限のため切断されました")
        return True

    def disconnect(self,notice):
        print("接続が中断しました")
        return True

def make_file(text):
    with open(FILE_NAME, mode="w+",encoding='utf-8') as f: #ファイル名を指定してなければ作成する
        for i in text:
            f.write(i)
            if i == ":": #ifやforの終わりに改行を入れて整形をする
                f.write("\n")
        return True

def run(TARGET_USER):
    res = subprocess.check_output("python " + FILE_NAME) #コマンドを実行して結果を格納
    decode_res = res.decode("UTF-8") #バイナリ形式で返ってくるようなのでデコード
    tweet = "@" + TARGET_USER + " " + decode_res #返信する用のツイート
    api.update_status(status=tweet) #送信


if __name__ == "__main__":
    myStreamListener = MyStreamListener()
    stream = tweepy.Stream(auth = api.auth, listener=MyStreamListener())
    stream.userstream() 

実行例

こんな感じでリプライを飛ばして f:id:ima3no:20180208191626p:plain

上手くいけば実行結果をbotが返信する f:id:ima3no:20180208191650p:plain

ファイルはこんな感じで改行を入れてそれっぽく出力される f:id:ima3no:20180208191722p:plain

課題と反省

  • そもそもPython以外の言語に対応してない
  • 送信の内容によっては上手く実行できない
  • 正規表現の部分がうまくできていない(勉強します

statusのオブジェクトを見ていて気付いたのですが、いつのまにか全角アットマークでもリプライ飛ばせるようになってたんですね。
送られてくるコードの置換のところを直せば実用的なものになりそうですね。

ではまた。