| @WWW

Parmesan chicken stripsg

自分は Tasty という BuzzFeed のレシピ動画を参考にするようにしている。自分も前はクックパッドを見ていたが、クックパッドにお金を払っていないため人気順でレシピをソートすることができず、検索してヒットする複数のレシピを見て比較したりするのに疲れてしまった。

Tasty は動画で料理が作られていく課程を見ながら料理をできるので楽しいし失敗しにくいと思う。映像や音楽もプロが作っているだけあって娯楽性が高い。 Tasty の問題点はレパートリーが洋食に偏ること。オリーブオイルどばどばで MOCO'Sキッチン のような感じになってしまいがち。あと簡単には手に入らない調味料を使っていることが多いので、カルディコーヒーなどの輸入食材店に足繁く通うことになってしまう。

手早く簡単に、家にあるもので何かを作りたい、という要求は満たせないかもしれないけど(クックパッドは冷蔵庫にある材料でレシピを検索したりできるのが便利)、料理を作ること自体が娯楽である人には Tasty はとても参考になると思う。

| @Mac/iPhone

Typinator

Lifehack (笑) 臭がしてこれまでキー入力拡張みたいなアプリケーションを使うのは敬遠してたんだけど(そもそもああいうのは IME がないアスキー文化圏の人向けだと思ってた)、 Pull Request 出すときのテンプレートとかを一発で出せたら便利だなと思ってその手のやつを使うことにしてみた。

有名どころだと TextExpander がある。試してみようとしたら何と月額課金に移行してて買い切りではなくなっていた。しかも結構高い(年額 $40)。いろいろ物色してたら昔何かの bundle で購入していた Typinator というやつがあって、こいつならアップグレード料金で使えるし買い切り型だったので使ってみることにした。新規で買っても EUR 24.99 で TextExpander の年間使用料より 1000 円くらい安い(24.99 EUR = 3061.5624 JPY)。

良く入力するやつを省入力できて便利

仕事で Zoom というビデオ会話ツールをよく使う。 Zoom には電話番号みたいに個人に紐付く固定の URL が存在してて、誰かと話したいときにそれを Slack 上に貼りつけて会話を始めたりする。この URL をいちいち Zoom を開いてコピペするのめんどいので ,zoom と打つと出せるようにしている。一瞬で MTG 始められて便利。

,dt と打って2017-03-11 のように今日の日付を表示させることも可能(入力キーや日付・時刻のフォーマットはカスタマイズできる)。こういう機能は ATOK にも付いているけどスペースキーを押したりリターンキーを押して確定したりしなくてよいのが快適。 ふむふむ~、ナルホディウスですぞ のような変換に何度も文節を調節したりしないといけないやつも ,naruho と打てば出せるようになってチャットが円滑に行えるようになった。

長めのやつも展開できて便利

冒頭に書いたように、 Pull Request 出すときに使ってる定型文みたいのがあって、過去の Pull Request からコピーしてきたりしていたのが一発で入力できるようになって異常に便利。 pullreq と入力するとシュバッと展開されるようにしている。こんな感じ。

Typinator

ATOK に辞書登録するのとは違って改行を含んでいてもいいし、日本語入力モードに切り替えなくても良いのが便利。

inputrc で vi mode にしている Terminal (iTerm.app) で使うときの問題点

Typinator には GItHub みたいになってしまうのを抑制する機能がついてて、大文字が二文字連続したあとに小文字が入力されると自動的に二文字目を小文字に変換するという機能( GItHub を GitHub に直してくれる)がついている。 Typinator は vi mode でシェルを操作しているとかは判別できないので勝手に補正してくれて上記のようなキーストロークが bbi と修正されてしまう。

Vimmer なのでシェルの操作モードを vi mode にしているのですけど、単語移動するときについつい

Shift + b Shift + b i

とか入力してしまうと Typinator が反応して bbi に補正されてしまってうざい。

設定に DOuble CAps Exception というのがあって例外設定できるみたいだったので BBi を追加してみたけどどうもうまく効いてないみたい…( bbi に補正されてしまう)

スクリーンショット 2017-03-11 13.59.08.png

さらに詳しく設定を調べてみると、アプリケーションごとにルールの有効・無効を切り替えられるっぽいので、 iTerm を使っているときは連続する大文字の小文字補正を行わないことにしてみた。これで様子を見てみよう。

