Add a "Retry" button to the news download failed error message. Fixes #1458076 [Add 'Retry' button to failed news fetch jobs](https://bugs.launchpad.net/calibre/+bug/1458076)

This commit is contained in:
Kovid Goyal 2015-05-23 07:35:35 +05:30
parent 99c414dc71
commit 886323b52f
3 changed files with 18 additions and 8 deletions

View File

@ -6,6 +6,7 @@ __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import gc import gc
from functools import partial
from PyQt5.Qt import Qt from PyQt5.Qt import Qt
@ -48,8 +49,7 @@ class FetchNewsAction(InterfaceAction):
func, args, desc, fmt, temp_files = \ func, args, desc, fmt, temp_files = \
fetch_scheduled_recipe(arg) fetch_scheduled_recipe(arg)
job = self.gui.job_manager.run_job( job = self.gui.job_manager.run_job(
Dispatcher(self.scheduled_recipe_fetched), func, args=args, Dispatcher(self.scheduled_recipe_fetched), func, args=args, description=desc)
description=desc)
self.conversion_jobs[job] = (temp_files, fmt, arg) self.conversion_jobs[job] = (temp_files, fmt, arg)
self.gui.status_bar.show_message(_('Fetching news from ')+arg['title'], 2000) self.gui.status_bar.show_message(_('Fetching news from ')+arg['title'], 2000)
@ -58,7 +58,7 @@ class FetchNewsAction(InterfaceAction):
fname = temp_files[0].name fname = temp_files[0].name
if job.failed: if job.failed:
self.scheduler.recipe_download_failed(arg) self.scheduler.recipe_download_failed(arg)
return self.gui.job_exception(job) return self.gui.job_exception(job, retry_func=partial(self.scheduler.download, arg['urn']))
id = self.gui.library_view.model().add_news(fname, arg) id = self.gui.library_view.model().add_news(fname, arg)
# Arg may contain a "keep_issues" variable. If it is non-zero, # Arg may contain a "keep_issues" variable. If it is non-zero,

View File

@ -339,6 +339,9 @@ class JobError(QDialog): # {{{
self.ctc_button = self.bb.addButton(_('&Copy to clipboard'), self.ctc_button = self.bb.addButton(_('&Copy to clipboard'),
self.bb.ActionRole) self.bb.ActionRole)
self.ctc_button.clicked.connect(self.copy_to_clipboard) self.ctc_button.clicked.connect(self.copy_to_clipboard)
self.retry_button = self.bb.addButton(_('&Retry'), self.bb.ActionRole)
self.retry_button.clicked.connect(self.retry)
self.retry_func = None
self.show_det_msg = _('Show &details') self.show_det_msg = _('Show &details')
self.hide_det_msg = _('Hide &details') self.hide_det_msg = _('Hide &details')
self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole) self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)
@ -358,6 +361,11 @@ class JobError(QDialog): # {{{
self.suppress.setVisible(False) self.suppress.setVisible(False)
self.do_resize() self.do_resize()
def retry(self):
if self.retry_func is not None:
self.accept()
self.retry_func()
def update_suppress_state(self): def update_suppress_state(self):
self.suppress.setText(_( self.suppress.setText(_(
'Hide the remaining %d error messages'%len(self.queue))) 'Hide the remaining %d error messages'%len(self.queue)))
@ -395,15 +403,15 @@ class JobError(QDialog): # {{{
self.bb.button(self.bb.Close).setFocus(Qt.OtherFocusReason) self.bb.button(self.bb.Close).setFocus(Qt.OtherFocusReason)
return ret return ret
def show_error(self, title, msg, det_msg=u''): def show_error(self, title, msg, det_msg=u'', retry_func=None):
self.queue.append((title, msg, det_msg)) self.queue.append((title, msg, det_msg, retry_func))
self.update_suppress_state() self.update_suppress_state()
self.pop() self.pop()
def pop(self): def pop(self):
if not self.queue or self.isVisible(): if not self.queue or self.isVisible():
return return
title, msg, det_msg = self.queue.pop(0) title, msg, det_msg, retry_func = self.queue.pop(0)
self.setWindowTitle(title) self.setWindowTitle(title)
self.msg_label.setText(msg) self.msg_label.setText(msg)
self.det_msg.setPlainText(det_msg) self.det_msg.setPlainText(det_msg)
@ -414,6 +422,8 @@ class JobError(QDialog): # {{{
self.update_suppress_state() self.update_suppress_state()
if not det_msg: if not det_msg:
self.det_msg_toggle.setVisible(False) self.det_msg_toggle.setVisible(False)
self.retry_button.setVisible(retry_func is not None)
self.retry_func = retry_func
self.do_resize() self.do_resize()
self.show() self.show()

View File

@ -731,7 +731,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
self.set_number_of_books_shown() self.set_number_of_books_shown()
self.update_status_bar() self.update_status_bar()
def job_exception(self, job, dialog_title=_('Conversion Error')): def job_exception(self, job, dialog_title=_('Conversion Error'), retry_func=None):
if not hasattr(self, '_modeless_dialogs'): if not hasattr(self, '_modeless_dialogs'):
self._modeless_dialogs = [] self._modeless_dialogs = []
minz = self.is_minimized_to_tray minz = self.is_minimized_to_tray
@ -813,7 +813,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
if not minz: if not minz:
self.job_error_dialog.show_error(dialog_title, self.job_error_dialog.show_error(dialog_title,
_('<b>Failed</b>')+': '+unicode(job.description), _('<b>Failed</b>')+': '+unicode(job.description),
det_msg=job.details) det_msg=job.details, retry_func=retry_func)
def read_settings(self): def read_settings(self):
geometry = config['main_window_geometry'] geometry = config['main_window_geometry']