From dc81cfe02911af1892b5e25b42acaf0ee28942b5 Mon Sep 17 00:00:00 2001 From: John Schember Date: Wed, 6 May 2009 19:45:34 -0400 Subject: [PATCH 1/2] Fix bug 2390: Use detailed message pane for message dialogs that have dynamic content. --- src/calibre/gui2/__init__.py | 12 ++++++++---- src/calibre/gui2/device.py | 10 +++++----- src/calibre/gui2/main.py | 16 +++++----------- src/calibre/gui2/tools.py | 9 ++++++--- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index ef6f37da8c..ebe877f823 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -100,27 +100,31 @@ def available_width(): def extension(path): return os.path.splitext(path)[1][1:].lower() -def warning_dialog(parent, title, msg): +def warning_dialog(parent, title, msg, det_msg=''): d = QMessageBox(QMessageBox.Warning, 'WARNING: '+title, msg, QMessageBox.Ok, parent) + d.setDetailedText(det_msg) d.setIconPixmap(QPixmap(':/images/dialog_warning.svg')) return d -def error_dialog(parent, title, msg): +def error_dialog(parent, title, msg, det_msg=''): d = QMessageBox(QMessageBox.Critical, 'ERROR: '+title, msg, QMessageBox.Ok, parent) + d.setDetailedText(det_msg) d.setIconPixmap(QPixmap(':/images/dialog_error.svg')) return d -def question_dialog(parent, title, msg): +def question_dialog(parent, title, msg, det_msg=''): d = QMessageBox(QMessageBox.Question, title, msg, QMessageBox.Yes|QMessageBox.No, parent) + d.setDetailedText(det_msg) d.setIconPixmap(QPixmap(':/images/dialog_information.svg')) return d -def info_dialog(parent, title, msg): +def info_dialog(parent, title, msg, det_msg=''): d = QMessageBox(QMessageBox.Information, title, msg, QMessageBox.NoButton, parent) + d.setDetailedText(det_msg) d.setIconPixmap(QPixmap(':/images/dialog_information.svg')) return d diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 3541d8105f..1a79631e8a 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -507,10 +507,10 @@ class DeviceGUI(object): self.status_bar.showMessage(_('Sending email to')+' '+to, 3000) if bad: - bad = '\n'.join('
  • %s
  • '%(i,) for i in bad) + bad = '\n'.join('%s'%(i,) for i in bad) d = warning_dialog(self, _('No suitable formats'), - '

    '+ _('Could not email the following books ' - 'as no suitable formats were found:

    ')%(bad,)) + _('Could not email the following books ' + 'as no suitable formats were found:'), bad) d.exec_() def emails_sent(self, results, remove=[]): @@ -694,12 +694,12 @@ class DeviceGUI(object): self.auto_convert(_auto_ids, on_card, format) if bad: - bad = '\n'.join('
  • %s
  • '%(i,) for i in bad) + bad = '\n'.join('%s'%(i,) for i in bad) d = warning_dialog(self, _('No suitable formats'), _('Could not upload the following books to the device, ' 'as no suitable formats were found. Try changing the output ' 'format in the upper right corner next to the red heart and ' - 're-converting.
    ')%(bad,)) + 're-converting.'), bad) d.exec_() def upload_booklists(self): diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 1d0281ead7..ce8cb418ba 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -445,14 +445,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): def change_output_format(self, x): of = unicode(x).strip() if of != prefs['output_format']: - if of not in ('LRF', 'EPUB', 'MOBI'): - warning_dialog(self, 'Warning', - ('

    %s support is still in beta. If you find bugs, ' - 'please report them by opening a ticket.')%of).exec_() prefs.set('output_format', of) - def test_server(self, *args): if self.content_server.exception is not None: error_dialog(self, _('Failed to start content server'), @@ -916,14 +910,14 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): callback=callback, single_format=single_format) if failures and single_format is not None: - msg = _('

    Could not save the following books to disk, ' - 'because the %s format is not available for them:

    ' + det_msg += '%s\n'%f[1] warning_dialog(self, _('Could not save some ebooks'), - msg).exec_() + msg, det_msg).exec_() QDesktopServices.openUrl(QUrl('file:'+dir)) else: paths = self.current_view().model().paths(rows) diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index 230ab9d5f6..8e19519ecc 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -12,6 +12,7 @@ import cPickle, os from PyQt4.Qt import QDialog from calibre.ptempfile import PersistentTemporaryFile +from calibre.gui2 import warning_dialog from calibre.gui2.convert import load_specifics from calibre.gui2.convert.single import NoSupportedInputFormats from calibre.gui2.convert.single import Config as SingleConfig @@ -60,10 +61,12 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format res = [] for id in bad: title = db.title(id, True) - res.append('
  • %s
  • '%title) + res.append('%s'%title) - msg = _('

    Could not convert %d of %d books, because no suitable source format was found.

    ')%(len(res), total, '\n'.join(res)) - warning_dialog(parent, _('Could not convert some books'), msg).exec_() + 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_() return jobs, changed, bad From c7f5598976b4781494fc98649e29627a23f95fe0 Mon Sep 17 00:00:00 2001 From: John Schember Date: Wed, 6 May 2009 21:46:25 -0400 Subject: [PATCH 2/2] status reporting for devices. jetbook uses news path and puts books in subdirs. Fix if elif else clause in _sanity_check. fix errors with the row to id changes. fix bug preventing auto convert to work correctly. --- src/calibre/devices/cybookg3/driver.py | 44 +++++---------------- src/calibre/devices/jetbook/driver.py | 35 +++++++++++------ src/calibre/devices/kindle/driver.py | 4 +- src/calibre/devices/prs505/books.py | 7 +++- src/calibre/devices/prs505/driver.py | 19 +++++++-- src/calibre/devices/usbms/driver.py | 53 +++++++++++++++++--------- src/calibre/gui2/device.py | 20 +++++----- src/calibre/gui2/library.py | 38 +++++++++++------- src/calibre/gui2/main.py | 3 +- src/calibre/gui2/tools.py | 1 + 10 files changed, 130 insertions(+), 94 deletions(-) diff --git a/src/calibre/devices/cybookg3/driver.py b/src/calibre/devices/cybookg3/driver.py index 7f3e5a82f4..5dde9ab51d 100644 --- a/src/calibre/devices/cybookg3/driver.py +++ b/src/calibre/devices/cybookg3/driver.py @@ -43,43 +43,13 @@ class CYBOOKG3(USBMS): def upload_books(self, files, names, on_card=None, end_session=True, metadata=None): - if on_card == 'carda' and not self._card_a_prefix: - raise ValueError(_('The reader has no storage card in this slot.')) - elif on_card == 'cardb' and not self._card_b_prefix: - raise ValueError(_('The reader has no storage card in this slot.')) - elif on_card and on_card not in ('carda', 'cardb'): - raise DeviceError(_('The reader has no storage card in this slot.')) - - if on_card == 'carda': - path = os.path.join(self._card_a_prefix, self.EBOOK_DIR_CARD_A) - if on_card == 'cardb': - path = os.path.join(self._card_b_prefix, self.EBOOK_DIR_CARD_B) - else: - path = os.path.join(self._main_prefix, self.EBOOK_DIR_MAIN) - - def get_size(obj): - if hasattr(obj, 'seek'): - obj.seek(0, os.SEEK_END) - size = obj.tell() - obj.seek(0) - return size - return os.path.getsize(obj) - - sizes = [get_size(f) for f in files] - size = sum(sizes) - - if not on_card and size > self.free_space()[0] - 2*1024*1024: - raise FreeSpaceError(_("There is insufficient free space in main memory")) - if on_card == 'carda' and size > self.free_space()[1] - 1024*1024: - raise FreeSpaceError(_("There is insufficient free space on the storage card")) - if on_card == 'cardb' and size > self.free_space()[2] - 1024*1024: - raise FreeSpaceError(_("There is insufficient free space on the storage card")) + path = self._sanity_check(on_card, files) paths = [] names = iter(names) metadata = iter(metadata) - for infile in files: + for i, infile in enumerate(files): newpath = path mdata = metadata.next() @@ -90,7 +60,6 @@ class CYBOOKG3(USBMS): newpath = os.path.join(newpath, mdata.get('title', '')) newpath = os.path.join(newpath, mdata.get('timestamp', '')) elif tag.startswith('/'): - newpath = path newpath += tag newpath = os.path.normpath(newpath) break @@ -125,10 +94,15 @@ class CYBOOKG3(USBMS): t2b.write_t2b(t2bfile, coverdata) t2bfile.close() + self.report_progress(i / float(len(files)), _('Transferring books to device...')) + + self.report_progress(1.0, _('Transferring books to device...')) + return zip(paths, cycle([on_card])) def delete_books(self, paths, end_session=True): - for path in paths: + for i, path in enumerate(paths): + self.report_progress((i+1) / float(len(paths)), _('Removing books from device...')) if os.path.exists(path): os.unlink(path) @@ -148,4 +122,4 @@ class CYBOOKG3(USBMS): os.removedirs(os.path.dirname(path)) except: pass - + self.report_progress(1.0, _('Removing books from device...')) diff --git a/src/calibre/devices/jetbook/driver.py b/src/calibre/devices/jetbook/driver.py index bdeb3a4032..05da539dd8 100644 --- a/src/calibre/devices/jetbook/driver.py +++ b/src/calibre/devices/jetbook/driver.py @@ -52,27 +52,34 @@ class JETBOOK(USBMS): names = iter(names) metadata = iter(metadata) - for infile in files: + for i, infile in enumerate(files): newpath = path - if self.SUPPORTS_SUB_DIRS: - mdata = metadata.next() + mdata = metadata.next() - if 'tags' in mdata.keys(): - for tag in mdata['tags']: - if tag.startswith('/'): - newpath += tag - newpath = os.path.normpath(newpath) - break - - if not os.path.exists(newpath): - os.makedirs(newpath) + if 'tags' in mdata.keys(): + for tag in mdata['tags']: + if tag.startswith(_('News')): + newpath = os.path.join(newpath, 'news') + newpath = os.path.join(newpath, mdata.get('title', '')) + newpath = os.path.join(newpath, mdata.get('timestamp', '')) + break + elif tag.startswith('/'): + newpath += tag + newpath = os.path.normpath(newpath) + break author = sanitize(mdata.get('authors','Unknown')).replace(' ', '_') title = sanitize(mdata.get('title', 'Unknown')).replace(' ', '_') fileext = os.path.splitext(os.path.basename(names.next()))[1] fname = '%s#%s%s' % (author, title, fileext) + if newpath == path: + newpath = os.path.join(newpath, author, title) + + if not os.path.exists(newpath): + os.makedirs(newpath) + filepath = os.path.join(newpath, fname) paths.append(filepath) @@ -87,6 +94,10 @@ class JETBOOK(USBMS): else: shutil.copy2(infile, filepath) + self.report_progress((i+1) / float(len(files)), _('Transferring books to device...')) + + self.report_progress(1.0, _('Transferring books to device...')) + return zip(paths, cycle([on_card])) @classmethod diff --git a/src/calibre/devices/kindle/driver.py b/src/calibre/devices/kindle/driver.py index 6f17cd335a..6471112c1a 100644 --- a/src/calibre/devices/kindle/driver.py +++ b/src/calibre/devices/kindle/driver.py @@ -39,7 +39,8 @@ class KINDLE(USBMS): r'(?P[^-]+)-asin_(?P<asin>[a-zA-Z\d]{10,})-type_(?P<type>\w{4})-v_(?P<index>\d+).*') def delete_books(self, paths, end_session=True): - for path in paths: + for i, path in enumerate(paths): + self.report_progress((i+1) / float(len(paths)), _('Removing books from device...')) if os.path.exists(path): os.unlink(path) @@ -48,6 +49,7 @@ class KINDLE(USBMS): # Delete the ebook auxiliary file if os.path.exists(filepath + '.mbp'): os.unlink(filepath + '.mbp') + self.report_progress(1.0, _('Removing books from device...')) @classmethod def metadata_from_path(cls, path): diff --git a/src/calibre/devices/prs505/books.py b/src/calibre/devices/prs505/books.py index 3fdb8a8432..b47ab5ae67 100644 --- a/src/calibre/devices/prs505/books.py +++ b/src/calibre/devices/prs505/books.py @@ -129,7 +129,7 @@ class Book(object): class BookList(_BookList): - def __init__(self, xml_file, mountpath): + def __init__(self, xml_file, mountpath, report_progress=None): _BookList.__init__(self) xml_file.seek(0) self.document = dom.parse(xml_file) @@ -144,7 +144,10 @@ class BookList(_BookList): else: self.prefix = '' - for book in self.root_element.childNodes: + nodes = self.root_element.childNodes + for i, book in enumerate(nodes): + if report_progress: + self.report_progress((i+1) / float(len(nodes)), _('Getting list of books on device...')) if hasattr(book, 'tagName') and book.tagName.endswith('text'): tags = [i.getAttribute('title') for i in self.get_playlists(book.getAttribute('id'))] self.append(Book(book, mountpath, tags, prefix=self.prefix)) diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index 702dd37592..e75f67223a 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -75,24 +75,29 @@ class PRS505(CLI, Device): self._card_b_prefix = None def get_device_information(self, end_session=True): + self.report_progress(1.0, _('Get device information...')) return (self.__class__.__name__, '', '', '') def books(self, oncard=None, end_session=True): if oncard == 'carda' and not self._card_a_prefix: + self.report_progress(1.0, _('Getting list of books on device...')) return [] elif oncard == 'cardb' and not self._card_b_prefix: + self.report_progress(1.0, _('Getting list of books on device...')) return [] elif oncard and oncard != 'carda' and oncard != 'cardb': + self.report_progress(1.0, _('Getting list of books on device...')) return [] db = self.__class__.CACHE_XML if oncard else self.__class__.MEDIA_XML prefix = self._card_a_prefix if oncard == 'carda' else self._card_b_prefix if oncard == 'cardb' else self._main_prefix - bl = BookList(open(prefix + db, 'rb'), prefix) + bl = BookList(open(prefix + db, 'rb'), prefix, self.report_progress) paths = bl.purge_corrupted_files() for path in paths: path = os.path.join(prefix, path) if os.path.exists(path): os.unlink(path) + self.report_progress(1.0, _('Getting list of books on device...')) return bl def upload_books(self, files, names, on_card=None, end_session=True, @@ -133,7 +138,7 @@ class PRS505(CLI, Device): names = iter(names) metadata = iter(metadata) - for infile in files: + for i, infile in enumerate(files): close = False if not hasattr(infile, 'read'): infile, close = open(infile, 'rb'), True @@ -170,6 +175,10 @@ class PRS505(CLI, Device): infile.close() ctimes.append(os.path.getctime(paths[-1])) + self.report_progress((i+1) / float(len(files)), _('Transferring books to device...')) + + self.report_progress(1.0, _('Transferring books to device...')) + return zip(paths, sizes, ctimes, cycle([on_card])) @classmethod @@ -186,9 +195,11 @@ class PRS505(CLI, Device): fix_ids(*booklists) def delete_books(self, paths, end_session=True): - for path in paths: + for i, path in enumerate(paths): + self.report_progress((i+1) / float(len(paths)), _('Removing books from device...')) if os.path.exists(path): os.unlink(path) + self.report_progress(1.0, _('Removing books from device...')) @classmethod def remove_books_from_metadata(cls, paths, booklists): @@ -215,3 +226,5 @@ class PRS505(CLI, Device): f.close() write_card_prefix(self._card_a_prefix, 1) write_card_prefix(self._card_b_prefix, 2) + + self.report_progress(1.0, _('Sending metadata to device...')) diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index 40a22c662e..700a072c5b 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -38,6 +38,7 @@ class USBMS(CLI, Device): report_progress=report_progress) def get_device_information(self, end_session=True): + self.report_progress(1.0, _('Get device information...')) return (self.__class__.__name__, '', '', '') def books(self, oncard=None, end_session=True): @@ -45,10 +46,13 @@ class USBMS(CLI, Device): bl = BookList() if oncard == 'carda' and not self._card_a_prefix: + self.report_progress(1.0, _('Getting list of books on device...')) return bl elif oncard == 'cardb' and not self._card_b_prefix: + self.report_progress(1.0, _('Getting list of books on device...')) return bl elif oncard and oncard != 'carda' and oncard != 'cardb': + self.report_progress(1.0, _('Getting list of books on device...')) return bl prefix = self._card_a_prefix if oncard == 'carda' else self._card_b_prefix if oncard == 'cardb' else self._main_prefix @@ -59,13 +63,20 @@ class USBMS(CLI, Device): for path, dirs, files in os.walk(os.path.join(prefix, ebook_dir)): # Filter out anything that isn't in the list of supported ebook types for book_type in self.FORMATS: - for filename in fnmatch.filter(files, '*.%s' % (book_type)): + match = fnmatch.filter(files, '*.%s' % (book_type)) + for i, filename in enumerate(match): + self.report_progress((i+1) / float(len(match)), _('Getting list of books on device...')) bl.append(self.__class__.book_from_path(os.path.join(path, filename))) else: path = os.path.join(prefix, ebook_dir) - for filename in os.listdir(path): + paths = os.listdir(path) + for i, filename in enumerate(paths): + self.report_progress((i+1) / float(len(paths)), _('Getting list of books on device...')) if path_to_ext(filename) in self.FORMATS: bl.append(self.__class__.book_from_path(os.path.join(path, filename))) + + self.report_progress(1.0, _('Getting list of books on device...')) + return bl def _sanity_check(self, on_card, files): @@ -78,7 +89,7 @@ class USBMS(CLI, Device): if on_card == 'carda': path = os.path.join(self._card_a_prefix, self.EBOOK_DIR_CARD_A) - if on_card == 'cardb': + elif on_card == 'cardb': path = os.path.join(self._card_b_prefix, self.EBOOK_DIR_CARD_B) else: path = os.path.join(self._main_prefix, self.EBOOK_DIR_MAIN) @@ -102,7 +113,7 @@ class USBMS(CLI, Device): raise FreeSpaceError(_("There is insufficient free space on the storage card")) return path - def upload_books(self, files, names, on_card=False, end_session=True, + def upload_books(self, files, names, on_card=None, end_session=True, metadata=None): path = self._sanity_check(on_card, files) @@ -111,7 +122,7 @@ class USBMS(CLI, Device): names = iter(names) metadata = iter(metadata) - for infile in files: + for i, infile in enumerate(files): newpath = path if self.SUPPORTS_SUB_DIRS: @@ -125,14 +136,14 @@ class USBMS(CLI, Device): newpath = os.path.join(newpath, mdata.get('timestamp', '')) break elif tag.startswith('/'): - newpath = path newpath += tag newpath = os.path.normpath(newpath) break if newpath == path: - newpath = os.path.join(newpath, mdata.get('authors', _('Unknown'))) - newpath = os.path.join(newpath, mdata.get('title', _('Unknown'))) + newpath = os.path.join(newpath, + mdata.get('authors', _('Unknown')), + mdata.get('title', _('Unknown'))) if not os.path.exists(newpath): os.makedirs(newpath) @@ -151,22 +162,28 @@ class USBMS(CLI, Device): else: shutil.copy2(infile, filepath) + self.report_progress((i+1) / float(len(files)), _('Transferring books to device...')) + + self.report_progress(1.0, _('Transferring books to device...')) + return zip(paths, cycle([on_card])) - @classmethod - def add_books_to_metadata(cls, locations, metadata, booklists): - for location in locations: + def add_books_to_metadata(self, locations, metadata, booklists): + for i, location in enumerate(locations): + self.report_progress((i+1) / float(len(locations)), _('Adding books to device metadata listing...')) path = location[0] blist = 2 if location[1] == 'cardb' else 1 if location[1] == 'carda' else 0 - book = cls.book_from_path(path) + book = self.book_from_path(path) if not book in booklists[blist]: booklists[blist].append(book) + self.report_progress(1.0, _('Adding books to device metadata listing...')) def delete_books(self, paths, end_session=True): - for path in paths: + for i, path in enumerate(paths): + self.report_progress((i+1) / float(len(paths)), _('Removing books from device...')) if os.path.exists(path): # Delete the ebook os.unlink(path) @@ -175,20 +192,22 @@ class USBMS(CLI, Device): os.removedirs(os.path.dirname(path)) except: pass + self.report_progress(1.0, _('Removing books from device...')) - @classmethod - def remove_books_from_metadata(cls, paths, booklists): - for path in paths: + def remove_books_from_metadata(self, paths, booklists): + for i, path in enumerate(paths): + self.report_progress((i+1) / float(len(paths)), _('Removing books from device metadata listing...')) for bl in booklists: for book in bl: if path.endswith(book.path): bl.remove(book) + self.report_progress(1.0, _('Removing books from device metadata listing...')) def sync_booklists(self, booklists, end_session=True): # There is no meta data on the device to update. The device is treated # as a mass storage device and does not use a meta data xml file like # the Sony Readers. - pass + self.report_progress(1.0, _('Sending metadata to device...')) @classmethod def metadata_from_path(cls, path): diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 1a79631e8a..97744db234 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -551,7 +551,7 @@ class DeviceGUI(object): for account, x in opts.accounts.items() if x[1]] sent_mails = [] for account, fmts in accounts: - files = self.library_view.model().\ + files, auto = self.library_view.model().\ get_preferred_formats_from_ids([id], fmts) files = [f.name for f in files if f is not None] if not files: @@ -580,7 +580,7 @@ class DeviceGUI(object): if self.device_connected: ids = list(dynamic.get('news_to_be_synced', set([]))) ids = [id for id in ids if self.library_view.model().db.has_id(id)] - files = self.library_view.model().get_preferred_formats_from_ids( + files, auto = self.library_view.model().get_preferred_formats_from_ids( ids, self.device_manager.device_class.settings().format_map) files = [f for f in files if f is not None] if not files: @@ -627,8 +627,8 @@ class DeviceGUI(object): else: _auto_ids = [] - ids = iter(ids) metadata = self.library_view.model().get_metadata(ids, True) + ids = iter(ids) for mi in metadata: cdata = mi['cover'] if cdata: @@ -663,19 +663,19 @@ class DeviceGUI(object): auto = [] if _auto_ids != []: - for row in _auto_ids: + for id in _auto_ids: if specific_format == None: - formats = [f.lower() for f in self.library_view.model().db.formats(row).split(',')] + 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(self.device_manager.device_class.settings().format_map).intersection(available_output_formats())) != []: - auto.append(row) + auto.append(id) else: - bad.append(self.library_view.model().title(row)) + bad.append(self.library_view.model().db.title(id, index_is_id=True)) else: if specific_format in available_output_formats(): - auto.append(row) + auto.append(id) else: - bad.append(self.library_view.model().title(row)) + bad.append(self.library_view.model().db.title(id, index_is_id=True)) if auto != []: format = None @@ -686,7 +686,7 @@ class DeviceGUI(object): if format is None: bad += auto else: - autos = [self.library_view.model().title(row) for row in auto] + autos = [self.library_view.model().db.title(id, index_is_id=True) for id in auto] autos = '\n'.join('<li>%s</li>'%(i,) for i in autos) d = info_dialog(self, _('No suitable formats'), _('Auto converting the following books before uploading to the device:<br><ul>%s</ul>')%(autos,)) diff --git a/src/calibre/gui2/library.py b/src/calibre/gui2/library.py index c67f9bc1b0..f35a478847 100644 --- a/src/calibre/gui2/library.py +++ b/src/calibre/gui2/library.py @@ -397,27 +397,39 @@ class BooksModel(QAbstractTableModel): else: return metadata - def get_preferred_formats_from_ids(self, ids, all_formats, mode='r+b'): + def get_preferred_formats_from_ids(self, ids, formats, paths=False, + set_metadata=False, specific_format=None, + exclude_auto=False, mode='r+b'): ans = [] + need_auto = [] + if specific_format is not None: + formats = [specific_format.lower()] for id in ids: format = None fmts = self.db.formats(id, index_is_id=True) if not fmts: fmts = '' - available_formats = set(fmts.lower().split(',')) - for f in all_formats: - if f.lower() in available_formats: - format = f.lower() + db_formats = set(fmts.lower().split(',')) + available_formats = set([f.lower() for f in formats]) + u = available_formats.intersection(db_formats) + for f in formats: + if f.lower() in u: + format = f break - if format is None: - ans.append(format) + if format is not None: + pt = PersistentTemporaryFile(suffix='.'+format) + pt.write(self.db.format(id, format, index_is_id=True)) + pt.flush() + if set_metadata: + _set_metadata(pt, self.db.get_metadata(id, get_cover=True, index_is_id=True), + format) + pt.close() if paths else pt.seek(0) + ans.append(pt) else: - f = self.db.format(id, format, index_is_id=True, as_file=True, - mode=mode) - ans.append(f) - return ans - - + need_auto.append(id) + if not exclude_auto: + ans.append(None) + return ans, need_auto def get_preferred_formats(self, rows, formats, paths=False, set_metadata=False, specific_format=None, diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index ce8cb418ba..96a3444ec4 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -966,7 +966,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): def auto_convert(self, row_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) if jobs == []: return for func, args, desc, fmt, id, temp_files in jobs: diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index 8e19519ecc..a8407df767 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -34,6 +34,7 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format d = SingleConfig(parent, db, book_id, None, out_format) if auto_conversion: + d.accept() result = QDialog.Accepted else: result = d.exec_()