diff options
author | Sayamindu Dasgupta <sayamindu@gmail.com> | 2009-11-25 23:44:43 (GMT) |
---|---|---|
committer | Sayamindu Dasgupta <sayamindu@gmail.com> | 2009-11-25 23:44:43 (GMT) |
commit | b790fe22551ea0e1e23cdf1c47b39ef9af1ee5c5 (patch) | |
tree | e0b9be43de0f9363bdd7cdc078ef711e9c604e75 | |
parent | 0b814c24bc007940a6d4588aea981d3531d29994 (diff) |
Implement support for resultsets returned in multiple pages
-rwxr-xr-x | GetIABooksActivity.py | 31 | ||||
-rw-r--r-- | opds.py | 69 |
2 files changed, 80 insertions, 20 deletions
diff --git a/GetIABooksActivity.py b/GetIABooksActivity.py index 0ffaebf..4a08207 100755 --- a/GetIABooksActivity.py +++ b/GetIABooksActivity.py @@ -247,6 +247,8 @@ class GetIABooksActivity(activity.Activity): self.list_scroller = gtk.ScrolledWindow(hadjustment=None, vadjustment=None) self.list_scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + vadjustment = self.list_scroller.get_vadjustment() + vadjustment.connect('value-changed', self.__vadjustment_value_changed_cb) self.list_scroller.add(self.listview) self.progressbar = gtk.ProgressBar() #TODO: Add a way to cancel download @@ -268,6 +270,9 @@ class GetIABooksActivity(activity.Activity): def can_close(self): self._lang_code_handler.close() + if self.queryresults is not None: + self.queryresults.cancel() + self.queryresults = None return True def selection_cb(self, widget): @@ -328,16 +333,16 @@ class GetIABooksActivity(activity.Activity): textbuffer = self.textview.get_buffer() textbuffer.set_text(_('Performing lookup, please wait...')) - self.queryresults.connect('completed', self.__query_completed_cb) + self.queryresults.connect('updated', self.__query_updated_cb) - def __query_completed_cb(self, query): + def __query_updated_cb(self, query, midway): self.listview.populate(self.queryresults) textbuffer = self.textview.get_buffer() - if len(self.queryresults) > 0: - textbuffer.set_text('') - else: + if len(self.queryresults) == 0: textbuffer.set_text(_('Sorry, no books could be found.')) + elif not midway: + textbuffer.set_text('') def __source_changed_cb(self, widget): search_terms = self._books_toolbar.get_search_terms() @@ -346,6 +351,22 @@ class GetIABooksActivity(activity.Activity): else: self.find_books(search_terms) + def __vadjustment_value_changed_cb(self, vadjustment): + + if not self.queryresults.is_ready(): + return + try: + # Use various tricks to update resultset as user scrolls down + if ((vadjustment.props.upper - vadjustment.props.lower) > 1000 \ + and (vadjustment.props.upper - vadjustment.props.value - \ + vadjustment.props.page_size)/(vadjustment.props.upper - \ + vadjustment.props.lower) < 0.3) or ((vadjustment.props.upper \ + - vadjustment.props.value - vadjustment.props.page_size) < 200): + if self.queryresults.has_next(): + self.queryresults.update_with_next() + finally: + return + def get_book(self): self._books_toolbar.enable_button(False) self.progressbar.show() @@ -16,6 +16,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +import logging import feedparser import threading @@ -23,6 +24,8 @@ import os import gobject +_logger = logging.getLogger('get-ia-books-activity') + _FEEDBOOKS_URI = 'http://feedbooks.com/books/search.atom?query=' _INTERNETARCHIVE_URI = 'http://bookserver.archive.org/catalog/opensearch?q=' @@ -31,19 +34,22 @@ _REL_OPDS_ACQUISTION = u'http://opds-spec.org/acquisition' gobject.threads_init() class DownloadThread(threading.Thread): - def __init__(self, obj): + def __init__(self, obj, midway): threading.Thread.__init__ (self) + self.midway = midway self.obj = obj self.stopthread = threading.Event() def _download(self): - if not self.obj.is_local(): + if not self.obj.is_local() and self.midway == False: feedobj = feedparser.parse(self.obj._uri + self.obj._queryterm.replace(' ', '+')) else: feedobj = feedparser.parse(self.obj._uri) + for entry in feedobj['entries']: + self.obj._booklist.append(Book(entry)) self.obj._feedobj = feedobj - self.obj.emit('completed') + self.obj.emit('updated', self.midway) self.obj._ready = True return False @@ -129,9 +135,9 @@ class Book(object): class QueryResult(gobject.GObject): __gsignals__ = { - 'completed': (gobject.SIGNAL_RUN_FIRST, + 'updated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, - ([])), + ([gobject.TYPE_BOOLEAN])), } def __init__(self, uri, queryterm): gobject.GObject.__init__(self) @@ -139,16 +145,45 @@ class QueryResult(gobject.GObject): self._uri = uri self._queryterm = queryterm self._feedobj = None + self._next_uri = '' self._ready = False + self._booklist = [] + self.threads = [] - - d_thread = DownloadThread(self) + self._start_download() + + def _start_download(self, midway = False): + d_thread = DownloadThread(self, midway) self.threads.append(d_thread) d_thread.start() def __len__(self): - return len(self._feedobj['entries']) + return len(self._booklist) + + def has_next(self): + ''' + Returns True if more result pages are + available for the resultset + ''' + if not self._feedobj['feed'].has_key('links'): + return False + for link in self._feedobj['feed']['links']: + if link['rel'] == u'next': + self._next_uri = link['href'] + return True + + return False + + def update_with_next(self): + ''' + Updates the booklist with the next resultset + ''' + if len(self._next_uri) > 0: + self._ready = False + self._uri = self._next_uri + self.cancel() #XXX: Is this needed ? + self._start_download(midway = True) def cancel(self): ''' @@ -157,18 +192,22 @@ class QueryResult(gobject.GObject): for d_thread in self.threads: d_thread.stop() - def get_book_n(self, n): - return Book(self._feedobj['entries'][n]) + ''' + Gets the n-th book + ''' + return self._booklist[n] def get_book_list(self): - ret = [] - for entry in self._feedobj['entries']: - ret.append(Book(entry)) - - return ret + ''' + Gets the entire booklist + ''' + return self._booklist def is_ready(self): + ''' + Returns False if a query is in progress + ''' return self._ready def is_local(self): |