mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Move from gprefs to a store specific JSON config that each store automatically has access to use.
This commit is contained in:
commit
4ff0747da0
@ -25,6 +25,7 @@ msprefs.defaults['max_tags'] = 20
|
||||
msprefs.defaults['wait_after_first_identify_result'] = 30 # seconds
|
||||
msprefs.defaults['wait_after_first_cover_result'] = 60 # seconds
|
||||
msprefs.defaults['swap_author_names'] = False
|
||||
msprefs.defaults['fewer_tags'] = True
|
||||
|
||||
# Google covers are often poor quality (scans/errors) but they have high
|
||||
# resolution, so they trump covers from better sources. So make sure they
|
||||
|
@ -216,7 +216,7 @@ class ISBNMerge(object):
|
||||
|
||||
# We assume the smallest set of tags has the least cruft in it
|
||||
ans.tags = self.length_merge('tags', results,
|
||||
null_value=ans.tags)
|
||||
null_value=ans.tags, shortest=msprefs['fewer_tags'])
|
||||
|
||||
# We assume the longest series has the most info in it
|
||||
ans.series = self.length_merge('series', results,
|
||||
|
@ -3,7 +3,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__copyright__ = '2011, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
'''
|
||||
@ -17,7 +17,7 @@ from lxml import html
|
||||
from lxml.html import soupparser
|
||||
|
||||
from calibre.ebooks.metadata import check_isbn
|
||||
from calibre.ebooks.metadata.sources.base import Source
|
||||
from calibre.ebooks.metadata.sources.base import Source, Option
|
||||
from calibre.ebooks.metadata.book.base import Metadata
|
||||
from calibre.ebooks.chardet import xml_to_unicode
|
||||
from calibre.library.comments import sanitize_comments_html
|
||||
@ -40,6 +40,18 @@ class OverDrive(Source):
|
||||
supports_gzip_transfer_encoding = False
|
||||
cached_cover_url_is_reliable = True
|
||||
|
||||
options = (
|
||||
Option('get_full_metadata', 'bool', False,
|
||||
_('Download all metadata (slow)'),
|
||||
_('Enable this option to gather all metadata available from Overdrive.')),
|
||||
)
|
||||
|
||||
config_help_message = '<p>'+_('Additional metadata can be taken from Overdrive\'s book detail'
|
||||
' page. This includes a limited set of tags used by libraries, comments, language,'
|
||||
' and the ebook ISBN. Collecting this data is disabled by default due to the extra'
|
||||
' time required. Check the download all metadata option below to'
|
||||
' enable downloading this data.')
|
||||
|
||||
def identify(self, log, result_queue, abort, title=None, authors=None, # {{{
|
||||
identifiers={}, timeout=30):
|
||||
ovrdrv_id = identifiers.get('overdrive', None)
|
||||
@ -54,11 +66,13 @@ class OverDrive(Source):
|
||||
self.parse_search_results(ovrdrv_data, mi)
|
||||
if ovrdrv_id is None:
|
||||
ovrdrv_id = ovrdrv_data[7]
|
||||
|
||||
if self.prefs['get_full_metadata']:
|
||||
self.get_book_detail(br, ovrdrv_data[1], mi, ovrdrv_id, log)
|
||||
|
||||
if isbn is not None:
|
||||
self.cache_isbn_to_identifier(isbn, ovrdrv_id)
|
||||
|
||||
self.get_book_detail(br, ovrdrv_data[1], mi, ovrdrv_id, log)
|
||||
|
||||
result_queue.put(mi)
|
||||
|
||||
return None
|
||||
@ -438,4 +452,3 @@ if __name__ == '__main__':
|
||||
authors_test(['Agatha Christie'])]
|
||||
),
|
||||
])
|
||||
|
||||
|
@ -10,8 +10,8 @@ from functools import partial
|
||||
|
||||
from PyQt4.Qt import QMenu
|
||||
|
||||
from calibre.gui2 import JSONConfig
|
||||
from calibre.gui2.actions import InterfaceAction
|
||||
from calibre.gui2.dialogs.confirm_delete import confirm
|
||||
|
||||
class StoreAction(InterfaceAction):
|
||||
|
||||
@ -19,8 +19,6 @@ class StoreAction(InterfaceAction):
|
||||
action_spec = (_('Get books'), 'store.png', None, None)
|
||||
|
||||
def genesis(self):
|
||||
self.config = JSONConfig('store/action')
|
||||
|
||||
self.qaction.triggered.connect(self.search)
|
||||
self.store_menu = QMenu()
|
||||
self.load_menu()
|
||||
@ -34,34 +32,35 @@ class StoreAction(InterfaceAction):
|
||||
self.qaction.setMenu(self.store_menu)
|
||||
|
||||
def search(self):
|
||||
self.first_run_check()
|
||||
self.show_disclaimer()
|
||||
from calibre.gui2.store.search import SearchDialog
|
||||
sd = SearchDialog(self.gui.istores, self.gui)
|
||||
sd.exec_()
|
||||
|
||||
def open_store(self, store_plugin):
|
||||
self.first_run_check()
|
||||
self.show_disclaimer()
|
||||
store_plugin.open(self.gui)
|
||||
|
||||
def first_run_check(self):
|
||||
if self.config.get('first_run', True):
|
||||
self.config['first_run'] = False
|
||||
from calibre.gui2 import info_dialog
|
||||
info_dialog(self.gui, _('About Get Books'), '<p>' +
|
||||
def show_disclaimer(self):
|
||||
confirm(('<p>' +
|
||||
_('Calibre helps you find the ebooks you want by searching '
|
||||
'the websites of a variety of commercial and public domain '
|
||||
'the websites of various commercial and public domain '
|
||||
'book sources for you.') +
|
||||
'<p>' +
|
||||
_('Using the integrated search you can easily find which '
|
||||
'store has the book you are looking for, at the best price. '
|
||||
'You will also get DRM status and other useful information.')
|
||||
'You also get DRM status and other useful information.')
|
||||
+ '<p>' +
|
||||
_('All transactions (paid or otherwise) are handled between '
|
||||
'you and the particular website. '
|
||||
'you and the book seller. '
|
||||
'Calibre is not part of this process and any issues related '
|
||||
'to a purchase should be directed to the website you are '
|
||||
'buying from. Be sure to double check that any books you get '
|
||||
'will work with your e-book reader, especially if the book you '
|
||||
'are buying has '
|
||||
'<a href="http://drmfree.calibre-ebook.com/about#drm">DRM</a>.'
|
||||
), show=True, show_copy_button=False)
|
||||
)), 'about_get_books_msg',
|
||||
parent=self.gui, show_cancel_button=False,
|
||||
confirm_msg=_('Show this message again'),
|
||||
pixmap='dialog_information.png', title=_('About Get Books'))
|
||||
|
||||
|
@ -25,7 +25,7 @@ class Dialog(QDialog, Ui_Dialog):
|
||||
|
||||
|
||||
def confirm(msg, name, parent=None, pixmap='dialog_warning.png', title=None,
|
||||
show_cancel_button=True):
|
||||
show_cancel_button=True, confirm_msg=None):
|
||||
if not dynamic.get(confirm_config_name(name), True):
|
||||
return True
|
||||
d = Dialog(msg, name, parent)
|
||||
@ -35,5 +35,7 @@ def confirm(msg, name, parent=None, pixmap='dialog_warning.png', title=None,
|
||||
d.setWindowTitle(title)
|
||||
if not show_cancel_button:
|
||||
d.buttonBox.button(d.buttonBox.Cancel).setVisible(False)
|
||||
if confirm_msg is not None:
|
||||
d.again.setText(confirm_msg)
|
||||
d.resize(d.sizeHint())
|
||||
return d.exec_() == d.Accepted
|
||||
|
@ -259,6 +259,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
r('wait_after_first_identify_result', msprefs)
|
||||
r('wait_after_first_cover_result', msprefs)
|
||||
r('swap_author_names', msprefs)
|
||||
r('fewer_tags', msprefs)
|
||||
|
||||
self.configure_plugin_button.clicked.connect(self.configure_plugin)
|
||||
self.sources_model = SourcesModel(self)
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>781</width>
|
||||
<height>300</height>
|
||||
<height>394</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -21,7 +21,7 @@
|
||||
<widget class="QStackedWidget" name="stack">
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" rowspan="6">
|
||||
<item row="0" column="0" rowspan="7">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Metadata sources</string>
|
||||
@ -105,7 +105,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Max. number of &tags to download:</string>
|
||||
@ -115,10 +115,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<item row="4" column="2">
|
||||
<widget class="QSpinBox" name="opt_max_tags"/>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Max. &time to wait after first match is found:</string>
|
||||
@ -128,14 +128,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<item row="5" column="2">
|
||||
<widget class="QSpinBox" name="opt_wait_after_first_identify_result">
|
||||
<property name="suffix">
|
||||
<string> secs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Max. time to wait after first &cover is found:</string>
|
||||
@ -145,13 +145,24 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<item row="6" column="2">
|
||||
<widget class="QSpinBox" name="opt_wait_after_first_cover_result">
|
||||
<property name="suffix">
|
||||
<string> secs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="opt_fewer_tags">
|
||||
<property name="toolTip">
|
||||
<string><p>Different metadata sources have different sets of tags for the same book. If this option is checked, then calibre will use the smaller tag sets. These tend to be more like genres, while the larger tag sets tend to describe the books content.
|
||||
<p>Note that this option will only make a practical difference if one of the metadata sources has a genre like tag set for the book you are searching for. Most often, they all have large tag sets.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Prefer &fewer tags</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_2"/>
|
||||
|
@ -46,9 +46,12 @@ class StorePlugin(object): # {{{
|
||||
'''
|
||||
|
||||
def __init__(self, gui, name):
|
||||
from calibre.gui2 import JSONConfig
|
||||
|
||||
self.gui = gui
|
||||
self.name = name
|
||||
self.base_plugin = None
|
||||
self.config = JSONConfig('store/stores/' + self.name)
|
||||
|
||||
def open(self, gui, parent=None, detail_item=None, external=False):
|
||||
'''
|
||||
|
@ -8,14 +8,8 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
from PyQt4.Qt import QWidget
|
||||
|
||||
from calibre.gui2 import gprefs
|
||||
from calibre.gui2.store.basic_config_widget_ui import Ui_Form
|
||||
|
||||
def save_settings(config_widget):
|
||||
gprefs[config_widget.store.name + '_open_external'] = config_widget.open_external.isChecked()
|
||||
tags = unicode(config_widget.tags.text())
|
||||
gprefs[config_widget.store.name + '_tags'] = tags
|
||||
|
||||
class BasicStoreConfigWidget(QWidget, Ui_Form):
|
||||
|
||||
def __init__(self, store):
|
||||
@ -27,10 +21,10 @@ class BasicStoreConfigWidget(QWidget, Ui_Form):
|
||||
self.load_setings()
|
||||
|
||||
def load_setings(self):
|
||||
settings = self.store.get_settings()
|
||||
config = self.store.config
|
||||
|
||||
self.open_external.setChecked(settings.get(self.store.name + '_open_external'))
|
||||
self.tags.setText(settings.get(self.store.name + '_tags', ''))
|
||||
self.open_external.setChecked(config.get('open_external', False))
|
||||
self.tags.setText(config.get('tags', ''))
|
||||
|
||||
class BasicStoreConfig(object):
|
||||
|
||||
@ -41,12 +35,6 @@ class BasicStoreConfig(object):
|
||||
return BasicStoreConfigWidget(self)
|
||||
|
||||
def save_settings(self, config_widget):
|
||||
save_settings(config_widget)
|
||||
|
||||
def get_settings(self):
|
||||
settings = {}
|
||||
|
||||
settings[self.name + '_open_external'] = gprefs.get(self.name + '_open_external', False)
|
||||
settings[self.name + '_tags'] = gprefs.get(self.name + '_tags', self.name + ', store, download')
|
||||
|
||||
return settings
|
||||
self.config['open_external'] = config_widget.open_external.isChecked()
|
||||
tags = unicode(config_widget.tags.text())
|
||||
self.config['tags'] = tags
|
||||
|
@ -23,10 +23,9 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class BeWriteStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
url = 'http://www.bewrite.net/mm5/merchant.mvc?Screen=SFNT'
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
if external or self.config.get('open_external', False):
|
||||
if detail_item:
|
||||
url = url + detail_item
|
||||
open_url(QUrl(url_slash_cleaner(url)))
|
||||
@ -36,7 +35,7 @@ class BeWriteStore(BasicStoreConfig, StorePlugin):
|
||||
detail_url = url + detail_item
|
||||
d = WebStoreDialog(self.gui, url, parent, detail_url)
|
||||
d.setWindowTitle(self.name)
|
||||
d.set_tags(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -25,8 +25,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class BNStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
|
||||
pub_id = '21000000000352219'
|
||||
# Use Kovid's affiliate id 30% of the time.
|
||||
if random.randint(1, 10) in (1, 2, 3):
|
||||
@ -40,12 +38,12 @@ class BNStore(BasicStoreConfig, StorePlugin):
|
||||
isbn = mo.group('isbn')
|
||||
detail_item = 'http://gan.doubleclick.net/gan_click?lid=41000000012871747&pid=' + isbn + '&adurl=' + detail_item + '&pubid=' + pub_id
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
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(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -24,7 +24,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class DieselEbooksStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
url = 'http://www.diesel-ebooks.com/'
|
||||
|
||||
aff_id = '?aid=2049'
|
||||
@ -37,12 +36,12 @@ class DieselEbooksStore(BasicStoreConfig, StorePlugin):
|
||||
detail_url = url + detail_item + aff_id
|
||||
url = url + aff_id
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
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(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -25,8 +25,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class EbookscomStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
|
||||
m_url = 'http://www.dpbolvw.net/'
|
||||
h_click = 'click-4879827-10364500'
|
||||
d_click = 'click-4879827-10281551'
|
||||
@ -40,12 +38,12 @@ class EbookscomStore(BasicStoreConfig, StorePlugin):
|
||||
if detail_item:
|
||||
detail_url = m_url + d_click + detail_item
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
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(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -25,8 +25,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class EHarlequinStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
|
||||
m_url = 'http://www.dpbolvw.net/'
|
||||
h_click = 'click-4879827-534091'
|
||||
d_click = 'click-4879827-10375439'
|
||||
@ -40,12 +38,12 @@ class EHarlequinStore(BasicStoreConfig, StorePlugin):
|
||||
if detail_item:
|
||||
detail_url = m_url + d_click + detail_item
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
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(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -23,11 +23,10 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class FeedbooksStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
url = 'http://m.feedbooks.com/'
|
||||
ext_url = 'http://feedbooks.com/'
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
if external or self.config.get('open_external', False):
|
||||
if detail_item:
|
||||
ext_url = ext_url + detail_item
|
||||
open_url(QUrl(url_slash_cleaner(ext_url)))
|
||||
@ -37,7 +36,7 @@ class FeedbooksStore(BasicStoreConfig, StorePlugin):
|
||||
detail_url = url + detail_item
|
||||
d = WebStoreDialog(self.gui, url, parent, detail_url)
|
||||
d.setWindowTitle(self.name)
|
||||
d.set_tags(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -23,11 +23,10 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class GutenbergStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
url = 'http://m.gutenberg.org/'
|
||||
ext_url = 'http://gutenberg.org/'
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
if external or self.config.get('open_external', False):
|
||||
if detail_item:
|
||||
ext_url = ext_url + detail_item
|
||||
open_url(QUrl(url_slash_cleaner(ext_url)))
|
||||
@ -37,7 +36,7 @@ class GutenbergStore(BasicStoreConfig, StorePlugin):
|
||||
detail_url = url + detail_item
|
||||
d = WebStoreDialog(self.gui, url, parent, detail_url)
|
||||
d.setWindowTitle(self.name)
|
||||
d.set_tags(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -24,8 +24,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class KoboStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
|
||||
m_url = 'http://www.dpbolvw.net/'
|
||||
h_click = 'click-4879827-10762497'
|
||||
d_click = 'click-4879827-10772898'
|
||||
@ -39,12 +37,12 @@ class KoboStore(BasicStoreConfig, StorePlugin):
|
||||
if detail_item:
|
||||
detail_url = m_url + d_click + detail_item
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
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(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -24,19 +24,18 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class ManyBooksStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
url = 'http://manybooks.net/'
|
||||
|
||||
detail_url = None
|
||||
if detail_item:
|
||||
detail_url = url + detail_item
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
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(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -18,7 +18,7 @@ from PyQt4.Qt import Qt, QUrl, QDialog, QAbstractItemModel, QModelIndex, QVarian
|
||||
pyqtSignal
|
||||
|
||||
from calibre import browser
|
||||
from calibre.gui2 import open_url, NONE, JSONConfig
|
||||
from calibre.gui2 import open_url, NONE
|
||||
from calibre.gui2.store import StorePlugin
|
||||
from calibre.gui2.store.basic_config import BasicStoreConfig
|
||||
from calibre.gui2.store.mobileread_store_dialog_ui import Ui_Dialog
|
||||
@ -29,20 +29,18 @@ from calibre.utils.icu import sort_key
|
||||
class MobileReadStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def genesis(self):
|
||||
self.config = JSONConfig('store/store/' + self.name)
|
||||
self.rlock = RLock()
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
url = 'http://www.mobileread.com/'
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
if external or self.config.get('open_external', False):
|
||||
open_url(QUrl(detail_item if detail_item else url))
|
||||
else:
|
||||
if detail_item:
|
||||
d = WebStoreDialog(self.gui, url, parent, detail_item)
|
||||
d.setWindowTitle(self.name)
|
||||
d.set_tags(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
else:
|
||||
d = MobeReadStoreDialog(self, parent)
|
||||
|
@ -23,10 +23,9 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class OpenLibraryStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
url = 'http://openlibrary.org/'
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
if external or self.config.get('open_external', False):
|
||||
if detail_item:
|
||||
url = url + detail_item
|
||||
open_url(QUrl(url_slash_cleaner(url)))
|
||||
@ -36,7 +35,7 @@ class OpenLibraryStore(BasicStoreConfig, StorePlugin):
|
||||
detail_url = url + detail_item
|
||||
d = WebStoreDialog(self.gui, url, parent, detail_url)
|
||||
d.setWindowTitle(self.name)
|
||||
d.set_tags(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
@ -396,7 +396,7 @@ class DetailsThreadPool(GenericDownloadThreadPool):
|
||||
|
||||
|
||||
class DetailsThread(Thread):
|
||||
|
||||
|
||||
def __init__(self, tasks, results):
|
||||
Thread.__init__(self)
|
||||
self.daemon = True
|
||||
@ -428,11 +428,14 @@ class Matches(QAbstractItemModel):
|
||||
|
||||
def __init__(self):
|
||||
QAbstractItemModel.__init__(self)
|
||||
|
||||
self.DRM_LOCKED_ICON = QPixmap(I('drm-locked.png')).scaledToHeight(64)
|
||||
self.DRM_UNLOCKED_ICON = QPixmap(I('drm-unlocked.png')).scaledToHeight(64)
|
||||
self.DRM_UNKNOWN_ICON = QPixmap(I('dialog_warning.png')).scaledToHeight(64)
|
||||
|
||||
|
||||
self.DRM_LOCKED_ICON = QPixmap(I('drm-locked.png')).scaledToHeight(64,
|
||||
Qt.SmoothTransformation)
|
||||
self.DRM_UNLOCKED_ICON = QPixmap(I('drm-unlocked.png')).scaledToHeight(64,
|
||||
Qt.SmoothTransformation)
|
||||
self.DRM_UNKNOWN_ICON = QPixmap(I('dialog_question.png')).scaledToHeight(64,
|
||||
Qt.SmoothTransformation)
|
||||
|
||||
# All matches. Used to determine the order to display
|
||||
# self.matches because the SearchFilter returns
|
||||
# matches unordered.
|
||||
@ -482,7 +485,7 @@ class Matches(QAbstractItemModel):
|
||||
return self.matches[row]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def filter_results(self):
|
||||
self.layoutAboutToBeChanged.emit()
|
||||
if self.query:
|
||||
@ -611,13 +614,13 @@ class Matches(QAbstractItemModel):
|
||||
self.reorder_matches()
|
||||
if reset:
|
||||
self.reset()
|
||||
|
||||
|
||||
def reorder_matches(self):
|
||||
self.matches = sorted(self.matches, key=lambda x: self.all_matches.index(x))
|
||||
|
||||
|
||||
class SearchFilter(SearchQueryParser):
|
||||
|
||||
|
||||
USABLE_LOCATIONS = [
|
||||
'all',
|
||||
'author',
|
||||
@ -637,7 +640,7 @@ class SearchFilter(SearchQueryParser):
|
||||
|
||||
def add_search_result(self, search_result):
|
||||
self.srs.add(search_result)
|
||||
|
||||
|
||||
def clear_search_results(self):
|
||||
self.srs = set([])
|
||||
|
||||
@ -710,7 +713,7 @@ class SearchFilter(SearchQueryParser):
|
||||
m = CONTAINS_MATCH
|
||||
else:
|
||||
m = matchkind
|
||||
|
||||
|
||||
if locvalue == 'format':
|
||||
vals = accessor(sr).split(',')
|
||||
else:
|
||||
|
@ -25,7 +25,6 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
class SmashwordsStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
settings = self.get_settings()
|
||||
url = 'http://www.smashwords.com/'
|
||||
|
||||
aff_id = '?ref=usernone'
|
||||
@ -38,12 +37,12 @@ class SmashwordsStore(BasicStoreConfig, StorePlugin):
|
||||
detail_url = url + detail_item + aff_id
|
||||
url = url + aff_id
|
||||
|
||||
if external or settings.get(self.name + '_open_external', False):
|
||||
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(settings.get(self.name + '_tags', ''))
|
||||
d.set_tags(self.config.get('tags', ''))
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
63
src/calibre/utils/text2int.py
Executable file
63
src/calibre/utils/text2int.py
Executable file
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python
|
||||
__author__ = "stackoverflow community"
|
||||
__docformat__ = 'restructuredtext en'
|
||||
"""
|
||||
Takes english numeric words and converts them to integers.
|
||||
Returns False if the word isn't a number.
|
||||
|
||||
implementation courtesy of the stackoverflow community:
|
||||
http://stackoverflow.com/questions/493174/is-there-a-way-to-convert-number-words-to-integers-python
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
numwords = {}
|
||||
|
||||
def text2int(textnum):
|
||||
if not numwords:
|
||||
|
||||
units = [ "zero", "one", "two", "three", "four", "five", "six",
|
||||
"seven", "eight", "nine", "ten", "eleven", "twelve",
|
||||
"thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
|
||||
"eighteen", "nineteen"]
|
||||
|
||||
tens = ["", "", "twenty", "thirty", "forty", "fifty", "sixty",
|
||||
"seventy", "eighty", "ninety"]
|
||||
|
||||
scales = ["hundred", "thousand", "million", "billion", "trillion",
|
||||
'quadrillion', 'quintillion', 'sexillion', 'septillion',
|
||||
'octillion', 'nonillion', 'decillion' ]
|
||||
|
||||
numwords["and"] = (1, 0)
|
||||
for idx, word in enumerate(units): numwords[word] = (1, idx)
|
||||
for idx, word in enumerate(tens): numwords[word] = (1, idx * 10)
|
||||
for idx, word in enumerate(scales): numwords[word] = (10 ** (idx * 3 or 2), 0)
|
||||
|
||||
ordinal_words = {'first':1, 'second':2, 'third':3, 'fifth':5,
|
||||
'eighth':8, 'ninth':9, 'twelfth':12}
|
||||
ordinal_endings = [('ieth', 'y'), ('th', '')]
|
||||
current = result = 0
|
||||
tokens = re.split(r"[\s-]+", textnum)
|
||||
for word in tokens:
|
||||
if word in ordinal_words:
|
||||
scale, increment = (1, ordinal_words[word])
|
||||
else:
|
||||
for ending, replacement in ordinal_endings:
|
||||
if word.endswith(ending):
|
||||
word = "%s%s" % (word[:-len(ending)], replacement)
|
||||
|
||||
if word not in numwords:
|
||||
#raise Exception("Illegal word: " + word)
|
||||
return False
|
||||
|
||||
scale, increment = numwords[word]
|
||||
|
||||
if scale > 1:
|
||||
current = max(1, current)
|
||||
|
||||
current = current * scale + increment
|
||||
if scale > 100:
|
||||
result += current
|
||||
current = 0
|
||||
|
||||
return result + current
|
Loading…
x
Reference in New Issue
Block a user