| @WWW

DSC_4054

以下の文章は正月に「2017 年の Lokka へのコントリビュート目標」というタイトルで書いたまま下書きになってたものです。もう 2017 年も終わりそうだけど公開しておきます。


RubyKaigi 2016 で komagata さんと Lokka についてしゃべったのだけど、 Lokka の開発も停滞してしまっていて(ブログとしては大体の機能そろっていて完成しているとも言える)、 "lokka" でググると JavaScript 製の GraphQL クライアントがヒットして、 GitHub のスター数ではこっちの方が多かったりする。

このままで紛らわしいからその名前こっちに寄越せ、とか言われかねない。もっと Lokka を盛り上げていきたい。

なので一度仕切り直しで今後の方針とかをどうするかを決めた方がよいのではないかと思っている。まずは Issue の棚卸が必要ではないかと思う。

加えて自分でも結構いろいろ lokka-plugin を作っているのだけど、個人のリポジトリに適当に上げてあるだけだとユーザーとしては利用しづらいと思う。そこで GitHub の Lokka org に lokka-plugins というリポジトリを作って、とりあえずそこにコードを集約するようにしたらどうかと思う。前に Rebuild で Jenkins の川口さんが話していたやり方。

OSS 、コードが素晴らしいことも大事だけど、利用しやすくないとユーザーに使ってもらえなくて盛り上がって行かないと思う。プラグインを使いやすい、作りやすいようにして裾野を広げていきたい。

ほかにも手軽に使ってもらうためにはいくつかやらないといけないことあると思う。 gem 化は是非とも必要だと思う。 Lokka 動かすために本体のソースコードごと管理しなければいけないのはやっぱり結構敷居が高いと思う。ディレクトリ作って Gemfile に gem 'lokka' と書いて bundle install し、 theme と db config さえ置けば動くようになるのがよさそう。ファイルをアップロードする仕組みについてもどうにかしたい。 Heroku 運用が前提のためファイルシステムを使うことができず本体にそういう仕組みがなかったのだと思う。 Amazon S3 や Google Cloud Storage 、 Dropbox 使えるようにするとかやり方を考えたい。

これらを推し進めるために、以下のことをやりたい。

  1. Lokka 開発者ミートアップを開催
  2. Slack にチームを作ってコミュニケーションできるようにする

1 は RubyKaigi のときに komagata さんに提案したけどそのあと動けてなかった。とりあえずは自分が komagta さんのところに会いに行くだけになるかもだけど、 Issue の棚卸と今後の方向性を固める会をやった方がよさげだと思う。仕事でも OSS でも意思や目的を共有しないと Project は先に進まないと思う。

2 に関しては Lokka は Lingr でコミュニケーションしていたが、いまは皆さん Slack を仕事で使っていると思うし Slack の方がコミュニケーションしやすいはず。というわけで Slack チームを立ち上げたい。1

という感じで 2017 年も Lokka の開発に関与していきたい。


転職して東京に行く機会がなくなり、結局 Lokka 開発者会議をやることはできなかった。プラグインの gem 化はおろかリポジトリへの集約も DataMapper => ActiveRecord への移行も手を付けられなかったが、それ以外で Lokka の改善は結構頑張ったと思う。

今年やった Lokka の改善

  • パーマリンク生成高速化 https://github.com/lokka/lokka/pull/220
    • Lokka はどのフォーマットで permalink を生成するかを DB に保存している
      • リンクを一つ生成する度に permalink のフォーマットを調べるためのクエリが流れる
    • ビュー内で各記事へのリンクは多数
      • めっちゃクエリが流れる 😱
    • request_store.gem を使ってリクエストごとに一回だけクエリが流れるようにする
      • テーマにもよるが記事一覧でパーマリンク生成のために 10 回くらい DB アクセスが発生していたところは 1/10 になる
      • 管理画面の記事一覧では 100 記事表示しているので 1/100 になる(爆速になった!!!、!)
  • 管理画面をスマートフォン最適化 https://github.com/lokka/lokka/pull/225
    • スマートフォンから管理画面が見やすくなるよう CSS を修正
    • 寝床からでもブログ書けるようになった!!!、!
  • ファイルアップロード機能を追加 https://github.com/lokka/lokka/pull/226
    • S3 にバケットを作ってもらいさえすれば GitHub のようにドラッグ&ドロップで画像をアップロード出来るように
    • めっちゃお手軽お気軽に画像アップロードできるようになって最高便利!!!、!
  • MySQL 絵文字対応 https://github.com/lokka/lokka/pull/230 😃
    • 今の時代、絵文字が使えないのはつらい 😅
  • Ruby 2.4 対応 https://github.com/lokka/lokka/pull/231
    • Lokka で Sinatra 、 DataMapper の次に依存度が高い PadrinoHelper のバージョンを上げることに成功(めっちゃ大変だった!!!、!)
      • 自分としては Rails 3 を Rails 4 に上げるくらいの働きをしたと思ってる😎

