From dfbb3aba29d0cbc74b36ef147a60b0b57d06dac1 Mon Sep 17 00:00:00 2001 From: Alexandr Popov Date: Sat, 28 Mar 2009 23:56:51 +0300 Subject: [PATCH] add src/searchfile.py - first approximation --- src/searchfile.py | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/searchfile.py diff --git a/src/searchfile.py b/src/searchfile.py new file mode 100644 index 0000000..dbdff7f --- /dev/null +++ b/src/searchfile.py @@ -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) -- 1.7.9.5