Pull from driver-dev

This commit is contained in:
Kovid Goyal 2009-05-07 21:47:24 -07:00
commit 8b0fc486b5
13 changed files with 313 additions and 279 deletions

View File

@ -83,8 +83,6 @@ class Device(DeviceConfig, DevicePlugin):
''' '''
FDI_LUNS = {'lun0':0, 'lun1':1, 'lun2':2} FDI_LUNS = {'lun0':0, 'lun1':1, 'lun2':2}
FDI_BCD_TEMPLATE = '<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.device_revision_bcd" int="%(bcd)s">' FDI_BCD_TEMPLATE = '<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.device_revision_bcd" int="%(bcd)s">'
FDI_LUNS = {'lun0':0, 'lun1':1, 'lun2':2}
def reset(self, key='-1', log_packets=False, report_progress=None) : def reset(self, key='-1', log_packets=False, report_progress=None) :
self._main_prefix = self._card_a_prefix = self._card_b_prefix = None self._main_prefix = self._card_a_prefix = self._card_b_prefix = None

View File

@ -211,7 +211,6 @@ def main(args=sys.argv):
OptionRecommendation.HIGH) \ OptionRecommendation.HIGH) \
for n in parser.options_iter() for n in parser.options_iter()
if n.dest] if n.dest]
print recommendations
plumber.merge_ui_recommendations(recommendations) plumber.merge_ui_recommendations(recommendations)
plumber.run() plumber.run()

View File

@ -6,8 +6,9 @@ __docformat__ = 'restructuredtext en'
import os import os
from calibre.customize.conversion import OutputFormatPlugin from calibre.customize.conversion import OutputFormatPlugin, \
from calibre.ebooks.pdb import PDBError, get_writer OptionRecommendation
from calibre.ebooks.pdb import PDBError, get_writer, FORMAT_WRITERS
class PDBOutput(OutputFormatPlugin): class PDBOutput(OutputFormatPlugin):
@ -15,20 +16,25 @@ class PDBOutput(OutputFormatPlugin):
author = 'John Schember' author = 'John Schember'
file_type = 'pdb' file_type = 'pdb'
options = set([
OptionRecommendation(name='format', recommended_value='doc',
level=OptionRecommendation.LOW,
short_switch='f', choices=FORMAT_WRITERS.keys(),
help=_('Format to use inside the pdb container. Choices are: '
'%s' % FORMAT_WRITERS.keys())),
])
def convert(self, oeb_book, output_path, input_plugin, opts, log): def convert(self, oeb_book, output_path, input_plugin, opts, log):
close = False close = False
if not hasattr(output_path, 'write'): if not hasattr(output_path, 'write'):
# Determine the format to write based upon the sub extension
format = os.path.splitext(os.path.splitext(output_path)[0])[1][1:]
close = True close = True
if not os.path.exists(os.path.dirname(output_path)) and os.path.dirname(output_path) != '': if not os.path.exists(os.path.dirname(output_path)) and os.path.dirname(output_path) != '':
os.makedirs(os.path.dirname(output_path)) os.makedirs(os.path.dirname(output_path))
out_stream = open(output_path, 'wb') out_stream = open(output_path, 'wb')
else: else:
format = os.path.splitext(os.path.splitext(output_path.name)[0])[1][1:]
out_stream = output_path out_stream = output_path
Writer = get_writer(format) Writer = get_writer(opts.format)
if Writer is None: if Writer is None:
raise PDBError('No writer avaliable for format %s.' % format) raise PDBError('No writer avaliable for format %s.' % format)

View File

@ -7,7 +7,7 @@ from PyQt4.Qt import QThread, SIGNAL, QMutex, QWaitCondition, Qt
from calibre.gui2.dialogs.progress import ProgressDialog from calibre.gui2.dialogs.progress import ProgressDialog
from calibre.constants import preferred_encoding from calibre.constants import preferred_encoding
from calibre.gui2.widgets import WarningDialog from calibre.gui2 import warning_dialog
class Add(QThread): class Add(QThread):
@ -113,13 +113,13 @@ class AddFiles(Add):
def process_duplicates(self): def process_duplicates(self):
if self.duplicates: if self.duplicates:
files = _('<p>Books with the same title as the following already ' files = ''
'exist in the database. Add them anyway?<ul>')
for mi in self.duplicates[2]: for mi in self.duplicates[2]:
files += '<li>'+mi.title+'</li>\n' files += mi.title+'\n'
d = WarningDialog (_('Duplicates found!'), d = warning_dialog(_('Duplicates found!'),
_('Duplicates found!'), _('Books with the same title as the following already '
files+'</ul></p>', parent=self._parent) 'exist in the database. Add them anyway?'),
files, parent=self._parent)
if d.exec_() == d.Accepted: if d.exec_() == d.Accepted:
num = self.db.add_books(*self.duplicates, num = self.db.add_books(*self.duplicates,
**dict(add_duplicates=True))[1] **dict(add_duplicates=True))[1]
@ -221,19 +221,19 @@ class AddRecursive(Add):
def process_duplicates(self): def process_duplicates(self):
if self.duplicates: if self.duplicates:
files = _('<p>Books with the same title as the following already ' files = ''
'exist in the database. Add them anyway?<ul>')
for mi in self.duplicates: for mi in self.duplicates:
title = mi[0].title title = mi[0].title
if not isinstance(title, unicode): if not isinstance(title, unicode):
title = title.decode(preferred_encoding, 'replace') title = title.decode(preferred_encoding, 'replace')
files += '<li>'+title+'</li>\n' files += title+'\n'
d = WarningDialog (_('Duplicates found!'), d = warning_dialog(_('Duplicates found!'),
_('Duplicates found!'), _('Books with the same title as the following already '
files+'</ul></p>', parent=self._parent) 'exist in the database. Add them anyway?'),
files, parent=self._parent)
if d.exec_() == d.Accepted: if d.exec_() == d.Accepted:
for mi, formats in self.duplicates: for mi, formats in self.duplicates:
self.db.import_book(mi, formats, notify=False) self.db.import_book(mi, formats, notify=False)
self.number_of_books_added += 1 self.number_of_books_added += 1

View File

@ -0,0 +1,116 @@
# -*- coding: utf-8 -*-
__license__ = 'GPL 3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
import sys
from PyQt4.Qt import QString, SIGNAL
from calibre.gui2.convert.single import Config, sort_formats_by_preference, \
GroupModel
from calibre.customize.ui import available_output_formats
from calibre.gui2 import ResizableDialog
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
from calibre.gui2.convert.page_setup import PageSetupWidget
from calibre.gui2.convert import GuiRecommendations
from calibre.ebooks.conversion.plumber import Plumber, OUTPUT_FORMAT_PREFERENCES
from calibre.utils.logging import Log
class BulkConfig(Config):
def __init__(self, parent, db, preferred_output_format=None):
ResizableDialog.__init__(self, parent)
self.setup_output_formats(db, preferred_output_format)
self.db = db
self.setup_pipeline()
self.input_formats.hide()
self.connect(self.output_formats, SIGNAL('currentIndexChanged(QString)'),
self.setup_pipeline)
self.connect(self.groups, SIGNAL('activated(QModelIndex)'),
self.show_pane)
self.connect(self.groups, SIGNAL('clicked(QModelIndex)'),
self.show_pane)
self.connect(self.groups, SIGNAL('entered(QModelIndex)'),
self.show_group_help)
self.groups.setMouseTracking(True)
def setup_pipeline(self, *args):
oidx = self.groups.currentIndex().row()
output_format = self.output_format
input_path = 'dummy.epub'
output_path = 'dummy.'+output_format
log = Log()
log.outputs = []
self.plumber = Plumber(input_path, output_path, log)
def widget_factory(cls):
return cls(self.stack, self.plumber.get_option_by_name,
self.plumber.get_option_help, self.db)
self.setWindowTitle(_('Bulk Convert'))
lf = widget_factory(LookAndFeelWidget)
ps = widget_factory(PageSetupWidget)
output_widget = None
name = 'calibre.gui2.convert.%s' % self.plumber.output_plugin.name.lower().replace(' ', '_')
try:
__import__(name)
output_widget = sys.modules[name]
pw = output_widget.PluginWidget
pw.ICON = ':/images/back.svg'
pw.HELP = _('Options specific to the output format.')
output_widget = widget_factory(pw)
except ImportError:
pass
while True:
c = self.stack.currentWidget()
if not c: break
self.stack.removeWidget(c)
widgets = [lf, ps]
if output_widget is not None:
widgets.append(output_widget)
for w in widgets:
self.stack.addWidget(w)
self.connect(w, SIGNAL('set_help(PyQt_PyObject)'),
self.help.setPlainText)
self._groups_model = GroupModel(widgets)
self.groups.setModel(self._groups_model)
idx = oidx if -1 < oidx < self._groups_model.rowCount() else 0
self.groups.setCurrentIndex(self._groups_model.index(idx))
def setup_output_formats(self, db, preferred_output_format):
available_formats = ''
available_formats = set([x.lower() for x in
available_formats.split(',')])
output_formats = sorted(available_output_formats())
output_formats.remove('oeb')
preferred_output_format = preferred_output_format if \
preferred_output_format in output_formats else \
sort_formats_by_preference(output_formats,
OUTPUT_FORMAT_PREFERENCES)[0]
self.output_formats.addItems(list(map(QString, [x.upper() for x in
output_formats])))
self.output_formats.setCurrentIndex(output_formats.index(preferred_output_format))
def accept(self):
recs = GuiRecommendations()
for w in self._groups_model.widgets:
x = w.commit(save_defaults=False)
recs.update(x)
self._recommendations = recs
ResizableDialog.accept(self)

