Added PAC skeleton
authorEugene Gagarin <mosfet07@ya.ru>
Tue, 21 Apr 2009 18:35:50 +0000 (22:35 +0400)
committerEugene Gagarin <mosfet07@ya.ru>
Tue, 21 Apr 2009 18:35:50 +0000 (22:35 +0400)
src/about.py [new file with mode: 0755]
src/debs/__init__.py [new file with mode: 0755]
src/debs/outdiagram.py [new file with mode: 0755]
src/debs/outtable.py [new file with mode: 0755]
src/debs/search.py [new file with mode: 0755]
src/files/__init__.py [new file with mode: 0755]
src/files/outdiagram.py [new file with mode: 0755]
src/files/outtable.py [new file with mode: 0755]
src/files/search.py [new file with mode: 0755]
src/main.py [new file with mode: 0755]
src/misc.py [new file with mode: 0755]

diff --git a/src/about.py b/src/about.py
new file mode 100755 (executable)
index 0000000..efc92f8
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+
+import gtk
+
+from __main__ import __version__, __progname__
+
+
+class About(gtk.AboutDialog):
+    """About dialog window."""
+
+    def __init__(self):
+        """Create&show about dialog."""
+        gtk.AboutDialog.__init__(self)
+
+        self.progname = __progname__
+        self.version = __version__
+        self.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.comments = 'Tool for find some information on computer.'
+        self.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_name(self.progname)
+        self.set_version(self.version)
+        self.set_authors(self.authors)
+        self.set_comments(self.comments)
+        self.set_license(self.license)
+
+        self.show_all()
+        self.run()
+        self.destroy()
diff --git a/src/debs/__init__.py b/src/debs/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/src/debs/outdiagram.py b/src/debs/outdiagram.py
new file mode 100755 (executable)
index 0000000..1b235a4
--- /dev/null
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+
+import gtk
+import gobject
+from random import randint
+
+class Out_Diag_Control(object):
+    def __init__(self, config):
+        win_width = config.get('window_width')
+        win_height = config.get('window_height')
+        self.out_ui = Out_Diag_Presentation(win_width, win_height)
+
+    def show(self, filelist, fullsize):
+        self.out_ui.get_data(filelist, fullsize)
+
+    def run(self):
+        self.out_ui.run()
+
+
+class Out_Diag_Abstraction(object):
+    pass
+
+
+class Out_Diag_Presentation(gtk.Window):
+
+    def __init__(self, win_width, win_height):
+        gtk.Window.__init__(self)
+        self.width = win_width
+        self.height = win_height
+        self.set_default_size(self.width, self.height)
+        self.set_border_width(4)
+        self.connect('delete_event', gtk.main_quit) 
+
+        scrollwind = gtk.ScrolledWindow()
+        scrollwind.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        
+        self.area = gtk.DrawingArea()
+        self.area.set_size_request(win_width, win_height)
+        self.area.set_events(gtk.gdk.POINTER_MOTION_MASK | 
+                gtk.gdk.POINTER_MOTION_HINT_MASK )
+        self.area.connect("expose-event", self.expose_event)
+        self.pixmap = None        
+        
+        scrollwind.add_with_viewport(self.area)
+        self.add(scrollwind)
+
+    
+    def expose_event(self, widget, event):
+        if not self.pixmap:
+            self.build_pixmap()
+        x , y, width, height = event.area
+        widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], \
+                self.pixmap, x, y, x, y, width, height)
+        return False
+
+    def build_pixmap(self):
+        self.pixmap=gtk.gdk.Pixmap(self.window, self.width, self.height)
+        cm=self.pixmap.get_colormap()
+        self.color={}
+        self.color['black']=cm.alloc_color("black")
+        self.color['white']=cm.alloc_color("white")
+        self.gc=self.pixmap.new_gc()
+        self.gc.set_foreground(self.color['white'])
+        self.pixmap.draw_rectangle(self.gc, True, 0, 0, self.width, self.height)
+    
+    def draw_diag(self):
+        start_angle = 0
+        for path, size, bsize in self.filelist:
+            end_angle = (bsize*360*64)/self.fullsize
+            print start_angle, end_angle
+            gc=self.pixmap.new_gc()
+            cm=self.pixmap.get_colormap()
+            col1 = cm.alloc_color(self.rand_color())
+            gc.set_foreground(col1)
+            gc.set_line_attributes(1,gtk.gdk.LINE_SOLID,gtk.gdk.CAP_NOT_LAST,gtk.gdk.JOIN_MITER)
+            self.pixmap.draw_arc(gc, True, 0, 0, self.width, self.height, start_angle, end_angle)
+            start_angle = start_angle + end_angle
+        self.area.queue_draw()
+
+    def rand_color(self):
+        r = randint(0, 65535)
+        g = randint(0, 65535)
+        b = randint(0, 65535)
+        return gtk.gdk.Color(r, g, b, 0)
+
+    def run(self):
+        self.show_all()
+        gobject.timeout_add(1000, self.draw_diag)
+        gtk.main()
+    
+    def get_data(self, filelist, fullsize):
+        self.filelist = filelist
+        self.fullsize = fullsize
diff --git a/src/debs/outtable.py b/src/debs/outtable.py
new file mode 100755 (executable)
index 0000000..753d8bc
--- /dev/null
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+
+import gtk
+import gobject
+from misc import size_hum_read
+
+class Out_Table_Control(object):
+    def __init__(self):
+        self.out_ui = Out_Table_Presentation()
+
+    def show(self, filelist, flsize):
+        self.out_ui.show_result(filelist, flsize)
+
+    def get_ui(self):
+        return self.out_ui.get_ui()
+
+class Out_Table_Abstraction(object):
+    pass
+
+class Out_Table_Presentation(object):
+    def __init__(self):
+        # Список файлов
+    
+        scrollwind = gtk.ScrolledWindow()
+        scrollwind.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+        # Определяем переменную в которой будет храниться выводимый список
+        self.liststore = gtk.ListStore(str, str, gobject.TYPE_INT64)
+        self.treeview = gtk.TreeView(self.liststore)
+        # На таблетке не отображаються заголовки столбцов по умолчанию -
+        # след строка заставляет их отображаться принудительно
+        self.treeview.set_headers_visible(1)
+        self.liststore.append(['', '', 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)
+
+        scrollwind.add(self.treeview)
+        self.label = gtk.Label('full dir size = ')
+        
+        self.vbox = gtk.VBox(False, 5)
+        self.vbox.pack_start(scrollwind, True, True, 0)
+        self.vbox.pack_start(self.label, False, False,0)
+
+    def show_result(self, filelist, fullsize):
+        self.liststore.clear()
+        for stroka in filelist:
+            self.liststore.append(stroka)
+        flsizestr = 'full dir size = %s' % size_hum_read(fullsize)
+        self.label.set_text(flsizestr)
+
+    def get_ui(self):
+        return self.vbox
diff --git a/src/debs/search.py b/src/debs/search.py
new file mode 100755 (executable)
index 0000000..d56e570
--- /dev/null
@@ -0,0 +1,132 @@
+#!/usr/bin/python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+
+import gtk
+#import apt_pkg
+from heapq import nlargest
+from misc import size_hum_read
+
+class Search_Pkg_Control(object):
+
+    def __init__(self, config, show_funct):
+        count = config.get('default_pkg_count')
+        self.show_func = show_funct
+        self.abstr = Search_Pkg_Abstraction()
+        self.present = Search_Pkg_Presentation(count, self.start_search)
+
+    def start_search(self, count, show_type):
+        pkglist = []
+        for psize, packg in nlargest(count, self.abstr.pkggetter()):
+            pkglist.append([packg, size_hum_read(psize), psize])
+        
+        if show_type is 'table_view':
+            from outtable import Out_Table_Control
+            out = Out_Table_Control()
+        #elif show_type is 'diag_view':
+        #    from outdiag import Out_Diag_Control
+        #    out = Out_Diag_Control(self.cfg)
+        out.show(pkglist, self.abstr.full())
+        self.show_func(None, out.get_ui())
+
+    def get_ui(self):
+        return self.present.get_ui()
+
+class Search_Pkg_Abstraction(object):
+
+    def __init__(self):
+        apt_pkg.InitConfig()
+        apt_pkg.InitSystem()
+        self.cache = apt_pkg.GetCache()
+
+    def pkggetter(self):
+        self.fullsize = 0
+        for pkg in self.cache.Packages:
+            # pkg is from a list of packages, sorted by name.
+            if pkg.CurrentState == apt_pkg.CurStateInstalled:
+                pkgsize = [version.InstalledSize for version in pkg.VersionList][0]
+                self.fullsize = self.fullsize + pkgsize
+                yield pkgsize, pkg.Name
+
+    def full(self):
+        return self.fullsize
+
+
+#==============================================================================
+
+class Gtk_Presentation(object):
+
+    def __init__(self):
+        import gtk
+
+        # "Packages quantity" label
+        qty_label = gtk.Label('Files quantity')
+
+        # "Packages quantity" spin
+        qty_spin = gtk.SpinButton()
+        qty_spin.set_numeric(True)
+        qty_spin.set_range(0, 65536)
+        qty_spin.set_increments(1, 10)
+
+        # "Start" button
+        start_btn = gtk.Button('Start')
+        start_btn.connect('released', self.start_search)
+
+        # Output selection
+        outtable_rbtn = gtk.RadioButton(None, 'Table')
+        outdiagram_rbtn = gtk.RadioButton(outtable_rbtn, 'Diagram')
+        out1_rbtn = gtk.RadioButton(outtable_rbtn, 'Another 1')
+        out_rbtns = [outtable_rbtn, outdiagram_rbtn, out1_rbtn]
+
+        hbox = gtk.HBox(False, 4)
+        hbox.pack_start(qty_label, False, False, 0)
+        hbox.pack_start(qty_spin, False, False, 0)
+        hbox.pack_start(start_btn, False, False, 0)
+        for btn in reversed(out_rbtns):
+            hbox.pack_end(btn, False, False, 0)
+
+        statusbar = gtk.Statusbar()
+        context_id = statusbar.get_context_id('Selected package')
+        statusbar.push(context_id, 'test')
+
+        self.vbox = gtk.VBox(False, 4)
+        self.vbox.set_border_width(4)
+        self.vbox.pack_start(hbox, False, False, 0)
+        self.vbox.pack_end(statusbar, False, False, 0)
+
+        self.show_out_toplevel(None, 'outtable') ###
+        self.frame = gtk.Frame('Deb packages search')
+        self.frame.add(self.vbox)
+        self.frame.show_all()
+
+    #=== Functions ============================================================
+    def start_search(self, widget, start_func):
+        self.stopit = False
+        self.butt_stop.set_sensitive(True)
+        self.butt_start.set_sensitive(False)
+        start_func(self.get_data, self.get_stopit, self.currfilelbl, self.kill_wind)
+
+    def stop_search(self, widget):
+        self.stopit = True
+        self.butt_stop.set_sensitive(False)
+        self.butt_start.set_sensitive(True)
+
+    def get_stopit(self):
+        return self.stopit
+
+    #=== Toplevel widget for embedding to main window =========================
+    def get_toplevel(self):
+        return self.frame ###
+
+    #=== Output type selecting ================================================
+    def show_out_toplevel(self, btn, output):
+        print 'Entering <' + output + '> output mode...'
+        from files.outtable import Gtk_Presentation ###
+        toplevel = Gtk_Presentation().get_toplevel()
+        ###self.vbox.remove(self.vbox.get_children()[2])
+        #self.vbox.add(toplevel)
+        self.vbox.pack_start(toplevel)
+
+#     def run(self):
+#         self.show_all()
+#         gtk.main()
diff --git a/src/files/__init__.py b/src/files/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/src/files/outdiagram.py b/src/files/outdiagram.py
new file mode 100755 (executable)
index 0000000..b309dca
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+
+import gtk
+import gobject
+from random import randint
+
+
+class Control(object):
+    def __init__(self, config):
+        win_width = config.get('window_width')
+        win_height = config.get('window_height')
+        self.out_ui = Out_Diag_Presentation(win_width, win_height)
+
+    def show(self, filelist, fullsize):
+        self.out_ui.get_data(filelist, fullsize)
+
+    def run(self):
+        self.out_ui.run()
+
+
+class Abstraction(object):
+    pass
+
+
+class Gtk_Presentation(object):
+
+    def __init__(self):
+
+        self.area = gtk.DrawingArea()
+        self.area.set_size_request(250, 200) ###
+        self.area.set_events(gtk.gdk.POINTER_MOTION_MASK |
+                             gtk.gdk.POINTER_MOTION_HINT_MASK )
+        self.area.connect('expose-event', self.expose_event)
+        self.pixmap = None
+
+    def expose_event(self, widget, event):
+        if not self.pixmap:
+            self.build_pixmap()
+        x, y, width, height = event.area
+        widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL],
+                                    self.pixmap, x, y, x, y, width, height)
+        return False
+
+    def build_pixmap(self):
+        #self.pixmap = gtk.gdk.Pixmap(self.window, self.width, self.height)
+        self.pixmap = gtk.gdk.Pixmap(None, 250, 200, 8) ###
+        cm = self.pixmap.get_colormap()
+        self.color = {}
+        self.color['black'] = cm.alloc_color('black')
+        self.color['white'] = cm.alloc_color('white')
+        self.gc = self.pixmap.new_gc()
+        self.gc.set_foreground(self.color['white'])
+        self.pixmap.draw_rectangle(self.gc, True, 0, 0, self.width, self.height)
+
+    def draw_diag(self):
+        start_angle = 0
+        for path, size, bsize in self.filelist:
+            end_angle = (bsize*360*64)/self.fullsize
+            print start_angle, end_angle
+            gc = self.pixmap.new_gc()
+            cm = self.pixmap.get_colormap()
+            col1 = cm.alloc_color(self.rand_color())
+            gc.set_foreground(col1)
+            gc.set_line_attributes(1,gtk.gdk.LINE_SOLID,gtk.gdk.CAP_NOT_LAST,gtk.gdk.JOIN_MITER)
+            self.pixmap.draw_arc(gc, True, 0, 0, self.width, self.height, start_angle, end_angle)
+            start_angle = start_angle + end_angle
+        self.area.queue_draw()
+
+    def rand_color(self):
+        r = randint(0, 65535)
+        g = randint(0, 65535)
+        b = randint(0, 65535)
+        return gtk.gdk.Color(r, g, b, 0)
+
+    def run(self):
+        self.show_all()
+        gobject.timeout_add(1000, self.draw_diag)
+        gtk.main()
+
+    def get_data(self, filelist, fullsize):
+        self.filelist = filelist
+        self.fullsize = fullsize
+
+    #=== Toplevel widget for embedding to search area =========================
+    def get_toplevel(self):
+        return self.area
diff --git a/src/files/outtable.py b/src/files/outtable.py
new file mode 100755 (executable)
index 0000000..da09ee0
--- /dev/null
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+
+import gtk
+import gobject
+
+#==============================================================================
+
+class OutTable_Control(object):
+    def __init__(self):
+        self.table_present = Gtk_Presentation()
+
+    def show(self, filelist, flsize):
+        self.table_present.show_result(filelist, flsize)
+
+    def get_ui(self):
+        return self.table_present.get_toplevel()
+
+#==============================================================================
+
+class OutTable_Abstraction(object):
+    pass
+
+#==============================================================================
+
+class Gtk_Presentation(object):
+    def __init__(self):
+
+        # Определяем переменную в которой будет храниться выводимый список
+        self.liststore = gtk.ListStore(str, str, gobject.TYPE_INT64)
+        self.treeview = gtk.TreeView(self.liststore)
+        # На таблетке не отображаються заголовки столбцов по умолчанию -
+        # след строка заставляет их отображаться принудительно
+        self.treeview.set_headers_visible(1)
+        self.liststore.append(['', '', 0])
+
+        # Создаем и настраиваем колонку с размером файла
+        size_col = gtk.TreeViewColumn( 'Size')
+        cell1 = gtk.CellRendererText()
+        cell1.set_property('width', 90)
+        size_col.pack_start(cell1, True)
+        size_col.add_attribute(cell1, '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)
+
+        self.swin = gtk.ScrolledWindow()
+        self.swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.swin.add(self.treeview)
+
+    #=== Functions ============================================================
+    def show_result(self, filelist, fullsize):
+        self.liststore.clear()
+        for line in filelist:
+            self.liststore.append(line)
+
+    #=== Toplevel widget for embedding to search area =========================
+    def get_toplevel(self):
+        return self.swin
diff --git a/src/files/search.py b/src/files/search.py
new file mode 100755 (executable)
index 0000000..2223540
--- /dev/null
@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+
+from os import walk
+from os.path import join, abspath, normcase, basename, isdir, getsize
+from heapq import nlargest
+import gtk ###
+
+from misc import *
+
+#==============================================================================
+
+class Control(object):
+    
+    def __init__(self):
+        ignore_dirs = ['/dev', '/proc', '/sys', '/mnt']
+        start_path = '.'
+        count = 7
+        self.search_abstrac = Abstraction(ignore_dirs)
+        self.search_present = Gtk_Presentation(start_path, count, self.start_search)
+
+    def start_search(self, get_data, get_stopit, label, kill_func):
+        filelist = []
+        start_path, count = get_data()
+        search_func = self.search_abstrac.filegetter(start_path, get_stopit, label)
+        for fsize, fpath in nlargest(count, search_func):
+            filelist.append([fpath, size_hum_read(fsize), int(fsize)])
+        if not get_stopit():
+            #kill_func()
+            self.search_present.show_out_toplevel(None, 'outtable', filelist)
+
+    def run(self):
+        return self.search_present.get_toplevel()
+
+#==============================================================================
+
+class Abstraction(object):
+    
+    def __init__(self, ignore_dirs):
+        self.ignore_dirs = ignore_dirs
+
+    def filegetter(self, startdir, get_stopit, label):
+        """Generator of file sizes and paths based on os.walk."""
+        # Проходим по всем папкам вглубь от заданного пути
+        self.full_dir_size = 0
+        for dirpath, dirnames, fnames in walk(startdir):
+            # Исключаем каталоги из поиска в соответствии со списком исключений
+            ignore_dirs = self.ignore_dirs
+            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))
+                # Выводим текущий опрашиваемый файл в строку статуса
+                #label.set_text(flpath)
+                # обновляем окно
+                gtk.main_iteration() ###
+                # Останавливаем цикл по нажатию кнопки стоп
+                stopit = get_stopit()
+                if stopit:
+                    stopit = False
+                    raise StopIteration
+                # Проверяем можем ли мы определить размер файла - иначе пропускаем его
+                try:
+                    # Возвращаем размер и полный путь файла
+                    yield getsize(flpath), flpath
+                except OSError:
+                    continue
+
+#==============================================================================
+
+class Cli_Presentation(object):
+    def __init__(self):
+        self.stopit = False
+        start_func(self.get_data, self.get_stopit, self.kill_wind)
+        pass
+
+#==============================================================================
+
+class Gtk_Presentation(object):
+
+    def __init__(self, start_path, count, start_func):
+        import gtk
+
+        # "Start path" entry
+        self.path_entry = gtk.Entry()
+        self.path_entry.set_text(start_path)
+
+        # "Files quantity" label
+        qty_label = gtk.Label('Files quantity')
+
+        # "Files quantity" spin
+        self.qty_spin = gtk.SpinButton()
+        self.qty_spin.set_numeric(True)
+        self.qty_spin.set_range(0, 65536)
+        self.qty_spin.set_increments(1, 10)
+        self.qty_spin.set_value(count)
+
+        # "Start" button
+        self.start_btn = gtk.Button('Start')
+        self.start_btn.connect('released', self.start_btn_released, start_func)
+
+        # "Stop" button
+        self.stop_btn = gtk.Button('Stop')
+        self.stop_btn.set_sensitive(False)
+        self.stop_btn.connect('clicked', self.stop_btn_clicked)
+
+        # Output selection
+        outtable_rbtn = gtk.RadioButton(None, 'Table')
+        outdiagram_rbtn = gtk.RadioButton(outtable_rbtn, 'Diagram')
+        out1_rbtn = gtk.RadioButton(outtable_rbtn, 'Another 1')
+        out2_rbtn = gtk.RadioButton(outtable_rbtn, 'Another 2')
+        out_rbtns = [outtable_rbtn, outdiagram_rbtn, out1_rbtn, out2_rbtn]
+
+        hbox = gtk.HBox(False, 4)
+        hbox.pack_start(qty_label, False, False, 0)
+        hbox.pack_start(self.qty_spin, False, False, 0)
+        hbox.pack_start(self.start_btn, False, False, 0)
+        hbox.pack_start(self.stop_btn, False, False, 0)
+        for btn in reversed(out_rbtns):
+            hbox.pack_end(btn, False, False, 0)
+
+        statusbar = gtk.Statusbar()
+        context_id = statusbar.get_context_id('Current walked file')
+        statusbar.push(context_id, 'test')
+
+        self.vbox = gtk.VBox(False, 4)
+        self.vbox.set_border_width(4)
+        self.vbox.pack_start(self.path_entry, False, False, 0)
+        self.vbox.pack_start(hbox, False, False, 0)
+        self.vbox.pack_end(statusbar, False, False, 0)
+
+#        self.show_out_toplevel(None, 'outtable')
+        self.frame = gtk.Frame('Files search')
+        self.frame.add(self.vbox)
+        self.frame.show_all()
+
+    #=== Functions ============================================================
+    def start_btn_released(self, widget, start_func):
+        self.stopit = False
+        self.stop_btn.set_sensitive(True)
+        self.start_btn.set_sensitive(False)
+        start_func(self.get_data, self.get_stopit, None, None)
+
+    def stop_btn_clicked(self, widget):
+        self.stopit = True
+        self.stop_btn.set_sensitive(False)
+        self.start_btn.set_sensitive(True)
+
+    def get_data(self):
+        return self.path_entry.get_text(), int(self.qty_spin.get_value())
+
+    def get_stopit(self):
+        return self.stopit
+
+    #=== Toplevel widget for embedding to main window =========================
+    def get_toplevel(self):
+        return self.frame ###
+
+    #=== Output type selecting ================================================
+    def show_out_toplevel(self, btn, outtype, results):
+        print 'Entering <' + outtype + '> output mode...'
+        out_present = __import__('files.' + outtype, None, None, outtype)
+        toplevel = out_present.Gtk_Presentation().get_toplevel()
+        ###self.vbox.remove(self.vbox.get_children()[2])
+        #self.vbox.add(toplevel)
+        self.vbox.pack_start(toplevel)
+        print results
diff --git a/src/main.py b/src/main.py
new file mode 100755 (executable)
index 0000000..c9a3485
--- /dev/null
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+# main.py --search files -o=table -p ". 7"
+
+import sys
+
+__progname__ = 'FindIT'
+__version__ = '0.2.0'
+
+#==============================================================================
+
+class Control(object):
+    def __init__(self):
+        if(len(sys.argv) > 1):
+            Cli_Presentation()
+        else:
+            Gtk_Presentation()
+
+#==============================================================================
+
+class Abstraction(object):
+    pass
+
+#==============================================================================
+
+class Cli_Presentation(object):
+
+    def __init__(self):
+        from optparse import OptionParser
+
+        parser = OptionParser()
+        parser.add_option('--search', '-s', dest='search', type='string')
+        parser.add_option('--output', '-o', dest='output', type='string')
+        parser.add_option('--params', '-p', dest='params', type='string')
+        (options, args) = parser.parse_args()
+        print options
+        print args
+
+        self.show_search_toplevel(options.search, options.output, options.params)
+
+    def show_search_toplevel(self, search, output, params):
+        search_present = __import__(search + '.search', globals(), locals(), 'Cli_Presentation')
+
+#==============================================================================
+
+class Gtk_Presentation(object):
+    """Main window class."""
+
+    def __init__(self):
+        import gtk
+
+        def _create_menu():
+            """ Create main menu """
+            menubar = gtk.MenuBar()
+            fileitem = gtk.MenuItem( '_File' )
+            viewitem = gtk.MenuItem( '_View' )
+            helpitem = gtk.MenuItem( '_Help' )
+            menubar.add(fileitem)
+            menubar.add(viewitem)
+            menubar.add(helpitem)
+            return menubar
+
+        window = gtk.Window()
+        window.set_default_size(560, 400)
+        window.set_border_width(4)
+        window.set_wmclass('MainWindow', 'FindIT')
+        window.connect('destroy', gtk.main_quit)
+
+        menu = _create_menu()
+
+        about_btn = gtk.Button('About')
+        about_btn.set_size_request(-1, 30)
+        about_btn.connect('clicked', self.about_dialog)
+
+        quit_btn = gtk.Button('Exit')
+        quit_btn.connect('clicked', gtk.main_quit)
+
+        file_btn = gtk.Button('Files search')
+        file_btn.connect('clicked', self.show_search_toplevel, 'files')
+
+        deb_btn = gtk.Button('Debs search')
+        deb_btn.connect('clicked', self.show_search_toplevel, 'debs')
+
+        toolbar = gtk.HBox(True, 4)
+        toolbar.pack_start(file_btn)
+        toolbar.pack_start(deb_btn)
+        toolbar.pack_start(about_btn)
+        toolbar.pack_start(quit_btn)
+
+        self.vbox = gtk.VBox(False, 4)
+        self.vbox.pack_start(menu, False, False, 0)
+        self.vbox.pack_start(toolbar, False, False, 0)
+        self.show_search_toplevel(None, 'files') ###
+
+        window.add(self.vbox)
+        window.show_all()
+        gtk.main()
+
+    def about_dialog(self, btn):
+        from about import About
+        About()
+
+    #=== Search selecting =====================================================
+    def show_search_toplevel(self, btn, searchtype):
+        print 'Entering <' + searchtype + '> search mode...'
+#         search_present = __import__(searchtype + '.search')
+#         toplevel = search_present.search.Gtk_Presentation().get_toplevel()
+
+        search_control = __import__(searchtype + '.search')
+        toplevel = search_control.search.Control().run()
+
+        try:
+            self.vbox.remove(self.vbox.get_children()[2])
+        except:
+            pass
+        self.vbox.pack_start(toplevel, True, True, 0)
+
+#==============================================================================
+
+if __name__ == '__main__':
+    Control()
diff --git a/src/misc.py b/src/misc.py
new file mode 100755 (executable)
index 0000000..b807c1d
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/python
+# -*-coding: utf-8 -*-
+# vim: sw=4 ts=4 expandtab ai
+
+def size_hum_read(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'