Category Archives: tumblr

tumblr

tumblr MOO minicards

去年の10月にroppongi.4Uという名の飲み会に行きました。4U好きの六本木周辺で働いてる人たちの集う会と銘打たれてはいたもののそこまでみんな4Uを使っている訳でもなく割と普通の飲み会でした。ただひとつのことを除いて。

なにが普通でなかったかというと、rosyposy flyflap!のひとがtumblrにpostした写真から厳選した女の子写真(なぜなら4U – beauty image bookmarkingというコンセプトのサイトだからです)を集めて、それをpocketerでカードにしたものを持ってきていたのです。

その場にいたみんながその天啓と蛮勇とに驚嘆した後、30種類くらいあったカードを順に交換しながらこれがかわいいなどと言いいつつひととおりチェックして、それぞれの(女の子の)好みに合わせてカードをもらいました。ただこのカード、注文の単位が100枚単位なので、roppongi.4Uで配ったところでまだまだたくさん余ります。残りはどうするのか聞いたところ、普通に勉強会で配りますよ、という返事が帰ってきました。実際、後日クックパッド&カカクコム共催・勉強会のときにFuture Insightのひとにこのroppongi.4Uのカードを渡してました。たしかに相手によっては話が弾む(こともある)ので悪くないかもしれません。

そこで今回自分もtumblrの写真を使ってMOOのカードを作ってみました。

moo cards

これは楽しいです。自分のtumblrには一度は自分の好みに合っていたことがあるはずの写真だけが入っているので、そこからカードにしたいものを選ぶのが楽しくないはずがありません。ああこんなのあったよね、と回想に耽りながら、これは人に渡したときに相手が喜んでくれそう、話が弾みそう、うけがとれる、かっこいい、とりあえず自分が好き、そう思えるものをピックアップしていきます。ただ自分の好みに合っているようなものでもこういうのは人に渡すことを考えたらやめておいたほうが無難だと思います。

どうやってTumblr写真をMOOに持ってくるか

MOOがTumblrの写真を直接読み込んでくれたらいいのですが、今のところそういう機能はないので一度Flickrにアップロードしておいたりする必要があります。roppingi.4UのカードはTumblrのAPIを使ってダウンロードした、と聞いた気がするのですがiviewを使っているとAPIがわからなくても何とかなります。

自分の場合は普段iviewの設定でSave to photo albumをonにして使っているので
save to photo album
reblog/shareしたときに同時にiPhoneの中のphoto albumにも写真が保存されるようになって、カメラロールがreblog写真で占領されるようになります。
Img 7168
そうするとiPhotoと同期をとったときにreblogした写真が全部iPhotoに取り込まれるようになります。これは便利な一方で、自分が撮った写真と混ざってしまうのでちょっと困るのですが、iPhotoでApple iPhoneで撮った写真のスマートアルバムを作ると少し整理しやすくなります(アプリからiPhoneに写真を保存するときにアルバムを分けたりできるといいのですが今はできないのです)。

reblog/shareした写真がiPhotoに取り込まれたら、あとはFree Flickr eXporter iPhoto Plugin (FFXporter)などを使ってFlickrにアップロードします。Flickrにアップロードすればその写真をMOOから読み込むことができるようになります。MOOにアクセスして、どこのサービスにある写真を使ってカードを作るか選択できるようになっているので、そのときにFlickrを選べばアップロードした写真が一覧で表示されます。
moo flickr

読み込んだ写真はカードのタテヨコ比に合わせてトリミングをしないといけません。たいていの写真はカードのように細長くないので、この段階で思ってたようにはうまくカードにできない写真がけっこうでてきます。
Resize
はじめに写真を選ぶときに細長くなっても大丈夫かを意識しながら、なるべく多めに選んでおくといいでしょう。

15%ディスカウント!

というわけであなたもMOOでTumblrミニカードを作ってみませんか。
はじめてMOOを使う人なら支払いのときに2RB2CKというコードを入れれば15%安くなるそうなのでぜひ。
discount code
MOOは日本からは遠く離れたイギリスの会社なのでオンラインで作ってから実際にカードが届くまでいつもだいたい2週間かかるのが不便なところなのですが、そのかわり日本では珍しい紙質のカードになって送られてきます。1ドル96円の今なら15%引き送料込みでだいたい1,800円。日本にも同じようにカードを作ってくれるサービスがあるのでそれらを利用する手もありますが高めの値段設定なので2週間待っていられる余裕があるのならMOOがおすすめです。

tableau – Tumblrに画像を投稿するchrome extension

いつのまにかOSX版のchromiumができてて驚いていたら、いつのまにかChrome Extension HOWTO ‎(Chromium Developer Documentation)‎というページができていました。

これを読むといつのまにかクロスドメインのXMLHttpRequestができるようになっています。クロスドメインでXMLHttpRequestが使えればそれなりにいろいろできると思うので、ためしにTumblrに画像をpostするextensionをつくりました。

インストール

tableau.crx

あと新しめのchromiumが必要です。最新のsnapshotを持ってくるのが無難です。

使い方

まずchromiumを起動するときにオプションをつけてextensionを有効にする必要があります。

chrome.exe --enable-extensions

そしてtableauをインストールしてchromiumを再起動すると(しなくてもいいのかも)、chromeの一番下にツールストリップ(toolstrip)というバーが出てきます。
Public
デフォルトでは投稿された画像は公開されます。プライベートで投稿したいときはクリックするとPrivateに表示が変わってプライベートで投稿されるようになります。

現在のchromium extensionはコンテキストメニューの拡張ができません。なので、投稿したい画像を右クリックしてメニューから選んで投稿、ということができません。しかたがないのでtableauでは右クリックでのマウスジェスチャーで画像を投稿するようになっています。

Sharing

投稿したい画像を右クリックしたままぐるっと円を書くように動かすとツールストライプの表示がSharing…に変わって画像がTumblrに投稿されます。

tumblr dashboard

コード

ku’s tableau at master – GitHub

解説

chrome extensionの作り方 2009.5版
まだ書いてないです

Ubigraph+ubi.jsでリブログの流れを可視化する

仕事でちょっとネットワークの可視化をしたい場面に遭遇したので、先日果たしてtumblrにアルファリブロガーは存在するのかのあとでtwitterでkybintさんに可視化ツールをいろいろ教えてもらったのでちょっと試してみようとやってみたらUbigraphがとてもお手軽でよかったです。インストールからはじめて、自分が持っているネットワークデータを可視化する方法を理解するまで5分、はじめてでも10分もあれば自分のデータを可視化できます!

ダウンロードのページからバイナリをダウンロードします(でも悲しいことに今はOSX版とLinux版しかありません)。ダウンロードするページにインストール方法、起動方法、サンプルコードの実行方法が載っているので、とにかくそれをコピーしてターミナルに貼れば本当に何も考えないでもサンプルが画面で表示されるところまでいけます。

で、おおー、っと思ったところではじめて画面に出てきたものとサンプルのコードを見比べていくと、ほしい数だけ頂点を作って繋がっているぶんだけ頂点2つを指定して辺を作っていくだけでいいのがすぐ分かります。Ubigraphの実体は、視覚化したものを表示するXMLRPCサーバで、それにXMLRPCでリクエストを送ると動的にネットワークが変化していく仕組みになっていて、いろんな言語から使うことができます。perlの場合は

#!/usr/bin/perl
use Frontier::Client;
my $client = Frontier::Client->new( url => 'http://127.0.0.1:20738/RPC2';);
$client->call('ubigraph.clear', 0);
my $a = $client->call('ubigraph.new_vertex');
my $b = $client->call('ubigraph.new_vertex');
$client->call('ubigraph.new_edge', $a, $b)

こういうコードで、画面に頂点がふたつ生成されて、そのふたつが辺で結ばれます。
perlを使うなら実際はFrontier::ClientをオブジェクトっぽくラップしているUbigraphのほうがなじみやすいと思います。RubyはmootohさんのRubigraphがあります。

Ubigraphのコードが分かりやすい、といっても、ほかのツールも同じようなもので、どの頂点とどの頂点が結ばれているかのデータファイルを作ってツールに流し込むだけで単純さはほとんど変わりません。ただ、手持ちのデータからそのツール用のデータファイルを作るためのプログラムを書いてそれをツールに読ませてビュワーで再読み込みさせるのより、手持ちのデータに従ってUbigraphのAPIを呼ぶプログラムを書けばそれで画面に反映されるところは地味に面倒な手順が減っていいなと思いました。

