diff options
author | Tomeu Vizoso <tomeu@sugarlabs.org> | 2009-01-10 18:01:12 (GMT) |
---|---|---|
committer | Tomeu Vizoso <tomeu@sugarlabs.org> | 2009-01-10 18:01:12 (GMT) |
commit | 3ae6d51ebc0af3298fe058b7ed6acca60d168f22 (patch) | |
tree | f9f0aec5e4aa6ba20946bfe902ded1db9fe96148 /src | |
parent | 5d15f1caf33f050bf8c3a0422f8a950b186a6215 (diff) |
Read removable devices asynchronously
Diffstat (limited to 'src')
-rw-r--r-- | src/jarabe/journal/listview.py | 40 | ||||
-rw-r--r-- | src/jarabe/journal/model.py | 70 |
2 files changed, 83 insertions, 27 deletions
diff --git a/src/jarabe/journal/listview.py b/src/jarabe/journal/listview.py index b0be70e..e609c8c 100644 --- a/src/jarabe/journal/listview.py +++ b/src/jarabe/journal/listview.py @@ -18,6 +18,7 @@ import logging import traceback import sys from gettext import gettext as _ +import time import hippo import gobject @@ -49,6 +50,8 @@ class BaseListView(gtk.HBox): self._page_size = 0 self._reflow_sid = 0 self._do_scroll_hid = None + self._progress_bar = None + self._last_progress_bar_pulse = None gtk.HBox.__init__(self) self.set_flags(gtk.HAS_FOCUS|gtk.CAN_FOCUS) @@ -185,7 +188,17 @@ class BaseListView(gtk.HBox): def refresh(self): logging.debug('ListView.refresh query %r' % self._query) + self._stop_progress_bar() + self._start_progress_bar() + self._result_set = model.find(self._query) + self._result_set.ready.connect(self.__result_set_ready_cb) + self._result_set.progress.connect(self.__result_set_progress_cb) + self._result_set.setup() + + def __result_set_ready_cb(self, **kwargs): + self._stop_progress_bar() + self._vadjustment.props.upper = self._result_set.length self._vadjustment.changed() @@ -205,6 +218,33 @@ class BaseListView(gtk.HBox): self._clear_message() self._do_scroll() + def __result_set_progress_cb(self, **kwargs): + if time.time() - self._last_progress_bar_pulse > 0.05: + if self._progress_bar is not None: + self._progress_bar.pulse() + self._last_progress_bar_pulse = time.time() + + def _start_progress_bar(self): + self.remove(self._canvas) + self.remove(self._vscrollbar) + + alignment = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.5) + self.pack_start(alignment) + alignment.show() + + self._progress_bar = gtk.ProgressBar() + self._progress_bar.props.pulse_step = 0.01 + self._last_progress_bar_pulse = time.time() + alignment.add(self._progress_bar) + self._progress_bar.show() + + def _stop_progress_bar(self): + self.remove(self.get_children()[0]) + self._progress_bar = None + + self.pack_start(self._canvas) + self.pack_end(self._vscrollbar, expand=False, fill=False) + def _scroll_event_cb(self, hbox, event): if event.direction == gtk.gdk.SCROLL_UP: if self._vadjustment.props.value > self._vadjustment.props.lower: diff --git a/src/jarabe/journal/model.py b/src/jarabe/journal/model.py index ba98a48..71d0534 100644 --- a/src/jarabe/journal/model.py +++ b/src/jarabe/journal/model.py @@ -22,6 +22,7 @@ import shutil from stat import S_IFMT, S_IFDIR, S_IFREG import traceback +import gobject import dbus import gconf @@ -88,6 +89,12 @@ class BaseResultSet(object): self._offset = 0 self._cache = _Cache() + self.ready = dispatch.Signal() + self.progress = dispatch.Signal() + + def setup(self): + self.ready.send(self) + def get_length(self): if self._total_count == -1: query = self._query.copy() @@ -215,50 +222,59 @@ class InplaceResultSet(BaseResultSet): BaseResultSet.__init__(self, query) self._mount_point = mount_point self._file_list = None + self._pending_directories = 0 + + def setup(self): + self._file_list = [] + self._recurse_dir(self._mount_point) + + def setup_ready(self): + self._file_list.sort(lambda a, b: b[2] - a[2]) + self.ready.send(self) def find(self, query): - entries, total_count = self._query_mount_point(self._mount_point, query) + if self._file_list is None: + raise ValueError('Need to call setup() first') - for entry in entries: - entry['mountpoint'] = self._mount_point + t = time.time() + + offset = int(query.get('offset', 0)) + limit = int(query.get('limit', len(self._file_list))) + total_count = len(self._file_list) + + files = self._file_list[offset:offset + limit] + + entries = [] + for file_path, stat, mtime_ in files: + metadata = _get_file_metadata(file_path, stat) + metadata['mountpoint'] = self._mount_point + entries.append(metadata) + + logging.debug('InplaceResultSet.find took %f s.' % (time.time() - t)) return entries, total_count - def _build_file_list(self, dir_path): + def _recurse_dir(self, dir_path): for entry in os.listdir(dir_path): full_path = dir_path + '/' + entry try: stat = os.stat(full_path) if S_IFMT(stat.st_mode) == S_IFDIR: - self._build_file_list(full_path) + self._pending_directories += 1 + gobject.idle_add(lambda s=full_path: self._recurse_dir(s)) + elif S_IFMT(stat.st_mode) == S_IFREG: self._file_list.append((full_path, stat, int(stat.st_mtime))) + self.progress.send(self) + except Exception, e: logging.error('Error reading file %r: %r' % \ (full_path, traceback.format_exc())) - def _query_mount_point(self, mount_point, query): - t = time.time() - - if self._file_list is None: - self._file_list = [] - self._build_file_list(mount_point) - self._file_list.sort(lambda a, b: b[2] - a[2]) - - offset = int(query.get('offset', 0)) - limit = int(query.get('limit', len(self._file_list))) - total_count = len(self._file_list) - - files = self._file_list[offset:offset + limit] - - result = [] - for file_path, stat, mtime_ in files: - metadata = _get_file_metadata(file_path, stat) - result.append(metadata) - - logging.debug('_query_mount_point took %f s.' % (time.time() - t)) - - return result, total_count + if self._pending_directories == 0: + self.setup_ready() + else: + self._pending_directories -= 1 def _get_file_metadata(path, stat): client = gconf.client_get_default() |