hirarafu’s diary

twitter:@guutaraiueokaki(https://twitter.com/guutaraiueokaki)

寮食を呟く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を作り始める f:id:hirarafu:20210405205821p:plain

何も分からなかったが調べていくうちにどうやらTwitterにアカウント登録をして認証のキーを貰うといいらしいということが分かり下のリンクを参考にして認証情報を取得した。

venvで仮想環境を作って作業したはず。
なんかtweetpyを使えば楽にツイートできると聞いたので一度tweetpyを使いツイートしてみたが、どういう処理でツイートできているのか全く分からなかった。requests_oauthlibで認証を行いツイートをpostする方法に次の日書き換えた。

2月23〜3月29日まで

インターンハッカソンに出て手をつけていなかった。

3月30日

そろそろ学校も始まるぞという時期になったので寮食bot作成を再開した。 f:id:hirarafu:20210405211045p:plain

ブランチを切らずに作業した悪い子がいるらしいですね。誰だろな〜。

ここらへんでGitFlowというmainブランチだけで作業するのではなく、機能ごとにdevelopブランチを切って作業を行うブランチモデルがあったことを思い出し、ブランチを切り始める。ただ、この時に切ったブランチはherokuにデプロイし始めるまでmasterに統合されることなく、機能ごとに分けずにずっっっっっとこのブランチで作業することになる。次からはもう少しブランチを切る頻度を増やしてmainを定期的に更新していけるようにしたい。

この日から日付に応じて寮食が記述されているPDFを取れるようになったらしい。beautifulsoupを使ってaタグのherfがPDFファイルになっているものだけを抜き出し、抜き出したリンクに振ってある日付とdatetimeから取得した今日の日時とを比べることでどのリンクから取得するかを決める処理にしていたはず。寮食は1週間間隔でPDFにまとめて上げられているので[今日の日時 - リンクに記述されている日時]の値が6以下の時にリンクを取得できるようにした。 f:id:hirarafu:20210405213611p:plain

3月31日

虚無を過ごしていた気がする。 f:id:hirarafu:20210405213759p:plain
とりあえずwith asでファイルにバイナリデータで書き込む処理を追加しただけっぽい。

4月1日

誤字ってる。
ここではpdf2imageを使って、トリミングしたpdfファイルをpngに変換する処理を書いてる。 f:id:hirarafu:20210405214203p:plain
プロジェクトのルートディレクトリにpopplerライブラリを持ってきてそのままコミットしたせいでコミットがえげついことになってる。

4月2日

ここか4月1日らへんでOCRを始める。最初はTesseractを使って画像から文字を取得したりしたが、あまりにも精度が悪かったのでTesseractの代わりにGoogle Cloud Vision APIを使った。 f:id:hirarafu:20210405214901p:plain
Vision APIOCRをした結果、文字の認識精度がほぼ100%だったので、「すげえ!流石天下のGoogle様や!」ってなってた。

OCRを使ってローカルで文をツイートするとこまでできたし、あとはheroku使ってデプロイするだけやな!heroku簡単らしいしすぐできるやろ!!!

4月3日

.....と思っていた時期が私にもありました(遠い目)

pipでインストールしたものはrequirements.txtに書き出して設定すればいいだけだったのだが、pngに変換するために使っていたpdf2imageを使うために必要なpopplerをHerokuに設定するために色々した。 heroku-buildpack-aptとかを使ってpopplerをなんとか設定しようとしたが数時間を溶かしただけで終わった。 f:id:hirarafu:20210405215244p:plain

pdf2imageを使わずにPDFをpngに変換する手段か、はたまた何か別の方法でOCRを行う方法がないかなと思ってググっているとvision APIでPDFを使って直でOCRができることを知った。 ただ、PDFを使ってそのままOCRを行う方法は、GCSに保存したPDFに対して処理を行うことにしか対応してないらしかったので、GCSを使うために公式のGCS記事を漁った。

4月4日

GCSに保存したPDFからOCRを行えるようにした。サンプルコードの意味が分からなかったので公式ドキュメントと照らし合わせて一行一行調べながら読んでた f:id:hirarafu:20210405220334p:plain

4月5日

Herokuにデプロイする時に環境変数としてGoogle Cloudの認証情報を渡すとこで詰まった。GOOGLE_APPLICATION_CREDENTIALSにjsonの中身をそのまま渡したら怒られた。
f:id:hirarafu:20210405220856p:plain

どうやって認証情報を環境変数として渡すか数時間悩んでたが、検索して結構最初の方に目を通した記事に方法が書いてあった。最初に記事に目を通した時はしっかり読めてなかったらしい。ちゃんと読んでないのに読んだ気になるの本当にやめた方がいい。
適当な環境変数jsonファイルの中身を渡して、Heroku起動時に読み込まれる.profileファイルでjsonの中身を渡した環境変数を展開してjsonファイルに書き込む処理を書き、GOOGLE_APPLICATION_CREDENTIALSには.profileに書いたjsonファイルを指定することでうまくいった。

ローカルで日付を変えて色々な条件でコードを動かしてみたところ上手くいったので、デプロイをしてTwitterbotが完成したことをツイートした。

この数時間後にバグを踏んだ。 まじで心臓に悪い。

調べてみるとPDFファイルの原点が右上に来ていたのがバグを踏んだ原因だと分かった。PDFの原点は基本は左下らしいので、PDFの左下から相対位置を指定してトリミングする処理を書いたのだが、今回ネット上に上げられたPDFはおそらく右上が原点になっていたのでトリミングの位置がずれ、OCRで読み込む文字もずれてツイートがちんぷんかんぷんな内容になっていた。

PDFの原点が右上の場合の処理を書いて再度デプロイした。

終わりに

途中で知り合いがたった2日で機能的には同じ(中身の処理はどうなってるのか知らないが)物を作った時は心が折れかけた。が根性で頑張った。
botが完成したのでやっとフロントの勉強に入れる。わーい