Improved command line options, formatting, increased GUI font size
* Added -h/--help/-? arguments explaining usage * Added ability to accept plain and gzipped du output as first argument * Increased font size and min height * Changed mixed tabs/spaces formatting to all spaces
This commit is contained in:
parent
12a6501522
commit
eb684a6e49
418
tkdu.py
Normal file → Executable file
418
tkdu.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# This is tkdu.py, an interactive program to display disk usage
|
# This is tkdu.py, an interactive program to display disk usage
|
||||||
# Copyright 2004 Jeff Epler <jepler@unpythonic.net>
|
# Copyright 2004 Jeff Epler <jepler@unpythonic.net>
|
||||||
#
|
#
|
||||||
@ -15,19 +17,19 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
import math, Tkinter, sys, os, stat, string, time, FileDialog
|
import math, Tkinter, sys, os, stat, string, time, gzip, FileDialog
|
||||||
from tkFileDialog import askdirectory
|
from tkFileDialog import askdirectory
|
||||||
|
|
||||||
MIN_PSZ = 1000
|
MIN_PSZ = 1000
|
||||||
MIN_IPSZ = 240
|
MIN_IPSZ = 240
|
||||||
MIN_W = 50
|
MIN_W = 50
|
||||||
MIN_H = 10
|
MIN_H = 15
|
||||||
VERTICAL = "vertical"
|
VERTICAL = "vertical"
|
||||||
HORIZONTAL = "horizontal"
|
HORIZONTAL = "horizontal"
|
||||||
NUM_QUEUE = 25
|
NUM_QUEUE = 25
|
||||||
FONT_FACE = ("helvetica", 8)
|
FONT_FACE = ("helvetica", 12)
|
||||||
BORDER = 2
|
BORDER = 2
|
||||||
FONT_HEIGHT = 8
|
FONT_HEIGHT = 12
|
||||||
FONT_HEIGHT2 = 20
|
FONT_HEIGHT2 = 20
|
||||||
|
|
||||||
dircolors = ['#ff7070', '#70ff70', '#7070ff']
|
dircolors = ['#ff7070', '#70ff70', '#7070ff']
|
||||||
@ -39,11 +41,11 @@ def allocate(path, files, canvas, x, y, w, h, first, depth):
|
|||||||
psz = w*h
|
psz = w*h
|
||||||
if psz < MIN_PSZ: return
|
if psz < MIN_PSZ: return
|
||||||
if path and path[-1] == "/":
|
if path and path[-1] == "/":
|
||||||
basename_idx = len(path)
|
basename_idx = len(path)
|
||||||
nslashes = string.count(path, os.sep) - 1
|
nslashes = string.count(path, os.sep) - 1
|
||||||
else:
|
else:
|
||||||
basename_idx = len(path) + 1
|
basename_idx = len(path) + 1
|
||||||
nslashes = string.count(path, os.sep)
|
nslashes = string.count(path, os.sep)
|
||||||
dircolor = dircolors[nslashes % len(dircolors)]
|
dircolor = dircolors[nslashes % len(dircolors)]
|
||||||
leafcolor = leafcolors[nslashes % len(dircolors)]
|
leafcolor = leafcolors[nslashes % len(dircolors)]
|
||||||
colors = (leafcolor, dircolor)
|
colors = (leafcolor, dircolor)
|
||||||
@ -53,8 +55,8 @@ def allocate(path, files, canvas, x, y, w, h, first, depth):
|
|||||||
if ff[0][1] == '/': del ff[0]
|
if ff[0][1] == '/': del ff[0]
|
||||||
ff = ff[first:]
|
ff = ff[first:]
|
||||||
for item in ff:
|
for item in ff:
|
||||||
totsz = totsz + item[0]
|
totsz = totsz + item[0]
|
||||||
item[2] = None
|
item[2] = None
|
||||||
|
|
||||||
if totsz == 0: return
|
if totsz == 0: return
|
||||||
|
|
||||||
@ -62,149 +64,149 @@ def allocate(path, files, canvas, x, y, w, h, first, depth):
|
|||||||
ratio = psz*1./totsz
|
ratio = psz*1./totsz
|
||||||
|
|
||||||
while i < len(ff) and w>2*BORDER and h>2*BORDER:
|
while i < len(ff) and w>2*BORDER and h>2*BORDER:
|
||||||
if w > h:
|
if w > h:
|
||||||
orient = VERTICAL
|
orient = VERTICAL
|
||||||
usew = w - h*2./3
|
usew = w - h*2./3
|
||||||
if usew < 50: usew = 50
|
if usew < 50: usew = 50
|
||||||
if usew > 200: usew = 200
|
if usew > 200: usew = 200
|
||||||
first_height = ff[i][0]/usew*ratio
|
first_height = ff[i][0]/usew*ratio
|
||||||
while first_height < .65 * usew:
|
while first_height < .65 * usew:
|
||||||
usew = usew / 1.5
|
usew = usew / 1.5
|
||||||
first_height = ff[i][0]/usew*ratio
|
first_height = ff[i][0]/usew*ratio
|
||||||
want = usew * h / ratio
|
want = usew * h / ratio
|
||||||
maxcnt = h/30
|
maxcnt = h/30
|
||||||
else:
|
else:
|
||||||
orient = HORIZONTAL
|
orient = HORIZONTAL
|
||||||
useh = h - w*2./3
|
useh = h - w*2./3
|
||||||
if useh < 50: useh = 50
|
if useh < 50: useh = 50
|
||||||
if useh > 100: useh = 100
|
if useh > 100: useh = 100
|
||||||
first_width = ff[i][0]/useh*ratio
|
first_width = ff[i][0]/useh*ratio
|
||||||
while first_width < .65 * useh:
|
while first_width < .65 * useh:
|
||||||
useh = useh / 1.5
|
useh = useh / 1.5
|
||||||
first_width = ff[i][0]/useh*ratio
|
first_width = ff[i][0]/useh*ratio
|
||||||
want = useh * w / ratio
|
want = useh * w / ratio
|
||||||
maxcnt = w/30
|
maxcnt = w/30
|
||||||
|
|
||||||
|
|
||||||
j = i+1
|
j = i+1
|
||||||
use = ff[i][0]
|
use = ff[i][0]
|
||||||
while j < len(ff) and use < want: #and j < i + maxcnt:
|
while j < len(ff) and use < want: #and j < i + maxcnt:
|
||||||
use = use + ff[j][0]
|
use = use + ff[j][0]
|
||||||
j=j+1
|
j=j+1
|
||||||
|
|
||||||
if orient is VERTICAL:
|
if orient is VERTICAL:
|
||||||
usew = use * ratio / h
|
usew = use * ratio / h
|
||||||
if usew <= 2*BORDER: break
|
if usew <= 2*BORDER: break
|
||||||
y0 = y
|
y0 = y
|
||||||
for item in ff[i:j]:
|
for item in ff[i:j]:
|
||||||
dy = item[0]/usew*ratio
|
dy = item[0]/usew*ratio
|
||||||
item[2] = (x, y0, usew, dy)
|
item[2] = (x, y0, usew, dy)
|
||||||
y0 = y0 + dy
|
y0 = y0 + dy
|
||||||
x = x + usew
|
x = x + usew
|
||||||
w = w - usew
|
w = w - usew
|
||||||
else:
|
else:
|
||||||
useh = use * ratio / w
|
useh = use * ratio / w
|
||||||
if useh <= 2*BORDER: break
|
if useh <= 2*BORDER: break
|
||||||
x0 = x
|
x0 = x
|
||||||
for item in ff[i:j]:
|
for item in ff[i:j]:
|
||||||
dx = item[0]/useh*ratio
|
dx = item[0]/useh*ratio
|
||||||
item[2] = (x0, y, dx, useh)
|
item[2] = (x0, y, dx, useh)
|
||||||
x0 = x0 + dx
|
x0 = x0 + dx
|
||||||
y = y + useh
|
y = y + useh
|
||||||
h = h - useh
|
h = h - useh
|
||||||
i = j
|
i = j
|
||||||
|
|
||||||
for item in ff:
|
for item in ff:
|
||||||
sz = item[0]
|
sz = item[0]
|
||||||
name = item[1]
|
name = item[1]
|
||||||
haskids = bool(getkids(files, name))
|
haskids = bool(getkids(files, name))
|
||||||
color = colors[haskids]
|
color = colors[haskids]
|
||||||
if item[2] is None: continue
|
if item[2] is None: continue
|
||||||
x, y, w, h = pos = item[2]
|
x, y, w, h = pos = item[2]
|
||||||
if w > 3*BORDER and h > 3*BORDER:
|
if w > 3*BORDER and h > 3*BORDER:
|
||||||
tk_call(canvas._w,
|
tk_call(canvas._w,
|
||||||
"create", "rectangle",
|
"create", "rectangle",
|
||||||
x+BORDER+2, y+BORDER+2, x+w-BORDER+1, y+h-BORDER+1,
|
x+BORDER+2, y+BORDER+2, x+w-BORDER+1, y+h-BORDER+1,
|
||||||
"-fill", "#3f3f3f",
|
"-fill", "#3f3f3f",
|
||||||
"-outline", "#3f3f3f")
|
"-outline", "#3f3f3f")
|
||||||
|
|
||||||
i = tk_call(canvas._w,
|
i = tk_call(canvas._w,
|
||||||
"create", "rectangle",
|
"create", "rectangle",
|
||||||
x+BORDER, y+BORDER, x+w-BORDER, y+h-BORDER,
|
x+BORDER, y+BORDER, x+w-BORDER, y+h-BORDER,
|
||||||
"-fill", color)
|
"-fill", color)
|
||||||
canvas.map[int(i)] = name
|
canvas.map[int(i)] = name
|
||||||
|
|
||||||
if h > FONT_HEIGHT+2*BORDER:
|
if h > FONT_HEIGHT+2*BORDER:
|
||||||
w1 = w - 2*BORDER
|
w1 = w - 2*BORDER
|
||||||
stem = name[basename_idx:]
|
stem = name[basename_idx:]
|
||||||
ssz = size(sz)
|
ssz = size(sz)
|
||||||
text = "%s %s" % (name[basename_idx:], ssz)
|
text = "%s %s" % (name[basename_idx:], ssz)
|
||||||
tw = int(tk_call("font", "measure", FONT_FACE, text))
|
tw = int(tk_call("font", "measure", FONT_FACE, text))
|
||||||
if tw > w1:
|
if tw > w1:
|
||||||
if h > FONT_HEIGHT2 + 2*BORDER:
|
if h > FONT_HEIGHT2 + 2*BORDER:
|
||||||
tw = max(
|
tw = max(
|
||||||
int(tk_call("font", "measure", FONT_FACE, stem)),
|
int(tk_call("font", "measure", FONT_FACE, stem)),
|
||||||
int(tk_call("font", "measure", FONT_FACE, ssz)))
|
int(tk_call("font", "measure", FONT_FACE, ssz)))
|
||||||
if tw < w1:
|
if tw < w1:
|
||||||
text = "%s\n%s" % (stem, ssz)
|
text = "%s\n%s" % (stem, ssz)
|
||||||
i = tk_call(canvas._w, "create", "text",
|
i = tk_call(canvas._w, "create", "text",
|
||||||
x+BORDER+2, y+BORDER,
|
x+BORDER+2, y+BORDER,
|
||||||
"-text", text,
|
"-text", text,
|
||||||
"-font", FONT_FACE, "-anchor", "nw")
|
"-font", FONT_FACE, "-anchor", "nw")
|
||||||
canvas.map[int(i)] = name
|
canvas.map[int(i)] = name
|
||||||
y = y + FONT_HEIGHT2
|
y = y + FONT_HEIGHT2
|
||||||
h = h - FONT_HEIGHT2
|
h = h - FONT_HEIGHT2
|
||||||
if w*h > MIN_PSZ and haskids and depth != 1:
|
if w*h > MIN_PSZ and haskids and depth != 1:
|
||||||
queue(canvas, allocate, name, files, canvas,
|
queue(canvas, allocate, name, files, canvas,
|
||||||
x+2*BORDER, y+2*BORDER,
|
x+2*BORDER, y+2*BORDER,
|
||||||
w-4*BORDER, h-4*BORDER, 0, depth-1)
|
w-4*BORDER, h-4*BORDER, 0, depth-1)
|
||||||
continue
|
continue
|
||||||
text = stem
|
text = stem
|
||||||
tw = int(tk_call("font", "measure", FONT_FACE, text))
|
tw = int(tk_call("font", "measure", FONT_FACE, text))
|
||||||
if tw < w1:
|
if tw < w1:
|
||||||
i = tk_call(canvas._w, "create", "text",
|
i = tk_call(canvas._w, "create", "text",
|
||||||
x+BORDER+2, y+BORDER,
|
x+BORDER+2, y+BORDER,
|
||||||
"-text", text,
|
"-text", text,
|
||||||
"-font", FONT_FACE, "-anchor", "nw")
|
"-font", FONT_FACE, "-anchor", "nw")
|
||||||
canvas.map[int(i)] = name
|
canvas.map[int(i)] = name
|
||||||
y = y + FONT_HEIGHT
|
y = y + FONT_HEIGHT
|
||||||
h = h - FONT_HEIGHT
|
h = h - FONT_HEIGHT
|
||||||
if w*h > MIN_PSZ and haskids and depth != 1:
|
if w*h > MIN_PSZ and haskids and depth != 1:
|
||||||
queue(canvas, allocate, name, files, canvas,
|
queue(canvas, allocate, name, files, canvas,
|
||||||
x+2*BORDER, y+2*BORDER,
|
x+2*BORDER, y+2*BORDER,
|
||||||
w-4*BORDER, h-4*BORDER, 0, depth-1)
|
w-4*BORDER, h-4*BORDER, 0, depth-1)
|
||||||
|
|
||||||
def queue(c, *args):
|
def queue(c, *args):
|
||||||
if c.aid is None:
|
if c.aid is None:
|
||||||
c.aid = c.after_idle(run_queue, c)
|
c.aid = c.after_idle(run_queue, c)
|
||||||
c.configure(cursor="watch")
|
c.configure(cursor="watch")
|
||||||
c.queue.append(args)
|
c.queue.append(args)
|
||||||
|
|
||||||
def run_queue(c):
|
def run_queue(c):
|
||||||
queue = c.queue
|
queue = c.queue
|
||||||
end = time.time() + .5
|
end = time.time() + .5
|
||||||
while 1:
|
while 1:
|
||||||
if not queue:
|
if not queue:
|
||||||
c.aid = None
|
c.aid = None
|
||||||
c.configure(cursor="")
|
c.configure(cursor="")
|
||||||
break
|
break
|
||||||
if time.time() > end: break
|
if time.time() > end: break
|
||||||
item = queue[0]
|
item = queue[0]
|
||||||
del queue[0]
|
del queue[0]
|
||||||
apply(item[0], item[1:])
|
apply(item[0], item[1:])
|
||||||
if queue:
|
if queue:
|
||||||
c.aid = c.after_idle(run_queue, c)
|
c.aid = c.after_idle(run_queue, c)
|
||||||
|
|
||||||
def chroot(e, r):
|
def chroot(e, r):
|
||||||
c = e.widget
|
c = e.widget
|
||||||
if not getkids(c.files, r):
|
if not getkids(c.files, r):
|
||||||
r = os.path.dirname(r)
|
r = os.path.dirname(r)
|
||||||
if r == c.cur: return
|
if r == c.cur: return
|
||||||
if r is None:
|
if r is None:
|
||||||
return
|
return
|
||||||
if not r.startswith(c.root):
|
if not r.startswith(c.root):
|
||||||
c.bell()
|
c.bell()
|
||||||
return
|
return
|
||||||
c.cur = r
|
c.cur = r
|
||||||
c.first = 0
|
c.first = 0
|
||||||
e.width = c.winfo_width()
|
e.width = c.winfo_width()
|
||||||
@ -214,9 +216,9 @@ def chroot(e, r):
|
|||||||
def item_under_cursor(e):
|
def item_under_cursor(e):
|
||||||
c = e.widget
|
c = e.widget
|
||||||
try:
|
try:
|
||||||
item = c.find_overlapping(e.x, e.y, e.x, e.y)[-1]
|
item = c.find_overlapping(e.x, e.y, e.x, e.y)[-1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
return c.map.get(item, None)
|
return c.map.get(item, None)
|
||||||
|
|
||||||
def descend(e):
|
def descend(e):
|
||||||
@ -231,11 +233,11 @@ def ascend(e):
|
|||||||
|
|
||||||
def size(n):
|
def size(n):
|
||||||
if n > 1024*1024*1024:
|
if n > 1024*1024*1024:
|
||||||
return "%.1fGB" % (n/1024./1024/1024)
|
return "%.1fGB" % (n/1024./1024/1024)
|
||||||
elif n > 1024*1024:
|
elif n > 1024*1024:
|
||||||
return "%.1fMB" % (n/1024./1024)
|
return "%.1fMB" % (n/1024./1024)
|
||||||
elif n > 1024:
|
elif n > 1024:
|
||||||
return "%.1fKB" % (n/1024.)
|
return "%.1fKB" % (n/1024.)
|
||||||
return "%d" % n
|
return "%d" % n
|
||||||
|
|
||||||
def scroll(e, dir):
|
def scroll(e, dir):
|
||||||
@ -245,10 +247,10 @@ def scroll(e, dir):
|
|||||||
if offset + 5 > l: offset = l-5
|
if offset + 5 > l: offset = l-5
|
||||||
if offset < 0: offset = 0
|
if offset < 0: offset = 0
|
||||||
if offset != c.first:
|
if offset != c.first:
|
||||||
c.first = offset
|
c.first = offset
|
||||||
e.width = c.winfo_width()
|
e.width = c.winfo_width()
|
||||||
e.height = c.winfo_height()
|
e.height = c.winfo_height()
|
||||||
reconfigure(e)
|
reconfigure(e)
|
||||||
|
|
||||||
def schedule_tip(e):
|
def schedule_tip(e):
|
||||||
c = e.widget
|
c = e.widget
|
||||||
@ -267,12 +269,12 @@ def make_tip(e, s):
|
|||||||
|
|
||||||
def cancel_tip(e, c=None):
|
def cancel_tip(e, c=None):
|
||||||
if c is None:
|
if c is None:
|
||||||
c = e.widget
|
c = e.widget
|
||||||
if c.tipa:
|
if c.tipa:
|
||||||
c.after_cancel(c.tipa)
|
c.after_cancel(c.tipa)
|
||||||
c.tipa = None
|
c.tipa = None
|
||||||
else:
|
else:
|
||||||
c.tip.wm_withdraw()
|
c.tip.wm_withdraw()
|
||||||
|
|
||||||
def reconfigure(e):
|
def reconfigure(e):
|
||||||
c = e.widget
|
c = e.widget
|
||||||
@ -281,16 +283,16 @@ def reconfigure(e):
|
|||||||
c.t.wm_title("%s (%s)" % (c.cur, size(getname(c.files, c.cur))))
|
c.t.wm_title("%s (%s)" % (c.cur, size(getname(c.files, c.cur))))
|
||||||
c.delete("all")
|
c.delete("all")
|
||||||
for cb in c.cb:
|
for cb in c.cb:
|
||||||
c.after_cancel(cb)
|
c.after_cancel(cb)
|
||||||
c.cb = []
|
c.cb = []
|
||||||
c.aid = None
|
c.aid = None
|
||||||
c.queue = []
|
c.queue = []
|
||||||
c.map = {}
|
c.map = {}
|
||||||
c.tipa = None
|
c.tipa = None
|
||||||
if c.cur == "/":
|
if c.cur == "/":
|
||||||
nslashes = -1
|
nslashes = -1
|
||||||
else:
|
else:
|
||||||
nslashes = string.count(c.cur, os.sep) - 1
|
nslashes = string.count(c.cur, os.sep) - 1
|
||||||
parent = os.path.dirname(c.cur)
|
parent = os.path.dirname(c.cur)
|
||||||
color = dircolors[nslashes % len(dircolors)]
|
color = dircolors[nslashes % len(dircolors)]
|
||||||
c.configure(background=color)
|
c.configure(background=color)
|
||||||
@ -299,16 +301,16 @@ def reconfigure(e):
|
|||||||
|
|
||||||
def putname_base(dict, name, base, size):
|
def putname_base(dict, name, base, size):
|
||||||
try:
|
try:
|
||||||
dict[base][name] = size
|
dict[base][name] = size
|
||||||
except:
|
except:
|
||||||
dict[base] = {name: size}
|
dict[base] = {name: size}
|
||||||
|
|
||||||
def putname(dict, name, size):
|
def putname(dict, name, size):
|
||||||
base = os.path.dirname(name)
|
base = os.path.dirname(name)
|
||||||
try:
|
try:
|
||||||
dict[base][name] = size
|
dict[base][name] = size
|
||||||
except:
|
except:
|
||||||
dict[base] = {name: size}
|
dict[base] = {name: size}
|
||||||
|
|
||||||
def getname(dict, name):
|
def getname(dict, name):
|
||||||
base = os.path.dirname(name)
|
base = os.path.dirname(name)
|
||||||
@ -316,14 +318,14 @@ def getname(dict, name):
|
|||||||
|
|
||||||
def getkids(dict, path):
|
def getkids(dict, path):
|
||||||
return dict.get(path, ((), {}))[1]
|
return dict.get(path, ((), {}))[1]
|
||||||
|
|
||||||
def doit(dir, files):
|
def doit(dir, files):
|
||||||
sorted_files = {}
|
sorted_files = {}
|
||||||
for k, v in files.items():
|
for k, v in files.items():
|
||||||
sv = map(lambda (k, v): [v, k, None], v.items())
|
sv = map(lambda (k, v): [v, k, None], v.items())
|
||||||
sv.sort()
|
sv.sort()
|
||||||
sv.reverse()
|
sv.reverse()
|
||||||
sorted_files[k] = (v, sv)
|
sorted_files[k] = (v, sv)
|
||||||
|
|
||||||
t = Tkinter.Tk()
|
t = Tkinter.Tk()
|
||||||
c = Tkinter.Canvas(t, width=1024, height=768)
|
c = Tkinter.Canvas(t, width=1024, height=768)
|
||||||
@ -344,10 +346,10 @@ def doit(dir, files):
|
|||||||
t.bind("<Unmap>", lambda e, c=c: cancel_tip(e, c))
|
t.bind("<Unmap>", lambda e, c=c: cancel_tip(e, c))
|
||||||
t.bind("<q>", lambda e, t=t: t.destroy())
|
t.bind("<q>", lambda e, t=t: t.destroy())
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
t.bind("<Key-%d>" % i, lambda e, c=c, i=i: setdepth(e, c, i))
|
t.bind("<Key-%d>" % i, lambda e, c=c, i=i: setdepth(e, c, i))
|
||||||
c.bind("<Button-4>", lambda e: scroll(e, -1))
|
c.bind("<Button-4>", lambda e: scroll(e, -1))
|
||||||
c.bind("<Button-5>", lambda e: scroll(e, 1))
|
c.bind("<Button-5>", lambda e: scroll(e, 1))
|
||||||
c.bind("<Button-3>", ascend)
|
c.bind("<Button-2>", ascend)
|
||||||
c.tag_bind("all", "<Button-1>", descend)
|
c.tag_bind("all", "<Button-1>", descend)
|
||||||
c.tag_bind("all", "<Enter>", schedule_tip)
|
c.tag_bind("all", "<Enter>", schedule_tip)
|
||||||
c.tag_bind("all", "<Leave>", cancel_tip)
|
c.tag_bind("all", "<Leave>", cancel_tip)
|
||||||
@ -360,14 +362,14 @@ def setdepth(e, c, i):
|
|||||||
c.depth = i
|
c.depth = i
|
||||||
reconfigure(e)
|
reconfigure(e)
|
||||||
|
|
||||||
def main_pipe():
|
def main(f = sys.stdin):
|
||||||
files = {}
|
files = {}
|
||||||
firstfile = None
|
firstfile = None
|
||||||
for line in sys.stdin.readlines():
|
for line in f.readlines():
|
||||||
sz, name = string.split(line[:-1], None, 1)
|
sz, name = string.split(line[:-1], None, 1)
|
||||||
# name = name.split("/")
|
# name = name.split("/")
|
||||||
sz = long(sz)*1024
|
sz = long(sz)*1024
|
||||||
putname(files, name, sz)
|
putname(files, name, sz)
|
||||||
doit(name, files)
|
doit(name, files)
|
||||||
|
|
||||||
def du(dir, files, fs=0, ST_MODE=stat.ST_MODE, ST_SIZE = stat.ST_SIZE, S_IFMT = 0170000, S_IFDIR = 0040000, lstat = os.lstat, putname_base = putname_base, fmt="%%s%s%%s" % os.sep):
|
def du(dir, files, fs=0, ST_MODE=stat.ST_MODE, ST_SIZE = stat.ST_SIZE, S_IFMT = 0170000, S_IFDIR = 0040000, lstat = os.lstat, putname_base = putname_base, fmt="%%s%s%%s" % os.sep):
|
||||||
@ -380,19 +382,19 @@ def du(dir, files, fs=0, ST_MODE=stat.ST_MODE, ST_SIZE = stat.ST_SIZE, S_IFMT =
|
|||||||
d = files[dir]
|
d = files[dir]
|
||||||
|
|
||||||
for fn in fns:
|
for fn in fns:
|
||||||
fn = fmt % (dir, fn)
|
fn = fmt % (dir, fn)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
info = lstat(fn)
|
info = lstat(fn)
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info[ST_MODE] & S_IFMT == S_IFDIR:
|
if info[ST_MODE] & S_IFMT == S_IFDIR:
|
||||||
sz = du(fn, files) + long(info[ST_SIZE])
|
sz = du(fn, files) + long(info[ST_SIZE])
|
||||||
else:
|
else:
|
||||||
sz = info[ST_SIZE]
|
sz = info[ST_SIZE]
|
||||||
d[fn] = sz
|
d[fn] = sz
|
||||||
tsz = tsz + sz
|
tsz = tsz + sz
|
||||||
return tsz
|
return tsz
|
||||||
|
|
||||||
def abspath(p):
|
def abspath(p):
|
||||||
@ -400,19 +402,19 @@ def abspath(p):
|
|||||||
|
|
||||||
class DirDialog(FileDialog.LoadFileDialog):
|
class DirDialog(FileDialog.LoadFileDialog):
|
||||||
def __init__(self, master, title=None):
|
def __init__(self, master, title=None):
|
||||||
FileDialog.LoadFileDialog.__init__(self, master, title)
|
FileDialog.LoadFileDialog.__init__(self, master, title)
|
||||||
self.files.destroy()
|
self.files.destroy()
|
||||||
self.filesbar.destroy()
|
self.filesbar.destroy()
|
||||||
|
|
||||||
def ok_command(self):
|
def ok_command(self):
|
||||||
file = self.get_selection()
|
file = self.get_selection()
|
||||||
if not os.path.isdir(file):
|
if not os.path.isdir(file):
|
||||||
self.master.bell()
|
self.master.bell()
|
||||||
else:
|
else:
|
||||||
self.quit(file)
|
self.quit(file)
|
||||||
|
|
||||||
def filter_command(self, event=None):
|
def filter_command(self, event=None):
|
||||||
END="end"
|
END="end"
|
||||||
dir, pat = self.get_filter()
|
dir, pat = self.get_filter()
|
||||||
try:
|
try:
|
||||||
names = os.listdir(dir)
|
names = os.listdir(dir)
|
||||||
@ -438,22 +440,48 @@ class DirDialog(FileDialog.LoadFileDialog):
|
|||||||
def main_builtin_du(args):
|
def main_builtin_du(args):
|
||||||
import sys
|
import sys
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
dir = args[1]
|
p = args[1]
|
||||||
else:
|
else:
|
||||||
t = Tkinter.Tk()
|
t = Tkinter.Tk()
|
||||||
t.wm_withdraw()
|
t.wm_withdraw()
|
||||||
dir = askdirectory()
|
p = askdirectory()
|
||||||
if Tkinter._default_root is t:
|
if Tkinter._default_root is t:
|
||||||
Tkinter._default_root = None
|
Tkinter._default_root = None
|
||||||
t.destroy()
|
t.destroy()
|
||||||
if dir is None: return
|
if p is None:
|
||||||
|
return
|
||||||
files = {}
|
files = {}
|
||||||
if dir == "-":
|
|
||||||
main_pipe()
|
if p == '-h' or p == '--help' or p == '-?':
|
||||||
|
base = os.path.basename(args[0])
|
||||||
|
print 'Usage:'
|
||||||
|
print ' ', base, '<file.gz> interpret file as gzipped du -ak output and visualize it'
|
||||||
|
print ' ', base, '<file> interpret file as du -ak output and visualize it'
|
||||||
|
print ' ', base, '<folder> analyze disk usage in that folder'
|
||||||
|
print ' ', base, '- interpret stdin input as du -ak output and visualize it'
|
||||||
|
print ' ', base, ' ask for folder to analyze'
|
||||||
|
print
|
||||||
|
print 'Controls:'
|
||||||
|
print ' * Press `q` to quit'
|
||||||
|
print ' * LMB: zoom in to item'
|
||||||
|
print ' * RMB: zoom out one level'
|
||||||
|
print ' * Press `1`..`9`: Show that many nested levels'
|
||||||
|
print ' * Press `0`: Show man nested levels'
|
||||||
|
return
|
||||||
|
|
||||||
|
if p == "-":
|
||||||
|
main()
|
||||||
else:
|
else:
|
||||||
dir = abspath(dir)
|
p = abspath(p)
|
||||||
putname(files, dir, du(dir, files))
|
if os.path.isfile(p):
|
||||||
doit(dir, files)
|
if p.endswith('.gz'):
|
||||||
|
# gzipped file
|
||||||
|
main(gzip.open(p, 'r'))
|
||||||
|
else:
|
||||||
|
main(open(p, 'r'))
|
||||||
|
else:
|
||||||
|
putname(files, p, du(p, files))
|
||||||
|
doit(p, files)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
|
Loading…
Reference in New Issue
Block a user