特殊なタイムライン

現在のmikutterのUIは、以下のような構成です。

img

ウィンドウが一つ有り、その中にユーザは任意の個数のペインを作ります。 ペインの中には1つ以上のタブがあり、タブの中身はプラグイン次第です が、基本的にはタイムラインが入っているはずです。

このセクションでは、特殊な抽出条件を持ったタイムラインを作成します。 タイムラインを用いたあらゆるプラグインに応用できる知識です。

コード

# -*- coding: utf-8 -*-
# mikutterについてフォロイーが言及したら、しばらくTLに入れる

Plugin.create :gossip_detector do

  EXPIRE = 300                  # 5 min

  gossip_users = {}

  tab :gossip_detector, 'Gossip Detector' do
    set_icon MUI::Skin.get("timeline.png")
    timeline :gossip_detector
  end

  # ツイートの受信、振り分け
  onupdate do |service, messages|
    timeline(:gossip_detector) << message.select { |m|
      if m.to_s =~ /mikutter|みくった/
        gossip_users[m.user] = Time.now + EXPIRE
        true
      else
        gossip_users.has_key?(m.user) and gossip_users[m.user] > m[:created]
      end
    }
  end

end

解説

このプラグインは、タイムラインをひとつ作って、フォロイーが mikutter に ついて何か言及したら、そのツイートをそのタイムラインにも表示します。 これだけだと、現在 mikutter に標準で入っている extract plugin と同じで すが、このプラグインはその人のツイートを、マッチしたツイートから5分間 の間は、無条件にタイムラインに入れます。

最初に mikutter の名前を出して、あとでツイートを小分けにして mikutter について言及しているかもしれないからです。そんなことないかもしれませんが、こんな変なフィルタも書けるんだよというデモなので勘弁して下さい。

イベントの待受

ユーザやTwitterから何かしらの入力があれば、mikutter内ではイベントが発生します。 ほとんどのプラグインは、このイベントを受け取って何かを実行することで、目的を達成します。 Plugin.create のブロック内に、以下のように書けば、イベント event が発生したときに 処理 が実行されます。その際、引数は params にセットされます。

onevent do |params|
  # 処理
end

onevent は、 on_event と書いても event を待ち受けます。イベント名が長いなど、つなげて書くと読みづらい場合は、間にアンダーバーを入れるパターンを使ってもいいかもしれません。 引数は、イベントによって異なります。 mikutter プラグインの開発にとってイベントはとても重要なものですが、数が多いので、このあと出てくるぶんについても逐一解説はしません。 各イベントについて知りたい場合は、付録のEvents and Filters を参照してください。 ただし、これがmikutterのすべてのイベントを網羅しているわけではありません。 プラグインが新しい種類のイベントを定義することができるからです。

タブとタイムライン

UIの定義を見てみましょう。このプラグインは、一つのタブを追加して、そのなかに一つのタイムラインがあるという、最も標準的なUIを持っています。 タブを作成するには、tabメソッドを使います。

tab :gossip_detector, "Gossip Detector"

第一引数はタブを区別するための一意な名前、第二引数はタイトル、具体的にはタブにフォーカスを合わせた時に出てくるチップヘルプのテキストを指定します。これだけでタブは表示されます。次にタイムラインを用意しましょう。上のコードにブロックを与え、少しばかりコードをかいてやります。

tab :gossip_detector, 'Gossip Detector' do
  set_icon MUI::Skin.get("timeline.png")
  timeline :gossip_detector
end

タイムラインを作成しているのは三行目です。引数はタイムラインを識別するための一意な名前です。例ではタブと衝突していますが、タブとタイムラインのように、種類が違うウィジェットの名前がかぶっても問題ありません。 二行目のset_iconは、タブのアイコンを設定しています。画像ファイルへのパスか、Web上のURLを使用することもできます。

  1. タイムラインにツイートを追加する

    作成したタイムラインを表示することは出来ました。次に、ツイートを タイムラインに追加する方法です。これは簡単です。

    timeline(:gossip_detector) << Message
    

    timelineメソッドに先ほど作成した時と同じ名前を指定してやれば、タイムラインのインターフェイスオブジェクトが取得できます。 それに«演算子で、Messageかその配列を渡せばそのツイートをタイムラインに追加できます。

    Messageについては、結構複雑なので後述します。今回の例では、 Message#user を使って、ツイートしたユーザを取得しているのと、 Message#[] の :created (投稿日時)を取得しています。

    この情報を元に、mikutterの言及があれば今後5分間だけツイートを抽出 するフィルタを実現できるわけです。 少し実装を変えれば、他のツイッタークライアントではできないような 複雑なフィルタを比較的簡単に実装することができるでしょう。

まとめ

イベントと、タイムラインの作り方について学びました。 イベントは、onXXXで定義し、mikutterやプラグインが発生させたイベントをトリガーに起動します。 tabはタブの作成、timelineはタイムライン作成のメソッドです。 既に作成したタブやタイムラインと同じ名前を指定すると、既に存在するオブジェクトが取得できます。