mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
KG updates
This commit is contained in:
commit
d16b92d501
BIN
recipes/icons/replicavedetelor.png
Normal file
BIN
recipes/icons/replicavedetelor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 709 B |
53
recipes/replicavedetelor.recipe
Normal file
53
recipes/replicavedetelor.recipe
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = u'2011, '
|
||||||
|
'''
|
||||||
|
replicavedetelor.ro
|
||||||
|
'''
|
||||||
|
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class ReplicaVedetelor(BasicNewsRecipe):
|
||||||
|
title = u'Replica Vedetelor'
|
||||||
|
__author__ = u'Silviu Cotoara'
|
||||||
|
description = u'Ofer\u0103 vedetelor dreptul la replic\u0103'
|
||||||
|
publisher = 'Replica Vedetelor'
|
||||||
|
oldest_article = 5
|
||||||
|
language = 'ro'
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
no_stylesheets = True
|
||||||
|
use_embedded_content = False
|
||||||
|
category = 'Ziare,Reviste,Vedete'
|
||||||
|
encoding = 'utf-8'
|
||||||
|
cover_url = 'http://www.webart-software.eu/_pics/lucrari_referinta/medium/84/1-Replica-Vedetelor.jpg'
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comments' : description
|
||||||
|
,'tags' : category
|
||||||
|
,'language' : language
|
||||||
|
,'publisher' : publisher
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'id':'zona-continut'})
|
||||||
|
]
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict(name='ul', attrs={'id':['lista-imagini']})
|
||||||
|
, dict(name='form', attrs={'id':['f-trimite-unui-prieten']})
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
remove_tags_after = [
|
||||||
|
dict(name='form', attrs={'id':['f-trimite-unui-prieten']})
|
||||||
|
]
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
(u'Feeds', u'http://www.replicavedetelor.ro/feed')
|
||||||
|
]
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
return self.adeify_images(soup)
|
||||||
|
|
20
recipes/welt_der_physik.recipe
Normal file
20
recipes/welt_der_physik.recipe
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class AdvancedUserRecipe1303841067(BasicNewsRecipe):
|
||||||
|
|
||||||
|
title = u'Welt der Physik'
|
||||||
|
__author__ = 'schuster'
|
||||||
|
remove_tags_befor = [dict(name='div', attrs={'class':'inhalt_bild_text_printonly'})]
|
||||||
|
remove_tags_after = [dict(name='span', attrs={'class':'clearinhalt_bild'})]
|
||||||
|
remove_tags = [dict(attrs={'class':['invisible', 'searchfld', 'searchbtn', 'topnavi', 'topsearch']}),
|
||||||
|
dict(id=['naservice', 'phservicemenu', '',]),
|
||||||
|
dict(name=['naservice'])]
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
no_stylesheets = True
|
||||||
|
use_embedded_content = False
|
||||||
|
language = 'de'
|
||||||
|
remove_javascript = True
|
||||||
|
|
||||||
|
|
||||||
|
feeds = [(u'Nachrichten und Neuigkeiten', u'http://www.weltderphysik.de/rss/alles.xml')]
|
@ -1096,6 +1096,11 @@ class StoreAmazonKindleStore(StoreBase):
|
|||||||
description = _('Kindle books from Amazon')
|
description = _('Kindle books from Amazon')
|
||||||
actual_plugin = 'calibre.gui2.store.amazon_plugin:AmazonKindleStore'
|
actual_plugin = 'calibre.gui2.store.amazon_plugin:AmazonKindleStore'
|
||||||
|
|
||||||
|
class StoreAmazonDEKindleStore(StoreBase):
|
||||||
|
name = 'Amazon DE Kindle'
|
||||||
|
description = _('Kindle eBooks')
|
||||||
|
actual_plugin = 'calibre.gui2.store.amazon_de_plugin:AmazonDEKindleStore'
|
||||||
|
|
||||||
class StoreAmazonUKKindleStore(StoreBase):
|
class StoreAmazonUKKindleStore(StoreBase):
|
||||||
name = 'Amazon UK Kindle'
|
name = 'Amazon UK Kindle'
|
||||||
description = _('Kindle books from Amazon.uk')
|
description = _('Kindle books from Amazon.uk')
|
||||||
@ -1111,6 +1116,11 @@ class StoreBNStore(StoreBase):
|
|||||||
description = _('Books, Textbooks, eBooks, Toys, Games and More.')
|
description = _('Books, Textbooks, eBooks, Toys, Games and More.')
|
||||||
actual_plugin = 'calibre.gui2.store.bn_plugin:BNStore'
|
actual_plugin = 'calibre.gui2.store.bn_plugin:BNStore'
|
||||||
|
|
||||||
|
class StoreBeamEBooksDEStore(StoreBase):
|
||||||
|
name = 'Beam EBooks DE'
|
||||||
|
description = _('der eBook Shop')
|
||||||
|
actual_plugin = 'calibre.gui2.store.beam_ebooks_de_plugin:BeamEBooksDEStore'
|
||||||
|
|
||||||
class StoreBeWriteStore(StoreBase):
|
class StoreBeWriteStore(StoreBase):
|
||||||
name = 'BeWrite Books'
|
name = 'BeWrite Books'
|
||||||
description = _('Publishers of fine books.')
|
description = _('Publishers of fine books.')
|
||||||
@ -1126,7 +1136,12 @@ class StoreEbookscomStore(StoreBase):
|
|||||||
description = _('The digital bookstore.')
|
description = _('The digital bookstore.')
|
||||||
actual_plugin = 'calibre.gui2.store.ebooks_com_plugin:EbookscomStore'
|
actual_plugin = 'calibre.gui2.store.ebooks_com_plugin:EbookscomStore'
|
||||||
|
|
||||||
class StoreEHarlequinStoretore(StoreBase):
|
class StoreEPubBuyDEStore(StoreBase):
|
||||||
|
name = 'EPUBBuy DE'
|
||||||
|
description = _('EPUBReaders eBook Shop')
|
||||||
|
actual_plugin = 'calibre.gui2.store.epubbuy_de_plugin:EPubBuyDEStore'
|
||||||
|
|
||||||
|
class StoreEHarlequinStore(StoreBase):
|
||||||
name = 'eHarlequin'
|
name = 'eHarlequin'
|
||||||
description = _('entertain, enrich, inspire.')
|
description = _('entertain, enrich, inspire.')
|
||||||
actual_plugin = 'calibre.gui2.store.eharlequin_plugin:EHarlequinStore'
|
actual_plugin = 'calibre.gui2.store.eharlequin_plugin:EHarlequinStore'
|
||||||
@ -1136,6 +1151,11 @@ class StoreFeedbooksStore(StoreBase):
|
|||||||
description = _('Read anywhere.')
|
description = _('Read anywhere.')
|
||||||
actual_plugin = 'calibre.gui2.store.feedbooks_plugin:FeedbooksStore'
|
actual_plugin = 'calibre.gui2.store.feedbooks_plugin:FeedbooksStore'
|
||||||
|
|
||||||
|
class StoreFoylesUKStore(StoreBase):
|
||||||
|
name = 'Foyles UK'
|
||||||
|
description = _('Foyles of London, online')
|
||||||
|
actual_plugin = 'calibre.gui2.store.foyles_uk_plugin:FoylesUKStore'
|
||||||
|
|
||||||
class StoreGutenbergStore(StoreBase):
|
class StoreGutenbergStore(StoreBase):
|
||||||
name = 'Project Gutenberg'
|
name = 'Project Gutenberg'
|
||||||
description = _('The first producer of free ebooks.')
|
description = _('The first producer of free ebooks.')
|
||||||
@ -1171,22 +1191,23 @@ class StoreWaterstonesUKStore(StoreBase):
|
|||||||
description = _('Feel every word')
|
description = _('Feel every word')
|
||||||
actual_plugin = 'calibre.gui2.store.waterstones_uk_plugin:WaterstonesUKStore'
|
actual_plugin = 'calibre.gui2.store.waterstones_uk_plugin:WaterstonesUKStore'
|
||||||
|
|
||||||
class StoreFoylesUKStore(StoreBase):
|
class StoreWeightlessBooksStore(StoreBase):
|
||||||
name = 'Foyles UK'
|
name = 'Weightless Books'
|
||||||
description = _('Foyles of London, online')
|
description = '(e)Books That Don\'t Weigh You Down'
|
||||||
actual_plugin = 'calibre.gui2.store.foyles_uk_plugin:FoylesUKStore'
|
actual_plugin = 'calibre.gui2.store.weightless_books_plugin:WeightlessBooksStore'
|
||||||
|
|
||||||
class AmazonDEKindleStore(StoreBase):
|
class StoreWizardsTowerBooksStore(StoreBase):
|
||||||
name = 'Amazon DE Kindle'
|
name = 'Wizards Tower Books'
|
||||||
description = _('Kindle eBooks')
|
description = 'Wizard\'s Tower Press'
|
||||||
actual_plugin = 'calibre.gui2.store.amazon_de_plugin:AmazonDEKindleStore'
|
actual_plugin = 'calibre.gui2.store.wizards_tower_books_plugin:WizardsTowerBooksStore'
|
||||||
|
|
||||||
plugins += [StoreAmazonKindleStore, AmazonDEKindleStore, StoreAmazonUKKindleStore,
|
plugins += [StoreAmazonKindleStore, StoreAmazonDEKindleStore, StoreAmazonUKKindleStore,
|
||||||
StoreBaenWebScriptionStore, StoreBNStore,
|
StoreBaenWebScriptionStore, StoreBNStore,
|
||||||
StoreBeWriteStore, StoreDieselEbooksStore, StoreEbookscomStore,
|
StoreBeamEBooksDEStore, StoreBeWriteStore,
|
||||||
StoreEHarlequinStoretore, StoreFeedbooksStore,
|
StoreDieselEbooksStore, StoreEbookscomStore, StoreEPubBuyDEStore,
|
||||||
|
StoreEHarlequinStore, StoreFeedbooksStore,
|
||||||
StoreFoylesUKStore, StoreGutenbergStore, StoreKoboStore, StoreManyBooksStore,
|
StoreFoylesUKStore, StoreGutenbergStore, StoreKoboStore, StoreManyBooksStore,
|
||||||
StoreMobileReadStore, StoreOpenLibraryStore, StoreSmashwordsStore,
|
StoreMobileReadStore, StoreOpenLibraryStore, StoreSmashwordsStore,
|
||||||
StoreWaterstonesUKStore]
|
StoreWaterstonesUKStore, StoreWeightlessBooksStore, StoreWizardsTowerBooksStore]
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -38,7 +38,7 @@ class KOBO(USBMS):
|
|||||||
|
|
||||||
VENDOR_ID = [0x2237]
|
VENDOR_ID = [0x2237]
|
||||||
PRODUCT_ID = [0x4161]
|
PRODUCT_ID = [0x4161]
|
||||||
BCD = [0x0110]
|
BCD = [0x0110, 0x0323]
|
||||||
|
|
||||||
VENDOR_NAME = ['KOBO_INC', 'KOBO']
|
VENDOR_NAME = ['KOBO_INC', 'KOBO']
|
||||||
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = ['.KOBOEREADER', 'EREADER']
|
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = ['.KOBOEREADER', 'EREADER']
|
||||||
|
@ -27,7 +27,7 @@ class StoreAction(InterfaceAction):
|
|||||||
self.store_menu.clear()
|
self.store_menu.clear()
|
||||||
self.store_menu.addAction(_('Search'), self.search)
|
self.store_menu.addAction(_('Search'), self.search)
|
||||||
self.store_menu.addSeparator()
|
self.store_menu.addSeparator()
|
||||||
for n, p in self.gui.istores.items():
|
for n, p in sorted(self.gui.istores.items(), key=lambda x: x[0].lower()):
|
||||||
self.store_menu.addAction(n, partial(self.open_store, p))
|
self.store_menu.addAction(n, partial(self.open_store, p))
|
||||||
self.qaction.setMenu(self.store_menu)
|
self.qaction.setMenu(self.store_menu)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
class StorePlugin(object): # {{{
|
class StorePlugin(object): # {{{
|
||||||
'''
|
'''
|
||||||
A plugin representing an online ebook repository (store). The store can
|
A plugin representing an online ebook repository (store). The store can
|
||||||
be a comercial store that sells ebooks or a source of free downloadable
|
be a commercial store that sells ebooks or a source of free downloadable
|
||||||
ebooks.
|
ebooks.
|
||||||
|
|
||||||
Note that this class is the base class for these plugins, however, to
|
Note that this class is the base class for these plugins, however, to
|
||||||
@ -43,6 +43,8 @@ class StorePlugin(object): # {{{
|
|||||||
The easiest way to handle affiliate money payouts is to randomly select
|
The easiest way to handle affiliate money payouts is to randomly select
|
||||||
between the author's affiliate id and calibre's affiliate id so that
|
between the author's affiliate id and calibre's affiliate id so that
|
||||||
70% of the time the author's id is used.
|
70% of the time the author's id is used.
|
||||||
|
|
||||||
|
See declined.txt for a list of stores that do not want to be included.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, gui, name):
|
def __init__(self, gui, name):
|
||||||
|
92
src/calibre/gui2/store/beam_ebooks_de_plugin.py
Normal file
92
src/calibre/gui2/store/beam_ebooks_de_plugin.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
# -*- 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 BeamEBooksDEStore(BasicStoreConfig, StorePlugin):
|
||||||
|
|
||||||
|
def open(self, parent=None, detail_item=None, external=False):
|
||||||
|
url = 'http://klick.affiliwelt.net/klick.php?bannerid=10072&pid=32307&prid=908'
|
||||||
|
url_details = ('http://klick.affiliwelt.net/klick.php?'
|
||||||
|
'bannerid=10730&pid=32307&prid=908&prodid={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.beam-ebooks.de/suchergebnis.php?Type=&sw=' + 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[tr/td/div[@class="stil2"]]'):
|
||||||
|
if counter <= 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
id = ''.join(data.xpath('./tr/td/div[@class="stil2"]/a/@href')).strip()
|
||||||
|
if not id:
|
||||||
|
continue
|
||||||
|
id = id[7:]
|
||||||
|
cover_url = ''.join(data.xpath('./tr/td[1]/a/img/@src'))
|
||||||
|
if cover_url:
|
||||||
|
cover_url = 'http://www.beam-ebooks.de' + cover_url
|
||||||
|
title = ''.join(data.xpath('./tr/td/div[@class="stil2"]/a/b/text()'))
|
||||||
|
author = ' '.join(data.xpath('./tr/td/div[@class="stil2"]/'
|
||||||
|
'child::b/text()'
|
||||||
|
'|'
|
||||||
|
'./tr/td/div[@class="stil2"]/'
|
||||||
|
'child::strong/text()'))
|
||||||
|
price = ''.join(data.xpath('./tr/td[3]/text()'))
|
||||||
|
pdf = data.xpath(
|
||||||
|
'boolean(./tr/td[3]/a/img[contains(@alt, "PDF")]/@alt)')
|
||||||
|
epub = data.xpath(
|
||||||
|
'boolean(./tr/td[3]/a/img[contains(@alt, "ePub")]/@alt)')
|
||||||
|
mobi = data.xpath(
|
||||||
|
'boolean(./tr/td[3]/a/img[contains(@alt, "Mobipocket")]/@alt)')
|
||||||
|
counter -= 1
|
||||||
|
|
||||||
|
s = SearchResult()
|
||||||
|
s.cover_url = cover_url
|
||||||
|
s.title = title.strip()
|
||||||
|
s.author = author.strip()
|
||||||
|
s.price = price
|
||||||
|
s.drm = SearchResult.DRM_UNLOCKED
|
||||||
|
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
|
5
src/calibre/gui2/store/declined.txt
Normal file
5
src/calibre/gui2/store/declined.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
This is a list of stores that objected, declined
|
||||||
|
or asked not to be included in the store integration.
|
||||||
|
|
||||||
|
* Borders (http://www.borders.com/)
|
||||||
|
* WH Smith (http://www.whsmith.co.uk/)
|
80
src/calibre/gui2/store/epubbuy_de_plugin.py
Normal file
80
src/calibre/gui2/store/epubbuy_de_plugin.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# -*- 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 EPubBuyDEStore(BasicStoreConfig, StorePlugin):
|
||||||
|
|
||||||
|
def open(self, parent=None, detail_item=None, external=False):
|
||||||
|
url = 'http://klick.affiliwelt.net/klick.php?bannerid=47653&pid=32307&prid=2627'
|
||||||
|
url_details = ('http://klick.affiliwelt.net/klick.php?bannerid=47653'
|
||||||
|
'&pid=32307&prid=2627&prodid={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.epubbuy.com/search.php?search_query=' + 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('//li[contains(@class, "ajax_block_product")]'):
|
||||||
|
if counter <= 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
id = ''.join(data.xpath('./div[@class="center_block"]'
|
||||||
|
'/p[contains(text(), "artnr:")]/text()')).strip()
|
||||||
|
if not id:
|
||||||
|
continue
|
||||||
|
id = id[6:].strip()
|
||||||
|
if not id:
|
||||||
|
continue
|
||||||
|
cover_url = ''.join(data.xpath('./div[@class="center_block"]'
|
||||||
|
'/a[@class="product_img_link"]/img/@src'))
|
||||||
|
if cover_url:
|
||||||
|
cover_url = 'http://www.epubbuy.com' + cover_url
|
||||||
|
title = ''.join(data.xpath('./div[@class="center_block"]'
|
||||||
|
'/a[@class="product_img_link"]/@title'))
|
||||||
|
author = ''.join(data.xpath('./div[@class="center_block"]/a[2]/text()'))
|
||||||
|
price = ''.join(data.xpath('.//span[@class="price"]/text()'))
|
||||||
|
counter -= 1
|
||||||
|
|
||||||
|
s = SearchResult()
|
||||||
|
s.cover_url = cover_url
|
||||||
|
s.title = title.strip()
|
||||||
|
s.author = author.strip()
|
||||||
|
s.price = price
|
||||||
|
s.drm = SearchResult.DRM_UNLOCKED
|
||||||
|
s.detail_item = id
|
||||||
|
s.formats = 'ePub'
|
||||||
|
|
||||||
|
yield s
|
@ -73,6 +73,6 @@ class FoylesUKStore(BasicStoreConfig, StorePlugin):
|
|||||||
s.price = price
|
s.price = price
|
||||||
s.detail_item = id
|
s.detail_item = id
|
||||||
s.drm = SearchResult.DRM_LOCKED
|
s.drm = SearchResult.DRM_LOCKED
|
||||||
s.formats = 'EPUB'
|
s.formats = 'ePub'
|
||||||
|
|
||||||
yield s
|
yield s
|
||||||
|
@ -47,7 +47,7 @@ class SearchDialog(QDialog, Ui_Dialog):
|
|||||||
# per search basis.
|
# per search basis.
|
||||||
stores_group_layout = QVBoxLayout()
|
stores_group_layout = QVBoxLayout()
|
||||||
self.stores_group.setLayout(stores_group_layout)
|
self.stores_group.setLayout(stores_group_layout)
|
||||||
for x in self.store_plugins:
|
for x in sorted(self.store_plugins.keys(), key=lambda x: x.lower()):
|
||||||
cbox = QCheckBox(x)
|
cbox = QCheckBox(x)
|
||||||
cbox.setChecked(True)
|
cbox.setChecked(True)
|
||||||
stores_group_layout.addWidget(cbox)
|
stores_group_layout.addWidget(cbox)
|
||||||
|
@ -76,7 +76,7 @@ class WaterstonesUKStore(BasicStoreConfig, StorePlugin):
|
|||||||
s.detail_item = id
|
s.detail_item = id
|
||||||
formats = []
|
formats = []
|
||||||
if epub:
|
if epub:
|
||||||
formats.append('EPUB')
|
formats.append('ePub')
|
||||||
if pdf:
|
if pdf:
|
||||||
formats.append('PDF')
|
formats.append('PDF')
|
||||||
s.formats = ', '.join(formats)
|
s.formats = ', '.join(formats)
|
||||||
|
76
src/calibre/gui2/store/weightless_books_plugin.py
Normal file
76
src/calibre/gui2/store/weightless_books_plugin.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# -*- 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 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 WeightlessBooksStore(BasicStoreConfig, StorePlugin):
|
||||||
|
|
||||||
|
def open(self, parent=None, detail_item=None, external=False):
|
||||||
|
url = 'http://weightlessbooks.com/'
|
||||||
|
|
||||||
|
if external or self.config.get('open_external', False):
|
||||||
|
open_url(QUrl(url_slash_cleaner(detail_item if detail_item else url)))
|
||||||
|
else:
|
||||||
|
d = WebStoreDialog(self.gui, url, parent, detail_item)
|
||||||
|
d.setWindowTitle(self.name)
|
||||||
|
d.set_tags(self.config.get('tags', ''))
|
||||||
|
d.exec_()
|
||||||
|
|
||||||
|
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())
|
||||||
|
for data in doc.xpath('//li[@id="product"]'):
|
||||||
|
if counter <= 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
id = ''.join(data.xpath('.//div[@class="cover"]/a/@href'))
|
||||||
|
if not id:
|
||||||
|
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()
|
||||||
|
s.author = author.strip()
|
||||||
|
s.price = price.strip()
|
||||||
|
s.detail_item = id.strip()
|
||||||
|
s.drm = SearchResult.DRM_UNLOCKED
|
||||||
|
s.formats = formats
|
||||||
|
|
||||||
|
yield s
|
88
src/calibre/gui2/store/wizards_tower_books_plugin.py
Normal file
88
src/calibre/gui2/store/wizards_tower_books_plugin.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# -*- 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 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 WizardsTowerBooksStore(BasicStoreConfig, StorePlugin):
|
||||||
|
|
||||||
|
url = 'http://www.wizardstowerbooks.com/'
|
||||||
|
|
||||||
|
def open(self, parent=None, detail_item=None, external=False):
|
||||||
|
if detail_item:
|
||||||
|
detail_item = self.url + detail_item
|
||||||
|
|
||||||
|
if external or self.config.get('open_external', False):
|
||||||
|
open_url(QUrl(url_slash_cleaner(detail_item if detail_item else url)))
|
||||||
|
else:
|
||||||
|
d = WebStoreDialog(self.gui, self.url, parent, detail_item)
|
||||||
|
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.wizardstowerbooks.com/search.html?for=' + urllib.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[@class="gridp"]//td'):
|
||||||
|
if counter <= 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
id = ''.join(data.xpath('.//span[@class="prti"]/a/@href'))
|
||||||
|
id = id.strip()
|
||||||
|
if not id:
|
||||||
|
continue
|
||||||
|
|
||||||
|
cover_url = ''.join(data.xpath('.//div[@class="prim"]/a/img/@src'))
|
||||||
|
cover_url = url_slash_cleaner(self.url + cover_url.strip())
|
||||||
|
|
||||||
|
price = ''.join(data.xpath('.//font[@class="selling_price"]//text()'))
|
||||||
|
price = price.strip()
|
||||||
|
if not price:
|
||||||
|
continue
|
||||||
|
|
||||||
|
title = ''.join(data.xpath('.//span[@class="prti"]/a/b/text()'))
|
||||||
|
author = ''.join(data.xpath('.//p[@class="last"]/text()'))
|
||||||
|
a, b, author = author.partition(' by ')
|
||||||
|
|
||||||
|
counter -= 1
|
||||||
|
|
||||||
|
s = SearchResult()
|
||||||
|
s.cover_url = cover_url
|
||||||
|
s.title = title.strip()
|
||||||
|
s.author = author.strip()
|
||||||
|
s.price = price.strip()
|
||||||
|
s.detail_item = id.strip()
|
||||||
|
s.drm = SearchResult.DRM_UNLOCKED
|
||||||
|
|
||||||
|
yield s
|
||||||
|
|
||||||
|
def get_details(self, search_result, timeout):
|
||||||
|
br = browser()
|
||||||
|
with closing(br.open(url_slash_cleaner(self.url + search_result.detail_item), timeout=timeout)) as nf:
|
||||||
|
idata = html.fromstring(nf.read())
|
||||||
|
|
||||||
|
formats = ', '.join(idata.xpath('//select[@id="N1_"]//option//text()'))
|
||||||
|
search_result.formats = formats.upper()
|
||||||
|
|
||||||
|
return True
|
@ -435,7 +435,7 @@ class DevicePage(QWizardPage, DeviceUI):
|
|||||||
self.registerField("device", self.device_view)
|
self.registerField("device", self.device_view)
|
||||||
|
|
||||||
def initializePage(self):
|
def initializePage(self):
|
||||||
self.label.setText(_('Choose you e-book device. If your device is'
|
self.label.setText(_('Choose your e-book device. If your device is'
|
||||||
' not in the list, choose a "%s" device.')%Device.manufacturer)
|
' not in the list, choose a "%s" device.')%Device.manufacturer)
|
||||||
self.man_model = ManufacturerModel()
|
self.man_model = ManufacturerModel()
|
||||||
self.manufacturer_view.setModel(self.man_model)
|
self.manufacturer_view.setModel(self.man_model)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user