From a26557414cf8734417db61775b2abe61074a262a Mon Sep 17 00:00:00 2001 From: John Schember Date: Sun, 15 May 2011 19:54:46 -0400 Subject: [PATCH] Store: Cleanup descriptions. Add Nexto store plugin. --- src/calibre/customize/builtins.py | 34 +++++----- src/calibre/gui2/store/nexto_plugin.py | 86 ++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 src/calibre/gui2/store/nexto_plugin.py diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 2677e008ae..761ec05402 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -1,4 +1,5 @@ -import os.path +# -*- coding: utf-8 -*- + __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' @@ -1094,22 +1095,22 @@ plugins += [LookAndFeel, Behavior, Columns, Toolbar, Search, InputOptions, # Store plugins {{{ class StoreAmazonKindleStore(StoreBase): name = 'Amazon Kindle' - description = _('Kindle books from Amazon') + description = _('Kindle books from Amazon.') actual_plugin = 'calibre.gui2.store.amazon_plugin:AmazonKindleStore' class StoreAmazonDEKindleStore(StoreBase): name = 'Amazon DE Kindle' - description = _('Kindle eBooks') + description = _('Kindle books form Amazon.de.') actual_plugin = 'calibre.gui2.store.amazon_de_plugin:AmazonDEKindleStore' class StoreAmazonUKKindleStore(StoreBase): name = 'Amazon UK Kindle' - description = _('Kindle books from Amazon.uk') + description = _('Kindle books from Amazon.uk.') actual_plugin = 'calibre.gui2.store.amazon_uk_plugin:AmazonUKKindleStore' class StoreArchiveOrgStore(StoreBase): name = 'Archive.org' - description = _('Rree Books : Download & Streaming : Ebook and Texts Archive : Internet Archive') + description = _('Free Books : Download & Streaming : Ebook and Texts Archive : Internet Archive.') actual_plugin = 'calibre.gui2.store.archive_org_plugin:ArchiveOrgStore' @@ -1125,7 +1126,7 @@ class StoreBNStore(StoreBase): class StoreBeamEBooksDEStore(StoreBase): name = 'Beam EBooks DE' - description = _('der eBook Shop') + description = _('Der eBook Shop.') actual_plugin = 'calibre.gui2.store.beam_ebooks_de_plugin:BeamEBooksDEStore' class StoreBeWriteStore(StoreBase): @@ -1145,12 +1146,12 @@ class StoreEbookscomStore(StoreBase): class StoreEPubBuyDEStore(StoreBase): name = 'EPUBBuy DE' - description = _('EPUBReaders eBook Shop') + description = _('EPUBReaders eBook Shop.') actual_plugin = 'calibre.gui2.store.epubbuy_de_plugin:EPubBuyDEStore' class StoreEHarlequinStore(StoreBase): name = 'eHarlequin' - description = _('entertain, enrich, inspire.') + description = _('Entertain, enrich, inspire.') actual_plugin = 'calibre.gui2.store.eharlequin_plugin:EHarlequinStore' class StoreFeedbooksStore(StoreBase): @@ -1160,7 +1161,7 @@ class StoreFeedbooksStore(StoreBase): class StoreFoylesUKStore(StoreBase): name = 'Foyles UK' - description = _('Foyles of London, online') + description = _('Foyles of London, online.') actual_plugin = 'calibre.gui2.store.foyles_uk_plugin:FoylesUKStore' class StoreGutenbergStore(StoreBase): @@ -1180,9 +1181,14 @@ class StoreManyBooksStore(StoreBase): class StoreMobileReadStore(StoreBase): name = 'MobileRead' - description = _('Ebooks handcrafted with the utmost care') + description = _('Ebooks handcrafted with the utmost care.') actual_plugin = 'calibre.gui2.store.mobileread.mobileread_plugin:MobileReadStore' +class StoreNextoStore(StoreBase): + name = 'Nexto' + description = _('Audiobooki mp3, ebooki, prasa - księgarnia internetowa.') + actual_plugin = 'calibre.gui2.store.nexto_plugin:NextoStore' + class StoreOpenLibraryStore(StoreBase): name = 'Open Library' description = _('One web page for every book.') @@ -1195,17 +1201,17 @@ class StoreSmashwordsStore(StoreBase): class StoreWaterstonesUKStore(StoreBase): name = 'Waterstones UK' - description = _('Feel every word') + description = _('Feel every word.') actual_plugin = 'calibre.gui2.store.waterstones_uk_plugin:WaterstonesUKStore' class StoreWeightlessBooksStore(StoreBase): name = 'Weightless Books' - description = '(e)Books That Don\'t Weigh You Down' + description = '(e)Books That Don\'t Weigh You Down.' actual_plugin = 'calibre.gui2.store.weightless_books_plugin:WeightlessBooksStore' class StoreWizardsTowerBooksStore(StoreBase): name = 'Wizards Tower Books' - description = 'Wizard\'s Tower Press' + description = 'Wizard\'s Tower Press.' actual_plugin = 'calibre.gui2.store.wizards_tower_books_plugin:WizardsTowerBooksStore' plugins += [StoreArchiveOrgStore, StoreAmazonKindleStore, StoreAmazonDEKindleStore, @@ -1214,7 +1220,7 @@ plugins += [StoreArchiveOrgStore, StoreAmazonKindleStore, StoreAmazonDEKindleSto StoreDieselEbooksStore, StoreEbookscomStore, StoreEPubBuyDEStore, StoreEHarlequinStore, StoreFeedbooksStore, StoreFoylesUKStore, StoreGutenbergStore, StoreKoboStore, StoreManyBooksStore, - StoreMobileReadStore, StoreOpenLibraryStore, StoreSmashwordsStore, + StoreMobileReadStore, StoreNextoStore, StoreOpenLibraryStore, StoreSmashwordsStore, StoreWaterstonesUKStore, StoreWeightlessBooksStore, StoreWizardsTowerBooksStore] # }}} diff --git a/src/calibre/gui2/store/nexto_plugin.py b/src/calibre/gui2/store/nexto_plugin.py new file mode 100644 index 0000000000..154274d12a --- /dev/null +++ b/src/calibre/gui2/store/nexto_plugin.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- + +from __future__ import (unicode_literals, division, absolute_import, print_function) + +__license__ = 'GPL 3' +__copyright__ = '2011, Tomasz Długosz ' +__docformat__ = 'restructuredtext en' + +import re +import urllib +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 NextoStore(BasicStoreConfig, StorePlugin): + + def open(self, parent=None, detail_item=None, external=False): + pid = '155711' + + url = 'http://www.nexto.pl/ebooki_c1015.xml?pid=' + pid + detail_url = None + + if detail_item: + book_id = re.search(r'p[0-9]*\.xml\Z', detail_item) + book_id = book_id.group(0).replace('.xml','').replace('p','') + if book_id: + detail_url = 'http://www.nexto.pl/rf/pr?p=' + book_id + '&pid=' + pid + + if external or self.config.get('open_external', False): + open_url(QUrl(url_slash_cleaner(detail_url if detail_url else url))) + else: + 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.nexto.pl/szukaj.xml?search-clause=' + urllib.quote_plus(query.encode('utf-8')) + '&scid=1015' + + br = browser() + + counter = max_results + with closing(br.open(url, timeout=timeout)) as f: + doc = html.fromstring(f.read()) + for data in doc.xpath('//ul[@class="productslist"]/li'): + if counter <= 0: + break + + id = ''.join(data.xpath('.//div[@class="cover_container"]/a[1]/@href')) + if not id: + continue + + price = ''.join(data.xpath('.//strong[@class="nprice"]/text()')) + + cover_url = ''.join(data.xpath('.//img[@class="cover"]/@src')) + title = ''.join(data.xpath('.//a[@class="title"]/text()')) + formats = ', '.join(data.xpath('.//ul[@class="formats_available"]/li//b/text()')) + DrmFree = re.search(r'bez.DRM', formats) + formats = re.sub(r'\(.+\)', '', formats) + + author = '' + with closing(br.open('http://www.nexto.pl/' + id.strip(), timeout=timeout/4)) as nf: + idata = html.fromstring(nf.read()) + author = ''.join(idata.xpath('//div[@class="basic_data"]/p[1]/b/a/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.strip() + s.drm = SearchResult.DRM_UNLOCKED if DrmFree else SearchResult.DRM_LOCKED + s.formats = formats.upper().strip() + + yield s