diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index c27fa2a57b..b11e641d4b 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -1109,6 +1109,11 @@ class StoreAmazonKindleStore(StoreBase): description = _('Kindle books from Amazon') actual_plugin = 'calibre.gui2.store.amazon_plugin:AmazonKindleStore' +class StoreAmazonUKKindleStore(StoreBase): + name = 'Amazon UK Kindle' + description = _('Kindle books from Amazon.uk') + actual_plugin = 'calibre.gui2.store.amazon_uk_plugin:AmazonUKKindleStore' + class StoreBaenWebScriptionStore(StoreBase): name = 'Baen WebScription' description = _('Ebooks for readers.') @@ -1174,10 +1179,27 @@ class StoreSmashwordsStore(StoreBase): description = _('Your ebook. Your way.') actual_plugin = 'calibre.gui2.store.smashwords_plugin:SmashwordsStore' -plugins += [StoreAmazonKindleStore, StoreBaenWebScriptionStore, StoreBNStore, +class StoreWaterstonesUKStore(StoreBase): + name = 'Waterstones UK' + description = _('Feel every word') + actual_plugin = 'calibre.gui2.store.waterstones_uk_plugin:WaterstonesUKStore' + +class StoreFoylesUKStore(StoreBase): + name = 'Foyles UK' + description = _('Foyles of London, online') + actual_plugin = 'calibre.gui2.store.foyles_uk_plugin:FoylesUKStore' + +class AmazonDEKindleStore(StoreBase): + name = 'Amazon DE Kindle' + description = _('Kindle eBooks') + actual_plugin = 'calibre.gui2.store.amazon_de_plugin:AmazonDEKindleStore' + +plugins += [StoreAmazonKindleStore, AmazonDEKindleStore, StoreAmazonUKKindleStore, + StoreBaenWebScriptionStore, StoreBNStore, StoreBeWriteStore, StoreDieselEbooksStore, StoreEbookscomStore, StoreEHarlequinStoretore, StoreFeedbooksStore, StoreGutenbergStore, StoreKoboStore, StoreManyBooksStore, - StoreMobileReadStore, StoreOpenLibraryStore, StoreSmashwordsStore] + StoreMobileReadStore, StoreOpenLibraryStore, StoreSmashwordsStore, + StoreFoylesUKStore, StoreWaterstonesUKStore] # }}} diff --git a/src/calibre/gui2/store/amazon_de_plugin.py b/src/calibre/gui2/store/amazon_de_plugin.py new file mode 100644 index 0000000000..782d6bf0ed --- /dev/null +++ b/src/calibre/gui2/store/amazon_de_plugin.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +from __future__ import (unicode_literals, division, absolute_import, print_function) + +__license__ = 'GPL 3' +__copyright__ = '2011, John Schember ' +__docformat__ = 'restructuredtext en' + +from PyQt4.Qt import QUrl + +from calibre.gui2 import open_url +from calibre.gui2.store.amazon_plugin import AmazonKindleStore + +class AmazonDEKindleStore(AmazonKindleStore): + ''' + For comments on the implementation, please see amazon_plugin.py + ''' + + search_url = 'http://www.amazon.de/s/url=search-alias%3Ddigital-text&field-keywords=' + details_url = 'http://amazon.de/dp/' + drm_search_text = u'Gleichzeitige Verwendung von Geräten' + drm_free_text = u'Keine Einschränkung' + + def open(self, parent=None, detail_item=None, external=False): + aff_id = {'tag': 'charhale0a-21'} + store_link = ('http://www.amazon.de/gp/redirect.html?ie=UTF8&site-redirect=de' + '&tag=%(tag)s&linkCode=ur2&camp=1638&creative=19454' + '&location=http://www.amazon.de/ebooks-kindle/b?node=530886031') % aff_id + if detail_item: + aff_id['asin'] = detail_item + store_link = ('http://www.amazon.de/gp/redirect.html?ie=UTF8' + '&location=http://www.amazon.de/dp/%(asin)s&site-redirect=de' + '&tag=%(tag)s&linkCode=ur2&camp=1638&creative=6742') % aff_id + open_url(QUrl(store_link)) diff --git a/src/calibre/gui2/store/amazon_plugin.py b/src/calibre/gui2/store/amazon_plugin.py index a68e4611f0..8a983f0e47 100644 --- a/src/calibre/gui2/store/amazon_plugin.py +++ b/src/calibre/gui2/store/amazon_plugin.py @@ -22,6 +22,11 @@ from calibre.gui2.store.search_result import SearchResult class AmazonKindleStore(StorePlugin): + search_url = 'http://www.amazon.com/s/url=search-alias%3Ddigital-text&field-keywords=' + details_url = 'http://amazon.com/dp/' + drm_search_text = u'Simultaneous Device Usage' + drm_free_text = u'Unlimited' + def open(self, parent=None, detail_item=None, external=False): ''' Amazon comes with a number of difficulties. @@ -117,7 +122,7 @@ class AmazonKindleStore(StorePlugin): open_url(QUrl(store_link)) def search(self, query, max_results=10, timeout=60): - url = 'http://www.amazon.com/s/url=search-alias%3Ddigital-text&field-keywords=' + urllib2.quote(query) + url = self.search_url + urllib2.quote(query) br = browser() counter = max_results @@ -180,18 +185,19 @@ class AmazonKindleStore(StorePlugin): yield s def get_details(self, search_result, timeout): - url = 'http://amazon.com/dp/' + url = self.details_url br = browser() with closing(br.open(url + search_result.detail_item, timeout=timeout)) as nf: idata = html.fromstring(nf.read()) - if idata.xpath('boolean(//div[@class="content"]//li/b[contains(text(), "Simultaneous Device Usage")])'): - if idata.xpath('boolean(//div[@class="content"]//li[contains(., "Unlimited") and contains(b, "Simultaneous Device Usage")])'): + if idata.xpath('boolean(//div[@class="content"]//li/b[contains(text(), "' + + self.drm_search_text + '")])'): + if idata.xpath('boolean(//div[@class="content"]//li[contains(., "' + + self.drm_free_text + '") and contains(b, "' + + self.drm_search_text + '")])'): search_result.drm = SearchResult.DRM_UNLOCKED else: search_result.drm = SearchResult.DRM_UNKNOWN else: search_result.drm = SearchResult.DRM_LOCKED return True - - diff --git a/src/calibre/gui2/store/amazon_uk_plugin.py b/src/calibre/gui2/store/amazon_uk_plugin.py new file mode 100644 index 0000000000..770db6cfd9 --- /dev/null +++ b/src/calibre/gui2/store/amazon_uk_plugin.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +from __future__ import (unicode_literals, division, absolute_import, print_function) + +__license__ = 'GPL 3' +__copyright__ = '2011, John Schember ' +__docformat__ = 'restructuredtext en' + + +from PyQt4.Qt import QUrl + +from calibre.gui2 import open_url +from calibre.gui2.store.amazon_plugin import AmazonKindleStore + +class AmazonUKKindleStore(AmazonKindleStore): + ''' + For comments on the implementation, please see amazon_plugin.py + ''' + + search_url = 'http://www.amazon.co.uk/s/url=search-alias%3Ddigital-text&field-keywords=' + details_url = 'http://amazon.co.uk/dp/' + + def open(self, parent=None, detail_item=None, external=False): + aff_id = {'tag': 'calcharles-21'} + store_link = 'http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&location=http://www.amazon.co.uk/Kindle-eBooks/b?ie=UTF8&node=341689031&ref_=sa_menu_kbo2&tag=%(tag)s&linkCode=ur2&camp=1634&creative=19450' % aff_id + + if detail_item: + aff_id['asin'] = detail_item + store_link = 'http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&location=http://www.amazon.co.uk/dp/%(asin)s&tag=%(tag)s&linkCode=ur2&camp=1634&creative=6738' % aff_id + open_url(QUrl(store_link)) diff --git a/src/calibre/gui2/store/foyles_uk_plugin.py b/src/calibre/gui2/store/foyles_uk_plugin.py new file mode 100644 index 0000000000..b2ad3e5de1 --- /dev/null +++ b/src/calibre/gui2/store/foyles_uk_plugin.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- + +from __future__ import (unicode_literals, division, absolute_import, print_function) + +__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/cread.php?awinmid=1414&awinaffid=120917&clickref=&p=' + url_redirect = 'http://www.foyles.co.uk' + + if external or self.config.get('open_external', False): + if detail_item: + url = url + url_redirect + detail_item + open_url(QUrl(url_slash_cleaner(url))) + else: + detail_url = None + if detail_item: + detail_url = url + url_redirect + 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://www.foyles.co.uk/Public/Shop/Search.aspx?fFacetId=1015&searchBy=1&quick=true&term=' + 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('//table[contains(@id, "MainContent")]/tr/td/div[contains(@class, "Item")]'): + if counter <= 0: + break + id = ''.join(data.xpath('.//a[@class="Title"]/@href')).strip() + if not id: + continue + + cover_url = ''.join(data.xpath('.//a[@class="Jacket"]/img/@src')) + if cover_url: + cover_url = 'http://www.foyles.co.uk' + cover_url + print(cover_url) + + title = ''.join(data.xpath('.//a[@class="Title"]/text()')) + author = ', '.join(data.xpath('.//span[@class="Author"]/text()')) + price = ''.join(data.xpath('./ul/li[@class="Strong"]/text()')) + price = price[price.rfind(' '):] + + 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 = 'EPUB' + + yield s diff --git a/src/calibre/gui2/store/waterstones_uk_plugin.py b/src/calibre/gui2/store/waterstones_uk_plugin.py new file mode 100644 index 0000000000..d422165c47 --- /dev/null +++ b/src/calibre/gui2/store/waterstones_uk_plugin.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +from __future__ import (unicode_literals, division, absolute_import, print_function) + +__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 +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 WaterstonesUKStore(BasicStoreConfig, StorePlugin): + + def open(self, parent=None, detail_item=None, external=False): + url = 'http://clkuk.tradedoubler.com/click?p=51196&a=1951604&g=19333484' + url_details = 'http://clkuk.tradedoubler.com/click?p(51196)a(1951604)g(16460516)url({0})' + + if external or self.config.get('open_external', False): + if detail_item: + url = url_details.format(detail_item) + open_url(QUrl(url)) + else: + detail_url = None + if detail_item: + detail_url = url_details.format(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://www.waterstones.com/waterstonesweb/advancedSearch.do?buttonClicked=1&format=3757&bookkeywords=' + 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[contains(@class, "results-pane")]'): + if counter <= 0: + break + + id = ''.join(data.xpath('./div/div/h2/a/@href')).strip() + if not id: + continue + cover_url = ''.join(data.xpath('.//div[@class="image"]/a/img/@src')) + title = ''.join(data.xpath('./div/div/h2/a/text()')) + author = ', '.join(data.xpath('.//p[@class="byAuthor"]/a/text()')) + price = ''.join(data.xpath('.//p[@class="price"]/span[@class="priceStandard"]/text()')) + drm = data.xpath('boolean(.//td[@headers="productFormat" and contains(., "DRM")])') + pdf = data.xpath('boolean(.//td[@headers="productFormat" and contains(., "PDF")])') + epub = data.xpath('boolean(.//td[@headers="productFormat" and contains(., "EPUB")])') + + counter -= 1 + + s = SearchResult() + s.cover_url = cover_url + s.title = title.strip() + s.author = author.strip() + s.price = price + if drm: + s.drm = SearchResult.DRM_LOCKED + else: + s.drm = SearchResult.DRM_UNKNOWN + s.detail_item = id + formats = [] + if epub: + formats.append('EPUB') + if pdf: + formats.append('PDF') + s.formats = ', '.join(formats) + + yield s