diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index ebe877f823..15a020e756 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -100,18 +100,23 @@ def available_width(): def extension(path): return os.path.splitext(path)[1][1:].lower() -def warning_dialog(parent, title, msg, det_msg=''): +def warning_dialog(parent, title, msg, det_msg='', show=False): d = QMessageBox(QMessageBox.Warning, 'WARNING: '+title, msg, QMessageBox.Ok, parent) d.setDetailedText(det_msg) d.setIconPixmap(QPixmap(':/images/dialog_warning.svg')) + + if show: + return d.exec_() return d -def error_dialog(parent, title, msg, det_msg=''): +def error_dialog(parent, title, msg, det_msg='', show=False): d = QMessageBox(QMessageBox.Critical, 'ERROR: '+title, msg, QMessageBox.Ok, parent) d.setDetailedText(det_msg) d.setIconPixmap(QPixmap(':/images/dialog_error.svg')) + if show: + return d.exec_() return d def question_dialog(parent, title, msg, det_msg=''): @@ -121,13 +126,16 @@ def question_dialog(parent, title, msg, det_msg=''): d.setIconPixmap(QPixmap(':/images/dialog_information.svg')) return d -def info_dialog(parent, title, msg, det_msg=''): +def info_dialog(parent, title, msg, det_msg='', show=False): d = QMessageBox(QMessageBox.Information, title, msg, QMessageBox.NoButton, parent) d.setDetailedText(det_msg) d.setIconPixmap(QPixmap(':/images/dialog_information.svg')) + if show: + return d.exec_() return d + def qstring_to_unicode(q): return unicode(q) diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index cf04e18ae6..b3dcf8a21c 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -530,8 +530,8 @@ class DeviceGUI(object): ]) error_dialog(self, _('Failed to email books'), _('Failed to email the following books:'), - '%s'%errors, - show=True) + '%s'%errors + ) else: self.status_bar.showMessage(_('Sent by email:') + ', '.join(good), 5000) diff --git a/src/calibre/gui2/dialogs/scheduler.py b/src/calibre/gui2/dialogs/scheduler.py index c9cb62cfaa..d757ec75c8 100644 --- a/src/calibre/gui2/dialogs/scheduler.py +++ b/src/calibre/gui2/dialogs/scheduler.py @@ -20,6 +20,7 @@ from calibre.utils.search_query_parser import SearchQueryParser from calibre.utils.pyparsing import ParseException from calibre.gui2 import NONE, error_dialog, config as gconf from calibre.utils.config import DynamicConfig +from calibre.ptempfile import PersistentTemporaryFile from calibre.gui2.dialogs.user_profiles import UserProfiles config = DynamicConfig('scheduler') @@ -522,8 +523,12 @@ class Scheduler(QObject): self.recipes.remove(recipe) save_recipes(self.recipes) return + pt = PersistentTemporaryFile('_builtin.recipe') + pt.write(script) + pt.close() + script = pt.name except ValueError: - script = recipe.title + script = recipe.title + '.recipe' self.debug('\tQueueing:', recipe) self.main.download_scheduled_recipe(recipe, script, self.recipe_downloaded) self.queue.add(recipe) diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 6840f4d7a8..4a6222dd7e 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -856,10 +856,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): _('Failed to download metadata for the following:'), details, self).exec_() else: - err = _('Failed to download metadata:')+\ - '
'+x.tb+'
' - error_dialog(self, _('Error'), err, - show=True) + err = _('Failed to download metadata:') + error_dialog(self, _('Error'), err, det_msg=x.tb).exec_() @@ -1414,8 +1412,9 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): return if isinstance(job.exception, JobKilled): return - error_dialog(self, _('Conversion Error'), job.gui_text(), - show=True) + error_dialog(self, _('Conversion Error'), + _('Failed to process')+': '+unicode(job.description), + det_msg=job.console_text()).exec_() def initialize_database(self): diff --git a/src/calibre/gui2/main_window.py b/src/calibre/gui2/main_window.py index 903848fb41..b77a3fe7c8 100644 --- a/src/calibre/gui2/main_window.py +++ b/src/calibre/gui2/main_window.py @@ -7,6 +7,7 @@ from PyQt4.Qt import QMainWindow, QString, Qt, QFont, QCoreApplication, SIGNAL,\ QAction, QMenu, QMenuBar, QIcon from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog from calibre.utils.config import OptionParser +from calibre.gui2 import error_dialog def option_parser(usage='''\ Usage: %prog [options] @@ -19,26 +20,26 @@ Launch the Graphical User Interface return parser class DebugWindow(ConversionErrorDialog): - + def __init__(self, parent): ConversionErrorDialog.__init__(self, parent, 'Console output', '') self.setModal(Qt.NonModal) font = QFont() font.setStyleHint(QFont.TypeWriter) self.text.setFont(font) - + def write(self, msg): self.text.setPlainText(self.text.toPlainText()+QString(msg)) - + def flush(self): - pass + pass class MainWindow(QMainWindow): ___menu_bar = None ___menu = None - __actions = [] - + __actions = [] + @classmethod def create_application_menubar(cls): mb = QMenuBar(None) @@ -50,8 +51,8 @@ class MainWindow(QMainWindow): mb.addMenu(menu) cls.___menu_bar = mb cls.___menu = menu - - + + @classmethod def get_menubar_actions(cls): preferences_action = QAction(QIcon(':/images/config.svg'), _('&Preferences'), None) @@ -59,7 +60,7 @@ class MainWindow(QMainWindow): preferences_action.setMenuRole(QAction.PreferencesRole) quit_action.setMenuRole(QAction.QuitRole) return preferences_action, quit_action - + def __init__(self, opts, parent=None): QMainWindow.__init__(self, parent) app = QCoreApplication.instance() @@ -69,19 +70,18 @@ class MainWindow(QMainWindow): self.__console_redirect = DebugWindow(self) sys.stdout = sys.stderr = self.__console_redirect self.__console_redirect.show() - + def unix_signal(self, signal): print 'Received signal:', repr(signal) - + def unhandled_exception(self, type, value, tb): try: sio = StringIO.StringIO() traceback.print_exception(type, value, tb, file=sio) fe = sio.getvalue() print >>sys.stderr, fe - msg = '

' + unicode(str(value), 'utf8', 'replace') + '

' - msg += '

Detailed traceback:

'+fe+'
' - d = ConversionErrorDialog(self, _('ERROR: Unhandled exception'), msg) - d.exec_() + msg = unicode(str(value), 'utf8', 'replace') + error_dialog(self, _('ERROR: Unhandled exception'), msg, det_msg=fe, + show=True) except: pass diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index b8dbbd5eba..4f3f837679 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -7,22 +7,22 @@ __docformat__ = 'restructuredtext en' Logic for setting up conversion jobs ''' -import cPickle, os +import cPickle from PyQt4.Qt import QDialog from calibre.ptempfile import PersistentTemporaryFile from calibre.gui2 import warning_dialog -from calibre.gui2.convert import load_specifics from calibre.gui2.convert.single import NoSupportedInputFormats from calibre.gui2.convert.single import Config as SingleConfig from calibre.gui2.convert.bulk import BulkConfig +from calibre.utils.config import prefs def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format=None): changed = False jobs = [] bad = [] - + total = len(book_ids) if total == 0: return None, None, None @@ -33,23 +33,23 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format try: d = SingleConfig(parent, db, book_id, None, out_format) - + if auto_conversion: d.accept() result = QDialog.Accepted else: result = d.exec_() - + if result == QDialog.Accepted: mi = db.get_metadata(book_id, True) in_file = db.format_abspath(book_id, d.input_format, True) - + out_file = PersistentTemporaryFile('.' + d.output_format) out_file.write(d.output_format) out_file.close() - + desc = _('Convert book %d of %d (%s)') % (i + 1, total, repr(mi.title)) - + recs = cPickle.loads(d.recommendations) args = [in_file, out_file.name, recs] temp_files = [out_file] @@ -76,7 +76,7 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None): changed = False jobs = [] bad = [] - + total = len(book_ids) if total == 0: return None, None, None @@ -95,16 +95,16 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None): try: d = SingleConfig(parent, db, book_id, None, output_format) d.accept() - + mi = db.get_metadata(book_id, True) in_file = db.format_abspath(book_id, d.input_format, True) - + out_file = PersistentTemporaryFile('.' + output_format) out_file.write(output_format) out_file.close() - + desc = _('Convert book %d of %d (%s)') % (i + 1, total, repr(mi.title)) - + args = [in_file, out_file.name, recs] temp_files = [out_file] jobs.append(('gui_convert', args, desc, d.output_format.upper(), book_id, temp_files)) @@ -126,33 +126,18 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None): return jobs, changed, bad -def _fetch_news(data, fmt): - pt = PersistentTemporaryFile(suffix='_feeds2%s.%s'%(fmt.lower(), fmt.lower())) - pt.close() - args = ['feeds2%s'%fmt.lower(), '--output', pt.name, '--debug'] - if data['username']: - args.extend(['--username', data['username']]) - if data['password']: - args.extend(['--password', data['password']]) - args.append(data['script'] if data['script'] else data['title']) - return 'fconvert_bulk_ebookseeds2'+fmt.lower(), [args], _('Fetch news from ')+data['title'], fmt.upper(), [pt] - - def fetch_scheduled_recipe(recipe, script): from calibre.gui2.dialogs.scheduler import config fmt = prefs['output_format'].lower() - pt = PersistentTemporaryFile(suffix='_feeds2%s.%s'%(fmt.lower(), fmt.lower())) + pt = PersistentTemporaryFile(suffix='_recipe_out.%s'%fmt.lower()) pt.close() - args = ['feeds2%s'%fmt.lower(), '--output', pt.name, '--debug'] + args = ['ebook-convert', script, pt.name, '-vv'] if recipe.needs_subscription: x = config.get('recipe_account_info_%s'%recipe.id, False) if not x: raise ValueError(_('You must set a username and password for %s')%recipe.title) args.extend(['--username', x[0], '--password', x[1]]) - args.append(script) - return 'feeds2'+fmt, [args], _('Fetch news from ')+recipe.title, fmt.upper(), [pt] -def fetch_news(data): - fmt = prefs['output_format'].lower() - return _fetch_news(data, fmt) + return 'ebook-convert', [args], _('Fetch news from ')+recipe.title, fmt.upper(), [pt] + diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index 0b8800035a..13553c6dc2 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -19,7 +19,6 @@ from calibre.gui2 import Application, ORG_NAME, APP_UID, choose_files, \ info_dialog, error_dialog from calibre.ebooks.oeb.iterator import EbookIterator from calibre.ebooks import DRMError -from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog from calibre.constants import islinux from calibre.utils.config import Config, StringConfig from calibre.gui2.library import SearchBox @@ -543,8 +542,8 @@ class EbookViewer(MainWindow, Ui_EbookViewer): if isinstance(worker.exception, DRMError): error_dialog(self, _('DRM Error'), _('

This book is protected by DRM')%'http://wiki.mobileread.com/wiki/DRM').exec_() else: - ConversionErrorDialog(self, _('Could not open ebook'), - _('%s

%s

')%(worker.exception, worker.traceback.replace('\n', '
')), show=True) + error_dialog(self, _('Could not open ebook'), + unicode(worker.exception), det_msg=worker.traceback, show=True) self.close_progress_indicator() else: self.metadata.show_opf(self.iterator.opf)