import os, os.path, stat, sys import gobject, gtk from threading import Thread import time class sum_list: data = [] the_sum = 0 name = None def __init__(self, l, name = None): self.data = list(l) self.name = name for fn, i in self.data: if isinstance(i, sum_list): self.the_sum += i.the_sum else: self.the_sum += i def __str__(self): return self.name+": "+str(self.data) class FringWalker( gobject.GObject ): __gsignals__ = { 'list-changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)), 'finished': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)), 'progress': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,gobject.TYPE_INT)), } def __init__(self): gobject.GObject.__init__(self) self.thread = None self.stopsignal = False self.showhidden = False def walk(self,path): self.thread = Thread(None,self._parse,None,(path,)) self.stopsignal = False print "stard thread (%s)"%path self.thread.start() def stop(self): if self.thread is None: return if not self.thread.isAlive(): self.thread = None return self.stopsignal = True print "stopping thread:" #self.thread.join() print "ok" def _parse(self,path): """ Parse the root directory """ l = [] i = 0 subdirectories = {} try: for fn in os.listdir(path): if not self.showhidden and fn[0] == '.': continue try: p = os.path.join(path, fn) except: continue s = os.lstat(p) if stat.S_ISDIR(s.st_mode): subdirectories[i] = (fn,p); l.append((fn, s.st_size)) elif stat.S_ISREG(s.st_mode): l.append((fn, s.st_size)) i += 1 except: pass gtk.gdk.threads_enter() self.emit("list-changed",sum_list(l, os.path.split(path)[-1])) gtk.gdk.threads_leave() c = 0 for n in subdirectories: c += 1 # give gtk a breath to redraw time.sleep(0.05) # walk subdirectory fn,p = subdirectories[n] l[n] = (fn, self._build_tree(p)); if self.stopsignal: return # emit signals gtk.gdk.threads_enter() self.emit("progress",c,len(subdirectories)) self.emit("list-changed",sum_list(l, os.path.split(path)[-1])) gtk.gdk.threads_leave() gtk.gdk.threads_enter() self.emit("finished",sum_list(l, os.path.split(path)[-1])) gtk.gdk.threads_leave() print "finished walking",path def _build_tree(self,path): """ Parse directories recursively """ l = [] try: # walk files in directory subdirectories = [] for fn in os.listdir(path): if self.stopsignal: return sum_list([]) if not self.showhidden and fn[0] == '.': continue try: p = os.path.join(path, fn) except: continue s = os.lstat(p) if stat.S_ISDIR(s.st_mode): subdirectories.append( (fn,p) ); elif stat.S_ISREG(s.st_mode): l.append((fn, s.st_size)) # add subdirectories after files for fn,p in subdirectories: l.append((fn, self._build_tree(p))) if self.stopsignal: return sum_list([]) except: pass return sum_list(l, os.path.split(path)[-1])