creating wizard view - finishing in src/core.py
[findit] / src / searchfile.py
1 #!/usr/bin/env python
2 # -*-coding: utf-8 -*-
3 # vim: sw=4 ts=4 expandtab ai
4
5 import gtk
6 import pango
7 from os import walk
8 from os.path import join, abspath, normcase, basename, \
9                             isdir, getsize
10 from heapq import nlargest
11
12 from misc import size_hum_read
13
14 class Search_File_Control(object):
15     
16     def __init__(self, get_start_data, ignore_dirs, show_func):
17         self.start_data = get_start_data
18         self.srch_abs = Search_File_Abstraction(ignore_dirs)
19         self.srch_present = Search_File_Presentation(self.start_search, show_func)
20
21     def get_ui(self):
22         return self.srch_present.get_ui()
23
24     def start_search(self, stopit, label, show_func):
25         self.filelist = []
26         start_path, count = self.start_data()
27         for fsize, fpath in nlargest(count, \
28                 self.srch_abs.filegetter(start_path, stopit, label) ):
29             self.filelist.append([fpath, size_hum_read(fsize), fsize])
30         show_func(self.filelist)
31
32
33 class Search_File_Abstraction(object):
34     
35     def __init__(self, ignore_dirs):
36         self.ignore_dirs = ignore_dirs
37
38     def filegetter(self, startdir, get_stopit, label):
39         """Generator of file sizes and paths based on os.walk."""
40         # Проходим по всем папкам вглубь от заданного пути
41         for dirpath, dirnames, fnames in walk(startdir):
42         # Исключаем каталоги из поиска в соответствии со списком исключений
43             ignore_dirs = self.ignore_dirs
44             for ign_dir in ignore_dirs[:]:
45                 for dirname in dirnames[:]:
46                     if ign_dir == normcase(join(abspath(dirpath), dirname)):
47                         dirnames.remove(dirname)
48                         ignore_dirs.remove(ign_dir)
49
50             for fname in fnames:
51                 flpath = abspath(join(dirpath, fname))
52                 # Выводим текущий опрашиваемый файл в строку статуса
53                 label.set_text(flpath)
54                 # обновляем окно
55                 gtk.main_iteration()
56                 # Останавливаем цикл по нажатию кнопки стоп
57                 stopit = get_stopit()
58                 if stopit:
59                     stopit = False
60                     raise StopIteration
61                 # Проверяем можем ли мы определить размер файла - иначе пропускаем его
62                 try:
63                     # Возвращаем размер и полный путь файла
64                     yield getsize(flpath), flpath
65                 except OSError:
66                     continue
67   
68 class Search_File_Presentation(object):
69     
70     def __init__(self, st_func, show_func):
71
72         # Строка вывода текущего осматриваемого файла
73         self.currfilelbl = gtk.Label('---')
74         self.currfilelbl.set_alignment(0, 0.5)
75         self.currfilelbl.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
76         self.currfilelbl.set_padding(2, 2)
77         currfilefrm = gtk.Frame()
78         currfilefrm.add(self.currfilelbl)
79
80         # Кнопка "Показать"
81         self.butt_start = gtk.Button('Go')
82         self.butt_start.connect('released', self.start_srch, st_func, show_func)
83
84         # Кнопка "Остановить"
85         self.butt_stop = gtk.Button('Stop')
86         self.butt_stop.set_sensitive(False)
87         self.stopit = False
88         self.butt_stop.connect('clicked', self.stop_srch)
89         
90
91         self.search_hbox = gtk.HBox(False, 10)
92         self.search_hbox.pack_start(currfilefrm, True, True, 0)
93         self.search_hbox.pack_end(self.butt_start, False, False, 0)
94         self.search_hbox.pack_end(self.butt_stop, False, False, 0)
95
96     def get_ui(self):
97         return self.search_hbox
98
99     def start_srch(self, widget, start_func, show_func):
100         self.stopit = False
101         self.butt_stop.set_sensitive(True)
102         self.butt_start.set_sensitive(False)
103         start_func(self.get_stopit, self.currfilelbl, show_func)
104         self.butt_stop.set_sensitive(False)
105         self.butt_start.set_sensitive(True)
106
107     def stop_srch(self, widget):
108         self.stopit = True
109         self.butt_stop.set_sensitive(False)
110         self.butt_start.set_sensitive(True)
111
112     def get_stopit(self):
113         return self.stopit