locale が i18n.gem がサポートしてるやつじゃないと 500 エラーになるという問題があって、こちらも自分のブログでは直してあるので修正する Pull Request を出したい。

P_BLOG のときもそうだったけど、どうも自分はユーザーの少なくなってきた CMS を細々と改造して使っていくのが好きみたいだ。このブログの開発・運用から学ぶことも多くて仕事にも役立っているので、まだしばらくは使い続けていきたいと思う。 Lokka は永遠に不滅です。


  1. 調べてみたらすでに lokka.slack.com は存在するみたいなんだけどこれって Lokka for CMS のやつですかね? 

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

ブログに人気記事を表示するようにしてみた。やり方はめっちゃ雑で、 Nginx の access_log を集計して Bot や Crawler 、 RSS Reader からのアクセス、画像や CSS 、 JS ファイルへのアクセスを除外してアクセス数を集計して結果をテキストファイルに出力し、 Ruby で parse してフッターに表示してる。

仕組み

こんな感じのシェルスクリプトを置いて cron で実行してる。

#!/bin/bash

zcat -f /path/to/access.log* \
  | grep -vE 'useragent:.+?(bot|Feed\s?Fetcher|Crawler|Fastladder|Feed|Ruby|Aol\sReader|proximic|Hatena\sAntenna|Mediapartners-Google|subscribe)' \ # bot や Crawler を除外
  | cut -f5 | sed -e 's/request_uri://' \ # request_path だけ抜き出し
  | grep -vE '(favicon\.ico|index\.atom|\.js|\.json|\.css|\.jpe?g|\.png|\.gif|\.txt|\.php|\/admin|^\-$|^\/$)' \ # HTML 以外へのリクエストを除外
  | sort | uniq -c | sort -nr | head -100 | sed -r 's/^[ \t]+//g' \ # 集計して上位 100 件だけを得る
  | tee /path/to/public/access-ranking.txt # テキストファイルに書き出し

zcat -f しているのは gzip 済みのログファイルも cat したいため。このやり方だと現存するログファイルからしか調べられないので logrotate で設定している期間(自分の場合は 30 日)の集計しかできない。またサーバーを複数並べて運用しているようなアプリケーションではアクセスログがばらけるのでこんな雑なやり方は使えない。

Nginx のログのフォーマットは LTSV にしているので grep でのフィルタリングがやりやすい。まず User-Agent で bot っぽいアクセスを除外したあと、ログから request_uri のフィールドだけを切り出し、静的ファイルなどへのアクセスを除外したあと sort -> uniq -c -> sort -nr してる。

Ruby ( Lokka ) の方では以下のようなコードを書いて access-ranking.txt を読み込んでる。これをやらないと記事のタイトル表示やリンクが生成できないため。

class Entry
  class << self
    def popular(count = 5)
      access_ranking = File.open(File.join(Lokka.root, 'public', 'access-ranking.txt'))
      slugs = {}
      access_ranking.each.with_index(1) do |line, index|
        access_count, path = *line.split(" ")
        slug = path.split("/")[-1]
        slugs[access_count] = slug
        break if index == count
      end
      all(slug: slugs.values, limit: count).sort_by {|entry| slugs.values.index(entry.slug) }
    end
  end
end

フッターは適度にキャッシュしているのでスピードはそんなに遅くならない。

感想

