Get Books: Fix #799367 (Could not download ebooks from store). Fixes to Legimi and Beam-ebooks.de. Add libri.de as a source

This commit is contained in:
Kovid Goyal 2011-06-20 17:22:17 -06:00
commit f5c01a26fe
7 changed files with 116 additions and 10 deletions

View File

@ -578,6 +578,7 @@ def url_slash_cleaner(url):
def get_download_filename(url, cookie_file=None): def get_download_filename(url, cookie_file=None):
''' '''
Get a local filename for a URL using the content disposition header Get a local filename for a URL using the content disposition header
Returns empty string if no content disposition header present
''' '''
from contextlib import closing from contextlib import closing
from urllib2 import unquote as urllib2_unquote from urllib2 import unquote as urllib2_unquote
@ -591,8 +592,10 @@ def get_download_filename(url, cookie_file=None):
cj.load(cookie_file) cj.load(cookie_file)
br.set_cookiejar(cj) br.set_cookiejar(cj)
last_part_name = ''
try: try:
with closing(br.open(url)) as r: with closing(br.open(url)) as r:
last_part_name = r.geturl().split('/')[-1]
disposition = r.info().get('Content-disposition', '') disposition = r.info().get('Content-disposition', '')
for p in disposition.split(';'): for p in disposition.split(';'):
if 'filename' in p: if 'filename' in p:
@ -612,7 +615,7 @@ def get_download_filename(url, cookie_file=None):
traceback.print_exc() traceback.print_exc()
if not filename: if not filename:
filename = r.geturl().split('/')[-1] filename = last_part_name
return filename return filename

View File

@ -1335,6 +1335,16 @@ class StoreLegimiStore(StoreBase):
headquarters = 'PL' headquarters = 'PL'
formats = ['EPUB'] formats = ['EPUB']
class StoreLibreDEStore(StoreBase):
name = 'Libri DE'
author = 'Charles Haley'
description = u'Sicher Bücher, Hörbücher und Downloads online bestellen.'
actual_plugin = 'calibre.gui2.store.libri_de_plugin:LibreDEStore'
headquarters = 'DE'
formats = ['EPUB', 'PDF']
affiliate = True
class StoreManyBooksStore(StoreBase): class StoreManyBooksStore(StoreBase):
name = 'ManyBooks' name = 'ManyBooks'
description = u'Public domain and creative commons works from many sources.' description = u'Public domain and creative commons works from many sources.'
@ -1485,6 +1495,7 @@ plugins += [
StoreGutenbergStore, StoreGutenbergStore,
StoreKoboStore, StoreKoboStore,
StoreLegimiStore, StoreLegimiStore,
StoreLibreDEStore,
StoreManyBooksStore, StoreManyBooksStore,
StoreMobileReadStore, StoreMobileReadStore,
StoreNextoStore, StoreNextoStore,

View File

@ -51,19 +51,19 @@ class BeamEBooksDEStore(BasicStoreConfig, StorePlugin):
if counter <= 0: if counter <= 0:
break break
id = ''.join(data.xpath('./tr/td/div[@class="stil2"]/a/@href')).strip() id = ''.join(data.xpath('./tr/td[1]/a/@href')).strip()
if not id: if not id:
continue continue
id = id[7:] id = id[7:]
cover_url = ''.join(data.xpath('./tr/td[1]/a/img/@src')) cover_url = ''.join(data.xpath('./tr/td[1]/a/img/@src'))
if cover_url: if cover_url:
cover_url = 'http://www.beam-ebooks.de' + cover_url cover_url = 'http://www.beam-ebooks.de' + cover_url
title = ''.join(data.xpath('./tr/td/div[@class="stil2"]/a/b/text()')) temp = ''.join(data.xpath('./tr/td[1]/a/img/@alt'))
author = ' '.join(data.xpath('./tr/td/div[@class="stil2"]/' colon = temp.find(':')
'child::b/text()' if not temp.startswith('eBook') or colon < 0:
'|' continue
'./tr/td/div[@class="stil2"]/' author = temp[5:colon]
'child::strong/text()')) title = temp[colon+1:]
price = ''.join(data.xpath('./tr/td[3]/text()')) price = ''.join(data.xpath('./tr/td[3]/text()'))
pdf = data.xpath( pdf = data.xpath(
'boolean(./tr/td[3]/a/img[contains(@alt, "PDF")]/@alt)') 'boolean(./tr/td[3]/a/img[contains(@alt, "PDF")]/@alt)')

View File

@ -58,6 +58,8 @@ class LegimiStore(BasicStoreConfig, StorePlugin):
cover_url = ''.join(data.xpath('.//div[@class="item_cover_container"]/a/img/@src')) cover_url = ''.join(data.xpath('.//div[@class="item_cover_container"]/a/img/@src'))
title = ''.join(data.xpath('.//div[@class="item_entries"]/h2/a/text()')) title = ''.join(data.xpath('.//div[@class="item_entries"]/h2/a/text()'))
author = ''.join(data.xpath('.//div[@class="item_entries"]/span[1]/a/text()')) author = ''.join(data.xpath('.//div[@class="item_entries"]/span[1]/a/text()'))
author = re.sub(',','',author)
author = re.sub(';',',',author)
price = ''.join(data.xpath('.//div[@class="item_entries"]/span[3]/text()')) price = ''.join(data.xpath('.//div[@class="item_entries"]/span[3]/text()'))
price = re.sub(r'[^0-9,]*','',price) + '' price = re.sub(r'[^0-9,]*','',price) + ''

View File

@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
from __future__ import (unicode_literals, division, absolute_import, print_function)
__license__ = 'GPL 3'
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
__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 LibreDEStore(BasicStoreConfig, StorePlugin):
def open(self, parent=None, detail_item=None, external=False):
url = 'http://ad.zanox.com/ppc/?18817073C15644254T'
url_details = ('http://ad.zanox.com/ppc/?18845780C1371495675T&ULP=[['
'http://www.libri.de/shop/action/productDetails?artiId={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.libri.de/shop/action/quickSearch?facetNodeId=6'
'&mainsearchSubmit=Los!&searchString=' + 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, "item")]'):
if counter <= 0:
break
details = data.xpath('./div[@class="beschreibungContainer"]')
if not details:
continue
details = details[0]
id = ''.join(details.xpath('./div[@class="text"]/a/@name')).strip()
if not id:
continue
cover_url = ''.join(details.xpath('./div[@class="bild"]/a/img/@src'))
title = ''.join(details.xpath('./div[@class="text"]/span[@class="titel"]/a/text()')).strip()
author = ''.join(details.xpath('./div[@class="text"]/span[@class="author"]/text()')).strip()
pdf = details.xpath(
'boolean(.//span[@class="format" and contains(text(), "pdf")]/text())')
epub = details.xpath(
'boolean(.//span[@class="format" and contains(text(), "epub")]/text())')
mobi = details.xpath(
'boolean(.//span[@class="format" and contains(text(), "mobipocket")]/text())')
price = (''.join(data.xpath('.//span[@class="preis"]/text()'))).replace('*', '')
counter -= 1
s = SearchResult()
s.cover_url = cover_url
s.title = title.strip()
s.author = author.strip()
s.price = price
s.drm = SearchResult.DRM_UNKNOWN
s.detail_item = id
formats = []
if epub:
formats.append('ePub')
if pdf:
formats.append('PDF')
if mobi:
formats.append('MOBI')
s.formats = ', '.join(formats)
yield s

