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

2011年12月26日月曜日

#mikutter 0.0.4, 0.1 rev.622

  • 0.0.4
    • URL開けない問題のパッチ当てるの忘れてたてへぺろ
  • 0.1
    • アイコンのキャッシュの持ち方の変更中
mikutterお誕生日おめでとうございます!!!なんかうちの時計めっちゃ進んでるみたいなので書き終わったらntpd起動しますね。こう簡単にデーモンが落ちると困りますよほんと

クリスマスなのでなんかと思ったんですが、先週も特に何も出来なかったので、1日くらいで出来そうなアイコンをロードするあたりの大掃除してました。
初期の頃からあったアイコン表示の部分がグロいことになってたのでリファクタリングしましょうというのと、一部ファイルシステムでは高速化も期待できますし、ついでにそのへんの細かい設定、プラグインによるキャッシュの制御もできるようにする予定です。

こんなどうでもいいことを長々と紹介する理由がわかるな?それ以外に言うことがない

あと、0.0.4はアップデートしたほうがいいですが、0.1は久しぶりにこれがスナップショットだという事を思い起こさせてくれる仕上がりとなっております(まだ途中だけどもう寝るのでここで切った)。ご注意くださいませ

2011年12月17日土曜日

#mikutter 0.0.3, 0.0.4, 0.1 rev.615

  • 0.0.3
    • デフォルトのブラウザの判別の不具合
  • 0.1
    • ruby-libnotifyを利用した通知を試験的に導入
関係ないけど、mikutterをテーマにした薄い本をどこかで頒布するらしく、いい機会なのでプラグインマニュアルをその本に載せるという体で書いて、Webにも公開しようと思ってます。
別に今週何もコミットしてないことの言い訳ではありません。ドキュメントのせいじゃないです。iPhoneで某名作が発売されるというトラブルがあったのが原因です。ドキュメントのせいじゃないです。

来週の日曜日はmikutterにとっては記念すべき日ですね。
12月25日…mikutterが書き始められた日です。今ではmikutterも広く認知されてきて、街ではmikutter二周年を祝って家とかにLEDを巻きつけたり木を置いたりしてお祝いムード一色です。
よーし、25は日曜日だから、思う存分コミットだ!

2011年12月11日日曜日

#mikutter 0.0.4, 0.1 rev.609

  • 0.0.4
    • URLをブラウザで開けない時にクラッシュする問題
  • 0.1
    • リストに表示されるべきでないツイートが入っている問題に関する修正
    • 一部環境で、設定画面のタブがいくつか欠落する問題
とまあfixだけです。
いやあ最近なんか忙しいと思ったら年末じゃないですかやだー
1.0無理だけど0.1はなんとかしたいなーとか思ってたらもう11日じゃないですかやだー
年賀状なんもしてないじゃないですかやだー

ておくれや

2011年11月27日日曜日

#mikutter 0.0.4, 0.1 rev.603

  • 0.0.4
    • 特定の条件を満たしたツイートを受信した時にクラッシュ
    • 同じ短縮URLのキャッシュが使われない場合があった
  • 0.1
    • 画像に対するリンクをポップアップで表示するようになった
    • 複数のPostBoxが存在している場合、いずれかを削除できるようになった
      • 空になっていることも削除の条件になります
      • ツイート失敗してから削除できるようにつけた機能です。通常は気にする必要はないです
    • 起動ロジックの書き直し
      • --profileオプションの追加
      • コマンドラインモード、デーモンモードを一度的に非サポートにしました。優先度低めで実装します
    • プラグインにコアライブラリの読み込みを明示的に書く必要が無くなった
      • 具体的には、miquireをプラグインに書く必要がなくなりました。書かなければ動かないという事があれば、バグです
わーいコミット600超えたー
0.1では大規模なリファクタリングばかりしていて、機能追加が全然ですね。
というのも、0.1でしたいと思ってることはあんまりなくて、掃除を主にやっていきたいなとおもってるんですよね。

追加したい機能で今のところ一番でかいのは、抽出タブの機能・UIを強化改善して、フレンドTLなどを取り払うというのが一番大きいでしょうか。TweetDeckのように、自由にタブを作る感じです。タイムラインにフィルタとかをつけることができるようになります。

あとはTLごとのイベント・フィルタですね。具体的には、タブごとに通知設定できます。
これ実はすごいことだと思いますよ。mikutterでこれを実装するということは、スレッドに対して通知が設定できるってことですからね。Skypeのチャットルームみたいに使えそうです。

とはいえ具体的にやりたいことをチケット化していないので、ちゃんとこのあたりもやらないといけないのだけど。

関係ないけどクリスマスにバージョン1.0は厳しそうです。いや、今の進捗的な意味でもそうかもしれないけれど、年末デスマーチフラグが建設されており…。やだなぁクリスマスに会社に泊まってたら横の家から愛し合ってる音とか聞こえてきたらやだなぁ

2011年11月19日土曜日

#mikutter 0.0.3, 0.0.4, 0.1 rev.592

  • 0.0.3
    • リストの設定を操作すると稀にクラッシュしていた
    • Twitterや回線の不調などの理由で、送信されずにずっと残り続けるツイートを削除できなかった
  • 0.0.4
    • ツイートを複数選択したあと右クリックすると、右クリックしたツイート以外の選択が全て解除されてしまっていた
    • Mac OSで動作させた場合にも、URLをブラウザで開けるようにした
  • 0.1.0
    • 適切にリンクが貼られないツイートがあった
ただのバグ修正です。深い意味はありません。

2011年11月16日水曜日

Activityについて

TwitterがActivity機能の提供を開始したようで。
これは、フォロイーのふぁぼ、リツイート、フォロー、公開リストの作成と追加を知ることができる。まだAPIは公開されてないし、それどころか一時的に機能停止したりといろいろと微妙な第一印象だけど、APIが公開されたらmikutterはどんなふうにサポートしていけるか、また何を追加すべきかを考えてみた。

ふぁぼ
現在、UserStreamを使えば自分のツイートのふぁぼられ、自分がふぁぼったツイートが取得できる。これに加えて、フォロイーのふぁぼりが取得できる。
mikutterでは、favstarのように各ツイートが誰にふぁぼられたかを表示する機能があるので、他人のふぁぼりも自然に表示することができる。
というよりは、UserStreamが発表されてからずっと、他人のふぁぼもわかるように成る時が来ると踏んでいて、こういうUIにしていた。今で約一年経ったが、APIが公開されればついに時が来るわけだ。
強いて言えば、自分に関係のないふぁぼは、TL上でageない、そもそも描画しないといった設定を作るべきだろう。

リツイート
現状でも、フォロワーのリツイートは見えるので、これがどのように表示されるかはご存知の通り。ここにさらに、フォロイーがリツイートされたツイートも入ってくる。
ここでも自分に関係のないものは表示しないようにするという選択肢があるといい。具体的に言うと、他人のツイートがフォローしていない人にリツイートされた場合は、自分に関係ないといえるはず。

フォロー
自分がフォローされたことは、UserStreamでわかる。ただし、libnotifyによる通知にしか対応していない。
また、フォロワーはフォロワータブで確認できる。

リスト
実は今のmikutterはList関連のイベントはだいたい無視してる。これは、取得した所で適切に表示する方法を持っていないからだ。
mikutterには今のところ、他人のリストを表示する方法はない。

アクティビティタイムライン
ということは、今のmikutterがアクティビティに対応するために致命的にかけているのは、せいぜいイベントをタイムライン表示することができないということだけだ。これがあれば、他の全ての機能はアクティビティ機能によって自然に強化されるだろう。

課題
単純に情報の流量が増えるので、今まで問題のなかった環境でも、パフォーマンスの問題が出るかもしれない。当然、そのためにアクティビティ機能は選択的に無効にすることができるようにするわけだけど、あったら全部使いたいよね。

まとめ
今からでも、システムメッセージのタイムラインなんかは作れるし、公開され次第すぐにでも対応したいところ。

2011年11月14日月曜日

#mikutter 0.0.3, 0.0.4, 0.1 rev.580

  • 0.0.3
    • 投稿中にしいたけを押せるようになった。投稿キャンセルができるように。
      • と思うじゃん?まだちゃんと動いてないんだなこれが
  • 0.0.4
    • なし
  • 0.1
    • Pluginモジュールをクラスに変更。PluginTagを廃止してPluginに統合。
    • 一部環境でmikutterが起動出来なかった
    • Ruby 1.8向けのコードを一部削除。
      • 多バイト文字の処理の違いを吸収するコードを削除したので、若干効率が良くなったはずです
うーん最近スランプ気味な気がする。全然コードを書く手が動かない。ミクに惚れた時以来だ。
サーバのrdocのバージョン上げて、テンプレートをdarkfishにしました。だからRDocがとても見やすくなってます。これでもう少し便利になったかな


Activity解禁おめでとうございます。mikutterは、ご存知の通り、他人のふぁぼも違和感なく表示することができます。だからはやくAPIを!公開して!ほしい!

2011年11月7日月曜日

プラグインが提供する設定項目とUI

プラグインを作っていると、設定を保存したいことが出てきます。ただの数字一つを保存するために、いちいちファイルに保存するのは非常にアレです。

設定値の保存と読み込み

そんなときは、UserConfigを使いましょう。以下のように使えば、mikutterの設定ファイルに設定を書き込めます。

UserConfig[:conftest_value] = 1

また、読み込みはこう書きます。

UserConfig[:conftest_value] # => 1

これは、全てのプラグインで共通なので、設定のキーの名前は、「プラグイン名_キー名」とするのが暗黙のルールみたいになってます。上の例の場合conftestプラグインですね。

手軽ですが、これをプラグイン間通信のために使わないでください。数少ない例外としては、表示の設定なんかは、設定用のプラグインが保存して、レンダリングするプラグインがその設定値を読みますが、そのあたりの裁量は空気を読みましょう。ベターな方法は、プラグインフィルタを使う方法ですが、まだ記事を書いてなかったので近いうちに書きます。すみません。

ユーザに設定させる

ユーザに設定してもらいたい項目が出てくることがあります。そんなとき、設定タブにプラグインの設定が追加できたら便利ですね。
mikutterでは、後から入れたプラグインが設定画面を新しく作ることができるようになっています。
以下は「表示設定」の設定画面を表示するプラグインです。先にいっておきますが、これが0.0.4ではちょっとマシになりました。ナウいやりかたは後述します。



なんかまーやりたいことはわからないでもないけど、ちょっと大きいですね。あとRubyらしくないと思う人も居ると思います。
0.0.4からは、プラグインの定義中で、settings do ... end の中に、設定項目を書くことができるようになりました。



ずいぶんすっきりしましたね。
この方法のメリットは、

  • ラベルと設定値と、最低限のUIの指定(候補から選択、キーボードで入力、ON/OFF等)だけになっている
  • RubyGtkを使わないので、実装が変わっても、RubyGTKを知らなくても簡単に書ける
とかがあります。

settings内で使えるメソッドの一覧は、core/addon/settings/builder.rbで定義されています。rdocあると思ったんだけど、プラグインなのでrdoc生成してません。コメント読んでください。

基本的には、第一引数がラベル名で、第二引数がUserConfigのキーです。ユーザが変更したら直ちに値がセットされます。

余談ですが、こういう適当にかいてることを、Wikiにまとめようと昨日あたりから動き出しました。だからもうちょっと丁寧な説明がまとめられるかもしれません。
そういうでかいマニュアルあまり書いたことが無いので、1分でわかるiPhoneアプリ開発みたいな本適当に読んでパクろうかなぁ

2011年11月4日金曜日

#mikutter 0.0.4, 0.1.0 rev.571

  • 0.0.4
    • コンソールから実行するRubyスクリプトにフッダがつく
    • URL再帰展開が上手く動かなくなっていた
    • SubpartsVoterのレンダリングの最適化
    • プラグイン独自の設定画面を提供するための新しいAPIを提供
      • ドキュメントは近々
    • 稀にクリックしても開けないURLがあった
  • 0.1
    • 次回バージョンを0.1としました
先週、風邪でリリース出来なかったので、今やっちゃいます。
trunkのバージョンを0.1にしました。それに伴い0.0.4のbranchを作成して、不安定版としてリリースします。

