3 # vim: sw=4 ts=4 expandtab ai
4 # pylint: disable-msg=C0301
6 from gtkmvc import Controller
10 from os.path import join, abspath, normcase, getsize
11 from heapq import nlargest
13 #from filesearch import FilesearchCtrl
14 from views.filesearch import FilesearchView
17 class FilesearchCtrl(Controller):
18 """Controller of the files search plugin"""
20 def __init__(self, model):
21 Controller.__init__(self, model)
23 def register_view(self, view):
24 Controller.register_view(self, view)
26 # connects the signals:
27 self.view['start_btn'].connect('released', self.start_btn_released_cb)
28 self.view['stop_btn'].connect('clicked', self.on_stop_btn_clicked)
29 self.view['qty_spin'].connect("value_changed", self.on_qty_spin_value_changed)
31 # sets initial values for the view
32 self.view.set_quantity_value(self.model.quantity)
33 self.view.set_start_path_value(self.model.start_path)
35 # -----------------------------------------------------
37 # -----------------------------------------------------
39 def filegetter(self, startdir): #, obj):
40 """Generator of file sizes and paths based on os.walk."""
41 # Список игнорируемых каталогов:
42 ignore_dirs = ['/dev', '/proc', '/sys', '/mnt']
43 # Проходим по всем папкам вглубь от заданного пути
44 for dirpath, dirnames, fnames in walk(startdir):
45 # Исключаем каталоги из поиска в соответствии со списком исключений
46 for ign_dir in ignore_dirs[:]:
47 for dirname in dirnames[:]:
48 if ign_dir == normcase(join(abspath(dirpath), dirname)):
49 dirnames.remove(dirname)
50 ignore_dirs.remove(ign_dir)
53 flpath = abspath(join(dirpath, fname))
54 # Выводим текущий опрашиваемый файл в строку статуса
55 self.view['currfile_lbl'].set_text(flpath)
58 # Останавливаем цикл по нажатию кнопки стоп
60 self.model.stopit = False
62 # Проверяем можем ли мы определить размер файла - иначе пропускаем его
64 # Возвращаем размер и полный путь файла
65 yield getsize(flpath), flpath
69 def size_convert(self, size):
70 """Return string with file size in b or Kb or Mb or Gb or Tb."""
72 for i, unit in enumerate(['%d b', '%.1f Kb', '%.2f Mb', '%.3f Gb', '%.4f Tb']):
73 if size < 1024**(i+1):
74 return unit % (size/1024.**i)
77 # -----------------------------------------------------
79 # -----------------------------------------------------
81 def on_qty_spin_value_changed(self, sb):
82 # Получаем значение количества файлов из SpinButton
83 self.model.quantity = sb.get_value_as_int()
85 def start_btn_released_cb(self, btn):
86 """Start file search. Button "Go" activate callback."""
88 # Получаем значение начального пути из Entry
89 start_path = self.view['path_entry'].get_text()
91 self.view['start_btn'].set_sensitive(False)
92 self.view['stop_btn'].set_sensitive(True)
95 self.view['liststore'].clear()
97 # Выравниваем размер колонок
98 self.view['treeview'].columns_autosize()
100 # Получаем нужное количество самых больших файлов
101 #for fsize, fpath in nlargest(self.model.quantity, self.filegetter(self.model.start_path)):
102 for fsize, fpath in nlargest(self.model.quantity, self.filegetter(start_path)):
103 # Заполняем treemodel: путь, размер в Мб строкой, размер в байтах
105 self.view['liststore'].append([fpath, self.size_convert(fsize), fsize])
107 # print type(fpath), type(self.size_convert(fsize)), type(fsize)
109 self.view['start_btn'].set_sensitive(True)
110 self.view['stop_btn'].set_sensitive(False)
111 self.view['path_entry'].grab_focus()
113 def on_stop_btn_clicked(self, btn):
114 """Stop search. "Stop" button clicked callback."""
116 self.model.stopit = True
118 # -----------------------------------------------------
119 # observable properties
120 # -----------------------------------------------------
122 def property_quantity_value_change(self, model, old, new):
124 #self.view.set_quantity_value(new)
126 def property_start_path_value_change(self, model, old, new):
127 print model, old, new
128 self.view.set_start_path_value(new)
130 def property_stopit_value_change(self, model, old, new):
131 self.view.set_stopit_value(new)