寮食を呟くbotを作った
今日(2021年4月5日)津山高専寮食botがひとまず完成した。文字通り津山高専の寮食を自動で呟くbotである。 プログラムの大まかな流れは
- 寮食が書かれているPDFが上がっている学校のサイトから日付に合ったPDFを取得
- PDFから今日の寮食が書かれている部分を抜き出してPDFとして保存
- トリミングしたPDFをGoogle Cloud Storageに保存
- Google Cloud Vision APIを使ってGCSに保存したPDFからOCR1で文字を取得
- 取得した文字をspilt["\n"]で分けて朝食、昼食、夕食のテンプレ当てはめる
- テンプレに当てはめた後の文字をTwitter APIを使ってtweet
という感じ
今が一番作ったものに対しての記憶が鮮明だろうということで、忘れない内にコミットメッセージをみて作業内容を思い出しながら備忘録を書くことにした。
2月22日
Twitterbotを作り始める
何も分からなかったが調べていくうちにどうやらTwitterにアカウント登録をして認証のキーを貰うといいらしいということが分かり下のリンクを参考にして認証情報を取得した。
venvで仮想環境を作って作業したはず。
なんかtweetpyを使えば楽にツイートできると聞いたので一度tweetpyを使いツイートしてみたが、どういう処理でツイートできているのか全く分からなかった。requests_oauthlibで認証を行いツイートをpostする方法に次の日書き換えた。
2月23〜3月29日まで
3月30日
そろそろ学校も始まるぞという時期になったので寮食bot作成を再開した。
ブランチを切らずに作業した悪い子がいるらしいですね。誰だろな〜。
ここらへんでGitFlowというmainブランチだけで作業するのではなく、機能ごとにdevelopブランチを切って作業を行うブランチモデルがあったことを思い出し、ブランチを切り始める。ただ、この時に切ったブランチはherokuにデプロイし始めるまでmasterに統合されることなく、機能ごとに分けずにずっっっっっとこのブランチで作業することになる。次からはもう少しブランチを切る頻度を増やしてmainを定期的に更新していけるようにしたい。
この日から日付に応じて寮食が記述されているPDFを取れるようになったらしい。beautifulsoupを使ってaタグのherfがPDFファイルになっているものだけを抜き出し、抜き出したリンクに振ってある日付とdatetimeから取得した今日の日時とを比べることでどのリンクから取得するかを決める処理にしていたはず。寮食は1週間間隔でPDFにまとめて上げられているので[今日の日時 - リンクに記述されている日時]の値が6以下の時にリンクを取得できるようにした。
3月31日
虚無を過ごしていた気がする。
とりあえずwith asでファイルにバイナリデータで書き込む処理を追加しただけっぽい。
4月1日
誤字ってる。
ここではpdf2imageを使って、トリミングしたpdfファイルをpngに変換する処理を書いてる。
プロジェクトのルートディレクトリにpopplerライブラリを持ってきてそのままコミットしたせいでコミットがえげついことになってる。
4月2日
ここか4月1日らへんでOCRを始める。最初はTesseractを使って画像から文字を取得したりしたが、あまりにも精度が悪かったのでTesseractの代わりにGoogle Cloud Vision APIを使った。
Vision APIでOCRをした結果、文字の認識精度がほぼ100%だったので、「すげえ!流石天下のGoogle様や!」ってなってた。
OCRを使ってローカルで文をツイートするとこまでできたし、あとはheroku使ってデプロイするだけやな!heroku簡単らしいしすぐできるやろ!!!
4月3日
.....と思っていた時期が私にもありました(遠い目)
pipでインストールしたものはrequirements.txtに書き出して設定すればいいだけだったのだが、pngに変換するために使っていたpdf2imageを使うために必要なpopplerをHerokuに設定するために色々した。 heroku-buildpack-aptとかを使ってpopplerをなんとか設定しようとしたが数時間を溶かしただけで終わった。
pdf2imageを使わずにPDFをpngに変換する手段か、はたまた何か別の方法でOCRを行う方法がないかなと思ってググっているとvision APIでPDFを使って直でOCRができることを知った。 ただ、PDFを使ってそのままOCRを行う方法は、GCSに保存したPDFに対して処理を行うことにしか対応してないらしかったので、GCSを使うために公式のGCS記事を漁った。
4月4日
GCSに保存したPDFからOCRを行えるようにした。サンプルコードの意味が分からなかったので公式ドキュメントと照らし合わせて一行一行調べながら読んでた
深夜にgoogle cloud vision apiの訳分からないサンプルコードを一行一行ドキュメントで調べる人になってる
— つよつよ園児にゃーになりたい (@guutara_nonki) 2021年4月3日
4月5日
Herokuにデプロイする時に環境変数としてGoogle Cloudの認証情報を渡すとこで詰まった。GOOGLE_APPLICATION_CREDENTIALSにjsonの中身をそのまま渡したら怒られた。
どうやって認証情報を環境変数として渡すか数時間悩んでたが、検索して結構最初の方に目を通した記事に方法が書いてあった。最初に記事に目を通した時はしっかり読めてなかったらしい。ちゃんと読んでないのに読んだ気になるの本当にやめた方がいい。
適当な環境変数にjsonファイルの中身を渡して、Heroku起動時に読み込まれる.profileファイルでjsonの中身を渡した環境変数を展開してjsonファイルに書き込む処理を書き、GOOGLE_APPLICATION_CREDENTIALSには.profileに書いたjsonファイルを指定することでうまくいった。
ローカルで日付を変えて色々な条件でコードを動かしてみたところ上手くいったので、デプロイをしてTwitterでbotが完成したことをツイートした。
既存の物が既にありますが、津山高専の寮食botを作りました!@nittc_ryousyoku
— つよつよ園児にゃーになりたい (@guutara_nonki) 2021年4月5日
寮食のデータを取ってくるリンクが設定されてない場合、リンク先のpdfに飯の情報が書いてない場合でも、必ず1日3回呟くことになってます。1日3回呟いてない時は多分バグを踏んでるので連絡もらえると嬉しいです
この数時間後にバグを踏んだ。 まじで心臓に悪い。
調べてみるとPDFファイルの原点が右上に来ていたのがバグを踏んだ原因だと分かった。PDFの原点は基本は左下らしいので、PDFの左下から相対位置を指定してトリミングする処理を書いたのだが、今回ネット上に上げられたPDFはおそらく右上が原点になっていたのでトリミングの位置がずれ、OCRで読み込む文字もずれてツイートがちんぷんかんぷんな内容になっていた。
PDFの原点が右上の場合の処理を書いて再度デプロイした。
終わりに
途中で知り合いがたった2日で機能的には同じ(中身の処理はどうなってるのか知らないが)物を作った時は心が折れかけた。が根性で頑張った。
botが完成したのでやっとフロントの勉強に入れる。わーい