鍋の底

雑多な記録

Thinkpad X220 と thinkfan

こんなことで引っかかったのは僕だけなんだろうが、記録しておく。

はじめに

いつの頃からか Debian sid の thinkfan をアップデートすると、エラーでインストールが完了しなくなった。
パッケージのバグならそのうち直るだろうと思っていたのだけど、どうやら直らなそうなので、重い腰を上げて対処することにした。

続きを読む

CSSでの表見出しの均等割付 (css3版)

NSEG Advent Calendar 2015 - Adventarにエントリを書きたいと思っていたら、ネタが降ってきたので急いで書きました。

というわけで12/23のエントリになります。

さて、ワープロなどにある均等割付を、Web でも表現したいという需要があります。

f:id:nabetaro:20151223212054p:plain

このとき css では text-align に justify を指定すると思います。 この文章のように複数行ある場合には、効いているように見えますが、 table の見出しセルを均等割付をしたい場合には、うまくいきません。

f:id:nabetaro:20151223214321p:plain

Webでしらべても「text-align justify 効かない」がサジェストに現れるくらいには、効かないもののようです。

なぜこうなるのか、文章に対する均等割付から考えてみましょう。 均等割付の際には、段落の最後で、均等に割り付けてしまうと、むしろおかしくなります。 そのためか、段落の最後では均等割付となりません。

f:id:nabetaro:20151223213656p:plain

tableの見出しセル(ここではth)が均等割付にならないのは、段落の最後と認識されてしまっているからだと思われます。

では、方法はないのでしょうか。

CSS3 では、text-align-last https://drafts.csswg.org/css-text-3/#propdef-text-align-last というプロパティが追加されており、これを利用すると、段落の最後に対する指定ができます。ブラウザが対応していれば、均等割付できそうです。

簡単に確認したところ、Firefoxではベンダープレフィックスが必要、Chromeではそのまま指定できそうです。 その他のブラウザは、後日時間のあるときに。

td {
  width: 200px;
}

th {
  width: 100px;
  -moz-text-align-last: justify;
  text-align-last: justify;
}

ひとまず、このスタイルで、以下のような表示にできました。

f:id:nabetaro:20151223220044p:plain

OmniAuthで独自認証機構を作る

OmniAuthのプラグイン

TwitterFacebookの認証を利用するのに、OmniAuth というライブラリがあります。 Webで検索してもすぐに情報が出てくるので、メジャーなのでしょう。

この OmniAuth の特徴の一つは、プラグイン形式により様々な認証機構に対応できることでしょう。 このプラグインを Strategy といいます。

List of Strategies · intridea/omniauth Wiki · GitHub には対応するStrategyが列挙され、さまざまな認証機構に対応していることがわかります。 また、Strategy Contribution Guide · intridea/omniauth Wiki · GitHub に沿って Strategy の開発もできます。 なので、既存の Strategy がなければ、どんなマイナーな認証機構でも自分で作ってしまえばいいのです。

このStrategyですが、Strategy Contribution Guide · intridea/omniauth Wiki · GitHubを見ればわかるとはいえ、日本語の情報は見つかりませんでした。 なので、備忘録を兼ねて書き出しておくことにします。

Strategyの基本構造

さて、Strategyの基本構造としては次の形となります。(hogeという認証機構向け)

modulerequire "omniauth"
OmniAuth
  module Strategies
    class Hoge
      include OmniAuth::Strategy

      # 定義部
      args [:hoge]
      option :fuga
      option :moge, "Moge"

      # リクエストフェーズ
      def request_phase
        ……
      end

      # コールバックフェーズ
      uid do
        # ユーザIDを返す
      end
      info do
        # 認証情報をハッシュで返す
      end
      credentials do
        # 認証情報をハッシュで返す
      end
      extra do
        # 認証情報をハッシュで返す
      end

    end
  end
end

ここから以下のことがわかります。

  • OmniAuth::Strategyをincludeした OmniAuth::Strategies::Hoge クラスを実装する。
  • 定義部、リクエストフェーズ、コールバックフェーズがある。

定義部

各appで利用する際のパラメータを、ここで定義します。 例えば、Railsで利用する際には以下のようになります。

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :hoge, "hogege", :fuga=> "Fuga-"
end

必須のパラメータは、args で引数として定義し、必須ではないパラメータは、option で定義するといいでしょう。 どちらもコード内では options.hogeのようにアクセスできます。

リクエストフェーズ

通常 /auth/hoge というURLで受け取る、認証の出発点となります。 OAuthのように、別のURLにリダイレクトしたり、ユーザIDとパスワードを入力するフォームを表示して入力を促したりできます。

このURLに渡されたリクエストパラメータは、session経由でコールバックフェーズで読み出せます。 env["omniauth.params"]にアクセスしてください。

コールバックフェーズ

Auth Hash Schema · intridea/omniauth Wiki · GitHub に定義されている、Auth Hash を定義するフェーズです。ここに認証プロバイダから受け取った認証情報やユーザの詳細情報が含まれています。このAuth Hashは、env['omniauth.auth']から読み出せます。

userとinfoは必ず定義してください。env['omniauth.auth'].user や env['omniauth.auth'].info で内容にアクセスできます。

コールバックURLは、appで定義してください。

最後に

List of Strategies · intridea/omniauth Wiki · GitHub には、たくさんのStrategyがあるのですが、OAuthのものが多く、POSTやHTTPヘッダで渡ってくるタイプのものが見つけられませんでした。 そこで、自分で実装することにしたのですが、定義の列挙のような形で実現できました。

認証はOmniAuthにやってもらい、認可についてはapp内でするという住み分けにもなるかと思います。

rails3とfast_gettextとgettext_i18n_rails

gettextのpoファイルを使用した国際化について、最近のrailsでの日本語の記事が見つけられなかったので、試しにやってみました。 *1

ベースになるアプリケーションは何でもよかったので、 http://railstutorial.jp/chapters/a-demo-app.html#top のデモアプリケーションを利用します。

今回はrails3系の最新(?)の3.2.14でやってみます。

チュートリアルのデモアプリを作成

ほぼチュートリアル通りに実行します。 異なったのは rails new の際にバージョンを指定したことぐらいです。 指定せずにrails4でやっても良かったかもしれません。

fast_gettext と gettext_i18n_rails のインストール

ここから、fast_gettextとそのrails I/F の gettext_i18n_rails を適用していきます。

その前に、ここで今回の適用方針を決めておきます。 といってもなるべくシンプルにしたいので、以下のような感じにします。

  • 翻訳はpoファイルのみで行う。moファイルは使用しない。
  • 翻訳のDB管理は今回対象外。
  • haml/slimファイルの翻訳は今回考えない。

https://github.com/grosser/gettext_i18n_rails によると、pluginとしてのインストールとgemとしてのインストールがあるようです。 ここではgemとしてインストールすることにします。

gemとしてインストールするにはGemfileに次の行を追加します。

gem 'gettext_i18n_rails'

bundle install すると、gettext_i18n_rails と fast_gettext がインストールされます。

アプリケーションへの組み込み

rails-i18n の成果の利用

gettext_i18n_railsrails標準(?)のi18nと、排他になるのではなく、共存できるようです。 https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale/ の翻訳ファイルには、翻訳済みのエラーメッセージや曜日などが収められていて、これを利用したほうがよいでしょう。

i18nで使用するように、config/locales に ja.ymlを格納します。

fast_gettextの初期化

config/initializers/fast_gettext.rb を作成して、以下を追加します。

FastGettext.add_text_domain 'app', :path => 'locale', :type => :po
FastGettext.default_available_locales = ['en','ja']
FastGettext.default_text_domain = 'app'

上記:pathで指定したディレクトリを作成しておいてください

mkdir locale

アプリケーションへの組み込み

app/controllers/application_controller.rb の ApplicationController クラス宣言の中に次の行を追加してください。

before_filter :set_gettext_locale

翻訳準備

翻訳したい文字列リテラル 'foobar' を _('foobar') のように囲みます。 囲み終わったら、以下のrakeターゲットを実行してください。

$ rake gettext:find

これで、locale/app.pot が生成されます。 ファイル名は、環境変数TEXTDOMAINの値、FastGettext.default_text_domainの値の順に参照されます*2

potファイルから、各言語のpoファイルを作成するには、GNU gettext で配布されている msginit を用いて、次のようにします。作成先は locale/言語コード としてください。

$ msginit -i locale/app.pot -o locale/ja/app.po

または、次のように単純にコピーしてから、内容を編集しても構いません。

$ cp locale/app.pot locale/ja/app.po

エラーメッセージや、画面表示などは、モデルから文字列を取得しています。 モデルの属性を翻訳できるようにしたほうが都合がいいと思います。 次のrakeターゲットでモデルの文字列を locale/model_attributes.rb に抽出しておきます。

$ rake gettext:store_model_attributes

翻訳

GNU gettext のpoファイルの編集と同じように翻訳できますし、共通のツールを利用できます。

特に locale/model_attributes.rb 由来なのですが、msgidが「User|Email」のようになっているものがあります。 「|」で名前空間の表しますので、msgstrには「電子メール」のように訳してください。「User|」を訳出する必要はありません。

適用

アプリを起動し、翻訳が反映されていることを確認できました。 ここで一つ疑問が。localeを明示していないのに、なぜ反映されているのでしょうか?

実はapp/controllers/application_controller.rbに指定した、set_gettext_locale メソッドに理由がありました。

set_gettext_locale メソッドのソースを見ると、次の順番にlocaleを評価して決定します。

  1. リクエストパラメータのlocale
  2. セッション内のlocale
  3. cookie内のlocale
  4. HTTP_ACCEPT_LANGUAGE
  5. I18n.default_locale

このため、特に指定せずともブラウザの表示言語からlocaleを決定していました。 一度決定してしまうと、cookieに記憶したセッションに記録されてしまうため、リクエストパラメータにlocaleを指定したり、cookieを削除したりしないと、言語の変更ができないことになります。

実際に、言語切り替えのロジックを実装する際には、このあたりに留意したほうがいいでしょうね。

まとめと課題

今回は、ここまでにしましたが、いくつか課題があります。

  • 実行時にpoファイルをパースしていると思うのだけど、遅くないかな?
  • pluralizeはどう処理するべきでしょうね。
  • viewのhtml部分の文字列はどうしましょう? (haml/slimファイルの翻訳で扱うのか?)

次はviewについて調べてみます。

*1:あとから http://d.hatena.ne.jp/next49/20101016/p1 を見つけました

*2:自分の環境では、TEXTDOMAINが別途定義されていて、思ったファイル名にならなかったりしました。unsetすればOK

Linux と HOLUX m-241 を Bluetooth でつないで使う

GPS ロガーの HOLUX m-241 を久しぶりに取り出してみたところ、 先代のマシンで接続設定をしていただけだったので、設定をやり直すことになりました。

いい機会なので、手順をまとめておきます。

方針

  • m-241Bluetooth でペアリングします。
  • Bluetooth の RFCOMM デバイスとして見えるように設定します。
  • mtkbabel で RFCOMM デバイスと通信し、gpx ファイルを取り出します。

Bluetoothのシリアルデバイス接続の手順としても、参考になるかもしれません。

念の為に書いておくと、m-241Bluetooth でつなぐと、余計に電池を喰います。 シビアな場合は、USBでつないだほうがいいかもしれません。

続きを読む