From e29f12ff19ff93cc65184fb8c0a13390689408f4 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Tue, 18 Feb 2014 13:37:51 +0100 Subject: [PATCH] Fix bookstores to account for website changes. Remove Foyles because their search now uses ajax (complicated), and no one ever buys from that store anyway. --- src/calibre/customize/builtins.py | 11 --- .../gui2/store/stores/amazon_de_plugin.py | 5 +- .../gui2/store/stores/amazon_es_plugin.py | 4 +- .../gui2/store/stores/amazon_fr_plugin.py | 4 +- .../gui2/store/stores/amazon_it_plugin.py | 4 +- .../gui2/store/stores/amazon_uk_plugin.py | 4 +- .../gui2/store/stores/foyles_uk_plugin.py | 76 ------------------- .../gui2/store/stores/mills_boon_uk_plugin.py | 23 +++--- 8 files changed, 22 insertions(+), 109 deletions(-) delete mode 100644 src/calibre/gui2/store/stores/foyles_uk_plugin.py diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index b77f841d99..75760ceada 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -1475,16 +1475,6 @@ class StoreFeedbooksStore(StoreBase): headquarters = 'FR' formats = ['EPUB', 'MOBI', 'PDF'] -class StoreFoylesUKStore(StoreBase): - name = 'Foyles UK' - author = 'Charles Haley' - description = u'Foyles of London\'s ebook store. Provides extensive range covering all subjects.' - actual_plugin = 'calibre.gui2.store.stores.foyles_uk_plugin:FoylesUKStore' - - headquarters = 'UK' - formats = ['EPUB', 'PDF'] - affiliate = True - class StoreGoogleBooksStore(StoreBase): name = 'Google Books' description = u'Google Books' @@ -1748,7 +1738,6 @@ plugins += [ StoreEKnigiStore, StoreEmpikStore, StoreFeedbooksStore, - StoreFoylesUKStore, StoreGoogleBooksStore, StoreGutenbergStore, StoreKoboStore, diff --git a/src/calibre/gui2/store/stores/amazon_de_plugin.py b/src/calibre/gui2/store/stores/amazon_de_plugin.py index 7bb2f43047..7adfe58a81 100644 --- a/src/calibre/gui2/store/stores/amazon_de_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_de_plugin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import (unicode_literals, division, absolute_import, print_function) -store_version = 4 # Needed for dynamic plugin loading +store_version = 5 # Needed for dynamic plugin loading __license__ = 'GPL 3' __copyright__ = '2011, John Schember ' @@ -67,7 +67,7 @@ class AmazonDEKindleStore(StorePlugin): './/ul[contains(@class, "rsltGridList")]' '//span[contains(@class, "lrg") and not(contains(@class, "bld"))]/text()') asin_xpath = '@name' - cover_xpath = './/img[@class="productImage"]/@src' + cover_xpath = './/img[contains(@class, "productImage")]/@src' title_xpath = './/h3[@class="newaps"]/a//text()' author_xpath = './/h3[@class="newaps"]//span[contains(@class, "reg")]//text()' price_xpath = ( @@ -156,3 +156,4 @@ class AmazonDEKindleStore(StorePlugin): def get_details(self, search_result, timeout): pass + diff --git a/src/calibre/gui2/store/stores/amazon_es_plugin.py b/src/calibre/gui2/store/stores/amazon_es_plugin.py index 1613e3f13a..fac927a41c 100644 --- a/src/calibre/gui2/store/stores/amazon_es_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_es_plugin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import (unicode_literals, division, absolute_import, print_function) -store_version = 4 # Needed for dynamic plugin loading +store_version = 5 # Needed for dynamic plugin loading __license__ = 'GPL 3' __copyright__ = '2011, John Schember ' @@ -66,7 +66,7 @@ class AmazonESKindleStore(StorePlugin): './/ul[contains(@class, "rsltGridList")]' '//span[contains(@class, "lrg") and not(contains(@class, "bld"))]/text()') asin_xpath = '@name' - cover_xpath = './/img[@class="productImage"]/@src' + cover_xpath = './/img[contains(@class, "productImage")]/@src' title_xpath = './/h3[@class="newaps"]/a//text()' author_xpath = './/h3[@class="newaps"]//span[contains(@class, "reg")]//text()' price_xpath = ( diff --git a/src/calibre/gui2/store/stores/amazon_fr_plugin.py b/src/calibre/gui2/store/stores/amazon_fr_plugin.py index 4d210111e8..f9f7ff68d9 100644 --- a/src/calibre/gui2/store/stores/amazon_fr_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_fr_plugin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import (unicode_literals, division, absolute_import, print_function) -store_version = 4 # Needed for dynamic plugin loading +store_version = 5 # Needed for dynamic plugin loading __license__ = 'GPL 3' __copyright__ = '2011, John Schember ' @@ -63,7 +63,7 @@ class AmazonFRKindleStore(StorePlugin): './/ul[contains(@class, "rsltGridList")]' '//span[contains(@class, "lrg") and not(contains(@class, "bld"))]/text()') asin_xpath = '@name' - cover_xpath = './/img[@class="productImage"]/@src' + cover_xpath = './/img[contains(@class, "productImage")]/@src' title_xpath = './/h3[@class="newaps"]/a//text()' author_xpath = './/h3[@class="newaps"]//span[contains(@class, "reg")]//text()' price_xpath = ( diff --git a/src/calibre/gui2/store/stores/amazon_it_plugin.py b/src/calibre/gui2/store/stores/amazon_it_plugin.py index 1e905d370e..9e9961f864 100644 --- a/src/calibre/gui2/store/stores/amazon_it_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_it_plugin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import (unicode_literals, division, absolute_import, print_function) -store_version = 4 # Needed for dynamic plugin loading +store_version = 5 # Needed for dynamic plugin loading __license__ = 'GPL 3' __copyright__ = '2011, John Schember ' @@ -66,7 +66,7 @@ class AmazonITKindleStore(StorePlugin): './/ul[contains(@class, "rsltGridList")]' '//span[contains(@class, "lrg") and not(contains(@class, "bld"))]/text()') asin_xpath = '@name' - cover_xpath = './/img[@class="productImage"]/@src' + cover_xpath = './/img[contains(@class, "productImage")]/@src' title_xpath = './/h3[@class="newaps"]/a//text()' author_xpath = './/h3[@class="newaps"]//span[contains(@class, "reg")]//text()' price_xpath = ( diff --git a/src/calibre/gui2/store/stores/amazon_uk_plugin.py b/src/calibre/gui2/store/stores/amazon_uk_plugin.py index 0cd5f34dbd..ef0650c9f3 100644 --- a/src/calibre/gui2/store/stores/amazon_uk_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_uk_plugin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import (unicode_literals, division, absolute_import, print_function) -store_version = 4 # Needed for dynamic plugin loading +store_version = 5 # Needed for dynamic plugin loading __license__ = 'GPL 3' __copyright__ = '2011, John Schember ' @@ -70,7 +70,7 @@ class AmazonUKKindleStore(StorePlugin): './/ul[contains(@class, "rsltGridList")]' '//span[contains(@class, "lrg") and not(contains(@class, "bld"))]/text()') asin_xpath = '@name' - cover_xpath = './/img[@class="productImage"]/@src' + cover_xpath = './/img[contains(@class, "productImage")]/@src' title_xpath = './/h3[@class="newaps"]/a//text()' author_xpath = './/h3[@class="newaps"]//span[contains(@class, "reg")]//text()' price_xpath = ( diff --git a/src/calibre/gui2/store/stores/foyles_uk_plugin.py b/src/calibre/gui2/store/stores/foyles_uk_plugin.py deleted file mode 100644 index b43e14fcef..0000000000 --- a/src/calibre/gui2/store/stores/foyles_uk_plugin.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import (unicode_literals, division, absolute_import, print_function) -store_version = 2 # Needed for dynamic plugin loading - -__license__ = 'GPL 3' -__copyright__ = '2011, John Schember ' -__docformat__ = 'restructuredtext en' - -import urllib2 -from contextlib import closing - -from lxml import html - -from PyQt4.Qt import QUrl - -from calibre import browser, url_slash_cleaner -from calibre.gui2 import open_url -from calibre.gui2.store import StorePlugin -from calibre.gui2.store.basic_config import BasicStoreConfig -from calibre.gui2.store.search_result import SearchResult -from calibre.gui2.store.web_store_dialog import WebStoreDialog - -class FoylesUKStore(BasicStoreConfig, StorePlugin): - - def open(self, parent=None, detail_item=None, external=False): - url = 'http://www.awin1.com/awclick.php?mid=1414&id=120917' - detail_url = 'http://www.awin1.com/cread.php?awinmid=1414&awinaffid=120917&clickref=&p=' - - if external or self.config.get('open_external', False): - if detail_item: - url = detail_url + detail_item - open_url(QUrl(url_slash_cleaner(url))) - else: - detail_url = None - if detail_item: - detail_url = url + detail_item - d = WebStoreDialog(self.gui, url, parent, detail_url) - d.setWindowTitle(self.name) - d.set_tags(self.config.get('tags', '')) - d.exec_() - - def search(self, query, max_results=10, timeout=60): - url = 'http://ebooks.foyles.co.uk/catalog/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[@class="doc-item"]'): - if counter <= 0: - break - id_ = ''.join(data.xpath('.//p[@class="doc-cover"]/a/@href')).strip() - if not id_: - continue - id_ = 'http://ebooks.foyles.co.uk' + id_ - - cover_url = ''.join(data.xpath('.//p[@class="doc-cover"]/a/img/@src')) - title = ''.join(data.xpath('.//span[@class="title"]/a/text()')) - author = ', '.join(data.xpath('.//span[@class="author"]/span[@class="author"]/text()')) - price = ''.join(data.xpath('.//span[@itemprop="price"]/text()')).strip() - format_ = ''.join(data.xpath('.//p[@class="doc-meta-format"]/span[last()]/text()')) - - counter -= 1 - - s = SearchResult() - s.cover_url = cover_url - s.title = title.strip() - s.author = author.strip() - s.price = price - s.detail_item = id_ - s.drm = SearchResult.DRM_LOCKED - s.formats = format_ - - yield s diff --git a/src/calibre/gui2/store/stores/mills_boon_uk_plugin.py b/src/calibre/gui2/store/stores/mills_boon_uk_plugin.py index b8969beaed..1b2f754f21 100644 --- a/src/calibre/gui2/store/stores/mills_boon_uk_plugin.py +++ b/src/calibre/gui2/store/stores/mills_boon_uk_plugin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import (unicode_literals, division, absolute_import, print_function) -store_version = 1 # Needed for dynamic plugin loading +store_version = 2 # Needed for dynamic plugin loading __license__ = 'GPL 3' __copyright__ = '2011, John Schember ' @@ -41,27 +41,26 @@ class MillsBoonUKStore(BasicStoreConfig, StorePlugin): d.exec_() def search(self, query, max_results=10, timeout=60): - base_url = 'http://millsandboon.co.uk' - url = base_url + '/pages/searchres.htm?search=true&booktypesearch=ebook&first=yes&inputsearch=' + urllib2.quote(query) + base_url = 'http://www.millsandboon.co.uk' + url = base_url + '/search?format=ebook&q=' + urllib2.quote(query) + #print(url) 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="catProdDiv"]'): + for data in doc.xpath('//article[contains(@class, "group")]'): if counter <= 0: break - id_ = ''.join(data.xpath('.//div[@class="catProdImage"]/div/a/@href')).strip() - id_ = base_url + id_[2:] + id_ = ''.join(data.xpath('.//div[@class="img-wrapper"]/a/@href')).strip() + id_ = base_url + id_ if not id_: continue - cover_url = ''.join(data.xpath('.//div[@class="catProdImage"]/div/a/img/@src')) - cover_url = base_url + cover_url[2:] - title = ''.join(data.xpath('.//div[@class="catProdImage"]/div/a/img/@alt')).strip() - title = title[23:] - author = ''.join(data.xpath('.//div[@class="catProdDetails"]/div[@class="catProdDetails-top"]/p[1]/a/text()')) - price = ''.join(data.xpath('.//span[@class="priceBold"]/text()')) + cover_url = ''.join(data.xpath('.//div[@class="img-wrapper"]/a/img/@src')) + title = ''.join(data.xpath('.//div[@class="img-wrapper"]/a/img/@alt')).strip() + author = ''.join(data.xpath('.//a[@class="author"]/text()')) + price = ''.join(data.xpath('.//li[@class="productAttribute" and child::span[text()="eBook"]]/input/@value')) format_ = ''.join(data.xpath('.//p[@class="doc-meta-format"]/span[last()]/text()')) drm = SearchResult.DRM_LOCKED