アクセスランキングを表示してみて、意外と Twitter やはてブでバズった記事へのアクセスは継続的には多くないことがわかる。最近だと ARC'TERYX や SIERRA DESIGNS のパーカーの記事が人気があるようだ。これはおそらく寒くなってきててそういうキーワードで検索してたどり着く人が多いのだろう。 GarageBand でのアナログレコード録音の方法は前から人気ある。はてブとかは大して付いてないが、 Yahoo! 知恵袋や 2ch の過去記事・まとめサイトからのアクセスが多いようである。謎なのが痔ろうの記事へのアクセス数の多さ。痔ろうの症状・治療方法を結構詳細に書いたので Google 先生が良記事判定してくれているのかも知れない。家の記事ははてブでバズって 2000 ブックマーク以上付いたが、それでもやっと 5 位という感じ。バズっても短期的なアクセスしか得ることができず(人の噂も 75 日!!!、!)、長期的に細々とトラフィックを集めるためには特定の属性の人にだけ響く詳細な記事を書くのがよいのかもしれない。

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

CircleCI.png

もうすぐ Ruby 2.5 が出そうだけど、このブログの Ruby のバージョンを 2.4 に上げた。

Ruby 2.4 がリリースされたあとすぐに Lokka を Ruby 2.4 に対応させようと頑張ってみたのだけど、 Ruby 2.4 に上げるためには ActiveSupport のバージョンアップが必要だった。しかし padrino-helper 0.11.4.1 が古いバージョンの ActiveSupport に依存しており、 Ruby 2.4 に対応した ActiveSupport を利用するためには padrino-helper をバージョンアップする必要があった。 padrino-helper をバージョンアップしてみると 0.12 から大幅な変更が入ったようで、ビューの表示がぐちゃぐちゃになった。 layout が適用されず中身の partial ビューだけ表示されたり、 HTML が過剰にエスケープされたり。 padrino-helper は 0.11 時代にあった脆弱性を修正して標準ですべての文字列出力を escape するようになったっぽい。しかし Lokka の方がそれに対応できておらずビューがぐちゃぐちゃになっているようだった。

Lokka はヘルパーメソッドやモデルで HTML を文字列から生成しているところがあって、そういうところをこまめに html_safe していったところ余分なエスケープは解消されていった。利用している gem でも文字列から HTML タグを生成しているところがあったので、そういうところもつぶさに調べていって無心で html_safe したり mark_safe していった。

とりあえずこのブログを Ruby 2.4.2 でしばらく運用してみて問題なかったら Lokka 本体の方に Pull Request を出すことにしよう。

あと今回ついでに CircleCI でテストしてテストが通ったら勝手に Production に deploy されるようにしておいた。 CircleCI ほんと便利。

追記 2017-12-03

Pull Request 出しておきました。

| @ブログ

このブログ( Lokka )の DB は MySQL を使っている。 MySQL のバージョンは 5.7 なので、 column encoding を utf8mb4 、 collation を utf8mb4_general_ci とかにしておけば emoji を使えるかと思ってたけど使えなかった。長らく DataMapper が 対応してないかと思ってたけどリポジトリを覗いてみたら随分前に対応されてた。どうも Lokka 側に問題があるっぽい。

Lokka の DB 接続設定は dsn を URL として記載するようになっている。 DataMapper は ActiveRecord のように Hash オブジェクトを DB 接続の引数に渡せるので、 encoding: 'UTF-8-MB4' をオプションとして渡せるようにしてやればよいっぽいが、いまの Lokka のコードでは encoding オプションを指定できないのでこれではダメっぽい。

ちょっと Lokka 側のコードをいじって encoding オプションを渡すようにしてみたところ無事 emoji が使えるようになったので lokka/lokka に Pull Request 出しておこう ⌨️

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

ブログの管理画面にファイルアップロード機能をつけてみた。 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 (この機能は自分が追加した)あたりとどういう風に折り合いを付けていくか考えないといけない。

| @ブログ

Lokka の管理画面をスマートフォン対応させた。携帯から記事を投稿したりスパムコメントを削除したいなと思うことがあっても Lokka の管理画面はモバイルフレンドリーではなくて非常に厳しかった。とても便利になったと思う。ドッグフーディング最高。

専業フロントエンダーではないのでマークアップと CSS コーディングは適当だけどこの様に寝床でごろんとしながらでも駄文を投稿できるようになって便利。 Lokka ご利用中の方はご活用ください。

ダッシュボード 記事一覧 投稿画面