diff --git a/src/calibre/ebooks/fb2/fb2ml.py b/src/calibre/ebooks/fb2/fb2ml.py index 0c0a4fb3f3..96c9e43676 100644 --- a/src/calibre/ebooks/fb2/fb2ml.py +++ b/src/calibre/ebooks/fb2/fb2ml.py @@ -119,11 +119,11 @@ class FB2MLizer(object): for item in elem: fb2_text += self.dump_text(item, stylizer, tag_stack) - close_tags = [] + close_tag_list = [] for i in range(0, tag_count): - close_tags.insert(0, tag_stack.pop()) + close_tag_list.insert(0, tag_stack.pop()) - fb2_text += self.close_tags(close_tags) + fb2_text += self.close_tags(close_tag_list) if hasattr(elem, 'tail') and elem.tail != None and elem.tail.strip() != '': if 'p' not in tag_stack: diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index b3dcf8a21c..a22703c748 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -463,15 +463,20 @@ class DeviceGUI(object): fmts = [x.strip().lower() for x in fmts.split(',')] self.send_by_mail(to, fmts, delete) - def send_by_mail(self, to, fmts, delete_from_library): - rows = self.library_view.selectionModel().selectedRows() - if not rows or len(rows) == 0: + def send_by_mail(self, to, fmts, delete_from_library, send_ids=None, do_auto_convert=True): + ids = [self.library_view.model().id(r) for r in self.library_view.selectionModel().selectedRows()] if send_ids is None else send_ids + if not ids or len(ids) == 0: return - ids = iter(self.library_view.model().id(r) for r in rows) + files, _auto_ids = self.library_view.model().get_preferred_formats_from_ids(ids, + fmts, paths=True, set_metadata=True, + exclude_auto=do_auto_convert) + if do_auto_convert: + ids = list(set(ids).difference(_auto_ids)) + else: + _auto_ids = [] + full_metadata = self.library_view.model().get_metadata( - rows, full_metadata=True)[-1] - files = self.library_view.model().get_preferred_formats(rows, - fmts, paths=True, set_metadata=True) + ids, full_metadata=True, rows_are_ids=True)[-1] files = [getattr(f, 'name', None) for f in files] bad, remove_ids, jobnames = [], [], [] @@ -506,6 +511,38 @@ class DeviceGUI(object): attachments, to_s, subjects, texts, attachment_names) self.status_bar.showMessage(_('Sending email to')+' '+to, 3000) + auto = [] + if _auto_ids != []: + for id in _auto_ids: + if specific_format == None: + formats = [f.lower() for f in self.library_view.model().db.formats(id, index_is_id=True).split(',')] + formats = formats if formats != None else [] + if list(set(formats).intersection(available_input_formats())) != [] and list(set(fmts).intersection(available_output_formats())) != []: + auto.append(id) + else: + bad.append(self.library_view.model().db.title(id, index_is_id=True)) + else: + if specific_format in available_output_formats(): + auto.append(id) + else: + bad.append(self.library_view.model().db.title(id, index_is_id=True)) + + if auto != []: + format = None + for fmt in fmts: + if fmt in list(set(fmts).intersection(set(available_output_formats()))): + format = fmt + break + if format is None: + bad += auto + else: + autos = [self.library_view.model().db.title(id, index_is_id=True) for id in auto] + autos = '\n'.join('
  • %s
  • '%(i,) for i in autos) + d = info_dialog(self, _('No suitable formats'), + _('Auto converting the following books before uploading to the device:
    ')%(autos,)) + d.exec_() + self.auto_convert_mail(to, delete_from_library, auto, format) + if bad: bad = '\n'.join('%s'%(i,) for i in bad) d = warning_dialog(self, _('No suitable formats'), @@ -691,7 +728,7 @@ class DeviceGUI(object): d = info_dialog(self, _('No suitable formats'), _('Auto converting the following books before uploading to the device:
    ')%(autos,)) d.exec_() - self.auto_convert(_auto_ids, on_card, format) + self.auto_convert(auto, on_card, format) if bad: bad = '\n'.join('%s'%(i,) for i in bad) diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 47276d2519..83190898ff 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -1030,11 +1030,11 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): ############################### Convert #################################### - def auto_convert(self, row_ids, on_card, format): + def auto_convert(self, book_ids, on_card, format): previous = self.library_view.currentIndex() rows = [x.row() for x in \ self.library_view.selectionModel().selectedRows()] - jobs, changed, bad = convert_single_ebook(self, self.library_view.model().db, row_ids, True, format) + 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: @@ -1047,6 +1047,23 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): current = self.library_view.currentIndex() self.library_view.model().current_changed(current, previous) + def auto_convert_mail(to, delete_from_library, book_ids, format): + previous = self.library_view.currentIndex() + rows = [x.row() for x in \ + 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) + + if changed: + self.library_view.model().refresh_rows(rows) + current = self.library_view.currentIndex() + self.library_view.model().current_changed(current, previous) + def get_books_for_conversion(self): rows = [r.row() for r in \ self.library_view.selectionModel().selectedRows()] @@ -1058,13 +1075,13 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): return [self.library_view.model().db.id(r) for r in rows] def convert_bulk(self, checked): - row_ids = self.get_books_for_conversion() - if row_ids is None: return + book_ids = self.get_books_for_conversion() + if book_ids is None: return previous = self.library_view.currentIndex() rows = [x.row() for x in \ self.library_view.selectionModel().selectedRows()] jobs, changed, bad = convert_bulk_ebook(self, - self.library_view.model().db, row_ids, out_format=prefs['output_format']) + self.library_view.model().db, book_ids, out_format=prefs['output_format']) 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), @@ -1077,13 +1094,13 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): self.library_view.model().current_changed(current, previous) def convert_single(self, checked): - row_ids = self.get_books_for_conversion() - if row_ids is None: return + book_ids = self.get_books_for_conversion() + if book_ids is None: return previous = self.library_view.currentIndex() rows = [x.row() for x in \ self.library_view.selectionModel().selectedRows()] jobs, changed, bad = convert_single_ebook(self, - self.library_view.model().db, row_ids, out_format=prefs['output_format']) + self.library_view.model().db, book_ids, out_format=prefs['output_format']) 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), @@ -1119,6 +1136,30 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): 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 = self.conversion_jobs.pop(job) + try: + if job.exception is not None: + self.job_exception(job) + return + data = open(temp_files[0].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()) + + self.send_by_mail(to, fmt, delete_from_library, send_ids=[book_id], do_auto_convert=False) + def book_converted(self, job): temp_files, fmt, book_id = self.conversion_jobs.pop(job) try: