hogashi.*

日記から何から

今週の頑張り

 一から Webアプリを作ったことがなかったので、現在地の情報を勝手にエディンバラに付けてツイートする Webアプリを作って勉強した。 Ruby 使っているけど Ruby あんまりわからないので雑。

github.com

 まずツイートしたいと思って、簡素にできると聞いていた Sinatra を使って、 apps.twitter.com でキーを 4つとも取得してコードに直書きして、 Twitter gem で OAuth 完了状態にしておいてツイートしたりした。Twitter::REST::Client.newにキー4つを渡すのだけど、 Twitter gem の使い方はなんとなくインターネットを見てやっているので正しいのかわからないけどリクエストはできている、みたいな状態。
 Twitter のアプリのキーを 4つとも取得して置くのは本当は違って、アプリ固有のキー (2つ)でユーザ固有のキー(2つ)を取得する、みたいなことをするのが OAuth で、以下で直していくけど、とりあえずツイートしたかったのだった。

 現在地情報は、Twitter::REST::Tweets#update の引数に渡すオプションのハッシュに latlong で緯度経度を指定すればよいらしいのでやったけど、できなくて、色々やっていたら place という方に Twitter::Place を渡すとできた。
 渡す Twitter::Place は、 Twitter::REST::PlacesAndGeo#geo_search で取ろうとしたけど、なんか情報がたくさん要るらしくてわからなくて、 Twitter::REST::PlacesAndGeo#similar_places のほうに、緯度経度をlat, long、「Edinburgh」という地名を name で渡した。
 これでエディンバラの場所情報がついたツイートができた。

 テンプレートを書いて、formからPOSTでリクエストしたらtextareaの中身をツイートするようにした。paramsにフォームの内容が入っていて、textarea[name="text"]ならparams[:text]で取れて、それをツイートする。

 なんとなくツイートできるようになったので、 OAuth したくなったのだけど、 Twitter gem にあるTwitter::REST::OAuthは使い方がよくわからなかったのでインターネットを見たら、 OmniAuth というのがよいという話だった。 Sinatra 公式が例として上げているくらいなのですごそう。実際に使うのは omniauth-twitterFacebook とかもあるらしい。
 アプリのキー2つConsumer Key (API Key)Consumer Secret (API Secret)を使って、ユーザのキー2つAccess TokenAccess Token Secretを取って、ユーザごとにTwitter::REST::Client.newするみたいな感じになる。
 OmniAuth で理解に苦しんだところは、肝心の OAuth するところで /auth/twitter とかいうエンドポイントにリダイレクトするけど、そのエンドポイントは定義してないじゃん、というところで、実はコメント文をよく見ると書いてあって、/auth/twitterは OmniAuth が拾うので、投げるだけでよいらしい。
 リクエストは投げられるけど Sinatra が 403 エラーを出すのでインターネットを見たら、 apps.twitter.com のほうでアプリの callback URL をちゃんと指定しないとそうなるらしかったので、したら直った。これ難しくて、 403 とだけ出されても、特に解決方法がわからない。 callback URL は、この場合ドメイン/auth/twitter/callback とするようになっているけど、多分なんでもよくて、beforepass if request.path_info =~ /^\/auth\//のところで引っ掛けたいから/authで始めている、というだけだと思う。ドメイン/koorubakku というふうにして、pass if request.path_info =~ /^\/koorubakku/とか足せば良いんだと思う。
 あとそもそも pass if request.path_info =~ /^\/auth\// にうまく引っかかってない感じがあって、無限に認証しまくるループになったりした。いや引っかかってるのかもしれないけど pass が上手くいってないのか、 pass がそもそも何なのか知らないので、何もわからなくて、使うのやめて、素朴に if で条件分岐するようにした。しかも、そもそも勝手に認証してほしくないので、before も使わなくなる(後述)。
 あと認証済みかどうかを保存するのにsessionというハッシュに突っ込んでおくようにしたけど、なんか Rack のセッションらしくて、よくわかっていない。なんかうまいことセッションをやってくれるんだと思う。あんまりなんでもかんでも突っ込むと、容量オーバーして怒られるので、最小限にする必要があるけど、ツイートごとにユーザを認証したりするのは絶対おかしいので、Twitter::REST::Clientは入れておくようにした。合ってるのか全然わからない。

 これで大体動くようになってきて、テンプレートにログイン/ログアウトボタン足したりした。

 ここでツイートをするのに毎度ページ遷移(見た目は変わらないけど毎度読み込んでる)するのはもったいないなと思ったので、JavaScript でPOSTリクエストすればいいか、となり、それなら axios が良いですよ、と教えてもらったので使った。POST リクエストは上手くパラメータが取れなかったので、GET リクエストにしている。ちゃんと勉強すればできるんだと思うけどちょっと勉強したくらいでは解決できなかった。

 あとの問題は公開で、サーバのこともよくわかってないので、ここの勉強もいずれはしたいけど、今回は良いかと思ってしまったので、 Nginx のこと勉強したりせずに、 Heroku にデプロイすることにした。 Procfileweb: bundle exec ruby app.rbとかやればいいらしいのだけど、Thin というサーバが小さくて便利だよとインターネットに書いてあったので開発中にも使っていて、そのまま使おうかなという気持ちになったので、bundle exec thin -R config.ru -p $PORT start とか書いた。 $PORT は勝手にセットされるらしい。開発環境で何もしていしないと 5000 番になった。 Heroku なら Heroku 側が好きなように渡してくれるんだと思う。
 Heroku で yarn installとかyarn run buildとかしてもらいたくてインターネット見たら、Heroku の Settings で Buildpacks ってところに Node.js を足せばよいらしいと書いてあって、そうした。yarn run heroku-postbuild とかを実行してくれるので、package.jsonに書いておくとやってくれる。今回は webpack 使ったので、それをやってほしかったのだった。
 これでちゃんと HTTPS で配信されるし便利。

 こういう気持ちで webpack.config.js 書いてるのか~とか、エンドポイントってこういう感じに切ると便利なのか~とか、少しずつ学びがあってよかった。今回は特に CSS はやっていないし、 Ruby とサーバは分かってないのでそこは勉強が必要。

