mikutterの最新の情報は、mikutter blogに引っ越しました。

2012年11月18日日曜日

mikutterプラグイン管理ツールの構想

本筋とは全く関係ない話。プラグインのパッケージ管理とかやってくれるのが欲しいと思って、ちょっとだけ作りかけてみました。

現状のプラグインシステムの問題点

mikutterはサードパーティプラグインを ~/.mikutter/plugin/ の中に入れたら動くようになっています。いちいちビルドとかしなくていいので楽ですし、単純なので理解しやすい(置く→動く!)のですが、単純過ぎる故に色々と問題がありました。

  1. プラグインを探すこれといった方法がない
    現状として、プラグイン纏まった場所がないので、プラグインを探す時はgoogle先生にきくしかなく、検索すべきキーワードがわからない、特に欲しいプラグインがないという時にダラダラ見れるリストは存在しないようです。
  2. 何が入ってるかパッとわからない
    プラグインディレクトリ見れば分かりますが、ねえ。
  3. mikutterのバージョンとプラグインが想定するバージョンを気にしなければならない
    多くはREADMEとかに書いてあると思うけど、ねえ。
  4. 最新版の確認を、全てのプラグイン毎に行う必要がある
    リポジトリを直接プラグインディレクトリにチェックアウトすると楽にできるけど、それにしたってステップ数が減るだけ
で、誰もがパッケージ管理みたいなことしてくれないのかよ、って思っていたのではないでしょうか。今まで挑戦した人もイタみたいですが、皆途中で一身上の都合又は音楽性の違いにより、完成には至らなかったようです。

私も以前一度やろうとしていましたが、既存のものを使って辺にこったものを作ろうとしてしまって頓挫しました。というのも、プラグインから提供してもらえる情報というのが意外と少ないんですよね。しかし、ちょっと0.2で状況が変わって来ました。

定義ファイルの導入

mikutter 0.2からプラグインの依存関係を記述する目的で、プラグインにYAMLで記述された定義ファイルを同梱しておく機能が導入されました。
これは、依存するプラグインを記述しておき、それが先にロードされるようにすることで、コアを書き換えるプラグインの機能に依存したプラグインを書けるようにという目論見です。
ついでに、プラグインのバージョンとかも書けるようにしました。詳しくは「プラグイン移行ガイド」の7章を見てください。

いろいろ書く割にはほとんどのキーが使われていないというのが現状ですが、この情報を利用したらパッケージ管理みたいなことができるのではないかと思ってやってみました。

理想
  1. リポジトリみたいなのに登録されてるプラグインを一覧したい。
  2. インストールはできるだけ簡単に。
  3. yumとかaptみたいな感じで、バージョンアップとか依存関係とか見てうまい感じにやってほしい
  4. app storeやGoogle Playみたいに評価とか付けれるようにしたい(審査ができないため、悪意のあるコードが入ったプラグインを実行してしまうと…。)
作ってみた


0.2で使えます。設定画面に「みっくストア」というのが増えてるので、そこからプラグインをダブルクリック(todo: なぜクリックで開かない)するとプラグインの説明が出てきて…っていうのはスクショ見たら大体イメージつくと思います。


はい。変なプラグインをインストールしてしまったのでインストール済みになってしまってます。プロトタイプなので使用はおすすめしませんが、現時点で以下のような機能があります。
  • プラグインをインストールする。
    通常のプラグインディレクトリにスラッグと同じ名前のディレクトリを作ってそこに設置。git cloneしてるだけなのでgitコマンド必須です。みっくストアを用いてインストールすると、すぐにmikutterにロードされるので再起動は必要ありません。
  • すでにインストールされてるプラグインを確認
    「導入」カラムに表示されているバージョンは、インストールされているプラグインのバージョンです。バージョンがないけどインストールされてるものは○、インストールされてないものは空白。「みっくストア」を用いずにインストールしたものも検知できます。
  • 開発者の気がふれていないか確認
    プラグイン開発者の頭に不具合がないか確認できます。mikutterプラグインはなんでもできてしまうので、信頼できないものは入れるべきではありません。こう簡単だとホイホイ入れちゃいそうだけど。
