From b52620748e21211df76551ec6993f7930f04fdfb Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 13 Sep 2009 10:27:36 -0600 Subject: [PATCH] IGN:Clean up conversion queueing code and add feedback while calibre is queueing bulk conversions --- src/calibre/gui2/main.py | 124 ++++----------- src/calibre/gui2/tools.py | 85 +++++++---- src/calibre/translations/calibre.pot | 220 ++++++++++++++------------- 3 files changed, 198 insertions(+), 231 deletions(-) diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 59047c92dd..813cd1f48b 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -1155,16 +1155,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): self.library_view.selectionModel().selectedRows()] jobs, changed, bad = convert_single_ebook(self, self.library_view.model().db, book_ids, True, format) if jobs == []: return - for func, args, desc, fmt, id, temp_files in jobs: - if id not in bad: - job = self.job_manager.run_job(Dispatcher(self.book_auto_converted), - func, args=args, description=desc) - self.conversion_jobs[job] = (temp_files, fmt, id, on_card) - - if changed: - self.library_view.model().refresh_rows(rows) - current = self.library_view.currentIndex() - self.library_view.model().current_changed(current, previous) + self.queue_convert_jobs(jobs, changed, bad, rows, previous, + self.book_auto_converted, extra_job_args=[on_card]) def auto_convert_mail(self, to, fmts, delete_from_library, book_ids, format): previous = self.library_view.currentIndex() @@ -1172,17 +1164,9 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): self.library_view.selectionModel().selectedRows()] jobs, changed, bad = convert_single_ebook(self, self.library_view.model().db, book_ids, True, format) if jobs == []: return - for func, args, desc, fmt, id, temp_files in jobs: - if id not in bad: - job = self.job_manager.run_job(Dispatcher(self.book_auto_converted_mail), - func, args=args, description=desc) - self.conversion_jobs[job] = (temp_files, fmt, id, - delete_from_library, to, fmts) - - if changed: - self.library_view.model().refresh_rows(rows) - current = self.library_view.currentIndex() - self.library_view.model().current_changed(current, previous) + self.queue_convert_jobs(jobs, changed, bad, rows, previous, + self.book_auto_converted_mail, + extra_job_args=[delete_from_library, to, fmts]) def auto_convert_news(self, book_ids, format): previous = self.library_view.currentIndex() @@ -1190,17 +1174,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): self.library_view.selectionModel().selectedRows()] jobs, changed, bad = convert_single_ebook(self, self.library_view.model().db, book_ids, True, format) if jobs == []: return - for func, args, desc, fmt, id, temp_files in jobs: - if id not in bad: - job = self.job_manager.run_job(Dispatcher(self.book_auto_converted_news), - func, args=args, description=desc) - self.conversion_jobs[job] = (temp_files, fmt, id) - - if changed: - self.library_view.model().refresh_rows(rows) - current = self.library_view.currentIndex() - self.library_view.model().current_changed(current, previous) - + self.queue_convert_jobs(jobs, changed, bad, rows, previous, + self.book_auto_converted_news) def get_books_for_conversion(self): rows = [r.row() for r in \ @@ -1219,16 +1194,24 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): rows = [x.row() for x in \ self.library_view.selectionModel().selectedRows()] if bulk or (bulk is None and len(book_ids) > 1): - jobs, changed, bad = convert_bulk_ebook(self, - self.library_view.model().db, book_ids, out_format=prefs['output_format']) + self.__bulk_queue = convert_bulk_ebook(self, self.queue_convert_jobs, + self.library_view.model().db, book_ids, + out_format=prefs['output_format'], args=(rows, previous, + self.book_converted)) else: jobs, changed, bad = convert_single_ebook(self, self.library_view.model().db, book_ids, out_format=prefs['output_format']) + self.queue_convert_jobs(jobs, changed, bad, rows, previous, + self.book_converted) + + def queue_convert_jobs(self, jobs, changed, bad, rows, previous, + converted_func, extra_job_args=[]): for func, args, desc, fmt, id, temp_files in jobs: if id not in bad: - job = self.job_manager.run_job(Dispatcher(self.book_converted), + job = self.job_manager.run_job(Dispatcher(converted_func), func, args=args, description=desc) - self.conversion_jobs[job] = (temp_files, fmt, id) + args = [temp_files, fmt, id]+extra_job_args + self.conversion_jobs[job] = tuple(args) if changed: self.library_view.model().refresh_rows(rows) @@ -1236,77 +1219,22 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): self.library_view.model().current_changed(current, previous) def book_auto_converted(self, job): - temp_files, fmt, book_id, on_card = self.conversion_jobs.pop(job) - try: - if job.failed: - return self.job_exception(job) - data = open(temp_files[-1].name, 'rb') - self.library_view.model().db.add_format(book_id, fmt, data, index_is_id=True) - data.close() - self.status_bar.showMessage(job.description + (' completed'), 2000) - finally: - for f in temp_files: - try: - if os.path.exists(f.name): - os.remove(f.name) - except: - pass - self.tags_view.recount() - if self.current_view() is self.library_view: - current = self.library_view.currentIndex() - self.library_view.model().current_changed(current, QModelIndex()) - + temp_files, fmt, book_id, on_card = self.conversion_jobs[job] + self.book_converted(job) self.sync_to_device(on_card, False, specific_format=fmt, send_ids=[book_id], do_auto_convert=False) def book_auto_converted_mail(self, job): - temp_files, fmt, book_id, delete_from_library, to, fmts = self.conversion_jobs.pop(job) - try: - if job.failed: - self.job_exception(job) - return - data = open(temp_files[-1].name, 'rb') - self.library_view.model().db.add_format(book_id, fmt, data, index_is_id=True) - data.close() - self.status_bar.showMessage(job.description + (' completed'), 2000) - finally: - for f in temp_files: - try: - if os.path.exists(f.name): - os.remove(f.name) - except: - pass - self.tags_view.recount() - if self.current_view() is self.library_view: - current = self.library_view.currentIndex() - self.library_view.model().current_changed(current, QModelIndex()) - + temp_files, fmt, book_id, delete_from_library, to, fmts = self.conversion_jobs[job] + self.book_converted(job) self.send_by_mail(to, fmts, delete_from_library, specific_format=fmt, send_ids=[book_id], do_auto_convert=False) def book_auto_converted_news(self, job): - temp_files, fmt, book_id = self.conversion_jobs.pop(job) - try: - if job.failed: - return self.job_exception(job) - data = open(temp_files[-1].name, 'rb') - self.library_view.model().db.add_format(book_id, fmt, data, index_is_id=True) - data.close() - self.status_bar.showMessage(job.description + (' completed'), 2000) - finally: - for f in temp_files: - try: - if os.path.exists(f.name): - os.remove(f.name) - except: - pass - self.tags_view.recount() - if self.current_view() is self.library_view: - current = self.library_view.currentIndex() - self.library_view.model().current_changed(current, QModelIndex()) - + temp_files, fmt, book_id = self.conversion_jobs[job] + self.book_converted(job) self.sync_news(send_ids=[book_id], do_auto_convert=False) def book_converted(self, job): - temp_files, fmt, book_id = self.conversion_jobs.pop(job) + temp_files, fmt, book_id = self.conversion_jobs.pop(job)[:3] try: if job.failed: self.job_exception(job) diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index 76c57d676c..8ffaceaa64 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -9,7 +9,7 @@ Logic for setting up conversion jobs import cPickle -from PyQt4.Qt import QDialog +from PyQt4.Qt import QDialog, QProgressDialog, QString, QTimer, SIGNAL from calibre.ptempfile import PersistentTemporaryFile from calibre.gui2 import warning_dialog, question_dialog @@ -94,7 +94,7 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format return jobs, changed, bad -def convert_bulk_ebook(parent, db, book_ids, out_format=None): +def convert_bulk_ebook(parent, queue, db, book_ids, out_format=None, args=[]): changed = False jobs = [] bad = [] @@ -112,32 +112,55 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None): user_recs = cPickle.loads(d.recommendations) book_ids = convert_existing(parent, db, book_ids, output_format) - for i, book_id in enumerate(book_ids): + return QueueBulk(parent, book_ids, output_format, queue, db, user_recs, args) + +class QueueBulk(QProgressDialog): + + def __init__(self, parent, book_ids, output_format, queue, db, user_recs, args): + QProgressDialog.__init__(self, '', + QString(), 0, len(book_ids), parent) + self.setWindowTitle(_('Queueing books for bulk conversion')) + self.book_ids, self.output_format, self.queue, self.db, self.args, self.user_recs = \ + book_ids, output_format, queue, db, args, user_recs + self.parent = parent + self.i, self.bad, self.jobs, self.changed = 0, [], [], False + self.timer = QTimer(self) + self.connect(self.timer, SIGNAL('timeout()'), self.do_book) + self.timer.start() + self.exec_() + + def do_book(self): + if self.i >= len(self.book_ids): + self.timer.stop() + return self.do_queue() + book_id = self.book_ids[self.i] + self.i += 1 + temp_files = [] - input_format = get_input_format_for_book(db, book_id, None)[0] try: - mi, opf_file = create_opf_file(db, book_id) - in_file = db.format_abspath(book_id, input_format, True) + input_format = get_input_format_for_book(self.db, book_id, None)[0] + mi, opf_file = create_opf_file(self.db, book_id) + in_file = self.db.format_abspath(book_id, input_format, True) - out_file = PersistentTemporaryFile('.' + output_format) - out_file.write(output_format) + out_file = PersistentTemporaryFile('.' + self.output_format) + out_file.write(self.output_format) out_file.close() temp_files = [] combined_recs = GuiRecommendations() default_recs = load_defaults('%s_input' % input_format) - specific_recs = load_specifics(db, book_id) + specific_recs = load_specifics(self.db, book_id) for key in default_recs: combined_recs[key] = default_recs[key] for key in specific_recs: combined_recs[key] = specific_recs[key] - for item in user_recs: + for item in self.user_recs: combined_recs[item[0]] = item[1] - save_specifics(db, book_id, combined_recs) + save_specifics(self.db, book_id, combined_recs) lrecs = list(combined_recs.to_recommendations()) - cover_file = create_cover_file(db, book_id) + cover_file = create_cover_file(self.db, book_id) if opf_file is not None: lrecs.append(('read_metadata_from_opf', opf_file.name, @@ -156,30 +179,34 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None): dtitle = unicode(mi.title) except: dtitle = repr(mi.title) - desc = _('Convert book %d of %d (%s)') % (i + 1, total, dtitle) + self.setLabelText(_('Queueing ')+dtitle) + desc = _('Convert book %d of %d (%s)') % (self.i, len(self.book_ids), dtitle) args = [in_file, out_file.name, lrecs] temp_files.append(out_file) - jobs.append(('gui_convert', args, desc, output_format.upper(), book_id, temp_files)) + self.jobs.append(('gui_convert', args, desc, self.output_format.upper(), book_id, temp_files)) - changed = True + self.changed = True + self.setValue(self.i) except NoSupportedInputFormats: - bad.append(book_id) + self.bad.append(book_id) - if bad != []: - res = [] - for id in bad: - title = db.title(id, True) - res.append('%s'%title) + def do_queue(self): + self.hide() + if self.bad != []: + res = [] + for id in self.bad: + title = self.db.title(id, True) + res.append('%s'%title) - msg = '%s' % '\n'.join(res) - 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_() - - jobs.reverse() - return jobs, changed, bad + msg = '%s' % '\n'.join(res) + warning_dialog(self.parent, _('Could not convert some books'), + _('Could not convert %d of %d books, because no suitable ' + 'source format was found.') % (len(res), len(self.book_ids)), + msg).exec_() + self.parent = None + self.jobs.reverse() + self.queue(self.jobs, self.changed, self.bad, *self.args) def fetch_scheduled_recipe(recipe, script): from calibre.gui2.dialogs.scheduler import config diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index a33e94cdb2..50c5852ac0 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.6.12\n" -"POT-Creation-Date: 2009-09-11 15:00+MDT\n" -"PO-Revision-Date: 2009-09-11 15:00+MDT\n" +"POT-Creation-Date: 2009-09-13 10:26+MDT\n" +"PO-Revision-Date: 2009-09-13 10:26+MDT\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -29,8 +29,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/comic/input.py:403 #: /home/kovid/work/calibre/src/calibre/ebooks/fb2/input.py:65 #: /home/kovid/work/calibre/src/calibre/ebooks/fb2/input.py:67 -#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:317 -#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:320 +#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:318 +#: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:321 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1895 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1897 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/output.py:24 @@ -99,9 +99,9 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/add.py:111 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:118 #: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:21 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:81 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:106 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:108 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:99 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:124 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:126 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:539 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:548 #: /home/kovid/work/calibre/src/calibre/gui2/device.py:765 @@ -976,7 +976,7 @@ msgid "Normally this input plugin re-arranges all the input files into a standar msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/html/input.py:266 -msgid "Average line length for line breaking if the HTML is from a previous partial conversion of a PDF file. Default is %default." +msgid "Average line length for line breaking if the HTML is from a previous partial conversion of a PDF file. Default is %default which disables this." msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/lit/from_any.py:47 @@ -2001,7 +2001,7 @@ msgid "Bulk Convert" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/bulk.py:73 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/single.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/single.py:177 msgid "Options specific to the output format." msgstr "" @@ -2339,43 +2339,43 @@ msgstr "" msgid "&Monospaced font family:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:23 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:41 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:145 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:169 msgid "Metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:25 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:43 msgid "Set the metadata. The output file will contain as much of this metadata as possible." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:152 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:95 msgid "Choose cover for " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:141 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:159 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:102 msgid "Cannot read" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:142 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:160 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:103 msgid "You do not have permission to read the file: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:150 -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:157 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:168 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:175 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:111 msgid "Error reading file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:151 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:169 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:112 msgid "

There was an error reading from file:
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:158 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:176 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:120 msgid " is not a valid picture" msgstr "" @@ -2571,7 +2571,7 @@ msgid "RB Output" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/convert/regex_builder.py:76 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1385 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1313 msgid "Choose the format to view" msgstr "" @@ -2603,11 +2603,11 @@ msgstr "" msgid "Regex:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/single.py:139 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/single.py:163 msgid "Convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/convert/single.py:164 +#: /home/kovid/work/calibre/src/calibre/gui2/convert/single.py:188 msgid "Options specific to the input format." msgstr "" @@ -2860,7 +2860,7 @@ msgid "

For example, to match all h2 tags that have class=\"chapter\", set tag msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/device.py:39 -#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:129 +#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:130 msgid "No details available." msgstr "" @@ -3184,7 +3184,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:788 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:140 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:1004 -#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:52 +#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:53 msgid "Error" msgstr "" @@ -3712,18 +3712,22 @@ msgstr "" msgid "Details of job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:41 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:44 msgid "Active Jobs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:42 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:45 msgid "&Stop selected job" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:43 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:46 msgid "Show job &details" msgstr "" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:47 +msgid "Stop &all jobs" +msgstr "" + #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:133 msgid "Edit Meta information" msgstr "" @@ -4474,11 +4478,11 @@ msgstr "" msgid "Job has already run" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:215 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:221 msgid "Unavailable" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:226 +#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:232 msgid " - Jobs" msgstr "" @@ -4673,7 +4677,7 @@ msgid "Save to disk in a single directory" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/main.py:280 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1487 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1415 msgid "Save only %s format to disk" msgstr "" @@ -4713,7 +4717,7 @@ msgid "Calibre Library" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/main.py:437 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1630 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1558 msgid "Choose a location for your ebook library." msgstr "" @@ -4817,7 +4821,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/main.py:1015 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:1048 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:1073 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1210 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1185 msgid "No books selected" msgstr "" @@ -4883,162 +4887,162 @@ msgstr "" msgid " fetched." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1209 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1184 msgid "Cannot convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1379 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1398 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1307 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1326 msgid "No book selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1379 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1429 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1307 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1357 msgid "Cannot view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1397 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1325 msgid "Cannot open folder" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1414 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1342 msgid "Multiple Books Selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1415 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1343 msgid "You are attempting to open %d books. Opening too many books at once can be slow and have a negative effect on the responsiveness of your computer. Once started the process cannot be stopped until complete. Do you wish to continue?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1430 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1358 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1471 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1399 msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1472 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1400 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1515 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1443 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1516 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1444 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1568 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1496 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1569 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1497 msgid "There was a temporary error talking to the device. Please unplug and reconnect the device and or reboot." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1592 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1610 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1520 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1538 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1593 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1521 msgid "

Could not convert: %s

It is a DRMed book. You must first remove the DRM using third party tools." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1611 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1539 msgid "Failed" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1639 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1567 msgid "Invalid library location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1640 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1568 msgid "Could not access %s. Using %s as the library." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1687 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1615 msgid "is the result of the efforts of many volunteers from all over the world. If you find it useful, please consider donating to support its development." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1711 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1639 msgid "There are active jobs. Are you sure you want to quit?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1714 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1642 msgid "" " is communicating with the device!
\n" " Quitting may cause corruption on the device.
\n" " Are you sure you want to quit?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1718 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1646 msgid "WARNING: Active jobs" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1769 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1697 msgid "will keep running in the system tray. To close it, choose Quit in the context menu of the system tray." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1788 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1716 msgid "Latest version: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1796 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1724 msgid "Update available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1797 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1725 msgid "%s has been updated to version %s. See the new features. Visit the download page?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1815 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1743 msgid "Use the library located at the specified path." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1817 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1745 msgid "Start minimized to system tray." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1819 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1747 msgid "Log debugging information to console" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1821 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1749 msgid "Do not check for updates" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1869 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1797 msgid "If you are sure it is not running" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1871 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1799 msgid "Cannot Start " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1872 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1800 msgid "%s is already running." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1875 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1803 msgid "may be running in the system tray, in the" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1877 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1805 msgid "upper right region of the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1879 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1807 msgid "lower right region of the screen." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1882 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1810 msgid "try rebooting your computer." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1884 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1896 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1812 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1824 msgid "try deleting the file" msgstr "" @@ -5224,39 +5228,47 @@ msgstr "" msgid "Publishers" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:32 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:103 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:34 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:105 msgid "Starting conversion of %d books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:62 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:153 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:64 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:183 msgid "Convert book %d of %d (%s)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:88 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:170 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:90 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:203 msgid "Could not convert some books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:89 -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:171 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:91 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:204 msgid "Could not convert %d of %d books, because no suitable source format was found." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:202 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:122 +msgid "Queueing books for bulk conversion" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:182 +msgid "Queueing " +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:236 msgid "You must set a username and password for %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:207 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:241 msgid "Fetch news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:218 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:252 msgid "Convert existing" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:253 msgid "The following books have already been converted to %s format. Do you wish to reconvert them?" msgstr "" @@ -6235,72 +6247,72 @@ msgid "" "Start the calibre content server." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:43 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:45 msgid "" "%sUsage%s: %s\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:87 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:89 msgid "Created by " msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:88 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:90 msgid "Whenever you pass arguments to %prog that have spaces in them, enclose the arguments in quotation marks." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:551 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:553 msgid "Path to the database in which books are stored" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:553 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:555 msgid "Pattern to guess metadata from filenames" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:555 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:557 msgid "Access key for isbndb.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:557 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:559 msgid "Default timeout for network operations (seconds)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:559 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:561 msgid "Path to directory in which your library of books is stored" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:561 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:563 msgid "The language in which to display the user interface" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:563 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:565 msgid "The default output format for ebook conversions." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:567 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:569 msgid "Ordered list of formats to prefer for input." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:569 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:571 msgid "Read metadata from files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/config.py:571 +#: /home/kovid/work/calibre/src/calibre/utils/config.py:573 msgid "The priority of worker processes" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:42 +#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:43 msgid "Waiting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:50 +#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:51 msgid "Stopped" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:52 +#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:53 msgid "Finished" msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:69 +#: /home/kovid/work/calibre/src/calibre/utils/ipc/job.py:70 msgid "Working..." msgstr "" @@ -6471,12 +6483,12 @@ msgid "sr-Latn-RS" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/web/feeds/recipes/recipe_le_monde.py:81 +#: /home/kovid/work/calibre/src/calibre/web/feeds/recipes/recipe_le_monde.py:108 msgid "Skipping duplicated article: %s" msgstr "" #: -#: /home/kovid/work/calibre/src/calibre/web/feeds/recipes/recipe_le_monde.py:86 +#: /home/kovid/work/calibre/src/calibre/web/feeds/recipes/recipe_le_monde.py:113 msgid "Skipping filtered article: %s" msgstr ""