今日の頑張り

 英語記事翻訳記事の原文を読むやつ、気力があるときに気まぐれにやるんですが、今日やったやつ異常に難しい割に面白かったので供養。面白いですか? あんまりわかりません。

 以下雑で、weblio引いてへぇって言いまくったのを起こします。いつもありがとうweblio。本文に出てないけど引いたやつは☆をつけます。

英和辞典・和英辞典 - Weblio辞書

続きを読む

 風邪をひいている。金曜の夕方には怪しかったがカカッと熱が出て寝込み続けている。寝込むと書くとおおごとに見えるけどそんなことはなくて、頭が痛いのと周期的にだるいのがくるので寝るという感じで、ご飯は食べられる。ので良くなるかと思いきやなかなか良くならない。ので今日は医者に行く。熱は37度ちょうどで、なんとも微妙。

 スマートフォン、大きくなっていっているけど、果たして大きくなると便利なのかという疑問はあって、軽くなるのは楽になるとおもうんだけど、軽くなりすぎても持ってる感じがしないというか、安定しないとかはありそう、大きさはもっと大変で、大抵片手で使いたい気持ちがあるのに持った手の親指では触れない画面箇所が生まれてくるし、そもそも持つこと自体大変で、手が大きければ良いけどそうでもないので、持つのに精一杯になったりする。小さくて画面に収めきれないとかいう前に少しだけボタンの配置とか考えてみてほしくて、そのボタンそんなところにおいてるけどもっとスペースあるじゃんとか、かっこよさに振ってる所為で形がユニークだけど場所を取るとか、一画面で色々やりすぎとかがあると思う。操作数は多くなってもまあ良いと思っていて、モーダルが出て選ぶとかにしてほしいんだけど、皆は嫌いらしくて、使いやすいものを探すのが難しい。文句しか言わないんなら自分で作れと言われそうだし、スマートフォンSNSクライアントも音楽再生ソフトも軽率に自分でつくれる時代になってほしい。

 好きな小説のシリーズが終了したので満たされ感がすごい、いや実際はあと何十冊でも続いてほしかったけどそういうことはないのでそれはそれでよくて、全く裏切られないというかむしろ与えられまくって脳がバグったりした。そもそも小説をほとんど読まないというのもあるかもしれない。

2ウィンドウを同時スクロールするブックマークレット

 2つのウィンドウに Web ページを開いて同時スクロールするブックマークレットを書いた。XYどちらも同期する。
 Google Chrome で動くことは確認した。そのままコピーして Console に貼り付けても動く。

  • 出るプロンプトにURLを入れると、新しいウィンドウで開かれる
  • 元ウィンドウをスクロールすると、新ウィンドウもスクロールされる
  • 元ウィンドウ上で Ctrlキーを連続 2回押すと、 "ズレ修正モード" に入る
    • 元/新ウィンドウを別々に好きな位置にスクロールしてから、
    • 元ウィンドウでもう一度 Ctrlキーを押すと、その状態で確定し
    • その位置からスクロールが同期する

Dentoo.LT のページを見比べる様子 (赤丸: クリック / 黒丸: Ctrl)

gist.github.com

実行したコマンドの終了をmacの通知で知らせるbash関数

 実行したコマンドが終わったことを、 mac の通知で知らせる bash 関数を書いた。実は関数だけではできなかったので、 alias との組み合わせ。

$ heavycommand --bigoption
...
# 終了時に終了ステータスとコマンド文字列が入った通知が出る:
#   0 : "heavycommand --bigoption"

gist.github.com

説明

 長いことかかるコマンドが終わったことを、他の作業をしていても気付けるように mac の通知で知らせる。すぐに終わるコマンドでも同様に通知が出て嬉しい。
 terminal-notifier というツールがあり、タイトルとかメッセージとかを指定すると通知として出る。これに、実行したコマンド自体の文字列と、実行した結果の終了コードを渡す。
 実行するコマンド自体の文字列を取るのが意外と難しくて、単純に関数の引数として取ったりすると、 alias とかが解決されていなくて、関数内で exec とかしても実行できない場合がある。ので、 alias を使って、 $READLINE_LINE を取る。これは bash の機能による変数のようで、プロンプトの後に打ち込んでいる最中の文字列がセットされる (reverse-search のカスタムに使ったりする)。これを参照すると、 alias や !$ のような bash の機能でのコマンド入力が、解決された状態で取れる。

  • nt: $READLINE_LINE でコマンド文字列を取り、関数_ntに渡す
  • _nt: 渡された文字列を実行して、終了コードを取り、文字列と一緒に通知する

 ntdosome は、頻出長大コマンドの簡略 alias の例。環境変数は、 ntの前でセットする。