2008年 01月 03日

Gyazo みたいにスクリーンショットを即 fotolife にアップロードするやつ

http://subtech.g.hatena.ne.jp/antipop/20071121/1195652375 を Ruby + Pit + atomutil とかで書いてみました。

最初は Perl のままアカウント情報のところだけ pit つかうようにしようと思ったのだけど、Pit もづーるがほしくなったりして、つくるなら Perl かかないととかいろいろ考えてたら Ruby で書いてしまっていた。

2008年 01月 02日

RSpec

atomutil のテスト書くときに (一行たしただけだけど)、はじめてさわったけど、思ったよりよさそうだ (食わず嫌いだった)

とりあえず assert_equal って補完使っても入力するのめんどくさいんだよね……

gerry++

おなかいたいわけじゃないけどなぜか gerry...

アカウント情報を管理するコマンド pit

というのを適当にでっちあげてみました (まだ gem source に反映されてないかも)。こまごまとした自動化スクリプトで、毎回 ~/domain.yaml とかにパスワード書いたりして分離するのがめんどうくさいので、そのへんをうまいことやってくれる gem です。

require "rubygems"
require "pit"

config = Pit.get("vox.com", :require => {
	"username" => "your email in Vox",
	"password" => "your password in Vox",
	"nickname" => "your subdomain in Vox"
})

みたいに書いておくと、設定されてない場合は $EDITOR で設定ファイルを開いて保存し、設定情報が config に入ります。

コマンドラインからもセットすることができて

$ pit set vox.com

とかやると、設定名が vox.com である設定を $EDITOR でひらきます。

でもって、設定のセット (プロファイル) をいくつかつくることができて、デフォルトだと default というプロファイルに保存されます。

$ pit switch devel

とかでプロファイルの切り替えができます。(プロファイル名に何も指定しないと default にもどります)


Ruby 以外でも一応つかえるように

pit get foobar

を実行すると $stdout に YAML をはきます (ただし tty のときはパスワードふくむときこわいので出力しません pit get foo | lv とかやるとみれる)


保存された設定は ~/.pit に特に暗号化されずに保存されます。

twitter4r

require "time"
require "rubygems"
gem "twitter4r"
require "twitter"
require "pit"

Twitter::Client.new(Pit.get("twitter.com", :require => {
	"login"    => "login name",
	"password" => "password"
})).status(:post, "Test posting from twitter4r with pit.")
2008年 01月 01日

Ruby の Atom/AtomPub ライブラリ

atomutil がいいっぽいですね。http://rubyforge.org/projects/atomutil/ とかいうか他に選択肢ない感 (rubyforge で atom を検索するといっぱいでてくるけど、殆どハズれ (リリースいっこもない))

つかってみたら、feed.links に feed 直下の要素ではない link 要素も含まれてしまう。

--- atomutil.rb.orig	2008-01-01 15:07:56.000000000 +0900
+++ atomutil.rb	2008-01-01 15:05:54.000000000 +0900
@@ -604,10 +604,10 @@
     def child_xpath(ns, element_name, attributes=nil)
       ns_uri = ns.is_a?(Namespace) ? ns.uri : ns
       unless !attributes.nil? && attributes.is_a?(Hash)
-        "descendant-or-self::*[local-name()='#{element_name}' and namespace-uri()='#{ns_uri}']"
+        "child::*[local-name()='#{element_name}' and namespace-uri()='#{ns_uri}']"
       else
         attr_str = attributes.collect{|key, val| "@#{key.to_s}='#{val}'"}.join(' and ')
-        "descendant-or-self::*[local-name()='#{element_name}' and namespace-uri()='#{ns_uri}' and #{attr_str}]"
+        "child::*[local-name()='#{element_name}' and namespace-uri()='#{ns_uri}' and #{attr_str}]"
       end
     end
   end

rubyforge の Tracker は使われてんのかなぁ……

ref. http://d.hatena.ne.jp/lyokato/20071211/1197353609

