diff --git a/src/calibre/ebooks/conversion/__init__.py b/src/calibre/ebooks/conversion/__init__.py index 384ccfb79c..e9461c7279 100644 --- a/src/calibre/ebooks/conversion/__init__.py +++ b/src/calibre/ebooks/conversion/__init__.py @@ -1,4 +1,25 @@ -from __future__ import with_statement -__license__ = 'GPL 3' -__copyright__ = '2009, Kovid Goyal ' +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' + + +class ConversionUserFeedBack(Exception): + + def __init__(self, title, msg, level='info', det_msg=''): + ''' Show a simple message to the user + + :param title: The title (very short description) + :param msg: The message to show the user + :param level: Must be one of 'info', 'warn' or 'error' + :param det_msg: Optional detailed message to show the user + ''' + import json + Exception.__init__(self, json.dumps({'msg':msg, 'level':level, + 'det_msg':det_msg, 'title':title})) + self.title, self.msg, self.det_msg = title, msg, det_msg + self.level = level + diff --git a/src/calibre/ebooks/conversion/cli.py b/src/calibre/ebooks/conversion/cli.py index f6975b3cb8..a860b75839 100644 --- a/src/calibre/ebooks/conversion/cli.py +++ b/src/calibre/ebooks/conversion/cli.py @@ -15,6 +15,7 @@ from calibre.utils.logging import Log from calibre.constants import preferred_encoding from calibre.customize.conversion import OptionRecommendation from calibre import patheq +from calibre.ebooks.conversion import ConversionUserFeedBack USAGE = '%prog ' + _('''\ input_file output_file [options] @@ -320,7 +321,16 @@ def main(args=sys.argv): if n.dest] plumber.merge_ui_recommendations(recommendations) - plumber.run() + try: + plumber.run() + except ConversionUserFeedBack as e: + ll = {'info': log.info, 'warn': log.warn, + 'error':log.error}.get(e.level, log.info) + ll(e.title) + if e.det_msg: + log.debug(e.detmsg) + ll(e.msg) + raise SystemExit(1) log(_('Output saved to'), ' ', plumber.output) diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index a7adac3e37..980a325c12 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -24,9 +24,9 @@ from calibre.utils.config import prefs, dynamic from calibre.utils.ipc.server import Server from calibre.library.database2 import LibraryDatabase2 from calibre.customize.ui import interface_actions, available_store_plugins -from calibre.gui2 import error_dialog, GetMetadata, open_url, \ - gprefs, max_available_height, config, info_dialog, Dispatcher, \ - question_dialog +from calibre.gui2 import (error_dialog, GetMetadata, open_url, + gprefs, max_available_height, config, info_dialog, Dispatcher, + question_dialog, warning_dialog) from calibre.gui2.cover_flow import CoverFlowMixin from calibre.gui2.widgets import ProgressIndicator from calibre.gui2.update import UpdateMixin @@ -653,6 +653,23 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ d.show() self._modeless_dialogs.append(d) return + + if 'calibre.ebooks.conversion.ConversionUserFeedBack:' in job.details: + if not minz: + import json + payload = job.details.rpartition( + 'calibre.ebooks.conversion.ConversionUserFeedBack:')[-1] + payload = json.loads('{' + payload.partition('{')[-1]) + d = {'info':info_dialog, 'warn':warning_dialog, + 'error':error_dialog}.get(payload['level'], + error_dialog) + d = d(self, payload['title'], + '

%s

'%payload['msg'], + det_msg=payload['det_msg']) + d.setModal(False) + d.show() + self._modeless_dialogs.append(d) + return except: pass if job.killed: diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 75e9d03d6e..86a8093e1f 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -656,9 +656,22 @@ class BasicNewsRecipe(Recipe): For an example, see the recipe for downloading `The Atlantic`. In addition, you can add 'author' for the author of the article. + + If you want to abort processing for some reason and have + calibre show the user a simple message instead of an error, call + :meth:`abort_recipe_processing`. ''' raise NotImplementedError + def abort_recipe_processing(self, msg): + ''' + Causes the recipe download system to abort the download of this recipe, + displaying a simple feedback message to the user. + ''' + from calibre.ebooks.conversion import ConversionUserFeedBack + raise ConversionUserFeedBack(_('Failed to download %s')%self.title, + msg) + def get_obfuscated_article(self, url): ''' If you set `articles_are_obfuscated` this method is called with