+++ /dev/null
-#!/usr/bin/env python
-# -*-coding: utf-8 -*-
-# vim: sw=4 ts=4 expandtab ai
-# pylint: disable-msg=C0301
-
-"""findIT: Gui prorgram to find various information.
- At the moment it only finds largest files
-"""
-
-import gtk
-import gobject
-import pango
-from os import walk
-from os.path import join, abspath, normcase, basename, \
- isdir, getsize, getatime, getmtime, expanduser
-from heapq import nlargest
-import gettext
-import time
-from sys import platform
-
-try:
- import hildon
- HILDON = True
-except ImportError:
- HILDON = False
-
-try:
- # Подразумевается, что ru/LC_MESSAGES/program.mo находится в текущем каталоге (sys.path[0])
- # Для стандартного /usr/share/locale писать gettext.translation('findit')
- #langRU = gettext.translation('findit', sys.path[0], languages=['ru'])
- LANGRU = gettext.translation('findit')
- LANGRU.install()
-except IOError:
- # Закомментировать перед использованием pygettext
- def _(text):
- return text
-
-
-### Common functions ###########################################################
-
-# Функция которая возвращает строку из числа и единиц для столбца "Размер"("Size")
-def size_convert(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(startdir, obj):
- """Generator of file sizes and paths based on os.walk."""
- # Список игнорируемых каталогов:
- ignore_dirs = ['/dev', '/proc', '/sys', '/mnt']
- # Проходим по всем папкам вглубь от заданного пути
- for dirpath, dirnames, fnames in walk(startdir):
- # Исключаем каталоги из поиска в соответствии со списком исключений
- for ign_dir in 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))
- # Выводим текущий опрашиваемый файл в строку статуса
- obj.statusbar.push(obj.context_id, flpath)
- # обновляем окно
- gtk.main_iteration()
- # Останавливаем цикл по нажатию кнопки стоп
- if obj.stopit:
- obj.stopit = False
- raise StopIteration
- # Проверяем можем ли мы определить размер файла - иначе пропускаем его
- try:
- # Возвращаем размер и полный путь файла
- yield getsize(flpath), flpath
- except OSError:
- continue
-
-# Fullscreen
-def toggle_fullscreen(obj):
- """Switch fullscreen on/off."""
- if obj.fullscreen:
- obj.window.unfullscreen()
- else:
- obj.window.fullscreen()
- obj.fullscreen = not obj.fullscreen
-
-# Нажатие на кнопку клавиатуры
-def on_key_press(obj, event):
- """Key press callback."""
- # Toggle fullscreen on Maemo when hw key is pressed
- if HILDON and event.keyval == gtk.keysyms.F6:
- toggle_fullscreen(obj)
-
-
-### Properties dialog ##########################################################
-
-class PropertiesDialog(gtk.Dialog):
- """File property dialog window."""
-
- def __init__(self, app, path, size, bytesize):
- """Create&show file properties dialog."""
- gtk.Dialog.__init__(self, _('File properties'), app,
- buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK))
- self.set_wmclass('PropertiesDialog', 'FindIT')
- self.set_resizable(False)
-
- # Достаем свойства выбранного файла
- name = basename(path)
- access = time.strftime('%x %X', time.localtime(getatime(path)))
- modified = time.strftime('%x %X', time.localtime(getmtime(path)))
-
- # Таблица надписей
- table = gtk.Table()
- table.set_border_width(10)
- table.set_col_spacings(10)
- table.set_row_spacings(10)
-
- # Надписи (подпись: значение)
- lbls = [(gtk.Label(_(name)), gtk.Label(value)) for name, value in
- [('Name', name), ('Size', '%s (%d b)' % (size, bytesize)),
- ('Opened', access), ('Modified', modified)]]
-
- # Упаковка надписей в таблицу и выравнивание
- for i, lbl in enumerate(lbls):
- name, value = lbl
- table.attach(name, 0, 1, i, i+1)
- table.attach(value, 1, 2, i, i+1)
- name.set_alignment(1, 0.5)
- value.set_alignment(0, 0.5)
-
- # Упаковка таблицы в vbox диалога
- self.vbox.add(table)
- self.show_all()
- self.run()
- self.destroy()
-
-
-### About dialog ###############################################################
-
-class AboutDialog(gtk.AboutDialog):
- """About dialog window."""
-
- def __init__(self, *args):
- """Create&show about dialog."""
- gtk.AboutDialog.__init__(self)
- self.set_wmclass('AboutDialog', 'FindIT')
-
- self.set_authors([ 'Alex Taker\n * Email: alteker@gmail.com\n',
- 'Eugene Gagarin\n * Email: mosfet07@ya.ru\n',
- 'Alexandr Popov\n * Email: popov2al@gmail.com' ])
-
- self.set_comments('Tool for find some information on computer.')
- self.set_version('0.1.0')
- self.set_license("This program is free software; you can redistribute it and/or\nmodify it under the terms of the GNU General Public License\nas published by the Free Software Foundation; either version 3\nof the License, or (at your option) any later version.")
- self.set_copyright('')
- self.set_website('')
-
- self.show_all()
- self.run()
- self.destroy()
-
-### Main window ################################################################
-
-class MainWindow(gtk.Window):
- """Main window class."""
-
- # Окно сообщения заданного типа с заданным текстом
- def mess_window(self, mestype, content):
- """Show popup message window."""
- dialog = gtk.MessageDialog(parent=self, flags=gtk.DIALOG_MODAL,
- type=mestype, buttons=gtk.BUTTONS_OK,
- message_format=content)
- dialog.set_wmclass('ErrorDialog', 'FindIT')
- dialog.set_title( _('Error!') )
- dialog.run()
- dialog.destroy()
-
- # Функция выполняющаяся при нажатии на кнопку "Показать"
- def start_print(self, widget):
- """Start file search. Button "Go" activate callback."""
- self.start_path = self.srch_p_entr.get_text()
- # Проверяем правильное ли значение введено
- if isdir(self.start_path):
- self.butt_start.set_sensitive(False)
- self.butt_stop.set_sensitive(True)
- self.propertiesbtn.set_sensitive(False)
- # Получаем значение количества файлов из SpinButton
- self.fl_cnt = int( self.file_cnt.get_value() )
- # Очищаем список
- self.treestore.clear()
- self.treeview.columns_autosize()
- # Получаем нужное количество самых больших файлов
- for fsize, fpath in nlargest(self.fl_cnt, filegetter(self.start_path, self)):
- # Возвращаем значения в treeview в таком порядке - путь,
- # размер в Мб строкой и размер в байтах
- # self.treestore.append(None, [fpath.replace(self.start_path,'', 1),
- # size_convert(fsize), fsize])
-
- # Выдает какую-то перманентную ошибку при присвоении значений treestore -
- # кто увидит скажите - нужна статистика
- try:
- self.treestore.append(None, [fpath, size_convert(fsize), fsize])
- except SystemError:
-# print 'error', fpath, size_convert(fsize), fsize
- self.mess_window('error','Error in %s' % fpath)
- self.butt_start.set_sensitive(True)
- self.butt_stop.set_sensitive(False)
- self.propertiesbtn.set_sensitive(True)
-# self.srch_p_entr.grab_focus()
- self.srch_p_btn.grab_focus()
- else:
- # Иначе выводим окошко с ошибкой
- self.mess_window('error', _('Invalid directory') )
-
- # Функция выполняющаяся при нажатии на кнопку "Стоп"
- def stop_print(self, widget):
- """Stop search. "Stop" button clicked callback."""
- self.stopit = True
-
- # Функция выполняющаяся при нажатии на кнопку "Обзор"
- def browse(self, widget):
- """Open directory browser. "Browse" button clicked callback."""
- dialog = gtk.FileChooserDialog( title=_('Choose directory'),
- parent=self,
- action='select-folder',
- buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK,
- gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) )
- dialog.set_current_folder(self.srch_p_entr.get_text())
- dialog.show_all()
- response = dialog.run()
- if response == gtk.RESPONSE_OK:
- self.srch_p_entr.set_text(dialog.get_filename())
- dialog.destroy()
-
-
- # Функция выполняющаяся при нажатии на кнопку "Свойства файла"
- def show_properties_dialog(self, *args):
- """Show property dialog window."""
- selection = self.treeview.get_selection()
- (model, item) = selection.get_selected()
- try:
- path = model.get_value(item, 0)
- size = model.get_value(item, 1)
- bytesize = model.get_value(item, 2)
- except (TypeError, ValueError):
- self.mess_window('error', _('Please select file') )
- return
- PropertiesDialog(self, path, size, bytesize)
-
- # Создание меню
- def create_menu(self):
- """ Create main menu """
- menubar = gtk.MenuBar()
-
- # File menu
- fileitem = gtk.MenuItem( _('_File') ) # Файл
- filemenu = gtk.Menu()
- fileitem.set_submenu(filemenu)
-
- open_menuitem = gtk.ImageMenuItem(gtk.STOCK_OPEN)
- delete_menuitem = gtk.ImageMenuItem(gtk.STOCK_DELETE)
- properties_menuitem = gtk.ImageMenuItem(gtk.STOCK_PROPERTIES)
- quit_menuitem = gtk.ImageMenuItem(gtk.STOCK_QUIT)
- filemenu.add(open_menuitem)
- filemenu.add(delete_menuitem)
- filemenu.add(properties_menuitem)
- filemenu.add(quit_menuitem)
- properties_menuitem.connect('activate', self.show_properties_dialog)
- quit_menuitem.connect('activate', gtk.main_quit)
-
- # View menu
- viewitem = gtk.MenuItem( _('_View') ) # Вид
- viewmenu = gtk.Menu()
-
- # Help menu
- helpitem = gtk.MenuItem( _('_Help') ) # Помощь
- helpmenu = gtk.Menu()
- helpitem.set_submenu(helpmenu)
-
- about_menuitem = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
- helpmenu.add(about_menuitem)
- about_menuitem.connect('activate', AboutDialog)
-
- # Packing
- menubar.add(fileitem)
- menubar.add(viewitem)
- menubar.add(helpitem)
-
- return menubar
-
-# def create_hildon_menu(self):
-# """ Create Hildon main menu """
-
- ### Window initialization ##################################################
-
- def __init__(self, win_width, win_height, st_path):
- """Create MainWindow."""
- # Создаем новое окно
- gtk.Window.__init__(self)
- self.set_default_size(win_width, win_height)
- self.set_border_width(4)
- self.fullscreen = False
- self.connect('delete_event', gtk.main_quit)
- self.connect('key-press-event', on_key_press)
- self.set_wmclass('MainWindow', 'FindIT')
-
- ######### Добавляем элементы ################
- # 1. Строка ввода каталога с которого начинать поиск
- # переменная в которой храниться стартовый каталог = self.start_path
- self.srch_p_entr = gtk.Entry()
- self.start_path = st_path
- self.srch_p_entr.set_text(self.start_path)
- # Отключаем автокапитализацию(ввод первой буквы заглавной) на таблетке
- if HILDON:
- self.srch_p_entr.set_property('hildon-input-mode', 'full')
- # Нажатие Enter в поле ввода
- self.srch_p_entr.connect('activate', self.start_print)
-
- # 2. Кнопка "Обзор"
- self.srch_p_btn = gtk.Button('Browse...')
- self.srch_p_btn.connect('clicked', self.browse)
-
- # 3. Надпись1 "Количество отображаемых файлов:"
- label1 = gtk.Label( _('Files quantity') )
-
- # 4. Окошко ввода количества файлов, мин значение=1 макс=65536 по умолчанию 10
- # данные храняться в переменной self.fl_cnt
- self.fl_cnt = 10
- if HILDON:
- self.file_cnt = hildon.NumberEditor(1, 99)
- self.file_cnt.set_value(self.fl_cnt)
- else:
- adj = gtk.Adjustment(self.fl_cnt, 1, 65536, 1, 5, 0)
- self.file_cnt = gtk.SpinButton(adj, 0, 0)
-
- # 5.1 Кнопка "Показать"
- self.butt_start = gtk.Button( _('Go') )
- self.butt_start.connect('released', self.start_print)
-
- # 5.2 Кнопка "Остановить"
- self.butt_stop = gtk.Button( _('Stop') )
- self.butt_stop.set_sensitive(False)
- self.butt_stop.connect('clicked', self.stop_print)
- self.stopit = False
-
- # 5.3 Кнопка "Свойства файла"
- self.propertiesbtn = gtk.Button( _('File properties') )
- self.propertiesbtn.connect('clicked', self.show_properties_dialog)
- self.propertiesbtn.set_sensitive(False)
-
- # 6. Закладки
-
- # 6.1 Список файлов
- scrollwind = gtk.ScrolledWindow()
- scrollwind.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-
- # Определяем переменную в которой будет храниться выводимый список
- self.treestore = gtk.TreeStore(str, str, gobject.TYPE_INT64)
- self.treeview = gtk.TreeView(self.treestore)
- # На таблетке не отображаються заголовки столбцов по умолчанию -
- # след строка заставляет их отображаться принудительно
- self.treeview.set_headers_visible(1)
- self.treeview.connect('row-activated', self.show_properties_dialog)
-
- self.treestore.append(None, ['', '', 0])
-
- # Создаем и настраиваем колонку с размером файла
- size_col = gtk.TreeViewColumn( _('Size') )
- cell = gtk.CellRendererText()
- cell.set_property('width', 90)
- size_col.pack_start(cell, True)
- size_col.add_attribute(cell, 'text', 1)
- self.treeview.append_column(size_col)
- # Создаем и настраиваем колонку с именем файла
- path_col = gtk.TreeViewColumn( _('Path') )
- cell2 = gtk.CellRendererText()
- path_col.pack_start(cell2, True)
- path_col.add_attribute(cell2, 'text', 0)
- self.treeview.append_column(path_col)
-
- # Добавляем сортировку для колонок
- self.treeview.set_search_column(1)
- path_col.set_sort_column_id(0)
- size_col.set_sort_column_id(2)
-
- # 6.2 Надпись "Найти"
-
- # 6.3 Строка выводящая текущий осматриваемый файл
- self.statusbar = gtk.Statusbar()
- self.context_id = self.statusbar.get_context_id("Current file path")
-
- # 7 Меню
- if HILDON:
- main_menu = self.create_hildon_menu()
- else:
- main_menu = self.create_menu()
-
- ######### Упаковываем элементы ################
- # Создаем основной вертикальный контейнер
- main_vbox = gtk.VBox(False, 4)
-
- # Создаем вспомогательный горизонтальный контейнер для Надписи1,
- # окошка ввода количества файлов и кнопки "Показать"
- hbox1 = gtk.HBox(False, 5)
- # Добавляем вышеперечисленные элементы во вспомогат. контейнер
- hbox1.pack_start(label1, False, False, 5)
- hbox1.pack_start(self.file_cnt, False, False, 0)
- hbox1.pack_start(self.butt_start, True, True, 0)
- hbox1.pack_start(self.butt_stop, True, True, 0)
- hbox1.pack_start(self.propertiesbtn, True, True, 0)
-
- hbox2 = gtk.HBox(False, 5)
- hbox2.pack_start(self.srch_p_entr, True, True, 0)
- hbox2.pack_start(self.srch_p_btn, False, False, 0)
-
- # Добавляем элементы в основной контейнер
- main_vbox.pack_start(main_menu, False, False, 0)
-# main_vbox.pack_start(self.srch_p_entr, False, False, 0)
-# main_vbox.pack_start(self.srch_p_btn, False, False, 0)
- main_vbox.pack_start(hbox2, False, False, 0)
- main_vbox.pack_start(hbox1, False, False, 0)
- scrollwind.add(self.treeview)
- main_vbox.pack_start(scrollwind, True, True, 0)
- main_vbox.pack_start(self.statusbar, False, False, 0)
-
- self.add(main_vbox)
-
- def run(self):
- """Show all widgets and run gtk.main()."""
- self.show_all()
- gtk.main()
-
-
-### Main call ##################################################################
-def main():
- """Main function."""
- gobject.set_application_name( _('FindIT') )
-
- if platform == 'win32':
- startpath = 'c:\\'
- else:
- startpath = expanduser('~')
-
- MainWindow(575, 345, startpath).run()
-
-if __name__ == '__main__':
- main()