これ以外は何も実装してません。バージョンアップ、アンインストール等はそのうちつくんじゃないかな。
また投げ出してしまいそうだけど、最低限のものはできてるので、いい感じにできないかなー

mikutterプラグインの管理が楽になるといいですね

2012年11月7日水曜日

#mikutter 0.2.0.1054


  • ツイートにフォーカスしてなくても会話タブを開くコマンドが使える問題
  • 意味のないトレースをエラー報告として送っていたのをやめた
あんまり何も変わっていない。二週間経ったのでバージョン上げてみた。いつかみたいに大して何もなくても毎週バージョン上げるようにしたら危機感持てて、ちょっとは開発速度上がるかなとか思って。
パッチとかももらってるし割と残してるバグもあるんだけど、最近元気がなくてなかなかコードをかけてない。mikutterの薄い本製作委員会がコミケ落選したのは関係ないです。

0.2ではプラグイン開発者が嬉しい機能とかあるのでそういうのもまとめたいと思っているんだけどコードすらかけてないし全然時間が足りない!これから寒くなったら自分の部屋でコード書くのがかなりしんどくなってくるのに。

2012年10月21日日曜日

#mikutter 0.2

9末とか言っててなんとかそれくらいにRC出してからぐだぐだしてたらもう21日じゃないですか!このまま噂されているiPad miniより遅れてせっかく作った特設ページとかまた作り直しなったら嫌だし、なんか忘れてる気がするけど、ここで区切らせてもらうぜ!
  • 機能追加・仕様変更
    • プロフィールプラグインのデザイン変更
    • 会話タブの抽出方法変更。会話のミックス等
    • 設定タブを廃止。ステータスバーに設置したボタンをクリックしたらポップアップするようになった
    • ショートカットキーにペインの移動、タブの移動等フォーカス関連のコマンドを追加
    • 隠し機能、mikutterコンソール機能を正式機能として採用。起動中のmikutterの中でRubyのインタプリタっぽいものが使える
    • 隠し機能、マルチペインを正式機能として採用。タブの右クリックやショートカットキーで、特定のタブを新しいペインに移動することができる
  • 内部変更
    • UIを一から書きなおした。自由度が上がって若干パフォーマンスも上がった。
    • コマンドロールを刷新。
    • UI DSLを採用。Gtkオブジェクトをイベントで渡す方法はオワコンになった。
    • プラグインメタ情報ファイルのサポート。
    • 収録されているすべての画像、音声のライセンスを「クリエイティブ・コモンズ 表示 - 継承 3.0 非移植」に変更
  • バグ追加
    • 新しいアイコンが可愛すぎる問題
    • and you
RC2の内容と全く同じです。RC2を使っていた人はバージョンアップする必要はありません。

