ハンドサイン一覧ジェネレーターを作りました #appengine #php
作りました→ http://handsign-gen.appspot.com/
ソースコードはこちら→ blueberrystream/handsign-gen · GitHub
サイトデザインは相変わらず自分でやるよりいい感じにできる人からpull requestが来ればいいなーなんて思ってわざとやってません。本当はtweetできるようにするところまでやりたかったのですが、31日に突然流行りだしたネタなので、ともかく最低限使えるものをリリースしたいと考え、こんな形でのリリースになりました。急ぎましたが、ネタの鮮度がだいぶ落ちているので、あまり話題にはならないですね。
もし、評判がよければ Issues · blueberrystream/handsign-gen · GitHub に載せたこと、これから載るかもしれないことを実現していこうかなと思っています。
いまのところ、私のTwitterアカウントがprotectedなのもあって、大々的に拡散されてアクセススパイクが来るということはないのですが、身内で使ってくれる人がいてうれしい限りです。
きっどたんのジェネレータで作ったDQ10盗賊がよく使うハンドサイン一覧 #DQ10 #DQX pic.twitter.com/t1oNmN1RRJ
— じょにー (@j_k54) 2014, 4月 3
ドラクズの身内チーム内でよく使うハンドサイン pic.twitter.com/BfLrINAooA
— 大臣さん(10) DQX&戦国無双 (@daijin) 2014, 4月 3
さて、せっかくこちらの ぶるべりてくにか のblogに記事を書くわけなので、技術的なことをつらつらと書いていこうと思います。
注: 本当に技術的なことはここよりもっと下に書いてあります。
今回は動的な画像加工をプログラムからやるということなので、間借りしているVPS上だったり、お借りしているwebスペース*1でやるのはよろしくないと判断してApp Engineにしました。
当初は、プログラムから画像加工をするならどうするのが早いかなーってぼやいてたら
画像合成はImageMagick使うのが一番楽じゃないかなあ…
— Lix / すかい (@skyriser) 2014, 3月 31
とLix先生がおっしゃる*2ので、ImageMagickのお世話になろうかと思ったのですが、AppEngineじゃ動かせるわけもなく…。そして、やりたいことはテンプレートの画像に文字を載せたいだけだったこともあり、PHPでGD関数を使うことにしました。
最近の流行に乗ってGo言語とかやってみたいと思っていますが、画像に文字を乗せるプログラムなんて書いたことがなかったので、ここは手に馴染んでいるとは言いがたいけど、Javaより素早く結果確認ができるPHPとなりました。
構成は、AppEngineでPHP、画像を扱うのはGD関数ってことで決まりました。お次は開発環境の構築です。AppEngine/PHPな環境はWindowsにもMac OS Xにも作っていなかったのでイチからの作業でした。push-to-deployができなくてハマったり、Google Cloud SDKをインストールしたらbashの様子がおかしくなったりで結局4時間くらいかかりました。1日目終了。
ようやく開発環境ができて、ちょこっと前に招待をもらったAtomを使って開発スタート。Development Serverで動かしながらある程度は形になってきたところで、Production Serverにdeployして動かしてみると動かない…ってところで2日目終了。これもだいたい4時間くらい作業したかな。
Production Serverだとテンプレートとなる画像にPHPからアクセスできなくて動かないという状況に陥り、結局はapp.yamlのhandler定義がよろしくなかっただけじゃんってことでリリースできたのが3日目でした。作業時間は2時間くらい。合計で10時間くらいで今回は初版リリースができました。
では、今回つまずいたところやおかしいなと思った点をまとめてみます。今回の開発はすべてMac OS X上で行いました。Windowsだとだいぶ勝手が違うかと思います。
push-to-deployができない
最初はDeveloper Consoleで表示されているリポジトリのURLをgit remote addしてpushすればいいだけだろ?って思ってたんですが、そんなことできようもなく…。これは、Git and Push-to-Deploy - Google App Engine — Google Developersに書いてあるように、
$ gcloud init PROJECT
としてやらないといけないわけです。でも、これをそのままやると、Googleアカウント情報を聞いてきます。正しく入力してもダメです。2段階認証のせいやろ〜と思ってアプリケーション固有パスワードを発行して使ってみてもダメです。正解は
$ gcloud auth login
としてあげることです。これで、gcloud init*3を実行できます。
この件は、ちゃんと公式文書を読みましょうってことに尽きますね。
Google Cloud SDKをインストールしたらbashの様子がおかしい
原因は、インストール時に~/.bash_profileなどに追記される
でした。path.bash.incの中身を見るまでもなく、Google Cloud SDKのbinをPATHに通そうとしてるわけですが、中身を見るとなんかごちゃごちゃやってたので、とりあえず上記の部分をコメントアウトしてディレクトリ直書きでPATHを通すことにして解決としました。根本的な原因はおそらく、bashでaliasを使いまくってる*4せいじゃないかなーと推測しています。
Production ServerでPHPから画像ファイルにアクセスできない
ログを見ると
PHP Warning: imagecreatefrompng(../static/image/template.png): failed to open stream: No such file or directory in /base/data/home/apps/s~handsign-gen/dev.374851488411224157/script/gen.php on line 29
と出ています。パスの指定の仕方が悪いのかなーと変えてみたりしましたが、結局はapp.yamlのhandlerの書き方が悪かっただけのようでした。
修正前は
handlers:
- url: /
static_files: static/index.html
upload: static/index.html
- url: /(.+\.(html|css|js|txt|ico|gif|png|jpg))$
static_files: static/\1
upload: static/.+\.(html|css|js|txt|ico|gif|png|jpg)$
- url: /(.+\.php)$
script: script/\1
- url: /image/template.png
static_files: static/image/template.png
upload: static/image/template.png
application_readable: true
としていましたが、
- url: /image/template.png
ではじまる部分を
より上に持ってくるように修正しました。handlerは上から順番に見ていって一番最初に引っかかったものを使うということですね。
Development Serverでログを確認できない
これはかなり参りました。そして今も解決できていません。AppEngine PHPではsyslog関数でログ吐きができます。吐かれたログはProduction ServerではDeveloper Consoleから確認できます。しかし、Development ServerではGoogleAppEngineLauncher.appのログビューにも出てきません。どうやったら出るんだろう?どこに出てるんだろうといろいろ試した結果が以下です。
- dev_appserver.pyにフラグ--log_level=debugを指定→出てこない
- dev_appserver.pyにフラグ--log_files=hogehogeを指定→ちゃんと起動しない
- まさかマジでsyslogに出てる?→syslog確認→出てない
- Development ServerのAdmin ConsoleにあるInteractive ConsoleでLogs PHP API Overviewに載っているSample codeを動かす→取れたり取れなかったり→そもそもこんなアクセス方法を期待しているわけではない
- php.iniに出力する最低ログレベルの設定があるのでは?→なさそう
というような感じです。Development Serverでログを確認する方法をぐぐって調べるも、たいていJavaについてばかりでした。Development Serverでログを確認する方法、詳細求ム…です。
フォントファイルをhandler定義に載せなくてもアクセスできる
今回のアプリではフォントファイルをプログラムで読み込むのですが、上述のPHPから画像ファイルにアクセスできない件で晒したapp.yamlのようにフォントファイル(*.ttf)についての定義がありません。画像のように
application_readable: true
と書いていないということです。しかし、Production Serverでも普通にPHPから読めているようです。謎です。
いまさらPHPかよって感じではありますが、ログの件とフォントファイルの件はおわかりになる方がいればぜひ教えていただきたいです。おねがいします。