Add documentation. Fix various issues.

This commit is contained in:
John Schember 2011-02-28 20:37:43 -05:00
parent 8e1fba87a3
commit 06e3186391
4 changed files with 53 additions and 11 deletions

View File

@ -590,11 +590,23 @@ class StorePlugin(Plugin): # {{{
# This needs to be changed to (0, 8, 0) # This needs to be changed to (0, 8, 0)
minimum_calibre_version = (0, 4, 118) minimum_calibre_version = (0, 4, 118)
def open(self, gui, parent=None, detail_item=None): def open(self, gui, parent=None, detail_item=None, external=False):
''' '''
Open a dialog for displaying the store. Open the store.
start_item is a refernce unique to the store
plugin and opens to the item when specified. :param gui: The main GUI. This will be used to have the job
system start downloading an item from the store.
:param parent: The parent of the store dialog. This is used
to create modal dialogs.
:param detail_item: A plugin specific reference to an item
in the store that the user should be shown.
:param external: When False open an internal dialog with the
store. When True open the users default browser to the store's
web site. :param:`detail_item` should still be respected when external
is True.
''' '''
raise NotImplementedError() raise NotImplementedError()
@ -607,12 +619,21 @@ class StorePlugin(Plugin): # {{{
:param max_results: The maximum number of results to return. :param max_results: The maximum number of results to return.
:param timeout: The maximum amount of time in seconds to spend download the search results. :param timeout: The maximum amount of time in seconds to spend download the search results.
:return: calibre.gui2.store.search_result.SearchResult object :return: :class:`calibre.gui2.store.search_result.SearchResult` objects
item_data is plugin specific and is used in :meth:`open` to open to a specifc place in the store. item_data is plugin specific and is used in :meth:`open` to open to a specifc place in the store.
''' '''
raise NotImplementedError() raise NotImplementedError()
def get_settings(self): def get_settings(self):
'''
This is only useful for plugins that implement
:attr:`config_widget` that is the only way to save
settings. This is used by plugins to get the saved
settings and apply when necessary.
:return: A dictionary filled with the settings used
by this plugin.
'''
raise NotImplementedError() raise NotImplementedError()
# }}} # }}}

View File

@ -33,16 +33,24 @@ class SearchDialog(QDialog, Ui_Dialog):
QDialog.__init__(self, *args) QDialog.__init__(self, *args)
self.setupUi(self) self.setupUi(self)
# We pass this on to the store plugins so they can
# tell the gui's job system to start downloading an
# item.
self.gui = gui self.gui = gui
# We keep a cache of store plugins and reference them by name.
self.store_plugins = {} self.store_plugins = {}
self.search_pool = SearchThreadPool(SearchThread, SEARCH_THREAD_TOTAL) self.search_pool = SearchThreadPool(SearchThread, SEARCH_THREAD_TOTAL)
# Check for results and hung threads.
self.checker = QTimer() self.checker = QTimer()
self.hang_check = 0 self.hang_check = 0
self.model = Matches() self.model = Matches()
self.results_view.setModel(self.model) self.results_view.setModel(self.model)
# Add check boxes for each store so the user
# can disable searching specific stores on a
# 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 store_plugins(): for x in store_plugins():
@ -96,6 +104,7 @@ class SearchDialog(QDialog, Ui_Dialog):
if not store_names: if not store_names:
return return
shuffle(store_names) shuffle(store_names)
# 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], TIMEOUT)
@ -117,7 +126,7 @@ class SearchDialog(QDialog, Ui_Dialog):
self.checker.stop() self.checker.stop()
while self.search_pool.has_results(): while self.search_pool.has_results():
res = self.search_pool.get_result_no_wait() res = self.search_pool.get_result()
if res: if res:
self.results_view.model().add_result(res) self.results_view.model().add_result(res)
@ -126,6 +135,9 @@ class SearchDialog(QDialog, Ui_Dialog):
self.store_plugins[result.store_name].open(self.gui, self, result.detail_item) self.store_plugins[result.store_name].open(self.gui, self, result.detail_item)
def get_store_checks(self): def get_store_checks(self):
'''
Returns a list of QCheckBox's for each store.
'''
checks = [] checks = []
for x in self.store_plugins: for x in self.store_plugins:
check = getattr(self, 'store_check_' + x, None) check = getattr(self, 'store_check_' + x, None)
@ -158,6 +170,9 @@ class GenericDownloadThreadPool(object):
self.tasks = Queue() self.tasks = Queue()
self.results = Queue() self.results = Queue()
self.threads = [] self.threads = []
def add_task(self):
raise NotImplementedError()
def start_threads(self): def start_threads(self):
for i in range(self.thread_count): for i in range(self.thread_count):

View File

@ -68,6 +68,7 @@ class NPWebView(QWebView):
def get_cookies(self): def get_cookies(self):
cj = CookieJar() cj = CookieJar()
# Translate Qt cookies to cookielib cookies for use by mechanize.
for c in self.page().networkAccessManager().cookieJar().allCookies(): for c in self.page().networkAccessManager().cookieJar().allCookies():
version = 0 version = 0
name = unicode(QString(c.name())) name = unicode(QString(c.name()))

View File

@ -47,6 +47,13 @@ class StoreDownloadJob(BaseJob):
def job_done(self): def job_done(self):
self.duration = time.time() - self.start_time self.duration = time.time() - self.start_time
self.percent = 1 self.percent = 1
try:
os.remove(self.tmp_file_name)
except:
import traceback
self.log_write(traceback.format_exc())
# Dump log onto disk # Dump log onto disk
lf = PersistentTemporaryFile('store_log') lf = PersistentTemporaryFile('store_log')
lf.write(self._log_file.getvalue()) lf.write(self._log_file.getvalue())
@ -55,11 +62,6 @@ class StoreDownloadJob(BaseJob):
self._log_file.close() self._log_file.close()
self._log_file = None self._log_file = None
try:
os.remove(self.tmp_file_name)
except:
pass
self.job_manager.changed_queue.put(self) self.job_manager.changed_queue.put(self)
def log_write(self, what): def log_write(self, what):
@ -97,8 +99,11 @@ class StoreDownloader(Thread):
continue continue
try: try:
job.percent = .1
self._download(job) self._download(job)
job.percent = .7
self._add(job) self._add(job)
job.percent = .8
self._save_as(job) self._save_as(job)
except Exception, e: except Exception, e:
if not self._run: if not self._run: