diff --git a/wizpym.py b/wizpym.py index e5f90b6..9c7bbc3 100644 --- a/wizpym.py +++ b/wizpym.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # -*- coding: utf-8 -*- # # wizpym - The Wyzard Python Module, a tool to write Wizard-like apps. @@ -17,9 +16,6 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, see . -# Requires Python 2.6 for with statements. -# Requires Python 2.5 for etree in test panes. - """A tool to write Wizard-like apps. This module provides classes to easily build wizard-type applications @@ -245,7 +241,6 @@ class ActivePane(Pane): it does nothing. """ if len(self._progress_box.get_children()): - print '#Hide' gobject.idle_add(self._progress_box.remove, self._progress_box.get_children()[0]) @@ -406,12 +401,10 @@ class AboutTestPane(Pane): self.link_to(InputTestPane) + self.pack_start(gtk.Label('A simple search tool.'), True, True, 10) self.pack_start( - gtk.Label('wizpym, Wizard Python Module v' + __version__), - True, True, 10) - self.pack_start( - gtk.Label('Copyright 2010 David Soulayrol '), - False, False, 5) + gtk.Label( + 'Copyright 2010 David Soulayrol '), False) comment = gtk.Label() comment.set_markup('This wizard tests the main features of wizpym, ' @@ -436,33 +429,77 @@ class InputTestPane(Pane): def __init__(self, frame): Pane.__init__(self, frame) - self.link_to(ActiveTestPane) - self.link_to(FinalTestPane) + self.set_header('Please select your kind of search and fill in criteria fields.') + self.ready = False + + self.link_to(GoogleSearchTestPane) + self.link_to(LocalSearchTestPane) + + frame = gtk.Frame('Kind of search:') + frame.set_border_width(10) + self.pack_start(frame, padding=10) + vbox = gtk.VBox() + frame.add(vbox) button = gtk.RadioButton(None, 'Search Google Code') - button.connect("toggled", self._on_button, ActiveTestPane) + button.connect("toggled", self._on_button, GoogleSearchTestPane) button.set_active(True) - self.pack_start(button, True, False) + vbox.pack_start(button) + + button = gtk.RadioButton(button, "Search Local Files") + button.connect("toggled", self._on_button, LocalSearchTestPane) + vbox.pack_start(button) box = gtk.HBox(False, 10) - self._entry = gtk.Entry() - box.pack_start(gtk.Label('Keywords:'), False, False) - box.pack_start(self._entry, True, True) - self.pack_start(box, False, False) + box.set_border_width(10) + self._folder_entry = gtk.Entry() + self._folder_entry.connect('changed', self._on_entry_update) + box.pack_start(gtk.Label('Directory:'), False) + box.pack_start(self._folder_entry) + vbox.pack_start(box) - button = gtk.RadioButton(button, "Go to final pane") - button.connect("toggled", self._on_button, FinalTestPane) - self.pack_start(button, True, False) + box = gtk.HBox(False, 10) + box.set_border_width(10) + self._keywords_entry = gtk.Entry() + self._keywords_entry.connect('changed', self._on_entry_update) + box.pack_start(gtk.Label('Keywords:'), False) + box.pack_start(self._keywords_entry) + self.pack_start(box) + + self._update_status() def leave(self): - self.subject = self._entry.get_text() + self.subject[0] = self._keywords_entry.get_text() + self.subject[1] = self._folder_entry.get_text() + + def _on_entry_update(self, w): + self._update_status() def _on_button(self, w, klass): if w.get_active(): self.switch(klass) + self._update_status() + + def _update_status(self): + r = len(self._keywords_entry.get_text()) + e = None if r else 'Please fill in the keywords field' + + if isinstance(self.next(), LocalSearchTestPane): + if not len(self._folder_entry.get_text()): + r = False + e = 'Local search needs a root folder' + else: + try: + os.stat(self._folder_entry.get_text()) + except OSError: + r = False + e = self._folder_entry.get_text() + ' is not a valid path' + + self.set_error(e) + self.ready = r -class ActiveTestPane(ActivePane): +class GoogleSearchTestPane(ActivePane): PATH = 'https://www.google.com/codesearch/feeds/search?' XMLNS_ATOM = '{http://www.w3.org/2005/Atom}' XMLNS_GCS = '{http://schemas.google.com/codesearch/2006}' @@ -470,17 +507,11 @@ class ActiveTestPane(ActivePane): def __init__(self, frame): ActivePane.__init__(self, frame) - self.link_to(FinalTestPane) - - self._label = gtk.Label() - self._label.set_line_wrap(True) - self.pack_start(self._label, False, False) - self._inner_pane = gtk.VBox(False, 5) self.pack_start(self._inner_pane, True, True) def enter(self): - self._label.set_text('Searching for: "' + self.subject + '"') + self.set_header('Google Code results for: "' + self.subject[0] + '"') self.remove(self._inner_pane) self._inner_pane = gtk.VBox(False, 5) @@ -491,23 +522,12 @@ class ActiveTestPane(ActivePane): def _runner(self): timer = gobject.timeout_add(100, lambda: self.update_progress_bar()) - - self.update_progress_bar(text='Connecting...') - c = httplib.HTTPSConnection('www.google.com') - self.update_progress_bar(text='Searching...') - c.request( - 'GET', self.PATH + urllib.urlencode({'q': self.subject}), - None, {'GData-Version': '2'}) - - # Simulate a longer task. - gobject.source_remove(timer) - self.update_progress_bar(0, 'Computing...') - for i in range(100): - self.update_progress_bar(i / 100.) - time.sleep(.02) - + c = httplib.HTTPSConnection('www.google.com') + c.request('GET', self.PATH + urllib.urlencode({'q': self.subject[0]}), + None, {'GData-Version': '2'}) self.hide_progress_bar() + gobject.source_remove(timer) gobject.idle_add(self._show_response, c.getresponse()) def _show_response(self, r): @@ -527,17 +547,62 @@ class ActiveTestPane(ActivePane): self.pack_start(self._inner_pane, True, True) -class FinalTestPane(Pane): +class LocalSearchTestPane(ActivePane): def __init__(self, frame): - Pane.__init__(self, frame) - self.add(gtk.Label('Last Pane: no successor.')) + ActivePane.__init__(self, frame) + + sw = gtk.ScrolledWindow() + sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + textview = gtk.TextView() + textview.set_editable(False) + sw.add(textview) + self.pack_start(sw) + + self._buffer = textview.get_buffer() + + def enter(self): + self.set_header( + 'Grep results for: "' + self.subject[0].split()[0] + '" in ' + self.subject[1]) + + # Start thread + ActivePane.enter(self) + + def _runner(self): + timer = gobject.timeout_add(100, lambda: self.update_progress_bar()) + self.update_progress_bar(0, 'Counting files...') + nb_files = 0 + for root, dirs, files in os.walk('/home/david/src/opensips'): + self._filter_directories(dirs) + nb_files += len(files) + gobject.source_remove(timer) + + # Tweak so that the division below operates on floats. + count = float(0) + item = self.subject[0].split()[0] + for root, dirs, files in os.walk('/home/david/src/opensips'): + self._filter_directories(dirs) + for f in files: + name = os.path.join(root, f) + p = subprocess.Popen(['grep', '-HnT', item, name], + stdout=subprocess.PIPE) + self._buffer.insert_at_cursor(p.communicate()[0]) + self.update_progress_bar( + count / nb_files, + name + '(' + str(int(count)) + '/' + str(nb_files) + ')') + count += 1 + self.hide_progress_bar() + + def _filter_directories(self, dirs): + for f in ['CVS', '.svn', '.git']: + if f in dirs: + dirs.remove(f) if __name__ == '__main__': - import httplib, urllib, time + import httplib, os, subprocess, urllib import xml.etree.ElementTree as etree gobject.threads_init() - Frame(AboutTestPane).run() + Frame(AboutTestPane, ['', '']).run() gtk.main()