ひととおり使い方が分かったので、前回の果たしてtumblrにアルファリブロガーは存在するのかのときに果たせなかったリブログされる様子のグラフも作ってみました。

Ubigraphは動的に変化するグラフを視覚的に見られるところが本当に素晴らしいのであって、こういうふうに動かない画像にすると全然魅力的に見えないんですが、ほんとはリブログされた時系列順で頂点が増えていきます。Ubigraphは次数(頂点から出ている辺の数)が多いものを中心にしてグラフがレイアウトされるので、なんか全ての始まりであるはずのところが、真ん中のほうにちょこっとついてるだけに見えちゃってますが、赤い球のところが一番はじめのpostです。
はじめにpostしたgipsさんからkielaさんがreblogして、そこから6人のひとに枝分かれして何人もの人を介して広がっていっているのが分かります(っていうのが初めてでも10分くらいで作れるので、ちょっとこれ見てみたいな、という時があったらぜひ試してみるのをお勧めします!)。

一部を拡大することもできます。

Ubigraphの神髄は動的に変化する様子が見られるところで、こういう変化しないものを見るときはレイアウトを細かく設定できるほかのツールのほうが優れてそうです。それでも、小さなネットワークであればUbigraphでも十分形を把握することはできますし、何よりとっときやすいところがよかったです。

Firebug+ubi.js

上のグラフはFirefox+FirebugでXMLHttpRequestを使ってUbigraphにXMLRPCリクエストを送信して作りました。

ほんとはFirefox3.1のクロスサイトXMLHttpRequestを使えたら、ウェブページに置かれたUbigraph用のjavascriptコードを読み込むだけでローカルのUbigraphを動かせるんですが、仕様が厳しくなってtext/xmlはリクエストを送られる側のサーバの許可なしで送れなくなったため*1、Ubigraph自身のページ(127.0.0.1:20738)でFirebugを開いてコードを実行しないといけません。

FirefoxでUbigraphを起動したあとFirefoxでhttp://127.0.0.1:20738/RPC2を開いてFirebugで下記のコードを実行すれば手元のUbigraphでリブログされていく様子を見ることができます。Firefox上でウェブにあるHTMLからデータを取り出してFirebugからUbigraphにデータを送れたらすごくスマートでいいなというわけでUnigraph APIのほんの一部をラップしたubi.jsというのgistに置いたので、ちょっとしたデータをちょっと見てみたいな、という時にはぜひUbigraphともども使ってみてください。

function s (u) {
var s = document.createElement("script");

s.src = u;
s.type = "text/javascript";
document.body.appendChild(s);
}

s("http://gist.github.com/raw/66201/b6784b8431305d74ec0c822f73e7b8de9aee95af/ubi.js");
s("http://re.ido.nu/action/73684294?callback=p")

var vt = {};

window.p = function(ret) {
  var u = new Ubigraph();
 u.clear();

  ret.map ( function (d) {
if ( d.action == "liked" )
            return;

// ignore multiple reblogs.
if ( vt[d.who] )
   return;
    
    var v = vt[ d.who ] = u.new_vertex();
    u.set_vertex_attribute(v, "label", d.who);
    u.set_vertex_attribute(v, "shape", "sphere");

if ( d.action != "reblogged" ) {
    u.set_vertex_attribute(v, "size", 1.5);
    u.set_vertex_attribute(v, "color", "#800000");
    return;
}

if ( vt[d.from]  && vt[d.who] ){
  var e =    u.new_edge(
        vt[ d.from ],
        vt[ d.who ]
     );
   u.set_edge_attribute(e, "arrow", "true");
   u.set_edge_attribute(e, "arrow_position", "1.0");
}
} );
}

参考

  1. HTTP access control – MDC

果たしてtumblrにアルファリブロガーは存在するのか

Tumblrのdashboardで

そして、所々にいる人がまさに電脳ハブとなっています。
有名人というよりも基本的には無名、だけどもごく一部では・・・という人が
ゴロゴロしています。followerが多いのも理由ですが、それだけではありません。
Tumblrは恐ろしい。(誤字訂正) – 湊子の徒然

というのを読みました。

それとはあんまり関係ないかもしれないけど、先日tumblrのnotes tokenを割り出す #2方法を編み出してからTumblrのデータを集めているので、実際にひとつのpostがどう広がっていくかを見てみましょう。Tumblrのreblogツリーはあることに関して誰からそれを知ったのかという地味だけど今までなかなか知れなかったことを不完全ながらも教えてくれます。それはまるで豊川信用金庫事件 – Wikipediaの真相を知るかのようなおもしろさがあります。

Introducing: Tumblr v5

reblog notesを集めるのはけっこう大変なので、そんなにたくさんデータがあるわけではないのですが、とりあえず今持っているデータの中で最もreblog(含like)されているのは712notesのIntroducing: Tumblr v5 | Tumblr Staff でした。

それがreblogされる様子をタテ8300ピクセルの巨大なPNGにしました。でかいので一部だけ紹介。

tumblr v5 video reblogtree

Tumblrの公式ブログだというのもあって、followしている人も多く、Tumblr Staffから直接reblog/likeしているひとが199人います。アイコンの横の数字が、その人からreblog/likeした人の数を表しています。2番目に表示されているjacobは最近新しくTumblrに加わった彫刻みたいな顔のデザイナーの人です。このひとから16人がreblog/likeしています。

ざーっとみていくとわかるのですが、700もreblog/likeされていても、ひとりのひとが4人以上からreblog/likeされていることは稀にしかありません。4reblog/likeが3人、3reblog/likeが4人で、ほとんどはゼロ(reblogされることのないlikeも含まれているので多くなります)か1です。16人からreblog/likeされているのはかなり珍しいです。ほかに多くの人からreblog/likeされているのはTumblrをつくったDavidの26reblog/likeだけです。

try to hide. by ~lemonsuicide on deviantART

reblog/likeの数が一番多かったTumblr v5ビデオの例はちょっと特殊なので、もうちょっとふつうのpostがどう広まるのかを見てみましょう。

下の写真はtry to hide. by ~lemonsuicide on deviantARTからgipsによってtumblrにpostされたもので177reblog/likeを集めています。

Try To Hide  By Lemonsuicide-1

これもタテ4200ピクセルくらいのPNGにしてみました。

lemonsuicide reblogtree

この写真はTumblr v5ビデオと違って、はじめにpostしたgipsからはkielaしかreblogしていません。ここでreblogされていなかったらtumblrの中では広がらず、177reblog/likeを集めて今ここでどのようにreblogされて広まっていくかの題材として紹介されることもなかったわけです。

Tumblr v5ビデオでは3reblog/likeは稀でしたが、このpostでは4reblog/likeくらいはわりと多く見られるのと、reblogしたひとからさらにreblogされる率が高く、結果としてツリーがどんどん深くなっていっているのが分かります。その深さ、一番深いところでは20人を介して一番はじめにTumblrにpostしたgipsに繋がります!

もしこのpostをreblogしたひとがいたら、これが自分のDashboardにどうやって流れ着いたのかをたどってみてください。自分の場合はgipsから深さ16のところで繋がっていました。それをreblog元へとずっとたどっていくと、何度かそのひとひとりしかreblogしていない危なっかしいところを経由して、自分のdashboardにまさに流れてきているのがわかります。

このpostに関して一番影響力があったと言えるのは深さ12のところで出てくる、エロ系のrebloggerの間では有名なbiccchiからの12reblog/likeが最多です。でもここからはあんまり深くならず、下には3段階しかのびていません。潜在的にreblogしそうなひとたちは深さ12になるまでにもうほかの人からreblog済みで、もうreblogする可能性のある人が少なくなっていたからかもしれません。

感想

マスメディアだろうと、ブログだろうと、Tumblrだろうと、見ている人が多いメディアが大きな影響力を持つのは変わらない、と思っていたけれど、try to hide. by ~lemonsuicide on deviantARTがTumblrでreblogされていく様子を見ると、見ている人の多さが直接の影響力に繋がっているわけではないみたいです。

集めたデータからあるユーザが何人のひとにreblogされている数からfollowerの数を推測することができるのですが、はじめのgipskielaもそんなにfollowされている数は多くはありません。followerが多そうな人を探してreblogtreeをたどっていくと、深さ6のところのroshroshroshは、ほかの人と比べて倍くらいの人にfollowされているようです。でもここから直接reblogしたひとは4人しかいません。kielaはその半分くらいの人にしかfollowされていないのに6人の人がreblogしています。

