mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Store: Add config widget for search accessible via the store plugin preferences.
This commit is contained in:
parent
f14c1a65fd
commit
4a8f83305f
@ -854,6 +854,17 @@ class ActionStore(InterfaceActionBase):
|
|||||||
name = 'Store'
|
name = 'Store'
|
||||||
author = 'John Schember'
|
author = 'John Schember'
|
||||||
actual_plugin = 'calibre.gui2.actions.store:StoreAction'
|
actual_plugin = 'calibre.gui2.actions.store:StoreAction'
|
||||||
|
|
||||||
|
def customization_help(self, gui=False):
|
||||||
|
return 'Customize the behavior of the store search.'
|
||||||
|
|
||||||
|
def config_widget(self):
|
||||||
|
from calibre.gui2.store.config.store import config_widget as get_cw
|
||||||
|
return get_cw()
|
||||||
|
|
||||||
|
def save_settings(self, config_widget):
|
||||||
|
from calibre.gui2.store.config.store import save_settings as save
|
||||||
|
save(config_widget)
|
||||||
|
|
||||||
plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog,
|
plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog,
|
||||||
ActionConvert, ActionDelete, ActionEditMetadata, ActionView,
|
ActionConvert, ActionDelete, ActionEditMetadata, ActionView,
|
||||||
|
@ -22,7 +22,7 @@ class GenericDownloadThreadPool(object):
|
|||||||
at the end of the function.
|
at the end of the function.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, thread_type, thread_count):
|
def __init__(self, thread_type, thread_count=1):
|
||||||
self.thread_type = thread_type
|
self.thread_type = thread_type
|
||||||
self.thread_count = thread_count
|
self.thread_count = thread_count
|
||||||
|
|
||||||
@ -30,6 +30,9 @@ class GenericDownloadThreadPool(object):
|
|||||||
self.results = Queue()
|
self.results = Queue()
|
||||||
self.threads = []
|
self.threads = []
|
||||||
|
|
||||||
|
def set_thread_count(self, thread_count):
|
||||||
|
self.thread_count = thread_count
|
||||||
|
|
||||||
def add_task(self):
|
def add_task(self):
|
||||||
'''
|
'''
|
||||||
This must be implemented in a sub class and this function
|
This must be implemented in a sub class and this function
|
||||||
@ -92,8 +95,8 @@ class SearchThreadPool(GenericDownloadThreadPool):
|
|||||||
def __init__(self, thread_count):
|
def __init__(self, thread_count):
|
||||||
GenericDownloadThreadPool.__init__(self, SearchThread, thread_count)
|
GenericDownloadThreadPool.__init__(self, SearchThread, thread_count)
|
||||||
|
|
||||||
def add_task(self, query, store_name, store_plugin, timeout):
|
def add_task(self, query, store_name, store_plugin, max_results, timeout):
|
||||||
self.tasks.put((query, store_name, store_plugin, timeout))
|
self.tasks.put((query, store_name, store_plugin, max_results, timeout))
|
||||||
GenericDownloadThreadPool.add_task(self)
|
GenericDownloadThreadPool.add_task(self)
|
||||||
|
|
||||||
|
|
||||||
@ -112,8 +115,8 @@ class SearchThread(Thread):
|
|||||||
def run(self):
|
def run(self):
|
||||||
while self._run and not self.tasks.empty():
|
while self._run and not self.tasks.empty():
|
||||||
try:
|
try:
|
||||||
query, store_name, store_plugin, timeout = self.tasks.get()
|
query, store_name, store_plugin, max_results, timeout = self.tasks.get()
|
||||||
for res in store_plugin.search(query, timeout=timeout):
|
for res in store_plugin.search(query, max_results=max_results, timeout=timeout):
|
||||||
if not self._run:
|
if not self._run:
|
||||||
return
|
return
|
||||||
res.store_name = store_name
|
res.store_name = store_name
|
||||||
|
@ -33,7 +33,7 @@ class Matches(QAbstractItemModel):
|
|||||||
HEADERS = [_('Cover'), _('Title'), _('Price'), _('DRM'), _('Store')]
|
HEADERS = [_('Cover'), _('Title'), _('Price'), _('DRM'), _('Store')]
|
||||||
HTML_COLS = (1, 4)
|
HTML_COLS = (1, 4)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, cover_thread_count=2, detail_thread_count=4):
|
||||||
QAbstractItemModel.__init__(self)
|
QAbstractItemModel.__init__(self)
|
||||||
|
|
||||||
self.DRM_LOCKED_ICON = QPixmap(I('drm-locked.png')).scaledToHeight(64,
|
self.DRM_LOCKED_ICON = QPixmap(I('drm-locked.png')).scaledToHeight(64,
|
||||||
@ -51,8 +51,8 @@ class Matches(QAbstractItemModel):
|
|||||||
self.matches = []
|
self.matches = []
|
||||||
self.query = ''
|
self.query = ''
|
||||||
self.search_filter = SearchFilter()
|
self.search_filter = SearchFilter()
|
||||||
self.cover_pool = CoverThreadPool(2)
|
self.cover_pool = CoverThreadPool(cover_thread_count)
|
||||||
self.details_pool = DetailsThreadPool(4)
|
self.details_pool = DetailsThreadPool(detail_thread_count)
|
||||||
|
|
||||||
self.sort_col = 2
|
self.sort_col = 2
|
||||||
self.sort_order = Qt.AscendingOrder
|
self.sort_order = Qt.AscendingOrder
|
||||||
|
@ -18,9 +18,6 @@ from calibre.gui2.store.search.download_thread import SearchThreadPool, \
|
|||||||
CacheUpdateThreadPool
|
CacheUpdateThreadPool
|
||||||
from calibre.gui2.store.search.search_ui import Ui_Dialog
|
from calibre.gui2.store.search.search_ui import Ui_Dialog
|
||||||
|
|
||||||
HANG_TIME = 75000 # milliseconds seconds
|
|
||||||
TIMEOUT = 75 # seconds
|
|
||||||
|
|
||||||
class SearchDialog(QDialog, Ui_Dialog):
|
class SearchDialog(QDialog, Ui_Dialog):
|
||||||
|
|
||||||
def __init__(self, istores, parent=None, query=''):
|
def __init__(self, istores, parent=None, query=''):
|
||||||
@ -28,13 +25,22 @@ class SearchDialog(QDialog, Ui_Dialog):
|
|||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
|
||||||
self.config = JSONConfig('store/search')
|
self.config = JSONConfig('store/search')
|
||||||
|
|
||||||
self.search_edit.initialize('store_search_search')
|
self.search_edit.initialize('store_search_search')
|
||||||
|
|
||||||
|
# Loads variables that store various settings.
|
||||||
|
# This needs to be called soon in __init__ because
|
||||||
|
# the variables it sets up are used later.
|
||||||
|
self.load_settings()
|
||||||
|
|
||||||
# We keep a cache of store plugins and reference them by name.
|
# We keep a cache of store plugins and reference them by name.
|
||||||
self.store_plugins = istores
|
self.store_plugins = istores
|
||||||
self.search_pool = SearchThreadPool(4)
|
|
||||||
self.cache_pool = CacheUpdateThreadPool(2)
|
# Setup our worker threads.
|
||||||
|
self.search_pool = SearchThreadPool(self.search_thread_count)
|
||||||
|
self.cache_pool = CacheUpdateThreadPool(self.cache_thread_count)
|
||||||
|
self.results_view.model().cover_pool.set_thread_count(self.cover_thread_count)
|
||||||
|
self.results_view.model().details_pool.set_thread_count(self.details_thread_count)
|
||||||
|
|
||||||
# Check for results and hung threads.
|
# Check for results and hung threads.
|
||||||
self.checker = QTimer()
|
self.checker = QTimer()
|
||||||
self.progress_checker = QTimer()
|
self.progress_checker = QTimer()
|
||||||
@ -42,7 +48,7 @@ class SearchDialog(QDialog, Ui_Dialog):
|
|||||||
|
|
||||||
# Update store caches silently.
|
# Update store caches silently.
|
||||||
for p in self.store_plugins.values():
|
for p in self.store_plugins.values():
|
||||||
self.cache_pool.add_task(p, 30)
|
self.cache_pool.add_task(p, self.timeout)
|
||||||
|
|
||||||
# Add check boxes for each store so the user
|
# Add check boxes for each store so the user
|
||||||
# can disable searching specific stores on a
|
# can disable searching specific stores on a
|
||||||
@ -128,7 +134,7 @@ class SearchDialog(QDialog, Ui_Dialog):
|
|||||||
# Add plugins that the user has checked to the search pool's work queue.
|
# Add plugins that the user has checked to the search pool's work queue.
|
||||||
for n in store_names:
|
for n in store_names:
|
||||||
if getattr(self, 'store_check_' + n).isChecked():
|
if getattr(self, 'store_check_' + n).isChecked():
|
||||||
self.search_pool.add_task(query, n, self.store_plugins[n], TIMEOUT)
|
self.search_pool.add_task(query, n, self.store_plugins[n], self.max_results, self.timeout)
|
||||||
self.hang_check = 0
|
self.hang_check = 0
|
||||||
self.checker.start(100)
|
self.checker.start(100)
|
||||||
self.pi.startAnimation()
|
self.pi.startAnimation()
|
||||||
@ -202,11 +208,32 @@ class SearchDialog(QDialog, Ui_Dialog):
|
|||||||
self.results_view.model().sort_order = self.config.get('sort_order', Qt.AscendingOrder)
|
self.results_view.model().sort_order = self.config.get('sort_order', Qt.AscendingOrder)
|
||||||
self.results_view.header().setSortIndicator(self.results_view.model().sort_col, self.results_view.model().sort_order)
|
self.results_view.header().setSortIndicator(self.results_view.model().sort_col, self.results_view.model().sort_order)
|
||||||
|
|
||||||
|
def load_settings(self):
|
||||||
|
# Seconds
|
||||||
|
self.timeout = self.config.get('timeout', 75)
|
||||||
|
# Milliseconds
|
||||||
|
self.hang_time = self.config.get('hang_time', 75) * 1000
|
||||||
|
self.max_results = self.config.get('max_results', 10)
|
||||||
|
|
||||||
|
# Number of threads to run for each type of operation
|
||||||
|
self.search_thread_count = self.config.get('search_thread_count', 4)
|
||||||
|
self.cache_thread_count = self.config.get('cache_thread_count', 2)
|
||||||
|
self.cover_thread_count = self.config.get('cover_thread_count', 2)
|
||||||
|
self.details_thread_count = self.config.get('details_thread_count', 4)
|
||||||
|
|
||||||
|
def config_finished(self):
|
||||||
|
self.load_settings()
|
||||||
|
|
||||||
|
self.search_pool.set_thread_count(self.search_thread_count)
|
||||||
|
self.cache_pool.set_thread_count(self.cache_thread_count)
|
||||||
|
self.results_view.model().cover_pool.set_thread_count(self.cover_thread_count)
|
||||||
|
self.results_view.model().details_pool.set_thread_count(self.details_thread_count)
|
||||||
|
|
||||||
def get_results(self):
|
def get_results(self):
|
||||||
# We only want the search plugins to run
|
# We only want the search plugins to run
|
||||||
# a maximum set amount of time before giving up.
|
# a maximum set amount of time before giving up.
|
||||||
self.hang_check += 1
|
self.hang_check += 1
|
||||||
if self.hang_check >= HANG_TIME:
|
if self.hang_check >= self.hang_time:
|
||||||
self.search_pool.abort()
|
self.search_pool.abort()
|
||||||
self.checker.stop()
|
self.checker.stop()
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user