News download now works

This commit is contained in:
Kovid Goyal 2009-05-08 22:04:19 -07:00
parent e58c5eb50f
commit 5f0c27e6d6
7 changed files with 58 additions and 62 deletions

View File

@ -100,18 +100,23 @@ def available_width():
def extension(path): def extension(path):
return os.path.splitext(path)[1][1:].lower() 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, d = QMessageBox(QMessageBox.Warning, 'WARNING: '+title, msg, QMessageBox.Ok,
parent) parent)
d.setDetailedText(det_msg) d.setDetailedText(det_msg)
d.setIconPixmap(QPixmap(':/images/dialog_warning.svg')) d.setIconPixmap(QPixmap(':/images/dialog_warning.svg'))
if show:
return d.exec_()
return d 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, d = QMessageBox(QMessageBox.Critical, 'ERROR: '+title, msg, QMessageBox.Ok,
parent) parent)
d.setDetailedText(det_msg) d.setDetailedText(det_msg)
d.setIconPixmap(QPixmap(':/images/dialog_error.svg')) d.setIconPixmap(QPixmap(':/images/dialog_error.svg'))
if show:
return d.exec_()
return d return d
def question_dialog(parent, title, msg, det_msg=''): 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')) d.setIconPixmap(QPixmap(':/images/dialog_information.svg'))
return d 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, d = QMessageBox(QMessageBox.Information, title, msg, QMessageBox.NoButton,
parent) parent)
d.setDetailedText(det_msg) d.setDetailedText(det_msg)
d.setIconPixmap(QPixmap(':/images/dialog_information.svg')) d.setIconPixmap(QPixmap(':/images/dialog_information.svg'))
if show:
return d.exec_()
return d return d
def qstring_to_unicode(q): def qstring_to_unicode(q):
return unicode(q) return unicode(q)

View File

@ -530,8 +530,8 @@ class DeviceGUI(object):
]) ])
error_dialog(self, _('Failed to email books'), error_dialog(self, _('Failed to email books'),
_('Failed to email the following books:'), _('Failed to email the following books:'),
'%s'%errors, '%s'%errors
show=True) )
else: else:
self.status_bar.showMessage(_('Sent by email:') + ', '.join(good), self.status_bar.showMessage(_('Sent by email:') + ', '.join(good),
5000) 5000)

View File

@ -20,6 +20,7 @@ from calibre.utils.search_query_parser import SearchQueryParser
from calibre.utils.pyparsing import ParseException from calibre.utils.pyparsing import ParseException
from calibre.gui2 import NONE, error_dialog, config as gconf from calibre.gui2 import NONE, error_dialog, config as gconf
from calibre.utils.config import DynamicConfig from calibre.utils.config import DynamicConfig
from calibre.ptempfile import PersistentTemporaryFile
from calibre.gui2.dialogs.user_profiles import UserProfiles from calibre.gui2.dialogs.user_profiles import UserProfiles
config = DynamicConfig('scheduler') config = DynamicConfig('scheduler')
@ -522,8 +523,12 @@ class Scheduler(QObject):
self.recipes.remove(recipe) self.recipes.remove(recipe)
save_recipes(self.recipes) save_recipes(self.recipes)
return return
pt = PersistentTemporaryFile('_builtin.recipe')
pt.write(script)
pt.close()
script = pt.name
except ValueError: except ValueError:
script = recipe.title script = recipe.title + '.recipe'
self.debug('\tQueueing:', recipe) self.debug('\tQueueing:', recipe)
self.main.download_scheduled_recipe(recipe, script, self.recipe_downloaded) self.main.download_scheduled_recipe(recipe, script, self.recipe_downloaded)
self.queue.add(recipe) self.queue.add(recipe)

View File

@ -856,10 +856,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
_('Failed to download metadata for the following:'), _('Failed to download metadata for the following:'),
details, self).exec_() details, self).exec_()
else: else:
err = _('<b>Failed to download metadata:')+\ err = _('Failed to download metadata:')
'</b><br><pre>'+x.tb+'</pre>' error_dialog(self, _('Error'), err, det_msg=x.tb).exec_()
error_dialog(self, _('Error'), err,
show=True)
@ -1414,8 +1412,9 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
return return
if isinstance(job.exception, JobKilled): if isinstance(job.exception, JobKilled):
return return
error_dialog(self, _('Conversion Error'), job.gui_text(), error_dialog(self, _('Conversion Error'),
show=True) _('Failed to process')+': '+unicode(job.description),
det_msg=job.console_text()).exec_()
def initialize_database(self): def initialize_database(self):

View File

