Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSayamindu Dasgupta <sayamindu@gmail.com>2009-11-25 23:44:43 (GMT)
committer Sayamindu Dasgupta <sayamindu@gmail.com>2009-11-25 23:44:43 (GMT)
commitb790fe22551ea0e1e23cdf1c47b39ef9af1ee5c5 (patch)
treee0b9be43de0f9363bdd7cdc078ef711e9c604e75
parent0b814c24bc007940a6d4588aea981d3531d29994 (diff)
Implement support for resultsets returned in multiple pages
-rwxr-xr-xGetIABooksActivity.py31
-rw-r--r--opds.py69
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()
diff --git a/opds.py b/opds.py
index 0f20b37..389ee78 100644
--- a/opds.py
+++ b/opds.py
@@ -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):