今回はいくつかUIに細かい変更を加えています。長い時間をかけてUIをできるだけ変更しない方法を模索していたけれど、やむを得ず変更を入れました。
大幅な内部変更のおかげでフォーカス処理などがプラグインからできるようになりました。単純なものはmikutterの標準で実装しています。詳しいことは使ってみればわかるんじゃないかな(http://mikutter.hachune.net/)
細かいバグがいくつか残っています。安定したmikutterが使いたい人*1は、アップデートを待ってもいいんじゃないでしょうか。

*1: アアアッwww

プラグイン開発者の方は、内部APIの一部に互換性が無いのでご自分のプラグインを確認してください。とりあえず動くようにするには、 mikutter 0.2 プラグイン移行ガイド を参照してください。ナウい♂プラグインマニュアルは今書いてます、多分次の薄い本にもそれが載ると思います。

2012年10月15日月曜日

#mikutter 0.2.0.1051 RC2


  • 不具合
    • アカウントのトークンが取得できない問題
    • 一部環境で起動できない問題
  • 仕様変更
    • リストでフォローしているアカウントがされたリツイートを取得しないように変更した。今後は(そういったプラグインを入れない限り)フォロイーのリツイートしか表示されない。
ちょっと遅くなりましたがRC2です。基本的にこれで大丈夫だったら0.2の最初の版ということにしようと思っています。
他にも判明している不具合はありますが、使用に支障をきたすほどのものではないので、これらができていないからといってリリースを延期する予定はありません。ただ、それまでに修正できたものについてはアップデートに含めます。
現在判明している不具合は以下のとおりです。他にも何かあれば報告お願いします。

2012年10月5日金曜日

#mikutter 0.2.0.1045 RC1

一定以上の優先度のタスクが全て終わりったので、mikutter 0.2 のRC版を公開します。一週間程様子を見て、大きな不具合がなければ、このまま押し切ります。
何かあれば教えてください。ダウンロードページの一番下からダウンロードできます。

主な変更点 http://mikutter.blogspot.jp/2012/09/mikutter-02_18.html

開発者用変更点 http://mikutter.blogspot.jp/2012/09/mikutter-02.html

残作業等 http://dev.mikutter.hachune.net/projects/mikutter/issues?fixed_version_id=5&set_filter=1&status_id=o

2012年9月18日火曜日

mikutter 0.2 開発版のテスト開始


若干日数がたってしまいましたが()、mikutter 0.2をtrunkにマージしたので、trunkを使っている人たちは、updateするともうmikutter 0.2がつかえるようになると思います。


で、これを以てバグ報告の受付を開始します。まだできてないこともあるけれど、数が減ってきたのである程度つかえるレベルになってきたと思います。さあ今こそかつての人柱魂を呼び起こす時だ!


A____A
|・ㅅ・|
|っ c|
| か |
| た |
| じ |   
| け |
| な |
| い |
| ! |
|   |
U ̄ ̄U


リリーススケジュール

Redmineのトラッカーが「機能」か「致命的」になっているものが全て完了した時点でRC1を公開(tarball)、致命的な不具合があれば修正して、数日サイクルでRCをリリースしていき、一週間大きな問題が見つからなければ0.2をリリースです。9/30あたりになればいいんだけどな。

新機能

ちょいちょい言ってますがざっとおさらい。

UI関連の内部APIの大幅変更

前回のエントリで説明したとおりです。人によっては、拾ってきて入れてるプラグインが対応して無くて起動できなくなると言ったこともあるでしょう。

マルチペイン

マルチペインに正式対応しました。二つ以上タブがあるペインのタブを右クリックすると、「新規ペインを作成」というコマンドが出てきます。これで新しいペインが一番左にできて、そのタブがそこに移動します。
今までの怪しい隙間にD&Dで増えるというのはないです。
ペインの構造が大幅に変わったので、0.1系のペイン情報は失われています。

設定

設定タブを廃止しました。ステータスバーの右にあるネギレンチアイコンをクリックすると、設定ウィンドウがポップアップします。設定はいままでどおり、触ったら即反映されます。決定ボタンなどはないので、設定が終わったらWMの機能を使って設定ウィンドウを閉じてください。

プロフィールプラグイン

プロフィールプラグインを書き直しています。レイアウトが大幅に変わったことと、ふぁぼ・ふぁぼられ数が見れるようになったことが変更点です。

フォーカス操作系のコマンド

左右のタブに移動する等、キーボード操作をしやすくするmikutterコマンドを大量に追加しました。ちょっとショートカットキーの割り当て画面考えないとそろそろきつくなってきましたね。

この世の全てをそこに置いてきた

いろんなプラグインにどさくさに紛れて隠し機能を追加しました。あと、いい忘れてる機能もありそうです。

バグ報告

クラッシュしたらレポートを送ってやってください。だけどバックトレースをコピペしてRedmineで適切に報告してくれたら、より早く対応できます。
バグ報告はRedmineでお願いします。Twitter上で報告されてもチケット化が追いつかないし、そもそもバグの報告から修正完了までの流れを扱うのに不向きです。また、流れが早いため他の人との情報の共有がうまく行きません。一応リプライで言われても聞きますが、基本的にTL上にいる時は休憩中なので、その場で聞いてるだけですぐに忘れる、ということがしばしばあります。人間だもの。
もちろん、質問はTwitterで結構です。でもアカウントを持ってる人には最終的なチケットの作成はお願いすると思います。

mikutterのRedmineアカウントを持っていない人で、報告するのに登録してやってもいいという方は、登録フォームから登録してください。ただしアクティベートは手動で行うので、登録したらリプとかで知らせてください。

チケット作成の流れはこちらの文書を参照してください。Redmineで残作業を確認するにはこちらから。コンソールのように、実装してあるのにまだチケットが残っているものは、現在作業中ということです。


今週は結構できるとおもうんだけどなーほんとに今月中にリリースとかできるんかな

2012年9月16日日曜日

mikutter 0.2 プラグイン移行ガイド

1 はじめに
まだバグは致命的なもの含めていくつか残ってますが、テストしてもらえる品質になったと判断したので、mikutter 0.2 を mikutter の trunk にマージしました。 今回のアップデートで、0.1 系と互換性が失われた部分がいくつかあり、プラグインを開発している人にはお手数ですが自分のプラグインに手を入れてもらわなけばいけなくなりました。

それもこれもクーラーが壊れたのが悪いんです。で、みなさんのプラグインをどうやって移行していけばいいかを簡単に説明します。 今回は、あくまで0.1用のプラグインが「動く」ようになることを主眼に説明します。 つまり、すべてをモダンな形式に書きなおす訳ではなく、互換性のあるところはできるだけ触らないようにして、 最小ステップで動くようにする方法を紹介します。 したがって、0.2対応のプラグインを書くためのドキュメントとしてはあまり使えません。

2 ざっくり
0.2 の目玉の変更はGUI関連に大幅に手が入ったことです。 これにより、複雑なGUIをもったプラグインが動作しない場合があります。 また、mikutterコマンドも変わったので、 もしあなたの作成したプラグインにmikutterコマンドを提供しているものがあるなら、 基本的には必ず書き替えなければならないと考えてください。

3 タブ
今までは、Gtkオブジェクトを作成して、 mui_tab_regist イベントでそれをGUIに渡して、適切な場所に配置されていました。 これからはGtkは基本的には使いません。全てはUI DSLを介して操作し、それをツールキットプラグインが表示する というスタイルをとっています。こうすることで、mikutterをGtk以外で操作する方法を提供する余地を持たせたい、 という目論見があります。 とはいうものの、UI DSLはmikutterプラグインのほとんどのニーズを満たすために最適化されているため、複雑な インターフェイスを定義することには向いていません。望むなら nativewidget メソッドを使ってタブの中に Gtkオブジェクトを直接埋め込めますし、 mui_tab_regist も非推奨ですが残されています (そして、いくつかのmikutterプラグインは未だにこの古い方法でタブを構築しています)。 ぶっちゃけて言えば mui_tab_regist はそのまま使える。Gtk::TimeLineもそのままでいい。 (Gtk::TimeLineは昨日あたりまでバグで動作してませんでしたが、今はもう大丈夫です)

あとどうでもいいんですけど、registっていう英単語はないんですってね。なんであると思い込んでたんだろう。 多分みんな使ってるから、調べもせずに日常的に使うようになってしまったんでしょうけど、 イベント名なので単純に変えられないし。早くこんな黒歴史イベント消し去りたいです。 このイベントを使わずにもっとクールに書く方法はあるんですが、今回の範囲外なのでカット。

4 設定
設定はポップアップウィンドウになりましたが、プラグインからsettings DSLを 使って設定を挿入することに変わりはありません。 これについても、内部のAPIは完全に互換性があります。

5 廃止されたイベント
内部でしかほとんど使っていなかったような、Gtk関係のフィルタを削除しました。残念ながら、見た目はほとんど 変わっていませんが、mikutterのUIの構造は大幅に変わっているので、安直に代替できるものはほとんどの場合ありません。 Gtkウィジェットのツリー構造を直接操作するようなプラグインも(多分見たことないけど)動かなくなります。

6 mikutter コマンド
おそらく一番多くの人にとって問題になるのはmikutterコマンドです。これは今回どうしても変更せざるを得ませんでした。

6.1 command メソッド
従来はmikutterコマンドを追加するためにはフィルタを用いていましたが、これからは command メソッドを使用します。 まずは従来の書き方をおさらいしてみましょう。
# in 0.1.x
on_command do |menu|
  menu[:reply] = {
    :slug = :reply,
    :name => '返信',
    :condition => lambda{ |ms| ms.map(&:message).all? &:repliable? },
    :exec => lambda{ |ms| ms.first.timeline.reply(ms.first.message, :subreplies => ms.map(&:message)) },
    :visible => true,
    :role => :message
  }
  [menu]
end
このモデルにはさまざまな問題があって、まずフィルタで受け取ったHashに、スラッグをキーにしてHashを入れる必要がありますが、 中に入れるハッシュの中にもスラッグを書いておかなければいけません。2つが違うと不具合が起こるので、 あまり好ましいAPIではありませんでした。 更に、フィルタなので、最後に引数を配列で返す必要があります。だいたいはスニペットで書いてしまうのでこれが問題になることは少ないですが、 ミスをする原因にしかなりません。 0.2では以上の点を改善しています。
# in 0.2
  command(:reply,
          name: '返信',
          condition: Plugin::Command[:CanReplyAll],
          visible: true,
          role: :timeline) do |opt|
    opt.widget.create_reply_postbox(opt.messages.first.message,
                                    subreplies: opt.messages.map(&:message)) end    
commandメソッドが追加されました。
command(slug, options, &proc)
slug にスラッグを設定して、 options は従来渡していたHashと同じ物を渡します。ポイントは、slugを指定する必要が なくなったことです。 slug に設定されている値が流用されます。 更に、 :exec キー(コマンドの実行内容)も不要になり、 &proc を使うようになりました。これも slug のように中で Hashが加工されているとお考えください。というかそうなってます。

6.2 condition
condition キーに、従来は無名関数を渡していましたが、例では Plugin::Command[:CanReplyAll] という値が 設定されています。 これは単純に、よくある条件を定数にまとめたもので、あえて使う必要はありません。 すべての定数は mikutterの「core/plugin/command/conditions.rb」にまとめられています。 実は引数に渡される構造体にも若干の変化があるのですが、それは次の実行部分の話にまとめます。

6.3 ロール
どのウィジェット上でコマンドを実行するかを指定する部分で、条件や実行時に渡ってくる引数が変わります。 ただ、今まであった :message:message_select のような、 直接存在しないウィジェットに紐づいていないロールは 廃止されています 。 0.2でも使用できるロールは、実際のウィジェットとして存在するもの、すなわち :timeline, :postbox です。 また、ウィジェット全てにロールが割り当てられたので、今までにはなかった :tab, :pane, :window, :profiletab, :profile が新たに使えるようになりました。移植するのに新しいロールを使うことはない と思うのでここでは割愛します。

6.4 条件及び実行時の引数
いままでは、ロールによって渡される引数が違いましたが、 これからはどのロールでも同じ構造体が渡されるようになりました。
Plugin::GUI::Event = Struct.new(:event, :widget, :messages)
event には、mikutterコマンドがどのような入力によって実行されたかがシンボルで入っています。 基本的には :contextmenu (右クリックメニューから選択された)か :keypress (ショートカットキー)です (mikutter 0.2 からはmikutterコマンドを呼ぶデバイス等も拡張できます。だから :gamepad とか :kinect とかが入ってくる可能性があります)。 widget は、イベントが発生したウィジェットです。ロールが :timeline なら、必ずPlugin::GUI::Timeline のインスタンスが入ります。 最後の :messageswidget のアクティブな子ウィジェットを再帰的に探索し、タイムラインがあれば、 そのタイムラインでイベント発生時にアクティブだった Message の配列が渡されます。 これは Plugin::GUI::Timeline#selected_messages の戻り値ですが、 選択されているツイートに対して実行されるコマンドには必ずこの配列の内容を使ってください。 イベント発生時と実行時には微妙なタイムラグがある可能性があり、コマンドを実行した時に選択していたツイートと、 実際に実行された時に選択しているツイートが違う可能性があるからです。

6.5 具体例等
mikutterの core/plugin/command/command.rb に、たいがいのコマンドが定義されているので参考になると思います。 フィーリングでコピったらいけるでしょう。

7 定義ファイル
プラグインによっては、正しく書いているのにNoMethodErrorなどでクラッシュすることがあります。 理由はたいがい、guiプラグイン等がプラグインDSLにあとからメソッドを足しているケースがあり、これらの プラグインよりそのプラグインが先にロードされていることが原因なんじゃないでしょうか。 0.2からはどのプラグインに依存しているかといった情報を書く定義ファイルが追加されたので、 依存するプラグインがあればそれを書いておくべきです。そうすれば、依存しているプラグインを先にロードしますし、 依存するプラグインが一つでも存在しなければ、ロードされません。

7.1 定義ファイルの書式
spec という名前のファイルを作成して、中にYAMLで記述します。 例えばダイレクトメッセージプラグインはこんなかんじです。
name: Direct Message
slug: directmessage
description:
  mikutterにリア充御用達機能ダイレクトメッセージを追加します。
  送受信したすべてのDMを見るタブと、各ユーザのプロフィールにそのユーザと自分がやり取りしたDMを表示するタブを追加します。
depends:
  mikutter: "0.2"
  plugin:
    - gui
    - gtk
version:
  "1.1"
author: toshi_a
  • name プラグインの通称です。日本語でもいいです。現在は使われませんが、インストールしてるプラグイン一覧みたいなのをそのうち作ってみたいですね。
  • slug プラグインのスラッグ。依存関係の解決に使われます。
  • description プラグインの簡単な説明。
  • depends/mikutter 想定するmikutterのバージョン。ここに書いてあるバージョンと現在のmikutterのバージョンに 互換性がなければプラグインがロードされません。
  • depends/plugin 依存するプラグインのスラッグ。今のところ、GUIがないと意味がないようなプラグインは gui を、 Gtkクラスを少しでも使っている場合は gtk を指定してください。DirectMessage は両方指定しています。 一つしかない場合も配列で指定してください。
  • version プラグイン自体のバージョン。今のところ特に用途はありません。
  • author プラグインの開発者のTwitterアカウントのscreen_name。これも今のところ特に用途はない。
8 まとめ
今回は当初の設計では想定していなかったことをいくつか実現するために、内部を大幅に書き換えたので、いくつか プラグインの互換性がなくなってしまいました。mikutterは今まで、必ず過去のプラグインも動くようにしていたので、 今回手を入れたGUIまわりは、最初の設計が誤っていたと言わざるを得ないでしょう。 

難しく言えば、クライアントに新たなユーザエクスペリエンスを提供するためにはアーキテクチャにイノベーションを起こすことが必要でした。 その代償としてコンパチビリティを失うソリューションしかトゥギャザーできなかったのは残念ですが、逆に言えば、 長いスパンで見ればプラグインデベロッパの開発コストを大幅に減らすオポチュニティと捉え、 プラグインDSLを拡張することによって新たなmikutterのコアコンピタンスを創出することができたので、 私とみなさんにとってWin-Winの変更になったと思う次第です。

mikutterのプラグインは本当にいろんなことができます。だから場合によってはここにある内容だけでは 移植することができないかもしれません。あと、なんか書き忘れてる気もします。 だから何かあれば適当に聞いてくれたらいいと思います。適当に答えますんで。