URI#path がつかわれてるけど、Atom ってクエリ文字列ふくんでる URI はダメなのかな……

client.get_resource("http://example.com/foo?bar") がたぶん失敗する (URI#path => "/foo")。rfc5023 には特に query についての記述はないっぽいけど、こういうリソースが妥当なのかどうか (実際あるのか) わからない。

atomutil で fotolife API をたたいてみる

fotolife API は Atom 0.3 なのでちょっとだけ工夫がいるのですが

require "rubygems"
require "atomutil"
require "yaml"
require "pathname"

file = Pathname.new("2150944907_5be2ee34ac.jpg")

entry = Atom::Entry.new({
	:title => file.basename.to_s,
	:updated => Time.now,
	:content => Atom::Content.new { |c|
		c.body = [file.read].pack('m')
		c.type = "image/jpeg"
		c.set_attr(:mode, "base64")
	},
})
puts entry.to_s

config = YAML.load(Pathname.new("~/.hatena.ne.jp.yaml").expand_path.read)
client = Atompub::Client.new({
	:auth => Atompub::Auth::Wsse.new(:username => config["user"], :password => config["pass"])
})

post_uri = "http://f.hatena.ne.jp/atom/post"
p post_uri
p client.create_entry(post_uri, entry, file.basename.to_s)

とやるとできるみたいです。Atom::Entry とかがブロックをとれるので綺麗にかけていいですね! (mode="base64" は Atom 1.0 だとなくて、バイナリをそのまま Content-Type 指定して送信するみたい (まだちゃんと読んでないけど……)。base64 でいけると XHR でも画像が POST できるからいいんだけどなぁ)

ちなみに拡張子から mime-type への変換は WEBrick 使うと簡単です (mechanize でもこうやってる)

require "webrick/httputils"
mime_type = WEBrick::HTTPUtils.mime_type("foo.jpg", WEBrick::HTTPUtils::DefaultMimeTypes)
p mime_type #=> "image/jpeg"

flickr の画像そのものの URL から、もとの HTML へ戻るブックマークレット

javascript:(function c(s,i,a){if(a){window.jsonFlickrApi=c;s.type="text/javascript";s.src="http://api.flickr.com/services/rest/?method=flickr.photos.getInfo&format=json&api_key=13b98c6e595d688ce25febb790f85bc5&photo_id="+i;document.body.appendChild(s);}else{location=(s.photo.urls.url[0]._content)}})(document.createElement("script"),RegExp("http://farm\\d+.static.flickr.com/\\d+/([^_]+)_").exec(location)[1],document,1);

http://farm3.static.flickr.com/2365/2153801040_558425c251_m.jpg みたいなとこから、もどるときユーザ名がわからないからめんどくさい。

やってることは flickr.photos.getInfo を JSONP で叩いているだけです。画像の URL も HTML として扱えるブラウザならうごきます (Opera はだめ。IE はしらない)

Opera でも動くようにしました。id:os0x さんありがとう!

もっと短かくしてみた

javascript:(function c(d,i){if(i)d.body.appendChild(s=d.createElement("script"),s.type="text/javascript",s.src="http://api.flickr.com/services/rest/?method=flickr.photos.getInfo&format=json&api_key=13b98c6e595d688ce25febb790f85bc5&photo_id="+i,jsonFlickrApi=c);else{location=d.photo.urls.url[0]._content}})(document,/\/\d+\/([^_]+)/.exec(location.pathname)[1]);

flickr 自体にリダイレクタがあるみたいです。→ http://monaural.net/post/2008/12/flickr-url/

2007年 12月 31日

みぎくりく

なんか右クリックすると Open Selection Links in Tabs が暴発することがかなりある…… たぶん右クリックメニューの挙動が変なんだろうけど、セレクションがないのにセレクションがあると勘違いするバグとの相乗効果でかなり困る。何がわるいんだろ……

2007年 12月 30日

userscripts.org 更新するのめんどくさい