Created
October 12, 2008 21:05
-
-
Save yhara/16467 to your computer and use it in GitHub Desktop.
A sample code of 'treemap' gem (and Rack). [1] du ~/ > a.du [2] edit path to a.du [3] rackup du.ru
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'yaml' | |
require 'rubygems' | |
require 'treemap' | |
require 'rack' | |
# monkey patch for treemap :-( | |
class Treemap::HtmlOutput | |
def node_label(node) | |
node.label | |
end | |
end | |
class DUParser | |
Entry = Struct.new(:size, :bytes, :path) | |
def initialize(src) | |
@data = src.lines.map{|x| | |
size, *rest = x.chomp.split(/\t/) | |
Entry.new(size.strip, size_to_bytes(size.strip), rest.join("\t")) | |
} | |
end | |
TYPES = { | |
"B" => 1, | |
"K" => 1024, | |
"M" => 1024 * 1024, | |
"G" => 1024 * 1024 * 1024, | |
"T" => 1024 * 1024 * 1024 * 1024, | |
"P" => 1024 * 1024 * 1024 * 1024 * 1024, | |
} | |
def size_to_bytes(s) | |
_, n, t = s.match(/([\d.]+)(.)/).to_a | |
if (m = TYPES[t]) | |
(n.to_f * m).to_i | |
else | |
raise ArgumentError, "bad size format: unknown size type: #{t}" | |
end | |
end | |
def ls(subpath) | |
@data.select{|entry| | |
(entry.path =~ %r<\A#{Regexp.quote subpath}(.+)>) and ($1 !~ %r<[^\\]/>) | |
}.map{|entry| | |
Entry.new(entry.size, entry.bytes, entry.path.sub(subpath, "")) | |
} | |
end | |
end | |
class TreemapApp | |
def initialize(path) | |
@parser = DUParser.new(File.read(path)) | |
@writer = Treemap::HtmlOutput.new{|o| | |
o.width = 800 | |
o.height = 600 | |
o.center_labels_at_depth = 1 | |
} | |
end | |
def call(env) | |
req = Rack::Request.new(env) | |
res = Rack::Response.new | |
res.write make_tree(req.path_info, @parser.ls("."+req.path_info)) | |
res.finish | |
end | |
def make_tree(here, data) | |
root = Treemap::Node.new | |
data.each do |entry| | |
newpath = "#{here}#{entry.path}/" | |
label = "#{entry.path}<br>(#{entry.size})" | |
root.new_child :size => entry.bytes, | |
:label => "<a href='#{newpath}' title='#{label}'>#{label}</a>" | |
end | |
@writer.to_html(root) | |
end | |
end | |
unless $NO_RUN | |
use Rack::Reloader | |
use Rack::CommonLogger | |
use Rack::ShowExceptions | |
use Rack::ShowStatus | |
run TreemapApp.new("/Users/yhara/a.du") | |
end | |
# vim: set ft=ruby: | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$NO_RUN = true | |
load 'du.ru' | |
DU_SAMPLE = <<EOD | |
36B ./A | |
4.0K ./B | |
2.0K ./C/chocolate | |
10B ./C/call\\/cc | |
4.0K ./C | |
2.0K ./D\\/F | |
100K . | |
EOD | |
describe "DUParser" do | |
before :each do | |
@parser = DUParser.new(DU_SAMPLE) | |
end | |
# it should take the path of the file which contains an output of 'du' command | |
it "は、インスタンス生成時にduの出力ファイルをとる" do | |
@parser.should be_an_instance_of(DUParser) | |
end | |
# it should convert size to bytes | |
it "は、サイズをバイト数に直せる" do | |
@parser.size_to_bytes("100B").should == 100 | |
@parser.size_to_bytes("0.5K").should == 512 | |
@parser.size_to_bytes("3M").should == (3 * 1024 * 1024) | |
end | |
# it should list up the directories under a given directory | |
it "は、指定したディレクトリ以下の情報を検索できる" do | |
@parser.ls("./").should == [ | |
DUParser::Entry.new("36B", 36, "A"), | |
DUParser::Entry.new("4.0K", 4096, "B"), | |
DUParser::Entry.new("4.0K", 4096, "C"), | |
DUParser::Entry.new("2.0K", 2048, "D\\/F") | |
] | |
@parser.ls("./C/").should == [ | |
DUParser::Entry.new("2.0K", 2048, "chocolate"), | |
DUParser::Entry.new("10B", 10, "call\\/cc"), | |
] | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment