mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Store: Get DRM status for all stores. Load extra details in a separate thread. delay loading covers where the cover url is gotten via extra details.
This commit is contained in:
parent
08b8ef818c
commit
2390a90e7b
@ -104,7 +104,7 @@ class StorePlugin(object): # {{{
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_details(self, search_result, timeout=60):
|
||||
raise NotImplementedError()
|
||||
pass
|
||||
|
||||
def get_settings(self):
|
||||
'''
|
||||
|
@ -85,6 +85,6 @@ class BaenWebScriptionStore(BasicStoreConfig, StorePlugin):
|
||||
s.author = author.strip()
|
||||
s.price = price
|
||||
s.detail_item = id.strip()
|
||||
s.drm = False
|
||||
s.drm = SearchResult.DRM_UNLOCKED
|
||||
|
||||
yield s
|
||||
|
@ -60,14 +60,6 @@ class BeWriteStore(BasicStoreConfig, StorePlugin):
|
||||
cover_url = ''
|
||||
price = ''
|
||||
|
||||
with closing(br.open(id.strip(), timeout=timeout/4)) as nf:
|
||||
idata = html.fromstring(nf.read())
|
||||
price = ''.join(idata.xpath('//div[@id="content"]//td[contains(text(), "ePub")]/text()'))
|
||||
price = '$' + price.split('$')[-1]
|
||||
cover_img = idata.xpath('//div[@id="content"]//img[1]/@src')
|
||||
if cover_img:
|
||||
cover_url = 'http://www.bewrite.net/mm5/' + cover_img[0]
|
||||
|
||||
counter -= 1
|
||||
|
||||
s = SearchResult()
|
||||
@ -76,6 +68,19 @@ class BeWriteStore(BasicStoreConfig, StorePlugin):
|
||||
s.author = author.strip()
|
||||
s.price = price.strip()
|
||||
s.detail_item = id.strip()
|
||||
s.drm = False
|
||||
s.drm = SearchResult.DRM_UNLOCKED
|
||||
|
||||
yield s
|
||||
|
||||
def get_details(self, search_result, timeout):
|
||||
br = browser()
|
||||
|
||||
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()'))
|
||||
price = '$' + price.split('$')[-1]
|
||||
search_result.price = price.strip()
|
||||
cover_img = idata.xpath('//div[@id="content"]//img[1]/@src')
|
||||
if cover_img:
|
||||
cover_url = 'http://www.bewrite.net/mm5/' + cover_img[0]
|
||||
search_result.cover_url = cover_url.strip()
|
||||
|
@ -78,5 +78,6 @@ class BNStore(BasicStoreConfig, StorePlugin):
|
||||
s.author = author.strip()
|
||||
s.price = price
|
||||
s.detail_item = id.strip()
|
||||
s.drm = SearchResult.DRM_UNKNOWN
|
||||
|
||||
yield s
|
||||
|
@ -75,13 +75,6 @@ class DieselEbooksStore(BasicStoreConfig, StorePlugin):
|
||||
if price_elem:
|
||||
price = price_elem[0]
|
||||
|
||||
with closing(br.open('http://www.diesel-ebooks.com/item/' + id.strip(), timeout=timeout/4)) as nf:
|
||||
idata = html.fromstring(nf.read())
|
||||
if idata.xpath('boolean(//table[@class="format-info"]//tr[contains(th, "DRM") and contains(td, "No")])'):
|
||||
drm = False
|
||||
else:
|
||||
drm = True
|
||||
|
||||
counter -= 1
|
||||
|
||||
s = SearchResult()
|
||||
@ -90,6 +83,16 @@ class DieselEbooksStore(BasicStoreConfig, StorePlugin):
|
||||
s.author = author.strip()
|
||||
s.price = price.strip()
|
||||
s.detail_item = '/item/' + id.strip()
|
||||
s.drm = drm
|
||||
|
||||
yield s
|
||||
|
||||
def get_details(self, search_result, timeout):
|
||||
url = 'http://www.diesel-ebooks.com/item/'
|
||||
|
||||
br = browser()
|
||||
with closing(br.open(url + search_result.detail_item, timeout=timeout)) as nf:
|
||||
idata = html.fromstring(nf.read())
|
||||
if idata.xpath('boolean(//table[@class="format-info"]//tr[contains(th, "DRM") and contains(td, "No")])'):
|
||||
search_result.drm = SearchResult.DRM_UNLOCKED
|
||||
else:
|
||||
search_result.drm = SearchResult.DRM_LOCKED
|
||||
|
@ -7,6 +7,7 @@ __copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import random
|
||||
import re
|
||||
import urllib2
|
||||
from contextlib import closing
|
||||
|
||||
@ -64,20 +65,6 @@ class EbookscomStore(BasicStoreConfig, StorePlugin):
|
||||
if not id:
|
||||
continue
|
||||
|
||||
price = ''
|
||||
with closing(br.open('http://www.ebooks.com/ebooks/book_display.asp?IID=' + id.strip(), timeout=timeout)) as fp:
|
||||
pdoc = html.fromstring(fp.read())
|
||||
pdata = pdoc.xpath('//table[@class="price"]/tr/td/text()')
|
||||
if len(pdata) >= 2:
|
||||
price = pdata[1]
|
||||
drm = False
|
||||
for sec in ('Printing', 'Copying', 'Lending'):
|
||||
if pdoc.xpath('boolean(//div[@class="formatTableInner"]//table//tr[contains(th, "%s") and contains(td, "Off")])' % sec):
|
||||
drm = True
|
||||
break
|
||||
if not price:
|
||||
continue
|
||||
|
||||
cover_url = ''.join(data.xpath('.//img[1]/@src'))
|
||||
|
||||
title = ''
|
||||
@ -94,8 +81,29 @@ class EbookscomStore(BasicStoreConfig, StorePlugin):
|
||||
s.cover_url = cover_url
|
||||
s.title = title.strip()
|
||||
s.author = author.strip()
|
||||
s.price = price.strip()
|
||||
s.detail_item = '?url=http://www.ebooks.com/cj.asp?IID=' + id.strip() + '&cjsku=' + id.strip()
|
||||
s.drm = drm
|
||||
|
||||
yield s
|
||||
|
||||
def get_details(self, search_result, timeout):
|
||||
url = 'http://www.ebooks.com/ebooks/book_display.asp?IID='
|
||||
|
||||
mo = re.search(r'\?IID=(?P<id>\d+)', search_result.detail_item)
|
||||
if mo:
|
||||
id = mo.group('id')
|
||||
if not id:
|
||||
return
|
||||
|
||||
price = _('Not Available')
|
||||
br = browser()
|
||||
with closing(br.open(url + id, timeout=timeout)) as nf:
|
||||
pdoc = html.fromstring(nf.read())
|
||||
pdata = pdoc.xpath('//table[@class="price"]/tr/td/text()')
|
||||
if len(pdata) >= 2:
|
||||
price = pdata[1]
|
||||
search_result.drm = SearchResult.DRM_UNLOCKED
|
||||
for sec in ('Printing', 'Copying', 'Lending'):
|
||||
if pdoc.xpath('boolean(//div[@class="formatTableInner"]//table//tr[contains(th, "%s") and contains(td, "Off")])' % sec):
|
||||
search_result.drm = SearchResult.DRM_LOCKED
|
||||
break
|
||||
search_result.price = price.strip()
|
||||
|
@ -7,6 +7,7 @@ __copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import random
|
||||
import re
|
||||
import urllib2
|
||||
from contextlib import closing
|
||||
|
||||
@ -68,12 +69,6 @@ class EHarlequinStore(BasicStoreConfig, StorePlugin):
|
||||
price = ''.join(data.xpath('.//div[@class="ourprice"]/font/text()'))
|
||||
cover_url = ''.join(data.xpath('.//a[@href="%s"]/img/@src' % id))
|
||||
|
||||
with closing(br.open('http://ebooks.eharlequin.com/' + id.strip(), timeout=timeout/4)) as nf:
|
||||
idata = html.fromstring(nf.read())
|
||||
drm = None
|
||||
if idata.xpath('boolean(//div[@class="drm_head"])'):
|
||||
drm = idata.xpath('boolean(//td[contains(., "Copy") and contains(., "not")])')
|
||||
|
||||
counter -= 1
|
||||
|
||||
s = SearchResult()
|
||||
@ -82,6 +77,26 @@ class EHarlequinStore(BasicStoreConfig, StorePlugin):
|
||||
s.author = author.strip()
|
||||
s.price = price.strip()
|
||||
s.detail_item = '?url=http://ebooks.eharlequin.com/' + id.strip()
|
||||
s.drm = drm
|
||||
|
||||
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())
|
||||
drm = SearchResult.DRM_UNKNOWN
|
||||
if idata.xpath('boolean(//div[@class="drm_head"])'):
|
||||
if idata.xpath('boolean(//td[contains(., "Copy") and contains(., "not")])'):
|
||||
drm = SearchResult.DRM_LOCKED
|
||||
else:
|
||||
drm = SearchResult.DRM_UNLOCKED
|
||||
search_result.drm = drm
|
||||
|
@ -90,3 +90,14 @@ class FeedbooksStore(BasicStoreConfig, StorePlugin):
|
||||
s.detail_item = id.strip()
|
||||
|
||||
yield s
|
||||
|
||||
def get_details(self, search_result, timeout):
|
||||
url = 'http://m.feedbooks.com/'
|
||||
|
||||
br = browser()
|
||||
with closing(br.open(url_slash_cleaner(url + search_result.detail_item), timeout=timeout)) as nf:
|
||||
idata = html.fromstring(nf.read())
|
||||
if idata.xpath('boolean(//div[contains(@class, "m-description-long")]//p[contains(., "DRM") or contains(b, "Protection")])'):
|
||||
search_result.drm = SearchResult.DRM_LOCKED
|
||||
else:
|
||||
search_result.drm = SearchResult.DRM_UNLOCKED
|
||||
|
@ -79,6 +79,6 @@ class GutenbergStore(BasicStoreConfig, StorePlugin):
|
||||
s.author = author.strip()
|
||||
s.price = price.strip()
|
||||
s.detail_item = '/ebooks/' + id.strip()
|
||||
s.drm = False
|
||||
s.drm = SearchResult.DRM_UNLOCKED
|
||||
|
||||
yield s
|
||||
|
@ -63,7 +63,7 @@ class KoboStore(BasicStoreConfig, StorePlugin):
|
||||
if not id:
|
||||
continue
|
||||
|
||||
price = ''.join(data.xpath('.//span[@class="SCOurPrice"]/strong/text()'))
|
||||
price = ''.join(data.xpath('.//li[@class="OurPrice"]/strong/text()'))
|
||||
if not price:
|
||||
price = '$0.00'
|
||||
|
||||
@ -71,6 +71,7 @@ class KoboStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
title = ''.join(data.xpath('.//div[@class="SCItemHeader"]/h1/a[1]/text()'))
|
||||
author = ''.join(data.xpath('.//div[@class="SCItemSummary"]/span/a[1]/text()'))
|
||||
drm = data.xpath('boolean(.//span[@class="SCAvailibilityFormatsText" and contains(text(), "DRM")])')
|
||||
|
||||
counter -= 1
|
||||
|
||||
@ -80,5 +81,6 @@ class KoboStore(BasicStoreConfig, StorePlugin):
|
||||
s.author = author.strip()
|
||||
s.price = price.strip()
|
||||
s.detail_item = '?url=http://www.kobobooks.com/' + id.strip()
|
||||
s.drm = SearchResult.DRM_LOCKED if drm else SearchResult.DRM_UNLOCKED
|
||||
|
||||
yield s
|
||||
|
@ -89,6 +89,6 @@ class ManyBooksStore(BasicStoreConfig, StorePlugin):
|
||||
s.author = author.strip()
|
||||
s.price = price.strip()
|
||||
s.detail_item = '/titles/' + id
|
||||
s.drm = False
|
||||
s.drm = SearchResult.DRM_UNLOCKED
|
||||
|
||||
yield s
|
||||
|
@ -76,7 +76,7 @@ class MobileReadStore(BasicStoreConfig, StorePlugin):
|
||||
matches = heapq.nlargest(max_results, matches)
|
||||
for score, book in matches:
|
||||
book.price = '$0.00'
|
||||
book.drm = False
|
||||
book.drm = SearchResult.DRM_UNLOCKED
|
||||
yield book
|
||||
|
||||
def update_book_list(self, timeout=10):
|
||||
|
@ -68,5 +68,6 @@ class OpenLibraryStore(BasicStoreConfig, StorePlugin):
|
||||
s.author = author.strip()
|
||||
s.price = price
|
||||
s.detail_item = id.strip()
|
||||
s.drm = SearchResult.DRM_UNKNOWN
|
||||
|
||||
yield s
|
||||
|
@ -415,9 +415,10 @@ class DetailsThread(Thread):
|
||||
result, store_plugin, callback, timeout = self.tasks.get()
|
||||
if result:
|
||||
store_plugin.get_details(result, timeout)
|
||||
callback()
|
||||
callback(result)
|
||||
self.tasks.task_done()
|
||||
except:
|
||||
traceback.print_exc()
|
||||
continue
|
||||
|
||||
class Matches(QAbstractItemModel):
|
||||
@ -464,8 +465,12 @@ class Matches(QAbstractItemModel):
|
||||
self.layoutAboutToBeChanged.emit()
|
||||
self.all_matches.append(result)
|
||||
self.search_filter.add_search_result(result)
|
||||
self.cover_pool.add_task(result, self.filter_results)
|
||||
self.details_pool.add_task(result, store_plugin, self.filter_results)
|
||||
if result.cover_url:
|
||||
result.cover_queued = True
|
||||
self.cover_pool.add_task(result, self.filter_results)
|
||||
else:
|
||||
result.cover_queued = False
|
||||
self.details_pool.add_task(result, store_plugin, self.got_result_details)
|
||||
self.filter_results()
|
||||
self.layoutChanged.emit()
|
||||
|
||||
@ -485,6 +490,15 @@ class Matches(QAbstractItemModel):
|
||||
self.reorder_matches()
|
||||
self.layoutChanged.emit()
|
||||
|
||||
def got_result_details(self, result):
|
||||
if not result.cover_queued and result.cover_url:
|
||||
result.cover_queued = True
|
||||
self.cover_pool.add_task(result, self.filter_results)
|
||||
if result in self.matches:
|
||||
row = self.matches.index(result)
|
||||
self.dataChanged.emit(self.index(row, 0), self.index(row, self.columnCount() - 1))
|
||||
self.filter_results()
|
||||
|
||||
def set_query(self, query):
|
||||
self.query = query
|
||||
|
||||
|
@ -90,5 +90,6 @@ class SmashwordsStore(BasicStoreConfig, StorePlugin):
|
||||
s.author = author.strip()
|
||||
s.price = price.strip()
|
||||
s.detail_item = '/books/view/' + id.strip()
|
||||
s.drm = SearchResult.DRM_UNLOCKED
|
||||
|
||||
yield s
|
||||
|
Loading…
x
Reference in New Issue
Block a user