スクリーンショット 2017-03-11 14.04.34.png

| @技術/プログラミング

Vim で Markdown を編集するとき、 vim-quickrun を使って Marked でプレビューするようにしてる。これが便利で体に染みついてるので、 Deckset で表示する用の Markdown スライドを Vim で編集しているときに一発で Deckset を開いてプレビューできたら便利だなと思ったので以下のようにしてみた。

  1. ファイルのパスに slides が含まれていたら filetype を markdown.slide にする
  2. そんで ft=markdown.slide のときは vim-quickrun で Deckset にファイルをプレビューできるようにする

こんな感じ。

au Bufread,BufNewFile /*/slides/*.markdown set filetype=markdown.slide
let g:quickrun_config['markdown.slide'] = {
      \ 'outputter' : 'null',
      \ 'command'   : 'open',
      \ 'cmdopt'    : '-a',
      \ 'args'      : 'Deckset',
      \ 'exec'      : '%c %o %a %s',
      \ }

便利。

| @技術/プログラミング

ブログの管理画面にファイルアップロード機能をつけてみた。 GitHub の Issue みたいにドラッグアンドドロップでアップロードしてくれる。こんな感じ。

file upload demo.gif

いまのところ埋め込みフォーマットは Markdown にしか対応してない。

Lokka は heroku とか PaaS を使うことを前提に作られているのでファイルをアップロードする機能が提供されてこなかった( heroku は永続的なファイル書き込みができない)。 heroku で動かしている人でも使えるように Amazon S3 に上げるようにしてみた。 AWS のアカウント作成とかが必要なのでレンタルサーバーに設置してある WordPress にファイルアップロードするのに比べたら敷居が高いけど、設定するのは1回だけだし全くアップロードする手立てがなかったこれまでに比べたら劇的に快適になるはず。自分で使ってみたけどめっちゃ便利になった。

ファイルアップロード、ちゃんと作るなら Paperclip みたいにファイルのチェックを厳密に行なわないと危ないと思うけど、管理画面から上げるの前提なのでチェックなしで雑にアップロードできるようになっている。 AWS の token 系の設定画面を作ったら Lokka 本体に Pull Request 出します。

なお一つ前の記事でアプリケーションサーバーを puma に変更 - portal shit!というのを書いたけど、このファイルアップロード機能がうまく動かなかったので unicorn を捨てたのだった( pow で動かしている環境や bundle exec rackup して WEBRick で起動しているサーバーではちゃんとアップロードできる)。なぜか unicorn で multipart/form-data な POST リクエストを rack アプリケーションに適切に渡すことができず EOFError が発生してしまう。

仕事で unicorn で動いてるサーバーにファイルアップロードする仕組み入れたことは何度かあるけどこんなエラーになったことはなかったのになぁ。謎い。

| @技術/プログラミング

ブログのアプリケーションサーバーには unicorn を使っていたのだけど puma に変えてみた。

2011 年から使っていたようなので丸 5 年は unicorn を使っていたことになる。 puma はスレッドセーフにしないと死ぬ、ということは聞き及んでいたのでおそるおそる変えてみたけどいまのところ問題なさげ。

手元で確認したときには scss のコンパイルで怪しい雰囲気があった(特定ページにアクセスしたあとレスポンスを返さなくなってしまう)ので 0.12.7 だった compass のバージョンを 1.0.3 に上げてみたところ問題が解決した。結果オーライということで深追いはしてないけど、リポジトリを見に行ってみたらメンテナンス停止しているようだった。最近はフロントエンドは JavaScript でやるのが当たり前ですもんね。

Lokka のフロントエンドは 2010 年頃ナウかった Ruby ベースの技術が満載で最近の傾向とは異なるので、フロントエンドで利用してる gem がメンテされておらず Ruby のバージョンアップ時のボトルネックとなってくることが考えられる。この前 Ruby 2.4.0 で動くか素振りしてみたけどダメだった。padrino-helpers 、 slim 、 haml 、 coffeescript (この機能は自分が追加した)あたりとどういう風に折り合いを付けていくか考えないといけない。

| @技術/プログラミング

Pinboard にブックマークしたらはてなブックマークに同期するやつを作った。

なんで Pinboard を使うのか、どうしてはてブに一本化しないのかというと、洋物のサービスを使うときに Pinboard の方が使いやすいから。 IFTTT に Pinboard 連携機能はあってもはてブ連携機能はないし、 Delibar や Reeder や ReadKit も Pinboard には対応しているけどはてブには対応してない。あと Pinboard は広告出ないしホッテントリ的なものもないので気がついたら Amazon で買い物してたとかホッテントリの海に溺れてた、ということも起こらない。とはいえはてブのコメントでキャッキャッウフフはしたい。なのでブックマークするときは両方にしたい。パソコンの Chrome からブックマークするときは Taberareloo でクロスポストできるのだけど、最近 iPhone からブックマークすることが増えて(iPhone 進化し過ぎて仕事するときしかパホコン使わなくなった) Pinboard とはてブにそれぞれブックマークするのがだるかった。そういうわけで Pinboard をメインにしつつはてブに同期を試みた。

はてなスタッフの aereal さんが作ってるはてブ API 用の gem (aereal/hatena-bookmark-restful: A client library for Hatena::Bookmark RESTful API)あって使わせてもらったのだけど、これはそのままだと使えない。タグが複数あるケースに対応してない& User-Agent を送らないので API 側から 401 Unauthorized が返ってくる。なので雑にモンキーパッチした。

はてなブックマークの API は tag を 10 個まで設定できるけど、以下のように Request Body が Encode されるのを期待しているっぽい。

"comment=&tags=ruby&tags=http&url=https%3A%2F%2Fgithub.com%2Flostisland%2Ffaraday"

この様な Request パラメーターを Ruby で表現すると以下のような Hash になると思う。

params = {
  comment: '',
  tags: ['ruby', 'http'],
  url: 'https://github.com/lostisland/faraday'
}

Hash は当然のことながら同じキーを複数持つことはできないから、 tags は配列として表現される。これをこのまま Faraday (Ruby の HTTP クライアント。上述の gem でも使われてる)に渡して Request Body を生成するとエラーになってしまうのだった。

最近の Faraday には encode option が追加されて FlatParamsEncoder というのを選べるようになってた。こいつを使うと配列を value に持つ Hash をシリアライズしたときに tags=foo&tags=bar みたいな形式にしてくれる。加えて User-Agent も載せるようにもした。こんな感じ。

class Hatena::Bookmark::Restful::V1
  def create_bookmark(bookmark_params)
    res = connection.post("/#{api_version}/my/bookmark") {|req|
      req.params = bookmark_params
    }
    attrs = JSON.parse(res.body)
    bookmark = Bookmark.new_from_response(attrs)
  end

  private

  def connection
    @connection ||= Faraday.new(url: 'http://api.b.hatena.ne.jp/') do |conn|
      conn.request :url_encoded
      conn.options.params_encoder = Faraday::FlatParamsEncoder
      conn.request     :oauth, {
        consumer_key:    @credentials.consumer_key,
        consumer_secret: @credentials.consumer_secret,
        token:           @credentials.access_token,
        token_secret:    @credentials.access_token_secret
      }
      conn.headers['User-Agent'] = 'Hatena::Bookmark::Restful Client'
      conn.adapter Faraday.default_adapter
    end
  end
end

なおはてブの API はリクエストパラメーターが不正なとき 400 Bad Request を返すのではなく 401 Unauthorized を返す。のみならず User-Agent なしのリクエストに対しても 401 を返す。一方で OAuth ヘッダーが不正なときは 400 を返す。原因の切り分けがむずかしくなるので、リクエストパラメータが不正なときは 400 を返して欲しいし認証できないときは 401 を返して欲しい。

追記 2017-05-22 18:34:38

作者の aereal さんに気づいてもらってパッチを取り込んでもらったんだけど、なんかやっぱりタグありの記事をブックマークしようとするとエラーになるっぽい。相変わらず 401 Unauthorized が返ってくる…。

| @散財

iPhone 7

iPhone 7 を買った。 iPhone 6 を買ったのは 2015 年 7 月で買い換えサイクルからするとだいぶ早いのだけど、いい加減両親にガラケーを卒業してもらおうと思って、弟も少し前に iPhone を買い換えたので自分のと弟のを両親に渡して docomo から MVNO に引っ越してもらおうという算段。弟の iPhone 6 は docomo のやつで自分の iPhone 6 は SIM フリーなので問題ない。いい世の中になった。

一括払いで 9 万円も払えるような富裕層ではないのでオリコのローン( 20 回分割まで金利が 0% のやつ)で買った。 iPhone 6 を買ったときは転職したばかりで社会的信用ゼロだった& iPhone 5 をクロアチアでなくしてしまって一刻も早く電話が必要だったためクレジットカードの分割払いで買っていたので、今回が人生初のオリコローン。審査結果出るまでに結構時間がかかり、ベンチャー企業に勤めてるせいで審査通らないのかなとやきもきした。急いで欲しい人はローンは使わない方がいいと思う。ひょっとすると一部上場企業勤務の人だと一瞬で審査降りるのかもしれない。

Suica on iPhone 7

iPhone 7 では Suica を Wallet に登録できるはずなので ANA VISA Suica を登録して電子マネーはこれに一本化しようかと思っていたけど、 ANA VISA カードの Suica を吸い出して Wallet に追加することはできないみたいだった。調べてみたところ JR 東日本の Suica アプリでモバイル Suica を新規発行し、そのチャージ用のカードに ANA VISA Suica をクレジットカードとして指定すればよいっぽい( Suica が一枚増える感じ)。 ANA VISA Suica は View カードでもあるのでモバイル Suica の年会費はかからない。これでいつでも iPhone からチャージできて便利。オートチャージの都合で JR 九州の SUGOCA を使っていたけど( Suica は関東でないとオートチャージできない)、 iPhone からいつでもチャージできるとなれば Suica でも困らなそう。ほかの電子マネーの Apple Pay 対応が遅れたら Suica が交通系電子マネーの乱世を統一するかもしれない。

ハードとしての iPhone 7 の感想は、とにかくめっちゃ速いのがいい。 Touch ID とか一瞬で認証される。 Force Touch もよい。 iPhone で長い文章を入力中にカーソル位置を動かすの、結構ストレスだったんだけど Force Touch だと押し込んだだけで Vim のビジュアルモードのようにするするとカーソルを動かせて便利。ストレージが増えてるのもいい。いわゆる "竹" スペックの 128GB のやつを買ったのだけど、これだけあれば Eye-Fi で写真転送しまくっても iPhone がお腹いっぱいになったりしないだろうから安心。音楽もいっぱい入れられるので飛行機に乗ったときに iTunes Match 使えなくてほとんど聞ける音楽がない、という事態も避けられる。

一方で残念な点。ホームボタンが物理ボタンじゃなくなったのは慣れない。押し込んだ時のバイブレーションが MacBook Pro のトラックパッドの完成度とは大違いで残念。あとこのホームボタン、風呂で使える系のケースに入れてると押せないことが判明して愕然とした。無印良品の風呂スマートフォンケースに入れてみたところ押しても反応せずホームボタンはお飾りとなった。防水とはいえ風呂で使って水漏れ判定されたという話を聞くので風呂 iPhone するときは防水ケースに入れたいもの。ホームボタン効かないと全く使えないわけではないけど著しく操作性が低下する(Today widget を呼び出して適当なアプリを開きロック解除、 Force Touch でアプリ切り替えを呼び出しホームスクリーンに切り替え)。

Silicone case for iPhone 7

ケースは Apple のシリコーンケースを買ってみたけどめっちゃすべって良くない。 iPhone 5 や iPhone 6 には革のケースを使っていて、滑るということはなかった。革ケースは高いし(安い Android が買えそうな値段) 2 年近く使ってると破れてくるので次はシリコーンケースにしてみようと変えてみたけど失敗だった。やっぱり iPhone は裸が薄くて持ちやすくて最高。ケースを付けずに iPhone を使えるような精神力が欲しい。ガラスの保護には Anker のやつを買った。 iPhone 6 使ってるとき 2 回くらいコンクリートの上に落としたことあるけど iPhone のガラスは何ともなかったのでこれは頼りになると思う。

不満なところ、不便なところもあるが、 iPhone 6 に比べると格段に良くなっている。地方に住んでて Suica 使えないので iPhone 7 はパス、と思ってる人も実は使えて便利になる可能性があるのでご一考をお勧めします。