View File

@ -4,8 +4,6 @@ __license__ = 'GPL 3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>' __copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import logging
from calibre.ebooks.conversion.plumber import Plumber from calibre.ebooks.conversion.plumber import Plumber
from calibre.utils.logging import Log from calibre.utils.logging import Log

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
__license__ = 'GPL 3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
from calibre.gui2.convert.pdb_output_ui import Ui_Form
from calibre.gui2.convert import Widget
from calibre.ebooks.pdb import FORMAT_WRITERS
from calibre.gui2.widgets import BasicComboModel
format_model = None
class PluginWidget(Widget, Ui_Form):
TITLE = _('PDB Output')
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
Widget.__init__(self, parent, 'pdb_output', ['format'])
self.db, self.book_id = db, book_id
self.initialize_options(get_option, get_help, db, book_id)
global format_model
if format_model is None:
format_model = BasicComboModel(FORMAT_WRITERS.keys())
self.format_model = format_model
self.opt_format.setModel(self.format_model)

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Format:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="opt_format"/>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>148</width>
<height>246</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -21,18 +21,12 @@ from calibre.gui2 import config, error_dialog, Dispatcher, dynamic, \
pixmap_to_data, warning_dialog, \ pixmap_to_data, warning_dialog, \
info_dialog info_dialog
from calibre.ebooks.metadata import authors_to_string from calibre.ebooks.metadata import authors_to_string
from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog
from calibre import sanitize_file_name, preferred_encoding from calibre import sanitize_file_name, preferred_encoding
from calibre.utils.filenames import ascii_filename from calibre.utils.filenames import ascii_filename
from calibre.devices.errors import FreeSpaceError from calibre.devices.errors import FreeSpaceError
from calibre.utils.smtp import compose_mail, sendmail, extract_email_address, \ from calibre.utils.smtp import compose_mail, sendmail, extract_email_address, \
config as email_config config as email_config
def warning(title, msg, details, parent):
from calibre.gui2.widgets import WarningDialog
WarningDialog(title, msg, details, parent).exec_()
class DeviceJob(Job): class DeviceJob(Job):
def __init__(self, func, *args, **kwargs): def __init__(self, func, *args, **kwargs):
@ -530,13 +524,13 @@ class DeviceGUI(object):
good.append(title) good.append(title)
if errors: if errors:
errors = '\n'.join([ errors = '\n'.join([
'<li><b>%s</b><br>%s<br>%s<br></li>' % '%s\n\n%s\n%s\n' %
(title, e, tb.replace('\n', '<br>')) for \ (title, e, tb) for \
title, e, tb in errors title, e, tb in errors
]) ])
ConversionErrorDialog(self, _('Failed to email books'), error_dialog(self, _('Failed to email books'),
'<p>'+_('Failed to email the following books:')+\ _('Failed to email the following books:'),
'<ul>%s</ul>'%errors, '%s'%errors,
show=True) show=True)
else: else:
self.status_bar.showMessage(_('Sent by email:') + ', '.join(good), self.status_bar.showMessage(_('Sent by email:') + ', '.join(good),

View File

@ -1,113 +0,0 @@
<ui version="4.0" >
<class>Dialog</class>
<widget class="QDialog" name="Dialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>727</width>
<height>432</height>
</rect>
</property>
<property name="windowTitle" >
<string>Dialog</string>
</property>
<property name="windowIcon" >
<iconset resource="../images.qrc" >
<normaloff>:/images/dialog_warning.svg</normaloff>:/images/dialog_warning.svg</iconset>
</property>
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="msg" >
<property name="text" >
<string>TextLabel</string>
</property>
<property name="wordWrap" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" >
<layout class="QHBoxLayout" name="horizontalLayout" >
<item>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QLabel" name="label" >
<property name="text" >
<string/>
</property>
<property name="pixmap" >
<pixmap resource="../images.qrc" >:/images/dialog_warning.svg</pixmap>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTextEdit" name="details" />
</item>
</layout>
</item>
<item row="2" column="0" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../images.qrc" />
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -24,7 +24,7 @@ from calibre.gui2 import APP_UID, warning_dialog, choose_files, error_dialog, \
max_available_height, config, info_dialog, \ max_available_height, config, info_dialog, \
available_width, GetMetadata available_width, GetMetadata
from calibre.gui2.cover_flow import CoverFlow, DatabaseImages, pictureflowerror from calibre.gui2.cover_flow import CoverFlow, DatabaseImages, pictureflowerror
from calibre.gui2.widgets import ProgressIndicator, WarningDialog from calibre.gui2.widgets import ProgressIndicator
from calibre.gui2.dialogs.scheduler import Scheduler from calibre.gui2.dialogs.scheduler import Scheduler
from calibre.gui2.update import CheckForUpdates from calibre.gui2.update import CheckForUpdates
from calibre.gui2.dialogs.progress import ProgressDialog from calibre.gui2.dialogs.progress import ProgressDialog
@ -36,8 +36,8 @@ from calibre.gui2.jobs2 import JobManager
from calibre.gui2.dialogs.metadata_single import MetadataSingleDialog from calibre.gui2.dialogs.metadata_single import MetadataSingleDialog
from calibre.gui2.dialogs.metadata_bulk import MetadataBulkDialog from calibre.gui2.dialogs.metadata_bulk import MetadataBulkDialog
from calibre.gui2.dialogs.jobs import JobsDialog from calibre.gui2.dialogs.jobs import JobsDialog
from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog from calibre.gui2.tools import convert_single_ebook, convert_bulk_ebook, \
from calibre.gui2.tools import convert_single_ebook, fetch_scheduled_recipe fetch_scheduled_recipe
from calibre.gui2.dialogs.config import ConfigDialog from calibre.gui2.dialogs.config import ConfigDialog
from calibre.gui2.dialogs.search import SearchDialog from calibre.gui2.dialogs.search import SearchDialog
from calibre.gui2.dialogs.choose_format import ChooseFormatDialog from calibre.gui2.dialogs.choose_format import ChooseFormatDialog
@ -89,7 +89,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.persistent_files = [] self.persistent_files = []
self.metadata_dialogs = [] self.metadata_dialogs = []
self.default_thumbnail = None self.default_thumbnail = None
self.device_error_dialog = ConversionErrorDialog(self, self.device_error_dialog = error_dialog(self, _('Error'),
_('Error communicating with device'), ' ') _('Error communicating with device'), ' ')
self.device_error_dialog.setModal(Qt.NonModal) self.device_error_dialog.setModal(Qt.NonModal)
self.tb_wrapper = textwrap.TextWrapper(width=40) self.tb_wrapper = textwrap.TextWrapper(width=40)
@ -865,16 +865,16 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
db = self.library_view.model().refresh_ids( db = self.library_view.model().refresh_ids(
x.updated, cr) x.updated, cr)
if x.failures: if x.failures:
details = ['<li><b>%s:</b> %s</li>'%(title, reason) for title, details = ['%s: %s'%(title, reason) for title,
reason in x.failures.values()] reason in x.failures.values()]
details = '<p><ul>%s</ul></p>'%(''.join(details)) details = '%s\n'%('\n'.join(details))
WarningDialog(_('Failed to download some metadata'), warning_dialog(_('Failed to download some metadata'),
_('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 = _('<b>Failed to download metadata:')+\
'</b><br><pre>'+x.tb+'</pre>' '</b><br><pre>'+x.tb+'</pre>'
ConversionErrorDialog(self, _('Error'), err, error_dialog(self, _('Error'), err,
show=True) show=True)
@ -1047,28 +1047,27 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
d = error_dialog(self, _('Cannot convert'), d = error_dialog(self, _('Cannot convert'),
_('No books selected')) _('No books selected'))
d.exec_() d.exec_()
return [], [] return None
return [self.library_view.model().db.id(r) for r in rows] return [self.library_view.model().db.id(r) for r in rows]
def convert_bulk(self, checked): def convert_bulk(self, checked):
r = self.get_books_for_conversion() row_ids = self.get_books_for_conversion()
if r is None: if row_ids is None: return
return previous = self.library_view.currentIndex()
comics, others = r rows = [x.row() for x in \
self.library_view.selectionModel().selectedRows()]
res = convert_bulk_ebooks(self, jobs, changed, bad = convert_bulk_ebook(self,
self.library_view.model().db, comics, others) self.library_view.model().db, row_ids)
if res is None:
return
jobs, changed = res
for func, args, desc, fmt, id, temp_files in jobs: for func, args, desc, fmt, id, temp_files in jobs:
job = self.job_manager.run_job(Dispatcher(self.book_converted), if id not in bad:
job = self.job_manager.run_job(Dispatcher(self.book_converted),
func, args=args, description=desc) func, args=args, description=desc)
self.conversion_jobs[job] = (temp_files, fmt, id) self.conversion_jobs[job] = (temp_files, fmt, id)
if changed: if changed:
self.library_view.model().resort(reset=False) self.library_view.model().refresh_rows(rows)
self.library_view.model().research() current = self.library_view.currentIndex()
self.library_view.model().current_changed(current, previous)
def convert_single(self, checked): def convert_single(self, checked):
row_ids = self.get_books_for_conversion() row_ids = self.get_books_for_conversion()
@ -1431,7 +1430,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
return return
if isinstance(job.exception, JobKilled): if isinstance(job.exception, JobKilled):
return return
ConversionErrorDialog(self, _('Conversion Error'), job.gui_text(), error_dialog(self, _('Conversion Error'), job.gui_text(),
show=True) show=True)

View File

@ -16,6 +16,7 @@ from calibre.gui2 import warning_dialog
from calibre.gui2.convert import load_specifics 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
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
@ -71,109 +72,59 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format
return jobs, changed, bad return jobs, changed, bad
def convert_bulk_ebooks(*args): def convert_bulk_ebook(parent, db, book_ids):
pass changed = False
#(fmt, parent, db, comics, others):
if others:
d = get_dialog(fmt)(parent, db)
if d.exec_() != QDialog.Accepted:
others, user_mi = [], None
else:
opts = d.opts
opts.verbose = 2
user_mi = d.user_mi
if comics:
comic_opts = ComicConf.get_bulk_conversion_options(parent)
if not comic_opts:
comics = []
bad_rows = []
jobs = [] jobs = []
total = sum(map(len, (others, comics))) bad = []
total = len(book_ids)
if total == 0: if total == 0:
return return None, None, None
parent.status_bar.showMessage(_('Starting Bulk conversion of %d books')%total, 2000) parent.status_bar.showMessage(_('Starting conversion of %d books') % total, 2000)
for i, row in enumerate(others+comics): d = BulkConfig(parent, db)
row_id = db.id(row) if d.exec_() != QDialog.Accepted:
if row in others: return jobs, changed, bad
data = None
for _fmt in EPUB_PREFERRED_SOURCE_FORMATS:
try:
data = db.format(row, _fmt.upper())
if data is not None:
break
except:
continue
if data is None:
bad_rows.append(row)
continue
options = opts.copy()
mi = db.get_metadata(row)
if user_mi is not None:
if user_mi.series_index == 1:
user_mi.series_index = None
mi.smart_update(user_mi)
db.set_metadata(db.id(row), mi)
opf = OPFCreator(os.getcwdu(), mi)
opf_file = PersistentTemporaryFile('.opf')
opf.render(opf_file)
opf_file.close()
pt = PersistentTemporaryFile('.'+_fmt.lower())
pt.write(data)
pt.close()
of = PersistentTemporaryFile('.'+fmt)
of.close()
cover = db.cover(row)
cf = None
if cover:
cf = PersistentTemporaryFile('.jpeg')
cf.write(cover)
cf.close()
options.cover = cf.name
options.output = of.name
options.from_opf = opf_file.name
args = [options, pt.name]
desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title))
temp_files = [cf] if cf is not None else []
temp_files.extend([opf_file, pt, of])
jobs.append(('any2'+fmt, args, desc, fmt.upper(), row_id, temp_files))
else:
options = comic_opts.copy()
mi = db.get_metadata(row)
if mi.title:
options.title = mi.title
if mi.authors:
options.author = ','.join(mi.authors)
data = None
for _fmt in ['cbz', 'cbr']:
try:
data = db.format(row, _fmt.upper())
if data is not None:
break
except:
continue
pt = PersistentTemporaryFile('.'+_fmt.lower()) output_format = d.output_format
pt.write(data) recs = cPickle.loads(d.recommendations)
pt.close()
of = PersistentTemporaryFile('.'+fmt)
of.close()
setattr(options, 'output', of.name)
options.verbose = 1
args = [pt.name, options]
desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title))
jobs.append(('comic2'+fmt, args, desc, fmt.upper(), row_id, [pt, of]))
if bad_rows: for i, book_id in enumerate(book_ids):
temp_files = []
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))
changed = True
except NoSupportedInputFormats:
bad.append(book_id)
if bad != []:
res = [] res = []
for row in bad_rows: for id in bad:
title = db.title(row) title = db.title(id, True)
res.append('<li>%s</li>'%title) res.append('%s'%title)
msg = _('<p>Could not convert %d of %d books, because no suitable source format was found.<ul>%s</ul>')%(len(res), total, '\n'.join(res)) msg = '%s' % '\n'.join(res)
warning_dialog(parent, _('Could not convert some books'), msg).exec_() warning_dialog(parent, _('Could not convert some books'),
_('Could not convert %d of %d books, because no suitable source format was found.' % (len(res), total)),
msg).exec_()
return jobs, False return jobs, changed, bad
def _fetch_news(data, fmt): def _fetch_news(data, fmt):
pt = PersistentTemporaryFile(suffix='_feeds2%s.%s'%(fmt.lower(), fmt.lower())) pt = PersistentTemporaryFile(suffix='_feeds2%s.%s'%(fmt.lower(), fmt.lower()))

View File

@ -19,7 +19,6 @@ from calibre import fit_image
from calibre.utils.fontconfig import find_font_families from calibre.utils.fontconfig import find_font_families
from calibre.ebooks.metadata.meta import metadata_from_filename from calibre.ebooks.metadata.meta import metadata_from_filename
from calibre.utils.config import prefs from calibre.utils.config import prefs
from calibre.gui2.dialogs.warning_ui import Ui_Dialog as Ui_WarningDialog
class ProgressIndicator(QWidget): class ProgressIndicator(QWidget):
@ -56,16 +55,6 @@ class ProgressIndicator(QWidget):
self.movie.setPaused(True) self.movie.setPaused(True)
self.setVisible(False) self.setVisible(False)
class WarningDialog(QDialog, Ui_WarningDialog):
def __init__(self, title, msg, details, parent=None):
QDialog.__init__(self, parent)
self.setupUi(self)
self.setWindowTitle(title)
self.msg.setText(msg)
self.details.setText(details)
class FilenamePattern(QWidget, Ui_Form): class FilenamePattern(QWidget, Ui_Form):
def __init__(self, parent): def __init__(self, parent):
@ -305,6 +294,31 @@ class FontFamilyModel(QAbstractListModel):
def index_of(self, family): def index_of(self, family):
return self.families.index(family.strip()) return self.families.index(family.strip())
class BasicComboModel(QAbstractListModel):
def __init__(self, items, *args):
QAbstractListModel.__init__(self, *args)
self.items = [i for i in items]
self.items.sort()
def rowCount(self, *args):
return len(self.items)
def data(self, index, role):
try:
item = self.items[index.row()]
except:
traceback.print_exc()
return NONE
if role == Qt.DisplayRole:
return QVariant(item)
if role == Qt.FontRole:
return QVariant(QFont(item))
return NONE
def index_of(self, item):
return self.items.index(item.strip())
class BasicListItem(QListWidgetItem): class BasicListItem(QListWidgetItem):