同じものをreblogしているひとたちはだいたいお互いにfollowed/followingの関係にあるので、dashboardで見ている時には時系列の逆順におなじpostが流れてきているのでしょう。だからroshroshroshをfollowしているひとはroshroshroshがreblogしたときにはじめてこのpostを見ることになります。そして、dashboardをさかのぼって何度か同じpostを見た時のどこかでやっぱりいいねと感じてreblogするからfollowerの多いroshroshroshからreblogするひとが相対的に少なくなっているのかもしれません。

ちょうどマスメディア広告である製品を知って、そのときは、へー、と思っただけだったけど、ともだちがその製品を使っているのを見て実際に買った、みたいなのと同じように、多くの人にfollowされている人はあるpostの存在をfollowerに認識してもらう役目を果たしているだけで、それを実際のreblogに繋げているのは意外とそのfollowerのほうなのかも。

tumblrのnotes tokenを割り出す #2

追記 2009.1.26

AppJetにあるものをこの方式で実装し直しました。

tumblrのnotes tokenを割り出すよりも簡単、予測可能な一定時間で終わるnotes token取り出し方法が見つかりました。

自分がfollowしているひとの一覧が表示されるfollowingのページにある、各ユーザのunfollowボタンのform要素のidにこんなfollowing_R2QqU1tdj_delete値が埋め込まれています。

これの真ん中の部分がtokenと同じになっているのでこれを取り出すだけです。

ちなみにfollowするときのボタンについてるnonceもおんなじ値では、と思ったけどfollowするときについてるのは全然違うものでした。

tumblrのnotes tokenを割り出す

追記 2009.1.26

AppJetのものをtumblrのnotes tokenを割り出す #2の方式で実装し直しました。このページに書かれた方法だとtokenがとれないユーザがいたりしましたが、新しい方法では確実にtokenを返してくれます。

tumblrの特定のpostがどうreblogされたかは

http://www.tumblr.com/dashboard/notes/$post_id/$token

にアクセスすることで知ることができます。

ただいろいろ制約があって$token$post_idのポストをしたひとのアカウントと結びつけられたトークンを設定しないといけなくて、それはそのポストをした人のアカウントでdashboardにログインしていないとわかりませんでした。(参考 自分のTumblrにpostのreblog数を表示させる – cxxの日記 – たんぶら部 – Tumblove -)

実はよく見ると、このtokenはphotoをtumblrにshareしたときにつけられるファイル名の一部として埋め込まれています。そしてpostによらず(一定期間?)共通なので、そのユーザがtumblrにshareした写真がひとつでもあれば、そのファイル名からトークンを割り出すことができます。これを利用して、アカウント名を渡すとそのユーザのトークンを返してくれるAPIをAppJetにつくりました。

% curl -q 'http://usertoken.appjet.net/ku'
SPCu3Mprz

APIでphotoを50件取ってきてその中で写真のファイル名に一番多く含まれているトークン3つをその人のものか確認するだけなので、特定の人からたくさんreblogしていたり、ぜんぜんphotoをshareしていない場合はトークンを取り出せないです。

これを使うと、ひとのpostでどうreblogされたものなのかが知りたい時にも自分でreblogすることなく、reblog treeを見ることができるようになります。

ありえないreblog.ido.nuのコードを公開しました

reblog.ido.nu ソース公開してくれないかなー。うちのガラパゴス携帯だと、css が地の文として表示されてしまったり、画像が大抵容量オーバで読みめなかったりするんだよね。

調子はどうだい – reblog.ido.nu ソース公開してくれないかなー。うちのガラパゴス携帯だと、css …

と書かれていたのでreblog.ido.nuのコードを公開しました。

ku’s reblog.ido.nu at master ― GitHub

自分がiPhoneにスイッチしてからメンテするモチベーションもなくなってしまったので、ソースは公開しておいて、だれかがいじってくれたらラッキー!パッチ取り込もう、みたいにしようと思ったりもしていたのですが、恥ずかしくて公開できないコードなので公開していませんでした。でも公開してほしいと言われたからにはちょっと迷ったけど公開します。もし書き直してもらえたらreblog.ido.nuのほうにも喜んでバックポートさせていただきますのでお気軽にgithubでpull requestをお送りください。むしろよろしくおねがいします。

概要

もともとdashboardが見られればいいや、というところから書きはじめて、そこから好きなのをpostしているひとのtumblrはみたいよね、というわけで*.reblog.ido.nuでひとりひとりのページを見られるようにして(ここはAPIでデータを取って表示しています)、しばらくケータイで使ってみたらやっぱりreblogしたいよね、でもケータイで普通にreblog終わるの待ってられないよね(実際タイムアウトしちゃうことが多かった)、というわけでperlのGearmanとPHPのNet_Gearmanでreblogサーバを作るなんてことをして今に至っています。

コードのファイル構成、中身のコードの意味がわからないのは何も考えずに困った時に困ったところだけをいじって直したからです。すいません。

sugarのtumblrクローンOnSugar

久々にMoMB | The Museum of Modern BetasをチェックしてたらOnSugarというのを発見。

Onsugar-Logo-Beta

このださいロゴのピンクは見覚えがあると思って確認したらやっぱりgeeksugarと同じところがやっていた。geeksugarなんてみなさま当然ご存じないと思いますが、geeksugarはテッキー女子向けガジェットブログです。そういう自分もsubscribeしてるけど全然読んでないので写真から判断してるだけですが男子向けとの違いはセレブリティとファッション。GeekSugar で見つけたおしゃれな iPhone ケースのリスト – 日本語で書く日記なんかが紹介されているブログです。

関係ないけど、以前にcafeglobeかなにかでノートパソコンにこそかわいいケースをみたいな記事を読んでその通りだと思って探したけど、そもそもノートパソコンにケースが必要なひとなんかいないみたいで(かわいいマウスはあってもかわいいキーボードなんかないように)、かわいいケースを手に入れるのは困難を極めて、マザーボード梱包用のトランスルーセントシルバーのプラスティックバッグを経て、けっきょくかわいくないのを使ってます。

この、かわいくないものにこそかわいさをの話でいつも思い出すのはこれで損益分岐点計算とかしたいと、大学を出てはじめて働いた会社で上司だったひとが日記に書かれていたので知った amadana + mina perhonen コラボ電卓。いつかノートパソコンも電卓くらいにチープなコモディティ製品になってこうしてコラボネタになったりする日が20年くらいしたら来るんでしょうか(そのころにはノートパソコンとかなくなってるか)。

Amadana Lc104Mina H

Share OnSugar

Geek Girl
で、話をOnSugarに戻すと、コピーにSweet & Simple Publishingと書いてあって、これが実は微妙にTumblrのクローンだったのでちょこっと触ってみました。しょっぱなから、私的かっこいいサービスかどうかの第一基準である2文字のアカウントを作れるをクリアできなかったものの、わりとおもしろかったところを紹介したいと思います。

まずBookmarkletがありません。Share OnSugar Bookmarklet | Help, bookmarklet, tools OnSugar Help – Support for OnSugarというページがあったみたいなんだけどページがなくなっています。でもTumblrのShare On TumblrをもじってShare OnSugarになっているところは好きです。さすがクローン。FAQにも

How do I create a post?
You can create a post by clicking on the “New Post” link in your site dropdown menu. Once there you can choose from 10 different types of posts.

って書いてあるだけなので、公式にbookmarkletをサポートしてないのかもしれません。

OnSugarの10のコンテンツ

ひとつのOnSugarサイトを複数のアカウントで編集できるとか、コメント機能がついているとか、メッセージが送れるとか、下書きが管理できるとか(tumblrは相変わらずcoming very soonでございます)、細かい違いはあれどもOnSugarの一番の目玉はtumblrの7つのコンテンツを上回る10のコンテンツを導入しているとこです!

GalleryはTumblrのPhotoと同じで、ただTumblrの場合ひとつのpostにひとつの写真しか入れられなかったのが、複数枚の写真を入れられるようになっています。ただ、証明書のついていないjavaのアプレットで写真をアップロードすることになっていて、警告は出るし起動するまでブラウザが死んだかと思ったし、Flashでやればいいのに。

TumblrにないのはSpread, Quiz, Pollのみっつ。ではわかりやすいものからそれぞれ見ていってみましょう。

UquizQuiz

Quizはその名の通りクイズをpostします。選択肢と正解を用意してpostすると

Quiz

こういうページのできあがり。ただ選択肢に日本語を入れると化けますねー。

PollPoll

