diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 76aaf3a8ce..451a1c9b62 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -1045,7 +1045,8 @@ from calibre.gui2.store.amazon_plugin import AmazonKindleStore from calibre.gui2.store.gutenberg_plugin import GutenbergStore from calibre.gui2.store.feedbooks_plugin import FeedbooksStore from calibre.gui2.store.manybooks_plugin import ManyBooksStore +from calibre.gui2.store.smashwords_plugin import SmashwordsStore -plugins += [AmazonKindleStore, GutenbergStore, FeedbooksStore, ManyBooksStore] +plugins += [GutenbergStore, FeedbooksStore, ManyBooksStore, SmashwordsStore] # }}} diff --git a/src/calibre/gui2/store/manybooks_plugin.py b/src/calibre/gui2/store/manybooks_plugin.py index 1d68dc774b..ac9cac5323 100644 --- a/src/calibre/gui2/store/manybooks_plugin.py +++ b/src/calibre/gui2/store/manybooks_plugin.py @@ -17,7 +17,7 @@ from calibre.gui2.store.search_result import SearchResult class ManyBooksStore(StorePlugin): name = 'ManyBooks' - description = _('The best ebooks at the best price: free!.') + description = _('The best ebooks at the best price: free!') def open(self, gui, parent=None, detail_item=None): diff --git a/src/calibre/gui2/store/search.py b/src/calibre/gui2/store/search.py index 39b3162c43..82d6fc5e65 100644 --- a/src/calibre/gui2/store/search.py +++ b/src/calibre/gui2/store/search.py @@ -134,8 +134,8 @@ class SearchThread(Thread): if self.abort.is_set(): return self.results.put((self.store_name, res)) - except: - pass + except Exception as e: + print e class CoverDownloadThread(Thread): diff --git a/src/calibre/gui2/store/smashwords_plugin.py b/src/calibre/gui2/store/smashwords_plugin.py new file mode 100644 index 0000000000..c4eb1bb741 --- /dev/null +++ b/src/calibre/gui2/store/smashwords_plugin.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- + +__license__ = 'GPL 3' +__copyright__ = '2011, John Schember ' +__docformat__ = 'restructuredtext en' + +import re +import urllib2 +from contextlib import closing + +from lxml import html + +from calibre import browser +from calibre.customize import StorePlugin +from calibre.gui2.store.search_result import SearchResult + +class SmashwordsStore(StorePlugin): + + name = 'Smashwords' + description = _('Your ebook. Your way.') + + + def open(self, gui, parent=None, detail_item=None): + from calibre.gui2.store.web_store_dialog import WebStoreDialog + d = WebStoreDialog(gui, 'http://www.smashwords.com/?ref=usernone', parent, detail_item) + d.setWindowTitle(self.name) + d = d.exec_() + + def search(self, query, max_results=10, timeout=60): + url = 'http://www.smashwords.com/books/search?query=' + 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[@id="pageCenterContent2"]//div[@class="bookCoverImg"]'): + if counter <= 0: + break + data = html.fromstring(html.tostring(data)) + + id = None + id_a = data.xpath('//a[@class="bookTitle"]') + if id_a: + id = id_a[0].get('href', None) + if id: + id = id.split('/')[-1] + if not id: + continue + + cover_url = '' + c_url = data.get('style', None) + if c_url: + mo = re.search(r'http://[^\'"]+', c_url) + if mo: + cover_url = mo.group() + + title = ''.join(data.xpath('//a[@class="bookTitle"]/text()')) + subnote = ''.join(data.xpath('//span[@class="subnote"]/text()')) + author = ''.join(data.xpath('//span[@class="subnote"]/a/text()')) + price = subnote.partition('$')[2] + price = price.split(u'\xa0')[0] + price = '$' + price + + counter -= 1 + + s = SearchResult() + s.cover_url = cover_url + s.title = title.strip() + s.author = author.strip() + s.price = price.strip() + s.detail_item = '/books/view/' + id.strip() + + yield s diff --git a/src/calibre/gui2/store/web_store_dialog.py b/src/calibre/gui2/store/web_store_dialog.py index 3910ca6912..fcb294cd69 100644 --- a/src/calibre/gui2/store/web_store_dialog.py +++ b/src/calibre/gui2/store/web_store_dialog.py @@ -42,7 +42,9 @@ class WebStoreDialog(QDialog, Ui_Dialog): def go_home(self, checked=False, detail_item=None): url = self.base_url if detail_item: - url += '/' + urllib.quote(detail_item) + url, q, ref = url.partition('?') + url = url + '/' + urllib.quote(detail_item) + q + ref + # Reduce redundant /'s because some stores # (Feedbooks) and server frameworks (cherrypy) # choke on them.