paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

映画視聴ツールにdry run的な機能を追加する

週末に映画を見てその記録をtwitterに残しておくという生活を送っているのですが、前回ツール使用時にこんな事象が発生しました。

(python3) masashi@PC-ubuntu:~/movietweet$ bash twmovieinfo.sh hot fuzz
Traceback (most recent call last):
  File "posttw.py", line 9, in <module>
    api.update_status(sys.argv[1])
  File "/home/masashi/python3/lib/python3.6/site-packages/tweepy/api.py", line 193, in update_status
    )(post_data=post_data, *args, **kwargs)
  File "/home/masashi/python3/lib/python3.6/site-packages/tweepy/binder.py", line 250, in _call
    return method.execute()
  File "/home/masashi/python3/lib/python3.6/site-packages/tweepy/binder.py", line 233, in execute
    raise TweepError(error_msg, resp, api_code=api_error_code)
tweepy.error.TweepError: [{'code': 186, 'message': 'Tweet needs to be a bit shorter.'}]

投稿できる文字数超過みたいですね。
今までこんなことなかったのに何が起きたのでしょうか?

原因

moviesコマンド結果をgrepしているのですが製作会社に「Title」が入っていて
映画タイトルと一緒にgrepして拾ってしまい投稿時の文字数超過エラーとなってしまったようです。

headコマンドを追加して回避しましたが、事前に出力確認する機能があれば怪しそうなところが発見できますよね。
という訳でdry run的な機能を追加しようと思います。

やりたいこと

  • 投稿前に出力させて内容を確認できるようにする
  • ついでに文字数確認

今までmoviesコマンド打って映画がヒットするの確認してからツールを打ってました。
出力結果が投稿ツールと違うし、チェックのフローも無いので今回のエラーが出てしまいました。

とはいったものの出来なさそうなので方向転換

よくあるdry run的な引数を作ってprintさせればいいかなんて思っていて、
pythonのargparseで引数から出力と投稿の分岐を考えたんですが、そういえば投稿ツール本体はshell scriptでした。

moviesというshell scriptを使用しているので投稿ツール本体もshellで書いたのですが、わざわざpythonで書き直すのもナンセンスです。

このままshell scriptの改修で進めよう。

実装方法

  1. 結果を出力するだけの引数処理を作る
  2. 出力、確認、投稿の処理に変更する
  3. 出力用のファイルを作る

映画のタイトルも引数で取っているので個別で1を作るのは難しそうです。
同じ様なファイルを作るのも何なので2を採用します。

映画情報を取ってきて投稿するだけなのでその前にechoとcaseで分岐すればできちゃいますね。

コード修正

diff --git a/twmovieinfo.sh b/twmovieinfo.sh
index 25d2345..7a72ae0 100644
--- a/twmovieinfo.sh
+++ b/twmovieinfo.sh
@@ -22,4 +22,21 @@ ${INFO}
 ---
 """
 
-python posttw.py "${TWEET}"
+echo "${TWEET}"
+strings=$(echo "${TWEET}" | wc -c)
+echo "${strings}文字"
+
+echo -n "投稿しますか?: [y/n]"
+read CONFIRM
+# デフォルトはNo
+case $CONFIRM in
+    [Yy]*)
+        python posttw.py "${TWEET}"
+        echo "投稿を完了しました。"
+    ;;
+    *)
+        echo "スクリプトを終了します。"
+        exit 0
+    ;;
+esac

修正はこれだけでした。
投稿しなくても、もう一度実行すればいいので特にループも無しです。
一応誤って投稿しないようにデフォルトはNoにしました。

出力結果

前回と同じHot Fuzzで打ってみます。

(python3) masashi@PC-ubuntu:~/movietweet$ bash twmovieinfo.sh 'hot fuzz' 
2020-09-23に「Hot Fuzz」を視聴しました。

Infomation
---
Year: 2007
Genre: Action, Comedy, Mystery, Thriller
Director: Edgar Wright
Actors: Simon Pegg, Martin Freeman, Bill Nighy, Robert Popper
Production: Working Title Films, Universal Pictures, StudioCanal #ここを拾って1行目のタイトルに反映されてしまっていた
---

275文字
投稿しますか?: [y/n]n
スクリプトを終了します。

いいんじゃないでしょうか。
投稿前の情報、文字数が確認できたのと投稿の選択も出来るようになりました。
投稿時のエラー判定まではできていませんが、280文字を超えないなら今まで通り使えそうです。

これで本体ツールだけで事足りる様になりました。

まとめ

本当はshellで引数を利用して出力だけ行うdry runの機構が作れたらと思ったんですが、難しいですね。
echoだけ行う判定を作ればいけそうですが、先述のとおり映画のタイトルも引数で拾っているので
その判定のために引数を分解して判定して…とやるよりは今回の方法で簡単にやってしまいました。

ふたを開ければただecho分を追加しただけですが、要件は満たせたので良しとします。

ちなみにHot Fuzzは田舎町に左遷されたエリート警官が田舎の闇とともに事件を解決していくという話です。
(警察が機能していないくらいの平和な田舎)
コメディ、サスペンス的な要素とドンパチのアクションもあり面白い映画でした。

参考サイト

2020年上半期見た映画メモ & twitter取得ツール改修 - paloma blog

Bash-Snippets - Useful BASH Scripts For Heavy Commandline Users