summaryrefslogtreecommitdiffstats
path: root/philesight
diff options
context:
space:
mode:
authorFlorian Pritz <bluewind@xinu.at>2011-10-23 22:01:53 +0200
committerFlorian Pritz <bluewind@xinu.at>2011-10-23 22:02:18 +0200
commitebc82b27288df5c58194083ead4a6e6de7f52d21 (patch)
tree30d4e874cc19a03dfc62a0ee7c6c5e6c9756d4ec /philesight
parent44c6e7dfa4967843b05ee961fd243f655ed31717 (diff)
downloadaur-packages-ebc82b27288df5c58194083ead4a6e6de7f52d21.tar.gz
aur-packages-ebc82b27288df5c58194083ead4a6e6de7f52d21.tar.xz
mass update (again :( )
Signed-off-by: Florian Pritz <bluewind@xinu.at>
Diffstat (limited to 'philesight')
-rw-r--r--philesight/README100
-rwxr-xr-xphilesight/philesight62
-rwxr-xr-xphilesight/philesight.cgi127
-rw-r--r--philesight/philesight.rb458
4 files changed, 0 insertions, 747 deletions
diff --git a/philesight/README b/philesight/README
deleted file mode 100644
index 1a9905e..0000000
--- a/philesight/README
+++ /dev/null
@@ -1,100 +0,0 @@
-
-Summary
-=======
-
-Philesight is a tool to browse your filesystem and see where the diskspace is
-being used at a glance. Philesight is implemented as a simple command line
-program that generates PNG files; a wrapper CGI script is supplied to allow
-navigating through the filesystem.
-
-Philesight is actually a clone of the filelight program. Wheres filelight is
-ment as an interactive, user friendly application for the X-windows desktop,
-philesight is designed to run on a remote server without graphical user
-interface.
-
-
-Dependencies
-============
-
-Philesight is written in ruby1.8, and requires the berkely-db4 and cairo
-ruby-libraries.
-
-Changelog
-=========
-
-2008-05-29 Added option (use_gradients) to enable/disable gradients
- in circular graph. Added option to set graph size.
-
-2008-04-16 Added optional table with file list to cgi, some bugfixes,
- increased default graph size to 800. (Thanks to Guillaume
- Sachot)
-
-2008-03-17 Fixed bug where no image was shown with CGI's running
- on apache-mpm-worker.
-
-2007-03-12 Fixed crash when indexing file named 'rest'
-
-2006-12-09 Workaround for segmentaion fault with ruby 1.8.5
-
-Usage
-=====
-
-Philesight can be run in different modes: first, the filesystem is indexed
-and the results are stored in a database. When the database is generated, the
-tool can used to generate PNG files with the graphs. The database should be
-updated every once in a while of course.
-
- * Index bulding:
-
- ./philesight --db {db} --index {path}
-
- {db} is the name of the database file that will be generated. It is a good
- idea to throw away existing database files before indexing to avoid removed
- files showing in your graph.
-
- {path} is the top-level directory to start indexing. Usually, '/' is a
- good choice.
-
- This process might take some time, since it traverses the whole tree
- from path-to-index downward and stores the data into the db. Make
- sure to remove previous database files before indexing.
-
-
- * PNG generating: In this mode, philesight generates a graph of the
- filesystem from path and 4 levels downward. i
-
- ./philesight --db {db} --path {path} --draw {png}
-
- {db} is the filename of the index file that was generated earlier,
- {path} is the directory which should be drawn, and {png} is the filename
- of the to-be-generated PNG image file
-
-
- * CGI: Philesight comes with a CGI module that can be run from within a
- web server. Edit the configurable parameters in the top of this file
- to point to the database. Make sure the datbase file is readable by
- the webserver!
-
- Available options:
-
- * db: Path to database file.
-
- * default_path: default path to show when CGI first loads.
-
- * size: graph size. 800 pixels is often a good choice.
-
- * show_list: render list of directories and their sizes blow graph.
-
- * use_gradients: use gradient colors in graph (set to 'false' to generate
- smaller PNG files)
-
-
-Bugs
-====
-
- * Philesight is a ruby program, and thus is not particulary fast.
- * Indexing takes longer than necassery.
- * Proper error handling is mostly missing.
- * Not very well tested.
- * It might eat your disks.
-
diff --git a/philesight/philesight b/philesight/philesight
deleted file mode 100755
index 5ab0e09..0000000
--- a/philesight/philesight
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/ruby
-# vi: ts=2 sw=2
-
-require 'getoptlong'
-require 'philesight'
-
-opts = GetoptLong.new(
- [ "--index", "-i", GetoptLong::REQUIRED_ARGUMENT ],
- [ "--draw", "-d", GetoptLong::REQUIRED_ARGUMENT ],
- [ "--path", "-p", GetoptLong::REQUIRED_ARGUMENT ],
- [ "--db", "-D", GetoptLong::REQUIRED_ARGUMENT ],
- [ "--dump", "-u", GetoptLong::NO_ARGUMENT ],
- [ "--help", "-h", GetoptLong::NO_ARGUMENT ]
-)
-
-def usage
- puts
- puts "usage: philesight <options>"
- puts
- puts "Options:"
- puts " --db <db> Set path to database file"
- puts " --path <path> Path to show in generated image"
- puts " --index <path> Top-level directory to start indexing"
- puts " --dump Dump database to readable format"
- puts
- puts "Examples:"
- puts " Index to database: philesight --db <db> --index <path>"
- puts " Generate PNG: philesight --db <db> --path <path> --draw <png>"
- puts
-end
-
-
-t = Philesight.new
-path = ""
-
-opts.each do |opt, arg|
-
- case opt
- when "--draw"
- t.draw(path, arg)
-
- when "--index"
- t.readdir(arg)
-
- when "--path"
- path = arg
-
- when "--db"
- t.db_open(arg)
-
- when "--dump"
- t.dump
-
- else
- usage
-
- end
-end
-
-#
-# End
-#
diff --git a/philesight/philesight.cgi b/philesight/philesight.cgi
deleted file mode 100755
index 969269a..0000000
--- a/philesight/philesight.cgi
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/usr/bin/ruby
-# vi: ts=4 sw=4
-
-require 'philesight'
-require 'cgi'
-
-# Config variables
-
-db = "./ps.db"
-default_path = "/"
-size = 800
-show_list = true
-use_gradients = true
-
-# Get parameters from environment and CGI. ISMAP image maps do not return a
-# proper CGI parameter, but only the coordinates appended after a question
-# mark. If this is found in the QUERY_STRING, assume the 'find' command
-
-cgi = CGI.new;
-qs = ENV["QUERY_STRING"]
-cmd = cgi.params['cmd'][0]
-path = cgi.params['path'][0] || default_path
-
-if(qs && qs =~ /\?(\d+,\d+)/ ) then
- find_pos = $1
- cmd = 'find'
-end
-
-ps = Philesight.new(4, size, use_gradients)
-ps.db_open(db)
-
-# Perform action depending on 'cmd' parameter
-
-case cmd
-
- when "img"
- puts "Content-type: image/png"
- puts
- $stdout.flush
- ps.draw(path, "-")
-
- when "find"
- if(find_pos =~ /(\d+),(\d+)/) then
- x, y = $1.to_i, $2.to_i
- url = "?path=%s" % ps.find(path, x, y)
- puts "Content-type: text/html"
- puts
- puts '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
- puts '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" >'
- puts '<head>'
- puts ' <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'
- puts ' <meta http-equiv="refresh" content="0; url=' + "#{url}" + '">'
- puts '</head>'
- puts '<body></body>'
- puts '</html>'
- end
-
- else
- random = ""
- 1.upto(32) { random += (rand(26) + ?a).chr }
- puts "Content-type: text/html"
- puts
- puts '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
- puts '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" >'
- puts '<head>'
- puts ' <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'
- puts " <title>Disk usage : #{path}</title>"
- puts ' <style type="text/css">'
- puts ' <!--'
- puts ' body {color:black;text-align:center;background:#FAFAFA;}'
- puts ' table {margin:auto;width:780px;}'
- puts ' table,td {border:0;}'
- puts ' td {padding:4px;text-align:left;}'
- puts ' td.size {text-align:right;}'
- puts ' thead td {font-weight:bold;border-bottom:1px solid black;background:#EEE;}'
- puts ' tbody td {background:#F0F0F0;}'
- puts ' tbody tr.parentdir td {background:#E5D0D0;}'
- puts ' tbody tr.evenrow td {background:#E4E4E4;}'
- puts ' '
- puts ' -->'
- puts ' </style>'
- puts '</head>'
- puts '<body>'
- puts ' <p><a href="' + "?path=#{path}&amp;" + '">'
- puts ' <img style="border:0" width="#{size}" height="#{size}" src="?cmd=img&amp;r=' + "#{random}&amp;path=#{path}" + '" ismap="ismap" alt="' + "#{path}" + '" />'
- puts ' </a></p>'
-
- if show_list then
- # Array of files
- content = ps.listcontent("#{path}")
- if(content && content[0]) then
- puts ' <table summary="File lists">'
- puts ' <thead>'
- puts ' <tr><td>Filename</td><td class="size">Size</td></tr>'
- puts ' </thead>'
- puts ' <tbody>'
- puts ' <tr class="parentdir"><td>' + content[0][:path].to_s + '</td><td class="size">' + content[0][:humansize].to_s + '</td></tr>'
-
- if(content[1].size > 0) then
- linenum = 0
-
- content[1] = content[1].sort_by { |f| - f[:size] }
- content[1].each do |f|
- if(linenum%2 == 0) then
- print ' <tr class="evenrow">'
- else
- print ' <tr>'
- end
-
- puts '<td><a href="?path='+ CGI.escape(f[:path].to_s) +'">' + f[:path].to_s + '</a></td><td class="size">' + f[:humansize].to_s + '</td></tr>'
-
- linenum += 1
- end
- end
- puts ' </tbody>'
- puts ' </table>'
- end
- end
-
- puts '</body>'
- puts '</html>'
-end
-
-#
-# End
-#
-
diff --git a/philesight/philesight.rb b/philesight/philesight.rb
deleted file mode 100644
index b669927..0000000
--- a/philesight/philesight.rb
+++ /dev/null
@@ -1,458 +0,0 @@
-#!/usr/bin/ruby
-# vi: ts=2 sw=2
-
-require 'getoptlong'
-require 'cgi'
-require 'cairo'
-require 'bdb'
-
-class PNGWriter
-
- def initialize(fname)
- if fname != "-" then
- @fd = File.open(fname, "w")
- end
- end
-
- def write(data)
- if @fd then
- @fd.write(data)
- else
- print(data)
- end
- return data.length
- end
-end
-
-
-class Philesight
-
- def initialize(ringcount=4, size=800, use_gradient=true)
- @max_files_per_dir = 50
- @w = size
- @h = size
- @cx = @w / 2
- @cy = @h / 2
- @ringcount = ringcount
- @ringwidth = ((size-50)/2) / (ringcount+1)
- @use_gradient = use_gradient
- @find_a = 0
- @find_r = 0
- end
-
-
- #
- # Open the database. Try read-write mode first, if this fails, re-open readonly
- #
-
- def db_open(fname)
- begin
- @db = BDB::Btree.open fname , nil, BDB::CREATE, 0644, "set_pagesize" => 1024, "set_cachesize" => [0, 32*1024,0]
- rescue
- @db = BDB::Btree.open fname , nil, BDB::RDONLY, 0644, "set_pagesize" => 1024, "set_cachesize" => [0, 32*1024,0]
- end
- end
-
-
- #
- # Dump database in human-readable form
- #
-
- def dump
- @db.keys.each do |f|
- puts "%s %s" % [ f, Marshal::load(@db[f]).inspect ]
- end
- end
-
-
- #
- # Concatenate a directory and a filename
- #
-
- def addpath(a, b)
- return a + b if(a =~ /\/$/)
- return a + "/" + b
- end
-
-
- #
- # Read a directory and add to the database; this function is recursive
- # for sub-directories
- #
-
- def readdir(dir)
-
- size_file = {}
- size_dir = {}
- size_total = 0
-
- # Traverse the directory and collect the size of all files and
- # directories
-
- begin
- Dir.foreach(dir) do |f|
-
- if(f != "." && f != "..") then
-
- f_full = addpath(dir, f)
- stat = File.lstat(f_full)
-
- if(!stat.symlink?) then
-
- if(stat.file?) then
- size = File.size(f_full)
- size_file[f] = size
- size_total += size
- end
-
- if(stat.directory?) then
- size = readdir(f_full)
- if(size > 0) then
- size_dir[f] = size
- size_total += size
- end
- end
- end
- end
-
- end
- rescue SystemCallError => errmsg
- puts errmsg
- end
-
- # If there are a lot of small files in this directory, group
- # the smallest into one entry to avoid clutter
-
- if(size_file.keys.length > @max_files_per_dir) then
- list = size_file.keys.select { |f| size_file[f] < size_total / @max_files_per_dir }
- rest = 0
- list.each do |f|
- rest += size_file[f]
- size_file.delete(f)
- end
- size_file['rest'] = rest
- end
-
- # Store the files in the database
-
- size_file.keys.each do |f|
- f_full = addpath(dir, f)
- @db[f_full] = Marshal::dump( [ size_file[f], [] ] )
- end
-
- # Store this directory with the list of children in the database
-
- size = size_dir.merge(size_file)
- children = size.keys.sort
- @db[dir] = Marshal::dump( [ size_total, children ] )
- return size_total
- end
-
-
- #
- # Draw one section
- #
-
- def draw_section(cr, ang_from, ang_to, r_from, r_to, brightness)
-
- ang_to, ang_from = ang_from, ang_to if (ang_to < ang_from)
-
- if(brightness > 0) then
- r, g, b = hsv2rgb((ang_from+ang_to)*0.5 / (Math::PI*2), 1.0-brightness, brightness/2+0.5)
- else
- r, g, b = 0.9, 0.9, 0.9
- end
-
- # Instead of using the r_from and r_to for the radial pattern, the stops
- # are calculated. This is to work around a bug in cairo
-
- r_total = ((@w - 50) / 2).to_f
- pat = Cairo::RadialPattern.new(@cx, @cy, 0, @cx, @cy, r_total)
- if @use_gradient then
- pat.add_color_stop_rgb(r_from / r_total, r*0.8, g*0.8, b*0.8)
- pat.add_color_stop_rgb(r_to / r_total, r*1.5, g*1.5, b*1.5)
- else
- pat.add_color_stop_rgb(0, r, g, b)
- end
-
- cr.new_path
- cr.arc(@cx, @cy, r_from, ang_from, ang_to)
- cr.arc_negative(@cx, @cy, r_to, ang_to, ang_from)
- cr.close_path
-
- cr.set_source(pat)
- cr.fill_preserve
- end
-
-
- #
- # Draw ring. This function is recursive for the outer rings
- #
-
- def draw_ring(cr, level, ang_min, ang_max, path)
-
- ang_from = ang_min
- ang_to = ang_min
- ang_range = (ang_max - ang_min).to_f
- r_from = level * @ringwidth
- r_to = r_from + @ringwidth
-
- unless(@db[path]) then
- return "/"
- end
-
- total_path, child_path = Marshal::load( @db[path] )
-
- # Draw a section proportional to the size of each file or subdir
-
- child_path.each do |f|
-
- f_full = addpath(path, f)
- total_f, child_f = Marshal::load( @db[f_full] )
-
- # Calculate start and end angles and draw section
-
- ang_from = ang_to
- ang_to += ang_range * total_f / total_path if(total_path > 0)
- brightness = r_from.to_f / @cx
- brightness = 0 if(f == 'rest')
- draw_section(cr, ang_from, ang_to, r_from, r_to, brightness) if(cr)
-
- # If we are looking for the path of an (x,y) pair, check if this section matches
-
- if( (@find_a >= ang_from) && (@find_a <= ang_to) && (@find_r >= r_from) && (@find_r <= r_to) ) then
- @find_path = f_full
- end
-
- # Draw outer rings
-
- if(level < @ringcount) then
- draw_ring(cr, level+1, ang_from, ang_to, f_full)
- else
- draw_section(cr, ang_from, ang_to, r_to, r_to+5, 0.5) if(cr && child_f.nitems > 0)
- end
-
- # Generate and save labels of filenames/sizes
-
- if(cr && (ang_to - ang_from > 0.2)) then
- size = filesize_readable(total_f)
- x, y = pol2xy((ang_from+ang_to)/2, (r_from+r_to)/2)
- label = {}
- label[:x] = x
- label[:y] = y
- label[:text] = "%s\n%s" % [ f, size]
- @labels << label
- end
- end
- end
-
-
- #
- # Draw graph of the given path
- #
-
- def draw(path, fname)
-
- # Create drawing context, white background
-
- format = Cairo::FORMAT_ARGB32
- surf = Cairo::ImageSurface.new(format, @w, @h)
- cr = Cairo::Context.new(surf)
- writer = PNGWriter.new(fname)
-
- # Draw top level filename and size
-
- unless(@db[path]) then
- draw_text(cr, @cx, @cy, "Path '#{path}' not found in database", 12)
- cr.target.write_to_png(writer)
- return
- end
-
- total_path, child_path = Marshal::load( @db[path] )
- draw_text(cr, @cx, 10, "%s (%s)" % [ path, filesize_readable(total_path) ], 14, true)
- draw_text(cr, @cx, @cy, "cd ..", 14, true)
-
- # Draw rings, recursively
-
- @labels = []
- draw_ring(cr, 1, 0, Math::PI*2, path)
-
- # Draw circles on ring borders
-
- cr.set_source_rgba(0, 0, 0, 0.7)
- 0.upto(@ringcount+1) do | level |
- cr.new_path
- cr.set_line_width(0.3)
- cr.arc(@cx, @cy, level * @ringwidth, 0, 2*Math::PI)
- cr.stroke
- end
-
- # Draw labels on top of graph
-
- @labels.each do |label|
-
- cr.select_font_face("Sans", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL)
- cr.set_font_size(9)
-
- # Draw text 4 times in a dark color, one time white on top
-
- [[-1, 0, 0.2], [+1, 0, 0.2], [0, -1, 0.2], [0, +1, 0.2], [0, 0, 0.9]].each do |dx, dy, color|
- cr.set_source_rgba(color, color, color, 1.0)
- draw_text(cr, label[:x]+dx, label[:y]+dy, label[:text])
- end
-
- end
-
- # Generate PNG file
-
- cr.target.write_to_png(writer)
- end
-
-
- #
- # List files/dir of the given path
- #
-
- def listcontent(path)
-
- unless(@db[path]) then
- return nil
- end
-
- dircontent = []
-
- total_path, child_path = Marshal::load( @db[path] )
-
- currentdir = {}
- currentdir[:path] = path
- currentdir[:humansize] = filesize_readable(total_path)
-
- child_path.each do |f|
- f_full = addpath(path, f)
- total_f, child_f = Marshal::load( @db[f_full] )
-
- fileinfo = {}
- fileinfo[:path] = f_full
- fileinfo[:size] = Integer(total_f)
- fileinfo[:humansize] = filesize_readable(total_f)
- dircontent << fileinfo
- end
-
- return [currentdir, dircontent]
- end
-
-
- #
- # Find the path belonging to a (x,y) position in the graph
- #
-
- def find(path, x, y)
- @find_a, @find_r = xy2pol(x, y)
- @find_path = File.dirname(path)
- draw_ring(nil, 1, 0, Math::PI*2, path)
- @find_path
- end
-
-
- private
-
-
- #
- # Draw text on pos x,y
- #
-
- def draw_text(cr, x, y, text, size=11, bold=false)
-
- lines = text.count("\n") + 1
- y -= (lines-1) * (size+2) / 2.0
-
- cr.select_font_face("Sans", Cairo::FONT_SLANT_NORMAL, bold ? Cairo::FONT_WEIGHT_BOLD : Cairo::FONT_WEIGHT_NORMAL)
- cr.set_font_size(size)
-
- text.split("\n").each do |line|
- extents = cr.text_extents(line)
- w = extents.width
- h = extents.height
- cr.move_to(x - w/2, y + h/2)
- cr.show_text(line)
- y += size+2
- end
- end
-
-
- #
- # convert color from (h,s,v) to (r,g,b) colorspace
- #
-
- def hsv2rgb(h, s, v)
-
- h = h.to_f
- s = s.to_f
- v = v.to_f
-
- h *= 6.0
- i = h.floor
- f = h - i
- f = 1-f if ((i & 1) == 0)
- m = v * (1 - s)
- n = v * (1 - s * f)
- i=0 if(i<0)
- i=6 if(i>6)
-
- case i
- when 0, 6: r=v; g=n; b=m
- when 1: r=n; g=v; b=m
- when 2: r=m; g=v; b=n
- when 3: r=m; g=n; b=v
- when 4: r=n; g=m; b=v
- when 5: r=v; g=m; b=n
- end
-
- [r, g, b]
- end
-
-
- #
- # Convert polair (ang,radius) coordinate to cartesian (x,y)
- #
-
- def pol2xy(a, r)
- x = Math.cos(a) * r + @cx
- y = Math.sin(a) * r + @cy
- [x, y]
- end
-
- #
- # Convert cartesian (x,y) coordinate to polair (ang, radius)
- #
-
- def xy2pol(x, y)
- x -= @cx;
- y -= @cy;
- a = Math.atan2(y, x)
- a += 2*Math::PI if(a<0)
- r = Math.sqrt(x*x + y*y)
- [a, r]
- end
-
-
- #
- # Convert a filesize in bytes to a human readable form
- #
-
- def filesize_readable(size)
- if(size > 1024*1024*1024) then
- return "%.1fG" % (size / (1024.0*1024*1024))
- elsif(size > 1024*1024) then
- return "%.1fM" % (size / (1024.0*1024))
- elsif(size > 1024) then
- return "%.1fK" % (size / (1024.0))
- end
- size
- end
-
-end
-
-#
-# End
-#