Pollも予想通りに投票機能です。こっちは日本語の選択肢を入れても文字化けしません。

Poll

ちなみにヤフーブログには投票機能があるらしい*1ので、この機能がどうしても欲しいひとはヤフーブログを使う手もあります。

SpreadSpread

Spreadは何なのかと思ったら、sugar inc.の持ってるいろいろなコンテンツからいろいろ写真を持ってきて自由に並べたりできるものです。テキストもレイアウトできます。フリーハンドで書けるのかと思ったけどそうではありませんでした。

Spread

このへんの大人の事情でbookmarkletが無くて、写真は必ずアップロードしたものを使わないといけないのかもしれません。

まとめ

そんなかんじで、Tumblrみたいなのを作ろう会議をやって、無視するわけにもいかないから企画部長の困った意見を容れつつ作ったらこうなりました、みたいなかんじの中途半端なできあがりです。

Tumblrのtypeはそれぞれのコンテンツを最小粒度で扱うように設計されている結果、目的のコンテンツだけを示すpermalinkが生成されているのに対し、OnSugarはPhotoを廃止して複数の写真を入れられるGalleryに変え、Quizも同様にひとつのpostに複数のクイズを入れられるようにしている結果、その利点が失われています。

OnSugarが新しく追加しているQuizPollは、postの内容の型だけでなく機能も規定してしまっています。ここは、クイズや投票機能自体はOnSugarというサイトに持たせて、コトノハのユーザのフィードのように、ユーザがそれに対してどう回答したかというデータだけをユーザのブログにpublishしてもらえば、ユーザのブログにはデータだけがpublishされるようにできるんじゃないかと思いました。もちろんOnSugarのページで見せる時には、その人の回答と(べつに表示しなくてもいい)そのPollやQuiz自身も表示してあげます。

まーでもやっぱり企画会議でそんな小難しい整合性を主張できるわけもなくtumblrは何なんだ – 準二級.jpのとおり、ふつうにミーティングして作ったらOnSugarみたいなのができあがると思います。

参考

tomblooハックス – share on WordPressにポストするためのMetaWeblog API

アップデート 2008.6.24

mattnさんにいただいたBig Sky :: tomblooハックス90_MetaWeblog.jsのパスワードをパスワードマネージャに保存するパッチを文字化けしないようにしてtombloo – Google Codeにコミットしました。ページのView raw fileのところからダウンロードしてください。

tomblooはtumblr専用のツールではありません。tomblooのポストする先をWordPressに変えればtomblooからWordPressにポストすることができて、自分専用プライベートtumblelogとか、社内でチーム共有のtubmlelogを作ってtomblooからポストすることもできます。MetaWeblog API posterはそのためのパッチです。

ダウンロード

90_MetaWeblog.js (for Firefox3)

設定

  1. 90_MetaWeblog.jsをダウンロードしてプロファイルディレクトリのextensions/tombloo@brasil.to/chrome/content/library/に入れます。
  2. 次にtomblooの設定を変更します。Postersの部分にMetaWeblogを追加してください。tomblooからポストしたときにTumblrと自分のWordPress両方にポストしたいときは (Tumblr|MetaWeblog) WordPressだけにポストしたいときは MetaWeblog にしてください。

    (UIつきバージョン経由でも投稿可能です)

  3. about:configでWordPressのAPIエンドポイントを指定します。ブラウザのアドレスバーにabout:configを入れて、右クリック»New»Stringを選んで extensions.tombloo.posters.MetaWeblog.endpoint という名前で設定を新しく作ります。
    Picture 3-26

    セットする値にはWordPressのAPIエンドポイントを入れます。これはブログのトップページがあるディレクトリのxmlrpc.phpです。ここのブログの場合はトップページがhttp://ido.nu/kuma/なのでエンドポイントはhttp://ido.nu/kuma/xmlrpc.phpになります。

  4. FirefoxにWordPressのユーザ名とパスワードを記憶させてください。このMetaWeblog API posterはここで記憶したユーザ名とパスワードを使ってAPIにアクセスします。ログイン画面はトップページがhttp://ido.nu/kuma/だったらhttp://ido.nu/kuma/wp-login.phpになります。ログインしている状態では表示されないので、記憶されていない場合は一度ログアウトしてからアクセスしてみてください。

Have ♡ fun

長い設定が終わったら後はいつもと同じようにtomblooを使って自分のWordPressにポストすることができます。

wired

タイトルには元のページのタイトルが入ります。ポスト先に使うWordPressにreblogという名前のカテゴリを作っておけば、tomblooから投稿した記事には自動的にreblogというカテゴリが設定されます。 投稿のタイプの名前のカテゴリ(photo, quote, link)も作っておけば、ポストのタイプも投稿時に自動的に設定されます。


既存のWordPressのテーマだとtumblrのようにきれいなみためにはならないですが、たぶん誰かがWordPress用のtumbleloggingに向いたテーマを作ってくれることでしょう。

MovableTypeで利用する場合

MetaWeblog APIはWordPressだけでなくMovableTypeでもサポートされているのでMovableTypeでも使うことができる。ただユーザ名とAPI用パスワードの設定を簡単にはできないので、ファイルに直接書くことになる。

あとがき

tomblooはウェブ上にあるページからtumblrの7つのコンテンツの形式にそってデータを取り出してくる。ユーザは取り出されたtumblr形式のデータをいろいろなところにポストすることができる。FFFFOUND!であったりWe heart itであったりはてなダイアリーであったりローカルのディスクであったり。

いろいろなサービスにAPIが導入された結果、以前はユーザインターフェイスとサービスとがくっついていてなかなかはがせなかったのが、比較的容易にはがせるようになった。結果としてユーザインターフェイスとサービスを好きな組み合わせで使うことが容易になってきている。Gyazoのインターフェイスで撮ったスクリーンショットをtumblrにアップロードするGyamblrみたいなのも極めて容易に作れる。

APIの可能性についてはブロギングプラットホームでいちばんはじめに試行錯誤された。結果としてブロギングプラットホームには様々な投稿用APIが備わっている。投稿するためのツールとウェブ上に存在するページとは完全に切り離すことができる。

自分一人のためのtumblrのクローンを作るのにはNanoGrabbrChyrpのような、フルスクラッチでtumblrのためのエンジンを作る必要はない。伝統的なブロギングプラットホームにかんたんに投稿するためのブックマークレットと、tumbleloggingに適したテーマを用意してあげるだけでできる。

metaWeblogはWordPressとMovableTypeでしかサポートされていないっぽい。atomで作るべきだった。反省。

Would You Take a Tumblr With This Man? | The New York Observer のほんの一部和訳

Twitter / KEMONO: vimeoって美大っぽい、YouTubeは情報工学生のイメージ

を読んでTumblrでもそんなことがどこかに書いてあったなと思って探して見つけてきた Would You Take a Tumblr With This Man? | The New York Observer にあるDavidのインタビューの和訳です。

この記事、文体がいかにもインタビューなかんじですが、いくつかあるインタビューの中ではおもしろいので読んでもたぶん損しないです。いきなりガールフレンドを朝4時に叩き起こして飛行機に乗せてプエルトリコで5日間飲んだくれてたとかいうエピソードとか。

感謝! 2008.5.27

Tumblrにquoteされていたの経由で読んでくださった方に、英語がわからなかったところを教えていただいたので差し替えました(語尾など細かいところをほかの部分と同じになるよう変えています)。ありがとうございます。

追記 2008.5.29

Would You Take a Tumblr With This Man? | The New York Observer の全文和訳 – いいことあるかいにきれいな日本語の全文和訳がやってきました!

“はじめはほんとに自分のためだった” とMr. Karpは言った。

“まだ誰も持ってないtumblelogが欲しかった” TumblrはMr. Karpsの人柄を多くの点で反映している。
インターフェイスはとてもシンプルで、ちょっと技術的な素養のある人たちだけでなく、Tumblrというプラットホームを白い石盤に見立てて、コードを書いたり自分だけのものを作ったりするひとたちにも魅力的だ。Mr. Karpはどちらのタイプのユーザも歓迎している。

また、Tumblrのデザインは、ユーザが自分自身でやりたいことをやりはじめるようになっている。(訳注: わかりませんでした。Also implicit in Tumblr’s design is how it allows its users to use their own initiative to create the kind of experience they want. )またTumblrのデザインを見れば、どうやってユーザの独自性を発揮して各自が望むようなユーザエクスペリエンスを作成すればいいかは理解できる。

