From df8347a62b6e56b2ca1c485e7508a987c9ba672b Mon Sep 17 00:00:00 2001 From: John Schember Date: Sat, 26 Feb 2011 11:51:01 -0500 Subject: [PATCH] ManyBooks store. Gutenberg search filters invalid items quicker and ensures full id is not truncated. --- src/calibre/customize/builtins.py | 3 +- src/calibre/gui2/store/gutenberg_plugin.py | 16 ++++-- src/calibre/gui2/store/manybooks_plugin.py | 60 ++++++++++++++++++++++ 3 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 src/calibre/gui2/store/manybooks_plugin.py diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 38aff09eb0..78fc0a4b9b 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -1043,7 +1043,8 @@ plugins += [GoogleBooks] # Store plugins {{{ from calibre.gui2.store.amazon_plugin import AmazonKindleStore from calibre.gui2.store.gutenberg_plugin import GutenbergStore +from calibre.gui2.store.manybooks_plugin import ManyBooksStore -plugins += [AmazonKindleStore, GutenbergStore] +plugins += [AmazonKindleStore, GutenbergStore, ManyBooksStore] # }}} diff --git a/src/calibre/gui2/store/gutenberg_plugin.py b/src/calibre/gui2/store/gutenberg_plugin.py index 6904e27bcd..e31fc1149d 100644 --- a/src/calibre/gui2/store/gutenberg_plugin.py +++ b/src/calibre/gui2/store/gutenberg_plugin.py @@ -38,14 +38,22 @@ class GutenbergStore(StorePlugin): if counter <= 0: break - heading = ''.join(data.xpath('div[@class="jd"]/a//text()')) + url = '' + url_a = data.xpath('div[@class="jd"]/a') + if url_a: + url_a = url_a[0] + url = url_a.get('href', None) + if url: + url = url.split('u=')[-1].split('&')[0] + if '/ebooks/' not in url: + continue + id = url.split('/')[-1] + + heading = ''.join(url_a.xpath('text()')) title, _, author = heading.partition('by') author = author.split('-')[0] price = '$0.00' - url = ''.join(data.xpath('span[@class="c"]/text()')) - id = url.split('/')[-1] - counter -= 1 yield ('', title.strip(), author.strip(), price.strip(), '/ebooks/' + id.strip()) diff --git a/src/calibre/gui2/store/manybooks_plugin.py b/src/calibre/gui2/store/manybooks_plugin.py new file mode 100644 index 0000000000..79818b9123 --- /dev/null +++ b/src/calibre/gui2/store/manybooks_plugin.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +__license__ = 'GPL 3' +__copyright__ = '2011, John Schember ' +__docformat__ = 'restructuredtext en' + +import urllib2 +from contextlib import closing + +from lxml import html + +from calibre import browser +from calibre.customize import StorePlugin + +class ManyBooksStore(StorePlugin): + + name = 'ManyBooks' + description = _('The best ebooks at the best price: free!.') + + + def open(self, gui, parent=None, start_item=None): + from calibre.gui2.store.web_store_dialog import WebStoreDialog + d = WebStoreDialog(gui, 'http://manybooks.net/', parent, start_item) + d.setWindowTitle('Ad-free eBooks for your eBook reader') + d = d.exec_() + + def search(self, query, max_results=10, timeout=60): + # ManyBooks website separates results for title and author. + # Using a google search so we can search on both fields at once. + url = 'http://www.google.com/xhtml?q=site:manybooks.net+' + urllib2.quote(query) + + br = browser() + + counter = max_results + with closing(br.open(url, timeout=timeout)) as f: + doc = html.fromstring(f.read()) + for data in doc.xpath('//div[@class="edewpi"]//div[@class="r ld"]'): + if counter <= 0: + break + + url = '' + url_a = data.xpath('div[@class="jd"]/a') + if url_a: + url_a = url_a[0] + url = url_a.get('href', None) + if url: + url = url.split('u=')[-1][:-2] + if '/titles/' not in url: + continue + id = url.split('/')[-1] + + heading = ''.join(url_a.xpath('text()')) + title, _, author = heading.partition('by') + author = author.split('-')[0] + price = '$0.00' + + counter -= 1 + yield ('', title.strip(), author.strip(), price.strip(), '/titles/' + id.strip()) + +