0.0.4は、Ruby1.8では警告が出て普通には起動できません。実用に耐えるほどのレスポンスが担保できないためです。
また、0.1では、Ruby1.9の機能を積極的に使って行きます。なので、今後0.1をruby1.8で使うと、Syntax Errorとかで起動しないと思います、多分。どうしてもRuby1.8で使いたい人は、0.0.3を使ってください。ubuntuならはやく11.10にうpgらですればいいと思いますの。

0.0.3は、よほど深刻なバグがない限りコミットしません。何かあれば開発者に教えてください。

Ruby1.9.3おめでとうございます。
mikutterも、Ruby1.9.3を積極的に使っていきたいと考えています。動作報告もあるので、暇な人はアップグレードしたら面白いかも知れません。


2011年10月23日日曜日

#mikutter 0.0.3.556 0.0.4.556

  • 0.0.3
    • TwitterのツイートのエスケープとEntityのindicesのずれを解消するために、indicesを見ないようにした
    • ユーザのプロフィールページを開くときのURLを修正
  • 0.0.4
    • Twitpicの画像が常に開けない
    • イベントにかかるフィルタの処理効率の改善
だめだこれは!全く間に合わねぇ!(残バグ数21件)
そろそろ0.0.3のバージョンをクローズすることも検討するレベルですね。いいかげんやばい。しばらく0.0.4のコミットをやめるとかしないと終わりそうにない雰囲気になってる。

過去のバージョンのmikutterではtwitpicのWebページの変更の影響を受けて画像のプレビューが効きません。検証が間に合わなくて0.0.3への取り込みは間に合いませんでした。

特定の時間にブロックを実行

例えばある時間に処理を実行したい場合がありますよね。そういう時のために、Reserverがあります。これは0.0.4.525から使えます。
Reserver.new(10){
  Post.primary_service.update(:message => '10秒後にツイート') }

Reserver.new("2011/11/23 04:00"){
  Post.primary_service.update(:message => 'もう2時か') }

と、指定した時間につぶやくようなことは簡単にできるようになります。他にもTimeを渡せば、その時間が来れば実行されます。Reserverを利用すると、いつかのよるほープラグインの例は、以下のようにかきかえられます。



とてもすっきり。最も、ピタリだったかどうかをつぶやく機能が無いのであまりこの比較は意味がないですが、いちいち自分でタイミングを合わせる必要がありません。
プラグインを書いていると、特定の時間に処理がしたい場合が出てくると思いますが、これを使えば面倒を見てもらえるので便利です。
当然、mikutterが終了してしまうとこの情報は消えてしまうので、実行されません。一年後の時間とかを設定してもまぁ無意味でしょう。
また、今の実装では、実際にブロックが実行されるたびに新しくThreadを立ち上げます。注意してください。

これからはコアでも積極的に使っていこうと思っていて、periodイベントなんかもこれを利用するようになる予定です。っていうか、periodイベントは精度も悪いし毎分実行しかできないし終わコン…?

駆け込みAPI

話はそれるけどコアでの有効利用の例。

ご存知の通り、TwitterのRest 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回使えるようになります。

今のところ使っているプラグインは、標準で添付されている list.rb くらいですね。

まとめ

  • 指定した時間に実行するとかラクにできてとてもおもしろい
  • つくっていうのもあれだがあんまり使う機会なさそう/(^o^)\

2011年10月17日月曜日

#mikutter 0.0.3.549, 0.0.4.549

  • 0.0.3
    • READMEの悪ふざけが足りなかったので追加
    • Twitter WebのURL表示方法に準拠。エスケープされた日本語のURLを案エスケープして表示するようにした。
  • 0.0.4
    • ubuntu 11.10で起動するようにした
    • エンティティの展開時に稀にUIが完全停止することがあった
Ubuntu 11.10

前回緊急リリースをしたのは0.0.3だけでした。今回から0.0.4でもubuntu11.10で起動できます。
ubuntu11.10での動かし方はREADMEをみてください。
あと、ubuntuのリリース日勘違いしてました。なので、若干目標を整理しなおし、0.0.3のメンテナンスを一週間伸ばして、10/31までとします。24日なんて中途半端な日をリミットにする意味が無くなったからです。

URLの表示方法の変更について

対策後。
リンクになってしまっているが文章として読める
何が問題なのか

現在、「twitter.com」のような、ドメイン名っぽいURLをつぶやくと、勝手に http://twitter.com/ とかに変換されてしまいます。これは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がきっとまたなにかやらかすに違いない
からです。

2011年10月12日水曜日

#mikutter 0.0.3.540

  • 0.0.3
    • Ubuntu 11.10 で起動しない問題
Ubuntuのリリース日をおもいっきり勘違いしていたので、焦ってやりました。
これ以前のバージョンをubuntu 11.10で起動するためには、Xの設定をいじる必要があります。
そういうことをいちいちしたくない人は、このバージョンを使いましょう。あと文章量が少ないのでリンクとか貼ってちょっとでも長くします。


mikutter 0.0.3は、ruby1.8でも起動はしますが、ruby1.9.2を推奨しています。
ubuntu 11.10では、以下のようなコマンドでインストールし

$ sudo apt-get install ruby1.9.1 ruby-gnome2 libnotify-bin

以下のようなコマンドで起動してください。

$ ruby1.9.1 mikutter.rb

環境によっては、rubyコマンドがruby1.8.7を指している場合があるので。

2011年10月10日月曜日

#mikutter 0.0.3.533, 0.0.4.534

  • 0.0.3
    • フッダを設定していると、Rubyコンソールから実行したコードにフッダがついて、Syntax Errorになる不具合
    • UIのアイコンが破損している時にクラッシュしないようにした
  • 0.0.4
    • 環境の要件を変更した
      以下に示すバージョンより古ければ今後起動することはできません。詳しくは後述
      • Ruby 1.9.2
      • Ruby GTK 1.0.0
    • Twitterリストのリアルタイム更新
      この為にStreaming APIを使用しています。次回のバージョンで、設定で無効にすることができるようになる予定です。
    • StreamingAPIをSSLを用いて接続するようになった
    • イベントキューの消化速度を変更できるようにした(今までは1.0)
      • 基本設定から変更できます。デフォルトでは全て0.1秒です。
    • Ruby1.8で起動しない不具合
Ubuntu 11.10の対応について

Ubuntu 11.10が10月24日にリリースされるようです(追記:13でした。でももう知らない)。Ubuntu 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からは、風評被害対策も兼ね、充分実用できるバージョンでしか起動しないようにしました。
要件に満たないバージョンを使っている場合、
  • 要件に合わせたバージョンに上げる(推奨)
  • --skip-version-check オプションをつけて起動する(非推奨)
  • 0.0.3系統を使う
の、いずれかの対策を取ってください。

0.0.4系では、今後積極的にRuby1.8で動作しない不具合を修正することはしませんが、パッチは受け付けます(Ruby1.9からの機能を使ってしまっている部分など)。
ただし、0.0.5からは、積極的にRuby1.9の新機能を使うので、そのようなパッチはrejectします。

2011年10月2日日曜日

#mikutter 0.0.3.522 0.0.4.522

0.0.3

  • アイコンキャッシュが削除されない不具合修正
  • TL更新時に稀にSegmentation Faultになっていた不具合修正


0.0.4

  • タイムラインのツイート表示が、プラグインでカスタマイズできるようになった
  • Streaming APIをSSLで接続するようにした
おひさしぶり!
今回は遂にSEGVを回避することが出来ました。これで、Ruby1.9.2とRubyGtk1.0.0でめっちゃ安定するはずです!
ubuntu 11.10までにダークマターも倒せるといいなぁヾ(@⌒ー⌒@)ノ

2011年9月30日金曜日

プラグインの新しい定義方法

前にプラグインを定義する方法を書いたんだけど、なかなか見た目が酷いものだったのでなんとかしようと思って、最近はもうちょっと情況が良くなってる。

例えば最近話題になってないDirectMessageのプラグインは、新しい書き方が使われてる。

今までは、Plugin.createで作ったプラグインオブジェクトにadd_eventメソッドとかで新しいイベントを定義してました。このせいで、mikutterのプラグインはかっこ悪いことになってました。

新しい形式では、Plugin.createがブロックを取れるようになっていて、プラグインオブジェクトのスコープでinstance_evalするようになりました。更にmethod_missingでイベントのフックがかけるので前回のプラグイン定義の記事のコードが

Module.new do
  plugin = Plugin.create(:myplugin)
  plugin.add_event(:update){ |service, messages|
    messages.each{ |m|
      puts m.to_s
    }
  }
  plugin.add_event(:mention){ |service, messages|
    messages.each{ |m|
      puts m.to_s
    }
  }
end

こうなります

Plugin.create(:myplugin) do
  onupdate do |service, messages|
    messages.each{ |m|
      puts m.to_s
    }
  end

  onmention do |service, messages|
    messages.each{ |m|
      puts m.to_s
    }
  end
end