“DavidはAmazonの”これはなに?”ボタンが嫌いなんだ” とMr. Seibert(訳注: Davidが14歳のときに働いていたアニメ会社のプロディーサ)は言った。“彼は、なんでも理解できる人たちの小さなグループを選ぶほうだ”(訳注:よくわかんない。 He has self-selected to a small group of people who can figure everything out.)“彼はなんでも自発的に解決できる少数派のグループに属することを選んだ”

“今は、アーティストに狙いを定めてる”とMr. Karpは言った。”以前は学生や若者を考えてた。でも自分をオンラインで表現したい大人をターゲットにするほうが簡単だ。アーティストやプロディーサにはYouTubeがあってミュージシャンはMySpaceに追いやられている。あれはサイテーなプラットホームだ” Tumblrは無理なくフィットする。

繰り返すと、Tumblrを使うとおそらく世界で最も簡単に考えたことを共有することができる。
そしてまた、タンブラーの良さをすべての人々にわかってもらうのもすごく簡単だろう。

(訳注:最後のところわかんない。facebookでクソみたいなことを言ってると自分に降り掛かってきて後悔することになる?)
Then again, perhaps Tumblr makes sharing thoughts with the world almost too easy. “If every shitty thing you said ended up at the top of your Facebook profile,” Mr. Karp said, “you would probably reconsider it.”

Mr. Karpはこう言っている。”Facebookでうっかり間抜けな発言をするたびにそれが自分のプロフィールのトップに表示されるのを見たら、きっとFacebookを使うのはもう止めようかと考え直すよ”

Tumblr Inc. 21-year-old founder David Karp following in Steve Jobs’ footsteps の一部和訳

今年はじめのインタビュー記事Tumblr Inc. 21-year-old founder David Karp following in Steve Jobs’ footsteps (Tech Confidential – Behind The Money Blog)の一部を和訳しました。

英語はわからないし、日本語もモスバーガーなみだと言われるほどちゃんと書けないので、ニュアンスが汲み取れてないと思います。

Tech Confidential
批判的なひとたちは”Tumblrはテッキーがテッキーのために作ってる”って言っていますが、どうやってメインストリームに持っていくつもりですか?
David Karp
たしかにぼくたちはfirst-adopter集団にむけてTumblrを公開しましたが、ぼくたちははじめからメインストリームのプロダクトを作ることと、この tumblelogging というカタチをみんなにひろめることとにフォーカスしています。
TC
大きなマーケティングキャンペーンなしに、どうやって大勢のひとたちに届くようにするんですか?
Karp
ユーザがほんとうにハッピーでいられるようにします。
トラフィックの40%はリンクからきています。すごくTumblrを愛しているひとたち − Tumblrで最高におもしろいことをやってくれるアーティストやミュージシャン、そのほかのクリエイティブなひとたち - にフォーカスして、その人たちがやっていることを次のレベルに持っていく助けになれれば、そのひとたちがほかのひとたちを感動させることで磁場ができてTumblrにひとが集まります。

TC
なんでそれでうまくいくと思うんですか?
Karp
Appleは製品の”coolness”で人をひきつけることで、メインストリームでも広く受け入れられるようになりました。Apple製品を使って最高にかっこいいことをやっている、最高にかっこいい人たちをすごく大切にすることでそれをやったんです。

ほかのみんなはクリエイティブな人がAppleの製品を使ってやったことを見て羨ましくなります。自分のためにひとつ買わないわけにはいかなかった。僕たちはTumblrでそれをやりたい。

微妙に新しくなったtumblrでReblogCommandを動くようにするためのパッチ

追記 2008.6.2

ReblogCommandの最新版はcodereposからインストールすることができます。

訂正 2008.4.13

reblogCommandのコード、間違ってたみたいです。修正してます。Tombloo0.1.6で動作確認済。

Tombloo 0.1.3、LDR + Tombloo – 実用でGreasemonkeyからTomblooの機能が利用できるようになっているので、それを使ってrelbogするようにするためのReblogCommandのパッチです。Tomblooの機能に依存しているのでTomblooがないと動かなくなります。

Tomblooにもパッチが必要です。Tomblooは extensions/tombloo/chrome/content/browser.xulgetReblogToken TUMBLR_URL を付け足すだけです。

--- browser.xul 2008-04-12 11:17:16.000000000 +0900
+++ browser.mine.xul    2008-04-12 16:24:51.000000000 +0900
@@ -40,7 +40,7 @@
                        GM_Tombloo.Tombloo.Service = update({}, env.Tombloo.Service,
                                'check share posters extracters'.split(' '));
                        GM_Tombloo.Tumblr = update({}, env.Tumblr,
-                               'post remove getInfo read reblog openTab getLoggedInUser'.split(' '));
+                               'post remove getInfo read reblog openTab getLoggedInUser getReblogToken TUMBLR_URL'.split(' '));
                        GM_Tombloo.FFFFOUND = update({}, env.FFFFOUND,
                                'post remove iLoveThis'.split(' '));
                        GM_Tombloo.Flickr = update({}, env.Flickr,

ReblogCommandのパッチは以下。パッチ済みのファイルをreblogcommand.user.jsに置いておきます。

あ、あと消すためのコマンドも入れました。でもバグっててピンをつけたのと違うやつが消えるっぽいので使わないでください!

pinned-or-current-link|deletePost

で消せます。

Tomblooのreblogメソッドで帰ってくるのがMochiKitのDeferredインスタンスなのですが、それをJsDeferredのDefferedListで扱う必要があるのでトリッキーなことをしています。こういうもともと繋がらないのをなんとかして繋げるの好きだなー。

--- reblogcommand.orig.js  2008-04-12 16:12:20.000000000 +0900
+++ reblogcommand.user.js  2008-04-13 11:15:38.000000000 +0900
@@ -86,26 +86,41 @@
 }
 
 function reblog(aURL){
-  var id  = getIDByPermalink(aURL);
-  var d;
-  with(D()){
-    d = Deferred();
-    if(!id) {
-      wait(0).next(function(){d.call()});
-      return d;
-    }
-  }
-  var url = getURLByID(id);
-  window.Minibuffer.status('ReblogCommand'+id, 'Reblog ...');
-  getSource(url).
-  next(function(res){
-    return postData(url, createPostData( parseParams( convertToHTMLDocument(res.responseText))));
-  }).
-  next(function(){ window.Minibuffer.status('ReblogCommand'+id, 'Reblog ... done.', 100); d.call()}).
-  error(function(){
-    if(confirm('reblog manually ? \n' + url)) reblogManually(aURL);
-    d.call();
+  return invokeTumblrMethod(
+    aURL, 'reblog', {
+      start:  'Reblog ...',
+      done:  'Reblog ... done.',
+      manual:  'reblog manually ? ',
+    }
+  );
+}
+
+function deletePost(aURL){
+console.log("deletePost", aURL);
+  return invokeTumblrMethod(
+    aURL, 'remove', {
+      start:  'Deleting ...',
+      done:  'Deleting ... done.',
+      manual:  'delete manually ? ',
+    }
+  );
+}
+
+function invokeTumblrMethod(aURL, methodName, msg) {
+console.log("invokeTumblrMethod", aURL);
+try {
+  window.Minibuffer.status('ReblogCommand'+aURL, msg.start);
+
+  var d = GM_Tombloo.Tumblr[methodName]( aURL ).addCallback ( function (res){
+    window.Minibuffer.status('ReblogCommand'+aURL, msg.done, 100);
+  }).addErrback( function(){
+    if(confirm( msg.manual + '\n' + url)) reblogManually(aURL);
+    d.callback();
   });
+console.log("invokeTumblrMethod", aURL, d);
+}catch(e) {
+  console.log(e);
+}
   return d;
 }
 
@@ -155,9 +171,8 @@
     window.Minibuffer.execute(target_cmd + ' | reblog -m' + clear_pin );
   }});
 
-window.Minibuffer.addCommand({
-  name: 'reblog',
-  command: function(stdin){
+
+var tumblrCommand = function(stdin, method, manualMethod){
     var args = this.args;
     var urls = [];
     if(!stdin.length){
@@ -175,23 +190,46 @@
     // reblog
     if(args.length = 1 && args[0] == '-m'){
       urls.forEach(function(aURL){
-        reblogManually(aURL);
+        manualMethod && manualMethod(aURL);
       });
     }else if(args.length){
       console.log('unknown args...');
     }else{
       urls = urls.filter(isTumblrUserURL);
       if(!urls.length) return stdin;
-      var lst = urls.map(reblog);
+      var lst = urls.map(method);
       if(lst.length > 1){
+        // JSDeferred/MochiKit Deferred compatibility hack.
+      var jsdl = {};
+      for ( var i = 0; i < lst.length; i++ ) {
+        var d = lst[i];
+        jsdl["jsd" + i] = d;
+        d.next = d.addCallback;
+        d.error = d.addErrback;
+      }
+
         with(D()){
-          parallel(lst).wait(2).
-          next(function(){window.Minibuffer.status('ReblogCommand','Everything is OK', 1000)});
+          var d = parallel(jsdl).wait(2).
+          next(function(){
+            window.Minibuffer.status('ReblogCommand','Everything is OK', 1000)
+        });
         }
       }
     }
     return stdin;
   }
+
+window.Minibuffer.addCommand({
+  name: 'reblog',
+  command: function (stdin) { return tumblrCommand.apply(this,[ stdin, reblog, reblogManually] ) }
 });
 
+window.Minibuffer.addCommand({
+  name: 'deletePost',
+  command: function (stdin) { return tumblrCommand.apply(this, [stdin, deletePost, null]) }
+});
+
+
 })()
+
+

tumblrの7つのコンテンツ

tumblrの持っている隠れた新しいところはブログのコンテンツを7つに大別したところだ。

tumblrはpostの種類を7つにわけた。ふつうの文章、写真、引用、リンク、チャット、音楽、映像。

tumblr content-types

もちろんtumblr以前にもこれらのコンテンツをブログに投稿することはできた。でもそれはふつうの文章の中に何のマークアップもされずに入っていたので、キカイにはそのpostの内容がなんなのかはわからなかった。たいていのブロギングプラットホームにはカテゴリという概念があって、その投稿が何についての投稿なのかを示すことはできたが、これはニンゲンが読むためのものだった。キカイには投稿の内容を知る術がなかった。

tumblrはProjectionist: A tumblelogに感銘を受けて作られたらしい。そしてブログに投稿できる形式を7つに制限した。おそらく、投稿するときの利便性と、投稿された内容に合わせて最適なみためを作る上で必要だったから、この7つに分類したのだと思う。ユーザはひとつのpostにひとつの写真、ひとつのpostにひとつのリンク、というような制約をうけることになった。いままでのブロギングプラットホームにはなかった制約。

コンテンツをわけることがセマンティクスをつくる

キカイの側からこのことをみると、ニンゲンが投稿の内容を判断して、内容に適したコンテンツのタイプを選んで投稿してくれているように見える。いままでのブロギングプラットホームに投稿されたpostは、キカイにとっては中に何が書かれているのかわからなかったけれど、tumblrにpostされたコンテンツは、その投稿の中身がなんなのかをニンゲンがあらかじめ判断して、記述してくれているのと同じだ。結果、tumblr上のコンテンツはキカイが適切に扱うことができる。

たとえば、MovableType上に投稿されたプログのエントリから、自動的に写真だけをFlickrにアップロードしたいとする。このときは、ユーザが写真をメインにした投稿をするときはカテゴリをphotoにする、というようなMovableTypeのシステムとして規定されていないルールを作っている必要がある。そういうルールなしに、単純にpostの中のimgをFlickrにアップロードすると、Deferredの動作を図解した画像もFlickrに上がってしまうだろう。ふつうのブロギングプラットホームは、ニンゲンが何の制約もなくコンテンツを投稿できる自由があるけれど、ニンゲンの自由な振る舞いはキカイに理解できないのでキカイが自動的に何かをするのには向いていない。MIMEに例えるなら、伝統的なブロギングプラットホームはmultipart/mixedのデータをそのまま貼っていて、tumblrはそれをひとつひとつばらばらにして、image/jpegだとかaudio/mpegとかをつけたかんじ。multipart/mixedのデータがFlickrにコピーできるかはニンゲンにしかわからないけれど、image/jpegだったらコピーできそうだ。そんなかんじ。

tumblr以前でも、フィードアグリゲータはフィードの種類を分けて扱っていた。コンテンツの種類を分けていた、というよりは、フィードを分類していた。フィードアグリゲータの流れを汲むFriendFeedはフィードの種類を8つに分けている。

FriendFeedはフィードの内容がログとして残っていくけれど、そこにはコンテンツの分類、という概念は希薄だ。あくまでfriendsのactivityをみる、というかんじで、コンテンツそのものをみるかんじは薄い。

あとがき

まだ何がいいたいのか固まってないなー。
コンテンツが7つに大別されたことが、いままで何ともいえないものだったコンテンツの型というのが、明確になり、互換性があるかないかがわかって、流通しやすくなった。pipesで画像を取り出して、MovableTypeに流し込んでも、それをreblogするときに、はたしてtextでreblogすればいいのかphotoでreblogすればいいのかは、わからない。
もちろんそれはtumblrの中だけの方言語彙の上で成立しているだけのセマンティクスなんだけど、ぞもそれがあればこれだけコンテンツを再利用したり、高速に流したりできる、というのがわかったこととか、tumblrというツールでの発見ではないか。

型違うと困るよねー。実行時型変換で変換できないとかで例外出たりするじゃん。意味のない値になったりとか。(int)”May 2008″でゼロになっちゃうみたいな。そういう型のミスマッチが事前にわかるところとかがコンテンツを扱いやすくしてる。

伝統的ブロギングプラットホームを作った連中がアホだったとかそんなわけじゃなくて、単に時間的な積み重ねから、データ型として何があったらいいのかが見えてきたということ。

あとレイヤは違うけど 最速インターフェース研究会 :: XMLはメタデータというより生データとしての利用価値が高まりつつあり、AjaxによるUIの切り離しがそれを加速する も同じことだと思う。

Tomblooハックス – background imageをポストできるようにする

2008.11.29 追記

今はデフォルトのTomblooで背景画像をpostできます。

たまに背景になっている画像をpostしたいときがあって、背景画像とかCSSとか調べてとらないとだめなのかなーと思っていたら意外にもコンテキストメニューオブジェクトから簡単にとれるのがわかったので作った。たぶんWeb1.0時代の、画像を壁紙にする、っていうめっきり使わなくなった機能の名残なんだと思う。

あと関係ないけど、menuitemtooltiptextつけたらツールチップ表示されるのを知った。ツールチップで実際にpostされるファイルの名前とか出そうとして、やめた。

ファイル

90_backgroundimage.js

Tomblooハックス – UIつきバージョン ポスト先にはてなダイアリーを追加する

前に作ったTomblooハックス – ポスト先にはてなダイアリーを追加するだと、常にtumblrとはてなダイアリーに追加されるようになって、いまだけはてなに、みたいなのができないので、そのへんのUIでできそうなのを探してやってみました。

Shiftを押してるときに動作を変える、というアプローチ。はじめにコンテキストメニューでShiftが押されているときはサブメニューが出て投稿先が選べる、というのにしようと思ったけどコンテキストメニューのpopupshowingではキーの状態が常にfalseでくるようになっていてだめでした(Windows/OSXどっちも)。

それで他にないかなーと思ってたらNoScript :: Firefox Add-onsとかで出てくるXUL:notificationbox – MDCが使えそうなので、試しに作ってみました。

コンテキストメニューから項目を選択するとき(下のscreenshotだとShare – Photoを選ぶとき)にShiftを押して選択すると

Select menu + shift button

ページの一番上にpostする先がボタンで出てくるので、postしたいところを押します。

Notification is popping up

押すと色が変わって押せなくなるので手がふるえてても二重に投稿されません。

Picture 5-11

コンテキストメニューのpopupで投稿先を選ぶ案(技術的な面でボツ)に比べて、同時に複数の投稿先を動的に変更できるのはいいところ。ページの一番上に出るのでマウスを移動させる距離が長いのが面倒だった(下にも出せるはずなんだけどやり方がよくわかんなかった。どっちに出そうが移動距離が長いのは変わらないけど)。notificationを使うのはいまいち。

でもこれでバリバリはてなダイアリーにquoteとかできる。photoはオリジナルへのホットリンクになるのでご注意ください。
あとはてなダイアリーだと当然tumblrみたいにquoteで文字が大きくなったりしないのでかっこわるいです。いちおうtombloo_quote, tombloo_photoというクラス名つきでpostされるので、CSSいじったらかっこよくなるかも。

コード

30_Tombloo.Service.20080405.diff
90_Hatena.20080405.js

愚痴

notificationのボタンのパラメータのcallbackが曲者で、ふつうのDOMイベントと違ってtrueを返したときにアクションがキャンセルされるようになってて、はじめfalse返したら何とかならんのかと思ってfalseにしたけどボタン押したらnotificationが閉じられちゃうので困ったなーと思って調べてたら mozilla/toolkit/content/widgets/notification.xml でコード見つけてこうなっててなんだそれと思った。

      <method name="_doButtonCommand">
        <parameter name="aEvent"/>
        <body>
          < ![CDATA[
            if (!("buttonInfo" in aEvent.target))
              return;
            var button = aEvent.target.buttonInfo;
            if (button.popup) {
              document.popupNode = aEvent.target;
              document.getElementById(button.popup).
                showPopup(aEvent.originalTarget, -1, -1, "popup", "bottomleft", "topleft");
              aEvent.stopPropagation();
            }
            else {
              var callback = button.callback;
              if (callback) {
                var result = callback(this, button);
                if (!result)
                  this.close();
                aEvent.stopPropagation();
              }
            }
          ]]>

なんでわざわざDOMのイベントと逆のtrueだとstopPropagationにしてるんだろう。おかげでそれを知るためだけにgrepかけたよー。

あと Google code search をみてると notification.hideclose = true で閉じるためのXボタンが消せるみたいなんだけど、実際やってみると消えなくて不可解だった。たしかにソースにもhidecloseで消えそうな部分はなかった。

Tomblooハックス – Vimeoのサポート

追記

Tombloo 0.1.4でVimeoもサポートされるようになりました。

Twitter / koyachi: jstnはvimeoで働いてるによればMuxtapejstnも働いているらしい個人的に今年最も注目しているVimeoはtumblrのブックマークレットではサポートされてるんだけどTomblooではサポートされてなかったので作りました。

Tomblooハックス – ポスト先にはてなダイアリーを追加するでTomblooの開発者のbrazilさんにいただいたコメントを参考にしてます。

Tombloo.Service.extracters = update( {
        'Video - Vimeo': {
                        check : function(ctx){
                                return ctx.hostname.match('vimeo.com');
                        },
                        extract : function(ctx){
                                return {
                                        type   : 'video',
                                        source : ctx.href,
                                        body   : ctx.title + '(via ' + 'Vimeo'.link( ctx.href) + ')'
                                };
                        }
                }
}, Tombloo.Service.extracters);

これを FirefoxProfileDirectory/extensions/tombloo@brasil.to/chrome/content/library/90_Tombloo.Service.Vimeo.js にして保存して再起動するとメニューにVideo – Vimeoが出てきます。

vimeo support

細かいこと

なんでわざわざupdateなんかしてるのか。

Tombloo.Service['Video - Vimeo'] = {
                        check : function(ctx){
                                return ctx.hostname.match('vimeo.com');
                        },
                        extract : function(ctx){
                                return {
                                        type   : 'video',
                                        source : ctx.href,
                                        body   : ctx.title + '(via ' + 'Vimeo'.link( ctx.href) + ')'
                                };
                        }
                }
};

上のように直接代入すると、for inでenumerateされる順番の関係(先に定義されたものが先に出てくる)でVidemo – Vimeoより先にLinkが出てきて使いにくいのでupdateしています。

Firefox3のCanvasにFlashが映るのでYouTubeをスライスできるからやった(でもWindowsはだめ)

補足 2008.3.12

Bug 313462 – plugin content not drawn via drawWindow()にファイルされていました。

This works fine on OS X on Trunk, but (I imagine) isn’t fixed in 1.8.

Comment #26

って書いてあるのでOSXでは動く状態になったけど他がまだ、という状態みたい。

あと書かれている通りwmode="transparent"になっていればWindowsでも映るのを確認。でもふつうはwmode="transparent"になっていないのでWindowsだと事実上映らない。

この問題はVistaのタスク切り替えみたいにタブのサムネイル一覧を出したときに、Flashの部分が映らないのはnot attractiveだから直したいみたいなので期待してよさそう。

bugzilla調べたらたいてい載ってるというのを学んだ。

Twitter / dotimpact: firefox3b4いれたら非互換addonがあるとクラッシュしたというのを見て、今回はバージョンあげるのやめとこうかなと思いながらもMozilla Firefox 3 Beta 4 Release Notesで何が変わったのかを見ていたら

[Improved in Beta 4!] Full page zoom: from the View menu and via keyboard shortcuts, the new zooming feature lets you zoom in and out of entire pages, scaling the layout, text and images, or optionally only the text size. Your settings will be remembered whenever you return to the site.

というのがあって、たぶんこれはCanvasのzoomを使って実現してるんだろうと推測していたので、もしこれでFlashが映るようになっていたらcapture.tumblr.js ブラウザでキャプチャしてtumblrにpostするやつもFlashが映るようになってるかも、と思ってやってみたらFlashが映るようになってるのです!Firefox3になってから試してなかったのでFirefox3であれば映るのかもしれませんが、とにかくFirefox3beta4からCanvasにFlashの中が映るようになりました。でもこれOSXだけ(?)なのかWindowsのFirefox3beta4ではやっぱりCanvasにFlashの中は映りません。FirefoxのFull page zoom機能ではWindowsでもちゃんとFlashがzoomされるので、原理的には映るような気もするけどそもそもfull page zoomはCanvasでできてる、という推測が違うのかな。

それで、もうなにがきっかけだったか忘れちゃったけど、ずっと前からやりたかったTAGIRIみたいにYouTubeの動画を一定時間ごとにキャプチャしてスライスを作る、というのができるようになってうれしい。YouTube – Fujiya & Miyagi Ankle Injuriesを使ってビデオのスライスを作った。上に数ピクセルゴミが入ってるのと、コントローラが入ってるのはてきとうに調整してあげたらなくせるけど面倒なだけでやればできるからそのままにしてある。

1秒に1回でローカルディスクに書くのだとコマ落ちせずにいけるかんじ。

Miyagi Sliced

そのあと1秒に1回でcapture.tumblr.jsのコードをちぎって貼ってtumblrにアップロードしてみると、tumblr側がレスポンスを返してくるのに5~10秒くらいかかるのでだんだんリクエストがたまるんだけど、結果的には問題なさそう。

jsでFlashのプレイヤーを操作したり、ビデオの長さを得たりできるとスクリプトで自動的にキャプチャを止められるんだけど、そのへんは詳しくないので手動で止めた。後で調べたら再生時間はswfArgs.lに書いてあった。

480×394のサイズでキャプチャ。87ファイルで35MBになった。PNGでエンコードして1ファイル平均で400kBくらい。jpegだとたぶん1/3くらいのサイズになる。

ためしてないけどYouTubeだけじゃなくて任意のFlashのプレイヤーのやつが撮れるはず。

ダウンロード

使ったJSActionsスクリプト。参考までに。
youtubeのページを開いて再生してる状態で実行すると1秒単位でスライスして /home/kuma/Desktop/miyagi/ にたくさんファイルができる状態になってます。てきとうに書き換えたらtumblrにアップロードされるようにもなる。

tagiru.tumblr.js

APNGと組み合わせる

APNG Edit :: Firefox Add-onsで使われているMozilla2:Image Encoding – MozillaWikiを使えば、これでスライスした画像をそのままAnimation PNGにするとかもできる。理論的には可能だけど実際やったらメモリの都合でできなかったりしそうだけど。

ビデオで、特定の部分だけ切り出してそこだけ動画にしてpostする、みたいなのがさくっとできるようになるといいなーと思います。このアプローチじゃ絶対に音が出ないので使えないんだけど。

参考

getBoundingClientRect を翻訳、 getClientRects を更新 – A Better Project@はてなダイアリー
getBoundingClientRect()を知らなくて困っていたところで助けられました。どうでもいいけどおなじくIE由来でFirefox3で導入されたdocument.activeElementもすごい便利で助けられてます。
プラダを着た悪魔
こないだ、服かわいいなー、これ全部スライスしたいなーと思いながら見てました。
SCRAPBLOG : canvas要素によるWebページのスクリーンショット保存機能
Code snippets:Canvas – MDC

One more Tombloo patch

TomblooをFirefox3で動くようにするパッチをちょこっと改良して追記。拡張機能をインストール/アンインストールして再起動したあとの1回目でTomblooが機能しないのを解決しました。

components/tombloo.jsのいちばんはじめのほうで

const ExtensionManager = getService('/extensions/manager;1', Ci.nsIExtensionManager);

と代入してしてExtensionManagerを利用すると、たぶんXPCOMの追加/削除が行われたあとでcompreg.datなんかを再構築するときのファイル読み込み順依存でnsIExtensionManagerが利用できる/できないが決まって、それがconstに代入されちゃうので、ほんとはXPCOMの初期化が終わったあとに呼び出されるのでnsIExtensionManagerは常に利用できるはずのTomblooServicecreateInstanceの中でもExtensionManagerが存在しなくてこけてるようでした。

XPCOMコンポーネントから他のXPCOMを使うときは、利用可能になるタイミングを意識しておく必要がありそうです。今回はcreateInstanceの中で使うからかんたんに解決できるけど、registerSelfみたいな初期化の過程で呼ばれるようなところの中で使いたかったらどーするんだろう。

TomblooをFirefox3で動くようにするパッチ#2

補足 2008.3.5

Tombloo0.1.2からFirefox3でも動くようになっているので、動かないときは新しくするといいですよ。

更新 2008.2.27

拡張機能インストール後の再起動時に動かない問題はtombloo.jscreateInstanceの中で改めてnsIExtensionManagerを取得するようにしたら解決しました。下のdiffに反映してあります。

補足 2008.2.22

Tomblooを入れて再起動してはじめのときだけじゃなくて、Tombloo以外の拡張機能でも、入れて再起動したはじめのときには動かなそうです。

TomblooがFirefox3で動かなくて困ってたけどちょっといじったら動くようになった。

Firefox3でnsIScriptableInterfaceInfoがなくなったのでそれを使ってるあたりでエラーが出てるのと、あとなんかインストール後の初回起動時にだけExtensionManagerがtype errorを出しててなんでなのかは知らない。例外をcatchするようにしたらインストール後初回起動時には動かないんだけど、もう一度再起動すると動くようになった。

extensions.checkCompatibilityをdisableにしたらバージョンチェックなくなるんですね。知らなかった。
Change CTRL+N to CTRL+T – MozillaZine Forums

diff --exclude=CVS --exclude='*.o' --exclude=.svn -rwu tombloo-0.1.1/chrome/content/library/00_Components.js tombloo/chrome/content/library/00_Components.js
--- tombloo-0.1.1/chrome/content/library/00_Components.js  2008-01-25 17:31:58.000000000 +0900
+++ tombloo/chrome/content/library/00_Components.js  2008-02-20 12:58:32.000000000 +0900
@@ -48,8 +48,8 @@
   Components.Constructor('@mozilla.org/io/string-input-stream;1', 'nsIStringInputStream', 'setData');
 const InputStream =
   Components.Constructor('@mozilla.org/scriptableinputstream;1', 'nsIScriptableInputStream', 'init');
-const InterfaceInfo =
-  Components.Constructor('@mozilla.org/scriptableInterfaceInfo;1', 'nsIScriptableInterfaceInfo');
+//const InterfaceInfo =
+//  Components.Constructor('@mozilla.org/scriptableInterfaceInfo;1', 'nsIScriptableInterfaceInfo');
 const ScriptError =
   Components.Constructor('@mozilla.org/scripterror;1', 'nsIScriptError', 'init');
@@ -84,6 +84,7 @@
 };
 function createMock(ifcNames){
+  return {};
   ifcNames = [].concat(ifcNames).map(function(ifcNames){
     return ''+ifcNames;
   });
diff --exclude=CVS --exclude='*.o' --exclude=.svn -rwu tombloo-0.1.1/components/tombloo.js tombloo/components/tombloo.js
--- tombloo-0.1.1/components/tombloo.js  2008-01-29 12:31:42.000000000 +0900
+++ tombloo/components/tombloo.js  2008-02-20 12:58:04.000000000 +0900
@@ -74,7 +74,7 @@
 }

 function getContentDir(){
-       var dir = ExtensionManager
+       var dir = getService('/extensions/manager;1', Ci.nsIExtensionManager)
                .getInstallLocation(EXTENSION_ID)
                .getItemLocation(EXTENSION_ID).QueryInterface(ILocalFile);
        dir.setRelativeDescriptor(dir, 'chrome/content');

diff --exclude=CVS --exclude='*.o' --exclude=.svn -rwu tombloo-0.1.1/install.rdf tombloo/install.rdf
--- tombloo-0.1.1/install.rdf  2008-02-02 20:19:16.000000000 +0900
+++ tombloo/install.rdf  2008-02-20 12:59:55.000000000 +0900
@@ -6,17 +6,16 @@
     <em:id>tombloo@brasil.to</em:id>
     <em:type>2</em:type>
     <em:name>Tombloo</em:name>
-    <em:version>0.1.1</em:version>
+    <em:version>0.1.1p1</em:version>
     <em:description>Tumblr Utilities</em:description>
     <em:creator>to</em:creator>
     <em:optionsURL>chrome://tombloo/content/prefs.xul</em:optionsURL>
-    <em:updateURL>http://www.asahi-net.or.jp/~xe4r-kmt/extension/tombloo/update.rdf</em:updateURL>
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>2.0</em:minVersion>
-        <em:maxVersion>2.0.0.*</em:maxVersion>
+        <em:maxVersion>3.0.0.*</em:maxVersion>
       </Description>
     </em:targetApplication>
   </Description>

Gyazowin tumblr for Windowsにファイルのアップロード機能を追加して名前をGyamblr for Windowsに変更

前に作ったGyazowin tumblr for Windowsに、ファイルのアップロード機能をつけて、ローカルの画像やテキストファイルをアップロードできるようにしました。

Gyamblr for Windows (was Gyazowin tumblr for Windows)のページからダウンロードできます。

ほんとうははじめI am gathering youを読んでから、OSの持ってるクリップボードのデータのログを取るクリップボードソーシャル、というのをネタで考えていたらTechCrunch Japanese アーカイブ » ControlC―カット&ペーストをウェブサービス化にほんとにまじめに作ってるやつが載ってたのに触発されて、Windowsのコンテキストメニューのコピーとかにcopy to tumblrみたいなのを追加できないかなと思ったんだけど、標準のやつはともかくアプリケーションの右クリックはアプリケーション管轄で制御されていてWindowsシロウト同然の自分には外からいじれなそうだったのであきらめました。

かわりに、じゃあどうやったらかんたんに普段使っているデスクトップとtumblrとをつなげられるかを考えて、で、エクスプローラの送るメニューがわりと便利かなあというわけで調べたらGyazowinにもともとファイルのアップロード機能がついていたのでまたちょっといじって画像だけじゃなくてテキストファイルもアップロードできるようにしてみました。文字コード変換する方法がわからなかったところで一番苦労して嫌になりました。なんかすごい細かくコンパイラに型が違うっていわれたし。BYTE*char*は昔はてきとうにうまいこと流してくれた気がしたけどデフォルトの警告レベルか定義の中身が変わったのかな。

関係ないけどControlCを使ってみての感想

2日ほど使ってみて、アイディアはともかくControlCの実装は使い物にならなかった。名前の通りCtrl-Cを押したときに、そのデータがサーバに送られるのだけれど、カードの番号とかパスワードとか、公開されるとまずいデータがコピーされることもあるので、データ自体はアップロードされるんだけど、デフォルトでは非公開に設定される。あとでブラウザでアクセスして中身を確認して設定を公開に変えて初めて他のひとから見られる状態になる。

やってみるとわかるけど、ふつうに作業をしていると、クリップボードにはどうでもいいようなデータが流れている。文章をかーいているときに、やっぱりこの順番のほうがいいな、と思って並べ替えたときの文章だったり、コードを書いているときにコピーしたひとつの行だったり、同じように#0063DCとかだったり。
ライフログとしてログを取るのは楽しいかもしれないけれど、人に見てもらうような価値はまったくない。どうでもいいようなデータばかりが流れるクリップボードを、もしかしたらコピーしているかもしれないカード番号をチェックするために、手動で確認して公開/非公開を変更するのも no-overhead blogging という観点からあり得ない。

あとから公開したいデータをちまちまマウスで選ぶくらいなら、はじめからCtrl+Alt+Cを押したらコピー&アップロードされるような実装にしたらいいじゃんか。はじめの、クリップボードのログを取るというアイディアにこだわりすぎていると感じた。

今回Windowsのコードを書いていて、もうWindowsのコードを書ける自信がなくなったけど、単純に、起動したときにクリップボードに入ってるデータの型に応じてアップロードするやつを作って、それのショートカットをCtrl+Alt+Tとかで登録しておいて、アップロードしたいときに押す、というのでいいんじゃないかなと思いました。