Fix memory leak when queueing books for bulk convert

This commit is contained in:
Kovid Goyal 2009-09-12 15:44:25 -06:00
parent a4dd30cea5
commit a1b42542e1
3 changed files with 68 additions and 41 deletions

View File

@ -18,6 +18,24 @@ from calibre.ebooks.metadata.opf2 import OPFCreator
from calibre.ptempfile import PersistentTemporaryFile
from calibre.gui2.convert import Widget
def create_opf_file(db, book_id):
mi = db.get_metadata(book_id, index_is_id=True)
mi.application_id = uuid.uuid4()
opf = OPFCreator(os.getcwdu(), mi)
opf_file = PersistentTemporaryFile('.opf')
opf.render(opf_file)
opf_file.close()
return mi, opf_file
def create_cover_file(db, book_id):
cover = db.cover(book_id, index_is_id=True)
cf = None
if cover:
cf = PersistentTemporaryFile('.jpeg')
cf.write(cover)
cf.close()
return cf
class MetadataWidget(Widget, Ui_Form):
TITLE = _('Metadata')
@ -181,12 +199,7 @@ class MetadataWidget(Widget, Ui_Form):
self.cover_file = self.opf_file = None
if self.db is not None:
self.db.set_metadata(self.book_id, self.user_mi)
self.mi = self.db.get_metadata(self.book_id, index_is_id=True)
self.mi.application_id = uuid.uuid4()
opf = OPFCreator(os.getcwdu(), self.mi)
self.opf_file = PersistentTemporaryFile('.opf')
opf.render(self.opf_file)
self.opf_file.close()
self.mi, self.opf_file = create_opf_file(self.db, self.book_id)
if self.cover_changed and self.cover_data is not None:
self.db.set_cover(self.book_id, self.cover_data)
cover = self.db.cover(self.book_id, index_is_id=True)

View File

@ -68,6 +68,36 @@ class GroupModel(QAbstractListModel):
return QVariant(f)
return NONE
def get_preferred_input_format_for_book(db, book_id):
recs = load_specifics(db, book_id)
if recs:
return recs.get('gui_preferred_input_format', None)
def get_available_formats_for_book(db, book_id):
available_formats = db.formats(book_id, index_is_id=True)
if not available_formats:
available_formats = ''
return set([x.lower() for x in
available_formats.split(',')])
def get_supported_input_formats_for_book(db, book_id):
available_formats = get_available_formats_for_book(db, book_id)
input_formats = set([x.lower() for x in supported_input_formats()])
input_formats = sorted(available_formats.intersection(input_formats))
if not input_formats:
raise NoSupportedInputFormats
return input_formats
def get_input_format_for_book(db, book_id, pref):
if pref is None:
pref = get_preferred_input_format_for_book(db, book_id)
input_formats = get_supported_input_formats_for_book(db, book_id)
input_format = pref if pref in input_formats else \
sort_formats_by_preference(input_formats, prefs['input_format_order'])[0]
return input_format, input_formats
class Config(ResizableDialog, Ui_Dialog):
'''
Configuration dialog for single book conversion. If accepted, has the
@ -86,12 +116,6 @@ class Config(ResizableDialog, Ui_Dialog):
preferred_input_format=None, preferred_output_format=None):
ResizableDialog.__init__(self, parent)
if preferred_input_format is None and db is not None:
recs = load_specifics(db, book_id)
if recs:
preferred_input_format = recs.get('gui_preferred_input_format',
None)
self.setup_input_output_formats(db, book_id, preferred_input_format,
preferred_output_format)
self.db, self.book_id = db, book_id
@ -194,22 +218,10 @@ class Config(ResizableDialog, Ui_Dialog):
preferred_output_format):
if preferred_output_format:
preferred_output_format = preferred_output_format.lower()
available_formats = db.formats(book_id, index_is_id=True)
if not available_formats:
available_formats = ''
available_formats = set([x.lower() for x in
available_formats.split(',')])
input_formats = set([x.lower() for x in supported_input_formats()])
input_formats = \
sorted(available_formats.intersection(input_formats))
if not input_formats:
raise NoSupportedInputFormats
output_formats = sorted(available_output_formats())
output_formats.remove('oeb')
preferred_input_format = preferred_input_format if \
preferred_input_format in input_formats else \
sort_formats_by_preference(input_formats,
prefs['input_format_order'])[0]
input_format, input_formats = get_input_format_for_book(db, book_id,
preferred_input_format)
preferred_output_format = preferred_output_format if \
preferred_output_format in output_formats else \
sort_formats_by_preference(output_formats,
@ -218,7 +230,7 @@ class Config(ResizableDialog, Ui_Dialog):
input_formats])))
self.output_formats.addItems(list(map(QString, [x.upper() for x in
output_formats])))
self.input_formats.setCurrentIndex(input_formats.index(preferred_input_format))
self.input_formats.setCurrentIndex(input_formats.index(input_format))
self.output_formats.setCurrentIndex(output_formats.index(preferred_output_format))
def show_pane(self, index):

View File

@ -14,8 +14,10 @@ from PyQt4.Qt import QDialog
from calibre.ptempfile import PersistentTemporaryFile
from calibre.gui2 import warning_dialog, question_dialog
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, \
get_input_format_for_book
from calibre.gui2.convert.bulk import BulkConfig
from calibre.gui2.convert.metadata import create_opf_file, create_cover_file
from calibre.customize.conversion import OptionRecommendation
from calibre.utils.config import prefs
from calibre.ebooks.conversion.config import GuiRecommendations, \
@ -112,13 +114,11 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
book_ids = convert_existing(parent, db, book_ids, output_format)
for i, book_id in enumerate(book_ids):
temp_files = []
input_format = get_input_format_for_book(db, book_id, None)[0]
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)
mi, opf_file = create_opf_file(db, book_id)
in_file = db.format_abspath(book_id, input_format, True)
out_file = PersistentTemporaryFile('.' + output_format)
out_file.write(output_format)
@ -126,7 +126,7 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
temp_files = []
combined_recs = GuiRecommendations()
default_recs = load_defaults('%s_input' % d.input_format)
default_recs = load_defaults('%s_input' % input_format)
specific_recs = load_specifics(db, book_id)
for key in default_recs:
combined_recs[key] = default_recs[key]
@ -137,14 +137,16 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
save_specifics(db, book_id, combined_recs)
lrecs = list(combined_recs.to_recommendations())
if d.opf_file is not None:
lrecs.append(('read_metadata_from_opf', d.opf_file.name,
cover_file = create_cover_file(db, book_id)
if opf_file is not None:
lrecs.append(('read_metadata_from_opf', opf_file.name,
OptionRecommendation.HIGH))
temp_files.append(d.opf_file)
if d.cover_file is not None:
lrecs.append(('cover', d.cover_file.name,
temp_files.append(opf_file)
if cover_file is not None:
lrecs.append(('cover', cover_file.name,
OptionRecommendation.HIGH))
temp_files.append(d.cover_file)
temp_files.append(cover_file)
for x in list(lrecs):
if x[0] == 'debug_pipeline':
@ -158,7 +160,7 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
args = [in_file, out_file.name, lrecs]
temp_files.append(out_file)
jobs.append(('gui_convert', args, desc, d.output_format.upper(), book_id, temp_files))
jobs.append(('gui_convert', args, desc, output_format.upper(), book_id, temp_files))
changed = True
except NoSupportedInputFormats: