blogに引っ越しました。rev.6220.0.4URL開けない問題のパッチ当てるの忘れてたてへぺろ0.1アイコンのキャッシュの持ち方の変更中mikutterお誕生日おめでとうございます!!!なんかうちの時計めっちゃ進んでるみたいなので書き終わったらntpd起動しますね。簡単にデーモンが落ちると困りますよほんとクリスマスなのでなんかと思ったんですが、先週も特に何も出来なかったので、1日くらいで出来そうなアイコンをロードするあたりの大掃除してました。初期の頃からあったアイコン表示の部分がグロいことになってたのでリファクタリングしましょうというのと、一部ファイルシステムでは高速化も期待できますし、ついでにそのへんの細かい設定、プラグインによるキャッシュの制御もできるようにする予定です。こんなどうでもいいことを長々と紹介する理由がわかるな?それ以外に言うことがないあと、0.0.4はアップデートしたほうがいいですが、0.1は久しぶりにこれがスナップショットだという事を思い起こさせてくれる仕上がりとなっております(まだ途中だけどもう寝るのでここで切った)。関係ないけど、mikutterをテーマにした薄い本をどこかで頒布するらしく、いい機会なのでプラグインマニュアルをその本に載せるという体で書いて、Webにも公開しようと思ってます。別に今週何もコミットしてないことの言い訳ではありません。ドキュメントのせいじゃないです。iPhoneで某名作が発売されるというトラブルがあったのが原因です。ドキュメントのせいじゃないです。来週の日曜日はmikutterにとっては記念すべき日ですね。12月25日...mikutterが書き始められた日です。今ではmikutterも広く認知されてきて、街ではmikutter二周年を祝って家とかにLEDを巻きつけたり木を置いたりしてお祝いムード一色です。一部環境で、設定画面のタブがいくつか欠落する問題とまあfixだけです。rev.6030.0.4特定の条件を満たしたツイートを受信した時にクラッシュ同じ短縮URLのキャッシュが使われない場合があった0.1画像に対するリンクをポップアップで表示するようになった複数のPostBoxが存在している場合、いずれかを削除できるようになった空になっていることも削除の条件になりますツイート失敗してから削除できるようにつけた機能です。通常は気にする必要はないです起動ロジックの書き直し--profileオプションの追加コマンドラインモード、デーモンモードを一度的に非サポートにしました。優先度低めで実装しますプラグインにコアライブラリの読み込みを明示的に書く必要が無くなった具体的には、miquireをプラグインに書く必要がなくなりました。書かなければ動かないという事があれば、バグですわーいコミット600超えたー0.1では大規模なリファクタリングばかりしていて、機能追加が全然ですね。いうのも、0.1でしたいと思ってることはあんまりなくて、掃除を主にやっていきたいなとおもってるんですよね。追加したい機能で今のところ一番でかいのは、抽出タブの機能・UIを強化改善して、フレンドTLなどを取り払うというのが一番大きいでしょうか。TweetDeckのように、自由にタブを作る感じです。タイムラインにフィルタとかをつけることができるようになります。あとはTLごとのイベント・フィルタですね。具体的には、タブごとに通知設定できます。これ実はすごいことだと思いますよ。mikutterでこれを実装するということは、スレッドに対して通知が設定できるってことですからね。Skypeのチャットルームみたいに使えそうです。いえ具体的にやりたいことをチケット化していないので、ちゃんとこのあたりもやらないといけないのだけど。関係ないけどクリスマスにバージョン1.0は厳しそうです。いや、今の進捗的な意味でもそうかもしれないけれど、年末デスマーチフラグが建設されており...。OSで動作させた場合にも、URLをブラウザで開けるようにした0.1.0適切にリンクが貼られないツイートがあったただのバグ修正です。深い意味はありません。release2011年11月16日水曜日ActivityについてTwitterがActivity機能の提供を開始したようで。これは、フォロイーのふぁぼ、リツイート、フォロー、公開リストの作成と追加を知ることができる。APIは公開されてないし、それどころか一時的に機能停止したりといろいろと微妙な第一印象だけど、APIが公開されたらmikutterはどんなふうにサポートしていけるか、また何を追加すべきかを考えてみた。ふぁぼ現在、UserStreamを使えば自分のツイートのふぁぼられ、自分がふぁぼったツイートが取得できる。これに加えて、フォロイーのふぁぼりが取得できる。mikutterでは、favstarのように各ツイートが誰にふぁぼられたかを表示する機能があるので、他人のふぁぼりも自然に表示することができる。いうよりは、UserStreamが発表されてからずっと、他人のふぁぼもわかるように成る時が来ると踏んでいて、こういうUIにしていた。今で約一年経ったが、APIが公開されればついに時が来るわけだ。言えば、自分に関係のないふぁぼは、TL上でageない、そもそも描画しないといった設定を作るべきだろう。リツイート現状でも、フォロワーのリツイートは見えるので、これがどのように表示されるかはご存知の通り。ここにさらに、フォロイーがリツイートされたツイートも入ってくる。ここでも自分に関係のないものは表示しないようにするという選択肢があるといい。具体的に言うと、他人のツイートがフォローしていない人にリツイートされた場合は、自分に関係ないといえるはず。自分がフォローされたことは、UserStreamでわかる。libnotifyによる通知にしか対応していない。フォロワーはフォロワータブで確認できる。リスト実は今のmikutterはList関連のイベントはだいたい無視してる。これは、取得した所で適切に表示する方法を持っていないからだ。mikutterには今のところ、他人のリストを表示する方法はない。アクティビティタイムラインということは、今のmikutterがアクティビティに対応するために致命的にかけているのは、せいぜいイベントをタイムライン表示することができないということだけだ。これがあれば、他の全ての機能はアクティビティ機能によって自然に強化されるだろう。単純に情報の流量が増えるので、今まで問題のなかった環境でも、パフォーマンスの問題が出るかもしれない。そのためにアクティビティ機能は選択的に無効にすることができるようにするわけだけど、あったら全部使いたいよね。まとめ今からでも、システムメッセージのタイムラインなんかは作れるし、公開され次第すぐにでも対応したいところ。rev.5800.0.3投稿中にしいたけを押せるようになった。投稿キャンセルができるように。思うじゃん?まだちゃんと動いてないんだなこれが0.0.4なし0.1Pluginモジュールをクラスに変更。PluginTagを廃止してPluginに統合。1.8向けのコードを一部削除。多バイト文字の処理の違いを吸収するコードを削除したので、若干効率が良くなったはずですうーん最近スランプ気味な気がする。コードを書く手が動かない。ミクに惚れた時以来だ。サーバのrdocのバージョン上げて、テンプレートをdarkfishにしました。RDocがとても見やすくなってます。これでもう少し便利になったかなhttp://mikutter.hachune.net/rdoc/index.htmlActivity解禁おめでとうございます。mikutterは、ご存知の通り、他人のふぁぼも違和感なく表示することができます。release2011年11月7日月曜日プラグインが提供する設定項目とUIプラグインを作っていると、設定を保存したいことが出てきます。ただの数字一つを保存するために、いちいちファイルに保存するのは非常にアレです。設定値の保存と読み込みそんなときは、UserConfigを使いましょう。以下のように使えば、mikutterの設定ファイルに設定を書き込めます。1また、読み込みはこう書きます。1これは、全てのプラグインで共通なので、設定のキーの名前は、「プラグイン名_キー名」とするのが暗黙のルールみたいになってます。上の例の場合conftestプラグインですね。手軽ですが、これをプラグイン間通信のために使わないでください。数少ない例外としては、表示の設定なんかは、設定用のプラグインが保存して、レンダリングするプラグインがその設定値を読みますが、そのあたりの裁量は空気を読みましょう。ベターな方法は、プラグインフィルタを使う方法ですが、まだ記事を書いてなかったので近いうちに書きます。ユーザに設定させるユーザに設定してもらいたい項目が出てくることがあります。そんなとき、設定タブにプラグインの設定が追加できたら便利ですね。mikutterでは、後から入れたプラグインが設定画面を新しく作ることができるようになっています。以下は「表示設定」の設定画面を表示するプラグインです。先にいっておきますが、これが0.0.4ではちょっとマシになりました。ナウいやりかたは後述します。なんかまーやりたいことはわからないでもないけど、ちょっと大きいですね。あとRubyらしくないと思う人も居ると思います。中に、設定項目を書くことができるようになりました。この方法のメリットは、ラベルと設定値と、最低限のUIの指定(候補から選択、キーボードで入力、ON/OFF等)だけになっているRubyGtkを使わないので、実装が変わっても、RubyGTKを知らなくても簡単に書けるとかがあります。settings内で使えるメソッドの一覧は、core/addon/settings/builder.rbで定義されています。rdocあると思ったんだけど、プラグインなのでrdoc生成してません。コメント読んでください。基本的には、第一引数がラベル名で、第二引数がUserConfigのキーです。ユーザが変更したら直ちに値がセットされます。余談ですが、こういう適当にかいてることを、Wikiにまとめようと昨日あたりから動き出しました。丁寧な説明がまとめられるかもしれません。稀にクリックしても開けないURLがあった0.1次回バージョンを0.1としました先週、風邪でリリース出来なかったので、今やっちゃいます。trunkのバージョンを0.1にしました。それに伴い0.0.4のbranchを作成して、不安定版としてリリースします。0.0.4は、Ruby1.8では警告が出て普通には起動できません。実用に耐えるほどのレスポンスが担保できないためです。0.1では、Ruby1.9の機能を積極的に使って行きます。Errorとかで起動しないと思います、多分。してもRuby1.8で使いたい人は、0.0.3を使ってください。ubuntuならはやく11.10にうpgらですればいいと思いますの。0.0.3は、よほど深刻なバグがない限りコミットしません。何かあれば開発者に教えてください。Ruby1.9.3おめでとうございます。mikutterも、Ruby1.9.3を積極的に使っていきたいと考えています。動作報告もあるので、暇な人はアップグレードしたら面白いかも知れません。0.0.4.5560.0.3TwitterのツイートのエスケープとEntityのindicesのずれを解消するために、indicesを見ないようにしたユーザのプロフィールページを開くときのURLを修正0.0.4Twitpicの画像が常に開けないイベントにかかるフィルタの処理効率の改善だめだこれは!全く間に合わねぇ!(残バグ数21件)そろそろ0.0.3のバージョンをクローズすることも検討するレベルですね。0.0.4のコミットをやめるとかしないと終わりそうにない雰囲気になってる。過去のバージョンのmikutterではtwitpicのWebページの変更の影響を受けて画像のプレビューが効きません。検証が間に合わなくて0.0.3への取り込みは間に合いませんでした。ある時間に処理を実行したい場合がありますよね。いう時のために、Reserverがあります。これは0.0.4.525から使えます。}と、指定した時間につぶやくようなことは簡単にできるようになります。他にもTimeを渡せば、その時間が来れば実行されます。Reserverを利用すると、いつかのよるほープラグインの例は、以下のようにかきかえられます。つぶやく機能が無いのであまりこの比較は意味がないですが、いちいち自分でタイミングを合わせる必要がありません。プラグインを書いていると、特定の時間に処理がしたい場合が出てくると思いますが、これを使えば面倒を見てもらえるので便利です。mikutterが終了してしまうとこの情報は消えてしまうので、実行されません。一年後の時間とかを設定してもまぁ無意味でしょう。今の実装では、実際にブロックが実行されるたびに新しくThreadを立ち上げます。これからはコアでも積極的に使っていこうと思っていて、periodイベントなんかもこれを利用するようになる予定です。いうか、periodイベントは精度も悪いし毎分実行しかできないし終わコン...?駆け込みAPI話はそれるけどコアでの有効利用の例。APIは1時間に350回まで使うことができます。APIにアクセスするたびに1づつ減っていって、0になるとアクセスできません。最初に叩いてから60分で残数が350にリセットされます。mikutterではフォローとかリストとか、とにかくいろんなものを取ってきますが、これがなかなかAPIを食ってしまう※。今後も増える予定だし(ふぁぼったツイート、ブロックしたユーザ一覧等)、APIはなかなか貴重なんです。mikutterで一番RestAPI使うのはin_reply_to_statusの参照なんだけどさということで、Reserverを使って、APIが回復する1分前にイベント「before_exit_api_section」を発生させるようにしてみました。プラグインはそれを受け取って、待ってましたといわんばかりにAPIを使うわけです。これで万が一APIが切れても、1分以内にまた350回使えるようになります。WebのURL表示方法に準拠。エスケープされた日本語のURLを案エスケープして表示するようにした。11.10前回緊急リリースをしたのは0.0.3だけでした。今回から0.0.4でもubuntu11.10で起動できます。ubuntu11.10での動かし方はREADMEをみてください。あと、ubuntuのリリース日勘違いしてました。若干目標を整理しなおし、0.0.3のメンテナンスを一週間伸ばして、10/31までとします。24日なんて中途半端な日をリミットにする意味が無くなったからです。URLの表示方法の変更について対策後。変換されてしまいます。これはTwitterサーバ上で行われていて、データが落ちてくるときには本文でそうなってしまっているのでどうしようもありません。t.coで短縮(多くの場合は長くなってるが)されています。悪いことに、「価格.com」のような文字列も、よしなに処理されてしまいます。Punycodeでエスケープされるので、「http://xn--1sqt31d.com/」とか表示されます。対策そこで、URLを表示するときにはPunycodeをアンエスケープするようにしました。entityのdisplay_url値を表示することで、http://とかも消えました。下線が引かれてリンクになってしまうことを除いては、従来通りの表示になります。副作用と今後mikutterは現在j.mpでURLを短縮するようになっています。現状display_urlを単純に使用しているので、多重短縮されたURLが展開できていません。いうものに関しては、展開できる場合はdisplay_urlは無視して展開形を表示に使用することで手を打つつもりです。話は違うけれど、今はもうあらゆるURLが短縮されるようになったので、bit.ly短縮は無効をデフォルトにするつもりです。それに合わせてクライアントサイドで字数オーバーを検出して末尾を切るような動作は廃止します。理由はRubyの標準のURL判別正規表現は、日本語を含むURLにマッチしないので面倒Twitterがきっとまたなにかやらかすに違いないからです。起動しない問題Ubuntuのリリース日をおもいっきり勘違いしていたので、焦ってやりました。11.10で起動するためには、Xの設定をいじる必要があります。いうことをいちいちしたくない人は、このバージョンを使いましょう。あと文章量が少ないのでリンクとか貼ってちょっとでも長くします。0.0.3は、ruby1.8でも起動はしますが、ruby1.9.2を推奨しています。libnotify-bin以下のようなコマンドで起動してください。mikutter.rb環境によっては、rubyコマンドがruby1.8.7を指している場合があるので。Errorになる不具合UIのアイコンが破損している時にクラッシュしないようにした0.0.4環境の要件を変更した以下に示すバージョンより古ければ今後起動することはできません。APIを使用しています。次回のバージョンで、設定で無効にすることができるようになる予定です。StreamingAPIをSSLを用いて接続するようになったイベントキューの消化速度を変更できるようにした(今までは1.0)基本設定から変更できます。デフォルトでは全て0.1秒です。11.10が10月24日にリリースされるようです(追記:13でした。11.04では、Ruby1.9.2とRubyGtk1.0.0(Ruby1.9向け)がパッケージされています。今までUbuntuのRubyGTKのバージョンは非常に古く、ライブラリのバグで頻繁にクラッシュしているというのはご存知の通りです。11.10からは新しいバージョンのライブラリが入るので、簡単に高速かつ安定した環境でmikutterを使えるようになると思います。beta2では何故か起動しないらしいので、24日までには何とかします。0.0.3のメンテナンスを10/23で打ち切り、新しいubuntuで0.0.4系のmikutterを使ってもらえるようにしたいと考えています。Ruby1.8のサポートについて現在、mikutterはRuby1.8で安定させることは不可能と考えており、これ以上サポートする予定もありません。上もそう言っているので、0.0.4.533からは、風評被害対策も兼ね、充分実用できるバージョンでしか起動しないようにしました。オプションをつけて起動する(非推奨)0.0.3系統を使うの、いずれかの対策を取ってください。0.0.4系では、今後積極的にRuby1.8で動作しない不具合を修正することはしませんが、パッチは受け付けます(Ruby1.9からの機能を使ってしまっている部分など)。0.0.5からは、積極的にRuby1.9の新機能を使うので、そのようなパッチはrejectします。APIをSSLで接続するようにしたおひさしぶり!今回は遂にSEGVを回避することが出来ました。前にプラグインを定義する方法を書いたんだけど、なかなか見た目が酷いものだったのでなんとかしようと思って、最近はもうちょっと情況が良くなってる。最近話題になってないDirectMessageのプラグインは、新しい書き方が使われてる。今までは、Plugin.createで作ったプラグインオブジェクトにadd_eventメソッドとかで新しいイベントを定義してました。このせいで、mikutterのプラグインはかっこ悪いことになってました。新しい形式では、Plugin.createがブロックを取れるようになっていて、プラグインオブジェクトのスコープでinstance_evalするようになりました。endend当社比よくなった、これは人類にとっては小さな(ryなにがよくなったかまとめるといちいちPluginを変数に入れなくていいPlugin.createがブロックを取るようになったので、外のスコープを汚さないための無名モジュールが消えたイベントを定義するところが簡潔になったとかかな。なっているかというと、このコミットがされた時のdiffを見れば一目瞭然なんですけど、onかon_で始まるメソッドが呼ばれたら、その後ろをイベント名として、イベントを登録するようになってます。on_が別に扱われてる理由は、long_name_eventみたいな名前のイベントを呼ぶとき、onlong_name_eventよりon_long_name_eventと書けたほうがバランスがいいからです。同様に、filter_?でイベントフィルタ、hook_?でフックを登録できるようになっています。やってること自体はRubyでは別に何ら特殊なことでもないし、こういう感じのもよく見かけますよね。これは、0.0.4から使えます。万が一こうやって書かれたプラグインを0.0.3にインストールすると、何も起こりません。APIが不安定なときに、大量にツイートなどの新着通知が発生してしまう場合がある0.0.4.514DMの削除とりあえず右クリックだけDM本文の自動改行するようにしたこの修正のせいで、たまにDMの画面がチカチカしたり表示されなかったりする不具合がありますDMをやりとりしたユーザ一覧を、最後にやりとりした日時がより最近のものから順番に表示するだいたいDM関連終わりましたね。あとはアイコン付けて色つけて。これを細かく作り込もうとは思ってません(ロードマップにあるぶんはやるよ)。DMが扱えるようにしているだけなので、ね。パッチとかは大歓迎です。まーまだやってる途中なのであれだが。あと次回のリリースはお休みします。お仕事忙しそうなので。その次はできるんじゃないかな。なる俺、どうなるmikutter!ヾ(@⌒ー⌒@)ノヾ(@⌒ー⌒@)ノヾ(@⌒ー⌒@)ノところで、最近コミッタを増やしてもいいんじゃないかなと思ってます。俺よりRuby得意|プログラミングの才能ある奴(あほっぽい言い方だ)がコミットしたら品質あがるのでは単純に人数が複数人いたら開発速度あがるのではパッチよく送ってくれる人はそもそもコミットすればよいのではという思惑があるのですが、ユニットテストが壊滅してるからせめて通るようにしてからにすべきではとしぁさんの動きが鈍いのではそんな暇人いないのではバク報告ツールで上がってきた統計情報を共有する手段がないという問題もあります。こちらがある程度動けないとコミット権限上げるとかもできないので、考えてるだけなんだけどね。落ち着いたらなにかアクション起こす。0.0.4.505追加ダイレクトメッセージの対応開始まだできてないDM権限のないトークンの場合、認証画面を再度表示して認証させる修正はじめてmikutterを起動するとき、ウィンドウが出ず、認証できないDMを一応使えるようにする試みをやってる最中。1.8.7で、接続タイムアウト時に稀にクラッシュしていたbit.lyのurlを展開するとき、稀にクラッシュしていたURL展開の高速化0.0.40.0.3のバグ修正をマージopenimgFlickrに対応Instagramに対応t.cot.co展開プラグインを取り込んだ今回は画像展開関連のことしかやってません。1.8は、安定した気がするけれどそもそもRubyGtkがこけまくるので体感安定性は変わってません。画像プレビューは、近いうちに一気に増やします。release版0.0.4.460をリリースしました。短縮URLを再帰的に展開する機能をつけた。TwitterがTwitpicなどの外部画像アップロードサービスのURLを勝手に短縮しても開けるようになった。0.0.4.460追加lockerzの画像プレビューに対応mikutterのプラグインを全て削除してbot機能のみを抽出するスクリプトの試作品を追加。8/15からTwitterが20字以上のURLを自動的にt.coで短縮するようになったので、mikutterなりに対策を講じました。release2011年8月13日土曜日Twitterの短縮URLかねてからアナウンスがあったように、Twitterが勝手にURLを短縮するようになりました。いえ、どんなURLでも短縮するわけではなくて、短縮されるには条件があります。URLが20文字以上せやな。URL短くしたいもんな。思っていたんですが、いざ始まってみるとbit.lyが更にt.coで短縮されるという糞仕様になってるではありませんか!これですよ?http://bit.ly/90tFUhいちにーさん・・・丁度20文字ある!残念ながらbit.lyはTwitter的には長すぎるので終わコンといいたいのでしょうかね。mikutterの対応というわけでbit.lyは切る...と思うじゃん?実はbitlyは、j.mpという更に短いドメインをもっていて、こっちなら20文字を超えません。http://j.mp/jRbcmi17文字!まだ我々には2桁残っている!やったね!というわけで、bit.lyの設定をいじって、mikutterで短縮すれば、j.mpで短縮がかかるように設定変更しました。今までの全てのmikutterで、bitlyでURL短縮をするとj.mpドメインが使われるようになります。この変更のためにお使いのmikutterのバージョンを上げる必要はないです。気づいてなくてヽ('ω')ノ三ヽ('ω')ノもうしわけねぇもうしわけねぇmikutterがt.coに切り替えづらい理由トリムとはいえ、わざわざbitlyに短縮してもらってから投稿してるのでは確実に時間がかかるので、今となっては無駄です。Twitterがやってくれるなら素直にOFFにすればいい話かと思ったんですが、そう単純な話ではないんですね。現在mikutterは、140字を超えたら自動的に超過分をトリムします。この動作が問題で、Twitter側で短縮されるならばこちらで送る前に字数が予測できません。いやまあt.coで短縮される文字数は決まってるんだけど普遍的なものじゃないでしょうというわけで、超過している場合でもとりあえず投稿してしまって、長いって弾かれたら戻ってくるようにするのがよさそうです。bit.lyのアカウントを設定できるbitlyのメリットあまり知られていないんだけど、bitlyには統計を取る機能があります。bitlyに自分でアカウントを登録して、そのアカウント情報をmikutterに設定すると、今後はそのbitlyアカウントでURLが短縮されるようになります。bitlyのサイトにログインすると、過去に自分が短縮したURLと、そのURLがどれくらいクリックされたかがわかります。あるWebページに自分がつぶやいたことで何アクセスされたかがわかるわけです。他にも登録ユーザ向けのいろんな機能が使えるので、t.coよりも高機能だと言えるんじゃないかな。twitterがt.coを推す理由の一つに、こういった統計情報を自分が知りたいというのがあるんじゃないでしょうか。t.co展開の対応mikutterはt.coの展開にとっくに対応しています。tco.rbなんて無いんですけれど。エンティティに対応したときに、あの中にt.coの展開後URLが入ってきていたので、それを利用して勝手に展開するようにしてみたんです。実はt.coの展開のほうがmikutterにとっては負荷が少なくていいんですよ。他のクライアントと比べてもかなり上手くやってる方じゃないかなぁ。ところで余談ですが、エンティティに対応したタイミングでTwitter画像アップロード機能にも対応してしまったので、pic.twitter.comのプレビュー?それ対応してるわー2ヶ月前に対応してるわーって感じです。どちらもエンティティを使ってるため、検索でひかかった奴では展開やプレビューができません。まとめbit.lyが糞仕様により殺されたのでj.mpで短縮するようにしました。設定の「ふぁぼられたつぶやきをTL上でageる」が効かない不具合ツイートのin_replyto_status取得中にツイートがTL上から削除されるとクラッシュする不具合バージョン番号のについて今回からバージョンの4桁目が、ウィークリーリリース番号からリビジョンになりました。この関係でバージョン番号が0.0.3.14から0.0.3.456に飛びました。0.0.3.456は、最新不安定版としてリリースします。不安定版について以前までは0.0.3.0が最新の不安定版で、バグも修正されませんでした。これからはバグ修正に限って、不安定版のバージョンアップが行われるようになります。今後は以下の2本のラインで開発を進めます。今週のバージョンは0.0.4.456です。Subversionのリポジトリについて不安定版用のbranch「svn://toshia.dip.jp/mikutter/branches/0.0.3」を用意しました。trunkは0.0.4です。どっちを使えばええんや不安定版のバグ修正ができるように今回の変更をしました。準人柱な人は0.0.3(不安定版)の最新を使ってもらって、人柱な人はSnapshot(0.0.4)やtrunkを使いましょう。非ASCII文字ハッシュタグのはなしなんか今更感のある日本語ハッシュタグが導入されましたねー(厳密には日本語以外もいけるようになったんだけど、このエントリは日本語なのでまぁ)。ここんところフォーラムも何も見てないのでそういう情報入ってきてないので、事前情報があったかもしれないけど寝て起きたらできてたかんじでした。わからんことがあったリンク条件どういう時に日本語ハッシュタグになるのかよくわかってない人が多いですね。これは公式ブログ書いてあるけどつまり最初にスペースorツイートの先頭#か#で始まる日本語とか(記号は不可)スペースか句読点で終わるを満たしていないと、そもそも一文字もハッシュタグとして認識されないというあれ。Twitterクライアントは、24時間以内にアップデートをかけて日本語ハッシュタグに対応してしまった。これはいいことですよね。上に述べたような、長音が含まれてるとハッシュタグとして認識されないというのはどういう扱いになっているんだろう。怪しい挙動だけど、仕様という解釈もできなくはなかった。そもそも最初からハッシュタグに以下のような正規表現を使ってるせいで#.+?\sそもそも日本語だろうと何だろうと全部リンクしてしまうあれなTwitterクライアントも結構ある。同じツイートなのにハッシュタグとして認識される範囲がツイッタークライアントによってまちまちであるというコーナーケースがいくつか存在してるわけですね。mikutterの対応みくったーユーザ「あ、ありのまま今起こったことを話すぜ...。mikutterを立ち上げたら、バージョンも上げていないのに、既にハッシュタグに対応していたんだ、自分でも何を言っているのかry」こんな風に勝手に対応してしまった理由は、俺が事前に情報をつかんでたわけではなく、Twitterにエンティティ情報を元にリンクを張っているからです。Webと全く同じ位置にリンクを貼ることができる。この情報を使っているツイッタークライアントは、Twitterが日本語ハッシュタグのリンク位置を送ってくるようになった瞬間から対応ができてしまっていたということになるわけですね。何かしらのバージョンアップをするということは、そういうことになりますよね。思いつく理由はこんな所かな出来たのが最近なので、対応していないTwitterが言うことなので、信用ならないいろいろと面倒くさい1は既に自前でやっててちゃんとできてるしいいじゃんという話。3は、なんか<>はエンティティエンコードされて送られてきてるのに&はされてなかった気がするんだけどあれナンダヨとか、実は微妙にバグってたりするんじゃねーのとか、まあそのあたり。mikutterには愚かにもこれを信用していて、Twitterが日本語ハッシュタグ対応した時点で、そのルールに合ったものについてはエンティティがくっついてくるようになったので、普通に日本語ハッシュタグがつかえるようになったというわけ。先に述べたような、全角長音記号が含まれているとハッシュタグとして認識されない不具合などまでそのまま反映してしまう(Twitterが治したタイミングで治ったが)。0.0.3.12変更なし修正voterのアイコンにチップヘルプでscreen_nameが出ていなかった。クリックでユーザのプロフィールが表示されていなかったフォロー・フォロワー一覧で、ホイールスクロールができない/statuses/updateを叩くときに、include_entities=1をつけて、自分のつぶやきにエンティティを付けさせるようにしたエスケープされた文字列を適切にカウントしてインデックスを補正するようにしているところですつぶやきがTLから消えた瞬間にリツイートされた場合にクラッシュすることがあるやったねバグが増減したよ!!!前回までのバージョンでは、自分のツイートに対して日本語ハッシュタグが正常に反映されない問題がありました(ほかのひとにはちゃんとみえてる)。このバージョンからは自分の投稿にも日本語ハッシュタグが正常にリンクされます。release2011年7月11日月曜日mikutterにDeferred入れたらどうなるのっとmikutterには実行予約の機能がいろいろある。RubyのThreadもある意味そうだけど、Delayerなんかもそう。0)みたいなもので、用途もウィジェットの更新とかなので被ってる。fail})いやーすばらしい。これはパクらない手はないdeferredは、連続した処理をぼちぼち順番にやっていって、エラーの捕捉もしやすい。http通信のメソッドとかがDeferredオブジェクトを返せば同じようにつかえて便利だなぁ。現在のmikutterでは例えばTwitterAPIを叩くのはPost#call_apiというメソッドを使う。こいつはAPI名とブロックを引数に取って、新しくスレッドを作ってリクエストを発行して、そのスレッドを返す。あとでリクエストが完了したらコールバックを呼ぶ。いう、JavaScriptのXMLHttpRequestだっけ、あれみたいな挙動をしている。スレッドを返す理由は、途中でThread#killを使ってキャンセルできるようにという深遠な理由がある。Deferredを使うとどうなるまず、今回の実験では、Deferredableをincludeした全てのクラスがdeferredみたいに振舞うことにした。これで、以下のオブジェクトが等しくDeferredのように振る舞える。DelayerSerialThreadThreadDeferredのブロックが返す値は、次のnext{}ブロックの引数になるけれど、それがDeferredのインスタンスだったら、それの実行を待ってから次のブロックが呼ばれる。Deferredをネストできる。fail}おなじこと。something}こういう感じで、複数のDeferredableの終了を待てる。今までだったらDelayerとThread両方が終わったら...なんてコードはよう書かなかったんだけど、Deferredableならできますよどうですか!Enumerableにeach_deferとか作っておけば、イベントで大量のつぶやきを受け取ったとき、時々休みながら実行ということができる。ループが長引いたら一旦処理を中断するというあれ。いいんじゃないかなとまあ適当なことを書き散らしたけれど、まあ利点は本家とたいして変わらない。DeferredableをincludeすればどんなオブジェクトでもDeferredになれるので、いろんなクラスのエラー処理をとてもスマートに書ける可能性がありますね。これはコミットせずに様子を見てる。プラグインが書きやすくなるだろうか。自分のツイートの削除時に稀にクラッシュするおおバグ直してるのにチケット数は減らねえぞどうなってやがru!(既知の)バグが全部なくならないと0.0.4ないでとはいえ。0.0.3.9最近働きっぱなしで、会社にきのこが生えてしまったよ...もういやだ...。ユーティリティmikutterでプラグインを作ると、時間がかかる処理をしたくなることが稀によくあるので、そんな時に便利そうなmikutter内部で使えるクラスなどをまとめました。現在のRubyでは、複数のThreadによる並列処理をしても、単一のプロセッサで複数のThreadが時系列で切り替わるだけなので、本当の意味で並列処理されるわけではないし、処理が速くなるわけじゃあない。俺は頭が弱いので、並列処理なんてしたら基本的にぽぽぽぽーんしてしまう残念な頭をしているので、極力使わないようにしています。!!!触らぬ神に祟なし!!!ということですね。積極的に使う数少ない例外ケースは、ネットワーク通信。サーバの応答待ちの間、シングルスレッドなら他の処理をブロックしてしまうけれど、他のスレッドでネットワーク通信をすればブロックされることはないと。mikutter内ではメインスレッドでしかGtk関連の操作をしてはいけないことになっています。通信などという役割になっています。APIを叩くためのメソッドは、メインスレッドで呼ばれるとクラッシュするようになっています。Gtk関連の一部メソッドも、メインスレッド以外で呼び出すとクラッシュするようになっています。並列・遅延処理のためのメソッドいろいろそんなmikutterのための並列処理などのためのお役立ちメソッド|クラスたち。Delayerコンストラクタに渡したブロックをあとで実行する。あとでというのは、そのうちヒマな時にやるということで、そんなに即時性が重要じゃない処理に使う。something}ブロックは登録された順番に呼ばれる。メインスレッドで呼ばれる。SerialThreadThreadとほとんど同じだけど、別々のSerialThread同士は順番に実行され、同時に実行されることはない。Delayerだとメインスレッドをブロックしてしまい、UI操作に支障をきたす可能性がある処理につかう。一つのThreadを使いまわすので、Threadが増えない。something}lazyRubyでHaskellみたいな遅延評価をするためのもの。ブロックを渡して使う。戻り値は、ブロックの実行結果なんだけど、ちょっとブロックの実行するタイミングが違う。lazy遅延評価オブジェクトを返す。このオブジェクトにたいしてメソッドが呼ばれたときに、1度だけブロックを実行する。b上の例だと、39の階乗が出力されるけれど、実際に計算されるのは表示されるとき。156の階乗も一見計算しているようだけど(a)、使われていないので計算されない。everytimelazyと殆ど同じだけど、メソッドが呼ばれるたびに毎回ブロックを実行する。parallellazyは最初に必要になったときだけど、parallelはすぐに別のスレッドでブロックを1度だけ実行する。実際に値が必要になったときに、まだ実行が終わっていない場合は、ブロックの実行終了まで待つ。atomicグローバルなMonitorのインスタンスのロックを取得してからブロックを処理する。ひとつしかMutexがなければデッドロックなんてないんや原理主義者のために用意されている。something}イベントが処理されるスレッドmikutterのイベント(PluginやPluginTag)は、必ずメインスレッドから呼ばれます。時間のかかりそうな処理はしないほうがいいです。イベントフィルタは、Plugin.filteringを呼んだ時に直ちに実行されるので、どのスレッドから呼ばれるかは不定です。フィルタは特にマルチスレッド処理に注意!ということです。まとめmikutterで処理のタイミングをずらすためのユーティリティをまとめました。スレッドの扱い方の暗黙のルールを明文化しました。0.0.3.8今回からWeeklyリリース(snapshot)を、mikutterのサイトのDownloadからDevelopの項目に移しました。使う人が、文章を読まずに単純な数値比較でWeeklyリリース版をダウンロードしてしまう事故を避けるためです。その他のバージョンは、今までどおりDownloadからダウンロードできます。通知関連のイベントの追加。これによって、以下のプラグインが追加されました。一部APIのキャッシュ機能ショートカットキーの編集でクラッシュする不具合いやー、0.0.3.9が0.0.4にならないかなーとか思ってたがなかなかそうもいきませんねぇヾ(@⌒ー⌒@)ノ0.0.2のようにバグを潰す為に.12くらいまで行ってしまうのだろうか。このバージョン番号についても0.0.4以降ちょっと変わるんだけど通知プラグインを小分けにしたおかげで、特定のプラットフォームでは音とかが鳴らなくなったと思います。Growlで通知出すこれらのプラグインの要領で、手軽に通知やサウンド関連を拡張できるようになりました。ニッチな環境でmikutterを使っている人はチェックだ!折角高速化できたところなので、このタイミングでぜひとも安定させていきたいところですね!!!当分はバグをとり続けることになるかなー。APIで短縮URLの展開形が取得できた場合、それを利用する修正タイムライン上のリンク文字のリンクの位置のずれメモリリークをちょっとマシにしたTwitterが画像アップロードサービスを自分で始めちゃいましたね。entityにそれがくっついてくるとのことで、急遽エンティティを読むようにした。それから、どうもentityはOAuth通さないとくっついてこないようで、今のmikutterの実装だとUserStream、home_timeline、mentions経由で取ったものでないとentityがない、つまり公式画像サービスを使ってアップされた画像が展開できないと。ブラウザで開けるんだけどね。日曜日になったから上げてみたものの、メモリ削ってる途中なので、相当重くなってますね。0.4.0のうち、使用しているファイルを添付その他不具合修正いやdisってないですって!!!すべてぼくのミスです!!!^p^1.8で使ってる人、多いんだなぁって驚きました。ubuntuと謳っているのでそりゃあそうか。1.8で使う日と1.9の日を交互とかでやるか。ユニットテストで追い切れない部分は使わないとどうしようもないしね。ここからは特に目立った機能追加はせずにバグを取って、0.0.4を目指そうと思います。UIをつかえることになりますね。release2011年5月27日金曜日mikutterコマンドプラグイン開発のおはなし。プラグインは、結構簡単に自分のタブをつくることができるようになってる。その方法は既存のcore/addon/friend_timeline.rbとかを見ればすべてわかるので省略するけれど、これだけじゃあプラグインには不十分なことがある。指定された特定のつぶやきに対して動作するものは、タイムライン上でつぶやきを右クリックしてメニューで選べると良い(コンテキストメニュー)。プロフィール表示はただのプラグインだけど、コンテキストメニューに「〇〇のプロフィール」という項目が出てくる。これは、今まで「コンテキストメニューフィルタ」というのを使ってて、イベントフィルタで右クリックメニューをガシガシ追加できるというものだった。0.0.3.5からはキーコンフィグで右クリックメニューで出てくるものにキーを割り当てることができるようになったので、ユーザは前より柔軟にカスタマイズができるようになった。そんなふうに、コンテキストメニューやショートカットキーにプラグインが追加できる機能、mikutterコマンドを新しく追加しました。}これは会話スレッドプラグインの、登録している箇所。(core/addon/smartthread.rb)。だいたいこれをテンプレに使って頂けたらとおもうんだけど、menuという連想配列に入れる内容がポイント。:slug一意なコマンド名。かぶっちゃいけないので、プラグイン開発者の独創性が試される。しておけってこった:name表示名。コンテキストメニューに表示される内容。String:descriptionこの機能の説明など。:iconアイコンがあれば。今のところ使われない。Gdk::PixbufとかString(ファイル名)を指定しましょう。:condition実行条件。これの値と===で引数(後述)が比較される。1.9では、Proc#===は、Proc#callのことなので、無名関数を渡すとなんでもできる。1.8でも、utils.rbで同じ機能が実装してあるので使ってください。:exec実行される本体。:conditionと同じ引数を受け取るが、:conditionがfalseになった場合はそもそもこれは呼ばれない。:visibleコンテキストメニューに表示するかどうかのフラグ。falseなら表示されない。これは例えば、「ひとつ上のつぶやきを選択」のように、コンテキストメニューに表示する意味がないもののためにある。:roleコマンドを実行できる環境。つぶやきを右クリックすると、ここに:messageが指定されたもののうち、:conditionがtrueなものだけが実行又はコンテキストメニューに表示される。指定できるもののバリエーションは後述。:conditionの「引数」というのは、:roleに何を設定したかによって変わる。:messageつぶやきにフォーカスがあるとき。以下のような構造体が引数になる。(Gdk::MiraclePainter)):message_select:messageの時で、なおかつテキストが選択されているとき。:timelineタイムラインで右クリックされたとき。基本的に:messageと同じタイミングだけど、引数はGtk::TimeLineしか受け取らないという点がちがう。:postboxつぶやき入力欄。今のところ、ショートカットキーにしか対応していない。引数としてGtk::PostBoxを受け取る。いうふうに、わりと簡単にmikutterコマンドを新しく追加できる。プラグインに依存しない機能(リプライとか)は、core/addon/contextmenu.rbに実装してあるので、例が見たければこれをどうぞ。これで随分プラグインの幅が広がるような気がします。新UIについてこんばんわ。先程新UIをリリースしました!何がどうなったのか簡単に説明するよ。mikutterの従来のレンダリング方法いままでのmikutter。動作は察してください。今までのmikutterは、ウィジェット※1を綺麗に並べてタイムラインを実現していました。この方法だと、あらゆるウィジェットを使用することができるので、タイムラインのレンダリングがとても自由にできます。※1...ウィンドウのパーツのことしたがって、mikutterのタイムラインは他のTwitterクライアントのそれに比べてかなりリッチな部類だと思います。なかでも、アイコンオーバーボタン(アイコンにマウスカーソルを重ねるとボタンが出てくる機能)、ふぁぼられ、リツイート累積表示、リプライ宛先表示などのmikutterの代表的な機能は、この方法でタイムラインをレンダリングしたからこそ容易に達成できた、という背景がありました。何が悪いのか本来、ウィジェットは頻繁に追加削除されるものではないので(大体は作ったらそれでおしまいですよね)、ある程度タイムラインの流れが速いと、異常な速度でウィジェットの作成/削除/パッキングが行われます。配置の自由度が高いぶん、こういった変化があったときの再描画のコストは馬鹿になりません。Ubuntuの最新版に入っているRubyGTKはとても古く(nattyには0.19.3が入っているが、最新は0.90.8)、大量のバグが含まれているのが現状です。Faultしてmikutterが巻き添えになることがしばしばありました。他のTwitterクライアントのレンダリング夜フクロウ。Linuxじゃない、Rubyじゃない、Gtkじゃない。リストビューっぽいですね。mikutterは他のTwitterクライアントと比較して、レンダリングが飛び抜けて遅いですね。説明は上記の通りだけど、ではどうしてそんなことをしたかというと、現在のmikutterは、とりあえず表示できるものを仮に作った段階だったのです。mikutterのUIは新たにつくり直す必要がありました。他のTwitterクライアントはどうしているかというと、リストビューを使用していると思われます。リストビューは、パーツが縦に並ぶことを前提にしているのでどうやら速いらしい。ソートオーダーなどの細かい話もGtkがやってくれるのでRubyでやるよりは早くなりそう。リストビューにすればいいじゃない、と簡単にはいかない。いうのも、この中に置けるのは、せいぜい画像と文字くらいだからで、新しいRendererを作成するにしても、今までのように好きなウィジェットを思いのままに設置するとはいきません。高速になったが見た目はそんなに変わらない。全部画像にしたらよくね!?という奇想天外なことを思いつきました。画像だったらすきにレンダリングできるけれど、キャッシュすれば速さもでるんじゃねーのと思ったわけです。リストビューは、任意のRendererを設定できるので、今回は実際にTLを描画するやつをMiraclePainterという名前にしました。TLの先まですべてミク色に染めていただきましょう!!!で、リッチな表示ができないとか言ってたけど蓋を開けたら右のようになってます。ついでだから微妙にマイナーチェンジしましたが。Faultの確率が減るかも!?と、圧倒的な進化を遂げました。CPU使用率も大幅に減ったので、いままで遅くて使えんと言っていた人もつかえるようになるんじゃないかな。そのためには、ショートカットキーなどの処理をもっときめ細かにやっていかないといけないと思っていて、例えば横のタブにフォーカスとか、リプライ後のフォーカス移動とか、そういうところに気を配らないとなぁ、と思ってます。ウィークリーリリース版に適応されています。右クリックメニューでできること全てにショートカットキーを割り当てられるようにしましたTLのレンダリング方法を革命的に変えました。設定と環境によっては過剰にAPIを消費することがある不具合とりいそぎでかいのだけ。有意なレポートがないのでこっちで再現したぶんだけ修正しています今回は静かですねーなんっでっかなー(新UIについてはまだです。それについては前回の記事を。ほとんどできているので、今週中にtrunkにマージして、1〜2回のウィークリーリリースを経て0.0.4にできたらなぁと考えています。なんか最近なんもしてないのに同じような不具合がたくさん報告されてくるのあれなんだろう。release2011年5月14日土曜日cairo版と言われてるものについてひっそりやってたんだけど思ったより拡散したので、解りづらい形式で説明します。説明に時間を食いたくないので簡単に。cairo版とは萌ゆいものとかわいいものが一緒になってやばいです具体的に何をしたの?タイムラインをリストビューにして、各セルをcairoでレンダリングしています。見た目はできるだけ今までと変わらないようにしています。別にcairoを使ったことだけが新しいわけじゃないんだけど、それに気づいたときにはみんな知ってたのでておくれました。何が良いのか高速になって、メモリ消費が少なくなって、ライブラリのバグを踏む確率が下がることを期待しています欠点はとくになし。リプライのUIが若干変わってしまうかも。これは最終的に従来の方法を実現できる可能性がある。それさえなければ欠点は特になさそうどうやって使うのかtrunkには入っていません。以下のリポジトリからチェックアウトしてください。svn://toshia.dip.jp/mikutter/branches/cairouiただし、未実装の部分が多く、クリックするとクラッシュするボタンがあったりします。なるまで待てないという早とちりな人用です。進捗を見たいここでやってます。http://dev.mikutter.hachune.net/issues/131バグ報告など上のチケットの中になければ報告欲しい...といいたいところですが、リソースをこちらに集中して開発しているので、おそらくバグ報告は行き違いになると思います。mikutter上で設定もできます。release2011年5月2日月曜日MUiなんとなくできてきた、ような...あれから紆余曲折あったけどMUiが構想からなんとなく動くものになってきた。Kitだったしねできるだけ、SXMLをそのままUIとしてレンダリングしたい!...と思っていたわけなんだけど、実際の動くコードは今こんなかんじ。world"))mui()というのは、jQueryで言うところの$()みたいなものと思っていただければ。$("<div>")とかやるじゃんこれが実際何をしているかというと、引数をMUiのGtkプラグインで定義されるオブジェクトでラップしたものを返してます。そのクラスはMUiBaseクラスのサブクラスで、MUiBaseはArrayのサブクラス。中身の値も渡された配列と全く同じになるようにコピーされます。渡された配列にいろいろextendしていく方法とこちらの方法で迷ったんだけど、extendする方法だと、freezeされた配列が渡されてきたときにエラーにせざるを得ないのと、この方法なら、同じ配列を雛形にして何度もMUiオブジェクトを作れるというメリットがある。DOMにはイベントのAPIで、AddEventListenerというのがあるので、ちょちょいと実装しました。これといって特筆することはないです、単に、第一引数にイベント名を取って、イベントが呼ばれたらブロックが実行されるだけなので。いうやつは、「windowウィジェットの子の中で要素名がbuttonのもの」という意味です。最終的にはCSSセレクタまがいなことが出来れば、と思ってる。少なくとも#.くらいは使えたほうがいいかとか。今は最初にマッチしたものを返してるだけなんだけど、jQueryって、複数返って来た時に、呼ばれたメソッドを各ウィジェット毎に繰り返し適用してるよね?あれ便利だけどどうなのかな。...というわけで実行したらこうなります\(^o^)/ポイントとしては配列でいいんだし、複雑なのは外部からYAMLで流しこめばいいでしょイベントのバインドはらくらく意外とメリットが少ない...もちろんMUiプラグインをgtk以外のものにすればいろいろ応用がきく、というのはちゃんと視野に入ってますよ。こらそこdebianとかマジレスしないミュートしたユーザが起こしたアクションに関する通知も表示しないようにしたJSONライブラリをうまくロードできていなかったSQLiteプラグインを廃止Twitter検索APIのマイナーチェンジに対応やっとお前ユーザID送ってくれるようになったんか...自分がふぁぼ・RTしたつぶやきを一番上に上げない設定を追加デフォルトで有効です。従来の動作に戻すには設定→表示から。11.04(nattyなんとか)でRubyGtkがクラッシュする不具合修正さて、死月はmikutterを一ヶ月止めるくらい忙しかったお陰で?GWはたくさん休みがあります。具体的にどれくらい休みがあるかTwitterで言ったら今フォロワー724人から命狙われてます!!!!!男はTLに出たら724人の敵がおるんやなので具体的には言いません!だけどいろいろできそうです!予定もあんまりないし^q^まあしかし...MUiの設計をある程度実装に落としこみかけて終わりそう、とも思います。-標準プラグインのsqlite.rbは、つぶやき、ユーザ、リスト、ふぁぼを恒久的に保存するためのプラグインで、SQLiteなので他の言語やプログラムでも気軽に統計などを取ったりして遊べる、一度取得したツイートをデータベースから取得するのでAPI消費が緩やかになるなどのメリットがある。最近うちのmikutterが遅くなってきてて、何があったのかなと思ってたら、このSQLiteのファイルが250MBにまで膨れ上がってた。これを消すとサクサク動くようになる。・・・では、sqliteプラグインを削除すればいいのかというとそう簡単に諦めません。従来のみくったーでは、データベースの書き込みは別スレッドで遅延実行してた。これによって並列実行され、表側には負荷がかからないと思い込んでいたのが全ての間違いで。SQLiteは結局、Rubyで実装されているわけではないので、アクセス中は他のスレッドは動かない。いうことは、結局挙動的にはメインスレッドで動いてるのと似たようなことになる。Waitになるのでその間他のスレッドが実行されるので、体感負荷はこっちのほうが小さい。これは0.0.3.0までの話。したものかといろいろ調べていたら、そういえばトランザクションの処理が荒いままだということを思い出した。SQLiteは明示的にトランザクションを張ってなければinsertやupdateの前後でトランザクションを張ってしまう。これのコストがかなり高いので、大量に書き込むときはトランザクションを貼るというのはセオリーなんだけれど、やってなかった。・・・というわけで、0.0.3.1では、SQLiteのexecuteメソッドに渡す引数を配列にして、Queueに入れて、一定時間キューに追加されなかったらそれらをまとめて一つのトランザクション内で書き込むという改良をした。結果どうだったかというと、体感速度は変わらず。起動は3秒速くなった。あとつぶやきを短時間に大量に受信したときにも負荷は落ちているはずで、一件あたり0.1秒ほど速くなっているみたいなんだけど、体感速度変化なし。結局のところ、データが多ければ処理は遅くなるはずで、俺のようにいっぱい溜め込むと読み込みですら足を引っ張ることがあると。考察mikutterが流速速いと遅すぎて使い物にならないのは周知の事実だけれども、流速が速いほうがためこまれるつぶやきの量は多くなるわけで、余計に事態が悪化していく。他のツイッタークライアントはこういった問題にどう対処しているかというと、そもそも溜め込んでいないのでこういう問題とは無縁というのがほとんど。それもそのはず、mikutterでも、ほとんどのSQLiteキャッシュは一度も使われず、ある程度昔のレコードになると全く使われない。再起動するまではmikutterコアが一定期間メモリキャッシュをするので、大抵SQLiteにまで問い合わせがいくことはなく、基本的に問い合わせはレコードが見つからずに終わることが殆ど。-このことから、現状のmikutterでは、SQLiteによる恒久的キャッシュの意味は薄いんじゃないかなと考えて、残念だけど0.0.3.2では標準プラグインからは降格させる予定。今はうちのgithubで元気にしているよ。mikutterで統計とか取って遊んでた人はこれで引き続き使えます。mikutterって、昔APIが少なかったころ、またTwitterが不安定だったころに設計されていて、できるだけTwitterにアクセスしなくていいように、Twitterを信頼しないという思想のもと書かれているところが多いんだけど、最近ではそんなにTwitterも不安定じゃないし、そういうところは一度見直したほうがいいと思ってる。Twitterも大きくなったよなぁ。APIのv3に対応1回の投稿に複数のURLが同時に記載されている場合に、全て抜け落ちる不具合bitlyよくもやりやがったなSQLiteのデータ書き込みを遅延させ、トランザクションの数を節約するようにした数秒速くなったがあまり意味はなかったちなみに、先の0.0.3.0には、上記修正は含まれていません。(r182)からの変更点。(new!)つぶやきの抽出機能。@seibe2)コミッタが増えたヾ(@⌒ー⌒@)ノなんかいろんな所に広がっててやばい風邪引いた眠いし仮眠とろうかなでも明日起きられなくなるしなウワアアアアアアアアアアアアアアアアアアアアアアア少ないよおおおおおおおおおおおおおおおイヤアアアアアアアアアアアアアアアアアアアアアwwwwwwwwwwwwwバグ修正書かなかったらほんと何もやってないみたいwうぇwたしか前のリリースが12/25とかだった気がするんだよね。Toolkitの抽象レイヤーを入れて、Gtk以外のバインディングを書く余地を与える(プラグインをGtkに依存させない)フレンドTLプラグインなどを削除して、全てextractプラグインにやらせて、どこぞのツイッタークライアントみたいなかんじにする1に絡むけどTLをCairoでレンダリングすることで高速化を図るコンテキストメニューとか、ショートカットキーとか、そういうのをカスタマイズできるようにしたいというところですね。0.0.2.13いえーい!!!ruby1.9.2に対応(notify)自分のつぶやきが公式リツイートされた時の通知に対応リプライと公式リツイートと混同されていたが、区別するようにした白い!白いよ!書くことがな^p^いちょっと間が空きすぎてエラー報告が全然目を通せる数じゃなかったので今回は普通にウィークリーリリース(苦笑)して安定してたら0.0.3いくよ。セグフォはバグじゃないよ。あと使う分には関係ないけど、今回からエラー報告プラグインが、エラー箇所を明示的に送るようになって、こっちの統計が取りやすくなりました!!!やったこれでいくら報告来ても大丈夫だ!バグ入れ放題!!!0.0.2.12リリース後から仕事しかしてなくて更新できなかった!本当に仕事しかしてなかったよポケモンもしなかったしうんこもしなかっただからここのところ腹具合がうわあああTwitterはするものじゃなくて住むものなので居ました。3/20からだからなんと一ヶ月!!!死ぬかと思った!!!んでもう終わったからリリース...と思ったら今日になって変更がきてるぞどうしてこうなったwwwwwwもうやだwwwwwwボクをTwitterで見かけたらふぁぼ以外の手段で慰めてください^q^p^q^p^q^p^q^p^q^p^なんか、gentooのパッケージに取り込まれたり色々大変なことになってるね、そのせいかユーザが増えたような気がするよよかったねみく。エイプリルフールも影響があったように見える。しようこんなものがw広がっていくwwwはぁここのところGUIが糞重いみたいなこと言われてるけどお前フォロー何百人いるんだよwww200人?そりゃだめだww俺?600wwうはwwwなんぞwwwってことになってるからちょっとそろそろ高速化しておかないとカスだと思われるし、フォロワー多い人も去年と比べると増えているのでマルチプロセス化してCairoでTLをレンダリングするという暴挙に出ようと思います。それができたら0.1です!おらに力を分けてくれえええヽ('ω')ノmuiという新しいサブプロジェクトを立ち上げました。これはGUIをDOMっぽく扱うためのGUIラッパです。S式をやりとりするだけなのでどんな言語でも使えるものになる予定で、ライブラリの層からも世界征服を企んでいますん。新しいUIについて色々考えてる考えてる途中のことを書き散らしてます。以下ただのつぶやきです。現在のmikutterは、Gtkに完全に依存している。プラグイン内でGtkライブラリを叩いていたり。guiプラグインがそういうものだったし、当たり前といえば当たり前のこと。いうか、暗中模索の中、開発速度を稼ぐために意図的にやった部分がある。最近いろんな環境で使われるようになって、様々な問題が出てきてしまった。Toolkit(Cocoa、Qt等)のバインディングを書きづらい強いGtk依存のため、RubyGtkの知識がプラグイン開発の事実上の絶対条件となり、の敷居を上げているGtkをさも悪者のように書いているように見えるかもしれないけれど、最初にQtを選んでいたらこの部分がQtになっただけの話。安定したものを使っていれば2は無かったかもね。開き直って、そこを抽象化してしまいませんか、という話。するかというと、特定のルールに従ったデータ構造(DOM)を与えると、それをUIとしてレンダリングする、というもの。domとかすると、そういうウィンドウが表示されると。ご察しのとおりHTMLをめちゃくちゃ意識してます。以下、mUi()は受け取った配列に色々Mixinとかをextendしまくって魔改造するものか、なんかでWrapして委譲するよなものだと思って読んでください。LangでS式※として取り扱えます。windowとかlabelとかいう関数が定義されたコンテキストをつくってそこでこの式を評価すると。その関数の実装次第でQtにしたりCocoaにしたりできる、よね。Langでのコードでありデータのこと。Kitを叩く計画は初期からあった。先に上げたのとの違いは、それがクラスなのか、配列なのかというところ。配列にしておくことのメリットは:DOMが簡単に保存できる。Gladeみたいなことが自然にできるRubyのコアオブジェクトを使っているので、メソッドは誰でも知ってるJSONに翻訳可能なので、別プロセスに渡せる。だいたいどんなプログラミング言語にもありそうなデータ構造を使っているため、言語の壁を越えることが出来る夢がひろがりんぐ\(^o^)/1については、UI関連のコードがソースコードと分離できるので便利だと思う。その形式はJSONとかYAMLとか、慣れ親しんだものでいける。2については、例えば要素を追加したい時に、さてこのMUIオブジェクトにはaddか、appendか、何が実装されているのかな...おお、DOM意識してappendChildだったか...。みたいな時間が節約できる。例の仮想コードの、「<<」にどん引きした人がいるかもしれないけれど、これはRubyユーザなら誰でも配列の末尾に値を追加するアレだということは知っている。+じゃだめですよ、あれは非破壊的だから。3からはちょっとぶっ飛んでて、できたらいいなみたいな。Rubyでは現在完全なマルチスレッドは出来ない。RubyのThreadクラスは、実は時系列で切り替わってるだけなので、本当に同時に複数スレッドが動くわけじゃない。Ruby2.0ではそのあたりの事情が変わるらしいけれど、今でもプロセスを分けてしまえば並列に動かすことは出来る。Chromeとかあえてそうしてるしね。プロセス間通信には、JSONが使える。S式が使いたかったんだけど、S式でHash表現するような魔改造すると、気軽に他のLispパーサでパースできなくなるので見送った。mUiで魔改造されたオブジェクトは、変更が加えられると別のプロセスにそれを報告してレンダリングさせるようにも出来るよね、ということ。Chromeって書いたけど、同じ利点と欠点をはらんでるね。GtkがクラッシュしてもコアプロセスからmUiのプロセスを再起動してやればいいだけ。4についてはその応用で、向こうのプロセスがJSONを受け取ってそれをレンダリングしてくれるならば、Rubyで書かれてようが、Pythonで書かれてようが、JavaScript(!)で書かれてようが関係ないじゃない、という話。これが出来るということは、Rubyが使えない人でも、mikutterの別のUIバインディングを作れるかもしれない、ということ。一応書いておくと、マルチプロセス化しますと言ってるわけじゃなくて、そういうこともできるね、という話。mobileあるでイベント渡す方法とかは、DOMのアレでいいんじゃないかな普通に。今の時代ならjQueryリスペクトしてもいいかも。DOMはW3Cがちゃんと規格化してた気がするから興味があったら調べてくだしあ、おれはあんなのよみたくないなんかこういうのありそうで探してるんだけど、うーん。オススメあったら俺が愚かな車輪の再発明するのを止めていただけると嬉しいけれど...。別プロジェクトでこういう事やってmikutterに取り込もうと思ってる。仕事終わったら詰めますね。-l213ピャアアアアアアアアアアアアアアアアアアアアアアアwwwwwwwwwwwwwなんだこのBOTnetはあああああああああああああwwwwwwww悪質きままりないwwwwあれwwwwきまわりないwwwwなぜか変換できないwwwwwwうぇwwwwwwwオーケー落ち着こう今日はエイプリルフールだ。冗談が何かを弁えていないアレなやつが、何を血迷ったか俺に田代砲を打ってきたんだ。HDD内をgrepすれば、どこかにここにアクセスしてくるプログラムがあるはずだ。4/1だけに使ったユーザは49人程度。いうことか!このうち、3.のユーザは、今回の騒ぎで面白そうだから入れてみた人と、知ってたけど何らかの理由で使ってなかったが、今回様子を見るためにちょっと起動してみた人。2のユーザは、3月中に使ってるわけだから、一見さんかアクティブユーザの何れか、ということになるから、まぁ100人程度のアクティブユーザは確実にいそうだ。実はsoramame_bsclにアイコン作るように去年のはじめにお願いしてて、半年放置されたからヤツの落書きを勝手にアイコンにしてただけだったんですwwwwやっとだよwwwwウェブページのファビコンにもしたよ!やったねたえちゃん!よくなかったことキャッシュがスレッドセーフじゃなかったギャアアアアアアアwwwww俺SUGEEEEEEEEEEwwwwwwww特定条件を満たすつぶやきをふぁぼると落ちるひでぇぇぇぇwwwwwwwリスト取得するときにたまに落ちてたウワアアアアアアアアアアwwwwwwwもうかくのめんどくせえよおおおおおwwwwww0.0.2.10以前を使ってる人は、ここのところ全く機能追加できてないお陰で安定性上がってるっぽいので是非バージョンアップしましょう。Faultが発生していた→rubyか周辺ライブラリのバグを踏んでいたようnotifyのリツイート通知の時に、原文が2回表示されていた最適化アイコン画像プリフェッチ殆ど何も変更できてないわけだけれど、これが0.0.3.0になるんじゃないかな、落ちないので。まあリリースして1日以内にクラッシュするような不具合が見つかるというのを10週連続でやってるんだけどね!あとレンダリング高速化しようとしてやっぱりやめました。時間をかけて大規模なのをやります今度。0.0.2.10リリースしました。ことがあるうけるヾ(@⌒ー⌒@)ノまじこれだけあと少しパフォーマンスを上げようとして、ああ、今回もだめだったよ。根本的な解決をしていきたい。mikutterのコードも当社比リファクタリングが進みきれいになったので、マルチスレッドでGtkのレンダリングをしても死なない気がしてきた!ちょっと頑張って見るかな。10:252011年3月2日水曜日streamingプラグインの最適化streamingプラグインはuserstreamを実現するためだけのプラグイン。(core/addon/streaming.rb)UserStreamは大量のデータが落ちてくることがしばしばあり、フォローが多いと秒間に数個からヘタをすると数十個のイベントが落ちてくることもあるかも知れない。(ここでつぶやきではなくイベントと言ってるのは、フォロー関係の変更やDM、favなども落ちてくるので)mikutterでは、正確にはわからないが、まあフォローが1000を超えていたら絶対に動かないだろう。これは、流速が処理速度を超えるから。いう極端に速い環境を切り捨てるのは仕方ないにせよ、全員が定期的に呟いている訳でもないので毎週火曜夜に流速が極端に速くなるということもあるかもしれない。できるだけ対策をしてみようと思った。これの33行目くらいから変な魔術を使ってる。endevent_favoriteメソッドがfavられた時に呼ばれる。こいつが実際のイベントをよんでいるんだけど、いちいちdefine_eventを使って定義している。このdefine_eventで定義されるevent_favoriteは、Queueに引数をそのまま積んでおしまい。実際には、定義されたと同時に作られた別のスレッドがイベントの処理をする。これによって、イベント発行にだらだらと時間を使ったりせず、効率的にイベントを発行できるというわけ。・・・ではなくて、見ていただければわかるとおり、1つキューを消化するごとにsleep(1)を実行しています。同時に100favされたとすると、普通の実装だと死ぬほどイベントを発行して、効果音がけたたましく鳴り響いてTLの更新がしばらくおっつかなくなるんですが、この実装によって、最初の1favは即時、残りは99秒かけて1秒間に1つづつイベントが実行される。これによってイベントの実行が遅れる場合が出てくるが、乱発されない限り目立った遅延は起こらない。1つづつしかイベントが発生しないので、処理もすぐに終わるからたいした負荷もかからない。フォローなどについても同様。唯一の例外はつぶやき受信関連。これだけはちょっと違って(詳しくはソースみてくださいそんなにありがたいものじゃないが)、つぶやき関連のイベントは、1回のイベントにいくつでもつぶやきを持たせることができる。1回のループで、キューに溜っているイベントを全て取り出して、一気にイベントを発生させる。これによって、1秒間に大量のつぶやきを処理する可能性があるけれど、実はイベントの発行って結構非効率なので、10イベンtの発行するよりも1イベントで10ツイートを処理するほうがはるかに経済的。いうかそんなのが頻繁に起こるならどのみちmikutterつかえない重要なのは、同じイベントは1秒に1回しか発生しないようになった、ということ。どんな速度でイベントが発生しても、ここでイベントの流量が制限されるようになるわけ。これによって、例えば1分間に100favとかされたときにフリーズすることがなくなりました。今後の展望(というか実験中のこと)としては、GUIイベントを処理している時など、今やったらユーザの操作に影響が出るぞっていう時にはイベントの発行をさらに1秒遅らせるというの。ウィンドウが完全に応答なしになってるのに次々イベントほりこんでもしゃーないでしょ、という話。TL速い時に起動が数秒遅くなってるんですが、これは起動直後にウィンドウに夥しい量のつぶやきが放り込まれて固まってる間にたくさんイベントが発生しているからに他ならないんですよ。本当に重くしてる原因は他にあると思うので、そっちを潰すのが先かなぁとも。動きが良いのは良いことです。0.0.2.9このようなことを2週前に書いたわけですねいいこと思いついたコミットしたことをブログでまとめれば毎週一回の更新という今キメた目標を達成できるんじゃないかやっほーい俺ってちょーてんさーい!で、先週は体調崩してリリースをしなかった、と。そんなの今年初なんだ信じてくれぇ!ksg今回の更新について。設定→通知から、イベントが発生したときに再生する効果音を設定できます。これに結構前から「フォローされたとき」「リムられたとき」UserStreamに対応した時からは「ふぁぼられたとき」が追加されてました。他のTwitterクライアントのUserStream対応が進まない中、mikutterの対応速度なんと3日だったわけですよすごいでしょ褒めろで、今回はfavられた時とReTweetされた時の効果音を追加しましたが、残念ながらReTweet時の通知はまだ実装されておらずリプライ扱いになっていることに気づいたわけだな。ここでもmikutterのカスっぷりが遺憾なく発揮されたわけであります。@seibe2さんから効果音の提供もいただきました。前はコンテキストメニューが独自のフックみたいなのをもってたのを、今回イベントフィルタで実装しなおしました。これで、前より気楽にコンテキストメニューが拡張できる予定です。コンテキストメニューの項目にショートカットキーを割り当てられるようにして、現在ハードコーディングしているショートカットキーの項目をプラグインから気軽に増やすことができるようにする予定です。ついでに並び替え、罫線の挿入もできるようにするつもりですが、まだこのあたりは終わっておらず、現在コンテキストメニューには罫線が表示されません。メニューの数多くないので我慢してくだしあここで言っているコンテキストメニューとはつぶやきのそれのことで、タブやPostBoxのそれにも同様のことをしようと思っていますがそれはまた別の話UserStreamの流速制御機能ただの最適化です。今までは、UserStreamに大量のイベントが一気に流れてきた場合、それをいっぺんに処理しようとしてフリーズすることがありました。ここ数日に限って言えば、Twitterが不安定になっており、しばらく止まったと思ったらつぶやきが10件ほど一気に流れてくるというようなことがありました。あと僕最近大量にfavられる嫌がらせ受けてるのでそれもありますねmikutter開発当初はUserStreamはなく、1つのイベントで複数のつぶやきを扱っていましたが、UserStreamでは1つぶやきに対して1件のイベントを発行していました。そこで、連続してたくさんのイベントが来た場合は一定期間待って、その間に来たつぶやきを全部まとめて1つのイベントとして扱うことで、ピーク時の負荷を下げています。そのせいで1秒程度遅延することがあるけど、まあお得な取引でしょう。ReTweet、Favoritedもだいたい同様です。今後なんか、bit.lyのAPIのバージョンが2から3に上がったみたいですんで対応しましょうか。t.co(だっけ)がTwitterの標準になるとかいってたけどアレは結局どうなったんだっけ。実はパッチを送ってもらったりしたんだけど、短縮URLの内部処理の変更を検討しているところで、なかなか取り込めない。あと、リツイートの効果音作ったので、リツイートに対応したいですね。0.0.2.8いいこと思いついたコミットしたことをブログでまとめれば毎週一回の更新という今キメた目標を達成できるんじゃないかやっほーい俺ってちょーてんさーい!(前Tumblrに書いてたのをいつからか完全にすっぽかすようになった)http://mikutter.hachune.net/ksg最近全然ぱっとしたことが出来てないんだけど、これは忙しいからというよりは安定化に舵を切っているからでしてごにょごにょどうでもいいけどcore/mui/gtk_mumble.rbはmikutterでは2番目に汚いファイルで、600行くらいあったんだけど、今回ふぁぼられ・被リツイート(まとめてVoteと呼んでる)を扱うGtk::MumbleVoteと、アクティブ(選択)の概念を管理するためのGtk::MumbleSelectに分けました。結果、この2つに関してはユニットテストが書けたし、コード量も結構減ったのでよかった。同じようにコンテキストメニューのところも分離したあと、ショートカットキーと統合してコンテキストメニューでできることにショートカットキーを割り当てれるようにしよう。コンテキストメニューをプラグインから追加する方法はあるので。複数ファイルからなるプラグイン今まで、プラグインは、plugin/以下にある*.rbにマッチするファイル名だけになってました。これでは複雑になったプラグインを複数ファイルに分けたり、画像ファイルなどを入れることができません。いうわけで、最新trunkにこんな仕様変更をしました。(#72)X/というディレクトリがあれば、X/X.rbをrequireするディレクトリがつかえるようになれば、いくらでもファイルを入れることができるね!X/とX.rbが同じ階層にあれば、X.rbが優先されるので注意。この変更によって、plugin/以下に別のリポジトリからプラグインをチェックアウトして使うということができるようになりました。githubで公開しているプラグインを入れてそのままつかえる、など。今のところgithubにdbus-mikutterというのをアップしてます。これはdbusでmikutterのTLの情報が取れます。mikuttering-mode.elというのが同梱されてますがこれを使えばemacsからmikutterをつかえるらしいです。ある人がやってくれました。10.04で、mikutterをruby1.9.1で動かす方法ubuntu10.04で動かすのは実は結構お手軽。ruby-gnome2の1.9.1用のは用意されていないので、自分でビルドする必要がある。mikutter.rbこんなかんじだったとおもう(最小構成)。ruby-gtk2のビルドのためにruby-devいれたり、hmacの1.9.1用のがaptで用意されていないから本来必要ないgemを入れたりとなかなか。1.9にしたら相当早くなるし、メモリもぜんぜん食わない(当社比)。起動も3倍早くなりますしただ、まだ1.9のほうは1.8に比べたら落ちることがあるみたいなのでそこはご容赦。いままで重くて使えないと言っていた人でも、これなら使える!という人が出てくるんじゃないかな。10.10入れたマシンもってないんだけど、まあ上手く動かないと。自動投稿(Postクラス)Twitterクライアントの基本はつぶやくこととつぶやきを見ること。Post#postというエイリアスもあります。http://mikutter.hachune.net/rdoc/classes/Post.htmlでも、updateは内部ではdefine_methodを使って定義しています。RDocには載っていません。載せ方書いてあったけどうまくいかなかったこのPostオブジェクトはもともとつぶやきの投稿のためのものだったんだけど気づいたらAPIのインターフェイスになってました。friend_timelineとかも実はこのクラスを使って取得するんだけど、普通はイベントを使ってください。そのうちServiceに名前変えたいと思ってたけどそろそろ引っ込みがつかなくなってきました肝心のupdateの使い方ですが、引数はハッシュ1つで、symbolで最大3つの引数を与えられます。つぶやきの本文をStringで。リプライ先のメッセージ(in_reply_to_status)。リプライ先のユーザ(in_reply_to_user)。このユーザに宛てられる。本文に@そのユーザ名が含まれているかreplytoがセットされていれば自動的に補完される。Userのインスタンスで。あと、実際の投稿は勝手に別スレッドでやります。補足説明)を引数に取って以下のタイミングで呼び出されます。strは引数の:messageの値。messageは投稿したメッセージのMessageオブジェクト。これが渡ってきたらもうリトライしないということ。exceptionには発生した例外オブジェクトか、不正なHTTPコードが送られてきた場合はnilが渡される。後でもう一回接続を試みる(現在は1秒後に決め打ち)。以下の例は、よるほーするプラグインです。endend適当な実装だけど、だいたいこんなかんじ。時間の判定がやたら汚いけど、まあこんなふうにとっても簡単に実装できます。ちなみにbootっていうイベントは起動時に一回だけ他のイベントより先に呼ばれるイベントで、今のところはPostオブジェクトを得る一番ベターな手段です。リプライの送り方ですが、あるメッセージへの返信だったら、Message#postを使えばリプライが打てます。つぶやきの受信と送信の機能があれば、よくあるお遊びbotは実装できます。フォローしてる人限定ぼむったーなんかは簡単な正規表現だけで実装できます。がんばればおはなしbotなんかも実装できるでしょう。プラグイン作成2011年1月14日金曜日PluginTag(プラグインオブジェクト)mikutterの内部の話をするブログを作ってみた飽きたらやめる基本的にRubyを知ってる人に対して書いてます。へんなことかいてたらごめんプラグインの作成方法基本編です。mikutter.rbのあるディレクトリのplugin/以下に、なんとか.rbというファイルを作成します。すると起動時に勝手に読み込まれます。ここにrubyでゴリゴリプラグインを実装していきます。キーになるのがPluginTagクラス。実際は、Plugin.createを使ってプラグインを作るので、PluginTagという名前はあまり使わないかも。詳しくはRDocをみてね。http://mikutter.hachune.net/rdoc/classes/Plugin/PluginTag.htmlまず、騙されたと思ってPluginTagのインスタンスを得ます。Plugin.createにはプラグインのファイル名の拡張子の前をSymbolで渡してあげればいいと思います。同じシンボルを渡せば同じインスタンスを返しますが、長ったらしいので変数に退避するのが望ましいです。Plugin.create(:myplugin)endmikutterの中では、TLにつぶやきが流れてきたりするたびに「イベント」が発生します。このイベントを投げる/受けることで、プラグインはコアや別のプラグインとコミュニケーションをとってるんです。フォローしてる人がつぶやいたらupdateイベントが呼ばれ、そのイベントをlistenしているプラグインが起動されると。}endイベントをリスンするにはPluginTag#add_eventを使います。詳しい使い方はRDocにかいてあるけれど見たとおりで、updateイベントが発生するとブロックが実行されます(イベントのコールバック)。イベントごとにブロックの引数が決まっています。それも上のリンク先に書いてありますが、updateイベントの場合はPostクラスとMessageクラスの配列を引数に与えられることになっています。Messageクラスはつぶやき1件を表現するクラスなので、これだけでTLをターミナルに書き出すプラグインの出来上がりです!短い!ひとつのプラグインにいくつでもイベントをリスンさせることもできます。}endね、簡単でしょう?思いついたとおりに描いていけばいいんです。大事なことは、イベントは必ずメインスレッドで実行されるということです。mikutterはメインスレッド以外でGtkを叩いてはいけないことになっています。イベントのコールバック内ならGtk関連の操作をしてもOK。あまりにも時間のかかる処理をここでしてしまうとmikutter全体のレスポンスが悪くなりますねイベントの概念は、Twitterに例えたら、自分がPluginTagのインスタンスで、イベント(updateとか)が他人のアカウントで、add_eventとかでフォローする感じ。解りやすいかと思ったけど文字にしたら解り難かった。あれだGtkで言うところのシグナルですふつうにまとめmikutterプラグインの根幹となる概念「イベント」についてちょっと触れました。短縮URLなど一部のプラグインを除けばほとんどのプラグインがこのイベントを使っています。毎回こんな感じで書いていって、あとからマニュアルみたいに使えたらいいなってだったらちゃんとかけよおれきょうはなんかちょっと冷たいものが歯にしみたので歯をよく磨いて寝ます。