mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
version numbers to support dynamic loading of get books plugins
This commit is contained in:
parent
792d4284b3
commit
d2e27f55b8
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -21,4 +22,4 @@ class AmazonESKindleStore(AmazonUKKindleStore):
|
||||
'&linkCode=ur2&camp=3626&creative=24790')
|
||||
search_url = 'http://www.amazon.es/s/?url=search-alias%3Ddigital-text&field-keywords='
|
||||
|
||||
author_article = 'de '
|
||||
author_article = 'de '
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -21,4 +22,4 @@ class AmazonITKindleStore(AmazonUKKindleStore):
|
||||
'linkCode=ur2&camp=3370&creative=23322')
|
||||
search_url = 'http://www.amazon.it/s/?url=search-alias%3Ddigital-text&field-keywords='
|
||||
|
||||
author_article = 'di '
|
||||
author_article = 'di '
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -135,11 +136,11 @@ class AmazonKindleStore(StorePlugin):
|
||||
title_xpath = './/h3[@class="newaps"]/a//text()'
|
||||
author_xpath = './/h3[@class="newaps"]//span[contains(@class, "reg")]/text()'
|
||||
price_xpath = './/ul[contains(@class, "rsltL")]//span[contains(@class, "lrg") and contains(@class, "bld")]/text()'
|
||||
|
||||
|
||||
for data in doc.xpath(data_xpath):
|
||||
if counter <= 0:
|
||||
break
|
||||
|
||||
|
||||
# Even though we are searching digital-text only Amazon will still
|
||||
# put in results for non Kindle books (author pages). Se we need
|
||||
# to explicitly check if the item is a Kindle book and ignore it
|
||||
@ -147,7 +148,7 @@ class AmazonKindleStore(StorePlugin):
|
||||
format = ''.join(data.xpath(format_xpath))
|
||||
if 'kindle' not in format.lower():
|
||||
continue
|
||||
|
||||
|
||||
# We must have an asin otherwise we can't easily reference the
|
||||
# book later.
|
||||
asin_href = None
|
||||
@ -161,7 +162,7 @@ class AmazonKindleStore(StorePlugin):
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
|
||||
|
||||
cover_url = ''.join(data.xpath(cover_xpath))
|
||||
|
||||
title = ''.join(data.xpath(title_xpath))
|
||||
@ -172,9 +173,9 @@ class AmazonKindleStore(StorePlugin):
|
||||
pass
|
||||
|
||||
price = ''.join(data.xpath(price_xpath))
|
||||
|
||||
|
||||
counter -= 1
|
||||
|
||||
|
||||
s = SearchResult()
|
||||
s.cover_url = cover_url.strip()
|
||||
s.title = title.strip()
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -22,7 +23,7 @@ from calibre.gui2.store.search_result import SearchResult
|
||||
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
|
||||
class BaenWebScriptionStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
url = 'http://www.baenebooks.com/'
|
||||
|
||||
@ -41,26 +42,26 @@ class BaenWebScriptionStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
url = 'http://www.baenebooks.com/searchadv.aspx?IsSubmit=true&SearchTerm=' + 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//table//table//table//tr'):
|
||||
if counter <= 0:
|
||||
break
|
||||
|
||||
|
||||
id = ''.join(data.xpath('./td[1]/a/@href'))
|
||||
if not id or not id.startswith('p-'):
|
||||
continue
|
||||
|
||||
|
||||
title = ''.join(data.xpath('./td[1]/a/text()'))
|
||||
|
||||
|
||||
author = ''
|
||||
cover_url = ''
|
||||
price = ''
|
||||
|
||||
|
||||
with closing(br.open('http://www.baenebooks.com/' + id.strip(), timeout=timeout/4)) as nf:
|
||||
idata = html.fromstring(nf.read())
|
||||
author = ''.join(idata.xpath('//span[@class="ProductNameText"]/../b/text()'))
|
||||
@ -68,16 +69,16 @@ class BaenWebScriptionStore(BasicStoreConfig, StorePlugin):
|
||||
price = ''.join(idata.xpath('//span[@class="variantprice"]/text()'))
|
||||
a, b, price = price.partition('$')
|
||||
price = b + price
|
||||
|
||||
|
||||
pnum = ''
|
||||
mo = re.search(r'p-(?P<num>\d+)-', id.strip())
|
||||
if mo:
|
||||
pnum = mo.group('num')
|
||||
if pnum:
|
||||
cover_url = 'http://www.baenebooks.com/' + ''.join(idata.xpath('//img[@id="ProductPic%s"]/@src' % pnum))
|
||||
|
||||
|
||||
counter -= 1
|
||||
|
||||
|
||||
s = SearchResult()
|
||||
s.cover_url = cover_url
|
||||
s.title = title.strip()
|
||||
@ -86,5 +87,5 @@ class BaenWebScriptionStore(BasicStoreConfig, StorePlugin):
|
||||
s.detail_item = id.strip()
|
||||
s.drm = SearchResult.DRM_UNLOCKED
|
||||
s.formats = 'RB, MOBI, EPUB, LIT, LRF, RTF, HTML'
|
||||
|
||||
|
||||
yield s
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -71,7 +72,7 @@ class BeWriteStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
with closing(br.open(search_result.detail_item, timeout=timeout)) as nf:
|
||||
idata = html.fromstring(nf.read())
|
||||
|
||||
|
||||
price = ''.join(idata.xpath('//div[@id="content"]//td[contains(text(), "ePub")]/text()'))
|
||||
if not price:
|
||||
price = ''.join(idata.xpath('//div[@id="content"]//td[contains(text(), "MOBI")]/text()'))
|
||||
@ -79,7 +80,7 @@ class BeWriteStore(BasicStoreConfig, StorePlugin):
|
||||
price = ''.join(idata.xpath('//div[@id="content"]//td[contains(text(), "PDF")]/text()'))
|
||||
price = '$' + price.split('$')[-1]
|
||||
search_result.price = price.strip()
|
||||
|
||||
|
||||
cover_img = idata.xpath('//div[@id="content"]//img/@src')
|
||||
if cover_img:
|
||||
for i in cover_img:
|
||||
@ -87,7 +88,7 @@ class BeWriteStore(BasicStoreConfig, StorePlugin):
|
||||
cover_url = 'http://www.bewrite.net/mm5/' + i
|
||||
search_result.cover_url = cover_url.strip()
|
||||
break
|
||||
|
||||
|
||||
formats = set([])
|
||||
if idata.xpath('boolean(//div[@id="content"]//td[contains(text(), "ePub")])'):
|
||||
formats.add('EPUB')
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2012, Alex Stanev <alex@stanev.org>'
|
||||
@ -26,7 +27,7 @@ class BiblioStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
|
||||
for s in OpenSearchOPDSStore.search(self, query, max_results, timeout):
|
||||
yield s
|
||||
|
||||
|
||||
def get_details(self, search_result, timeout):
|
||||
# get format and DRM status
|
||||
from calibre import browser
|
||||
@ -39,13 +40,13 @@ class BiblioStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
search_result.formats = ''
|
||||
if idata.xpath('.//span[@class="format epub"]'):
|
||||
search_result.formats = 'EPUB'
|
||||
|
||||
|
||||
if idata.xpath('.//span[@class="format pdf"]'):
|
||||
if search_result.formats == '':
|
||||
search_result.formats = 'PDF'
|
||||
else:
|
||||
search_result.formats.join(', PDF')
|
||||
|
||||
|
||||
if idata.xpath('.//span[@class="format nodrm-icon"]'):
|
||||
search_result.drm = SearchResult.DRM_UNLOCKED
|
||||
else:
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, Alex Stanev <alex@stanev.org>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011-2012, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2012, Florent FAYOLLE <florent.fayolle69@gmail.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -36,9 +37,9 @@ class EHarlequinStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
url = 'http://ebooks.eharlequin.com/BANGSearch.dll?Type=FullText&FullTextField=All&FullTextCriteria=' + urllib2.quote(query)
|
||||
|
||||
|
||||
br = browser()
|
||||
|
||||
|
||||
counter = max_results
|
||||
with closing(br.open(url, timeout=timeout)) as f:
|
||||
doc = html.fromstring(f.read())
|
||||
@ -64,19 +65,19 @@ class EHarlequinStore(BasicStoreConfig, StorePlugin):
|
||||
s.price = price.strip()
|
||||
s.detail_item = 'http://ebooks.eharlequin.com/' + id.strip()
|
||||
s.formats = 'EPUB'
|
||||
|
||||
|
||||
yield s
|
||||
|
||||
|
||||
def get_details(self, search_result, timeout):
|
||||
url = 'http://ebooks.eharlequin.com/en/ContentDetails.htm?ID='
|
||||
|
||||
|
||||
mo = re.search(r'\?ID=(?P<id>.+)', search_result.detail_item)
|
||||
if mo:
|
||||
id = mo.group('id')
|
||||
if not id:
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
br = browser()
|
||||
with closing(br.open(url + id, timeout=timeout)) as nf:
|
||||
idata = html.fromstring(nf.read())
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, Alex Stanev <alex@stanev.org>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011-2012, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
@ -68,7 +69,7 @@ class EmpikStore(BasicStoreConfig, StorePlugin):
|
||||
counter -= 1
|
||||
|
||||
s = SearchResult()
|
||||
s.cover_url = cover_url
|
||||
s.cover_url = cover_url
|
||||
s.title = title.strip() + ' ' + formats
|
||||
s.author = author.strip()
|
||||
s.price = price
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -11,10 +12,10 @@ from calibre.gui2.store.opensearch_store import OpenSearchOPDSStore
|
||||
from calibre.gui2.store.search_result import SearchResult
|
||||
|
||||
class FeedbooksStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
|
||||
|
||||
open_search_url = 'http://assets0.feedbooks.net/opensearch.xml?t=1253087147'
|
||||
web_url = 'http://feedbooks.com/'
|
||||
|
||||
|
||||
# http://www.feedbooks.com/catalog
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -38,7 +39,7 @@ class GoogleBooksStore(BasicStoreConfig, StorePlugin):
|
||||
'ganpub': 'k352583',
|
||||
'ganclk': 'GOOG_1335335464',
|
||||
}
|
||||
|
||||
|
||||
url = 'http://gan.doubleclick.net/gan_click?lid=%(lid)s&pubid=%(pubid)s' % aff_id
|
||||
if detail_item:
|
||||
detail_item += '&ganpub=%(ganpub)s&ganclk=%(ganclk)s' % aff_id
|
||||
@ -53,9 +54,9 @@ class GoogleBooksStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
url = 'http://www.google.com/search?tbm=bks&q=' + urllib.quote_plus(query)
|
||||
|
||||
|
||||
br = browser()
|
||||
|
||||
|
||||
counter = max_results
|
||||
with closing(br.open(url, timeout=timeout)) as f:
|
||||
doc = html.fromstring(f.read())
|
||||
@ -76,22 +77,22 @@ class GoogleBooksStore(BasicStoreConfig, StorePlugin):
|
||||
author = ', '.join(authors)
|
||||
|
||||
counter -= 1
|
||||
|
||||
|
||||
s = SearchResult()
|
||||
s.title = title.strip()
|
||||
s.author = author.strip()
|
||||
s.detail_item = id.strip()
|
||||
s.drm = SearchResult.DRM_UNKNOWN
|
||||
|
||||
|
||||
yield s
|
||||
|
||||
|
||||
def get_details(self, search_result, timeout):
|
||||
br = browser()
|
||||
with closing(br.open(search_result.detail_item, timeout=timeout)) as nf:
|
||||
doc = html.fromstring(nf.read())
|
||||
|
||||
|
||||
search_result.cover_url = ''.join(doc.xpath('//div[@class="sidebarcover"]//img/@src'))
|
||||
|
||||
|
||||
# Try to get the set price.
|
||||
price = ''.join(doc.xpath('//div[@id="gb-get-book-container"]//a/text()'))
|
||||
if 'read' in price.lower():
|
||||
@ -101,10 +102,10 @@ class GoogleBooksStore(BasicStoreConfig, StorePlugin):
|
||||
elif '-' in price:
|
||||
a, b, price = price.partition(' - ')
|
||||
search_result.price = price.strip()
|
||||
|
||||
|
||||
search_result.formats = ', '.join(doc.xpath('//div[contains(@class, "download-panel-div")]//a/text()')).upper()
|
||||
if not search_result.formats:
|
||||
search_result.formats = _('Unknown')
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
@ -24,7 +25,7 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class LegimiStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
|
||||
|
||||
plain_url = 'http://www.legimi.com/pl/ebooki/'
|
||||
url = 'https://ssl.afiliant.com/affskrypt,,2f9de2,,11483,,,?u=(' + plain_url + ')'
|
||||
detail_url = None
|
||||
@ -42,17 +43,17 @@ class LegimiStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
url = 'http://www.legimi.com/pl/ebooki/?szukaj=' + urllib.quote_plus(query)
|
||||
|
||||
|
||||
br = browser()
|
||||
drm_pattern = re.compile("zabezpieczona DRM")
|
||||
|
||||
|
||||
counter = max_results
|
||||
with closing(br.open(url, timeout=timeout)) as f:
|
||||
doc = html.fromstring(f.read())
|
||||
for data in doc.xpath('//div[@id="listBooks"]/div'):
|
||||
if counter <= 0:
|
||||
break
|
||||
|
||||
|
||||
id = ''.join(data.xpath('.//a[@class="plainLink"]/@href'))
|
||||
if not id:
|
||||
continue
|
||||
@ -73,7 +74,7 @@ class LegimiStore(BasicStoreConfig, StorePlugin):
|
||||
drm = drm_pattern.search(''.join(idata.xpath('.//div[@id="fullBookFormats"]/p/text()')))
|
||||
|
||||
counter -= 1
|
||||
|
||||
|
||||
s = SearchResult()
|
||||
s.cover_url = 'http://www.legimi.com/' + cover_url
|
||||
s.title = title.strip()
|
||||
@ -82,5 +83,5 @@ class LegimiStore(BasicStoreConfig, StorePlugin):
|
||||
s.detail_item = 'http://www.legimi.com/' + id.strip()
|
||||
s.formats = ', '.join(formats)
|
||||
s.drm = SearchResult.DRM_LOCKED if drm else SearchResult.DRM_UNLOCKED
|
||||
|
||||
|
||||
yield s
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, Roman Mukhin <ramses_ru at hotmail.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -26,7 +27,7 @@ class ManyBooksStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
'''
|
||||
Manybooks uses a very strange opds feed. The opds
|
||||
main feed is structured like a stanza feed. The
|
||||
main feed is structured like a stanza feed. The
|
||||
search result entries give very little information
|
||||
and requires you to go to a detail link. The detail
|
||||
link has the wrong type specified (text/html instead
|
||||
@ -45,7 +46,7 @@ class ManyBooksStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
oquery.searchTerms = query
|
||||
oquery.count = max_results
|
||||
url = oquery.url()
|
||||
|
||||
|
||||
counter = max_results
|
||||
br = browser()
|
||||
with closing(br.open(url, timeout=timeout)) as f:
|
||||
@ -55,11 +56,11 @@ class ManyBooksStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
for data in doc.xpath('//*[local-name() = "entry"]'):
|
||||
if counter <= 0:
|
||||
break
|
||||
|
||||
|
||||
counter -= 1
|
||||
|
||||
|
||||
s = SearchResult()
|
||||
|
||||
|
||||
detail_links = data.xpath('./*[local-name() = "link" and @type = "text/html"]')
|
||||
if not detail_links:
|
||||
continue
|
||||
@ -73,7 +74,7 @@ class ManyBooksStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
# just in case.
|
||||
s.title = ''.join(data.xpath('./*[local-name() = "title"]//text()')).strip()
|
||||
s.author = ', '.join(data.xpath('./*[local-name() = "author"]//text()')).strip()
|
||||
|
||||
|
||||
# Follow the detail link to get the rest of the info.
|
||||
with closing(br.open(detail_href, timeout=timeout/4)) as df:
|
||||
ddoc = etree.fromstring(df.read())
|
||||
@ -89,9 +90,9 @@ class ManyBooksStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
s.author = s.author[1:]
|
||||
if s.author.endswith(','):
|
||||
s.author = s.author[:-1]
|
||||
|
||||
|
||||
s.cover_url = ''.join(ddata.xpath('./*[local-name() = "link" and @rel = "http://opds-spec.org/thumbnail"][1]/@href')).strip()
|
||||
|
||||
|
||||
for link in ddata.xpath('./*[local-name() = "link" and @rel = "http://opds-spec.org/acquisition"]'):
|
||||
type = link.get('type')
|
||||
href = link.get('href')
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011-2012, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2012, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, Roman Mukhin <ramses_ru at hotmail.com>'
|
||||
@ -24,33 +25,33 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
|
||||
class OzonRUStore(BasicStoreConfig, StorePlugin):
|
||||
shop_url = 'http://www.ozon.ru'
|
||||
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
|
||||
|
||||
aff_id = '?partner=romuk'
|
||||
# Use Kovid's affiliate id 30% of the time.
|
||||
if random.randint(1, 10) in (1, 2, 3):
|
||||
aff_id = '?partner=kovidgoyal'
|
||||
|
||||
|
||||
url = self.shop_url + aff_id
|
||||
detail_url = None
|
||||
if detail_item:
|
||||
# http://www.ozon.ru/context/detail/id/3037277/
|
||||
detail_url = self.shop_url + '/context/detail/id/' + urllib2.quote(detail_item) + aff_id
|
||||
|
||||
|
||||
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_()
|
||||
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=15, timeout=60):
|
||||
search_url = self.shop_url + '/webservice/webservice.asmx/SearchWebService?'\
|
||||
'searchText=%s&searchContext=ebook' % urllib2.quote(query)
|
||||
search_urls = [ search_url ]
|
||||
|
||||
|
||||
## add this as the fist try if it looks like ozon ID
|
||||
if re.match("^\d{6,9}$", query):
|
||||
ozon_detail = self.shop_url + '/webservices/OzonWebSvc.asmx/ItemDetail?ID=%s' % query
|
||||
@ -59,7 +60,7 @@ class OzonRUStore(BasicStoreConfig, StorePlugin):
|
||||
xp_template = 'normalize-space(./*[local-name() = "{0}"]/text())'
|
||||
counter = max_results
|
||||
br = browser()
|
||||
|
||||
|
||||
for url in search_urls:
|
||||
with closing(br.open(url, timeout=timeout)) as f:
|
||||
raw = xml_to_unicode(f.read(), strip_encoding_pats=True, assume_utf8=True)[0]
|
||||
@ -86,10 +87,10 @@ class OzonRUStore(BasicStoreConfig, StorePlugin):
|
||||
with closing(br.open(url, timeout=timeout)) as f:
|
||||
raw = xml_to_unicode(f.read(), verbose=True)[0]
|
||||
doc = html.fromstring(raw)
|
||||
|
||||
|
||||
# example where we are going to find formats
|
||||
# <div class="l">
|
||||
# <p>
|
||||
# <p>
|
||||
# Доступно:
|
||||
# </p>
|
||||
# </div>
|
||||
@ -104,16 +105,16 @@ class OzonRUStore(BasicStoreConfig, StorePlugin):
|
||||
search_result.formats = ', '.join(_parse_ebook_formats(formats))
|
||||
# unfortunately no direct links to download books (only buy link)
|
||||
# search_result.downloads['BF2'] = self.shop_url + '/order/digitalorder.aspx?id=' + + urllib2.quote(search_result.detail_item)
|
||||
|
||||
|
||||
#<p class="main-cost"><span class="main">215</span><span class="submain">00</span> руб.</p>
|
||||
#<span itemprop="price" class="hidden">215.00</span>
|
||||
#<meta itemprop="priceCurrency" content="RUR " />
|
||||
|
||||
|
||||
# if the price not in the search result (the ID search case)
|
||||
if not search_result.price:
|
||||
price = doc.xpath(u'normalize-space(//*[@itemprop="price"]/text())')
|
||||
search_result.price = format_price_in_RUR(price)
|
||||
|
||||
|
||||
return result
|
||||
|
||||
def format_price_in_RUR(price):
|
||||
@ -134,12 +135,12 @@ def format_price_in_RUR(price):
|
||||
def _parse_ebook_formats(formatsStr):
|
||||
'''
|
||||
Creates a list with displayable names of the formats
|
||||
|
||||
:param formatsStr: string with comma separated book formats
|
||||
|
||||
:param formatsStr: string with comma separated book formats
|
||||
as it provided by ozon.ru
|
||||
:return: a list with displayable book formats
|
||||
'''
|
||||
|
||||
|
||||
formatsUnstruct = formatsStr.lower()
|
||||
formats = []
|
||||
if 'epub' in formatsUnstruct:
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -14,7 +15,7 @@ class PragmaticBookshelfStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
|
||||
open_search_url = 'http://pragprog.com/catalog/search-description'
|
||||
web_url = 'http://pragprog.com/'
|
||||
|
||||
|
||||
# http://pragprog.com/catalog.opds
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2012, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
@ -73,5 +74,5 @@ class RW2010Store(BasicStoreConfig, StorePlugin):
|
||||
s.detail_item = re.sub(r'%3D', '=', id)
|
||||
s.drm = SearchResult.DRM_UNLOCKED
|
||||
s.formats = formats[0:-2].upper()
|
||||
|
||||
|
||||
yield s
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -36,7 +37,7 @@ class SmashwordsStore(BasicStoreConfig, StorePlugin):
|
||||
if detail_item:
|
||||
detail_url = url + detail_item + aff_id
|
||||
url = url + aff_id
|
||||
|
||||
|
||||
if external or self.config.get('open_external', False):
|
||||
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else url)))
|
||||
else:
|
||||
@ -47,9 +48,9 @@ class SmashwordsStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
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())
|
||||
@ -57,7 +58,7 @@ class SmashwordsStore(BasicStoreConfig, StorePlugin):
|
||||
if counter <= 0:
|
||||
break
|
||||
data = html.fromstring(html.tostring(data))
|
||||
|
||||
|
||||
id = None
|
||||
id_a = data.xpath('//a[@class="bookTitle"]')
|
||||
if id_a:
|
||||
@ -66,14 +67,14 @@ class SmashwordsStore(BasicStoreConfig, StorePlugin):
|
||||
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[1]//text()'))
|
||||
@ -85,7 +86,7 @@ class SmashwordsStore(BasicStoreConfig, StorePlugin):
|
||||
price = '$0.00'
|
||||
|
||||
counter -= 1
|
||||
|
||||
|
||||
s = SearchResult()
|
||||
s.cover_url = cover_url
|
||||
s.title = title.strip()
|
||||
@ -93,12 +94,12 @@ class SmashwordsStore(BasicStoreConfig, StorePlugin):
|
||||
s.price = price.strip()
|
||||
s.detail_item = '/books/view/' + id.strip()
|
||||
s.drm = SearchResult.DRM_UNLOCKED
|
||||
|
||||
|
||||
yield s
|
||||
|
||||
def get_details(self, search_result, timeout):
|
||||
url = 'http://www.smashwords.com/'
|
||||
|
||||
|
||||
br = browser()
|
||||
with closing(br.open(url + search_result.detail_item, timeout=timeout)) as nf:
|
||||
idata = html.fromstring(nf.read())
|
||||
|
@ -2,6 +2,7 @@
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -35,9 +36,9 @@ class WeightlessBooksStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
url = 'http://weightlessbooks.com/?s=' + urllib.quote_plus(query)
|
||||
|
||||
|
||||
br = browser()
|
||||
|
||||
|
||||
counter = max_results
|
||||
with closing(br.open(url, timeout=timeout)) as f:
|
||||
doc = html.fromstring(f.read())
|
||||
@ -50,20 +51,20 @@ class WeightlessBooksStore(BasicStoreConfig, StorePlugin):
|
||||
continue
|
||||
|
||||
cover_url = ''.join(data.xpath('.//div[@class="cover"]/a/img/@src'))
|
||||
|
||||
|
||||
price = ''.join(data.xpath('.//div[@class="buy_buttons"]/b[1]/text()'))
|
||||
if not price:
|
||||
continue
|
||||
|
||||
|
||||
formats = ', '.join(data.xpath('.//select[@class="eStore_variation"]//option//text()'))
|
||||
formats = formats.upper()
|
||||
|
||||
|
||||
title = ''.join(data.xpath('.//h3/a/text()'))
|
||||
author = ''.join(data.xpath('.//h3//text()'))
|
||||
author = author.replace(title, '')
|
||||
|
||||
counter -= 1
|
||||
|
||||
|
||||
s = SearchResult()
|
||||
s.cover_url = cover_url
|
||||
s.title = title.strip()
|
||||
@ -72,5 +73,5 @@ class WeightlessBooksStore(BasicStoreConfig, StorePlugin):
|
||||
s.detail_item = id.strip()
|
||||
s.drm = SearchResult.DRM_UNLOCKED
|
||||
s.formats = formats
|
||||
|
||||
|
||||
yield s
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011-2012, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
@ -20,25 +21,25 @@ class XinXiiStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
|
||||
open_search_url = 'http://www.xinxii.com/catalog-search/'
|
||||
web_url = 'http://xinxii.com/'
|
||||
|
||||
|
||||
# http://www.xinxii.com/catalog/
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
'''
|
||||
XinXii's open search url is:
|
||||
http://www.xinxii.com/catalog-search/query/?keywords={searchTerms}&pw={startPage?}&doc_lang={docLang}&ff={docFormat},{docFormat},{docFormat}
|
||||
|
||||
|
||||
This url requires the docLang and docFormat. However, the search itself
|
||||
sent to XinXii does not require them. They can be ignored. We cannot
|
||||
push this into the stanard OpenSearchOPDSStore search because of the
|
||||
required attributes.
|
||||
|
||||
|
||||
XinXii doesn't return all info supported by OpenSearchOPDSStore search
|
||||
function so this one is modified to remove parts that are used.
|
||||
'''
|
||||
|
||||
|
||||
url = 'http://www.xinxii.com/catalog-search/query/?keywords=' + urllib.quote_plus(query)
|
||||
|
||||
|
||||
counter = max_results
|
||||
br = browser()
|
||||
with closing(br.open(url, timeout=timeout)) as f:
|
||||
@ -46,29 +47,29 @@ class XinXiiStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
for data in doc.xpath('//*[local-name() = "entry"]'):
|
||||
if counter <= 0:
|
||||
break
|
||||
|
||||
|
||||
counter -= 1
|
||||
|
||||
|
||||
s = SearchResult()
|
||||
|
||||
|
||||
s.detail_item = ''.join(data.xpath('./*[local-name() = "id"]/text()')).strip()
|
||||
|
||||
for link in data.xpath('./*[local-name() = "link"]'):
|
||||
rel = link.get('rel')
|
||||
href = link.get('href')
|
||||
type = link.get('type')
|
||||
|
||||
|
||||
if rel and href and type:
|
||||
if rel in ('http://opds-spec.org/thumbnail', 'http://opds-spec.org/image/thumbnail'):
|
||||
s.cover_url = href
|
||||
if rel == 'alternate':
|
||||
s.detail_item = href
|
||||
|
||||
|
||||
s.formats = 'EPUB, PDF'
|
||||
|
||||
|
||||
s.title = ' '.join(data.xpath('./*[local-name() = "title"]//text()')).strip()
|
||||
s.author = ', '.join(data.xpath('./*[local-name() = "author"]//*[local-name() = "name"]//text()')).strip()
|
||||
|
||||
|
||||
price_e = data.xpath('.//*[local-name() = "price"][1]')
|
||||
if price_e:
|
||||
price_e = price_e[0]
|
||||
@ -76,6 +77,6 @@ class XinXiiStore(BasicStoreConfig, OpenSearchOPDSStore):
|
||||
price = ''.join(price_e.xpath('.//text()')).strip()
|
||||
s.price = currency_code + ' ' + price
|
||||
s.price = s.price.strip()
|
||||
|
||||
|
||||
|
||||
yield s
|
||||
|
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
store_version = 1 # Needed for dynamic plugin loading
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2011, Tomasz Długosz <tomek3d@gmail.com>'
|
||||
|
Loading…
x
Reference in New Issue
Block a user