def add_books_to_metadata(self, mtp_files, metadata, booklists): debug('add_books_to_metadata() called') from calibre.devices.mtp.books import Book i, total = 0, len(mtp_files) self.report_progress(0, _('Adding books to device metadata listing...')) for x, mi in izip(mtp_files, metadata): mtp_file, bl_idx = x bl = booklists[bl_idx] book = Book(mtp_file.storage_id, '/'.join(mtp_file.mtp_relpath), other=mi) book = bl.add_book(book, replace_metadata=True) if book is not None: book.size = mtp_file.size book.datetime = mtp_file.last_modified.timetuple() book.path = mtp_file.mtp_id_path i += 1 self.report_progress(i/total, _('Added %s')%mi.title) self.report_progress(1, _('Adding complete')) debug('add_books_to_metadata() ended')
def books(self, oncard=None, end_session=True): from calibre.devices.mtp.books import JSONCodec from calibre.devices.mtp.books import BookList, Book self.report_progress(0, _('Listing files, this can take a while')) self.get_driveinfo() # Ensure driveinfo is loaded sid = {'carda':self._carda_id, 'cardb':self._cardb_id}.get(oncard, self._main_id) if sid is None: return BookList(None) bl = BookList(sid) # If True then there is a mismatch between the ebooks on the device and # the metadata cache need_sync = False all_books = list(self.filesystem_cache.iterebooks(sid)) steps = len(all_books) + 2 count = 0 self.report_progress(0, _('Reading e-book metadata')) # Read the cache if it exists storage = self.filesystem_cache.storage(sid) cache = storage.find_path(self.calibre_file_paths['metadata'].split('/')) if cache is not None: json_codec = JSONCodec() try: stream = self.get_mtp_file(cache) json_codec.decode_from_file(stream, bl, Book, sid) except: need_sync = True relpath_cache = {b.mtp_relpath:i for i, b in enumerate(bl)} for mtp_file in all_books: count += 1 relpath = mtp_file.mtp_relpath idx = relpath_cache.get(relpath, None) if idx is not None: cached_metadata = bl[idx] del relpath_cache[relpath] if cached_metadata.size == mtp_file.size: cached_metadata.datetime = mtp_file.last_modified.timetuple() cached_metadata.path = mtp_file.mtp_id_path debug('Using cached metadata for', '/'.join(mtp_file.full_path)) continue # No need to update metadata book = cached_metadata else: book = Book(sid, '/'.join(relpath)) bl.append(book) need_sync = True self.report_progress(count/steps, _('Reading metadata from %s')% ('/'.join(relpath))) try: book.smart_update(self.read_file_metadata(mtp_file)) debug('Read metadata for', '/'.join(mtp_file.full_path)) except: prints('Failed to read metadata from', '/'.join(mtp_file.full_path)) traceback.print_exc() book.size = mtp_file.size book.datetime = mtp_file.last_modified.timetuple() book.path = mtp_file.mtp_id_path # Remove books in the cache that no longer exist for idx in sorted(relpath_cache.itervalues(), reverse=True): del bl[idx] need_sync = True if need_sync: self.report_progress(count/steps, _('Updating metadata cache on device')) self.write_metadata_cache(storage, bl) self.report_progress(1, _('Finished reading metadata from device')) return bl