add src/searchfile.py - first approximation
authorAlexandr Popov <popov2al@gmail.com>
Sat, 28 Mar 2009 20:56:51 +0000 (23:56 +0300)
committerAlexandr Popov <popov2al@gmail.com>
Sat, 28 Mar 2009 20:56:51 +0000 (23:56 +0300)
src/searchfile.py [new file with mode: 0644]

diff --git a/src/searchfile.py b/src/searchfile.py
new file mode 100644 (file)
index 0000000..dbdff7f
--- /dev/null
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+
+import gtk
+import pango
+from os import walk
+from os.path import join, abspath, normcase, basename, \
+                            isdir, getsize
+from heapq import nlargest
+
+class Search_File_Control(object):
+    
+    def __init__(self, start_dir, ignore_dirs, count):
+        self.filelist = []
+        self.srch_present = Search_File_Presentation(self.start_search)
+        self.srch_abs = Search_File_Abstraction(start_dir, ignore_dirs)
+        self.fl_cnt = count
+
+    def get_ui(self):
+        return self.srch_present.get_ui()
+
+    def start_search(self, label):
+        count, start_path = self.srch_present() 
+        for fsize, fpath in nlargest(self.fl_cnt, \
+                self.srch_abs.filegetter(self.srch_present.stopit, label) ):
+            self.filelist.append([fpath, self.srch_abs.size_convert(fsize), fsize])
+        return self.filelist
+
+
+class Search_File_Abstraction(object):
+    
+    def __init__(self, startdir, ignore_dirs):
+        self.startdir = startdir
+        self.ignore_dirs = ignore_dirs
+        self.label = label
+        
+    def size_convert(self, size):
+        """Return string with file size in b or Kb or Mb or Gb or Tb."""
+        for i, unit in enumerate(['%d b', '%.1f Kb', '%.2f Mb', '%.3f Gb', '%.4f Tb']):
+            if size < 1024**(i+1):
+                return unit % (size/1024.**i)
+        return '>1024 Tb'
+
+    def filegetter(self, stopit, label):
+        """Generator of file sizes and paths based on os.walk."""
+        # Проходим по всем папкам вглубь от заданного пути
+        for dirpath, dirnames, fnames in walk(self.startdir):
+        # Исключаем каталоги из поиска в соответствии со списком исключений
+            for ign_dir in self.ignore_dirs[:]:
+                for dirname in dirnames[:]:
+                    if ign_dir == normcase(join(abspath(dirpath), dirname)):
+                        dirnames.remove(dirname)
+                        ignore_dirs.remove(ign_dir)
+
+            for fname in fnames:
+                flpath = abspath(join(dirpath, fname))
+                # Выводим текущий опрашиваемый файл в строку статуса
+                label.set_text(flpath)
+                # обновляем окно
+                gtk.main_iteration()
+                # Останавливаем цикл по нажатию кнопки стоп
+                if stopit:
+                    stopit = False
+                    raise StopIteration
+                # Проверяем можем ли мы определить размер файла - иначе пропускаем его
+                try:
+                    # Возвращаем размер и полный путь файла
+                    yield getsize(flpath), flpath
+                except OSError:
+                    continue
+  
+class Search_File_Presentation(object):
+    
+    def __init__(self, st_func):
+        # Строка вывода текущего осматриваемого файла
+        self.currfilelbl = gtk.Label('---')
+        self.currfilelbl.set_alignment(0, 0.5)
+        self.currfilelbl.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
+        self.currfilelbl.set_padding(2, 2)
+        currfilefrm = gtk.Frame()
+        currfilefrm.add(self.currfilelbl)
+
+        # Кнопка "Показать"
+        self.butt_start = gtk.Button('Go')
+        self.butt_start.connect('released', self.start_srch(st_func))
+
+        # Кнопка "Остановить"
+        self.butt_stop = gtk.Button('Stop')
+        self.butt_stop.set_sensitive(False)
+        self.butt_stop.connect('clicked', self.stop_srch)
+        self.stopit = False
+
+        self.search_hbox = gtk.HBox(False, 10)
+        self.search_hbox.pack_start(currfilefrm, False, False, 0)
+        self.search_hbox.pack_end(self.butt_start, False, False, 0)
+        self.search_hbox.pack_end(self.butt_stop, False, False, 0)
+
+    def get_ui(self):
+        return self.search_hbox
+
+    def start_srch(self, start_func):
+        self.butt_stop.set_sensitive(True)
+        self.butt_start.set_sensitive(False)
+        start_func(self.currfilelbl)
+        self.butt_stop.set_sensitive(False)
+        self.butt_start.set_sensitive(True)
+
+    def stop_srch(self):
+        self.stopit = True
+        self.butt_stop.set_sensitive(False)
+        self.butt_start.set_sensitive(True)