pve/lib/pve/helper.rb

168 lines
4.3 KiB
Ruby

class Measured
class <<self
def bytes1 v
v = v.to_f
return "%d B" % v if 512 > v
%w[KiB MiBy GiByt TiByte ExiByte PetiByte].each_with_index do |m|
v /= 1024
#return "%.1f %s" % [v, m] if 10 > v
#return "%d %s" % [v, m] if 512 > v
return "%.1f %s" % [v, m] if 512 > v
end
"%d PetiByte" % v
end
def bytes2 v
r = (v.to_i / 1024 / 1024).to_s
return '·' if 0 == r
r.
reverse.
each_char.
each_slice( 3).
to_a.
reverse.
map {|a| a.reverse.join }.
join " "
end
alias bytes bytes2
def seconds i
i = i.to_i
return '·' if 0 == i
return "%d s" % i if 90 > i
i /= 60
return "%d mi" % i if 90 > i
i /= 60
return "%d hou" % i if 36 > i
i /= 24
return "%d days" % i if 14 > i
j = i / 7
return "%d weeks" % j if 25 > j
i /= 365
return "%.1f years" if 550 > i
"%dy" % i
end
end
end
class ColoredString
attr_reader :string, :color_codes
def initialize string, color_codes
@string, @color_codes = string, color_codes
end
def inspect
"#<ColoredString #{@color_codes} #{@string.inspect}>"
end
def length() @string.length end
alias size length
#def to_str() self end
def to_s() "\e[#{@color_codes}m#{@string}\e[0m" end
alias to_str to_s
#alias inspect to_str
include Comparable
def <=>(o) @string <=> o.string end
end
class TablizedOutput
def initialize header, stdout: nil
@header = header.map &:to_s
@columnc = header.size
@maxs = header.map &:length
@stdout ||= STDOUT
@lines = []
end
class B
include Comparable
def <=>(o) @v <=> o.v end
end
class V < B
attr_reader :v, :s
def initialize( v, s=nil) @v, @s = v, s || "#{v}" end
def to_s() @s end
def length() @s.length end
def inspect() "#<TO:V #{@v.inspect} #{@s.inspect}>" end
end
class Percentage < B
attr_reader :v, :w
def initialize( v, w=nil) @v, @w = v, w || 10 end
def length() @w end
def inspect() "#<TO:Percentage #{@v}%>" end
def to_s
y = w - (v*w).round
x = (100*v).round
r = "%*s" % [w, 0==x ? '·' : x]
"\e[0m#{r[0...y]}\e[1;4;#{0.75>v ? 32 : 31}m#{r[y..-1]}\e[0m"
end
end
def push fields
fields =
fields.map do |x|
case x
when String, ColoredString, B then x
else V.new x
end
end
@maxs = @columnc.times.map {|i| [@maxs[i], fields[i].length].max }
@lines.push fields
end
def pushs lines
lines.each &method( :push)
end
def print order: nil
format = "#{(["\e[%%sm%% %ds\e[0m"] * @columnc).join( ' ') % @maxs}\n"
ls = @lines
if order
eval <<-EOC, binding, __FILE__, 1+__LINE__
ls = ls.sort {|a,b|
[#{order.map {|i| 0 < i ? "a[#{i-1}]" : "b[#{-i-1}]" }.join ', '}] <=>
[#{order.map {|i| 0 < i ? "b[#{i-1}]" : "a[#{-i-1}]" }.join ', '}]
}
EOC
end
#ls = ls.sort_by {|e| p e; order.map &e.method(:[]) } if order
@stdout.printf format, *@header.flat_map {|s|['',s]}
ls.each {|l| @stdout.printf format, *l.flat_map {|s| s.is_a?(ColoredString) ? [s.color_codes, s.string] : ["", s.to_s] } }
end
def virt v
ha = v.respond_to?( :ha) ? v.ha : nil
unknown = V.new 0, '-'
push [
case v.status
when "running", "online" then ColoredString.new v.status, "32"
when "stopped" then ColoredString.new v.status, "31"
else v.status
end,
ha&.state || '·',
case v.t
when "nd" then ColoredString.new v.sid, "33"
when "qm" then ColoredString.new v.sid, "35"
when "ct" then ColoredString.new v.sid, "36"
else v.sid
end,
v.name, v.node.is_a?(String) ? v.node : v.node.node,
v.respond_to?(:uptime) ? V.new( v.uptime, Measured.seconds( v.uptime)) : unknown,
v.respond_to?(:cpu) ? Percentage.new( v.cpu) : unknown,
v.respond_to?(:mem) ? V.new( v.mem, Measured.bytes( v.mem)) : unknown,
v.respond_to?(:maxmem) ? Percentage.new( v.mem/v.maxmem.to_f) : unknown,
v.respond_to?(:disk) ? V.new( v.disk.to_i, Measured.bytes( v.disk.to_i)) : unknown,
if v.respond_to?(:maxdisk) and 0 < v.maxdisk.to_i
Percentage.new( v.disk.to_f/v.maxdisk.to_f)
else unknown end,
]
end
end