見出し画像

CraftLaunchでツイートする

CraftLaunchでTweetを行うコマンドを作ります。

CraftLaunch(以下"clnch")は、craftwareさん制作のWindows10向けPythonベースコマンドランチャーです。キーワードを登録してアプリケーションの起動などを行えます。

内部処理がPythonで行われていることを利用して、設定ファイルに複雑な処理を追加してコマンド一発で呼び出すことも可能です。Tweetを行うのに必要なソースを設定ファイルに書き込んで実装します。

下処理としていろいろファイルを移動したり落としたりするのが面倒くさいですが、間違えても致命的なエラーは起こさないので気楽に出来ます。

clnchのインストール・設定ファイルの移動

まずはclnchを入手します。お持ちの方は次の「Twitter開発者アカウントの取得」に進んでください。

画像1

clnchのページから最新版(ページ上部)をダウンロードします。
ダウンロードしたclnch_***.zipを解凍して任意のフォルダに配置してください。インストールはこれで完了しました。clnch.exeを起動してclnchの操作感を体験してみてください。

このままでもTweet機能の実装には問題ないのですが、設定をいじりやすいよう設定ファイルをclnch.exeと同じフォルダに持ってきます。
clnchのヘルプに掲載されている設定フォルダ(c:/Users/{ユーザー名}/AppData/Roaming/CraftLaunch)からconfig.iniとconfig.pyを拾ってきてclnch.exeと同じフォルダにコピーして完了です。ちなみにこの作業によってclnchをUSBに入れて持ちあるくことが可能になります。

Twitter開発者アカウントの取得

Tweet機能を実装する前に、TwitterをPythonから操作するための認証情報を取得します。認証情報取得にはTwitter開発者アカウントが必要なのでこちらを先に取得します。
2020年に久しぶりに開いたらちょっとややこしいことになっていたので以下のサイトを参考のうえ頑張って取得してきてください。

・このサイトはAPIキーの取得まで書かれているためこっち全部読めばほぼOK

・開発者アカウント新規取得の際のメールのやり取りも載ってた。メールのやり取りが始まったらこっち

どうややこしいかと言うと割と英語を書かなければいけなかったりします。以前はとくに何も聞かれず開発者アカウントを利用できましたが、現在はAPIの用途を詳しく聞かれます。
今回の目的「PythonからTweetします」だけだともう文字数がまるで足りないので適当に文章を水増しする覚悟をしてください。日本語でそこそこの長さを書ければGoogle翻訳にかけてどうにでもなるので頑張って!(丸投げ)

なお、開発者アカウントの取得の前にTwitterの電話番号認証が必要らしいのでやっておきましょう。終わったらTwitterの開発者向けページにアクセスしてAPIキーを取得してください。
https://developer.twitter.com/

必要なPythonパッケージをclnchに配置

TwitterAPIを使う準備は整いましたが、clnch上でTwitterを扱うにはパッケージの配置が必要です。clnchのPythonとPCに自前で入れるPythonは別で動作するため、clnchが読み出せる場所、具体的にはclnch.exeと同じフォルダに各種パッケージを配置します。

ここでPythonとPyPI(pip)が必要になるので、ない方はインストールを行ってください。WSL環境を構築してapt-getでpythonとpipをインストールすれば楽です(Python2.7.9もしくはPython3.4以上では一緒にインストールされているそうです)。というかスタンドアロンのインストーラー使うほうが大変そうなのでbashなりCygwinなりを用意したほうがいいです。以下でWSL環境の構築について読めます。

pipが使えるようになったら、必要なパッケージをインストールします。TwitterAPIに使うパッケージはrequestsとrequests_oauthの2つです。WSL環境では以下のコマンドでインストールします。cmdかPowerShellなら管理者権限で立ち上げてからsudoの代わりに"py -m"をつけてください。

sudo pip install requests requests_oauth

インストールの際、依存しているパッケージも同時にインストールされるため、落とすだけなら何も考えずに行えます。インストールが終わったらパッケージのインストール場所を探しましょう。以下のコマンドでパッケージの場所を表示させます。(cmd,PowerShellは引き続き"py -m"が必要)

pip show requests

画像2

ここにでるディレクトリ(Location)に移動してファイル群を確認してください。pipで落としたパッケージはおそらく分散せずに集まっているので、requestsだけでなくrequests_oauthも同じフォルダに入っているはずです。ない場合は上のコマンドをrequests_oauthで行って確認しましょう。

画像3

確認できたらパッケージ名のフォルダをclnchのディレクトリへコピーします。コマンド入力でコピーする場合はパッケージのインストールディレクトリに移動して次のコマンドを入力してください。エクスプローラーで開いている方はコマンド中のフォルダを全部手動でコピーしてください。

cp __pycache__ certifi chardet idna oauthlib requests requests_oauthlib urllib3 (clnch.exeのあるフォルダ) (bashは末尾に-r)

画像6

これらが全て揃えばclnchでTwitterAPIを使えるようになります。ターミナル作業は以上です。

config.pyにTweet処理を追加する

下準備がやっと終わりました。ここから本実装です。とはいえここから先はほぼ他サイトを参考にしたコードを持ってくるだけの作業が続くのであまり頭は使いません。具体的には以下のサイトにあるものを持ってきただけです。ここにclnch特有の動作やディレクトリの表記形式が絡んでくるため少しだけいじります。

認証部分をconfig.pyに入れておくと、clnchが異常終了したときにAPIキーが消えて面倒なことになるので、別にtwconfig.pyとして保存します。

import requests
import requests_oauthlib
import json
from requests_oauthlib import OAuth1Session

CONSUMER_KEY = "取得したkey"
CONSUMER_SECRET = "取得したkey"
ACCESS_TOKEN = "取得したkey"
ACCESS_TOKEN_SECRET = "取得したkey"

twitter = OAuth1Session(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

twurl = "https://api.twitter.com/1.1/statuses/update.json"

twconfig.pyあとで画像投稿のapiにも触れるのですが、twconfig.pyに変数として配置したところなぜか失敗するのでconfig.py側に配置します。
あとはconfig.pyにインポートしてTweetコマンドを作るだけです。コマンド追加のときはインデントに注意してください。

#config.pyの先頭に追加
import twconfig
import json
    def command_Tweet(twscr):
       params = {"status": twscr.args[0]}
       res = twconfig.twitter.post(twconfig.twurl, params = params)

       if res.status_code != 200:
           print("Failed. : %d"% res.status_code)

   window.launcher.command_list += [ ( "Tweet", command_Tweet ) ]

これでテキストツイートが可能です。試しにclnchに打ち込んでみます。
コマンドの仕様は「Tweet」のあとにセミコロンを入れて引数を渡すようにしました。

画像4

画像5

時間がかかる場合はAPI制限に引っかかっているかもしれない(分かってない)のでひと呼吸おいてもう一度試してください。

ツイートするだけならこれで終了ですが、clnchの仕様で空白と改行ができません。改行は手を尽くしましたができませんでした。空白については引数を複数とる書式を活用してセミコロンで代用できる形をとります。

    def command_Tweet(twscr):
       #paramsはdict型.dictの操作を使えば後から要素の追加が可能.
       params = dict.fromkeys(["status"])
       twbody = ""

       for prms in twscr.args:
           if len(twbody)>1:
               twbody += ' '
           twbody += prms

       params["status"] = twbody

       res = twconfig.twitter.post(twconfig.twurl, params = params)

       if res.status_code != 200:
           print("Failed. : %d"% res.status_code)

   window.launcher.command_list += [ ( "Tweet", command_Tweet ) ]

画像やURLに対応させる

URLの特別処置はあまり必要なかったのですが、Python学習のついでなのでhttpから始まるURLがきたときは末尾に追記する形をとりました。
さらに画像のパスを投げると画像投稿ができるようにしています。(拡張子判定などはしていないため使う人が間違えない前提となっています。余力があれば判定式を入れておくと安全)
Windows環境対策でバックスラッシュをスラッシュに変換するスクリプトつきです。

    def command_Tweet(twscr):
       #paramsはdict型.dictの操作を使えば後から要素の追加が可能.
       url_media = "https://upload.twitter.com/1.1/media/upload.json"
       params = dict.fromkeys(["status"])
       tburl = "ur"
       twbody = ""

       #画像やURLを投げられるようにする.引数を複数出してもらって対応
       for prms in twscr.args:
           #先行して\を/に置換
           if ":\\" in prms:
               prms = prms.replace('\\','/').strip('"')
               print(prms)

           #URLセクション
           if 'http://' in prms or 'https://' in prms:
               tburl = prms

           #画像セクション
           elif ":/" in prms:
               pfile = {"media" : open(prms, 'rb')}
               req_media = twconfig.twitter.post(url_media, files = pfile)
               if req_media.status_code != 200:
                   print("MEDIA UPLOAD FAILED %s", req_media.text)
                   return -1
               media_id = json.loads(req_media.text)['media_id']
               params["media_ids"] = [media_id]

           #ツイートセクション
           else:
               if len(twbody)>1:
                   twbody += ' '
               twbody += prms

       #引数読み出し終了

       #データ整形
       if len(tburl)>=5:
           twbody += ' ' + tburl
       params["status"] = twbody

       res = twconfig.twitter.post(twconfig.twurl, params = params)

       if res.status_code != 200:
           print("Failed. : %d"% res.status_code)

   window.launcher.command_list += [ ( "Tweet", command_Tweet ) ]

(URLセクションと画像セクションの順番を間違えるとopen関数がエラーを吐きます。)

試しに3種類全部のせしました。1回タイムアウトしてます。あせらない。

Tweet;記事に載せるサンプル;D:\_userfile\Picture\IMG_0856.jpg;http://kosyokai.tumblr.com/

画像7

参考



この記事が気に入ったらサポートをしてみませんか?