当社比よくなった、これは人類にとっては小さな(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にインストールすると、何も起こりません。注意してください。


2011年9月21日水曜日

#mikutter 0.0.3.514, 0.0.4.514

  • 0.0.3.514
    • 規制されているときに誤ってPOSTしてしまった時に、設定した回数無駄にリトライしていた不具合
    • TwitterのREST APIが不安定なときに、大量にツイートなどの新着通知が発生してしまう場合がある
  • 0.0.4.514
    • DMの削除
      • とりあえず右クリックだけ
    • DM本文の自動改行するようにした
      • この修正のせいで、たまにDMの画面がチカチカしたり表示されなかったりする不具合があります
    • DMをやりとりしたユーザ一覧を、最後にやりとりした日時がより最近のものから順番に表示する
だいたいDM関連終わりましたね。
あとはアイコン付けて色つけて。あまりこれを細かく作り込もうとは思ってません(ロードマップにあるぶんはやるよ)。DMが扱えるようにしているだけなので、ね。もちろんパッチとかは大歓迎です。まーまだやってる途中なのであれだが。

あと次回のリリースはお休みします。お仕事忙しそうなので。下手するとその次も。流石にその次はできるんじゃないかな。どうなる俺、どうなるmikutter!


ヾ(@⌒ー⌒@)ノヾ(@⌒ー⌒@)ノヾ(@⌒ー⌒@)ノ


ところで、最近コミッタを増やしてもいいんじゃないかなと思ってます。
  • 俺よりRuby得意|プログラミングの才能ある奴(あほっぽい言い方だ)がコミットしたら品質あがるのでは
  • 単純に人数が複数人いたら開発速度あがるのでは
  • パッチよく送ってくれる人はそもそもコミットすればよいのでは
という思惑があるのですが、
  • ユニットテストが壊滅してるからせめて通るようにしてからにすべきでは
  • としぁさんの動きが鈍いのでは
  • そんな暇人いないのでは
  • バク報告ツールで上がってきた統計情報を共有する手段がない
という問題もあります。

こちらがある程度動けないとコミット権限上げるとかもできないので、考えてるだけなんだけどね。落ち着いたらなにかアクション起こす。
DMやってる間他のデバッグとかが止まるということがなくなったりするとうれしいかもね

2011年9月12日月曜日

#mikutter 0.0.4.505

追加
  • ダイレクトメッセージの対応開始
    • まだできてない
  • DM権限のないトークンの場合、認証画面を再度表示して認証させる
修正
  • はじめてmikutterを起動するとき、ウィンドウが出ず、認証できない
DMを一応使えるようにする試みをやってる最中。あと細かい並び替えとかそういうのが残っている
そしていろいろバグがでてきましたね

2011年9月4日日曜日

#mikutter 0.0.4.493


  • スクロールアニメーションを変更
ヾ(@⌒ー⌒@)ノなんかごめん
今週はなにか大きなことをします

あと、今回は0.0.3のリリースはありません

2011年8月27日土曜日

#mikutter 0.0.3.485, 0.0.4.485

0.0.3

  • 画像プレビューで、HTMLタグが1行に収まっていない場合開けなかった
  • 画像プレビューで、URLが短縮されていても強制的に展開してプレビューできるようにした
  • Ruby 1.8.7で、URLを含むツイートを右クリックするとクラッシュしていた
  • Ruby 1.8.7で、接続タイムアウト時に稀にクラッシュしていた
  • bit.lyのurlを展開するとき、稀にクラッシュしていた
  • URL展開の高速化


0.0.4

  • 0.0.3のバグ修正をマージ
  • openimg
    • Flickrに対応
    • Instagramに対応
  • t.co
    • t.co展開プラグインを取り込んだ
今回は画像展開関連のことしかやってません。1.8は、安定した気がするけれどそもそもRubyGtkがこけまくるので体感安定性は変わってません。近々手を打ちます。

画像プレビューは、近いうちに一気に増やします。もし http://dev.mikutter.hachune.net/issues/278 に書いてないサービスでmikutterが対応していないものがあれば教えてください

2011年8月21日日曜日

#mikutter 0.0.3.472, 0.0.4.472

0.0.3

  • Ruby 1.8.7環境でURLを含むツイートを右クリックするとクラッシュする
  • タイムラインの一番上から下にスクロールするとき、一度オートスクロールアップが誤動作する
  • 各種通知にミュートが働いていない
  • TL更新時に稀にクラッシュする
  • ユーザ情報が過去のものになることがある
  • タイムアウト時に稀にクラッシュする


0.0.4

  • GYAZOの画像プレビューに対応
いろいろバグをなおしました!0.1結局無理ですね!

2011年8月14日日曜日

#mikutter 0.0.3.460 0.0.4.460

不安定版 0.0.3.460と、weekly release版0.0.4.460をリリースしました。

0.0.3.460

  • 追加
    • 短縮URLを再帰的に展開する機能をつけた。TwitterがTwitpicなどの外部画像アップロードサービスのURLを勝手に短縮しても開けるようになった。


0.0.4.460

  • 追加
    • lockerzの画像プレビューに対応
    • mikutterのプラグインを全て削除してbot機能のみを抽出するスクリプトの試作品を追加。

8/15からTwitterが20字以上のURLを自動的にt.coで短縮するようになったので、mikutterなりに対策を講じました。
えへへー殆ど何もできてないよぉー

2011年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/jRbcmi
17文字!まだ我々には2桁残っている!やったね!
というわけで、bit.lyの設定をいじって、mikutterで短縮すれば、j.mpで短縮がかかるように設定変更しました。今までの全てのmikutterで、bitlyでURL短縮をするとj.mpドメインが使われるようになります。この変更のためにお使いのmikutterのバージョンを上げる必要はないです。気づいてなくてヽ('ω')ノ三ヽ('ω')ノもうしわけねぇもうしわけねぇ

mikutterがt.coに切り替えづらい理由

トリム

とはいえ、わざわざbitlyに短縮してもらってから投稿してるのでは確実に時間がかかるので、今となっては無駄です。Twitterがやってくれるなら素直にOFFにすればいい話かと思ったんですが、そう単純な話ではないんですね。

現在mikutterは、140字を超えたら自動的に超過分をトリムします。当然URL短縮後にです。この動作が問題で、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で短縮するようにしました。
  • mikutterのbitlyプラグインは展開にも使うので残すけど、短縮という意味においても依然アドバンテージがありますのよ

2011年8月7日日曜日

#mikutter 0.0.3.456

追加
  • MIKU Langの高速化
  • mikutterコマンド「URLを開く」追加
修正
  • 非フルカラー環境で起動に失敗する問題
  • UserStream使用時、フォロー通知が一人につき2回表示される不具合
  • 設定の「ふぁぼられたつぶやきをTL上でageる」が効かない不具合
  • ツイートのin_replyto_status取得中にツイートがTL上から削除されるとクラッシュする不具合
バージョン番号のについて

今回からバージョンの4桁目が、ウィークリーリリース番号からリビジョンになりました。この関係でバージョン番号が0.0.3.14から0.0.3.456に飛びました。
また、0.0.3.456は、最新不安定版としてリリースします

不安定版について

以前までは0.0.3.0が最新の不安定版で、バグも修正されませんでした。これからはバグ修正に限って、不安定版のバージョンアップが行われるようになります。

今後は以下の2本のラインで開発を進めます。
ウィークリーリリースは、従来通り http://mikutter.hachune.net/develop に毎週公開します。今週のバージョンは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を使いましょう。

2011年7月30日土曜日

#mikutter 0.0.3.14

追加
  • なし
修正
  • 初回起動時にクラッシュすることがあった
  • Twitter APIの不具合に対応
  • mousedownとmousedownで著しく位置が違う場合にもclickが発生している
  • 非フルカラー環境で起動しない
  • 不要なファイルを削除した
  • bit.lyの展開ミスった時にクラッシュする
うわああああああああああああああああああああああああああwwwwバグまだたくさん7月中にリリースできないよおおおおおお^p^p^p^p^p^p^

このままでは8月中に0.0.4いけるか微妙ですね!死ぬ!

2011年7月23日土曜日

#mikutter 0.0.3.13

追加

  • なし


修正

  • 空文字からコンテキストメニューでペーストした後、投稿ボタンが有効にならない

^q^?

^q^≡^p^

/(^o^)\

今回は細かすぎて伝わらないところやってたしそもそもコミット数が少なくてあれ
実はミクの誕生日に0.1にしたいと思っているんだけど、目安として

0.1→既知のバグのうち「バグ」「致命的」レベルのチケットを全て消す
0.0.4→「致命的」を全て消す

というふうに思っているので、0.0.4は一ヶ月前にはリリースしておきたかったね…
(「致命的」の報告が一週間ないバージョンがあれば、それが0.0.4になるので)

んでこのバージョンの上げ方どうよというのは前から言ってるので.4になるまでにはなんとかするというタスクも実はある

2011年7月18日月曜日

非ASCII文字ハッシュタグのはなし

なんか今更感のある日本語ハッシュタグが導入されましたねー(厳密には日本語以外もいけるようになったんだけど、このエントリは日本語なのでまぁ)。
ここんところフォーラムも何も見てないのでそういう情報入ってきてないので、事前情報があったかもしれないけど寝て起きたらできてたかんじでした。
で、いろいろとよくわからんことがあった

リンク条件

どういう時に日本語ハッシュタグになるのかよくわかってない人が多いですね。これは公式ブログ書いてあるけどつまり
  • 最初にスペースorツイートの先頭
  • #か#で始まる
  • 日本語とか(記号は不可)
  • スペースか句読点で終わる
を満たしていないと、そもそも一文字もハッシュタグとして認識されないというあれ。たとえば「#みくったー」は記号「ー」が含まれているのでハッシュタグじゃないです「みくった」の部分だけハッシュタグになるということもないです
(→流石にこの(糞仕様|バグ)は改善されて昨日あたりから「ー」が許されるようになった)

各種Twitterクライアントの対応の差異

大抵のTwitterクライアントは、24時間以内にアップデートをかけて日本語ハッシュタグに対応してしまった。まあこれはいいことですよね。
ただ、上に述べたような、長音が含まれてるとハッシュタグとして認識されないというのはどういう扱いになっているんだろう。かなり怪しい挙動だけど、仕様という解釈もできなくはなかった。また、そもそも最初からハッシュタグに以下のような正規表現を使ってるせいで
#.+?\s
そもそも日本語だろうと何だろうと全部リンクしてしまうあれなTwitterクライアントも結構ある。
つまり、同じツイートなのにハッシュタグとして認識される範囲がツイッタークライアントによってまちまちであるというコーナーケースがいくつか存在してるわけですね。

mikutterの対応

みくったーユーザ「あ、ありのまま今起こったことを話すぜ…。mikutterを立ち上げたら、バージョンも上げていないのに、既にハッシュタグに対応していたんだ、自分でも何を言っているのかry」

こんな風に勝手に対応してしまった理由は、俺が事前に情報をつかんでたわけではなく、Twitterにエンティティ情報を元にリンクを張っているからです。

https://dev.twitter.com/docs/tweet-entities

Twitter的には何文字から何文字目がURLだとか、そういう情報を送ってきている(エンティティ)ので、そのとおりにリンクを張れば、Twitter Webと全く同じ位置にリンクを貼ることができる。
この情報を使っているツイッタークライアントは、Twitterが日本語ハッシュタグのリンク位置を送ってくるようになった瞬間から対応ができてしまっていたということになるわけですね。

エンティティ情報を使っていないのが大多数

何かしらのバージョンアップをするということは、そういうことになりますよね。
ぱっと思いつく理由はこんな所かな

  1. 出来たのが最近なので、対応していない
  2. Twitterが言うことなので、信用ならない
  3. いろいろと面倒くさい

1は既に自前でやっててちゃんとできてるしいいじゃんという話。2は、まあ、はい。3は、なんか<>はエンティティエンコードされて送られてきてるのに&はされてなかった気がするんだけどあれナンダヨとか、実は微妙にバグってたりするんじゃねーのとか、まあそのあたり。

で、mikutterには愚かにもこれを信用していて、Twitterが日本語ハッシュタグ対応した時点で、そのルールに合ったものについてはエンティティがくっついてくるようになったので、普通に日本語ハッシュタグがつかえるようになったというわけ。
だけど、先に述べたような、全角長音記号が含まれているとハッシュタグとして認識されない不具合などまでそのまま反映してしまう(Twitterが治したタイミングで治ったが)。

まとめ

みんなエンティティつかってないんだね…僕テッキリ使ってると思ってたよ…グスン

2011年7月16日土曜日

#mikutter 0.0.3.12

変更
  • なし
修正
  • voterのアイコンにチップヘルプでscreen_nameが出ていなかった。また、クリックでユーザのプロフィールが表示されていなかった
  • フォロー・フォロワー一覧で、ホイールスクロールができない
  • /statuses/updateを叩くときに、include_entities=1をつけて、自分のつぶやきにエンティティを付けさせるようにした
  • エスケープされた文字列を適切にカウントしてインデックスを補正するようにしているところです
  • つぶやきがTLから消えた瞬間にリツイートされた場合にクラッシュすることがある
やったねバグが増減したよ!!!
前回までのバージョンでは、自分のツイートに対して日本語ハッシュタグが正常に反映されない問題がありました(ほかのひとにはちゃんとみえてる)。このバージョンからは自分の投稿にも日本語ハッシュタグが正常にリンクされます。

2011年7月11日月曜日

mikutterにDeferred入れたらどうなるのっと

mikutterには実行予約の機能がいろいろある。
RubyのThreadもある意味そうだけど、Delayerなんかもそう。これはJavaScriptでいうところのSetTimeout(callback, 0)みたいなもので、用途もウィジェットの更新とかなので被ってる。

で、JavaScriptではJSDeferredが便利だ

http.get('some_twitter_api').next(function(){
  // success
}).error(function(){
  // fail
})

いやーすばらしい。これはパクらない手はない
deferredは、連続した処理をぼちぼち順番にやっていって、エラーの捕捉もしやすい。で、http通信のメソッドとかがDeferredオブジェクトを返せば同じようにつかえて便利だなぁ。
ちょっと実験してみましょう。

現在のmikutterでは

例えばTwitterAPIを叩くのはPost#call_apiというメソッドを使う。こいつはAPI名とブロックを引数に取って、新しくスレッドを作ってリクエストを発行して、そのスレッドを返す。
あとでリクエストが完了したらコールバックを呼ぶ。という、JavaScriptのXMLHttpRequestだっけ、あれみたいな挙動をしている。スレッドを返す理由は、途中でThread#killを使ってキャンセルできるようにという深遠な理由がある。

Deferredを使うとどうなる

まず、今回の実験では、Deferredableをincludeした全てのクラスがdeferredみたいに振舞うことにした。これで、以下のオブジェクトが等しくDeferredのように振る舞える。

  • Delayer
  • SerialThread
  • Thread
Deferredのブロックが返す値は、次のnext{}ブロックの引数になるけれど、それがDeferredのインスタンスだったら、それの実行を待ってから次のブロックが呼ばれる。つまりDeferredをネストできる。
ということは、Deferredのブロックの戻り値にThreadとかを設定できてしまう

deferred{
  post.call_api(:api)
}.next{ |value|
  // success
}.trap{ |exception|
  // fail
}

Proc#call_apiの戻り値はThreadなので、本当は以下のように書ける

post.call_api(:api).next{ |value|
  // success
}.trap{ |exception|
  // fail
}

おなじこと。
こうする利点は、whenとかloopとかがつかえることかな

Deferred.when(deferred_1, deferred_2, ..., deferred_n).next{
  // do something
}

こういう感じで、複数のDeferredableの終了を待てる。今までだったらDelayerとThread両方が終わったら…なんてコードはよう書かなかったんだけど、Deferredableならできますよどうですか!

Enumerableにeach_deferとか作っておけば、イベントで大量のつぶやきを受け取ったとき、時々休みながら実行ということができる。つまり、ループが長引いたら一旦処理を中断するというあれ。なかなかいいんじゃないかな

とまあ適当なことを書き散らしたけれど、まあ利点は本家とたいして変わらない。DeferredableをincludeすればどんなオブジェクトでもDeferredになれるので、いろんなクラスのエラー処理をとてもスマートに書ける可能性がありますね。
まだこれはコミットせずに様子を見てる。プラグインが書きやすくなるだろうか。

2011年7月9日土曜日

#mikutter 0.0.3.11

追加

  • なし


修正

  • 起動時に稀にクラッシュする
  • mikutterが起動するプロセスが全てゾンビになる
  • 削除されたツイートへのリプライを表示するとクラッシュする
  • フォロー関係のキャッシュファイルの節約
  • 自分のツイートの削除時に稀にクラッシュする
おおバグ直してるのにチケット数は減らねえぞどうなってやがru!
(既知の)バグが全部なくならないと0.0.4ないで

とはいえ。まだまだデスマが続きそうなので、今夏中に不安定版上げるのは無理ですね工数的な意味で
明日も休出なので今日は気が向いたらなにかやるかな しかし
コミット権限を持っている人を増やしたほうがよい気がしてきた でもそうしたら運用ポリシーどうしたらええのんかわからぬ
自分に害のあるバグとか見つけたらソースコード探ってみたりする人とかいるみたいだし俺のTLポテンシャルあるよ!!!

まあちょっとづつコミットできてるからいつかリリースはできるよ

2011年7月3日日曜日

#mikutter 0.0.3.10

ピャアアアアアwwwww 僕がデスマーチしてる間に時間が2週間も過ぎてたのおおおおwwwwww

追加

  • 起動時は、最後に取得したフォロー・フォロワーをレジュームするようにした
    • キャッシュを大量生産するのでちゃんとゴミ集めしないとなー

修正

  • フォロー・フォロワーが最新の200人しか取得されていなかった
  • ツイートを選択した状態でほったらかしておくとクラッシュしていた
  • URL展開に失敗したときにクラッシュしていた
  • 起動時に稀にクラッシュしていた

投稿遅いことがあるのはTwitterが原因ですのでさっさと直してくださいな、時間がない

2011年6月19日日曜日

#mikutter 0.0.3.9

最近働きっぱなしで、会社にきのこが生えてしまったよ…もういやだ…。

追加
  • なし
修正
  • 日本語で検索できなかった
  • 日本語でgoogle検索ができなかった
  • 検索文字列を入力中に、つぶやき用のショートカットキーが発動してしまっていた
  • メモリリークを随分マシにした
  • 自分を認証していない鍵付きアカウントのつぶやきを取得しようとしたらAPIを食い尽くすまでリトライし続けていた
  • 一部プラットフォームでサウンドが鳴らない不具合
今回はバグ修正しかしていないwwwwwwwwwちょっとへんなハックしたから逆に増えてるかもwwwwwwwwwwちゃんとテストしたけど自分信用できないwwwwwwwwwwユニットテストも書けない部分とかぶっちゃけ弄りたくないよおおおおwwwwwwwwwwwwUIいやだあああよおおおおwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwworz

もっと安定させていきたいですね!!!ヾ(@⌒ー⌒@)ノ

mikutterプラグインから使う並列処理・遅延処理のユーティリティ

mikutterでプラグインを作ると、時間がかかる処理をしたくなることが稀によくあるので、そんな時に便利そうなmikutter内部で使えるクラスなどをまとめました。Ruby標準のThreadなどは使えるけど省略

mikutterのThreadによる並列処理の考え方

現在のRubyでは、複数のThreadによる並列処理をしても、単一のプロセッサで複数のThreadが時系列で切り替わるだけなので、本当の意味で並列処理されるわけではないし、処理が速くなるわけじゃあない。んで俺は頭が弱いので、並列処理なんてしたら基本的にぽぽぽぽーんしてしまう残念な頭をしているので、極力使わないようにしています。

!!!触らぬ神に祟なし!!!

ということですね。
積極的に使う数少ない例外ケースは、ネットワーク通信。サーバの応答待ちの間、シングルスレッドなら他の処理をブロックしてしまうけれど、他のスレッドでネットワーク通信をすればブロックされることはないと。
また、mikutter内ではメインスレッドでしかGtk関連の操作をしてはいけないことになっています。つまり
メインスレッド → UIの処理、すぐやるべき処理
その他スレッド → 通信など
という役割になっています。だからメインスレッドであんまり時間がかかる処理はしないように心がけましょう!

Twitter APIを叩くためのメソッドは、メインスレッドで呼ばれるとクラッシュするようになっています。又、Gtk関連の一部メソッドも、メインスレッド以外で呼び出すとクラッシュするようになっています。

並列・遅延処理のためのメソッドいろいろ

そんなmikutterのための並列処理などのためのお役立ちメソッド|クラスたち。

コンストラクタに渡したブロックをあとで実行する。あとでというのは、そのうちヒマな時にやるということで、そんなに即時性が重要じゃない処理に使う。
Delayer.new{
  # Do something
}
ブロックは登録された順番に呼ばれる。また、必ずメインスレッドで呼ばれる。

Threadとほとんど同じだけど、別々のSerialThread同士は順番に実行され、同時に実行されることはない。Delayerだとメインスレッドをブロックしてしまい、UI操作に支障をきたす可能性がある処理につかう。一つのThreadを使いまわすので、Threadが増えない。
SerialThread.new{
  # Do something
}

RubyでHaskellみたいな遅延評価をするためのもの。ちょっとへんなのもあるけど。
ブロックを渡して使う。戻り値は、ブロックの実行結果なんだけど、ちょっとブロックの実行するタイミングが違う。

lazy
遅延評価オブジェクトを返す。初めてこのオブジェクトにたいしてメソッドが呼ばれたときに、1度だけブロックを実行する。
a = lazy{ fact(156) }
b = lazy{ fact(39) }
p b
上の例だと、39の階乗が出力されるけれど、実際に計算されるのは表示されるとき。156の階乗も一見計算しているようだけど(a)、使われていないので計算されない。

everytime
lazyと殆ど同じだけど、メソッドが呼ばれるたびに毎回ブロックを実行する。

parallel
lazyは最初に必要になったときだけど、parallelはすぐに別のスレッドでブロックを1度だけ実行する。実際に値が必要になったときに、まだ実行が終わっていない場合は、ブロックの実行終了まで待つ。

atomic
グローバルなMonitorのインスタンスのロックを取得してからブロックを処理する。ひとつしかMutexがなければデッドロックなんてないんや原理主義者のために用意されている。コアで使うためにと思って用意しました
atomic{
  # Do something
}
イベントが処理されるスレッド

mikutterのイベント(PluginPluginTag)は、必ずメインスレッドから呼ばれます。なのであんまり時間のかかりそうな処理はしないほうがいいです。
一方、イベントフィルタは、Plugin.filteringを呼んだ時に直ちに実行されるので、どのスレッドから呼ばれるかは不定です。つまり、フィルタは特にマルチスレッド処理に注意!ということです。

まとめ

mikutterで処理のタイミングをずらすためのユーティリティをまとめました。また、スレッドの扱い方の暗黙のルールを明文化しました。

2011年6月12日日曜日

#mikutter 0.0.3.8

今回からWeeklyリリース(snapshot)を、mikutterのサイトのDownloadからDevelopの項目に移しました。初めて使う人が、文章を読まずに単純な数値比較でWeeklyリリース版をダウンロードしてしまう事故を避けるためです。その他のバージョンは、今までどおりDownloadからダウンロードできます。

http://mikutter.hachune.net/develop

追加

  • 通知関連のイベントの追加。これによって、以下のプラグインが追加されました。その他については後述
    • alsa - サウンドを鳴らすプラグイン
    • libnotify - libnotifyを使って通知を表示するプラグイン

修正

  • 規制されたときにクラッシュする不具合
  • 付属のJSONライブラリのバージョンが古く、一部環境で問題が出ていた
  • 設定が正常に保存されない不具合
  • リンク位置がずれる不具合
  • 一部APIのキャッシュ機能
  • ショートカットキーの編集でクラッシュする不具合
いやー、0.0.3.9が0.0.4にならないかなーとか思ってたがなかなかそうもいきませんねぇヾ(@⌒ー⌒@)ノ
0.0.2のようにバグを潰す為に.12くらいまで行ってしまうのだろうか。このバージョン番号についても0.0.4以降ちょっと変わるんだけど

通知プラグインを小分けにしたおかげで、特定のプラットフォームでは音とかが鳴らなくなったと思います。そんな時は以下のプラグインを入れてみましょう

https://github.com/toshia/mikutter-win32sound - Windowsでサウンド鳴らす
https://github.com/toshia/mikutter-sdl - SDLでサウンド鳴らす

これらのプラグインの要領で、手軽に通知やサウンド関連を拡張できるようになりました。ニッチな環境でmikutterを使っている人はチェックだ!

折角高速化できたところなので、このタイミングでぜひとも安定させていきたいところですね!!!当分はバグをとり続けることになるかなー。今バグチケット21個もあるんだけど^p^

2011年6月5日日曜日

#mikutter 0.0.3.7

追加

  • Twitter公式画像アップロードサービスを使ってアップされた画像のプレビュー機能
  • Twitter APIで短縮URLの展開形が取得できた場合、それを利用する

修正

  • タイムライン上のリンク文字のリンクの位置のずれ
  • メモリリークをちょっとマシにした
Twitterが画像アップロードサービスを自分で始めちゃいましたね。entityにそれがくっついてくるとのことで、急遽エンティティを読むようにした。それから、どうもentityはOAuth通さないとくっついてこないようで、今のmikutterの実装だとUserStream、home_timeline、mentions経由で取ったものでないとentityがない、つまり公式画像サービスを使ってアップされた画像が展開できないと。まぁブラウザで開けるんだけどね。

とりあえず日曜日になったから上げてみたものの、メモリ削ってる途中なので、相当重くなってますね。このところ時間が取れないから0.0.4は梅雨明け以降かな…

2011年5月28日土曜日

#mikutter 0.0.3.6

はいはーい

  • ruby1.8で、タイムラインの右クリックメニューが表示されない
  • ruby1.8で、ショートカットキーの新規割り当てで確実にクラッシュする
  • ruby1.8で、MiraclePainterが更新された時にSegmentation faultする
  • ruby1.8で、文字列選択でクラッシュする
  • ミュートしたユーザがTLに表示される不具合
  • リツイート、リツイート解除、のmikutterコマンドの修正
  • ふぁぼ解除のmikutterコマンドの追加
  • 選択範囲をgoogleで検索
  • ruby-hmac 0.4.0のうち、使用しているファイルを添付
  • その他不具合修正
いやdisってないですって!!!すべてぼくのミスです!!!^p^

1.8で使ってる人、多いんだなぁって驚きました。ubuntuと謳っているのでそりゃあそうか。これからは十分速くなったのでruby 1.8で使う日と1.9の日を交互とかでやるか。ユニットテストで追い切れない部分は使わないとどうしようもないしね。

ここからは特に目立った機能追加はせずにバグを取って、0.0.4を目指そうと思います。またruby1.8ではこのバージョンから実質new UIをつかえることになりますね。うへへヾ(@⌒ー⌒@)ノ


2011年5月27日金曜日

mikutterコマンド

プラグイン開発のおはなし。

プラグインは、結構簡単に自分のタブをつくることができるようになってる。その方法は既存のcore/addon/friend_timeline.rbとかを見ればすべてわかるので省略するけれど、これだけじゃあプラグインには不十分なことがある。

例えば、指定された特定のつぶやきに対して動作するものは、タイムライン上でつぶやきを右クリックしてメニューで選べると良い(コンテキストメニュー)。
例えば、プロフィール表示はただのプラグインだけど、コンテキストメニューに「〇〇のプロフィール」という項目が出てくる。これは、今まで「コンテキストメニューフィルタ」というのを使ってて、イベントフィルタで右クリックメニューをガシガシ追加できるというものだった。

0.0.3.5からはキーコンフィグで右クリックメニューで出てくるものにキーを割り当てることができるようになったので、ユーザは前より柔軟にカスタマイズができるようになった。
そんなふうに、コンテキストメニューやショートカットキーにプラグインが追加できる機能、mikutterコマンドを新しく追加しました。
今回はその話。

    plugin.add_event_filter(:command){ |menu|
      menu[:smartthread] = {
        :slug => :smartthread,
        :name => '会話スレッドを表示',
        :icon => MUI::Skin.get("list.png"),
        :condition => lambda{ |m| m.message.repliable? },
        :exec => lambda{ |m| tabclass.new("Thread #{counter.call}", service,
                                          :message => m.message,
                                          :icon => MUI::Skin.get("list.png")) },
        :visible => true,
        :role => :message }
      [menu]
    }

これは会話スレッドプラグインの、登録している箇所。(core/addon/smartthread.rb)。だいたいこれをテンプレに使って頂けたらとおもうんだけど、menuという連想配列に入れる内容がポイント。

:slug
一意なコマンド名。かぶっちゃいけないので、プラグイン開発者の独創性が試される。Symbolで何か。まあおまえら初心者は、:プラグイン名_機能名 にでもしておけってこった
: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
    つぶやきにフォーカスがあるとき。以下のような構造体が引数になる。
    Struct.new(:event (Gdk::Event or nil), :message (Message), :timeline (Gtk::TimeLine), :miraclepainter (Gdk::MiraclePainter))
  • :message_select
    :messageの時で、なおかつテキストが選択されているとき。引数も同じ。
  • :timeline
    タイムラインで右クリックされたとき。基本的に:messageと同じタイミングだけど、引数はGtk::TimeLineしか受け取らないという点がちがう。
  • :postbox
    つぶやき入力欄。今のところ、ショートカットキーにしか対応していない。引数としてGtk::PostBoxを受け取る。
こういうふうに、わりと簡単にmikutterコマンドを新しく追加できる。プラグインに依存しない機能(リプライとか)は、core/addon/contextmenu.rbに実装してあるので、例が見たければこれをどうぞ。

これで随分プラグインの幅が広がるような気がします。おもしろいものをつくってね!!!

2011年5月23日月曜日

新UIについて

こんばんわ。先程新UIをリリースしました!何がどうなったのか簡単に説明するよ。

mikutterの従来のレンダリング方法

いままでのmikutter。見た目はリッチ。
動作は察してください。
今までのmikutterは、ウィジェット※1を綺麗に並べてタイムラインを実現していました。この方法だと、あらゆるウィジェットを使用することができるので、タイムラインのレンダリングがとても自由にできます。

※1…ウィンドウのパーツのこと

したがって、mikutterのタイムラインは他のTwitterクライアントのそれに比べてかなりリッチな部類だと思います。なかでも、アイコンオーバーボタン(アイコンにマウスカーソルを重ねるとボタンが出てくる機能)、ふぁぼられ、リツイート累積表示、リプライ宛先表示などのmikutterの代表的な機能は、この方法でタイムラインをレンダリングしたからこそ容易に達成できた、という背景がありました。

何が悪いのか

本来、ウィジェットは頻繁に追加削除されるものではないので(大体は作ったらそれでおしまいですよね)、ある程度タイムラインの流れが速いと、異常な速度でウィジェットの作成/削除/パッキングが行われます。
配置の自由度が高いぶん、こういった変化があったときの再描画のコストは馬鹿になりません。また、Ubuntuの最新版に入っているRubyGTKはとても古く(nattyには0.19.3が入っているが、最新は0.90.8)、大量のバグが含まれているのが現状です。そのようなAPIに頻繁にアクセスするので、ライブラリがSegmentation Faultしてmikutterが巻き添えになることがしばしばありました。

他のTwitterクライアントのレンダリング

夜フクロウ。
Linuxじゃない、Rubyじゃない、Gtkじゃない。
けどリストビューっぽいですね。
mikutterは他のTwitterクライアントと比較して、レンダリングが飛び抜けて遅いですね。説明は上記の通りだけど、ではどうしてそんなことをしたかというと、現在のmikutterは、とりあえず表示できるものを仮に作った段階だったのです。つまり、mikutterのUIは新たにつくり直す必要がありました。

では、他のTwitterクライアントはどうしているかというと、リストビューを使用していると思われます。
リストビューは、パーツが縦に並ぶことを前提にしているのでどうやら速いらしい。ソートオーダーなどの細かい話もGtkがやってくれるのでRubyでやるよりは早くなりそう。

しかし、じゃあリストビューにすればいいじゃない、と簡単にはいかない。というのも、この中に置けるのは、せいぜい画像と文字くらいだからで、新しいRendererを作成するにしても、今までのように好きなウィジェットを思いのままに設置するとはいきません。

Cairo+リストビュー

新UI。かなり高速になったが見た目はそんなに変わらない。
じゃあ、全部画像にしたらよくね!?という奇想天外なことを思いつきました。画像だったらすきにレンダリングできるけれど、キャッシュすれば速さもでるんじゃねーのと思ったわけです。

リストビューは、任意のRendererを設定できるので、今回は実際にTLを描画するやつをMiraclePainterという名前にしました。TLの先まですべてミク色に染めていただきましょう!!!

で、リッチな表示ができないとか言ってたけど蓋を開けたら右のようになってます。ついでだから微妙にマイナーチェンジしましたが。これがどの程度速くなったかは、実際に起動してもらったほうがよさそうなのでここでは書かないけれど、

  • ボトルネックになってた部分は100倍くらいの効率のアップ
  • 起動時間は2秒
  • 新しいタブを作ったりした時にブラックアウトすることもなくなった
  • 入力中に固まってイライラすることもなくなった
  • RubyGtkのAPIを叩く回数が減ったので、Segmentation Faultの確率が減るかも!?

と、圧倒的な進化を遂げました。CPU使用率も大幅に減ったので、いままで遅くて使えんと言っていた人もつかえるようになるんじゃないかな。

ただそのためには、ショートカットキーなどの処理をもっときめ細かにやっていかないといけないと思っていて、例えば横のタブにフォーカスとか、リプライ後のフォーカス移動とか、そういうところに気を配らないとなぁ、と思ってます。

現在この最適化は、0.0.3.5 ウィークリーリリース版に適応されています。これからバグを取ったり最適化をする段階だけど、興味がある人は是非!!!

#mikutter 0.0.3.5

さあドッグフードを食え!!!

  • TLのレンダリング方法の変更
    • 高速化しました
      • 一部機能はまだ実装中です
  • ショートカットキーの設定の大幅刷新
    • 右クリックメニューでできること全てにショートカットキーを割り当てられるようにしました
TLのレンダリング方法を革命的に変えました。そんで今回は、久しぶりにバグてんこ盛りのウィークリーリリースになってます!!これからなおしていこう!!!

2011年5月16日月曜日

#mikutter 0.0.3.4

みんな元気ー(^p^)つ!?またゴールデンウィーク来ないかなーーーー!!!ヾ(@⌒ー⌒@)ノ



はぁ

  • PIAPRO画像プレビュープラグインの修正
    • PIAPROの仕様変更に対応
  • 設定と環境によっては過剰にAPIを消費することがある不具合
    • とりいそぎでかいのだけ。有意なレポートがないのでこっちで再現したぶんだけ修正しています
今回は静かですねーなんっでっかなー(

新UIについてはまだです。それについては前回の記事を。ほとんどできているので、今週中にtrunkにマージして、1〜2回のウィークリーリリースを経て0.0.4にできたらなぁと考えています。

なんか最近なんもしてないのに同じような不具合がたくさん報告されてくるのあれなんだろう。mikutterも五月病なのかなだらしねぇな ←

新UIが安定したら0.1あるでと思ってます、応援してね!!!

2011年5月14日土曜日

cairo版と言われてるものについて

ひっそりやってたんだけど思ったより拡散したので、解りづらい形式で説明します。
あまり説明に時間を食いたくないので簡単に。

cairoとは

すごくかわいくなります

mikutter cairo版とは

萌ゆいものとかわいいものが一緒になってやばいです

具体的に何をしたの?

タイムラインをリストビューにして、各セルをcairoでレンダリングしています。見た目はできるだけ今までと変わらないようにしています。
だから別にcairoを使ったことだけが新しいわけじゃないんだけど、それに気づいたときにはみんな知ってたのでておくれました。

何が良いのか

高速になって、メモリ消費が少なくなって、ライブラリのバグを踏む確率が下がることを期待しています

欠点は

とくになし。ただし、リプライのUIが若干変わってしまうかも。これは最終的に従来の方法を実現できる可能性がある。
それさえなければ欠点は特になさそう

どうやって使うのか

trunkには入っていません。以下のリポジトリからチェックアウトしてください。
svn://toshia.dip.jp/mikutter/branches/cairoui
ただし、未実装の部分が多く、クリックするとクラッシュするボタンがあったりします。あくまで、ちゃんとなるまで待てないという早とちりな人用です。

進捗を見たい

ここでやってます。 http://dev.mikutter.hachune.net/issues/131

バグ報告など

上のチケットの中になければ報告欲しい…といいたいところですが、リソースをこちらに集中して開発しているので、おそらくバグ報告は行き違いになると思います。

2011年5月7日土曜日

#mikutter 0.0.3.3

みんなみてるぅー?いえーいヾ(@⌒ー⌒@)ノ

  • プロキシサーバを利用してアクセスする機能
    • デフォルトでは、環境変数 HTTP_PROXY の内容を利用します。mikutter上で設定もできます。
    • @osa_kさんにプラグインをいただきました!
  • Growlを利用した通知に対応
    • @katsyoshiさんにパッチをいただきました!
  • SDLを用いたサウンドの再生
    • 同上
  • debian系OSで、mikutterを動作させるために必要なアプリケーションをビルドするスクリプトを同梱
  • 鍵付きアカウントのつぶやき取得に関する不具合
  • いくつかのクラッシュする可能性のあるバグ、最適化

遂にプロキシ機能付いたよ!これで一部大学・会社なんかのtwitterをブロックしているFW内からmikutterがつかえるね!やったねたえちゃん!







フフフヾ(@⌒ー⌒@)ノ

2011年5月2日月曜日

MUiなんとなくできてきた、ような…

あれから紆余曲折あったけどMUiが構想からなんとなく動くものになってきた。
MUiの略称は Mikutter UI くらいにしておこうとおもう。GTKだってGimp Tool Kitだったしね

できるだけ、SXMLをそのままUIとしてレンダリングしたい!…と思っていたわけなんだけど、実際の動くコードは今こんなかんじ。

require File.join(File.dirname(__FILE__), '..', 'mui')

MUi.toolkit = 'gtk'
window = mui([:window, [:button, 'hello, world']])
window.add_event_listener(:close){
  mui.mainloop_quit
}
(window / 'button').add_event_listener(:click){
  p 'clicked!!'
}
mui.mainloop

ドヤァ
まあ最初の方は授業とかでおまじないと言われるアレですね

window = mui([:window, [:button, 'hello, world']])

これは、以下のようなSXMLをRubyの配列で表現したもの

(window
  (button "hello, world"))

mui()というのは、jQueryで言うところの$()みたいなものと思っていただければ。$("<div>")とかやるじゃん
これが実際何をしているかというと、引数をMUiのGtkプラグインで定義されるオブジェクトでラップしたものを返してます。そのクラスはMUiBaseクラスのサブクラスで、MUiBaseはArrayのサブクラス。そして中身の値も渡された配列と全く同じになるようにコピーされます。

渡された配列にいろいろextendしていく方法とこちらの方法で迷ったんだけど、extendする方法だと、freezeされた配列が渡されてきたときにエラーにせざるを得ないのと、この方法なら、同じ配列を雛形にして何度もMUiオブジェクトを作れるというメリットがある。

そしてDOMにはイベントのAPIで、AddEventListenerというのがあるので、ちょちょいと実装しました。これといって特筆することはないです、単に、第一引数にイベント名を取って、イベントが呼ばれたらブロックが実行されるだけなので。

二つ目のイベントの

(window / 'button').add_event_listener(:click){
  p 'clicked!!'
}

window / 'button' というやつは、「windowウィジェットの子の中で要素名がbuttonのもの」という意味です。最終的にはCSSセレクタまがいなことが出来れば、と思ってる。少なくとも#.くらいは使えたほうがいいかとか。今は最初にマッチしたものを返してるだけなんだけど、jQueryって、複数返って来た時に、呼ばれたメソッドを各ウィジェット毎に繰り返し適用してるよね?あれ便利だけどどうなのかな。

…というわけで


実行したらこうなります\(^o^)/ポイントとしては

  • 配列でいいんだし、複雑なのは外部からYAMLで流しこめばいいでしょ
  • イベントのバインドはらくらく

意外とメリットが少ない…
もちろんMUiプラグインをgtk以外のものにすればいろいろ応用がきく、というのはちゃんと視野に入ってますよ。例えばまだ全然できてないけどマルチプロセス用のプラグインを指定すれば、gtkの時と全く同じようにマルチプロセスになるとか、ね。




・・・




・・・




・・・




やばいなんか微妙な気がしてきた大丈夫かこれうあああああ^p^

2011年4月30日土曜日

#mikutter 0.0.3.2

ubuntu nattyリリースおめでとうございます!ありふれた操作でセグフォする化石みたいな古いRubyGtkを同梱しているnattyちゃんに祝福のつばを吐きかけましょう!!!!!1234ubuntuのリポジトリはRubyGtkの博物館d
(#^ω^)「ubuntuの関係者のものですが」
ヽ('ω')ノ「いやあああああああああごめんなさいいいいいいいいいい^p^」
# こらそこdebianとかマジレスしない
  • ミュートしたユーザが起こしたアクションに関する通知も表示しないようにした
  • JSONライブラリをうまくロードできていなかった
  • SQLiteプラグインを廃止
  • Twitter検索APIのマイナーチェンジに対応
    • やっとお前ユーザID送ってくれるようになったんか…
  • 自分がふぁぼ・RTしたつぶやきを一番上に上げない設定を追加
    • デフォルトで有効です。従来の動作に戻すには設定→表示から。
  • ubuntu 11.04(nattyなんとか)でRubyGtkがクラッシュする不具合修正
さて、死月はmikutterを一ヶ月止めるくらい忙しかったお陰で?GWはたくさん休みがあります。具体的にどれくらい休みがあるかTwitterで言ったら今フォロワー724人から命狙われてます!!!!!
男はTLに出たら724人の敵がおるんや
なので具体的には言いません!だけどいろいろできそうです!予定もあんまりないし^q^
まあしかし…MUiの設計をある程度実装に落としこみかけて終わりそう、とも思います。ともあれ纏まった時間がとれるので、いろいろやりたいね

2011年4月29日金曜日

SQLiteプラグインの消失 - DEAD END -

標準プラグインのsqlite.rbは、つぶやき、ユーザ、リスト、ふぁぼを恒久的に保存するためのプラグインで、SQLiteなので他の言語やプログラムでも気軽に統計などを取ったりして遊べる、一度取得したツイートをデータベースから取得するのでAPI消費が緩やかになるなどのメリットがある。

最近うちのmikutterが遅くなってきてて、何があったのかなと思ってたら、このSQLiteのファイルが250MBにまで膨れ上がってた。当然これを消すとサクサク動くようになる。

SQLiteプラグインの最適化

・・・では、sqliteプラグインを削除すればいいのかというとそう簡単に諦めません。
従来のみくったーでは、データベースの書き込みは別スレッドで遅延実行してた。これによって並列実行され、表側には負荷がかからないと思い込んでいたのが全ての間違いで。SQLiteは結局、Rubyで実装されているわけではないので、アクセス中は他のスレッドは動かない。ということは、結局挙動的にはメインスレッドで動いてるのと似たようなことになる。一方TwitterAPIで問い合わせに行くと、IO Waitになるのでその間他のスレッドが実行されるので、体感負荷はこっちのほうが小さい。これは0.0.3.0までの話。

どうしたものかといろいろ調べていたら、そういえばトランザクションの処理が荒いままだということを思い出した。
SQLiteは明示的にトランザクションを張ってなければinsertやupdateの前後でトランザクションを張ってしまう。そしてこれのコストがかなり高いので、大量に書き込むときはトランザクションを貼るというのはセオリーなんだけれど、やってなかった。
・・・というわけで、0.0.3.1では、SQLiteのexecuteメソッドに渡す引数を配列にして、Queueに入れて、一定時間キューに追加されなかったらそれらをまとめて一つのトランザクション内で書き込むという改良をした。

最適化の結果

結果どうだったかというと、体感速度は変わらず。ただし起動は3秒速くなった。あとつぶやきを短時間に大量に受信したときにも負荷は落ちているはずで、一件あたり0.1秒ほど速くなっているみたいなんだけど、体感速度変化なし。
結局のところ、データが多ければ処理は遅くなるはずで、俺のようにいっぱい溜め込むと読み込みですら足を引っ張ることがあると。

考察

mikutterが流速速いと遅すぎて使い物にならないのは周知の事実だけれども、流速が速いほうがためこまれるつぶやきの量は多くなるわけで、余計に事態が悪化していく。では、他のツイッタークライアントはこういった問題にどう対処しているかというと、そもそも溜め込んでいないのでこういう問題とは無縁というのがほとんど。
それもそのはず、mikutterでも、ほとんどのSQLiteキャッシュは一度も使われず、ある程度昔のレコードになると全く使われない。
更に、再起動するまではmikutterコアが一定期間メモリキャッシュをするので、大抵SQLiteにまで問い合わせがいくことはなく、基本的に問い合わせはレコードが見つからずに終わることが殆ど。

SQLiteプラグインの消失 - DEAD END -

このことから、現状のmikutterでは、SQLiteによる恒久的キャッシュの意味は薄いんじゃないかなと考えて、残念だけど0.0.3.2では標準プラグインからは降格させる予定。今はうちのgithubで元気にしているよ。mikutterで統計とか取って遊んでた人はこれで引き続き使えます。

mikutterって、昔APIが少なかったころ、またTwitterが不安定だったころに設計されていて、できるだけTwitterにアクセスしなくていいように、Twitterを信頼しないという思想のもと書かれているところが多いんだけど、最近ではそんなにTwitterも不安定じゃないし、そういうところは一度見直したほうがいいと思ってる。Twitterも大きくなったよなぁ。

2011年4月23日土曜日

#mikutter 0.0.3.1

今週はこれ!!

  • RubyのライブラリやRuby本体が原因でクラッシュした後の起動でバグレポートを送ろうとするとお礼を言われないどころか発狂されるバグを修正
  • bit.ly APIのv3に対応
  • 1回の投稿に複数のURLが同時に記載されている場合に、全て抜け落ちる不具合
    • bitlyよくもやりやがったな
  • SQLiteのデータ書き込みを遅延させ、トランザクションの数を節約するようにした
    • 数秒速くなったがあまり意味はなかった
ちなみに、先の0.0.3.0には、上記修正は含まれていません。
GWはMUiに舵を切って、mikutterの高速化のためにがんばるかな…

#mikutter 0.0.3.0

不安定版リリース!!!おめでとう!!!!!
えっじゃあ四桁目はなんなのかって?ウィークリーリリースだよなめんな!あれは動けばラッキーの毎週とりあえずtarに固めてるヤツです!!!もっというとやってますよっていうアピールです!!!!!それが安定していると、こうやって桁が上がるんです!どんなに重くてもな!!!つまり中身は0.0.2.13と同じだ!!!!11

これが0.0.2.0 (r182)からの変更点。繰り返しになるけど。

  • mikutterコア
    • フィルタの呼び出しの大幅な高速化
    • 公式RT、ふぁぼられの通知の仕方を細かく設定できるようにした
  • プラグイン
    • 各種タイムライン
      • つぶやきを表示するかどうかを判断するフィルタ
    • notify
      • 被公式リツイートの通知
    • profile
      • ユーザのミュート機能
    • gui
      • ふぁぼられた時の負荷低減
    • extract (new!)
      • つぶやきの抽出機能。いわゆるエゴサーチタブが作れる
  • その他
    • mikutterのアイコンが完成しました (thanks @soramame_bscl)
    • ruby 1.9.1 及び 1.9.2 に対応。見たところ3倍速程度で動きます
    • 新たにリツイートなどの通知音を追加
    • 効果音の提供を受けた (thanks @seibe2)
    • コミッタが増えたヾ(@⌒ー⌒@)ノ
    • なんかいろんな所に広がっててやばい
    • 風邪引いた
    • 眠いし仮眠とろうかな
    • でも明日起きられなくなるしな
ウワアアアアアアアアアアアアアアアアアアアアアアア少ないよおおおおおおおおおおおおおおおイヤアアアアアアアアアアアアアアアアアアアアアwwwwwwwwwwwww
バグ修正書かなかったらほんと何もやってないみたいwうぇwたしか前のリリースが12/25とかだった気がするんだよね。てかさっき気づいたけど各tar玉にリリース日併記しとけよ俺マジ糞システムだな
さて1年の1/3もの期間を使って何をしたかというとですね 直ちに人体に影響のないものを片付けたりしてたんですよ、ええ

今後の展望としては
  1. GUI Toolkitの抽象レイヤーを入れて、Gtk以外のバインディングを書く余地を与える(プラグインをGtkに依存させない)
  2. フレンドTLプラグインなどを削除して、全てextractプラグインにやらせて、どこぞのツイッタークライアントみたいなかんじにする
  3. 1に絡むけどTLをCairoでレンダリングすることで高速化を図る
  4. コンテキストメニューとか、ショートカットキーとか、そういうのをカスタマイズできるようにしたい
というところですね。ちょっと見た目もいらえば華々しい変更に見えるかな

2011年4月17日日曜日

#mikutter 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式をやりとりするだけなのでどんな言語でも使えるものになる予定で、ライブラリの層からも世界征服を企んでいますん。やりすぎかな。ちょっとまだパッチ投げてもらったりできるほどになっていないのでまあもうしばらくしたらおらに力を分けてくれえええ

2011年4月4日月曜日

新しいUIについて色々考えてる

考えてる途中のことを書き散らしてます。以下ただのつぶやきです。
現在のmikutterは、Gtkに完全に依存している。
例えばプラグイン内でGtkライブラリを叩いていたり。

もともと、guiプラグインがそういうものだったし、当たり前といえば当たり前のこと。というか、暗中模索の中、開発速度を稼ぐために意図的にやった部分がある。
ただ、最近いろんな環境で使われるようになって、様々な問題が出てきてしまった。

  1. Gtkが事実上使えない・使用に難がある環境(Mac OS、各種スマートフォン)では、mikutterが使えない
  2. あるRubyGtkやRubyのバージョンの組み合わせでは、それらのバグを踏んでSegmentation Faultになることがしょっちゅうあるらしく、作者自信が自虐ネタでふぁぼを稼ぐ深刻な事態へと発展している
  3. Gtkに強く依存しているために他のGUI Toolkit(Cocoa、Qt等)のバインディングを書きづらい
  4. 強いGtk依存のため、RubyGtkの知識がプラグイン開発の事実上の絶対条件となり、の敷居を上げている
Gtkをさも悪者のように書いているように見えるかもしれないけれど、最初にQtを選んでいたらこの部分がQtになっただけの話。安定したものを使っていれば2は無かったかもね。

で、じゃあいっそかなり開き直って、そこを抽象化してしまいませんか、という話。

どうするかというと、特定のルールに従ったデータ構造(DOM)を与えると、それをUIとしてレンダリングする、というもの。
例。
dom = [:vbox, [:label "hello"], [:button, {:id => :btn1}, "exit"] ]


とまあ、こういうありきたりなRubyのオブジェクトを

mui = mUi([:window, {:width => 320, :height => 240, :id => :main}])
mui << dom

とかすると、そういうウィンドウが表示されると。ご察しのとおりHTMLをめちゃくちゃ意識してます。
以下、mUi()は受け取った配列に色々Mixinとかをextendしまくって魔改造するものか、なんかでWrapして委譲するよなものだと思って読んでください。

Rubyの配列は、MIKU LangでS式として取り扱えます。つまり、windowとかlabelとかいう関数が定義されたコンテキストをつくってそこでこの式を評価すると。その関数の実装次第でQtにしたりCocoaにしたりできる、よね。
 MIKU Langでのコードでありデータのこと。ただの配列が実行出来るんだよ(Lisp)

実は、MUIというクラスを定義して、それの中身で別々のGUI Tool Kitを叩く計画は初期からあった。けどもういいや。先に上げたのとの違いは、それがクラスなのか、配列なのかというところ。配列にしておくことのメリットは:

  1. DOMが簡単に保存できる。なので、Gladeみたいなことが自然にできる
  2. Rubyのコアオブジェクトを使っているので、メソッドは誰でも知ってる
  3. JSONに翻訳可能なので、別プロセスに渡せる。
  4. だいたいどんなプログラミング言語にもありそうなデータ構造を使っているため、言語の壁を越えることが出来る
夢がひろがりんぐ\(^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バインディングを作れるかもしれない、ということ。

一応書いておくと、マルチプロセス化しますと言ってるわけじゃなくて、そういうこともできるね、という話。でも結構やる気。mikutter mobileあるで


イベント渡す方法とかは、DOMのアレでいいんじゃないかな普通に


mui.getElementById(:btn1).addEventListener(:click){ exit }

アツいなこれは。今の時代ならjQueryリスペクトしてもいいかも。DOMはW3Cがちゃんと規格化してた気がするから興味があったら調べてくだしあ、おれはあんなのよみたくない

なんかこういうのありそうで探してるんだけど、うーん。オススメあったら俺が愚かな車輪の再発明するのを止めていただけると嬉しいけれど…。

別プロジェクトでこういう事やってmikutterに取り込もうと思ってる。仕事終わったら詰めますね。

2011年4月1日金曜日

謝罪

やあごきげんようエイプリルフールなのに何もできなくてヽ('ω')ノ三ヽ('ω')ノもうしわけねぇもうしわけねぇ
さてさて、うちのサイト(mikutterではない・あれ存在意義ないし潰そうかな)のアクセス数どれくらいあったかなー?

toshi@lime:/tmp$ wc -l apache.log
16188 apache.log
toshi@lime:/tmp$ grep /img/api/ apache.log | wc -l
14150

ギャアアアアアアアなんじゃこりゃあああ!!! /img/apiとかいう意味の分からないディレクトリに異常にアクセスがあるわー、なんじゃこりゃー!この下png画像256枚が入ってるだけで特に何もないんだけどなー

toshi@lime:/tmp$ ruby -e 'p 16188 - 14150'
2038

おかしいおかしいおかしいwwwwこの比率は間違いなくおかしいwwww
さーてーはー俺が多忙なことにつけ込んで田代砲だなぁ?ふぁぼテロはまあ見逃してやってるがこれはちょっと 度 が す ぎ る ぞ !通報してやるううう!!!おまわりさん!!!!!犯人の人数は

toshi@lime:/tmp$ grep /img/api/ apache.log | awk '{print $1}' | sort | uniq | wc -l
213

ピャアアアアアアアアアアアアアアアアアアアアアアアwwwwwwwwwwwwwなんだこのBOTnetはあああああああああああああwwwwwwwwきままりないwwwwあれwwwwきまわりないwwwwなぜか変換できないwwwwwwうぇwwwwwww

オーケー落ち着こう

今日はエイプリルフールだ。そう、つまり、冗談が何かを弁えていないアレなやつが、何を血迷ったか俺に田代砲を打ってきたんだ。違いない。つまり、4月1日のアクセスがほとんどのはずだ

toshi@lime:/tmp$ grep /img/api/ apache.log | grep '1/Apr/2011' | wc -l
2071

ピャアアアア…あれ?
14150アクセスのうち、4/1は2071件だけ…?

toshi@lime:/tmp$ grep /img/api/ apache.log | grep '1/Apr/2011' | awk '{print $1}' | sort | uniq | wc -l
82
toshi@lime:/tmp$ grep /img/api/ apache.log | grep -v '1/Apr/2011' | awk '{print $1}' | sort | uniq | wc -l
164

およよ!?3月と4/1では丁度倍も3月のほうがユニークビジターが多い…!?(しかも/img/api以下の)

なんじゃあこりゃあああ!!
ログを一つ見てみよう

192.168.0.3 - - [01/Apr/2011:02:24:55 +0900] "GET /img/api/B6.png HTTP/1.1" 200 3181 "-" "Ruby"

なんだUserAgentのRubyって!畜生反撃してやる!

toshi@lime:/tmp$ eternal-force-blizzard 192.168.0.3

ってちょっと待ったぁぁぁぁ!!!!
このマシンのローカルIPじゃねえかwwwwwこれマジでやばいんじゃないかwwwwww乗っ取られてるwwwwww

よーしちょっと落ち着こう

"/img/api" で、HDD内をgrepすれば、どこかにここにアクセスしてくるプログラムがあるはずだ。もはやここまで、年貢の納めどきだぁ!正体を表せ!!!(プライバシー保護のためにディレクトリ名は一部加工したよ!)

seminole% find / -type f -print | xargs grep "/img/api"
*****/mikutter/core/mui/gtk_mumble.rb:        "http://toshia.dip.jp/img/api/#{Digest::MD5.hexdigest(url)[0,2].upcase}.png"
*****/mikutter/core/mui/gtk_mumble.rb:          Gtk::WebIcon.local_path("http://toshia.dip.jp/img/api/#{Digest::MD5.hexdigest(url)[0,2].upcase}.png") }

うおおおおなんだこのmikutterとかいう悪しきアプリケーションは!めちゃくちゃあからさまに書いてるじゃないか!!!!!ヒーーーー!!!!

Rubyならわかるぜ…Redmineで差分を見てやる!!!



にょほおおおおおお!!!!ちゃっかり最近のリビジョンで追加されてる・・・違う!改良されただけだ!アイコンが16種類から256種類に拡張された形跡がある!なになに・・・2010-03-19!?去年もやらかしていただと!?きみたちは最初からボクの手のひらで踊らされていたんだ

どれどれ・・・つまりこのメソッドは
  1. 4/1の間は、俺のサイトの/img/api以下の画像のURLを返す
  2. 3月の間は、呼び出されるたびに(日/100)の確率でフェッチしてローカルにキャッシュを残すことにより、普段から使ってくれているユーザの皆さんにはエイプリルフール期間前にキャッシュを取り終わらせることで、サーバにもユーザにも無理なくエイプリルフールに移行できるように工夫されている
ということかぁ!一体俺のこの日のために何ヶ月もかけていろんな所からライセンスとか若干気にしながらまあ今日だけだ許せとかちょっとそういう部分もあったけど厳選したえ萌ミクアイコンを一体どんなことに使ったかは知らないが許さないぞ!この作者はとんでもないヤツに違いない!つまり今回の件で、IPアドレス基準なので確かなことは言えないけれど
  1. 213人以下の潜在的なmikutterユーザがいる
  2. そのうち、3/1から3/31の間にmikutterを一度でも使ったユーザは164人以下
  3. 更に、4/1だけに使ったユーザは49人程度。
ということか!

このうち、3.のユーザは、今回の騒ぎで面白そうだから入れてみた人と、知ってたけど何らかの理由で使ってなかったが、今回様子を見るためにちょっと起動してみた人。
2のユーザは、3月中に使ってるわけだから、一見さんかアクティブユーザの何れか、ということになるから、まぁ100人程度のアクティブユーザは確実にいそうだ。

去年の今頃のユーザはたった10人前後だったのが、アクティブユーザが10倍以上に膨れ上がっているッ!!こんなアレなTwitterクライアントを使ってくれてみんなありがとう!!これからもがんばるよ!!!

いい話風にまとめちゃいましたわぁ(ドヤ

2011年3月20日日曜日

#mikutter 0.0.2.12

ピャアアアアアアアアアアwwwwwwww今週リリースしない予定だったけど調子でないから休憩中にバグとか直してたらつい時間をかけすぎてリリースしちゃうwwwwwwww楽しいfixがwwwwwwポポポポーンwwwwwww

よかったこと
mikutterのアイコン完成
実はsoramame_bsclにアイコン作るように去年のはじめにお願いしてて、半年放置されたからヤツの落書きを勝手にアイコンにしてただけだったんですwwwwやっとだよwwwwウェブページのファビコンにもしたよ!やったねたえちゃん!

よくなかったこと
キャッシュがスレッドセーフじゃなかった
ギャアアアアアアアwwwww俺SUGEEEEEEEEEEwwwwwwww

特定条件を満たすつぶやきをふぁぼると落ちる
ひでぇぇぇぇwwwwwww

リスト取得するときにたまに落ちてた
ウワアアアアアアアアアアwwwwwwwもうかくのめんどくせえよおおおおおwwwwww

0.0.2.10以前を使ってる人は、ここのところ全く機能追加できてないお陰で安定性上がってるっぽいので是非バージョンアップしましょう。どうせおちるんだろうけどねwwwwうわあああ死にたくないよおおおwwwwwwwww

2011年3月13日日曜日

#mikutter 0.0.2.11

  • 不具合修正
    • ruby 1.9.2を使用している場合、頻繁にSegmentation Faultが発生していた
      • →rubyか周辺ライブラリのバグを踏んでいたよう
    • notifyのリツイート通知の時に、原文が2回表示されていた
  • 最適化
    • アイコン画像プリフェッチ
殆ど何も変更できてないわけだけれど、これが0.0.3.0になるんじゃないかな、落ちないので。
まあリリースして1日以内にクラッシュするような不具合が見つかるというのを10週連続でやってるんだけどね!

あとレンダリング高速化しようとしてやっぱりやめました。もうちょっと時間をかけて大規模なのをやります今度。

それから、mikutterのサイトのリリースノートやめてこっちにしますんで!だってあのリリースノートRSSにも対応してないただのHTMLなんですもの…(´・ω・`)

2011年3月6日日曜日

#mikutter 0.0.2.10

リリースしました。出先からなので適当に

○プロフィールを開いてすぐに閉じる
とクラッシュする
○Mumbleオブジェクト作成中に落ち ることがある

うけるヾ(@⌒ー⌒@)ノまじこれだけ

あと少しパフォーマンスを上げようとして、ああ、今回もだめだったよ。

そろそろ根本的な解決をしていきたい。mikutterのコードも当社比リファクタリングが進みきれいになったので、マルチスレッドでGtkのレンダリングをしても死なない気がしてきた!ちょっと頑張って見るかな。

あと1.9.2で特定リビジョンがうごかんと言われて試したら、うちでは全バージョンが動かなかった!どうしてこうなった!一応サポートしてるのは1.9.1なんだけど、これもかっこ悪いのでぽちぽちなおしますね…

いつ2次元に旅立っても大丈夫なように@Phenomerさんにコミッタになってもらいました!だけど今クールいくといろいろひどいことされそうなのでもう少し娑婆で頑張る!

2011年3月2日水曜日

streamingプラグインの最適化

streamingプラグインはuserstreamを実現するためだけのプラグイン。(core/addon/streaming.rb)

UserStreamは大量のデータが落ちてくることがしばしばあり、フォローが多いと秒間に数個からヘタをすると数十個のイベントが落ちてくることもあるかも知れない。
(ここでつぶやきではなくイベントと言ってるのは、フォロー関係の変更やDM、favなども落ちてくるので)
mikutterでは、正確にはわからないが、まあフォローが1000を超えていたら絶対に動かないだろう。これは、流速が処理速度を超えるから。
そういう極端に速い環境を切り捨てるのは仕方ないにせよ、全員が定期的に呟いている訳でもないので毎週火曜夜に流速が極端に速くなるということもあるかもしれない。なので、できるだけ対策をしてみようと思った。

これの33行目くらいから変な魔術を使ってる。

# イベントを定義するためメソッド
    def self.define_event(event_name)
      type_strict event_name => tcor(Symbol, String)
      queue = Queue.new
      service = nil
      Thread.new{
        sleep(1) while not service
        loop{
          datum = queue.pop
          yield(service, datum)
          sleep(1) } }
      define_method("event_#{event_name}"){ |json|
        type_strict json => tcor(Array, Hash)
        service ||= @service
        queue << json } end

    # favられイベントの定義
    define_event(:favorite) do |service, json|
      by = service.__send__(:parse_json, json['source'], :user_show)
      to = service.__send__(:parse_json, json['target_object'], :status_show)
      if(by.respond_to?(:first) and to.respond_to?(:first) and to.first.respond_to?(:add_favorited_by))
        to.first.add_favorited_by(by.first, Time.parse(json['created_at'])) end end

event_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速い時に起動が数秒遅くなってるんですが、これは起動直後にウィンドウに夥しい量のつぶやきが放り込まれて固まってる間にたくさんイベントが発生しているからに他ならないんですよ。

一方、本当に重くしてる原因は他にあると思うので、そっちを潰すのが先かなぁとも。やはり動きが良いのは良いことです。

2011年2月27日日曜日

#mikutter 0.0.2.9

このようなことを2週前に書いたわけですね

いいこと思いついたコミットしたことをブログでまとめれば毎週一回の更新という今キメた目標を達成できるんじゃないかやっほーい俺ってちょーてんさーい!

で、先週は体調崩してリリースをしなかった、と。
でもそんなの今年初なんだ信じてくれぇ!

ksg
今回の更新について。

効果音の追加

設定→通知から、イベントが発生したときに再生する効果音を設定できます。これに結構前から「フォローされたとき」「リムられたとき」UserStreamに対応した時からは「ふぁぼられたとき」が追加されてました。他のTwitterクライアントのUserStream対応が進まない中、mikutterの対応速度なんと3日だったわけですよすごいでしょ褒めろ
で、今回はfavられた時とReTweetされた時の効果音を追加しましたが、残念ながらReTweet時の通知はまだ実装されておらずリプライ扱いになっていることに気づいたわけだな。ここでもmikutterのカスっぷりが遺憾なく発揮されたわけであります。
更に、@seibe2さんから効果音の提供もいただきました。みんなでmikutterの感染を広げていきましょう!!!!!!!!!!!!!!!!^q^

コンテキストメニュー(右クリックメニュー)の内部仕様

前はコンテキストメニューが独自のフックみたいなのをもってたのを、今回イベントフィルタで実装しなおしました。
これで、前より気楽にコンテキストメニューが拡張できる予定です。更にコンテキストメニューの項目にショートカットキーを割り当てられるようにして、現在ハードコーディングしているショートカットキーの項目をプラグインから気軽に増やすことができるようにする予定です。
ついでに並び替え、罫線の挿入もできるようにするつもりですが、まだこのあたりは終わっておらず、現在コンテキストメニューには罫線が表示されません。あんまりメニューの数多くないので我慢してくだしあ
ここで言っているコンテキストメニューとはつぶやきのそれのことで、タブや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.3に、と言いたいところだがなんか早速死亡フラグが立っててアレ

2011年2月12日土曜日

#mikutter 0.0.2.8

いいこと思いついたコミットしたことをブログでまとめれば毎週一回の更新という今キメた目標を達成できるんじゃないかやっほーい俺ってちょーてんさーい!
(前Tumblrに書いてたのをいつからか完全にすっぽかすようになった)

http://mikutter.hachune.net/

ksg
最近全然ぱっとしたことが出来てないんだけど、これは忙しいからというよりは安定化に舵を切っているからでしてごにょごにょ

どうでもいいけどcore/mui/gtk_mumble.rbはmikutterでは2番目に汚いファイルで、600行くらいあったんだけど、今回ふぁぼられ・被リツイート(まとめてVoteと呼んでる)を扱うGtk::MumbleVoteと、アクティブ(選択)の概念を管理するためのGtk::MumbleSelectに分けました。結果、この2つに関してはユニットテストが書けたし、コード量も結構減ったのでよかった。

同じようにコンテキストメニューのところも分離したあと、ショートカットキーと統合してコンテキストメニューでできることにショートカットキーを割り当てれるようにしよう。もうコンテキストメニューをプラグインから追加する方法はあるので。

2011年2月6日日曜日

複数ファイルからなるプラグイン

今まで、プラグインは、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をつかえるらしいです。ある人がやってくれました。

これからももっと拡張しやすくしていきたい


2011年2月4日金曜日

ubuntu 10.04で、mikutterをruby1.9.1で動かす方法

ubuntu10.04で動かすのは実は結構お手軽。ただし、ruby-gnome2の1.9.1用のは用意されていないので、自分でビルドする必要がある。他のubuntuでは通用しない方法です(後述

$ sudo apt-get install checkinstall ruby1.9.1-dev
$ sudo apt-get build-dep ruby-gnome2
$ sudo apt-get install rubygems1.9.1 libopenssl-ruby1.9.1
$ sudo gem1.9.1 install pkg-config
$ sudo gem1.9.1 install ruby-hmac
$ wget -O - http://jaist.dl.sourceforge.net/project/ruby-gnome2/ruby-gnome2/ruby-gnome2-0.90.5/ruby-gtk2-0.90.5.tar.gz | tar zx
$ cd ruby-gtk2-0.90.5/
$ ruby1.9.1 extconf.rb
$ make
$ sudo checkinstall
$ cd ..
$ svn co svn://toshia.dip.jp/mikutter/trunk mikutter
$ cd mikutter
$ ruby1.9.1 mikutter.rb

こんなかんじだったとおもう(最小構成)。ruby-gtk2のビルドのためにruby-devいれたり、hmacの1.9.1用のがaptで用意されていないから本来必要ないgemを入れたりとなかなか。

1.9にしたら相当早くなるし、メモリもぜんぜん食わない(当社比)。ので結構おすすめ。起動も3倍早くなりますし

ただ、まだ1.9のほうは1.8に比べたら落ちることがあるみたいなのでそこはご容赦。だけどいままで重くて使えないと言っていた人でも、これなら使える!という人が出てくるんじゃないかな。

10.10入れたマシンもってないんだけど、まあ上手く動かないと。後述とか書いたけどごめんもってないからわからない
情報募集中です

追記
10.10専用スクリプト
http://twitter.com/Phenomer/status/33189686042165248
いけるらしい(未確認)

2011年1月15日土曜日

自動投稿(Postクラス)

Twitterクライアントの基本はつぶやくこととつぶやきを見ること。mikutterでは、Post#update を使ってつぶやけます。Post#postというエイリアスもあります。

Postクラス http://mikutter.hachune.net/rdoc/classes/Post.html

でも、updateは内部ではdefine_methodを使って定義しています。だからRDocには載っていません。載せ方書いてあったけどうまくいかなかった
このPostオブジェクトはもともとつぶやきの投稿のためのものだったんだけど気づいたらAPIのインターフェイスになってました。だからfriend_timelineとかも実はこのクラスを使って取得するんだけど、普通はイベントを使ってください。そのうちServiceに名前変えたいと思ってたけどそろそろ引っ込みがつかなくなってきました

肝心のupdateの使い方ですが、引数はハッシュ1つで、symbolで最大3つの引数を与えられます。

  • :message つぶやきの本文をStringで。必須
  • :replyto リプライ先のメッセージ(in_reply_to_status)。Messageのインスタンスを渡す
  • :receiver リプライ先のユーザ(in_reply_to_user)。このユーザに宛てられる。本文に@そのユーザ名が含まれているかreplytoがセットされていれば自動的に補完される。Userのインスタンスで。

あと、実際の投稿は勝手に別スレッドでやります。気をつけてください。
ブロックを渡すと、(状態, 補足説明)を引数に取って以下のタイミングで呼び出されます。

  • (:try, str) コネクション開始。strは引数の:messageの値。
  • (:success, message) 投稿成功。messageは投稿したメッセージのMessageオブジェクト。
  • (:fail, exception) 失敗。これが渡ってきたらもうリトライしないということ。exceptionには発生した例外オブジェクトか、不正なHTTPコードが送られてきた場合はnilが渡される。
  • (:retry, exception) 失敗。ただし、後でもう一回接続を試みる(現在は1秒後に決め打ち)。

以下の例は、よるほーするプラグインです。

Module.new do
  plugin = Plugin.create(:yoruho)
  plugin.add_event(:boot){ |service|
    Thread.new{
      yoruho = nextyrhtime
      loop{
        nex = yoruho - Time.new # 次回のよるほーまでの秒数
        if(nex <= 0.5)
          say_yoruho(service)
          sleep(43200) # 半日待つ
          yoruho = nextyrhtime
        else
          sleep(nex / 2)
        end
      }
    }
  }

  # 次回のよるほー時間を取得
  def self.nextyrhtime
    now = Time.new
    result = Time.local(now.year, now.month, now.day, 0, 0)
    while result < now
      result += 86400 end
    result
  end

  # よるほーとつぶやく
  def self.say_yoruho(service)
    service.update(:message => 'よるほー'){ |stat, value|
      if stat == :success
        reflection(service, value)
      end
    }
  end

  # messageがよるほーに成功していたらドヤ顔をする
  def self.reflection(service, message)
    if is_pitari?(message[:created])
      service.update(:message => '決まったァ…(ドヤ')
    else
      service.update(:message => 'なん・・・だと・・・')
    end
  end

  # timeが0時0分0秒ならtrueを返す
  def self.is_pitari?(time)
    time.hour == 0 and time.min == 0 and time.sec == 0
  end

end

適当な実装だけど、だいたいこんなかんじ。時間の判定がやたら汚いけど、まあこんなふうにとっても簡単に実装できます。
ちなみに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で渡してあげればいいと思います。同じシンボルを渡せば同じインスタンスを返しますが、長ったらしいので変数に退避するのが望ましいです。
あと、関数のスコープが別のプラグインとぶつかるのが嫌なので、無名モジュールで囲ったりしてます

Module.new do
  plugin = Plugin.create(:myplugin)
end

mikutterの中では、TLにつぶやきが流れてきたりするたびに「イベント」が発生します。このイベントを投げる/受けることで、プラグインはコアや別のプラグインとコミュニケーションをとってるんです。
例えばフォローしてる人がつぶやいたらupdateイベントが呼ばれ、そのイベントをlistenしているプラグインが起動されると。
ごたくはともかく例。

Module.new do
  plugin = Plugin.create(:myplugin)
  plugin.add_event(:update){ |service, messages|
    messages.each{ |m|
      puts m.to_s
    }
  }
end

イベントをリスンするにはPluginTag#add_eventを使います。詳しい使い方はRDocにかいてあるけれど見たとおりで、updateイベントが発生するとブロックが実行されます(イベントのコールバック)。
イベントごとにブロックの引数が決まっています。それも上のリンク先に書いてありますが、updateイベントの場合はPostクラスとMessageクラスの配列を引数に与えられることになっています。
Messageクラスはつぶやき1件を表現するクラスなので、これだけでTLをターミナルに書き出すプラグインの出来上がりです!短い!
ひとつのプラグインにいくつでもイベントをリスンさせることもできます。リプライも表示させるならこんな感じ

Module.new do
  plugin = Plugin.create(:myplugin)
  plugin.add_event(:update){ |service, messages|
    messages.each{ |m|
      puts m.to_s
    }
  }
  plugin.add_event(:mention){ |service, messages|
    messages.each{ |m|
      puts m.to_s
    }
  }
end

ね、簡単でしょう?思いついたとおりに描いていけばいいんです。

大事なことは、イベントは必ずメインスレッドで実行されるということです。mikutterはメインスレッド以外でGtkを叩いてはいけないことになっています。だからイベントのコールバック内ならGtk関連の操作をしてもOK。ただし、あまりにも時間のかかる処理をここでしてしまうとmikutter全体のレスポンスが悪くなりますね

イベントの概念は、Twitterに例えたら、自分がPluginTagのインスタンスで、イベント(updateとか)が他人のアカウントで、add_eventとかでフォローする感じ。解りやすいかと思ったけど文字にしたら解り難かった。

まああれだGtkで言うところのシグナルですふつうに

まとめ

mikutterプラグインの根幹となる概念「イベント」についてちょっと触れました。短縮URLなど一部のプラグインを除けばほとんどのプラグインがこのイベントを使っています。
毎回こんな感じで書いていって、あとからマニュアルみたいに使えたらいいなってだったらちゃんとかけよおれ

きょうはなんかちょっと冷たいものが歯にしみたので歯をよく磨いて寝ます。時間も遅いから校正はやめとく おやすみ