mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
News download now works
This commit is contained in:
parent
e58c5eb50f
commit
5f0c27e6d6
@ -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)
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user