3 # vim: sw=4 ts=4 expandtab ai
9 from os.path import getsize, join, isdir, abspath, normcase
10 from heapq import nlargest
14 try: import hildon; hildonFound = True
15 except: hildonFound = False
18 # Подразумевается, что ru/LC_MESSAGES/program.mo находится в текущем каталоге (sys.path[0])
19 # Для стандартного /usr/share/locale писать gettext.translation('findit')
20 langRU = gettext.translation('findit', sys.path[0], languages=['ru'])
23 # Закомментировать перед использованием pygettext
24 def _(text): return text
27 ### Common functions ###########################################################
29 # Функция которая возвращает строку из числа и единиц для столбца "Размер"("Size")
30 def size_convert(size):
31 for i, unit in enumerate(['%d b', '%.1f Kb', '%.2f Mb', '%.3f Gb', '%.4f Tb']):
32 if size < 1024**(i+1):
33 return unit % (size/1024.**i)
36 # Функция поставляющая размер файла и путь к нему
37 def filegetter(startpath, obj):
38 # Список игнорируемых каталогов:
39 ignore_dirs = ['/dev', '/proc', '/sys', '/mnt']
40 # Проходим по всем папкам вглубь от заданного пути
41 for dirpath, dirnames, fnames in walk(startpath):
42 # Исключаем каталоги из поиска в соответствии со списком исключений
43 for ign_dir in ignore_dirs[:]:
44 for dirname in dirnames[:]:
45 if ign_dir == normcase(join(abspath(dirpath), dirname)):
46 dirnames.remove(dirname)
47 ignore_dirs.remove(ign_dir)
50 flpath = join(dirpath, fname)
51 # Выводим текущий опрашиваемый файл в строку статуса
52 obj.currFileLbl.set_text(abspath(flpath))
55 # Останавливаем цикл по нажатию кнопки стоп
59 # Проверяем можем ли мы определить размер файла - иначе пропускаем его
60 try: flsize = getsize(flpath)
62 # Возвращаем размер и полный путь файла
63 yield flsize, abspath(flpath)
66 def toggle_fullscreen(obj):
68 obj.window.unfullscreen()
69 else: obj.window.fullscreen()
70 obj.fullscreen = not obj.fullscreen
72 # Нажатие на кнопку клавиатуры
73 def on_key_press(obj, event):
74 if hildonFound and event.keyval == gtk.keysyms.F6:
75 toggle_fullscreen(obj)
77 ### Main window ################################################################
79 class MainWindow(gtk.Window):
81 # Окно сообщения заданного типа с заданным текстом
82 def mess_window(self, mestype, content):
83 dialog = gtk.MessageDialog(parent=self, flags=gtk.DIALOG_MODAL,
84 type=mestype, buttons=gtk.BUTTONS_OK,
85 message_format=content)
86 dialog.set_title( _('Error!') )
90 # Функция выполняющаяся при нажатии на кнопку "Показать"
91 def start_print(self, widget):
92 self.start_path = self.srch_p_entr.get_text()
93 # Проверяем правильное ли значение введено
94 if isdir(self.start_path):
95 self.butt_start.set_sensitive(False)
96 self.butt_stop.set_sensitive(True)
97 # Получаем значение количества файлов из SpinButton
98 self.fl_cnt = int( self.file_cnt.get_value() )
100 self.treestore.clear()
101 # Получаем нужное количество самых больших файлов
102 for fsize, fpath in nlargest(self.fl_cnt, filegetter(self.start_path, self)):
103 # Возвращаем значения в treeview в таком порядке - путь,
104 # размер в Мб строкой и размер в байтах
105 # self.treestore.append(None, [fpath.replace(self.start_path,'', 1),
106 # size_convert(fsize), fsize])
108 # Выдает какую-то перманентную ошибку при присвоении значений treestore -
109 # кто увидит скажите - нужна статистика
110 try: self.treestore.append(None, [fpath, size_convert(fsize), fsize])
111 except: 'error', fpath, size_convert(fsize), fsize
112 self.butt_start.set_sensitive(True)
113 self.butt_stop.set_sensitive(False)
115 # Иначе выводим окошко с ошибкой
116 self.mess_window(gtk.MESSAGE_ERROR, _('Invalid directory') )
118 def stop_print(self, widget):
121 ### Window initialization ##################################################
123 def __init__(self, win_width, win_height, st_path):
125 gtk.Window.__init__(self)
126 self.set_default_size(win_width, win_height)
127 self.set_border_width(4)
128 self.fullscreen = False
129 self.connect('delete_event', gtk.main_quit)
130 self.connect("key-press-event", on_key_press)
132 ######### Добавляем элементы ################
133 # 1. Строка ввода каталога с которого начинать поиск
134 # переменная в которой храниться стартовый каталог = self.start_path
135 self.srch_p_entr = gtk.Entry()
136 self.start_path = st_path
137 self.srch_p_entr.set_text(self.start_path)
138 # Отключаем автокапитализацию(ввод первой буквы заглавной) на таблетке
140 self.srch_p_entr.set_property("hildon-input-mode", 'full')
141 # Нажатие Enter в поле ввода
142 self.srch_p_entr.connect("activate", self.start_print)
146 # 3. Надпись1 "Количество отображаемых файлов:"
147 label1 = gtk.Label( _('Files quantity') )
149 # 4. Окошко ввода количества файлов, мин значение=1 макс=65536 по умолчанию 10
150 # данные храняться в переменной self.fl_cnt
153 self.file_cnt = hildon.NumberEditor(1, 99)
154 self.file_cnt.set_value(self.fl_cnt)
156 adj = gtk.Adjustment(self.fl_cnt, 1, 65536, 1, 5, 0)
157 self.file_cnt = gtk.SpinButton(adj, 0, 0)
159 # 5.1 Кнопка "Показать"
160 self.butt_start = gtk.Button( _('Go') )
161 self.butt_start.connect('clicked', self.start_print)
163 # 5.2 Кнопка "Остановить"
164 self.butt_stop = gtk.Button( _('Stop') )
165 self.butt_stop.set_sensitive(False)
166 self.butt_stop.connect('clicked', self.stop_print)
172 scrollwind = gtk.ScrolledWindow()
173 scrollwind.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
175 # Определяем переменную в которой будет храниться выводимый список
176 self.treestore = gtk.TreeStore(str, str, int)
177 treeview = gtk.TreeView(self.treestore)
178 # На таблетке не отображаються заголовки столбцов по умолчанию -
179 # след строка заставляет их отображаться принудительно
180 treeview.set_headers_visible(1)
182 self.treestore.append(None, ['','', 0])
184 # Создаем и настраиваем колонку с размером файла
185 size_col = gtk.TreeViewColumn( _('Size') )
186 cell = gtk.CellRendererText()
187 cell.set_property('width', 90)
188 size_col.pack_start(cell, True)
189 size_col.add_attribute(cell, 'text', 1)
190 treeview.append_column(size_col)
191 # Создаем и настраиваем колонку с именем файла
192 path_col = gtk.TreeViewColumn( _('Path') )
193 cell2 = gtk.CellRendererText()
194 path_col.pack_start(cell2, True)
195 path_col.add_attribute(cell2, 'text', 0)
196 treeview.append_column(path_col)
198 # Добавляем сортировку для колонок
199 treeview.set_search_column(1)
200 path_col.set_sort_column_id(0)
201 size_col.set_sort_column_id(2)
203 # 6.2 Надпись "Найти"
205 # 6.3 Строка выводящая текущий осматриваемый файл
206 self.currFileLbl = gtk.Label()
207 self.currFileLbl.set_alignment(0, 0.5)
208 self.currFileLbl.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
210 ######### Упаковываем элементы ################
211 # Создаем основной вертикальный контейнер
212 main_Vbox = gtk.VBox(False, 4)
214 # Создаем вспомогательный горизонтальный контейнер для Надписи1,
215 # окошка ввода количества файлов и кнопки "Показать"
216 hbox1 = gtk.HBox(False, 5)
217 # Добавляем вышеперечисленные элементы во вспомогат. контейнер
218 hbox1.pack_start(label1, False, False, 5)
219 hbox1.pack_start(self.file_cnt, False, False, 0)
220 hbox1.pack_start(self.butt_start, True, True, 0)
221 hbox1.pack_start(self.butt_stop, True, True, 0)
223 # Добавляем элементы в основной контейнер
224 main_Vbox.pack_start(self.srch_p_entr, False, False, 0)
225 main_Vbox.pack_start(hbox1, False, False, 0)
226 scrollwind.add(treeview)
227 main_Vbox.pack_start(scrollwind, True, True, 0)
228 main_Vbox.pack_start(self.currFileLbl, False, False, 0)
238 ### Main call ##################################################################
240 if __name__ == '__main__':
241 # gobject.set_application_name( _('FindIT') )
242 MainWindow(575, 345, '/').run()