2008/4/28: 遅すぎるけど、Tumblrの画像データのホスト名が変わったので対応。 data.tumblr.com が media.tumblr.com になった。
FastladderでTumblrのfeedを購読して、ReblogCommandでReblogするという使い方をしているのだけど、画像が多い場合に読み込み速度がネックになってあまり快適でない。
""Mechanizeをcronで定期的に回してあらかじめtumblr Dashboardの画像とかをpolipo cacheに入れておくと閲覧速くなるよ lang:ja
""
""[[http://twitter.com/otsune/statuses/765543764]]
というわけで、クイックハックやってみた。
RubyでもWWW::Mechanizeはあるので、初めはそれを使おうと思ってたんだけど、よく考えると、feedの画像を読むので特に必要ないかなと思い直して、普通に画像を取得する事にした。ネットワーク周りはよくわからないんだけど、Keep Aliveなんかはpolipoがやってくれるのかしら?とか疑問に思いながらも、なんだかんだで以下の通り完成。
とりあえず、PC起動したら手動でこのスクリプトを走らせておいて、先読みが完了したらフィードを読みに行く事にしている。フィード読み始めた時には既にキャッシュされているので画像がすぐに表示されるよ。
FEED_LIST は feed の uri を改行で区切ったテキスト。先読み完了時に Growl 通知を使わない場合は GROWL を false にする。
#!/opt/local/bin/ruby -Ku
#$DEBUG = true
$VERBOSE = true
require 'open-uri'
require 'pstore'
module Tumblr
module Cache
FEED_LIST = "./prefetch.conf" #フィードのアドレスリスト
CACHED = "./cache/prefetch" #キャッシュを保存するファイル
PROXY = "http://localhost:8123/" # polipo
GROWL = false #終了をGrowlで通知するかどうか
end
end
Dir.chdir(File.dirname(__FILE__))
routes = []
uris = []
fresh = []
errors = []
puts 'start'
File.open(Tumblr::Cache::FEED_LIST) do |conf|
conf.each_line do |uri|
uri = uri.strip
next if uri =~ /^#/
next if uri == ""
routes.push uri
end
end
routes2 = routes.dup
routes.uniq!
(routes2 - routes).each do |redundant|
printf "redundancy: %s\n", redundant
end
printf "total: %d\n", routes.size
routes.each_with_index do |route, idx|
begin
URI.extract(URI.parse(route).read, ['http']).each do |path|
if path =~ /^http\:\/\/media\.tumblr\.com\/.+\.(jpg|jpeg|png|gif)$/
uris.push path
end
end
printf "%d/%d: %s.\n", idx+1, routes.size, route
rescue Exception => e
errors.push e.to_s
printf "Error %d/%d: %s.\n", idx+1, routes.size, e.to_s
end
end
db = PStore.new(Tumblr::Cache::CACHED)
db.transaction do
cache = db['cache'] || Array.new
fresh = uris - cache
uris.each do |line|
cache.push line
end
db['cache'] = cache.uniq
end
printf "total: %d\n", fresh.size
fresh.each_with_index do |resrc, idx|
begin
open(resrc, {:proxy => Tumblr::Cache::PROXY})# {|f| f.read }
printf "%d/%d: %s.\n", idx+1, fresh.size, resrc
rescue Exception => e
errors.push e.to_s
printf "Error %d/%d: %s.\n", idx+1, fresh.size, e.to_s
end
end
puts "Done."
if errors.size > 0
printf "Error: %d\n", errors.size
errors.each_with_index do |error, idx|
printf "%d/%d: %s.\n", idx+1, errors.size, error
end
end
if Tumblr::Cache::GROWL
require 'rubygems'
require 'ruby-growl'
Growl.new('localhost', "ruby-grow", ["ruby-growl Notification"]).notify("ruby-growl Notification", "Tumblr prefetcher", "Done.")
end