View File

@ -57,7 +57,7 @@ class WoblinkStore(BasicStoreConfig, StorePlugin):
cover_url = ''.join(data.xpath('.//td[@class="w10 va-t"]/a[1]/img/@src')) cover_url = ''.join(data.xpath('.//td[@class="w10 va-t"]/a[1]/img/@src'))
title = ''.join(data.xpath('.//h3[@class="title"]/a[1]/text()')) title = ''.join(data.xpath('.//h3[@class="title"]/a[1]/text()'))
author = ''.join(data.xpath('.//p[@class="author"]/a[1]/text()')) author = ', '.join(data.xpath('.//p[@class="author"]/a/text()'))
price = ''.join(data.xpath('.//div[@class="prices"]/p[1]/span/text()')) price = ''.join(data.xpath('.//div[@class="prices"]/p[1]/span/text()'))
price = re.sub('PLN', '', price) price = re.sub('PLN', '', price)
price = re.sub('\.', ',', price) price = re.sub('\.', ',', price)

View File

@ -53,7 +53,7 @@ class ZixoStore(BasicStoreConfig, StorePlugin):
cover_url = ''.join(data.xpath('.//a[@class="productThumb"]/img/@src')) cover_url = ''.join(data.xpath('.//a[@class="productThumb"]/img/@src'))
title = ''.join(data.xpath('.//a[@class="title"]/text()')) title = ''.join(data.xpath('.//a[@class="title"]/text()'))
author = ''.join(data.xpath('.//div[@class="productDescription"]/span[1]/a/text()')) author = ','.join(data.xpath('.//div[@class="productDescription"]/span[1]/a/text()'))
price = ''.join(data.xpath('.//div[@class="priceList"]/span/text()')) price = ''.join(data.xpath('.//div[@class="priceList"]/span/text()'))
price = re.sub('\.', ',', price) price = re.sub('\.', ',', price)