@ -7,6 +7,7 @@ from PyQt4.Qt import QMainWindow, QString, Qt, QFont, QCoreApplication, SIGNAL,\
QAction, QMenu, QMenuBar, QIcon QAction, QMenu, QMenuBar, QIcon
from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog
from calibre.utils.config import OptionParser from calibre.utils.config import OptionParser
from calibre.gui2 import error_dialog
def option_parser(usage='''\ def option_parser(usage='''\
Usage: %prog [options] Usage: %prog [options]
@ -19,26 +20,26 @@ Launch the Graphical User Interface
return parser return parser
class DebugWindow(ConversionErrorDialog): class DebugWindow(ConversionErrorDialog):
def __init__(self, parent): def __init__(self, parent):
ConversionErrorDialog.__init__(self, parent, 'Console output', '') ConversionErrorDialog.__init__(self, parent, 'Console output', '')
self.setModal(Qt.NonModal) self.setModal(Qt.NonModal)
font = QFont() font = QFont()
font.setStyleHint(QFont.TypeWriter) font.setStyleHint(QFont.TypeWriter)
self.text.setFont(font) self.text.setFont(font)
def write(self, msg): def write(self, msg):
self.text.setPlainText(self.text.toPlainText()+QString(msg)) self.text.setPlainText(self.text.toPlainText()+QString(msg))
def flush(self): def flush(self):
pass pass
class MainWindow(QMainWindow): class MainWindow(QMainWindow):
___menu_bar = None ___menu_bar = None
___menu = None ___menu = None
__actions = [] __actions = []
@classmethod @classmethod
def create_application_menubar(cls): def create_application_menubar(cls):
mb = QMenuBar(None) mb = QMenuBar(None)
@ -50,8 +51,8 @@ class MainWindow(QMainWindow):
mb.addMenu(menu) mb.addMenu(menu)
cls.___menu_bar = mb cls.___menu_bar = mb
cls.___menu = menu cls.___menu = menu
@classmethod @classmethod
def get_menubar_actions(cls): def get_menubar_actions(cls):
preferences_action = QAction(QIcon(':/images/config.svg'), _('&Preferences'), None) preferences_action = QAction(QIcon(':/images/config.svg'), _('&Preferences'), None)
@ -59,7 +60,7 @@ class MainWindow(QMainWindow):
preferences_action.setMenuRole(QAction.PreferencesRole) preferences_action.setMenuRole(QAction.PreferencesRole)
quit_action.setMenuRole(QAction.QuitRole) quit_action.setMenuRole(QAction.QuitRole)
return preferences_action, quit_action return preferences_action, quit_action
def __init__(self, opts, parent=None): def __init__(self, opts, parent=None):
QMainWindow.__init__(self, parent) QMainWindow.__init__(self, parent)
app = QCoreApplication.instance() app = QCoreApplication.instance()
@ -69,19 +70,18 @@ class MainWindow(QMainWindow):
self.__console_redirect = DebugWindow(self) self.__console_redirect = DebugWindow(self)
sys.stdout = sys.stderr = self.__console_redirect sys.stdout = sys.stderr = self.__console_redirect
self.__console_redirect.show() self.__console_redirect.show()
def unix_signal(self, signal): def unix_signal(self, signal):
print 'Received signal:', repr(signal) print 'Received signal:', repr(signal)
def unhandled_exception(self, type, value, tb): def unhandled_exception(self, type, value, tb):
try: try:
sio = StringIO.StringIO() sio = StringIO.StringIO()
traceback.print_exception(type, value, tb, file=sio) traceback.print_exception(type, value, tb, file=sio)
fe = sio.getvalue() fe = sio.getvalue()
print >>sys.stderr, fe print >>sys.stderr, fe
msg = '<p><b>' + unicode(str(value), 'utf8', 'replace') + '</b></p>' msg = unicode(str(value), 'utf8', 'replace')
msg += '<p>Detailed <b>traceback</b>:<pre>'+fe+'</pre>' error_dialog(self, _('ERROR: Unhandled exception'), msg, det_msg=fe,
d = ConversionErrorDialog(self, _('ERROR: Unhandled exception'), msg) show=True)
d.exec_()
except: except:
pass pass

View File

@ -7,22 +7,22 @@ __docformat__ = 'restructuredtext en'
Logic for setting up conversion jobs Logic for setting up conversion jobs
''' '''
import cPickle, os import cPickle
from PyQt4.Qt import QDialog from PyQt4.Qt import QDialog
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from calibre.gui2 import warning_dialog 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 NoSupportedInputFormats
from calibre.gui2.convert.single import Config as SingleConfig from calibre.gui2.convert.single import Config as SingleConfig
from calibre.gui2.convert.bulk import BulkConfig 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): def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format=None):
changed = False changed = False
jobs = [] jobs = []
bad = [] bad = []
total = len(book_ids) total = len(book_ids)
if total == 0: if total == 0:
return None, None, None return None, None, None
@ -33,23 +33,23 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format
try: try:
d = SingleConfig(parent, db, book_id, None, out_format) d = SingleConfig(parent, db, book_id, None, out_format)
if auto_conversion: if auto_conversion:
d.accept() d.accept()
result = QDialog.Accepted result = QDialog.Accepted
else: else:
result = d.exec_() result = d.exec_()
if result == QDialog.Accepted: if result == QDialog.Accepted:
mi = db.get_metadata(book_id, True) mi = db.get_metadata(book_id, True)
in_file = db.format_abspath(book_id, d.input_format, True) in_file = db.format_abspath(book_id, d.input_format, True)
out_file = PersistentTemporaryFile('.' + d.output_format) out_file = PersistentTemporaryFile('.' + d.output_format)
out_file.write(d.output_format) out_file.write(d.output_format)
out_file.close() out_file.close()
desc = _('Convert book %d of %d (%s)') % (i + 1, total, repr(mi.title)) desc = _('Convert book %d of %d (%s)') % (i + 1, total, repr(mi.title))
recs = cPickle.loads(d.recommendations) recs = cPickle.loads(d.recommendations)
args = [in_file, out_file.name, recs] args = [in_file, out_file.name, recs]
temp_files = [out_file] temp_files = [out_file]
@ -76,7 +76,7 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
changed = False changed = False
jobs = [] jobs = []
bad = [] bad = []
total = len(book_ids) total = len(book_ids)
if total == 0: if total == 0:
return None, None, None return None, None, None
@ -95,16 +95,16 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
try: try:
d = SingleConfig(parent, db, book_id, None, output_format) d = SingleConfig(parent, db, book_id, None, output_format)
d.accept() d.accept()
mi = db.get_metadata(book_id, True) mi = db.get_metadata(book_id, True)
in_file = db.format_abspath(book_id, d.input_format, True) in_file = db.format_abspath(book_id, d.input_format, True)
out_file = PersistentTemporaryFile('.' + output_format) out_file = PersistentTemporaryFile('.' + output_format)
out_file.write(output_format) out_file.write(output_format)
out_file.close() out_file.close()
desc = _('Convert book %d of %d (%s)') % (i + 1, total, repr(mi.title)) desc = _('Convert book %d of %d (%s)') % (i + 1, total, repr(mi.title))
args = [in_file, out_file.name, recs] args = [in_file, out_file.name, recs]
temp_files = [out_file] temp_files = [out_file]
jobs.append(('gui_convert', args, desc, d.output_format.upper(), book_id, temp_files)) 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 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): def fetch_scheduled_recipe(recipe, script):
from calibre.gui2.dialogs.scheduler import config from calibre.gui2.dialogs.scheduler import config
fmt = prefs['output_format'].lower() 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() pt.close()
args = ['feeds2%s'%fmt.lower(), '--output', pt.name, '--debug'] args = ['ebook-convert', script, pt.name, '-vv']
if recipe.needs_subscription: if recipe.needs_subscription:
x = config.get('recipe_account_info_%s'%recipe.id, False) x = config.get('recipe_account_info_%s'%recipe.id, False)
if not x: if not x:
raise ValueError(_('You must set a username and password for %s')%recipe.title) raise ValueError(_('You must set a username and password for %s')%recipe.title)
args.extend(['--username', x[0], '--password', x[1]]) 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): return 'ebook-convert', [args], _('Fetch news from ')+recipe.title, fmt.upper(), [pt]
fmt = prefs['output_format'].lower()
return _fetch_news(data, fmt)

