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 ""