View File

@ -19,7 +19,6 @@ from calibre.gui2 import Application, ORG_NAME, APP_UID, choose_files, \
info_dialog, error_dialog info_dialog, error_dialog
from calibre.ebooks.oeb.iterator import EbookIterator from calibre.ebooks.oeb.iterator import EbookIterator
from calibre.ebooks import DRMError from calibre.ebooks import DRMError
from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog
from calibre.constants import islinux from calibre.constants import islinux
from calibre.utils.config import Config, StringConfig from calibre.utils.config import Config, StringConfig
from calibre.gui2.library import SearchBox from calibre.gui2.library import SearchBox
@ -543,8 +542,8 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
if isinstance(worker.exception, DRMError): if isinstance(worker.exception, DRMError):
error_dialog(self, _('DRM Error'), _('<p>This book is protected by <a href="%s">DRM</a>')%'http://wiki.mobileread.com/wiki/DRM').exec_() error_dialog(self, _('DRM Error'), _('<p>This book is protected by <a href="%s">DRM</a>')%'http://wiki.mobileread.com/wiki/DRM').exec_()
else: else:
ConversionErrorDialog(self, _('Could not open ebook'), error_dialog(self, _('Could not open ebook'),
_('<b>%s</b><br/><p>%s</p>')%(worker.exception, worker.traceback.replace('\n', '<br>')), show=True) unicode(worker.exception), det_msg=worker.traceback, show=True)
self.close_progress_indicator() self.close_progress_indicator()
else: else:
self.metadata.show_opf(self.iterator.opf) self.metadata.show_opf(self.iterator.opf)