def _populate_book_from_calibre_id(self, book, db=None): mi = db.get_metadata(book['calibre_id'], index_is_id=True) #book = {} book['good'] = True book['calibre_id'] = mi.id book['title'] = mi.title book['authors'] = mi.authors book['author_sort'] = mi.author_sort book['tags'] = mi.tags book['series'] = mi.series book['comments'] = mi.comments book['publisher'] = mi.publisher book['pubdate'] = mi.pubdate if book['series']: book['series_index'] = mi.series_index else: book['series_index'] = None book['languages'] = mi.languages book['error'] = '' if db.has_format(mi.id,'EPUB',index_is_id=True): book['epub'] = StringIO(db.format(mi.id,'EPUB',index_is_id=True)) if prefs['keepmeta']: set_metadata(book['epub'], mi, stream_type='epub') book['epub_size'] = len(book['epub'].getvalue()) else: book['good'] = False; book['error'] = _("%s by %s doesn't have an EPUB.")%(mi.title,', '.join(mi.authors))
def update_metadata(mi, fmt, stream, plugboards, cdata, error_report=None, plugboard_cache=None): from calibre.ebooks.metadata.meta import set_metadata if error_report is not None: def report_error(mi, fmt, tb): error_report(fmt, tb) try: if plugboard_cache is not None: cpb = plugboard_cache[fmt] else: cpb = find_plugboard(plugboard_save_to_disk_value, fmt, plugboards) if cpb: newmi = mi.deepcopy_metadata() newmi.template_to_attribute(mi, cpb) else: newmi = mi if cdata: newmi.cover_data = ('jpg', cdata) set_metadata(stream, newmi, fmt, report_error=None if error_report is None else report_error) except: if error_report is None: prints('Failed to set metadata for the', fmt, 'format of', mi.title) traceback.print_exc() else: error_report(fmt, traceback.format_exc())
def _populate_book_from_calibre_id(self, book, db=None): mi = db.get_metadata(book['calibre_id'], index_is_id=True) #book = {} book['good'] = True book['calibre_id'] = mi.id book['title'] = mi.title book['authors'] = mi.authors book['author_sort'] = mi.author_sort book['tags'] = mi.tags book['series'] = mi.series book['comments'] = mi.comments book['publisher'] = mi.publisher book['pubdate'] = mi.pubdate if book['series']: book['series_index'] = mi.series_index else: book['series_index'] = None book['languages'] = mi.languages book['error'] = '' if db.has_format(mi.id, 'EPUB', index_is_id=True): book['epub'] = StringIO(db.format(mi.id, 'EPUB', index_is_id=True)) if prefs['keepmeta']: set_metadata(book['epub'], mi, stream_type='epub') book['epub_size'] = len(book['epub'].getvalue()) else: book['good'] = False book['error'] = _("%s by %s doesn't have an EPUB.") % ( mi.title, ', '.join(mi.authors))
def updateMetadata(self): from calibre.library import db from calibre.ebooks.metadata.meta import set_metadata from calibre.gui2 import error_dialog, info_dialog rows = self.gui.library_view.selectionModel().selectedRows() if not rows or len(rows) == 0: return error_dialog(self.gui, 'Cannot update metadata', 'No books selected', show=True) ids = list(map(self.gui.library_view.model().id, rows)) db = self.gui.current_db.new_api for book_id in ids: mi = db.get_metadata(book_id, get_cover=True, cover_as_data=True) fmts = db.formats(book_id) if not fmts: continue for fmt in fmts: fmt = fmt.lower() ffile = db.format(book_id, fmt, as_file=True) ffile.seek(0) set_metadata(ffile, mi, fmt) ffile.seek(0) db.add_format(book_id, fmt, ffile, run_hooks=False) print('Updated')
def run(self, path_to_ebook): from calibre.ebooks.metadata.meta import get_metadata, set_metadata with open(path_to_ebook, 'r+b') as file: ext = os.path.splitext(path_to_ebook)[-1][1:].lower() mi = get_metadata(file, ext) mi.publisher = 'Hello World' set_metadata(file, mi, ext) return path_to_ebook
def run(self, path_to_ebook): from calibre.ebooks.metadata.meta import get_metadata, set_metadata file = open(path_to_ebook, 'r+b') ext = os.path.splitext(path_to_ebook)[-1][1:].lower() mi = get_metadata(file, ext) mi.publisher = 'Hello World' set_metadata(file, mi, ext) return path_to_ebook
def get_format(self, id, format): format = format.upper() fm = self.db.format_metadata(id, format, allow_cache=False) if not fm: raise cherrypy.HTTPError( 404, 'book: %d does not have format: %s' % (id, format)) update_metadata = format in {'MOBI', 'EPUB', 'AZW3'} mi = newmi = self.db.get_metadata(id, index_is_id=True, cover_as_data=True, get_cover=update_metadata) cherrypy.response.headers['Last-Modified'] = \ self.last_modified(max(fm['mtime'], mi.last_modified)) fmt = self.db.format(id, format, index_is_id=True, as_file=True, mode='rb') if fmt is None: raise cherrypy.HTTPError( 404, 'book: %d does not have format: %s' % (id, format)) mt = guess_type('dummy.' + format.lower())[0] if mt is None: mt = 'application/octet-stream' cherrypy.response.headers['Content-Type'] = mt if format.lower() in plugboard_content_server_formats: # Get any plugboards for the content server plugboards = self.db.prefs.get('plugboards', {}) cpb = find_plugboard(plugboard_content_server_value, format.lower(), plugboards) if cpb: # Transform the metadata via the plugboard newmi = mi.deepcopy_metadata() newmi.template_to_attribute(mi, cpb) if update_metadata: # Write the updated file from calibre.ebooks.metadata.meta import set_metadata set_metadata(fmt, newmi, format.lower()) fmt.seek(0) fmt.seek(0, 2) cherrypy.response.headers['Content-Length'] = fmt.tell() fmt.seek(0) au = authors_to_string( newmi.authors if newmi.authors else [_('Unknown')]) title = newmi.title if newmi.title else _('Unknown') fname = u'%s - %s_%s.%s' % (title[:30], au[:30], id, format.lower()) fname = ascii_filename(fname).replace('"', '_') cherrypy.response.headers['Content-Disposition'] = \ b'attachment; filename="%s"'%fname cherrypy.response.body = fmt cherrypy.response.timeout = 3600 return fmt
def copy_func(dest): db.copy_format_to(book_id, fmt, dest) if update_metadata: if not mi.cover_data or not mi.cover_data[-1]: cdata = db.cover(book_id) if cdata: mi.cover_data = ('jpeg', cdata) set_metadata(dest, mi, fmt) dest.seek(0)
def run(self, path_to_ebook): # print("run FanficAuthorsNetCSSFix") # logger.warn("logger") book_format = 'epub' ## Really crude brute force check to see if it's a ## fanficauthors.net epub: epub = ZipFile( path_to_ebook, 'r') # works equally well with inputio as a path or a blob tocfile = "content/toc.ncx" if not (tocfile in epub.namelist() and "fanficauthors.net" in epub.read(tocfile)): # bail without doing anything return path_to_ebook print("It's a fanficauthors.net epub!") tmpfile = self.temporary_file('.' + book_format) outputepub = ZipFile(tmpfile, "w", compression=ZIP_STORED) outputepub.debug = 3 outputepub.writestr("mimetype", "application/epub+zip") outputepub.close() ## Re-open file for content. outputepub = ZipFile(tmpfile, "a", compression=ZIP_DEFLATED) outputepub.debug = 3 for fname in epub.namelist(): if fname.endswith('.html'): outputepub.writestr( fname, epub.read(fname).replace( """body { margin-top: 0px; padding-top: 0px; }""", """body { background-color: #FFFFFF; text-align: justify; margin: 2%; adobe-hyphenate: none; }""")) elif fname != "mimetype": outputepub.writestr(fname, epub.read(fname)) for zf in outputepub.filelist: zf.create_system = 0 outputepub.close() # file = open(path_to_ebook, 'r+b') ext = os.path.splitext(path_to_ebook)[-1][1:].lower() mi = get_metadata(tmpfile, ext) mi.publisher = "fanficauthors.net" set_metadata(tmpfile, mi, ext) # return path_to_ebook return tmpfile.name
def run(self, path_to_ebook): from calibre.ebooks.metadata.meta import get_metadata, set_metadata file = open(path_to_ebook, 'r+b') ext = os.path.splitext(path_to_ebook)[-1][1:].lower() mi = get_metadata(file, ext) outfile = run_on_file(path_to_ebook) set_metadata(outfile, mi, 'mp3') return path_to_ebook
def get_format(self, id, format): format = format.upper() fm = self.db.format_metadata(id, format, allow_cache=False) if not fm: raise cherrypy.HTTPError(404, 'book: %d does not have format: %s'%(id, format)) update_metadata = format in {'MOBI', 'EPUB', 'AZW3'} mi = newmi = self.db.get_metadata( id, index_is_id=True, cover_as_data=True, get_cover=update_metadata) cherrypy.response.headers['Last-Modified'] = \ self.last_modified(max(fm['mtime'], mi.last_modified)) fmt = self.db.format(id, format, index_is_id=True, as_file=True, mode='rb') if fmt is None: raise cherrypy.HTTPError(404, 'book: %d does not have format: %s'%(id, format)) mt = guess_type('dummy.'+format.lower())[0] if mt is None: mt = 'application/octet-stream' cherrypy.response.headers['Content-Type'] = mt if format.lower() in plugboard_content_server_formats: # Get any plugboards for the content server plugboards = self.db.prefs.get('plugboards', {}) cpb = find_plugboard(plugboard_content_server_value, format.lower(), plugboards) if cpb: # Transform the metadata via the plugboard newmi = mi.deepcopy_metadata() newmi.template_to_attribute(mi, cpb) if update_metadata: # Write the updated file from calibre.ebooks.metadata.meta import set_metadata set_metadata(fmt, newmi, format.lower()) fmt.seek(0) fmt.seek(0, 2) cherrypy.response.headers['Content-Length'] = fmt.tell() fmt.seek(0) ua = cherrypy.request.headers.get('User-Agent', '').strip() have_kobo_browser = self.is_kobo_browser(ua) file_extension = "kepub.epub" if have_kobo_browser and format.lower() == "kepub" else format au = authors_to_string(newmi.authors if newmi.authors else [_('Unknown')]) title = newmi.title if newmi.title else _('Unknown') fname = u'%s - %s_%s.%s'%(title[:30], au[:30], id, file_extension.lower()) fname = ascii_filename(fname).replace('"', '_') cherrypy.response.headers['Content-Disposition'] = \ b'attachment; filename="%s"'%fname cherrypy.response.body = fmt cherrypy.response.timeout = 3600 return fmt
def do_set_metadata(opts, mi, stream, stream_type): mi = MetaInformation(mi) for x in ('guide', 'toc', 'manifest', 'spine'): setattr(mi, x, None) from_opf = getattr(opts, 'from_opf', None) if from_opf is not None: from calibre.ebooks.metadata.opf2 import OPF opf_mi = OPF(open(from_opf, 'rb')).to_book_metadata() mi.smart_update(opf_mi) for pref in config().option_set.preferences: if pref.name in ('to_opf', 'from_opf', 'authors', 'title_sort', 'author_sort', 'get_cover', 'cover', 'tags', 'lrf_bookid', 'identifiers'): continue val = getattr(opts, pref.name, None) if val is not None: setattr(mi, pref.name, val) if getattr(opts, 'authors', None) is not None: mi.authors = string_to_authors(opts.authors) mi.author_sort = authors_to_sort_string(mi.authors) if getattr(opts, 'author_sort', None) is not None: mi.author_sort = opts.author_sort if getattr(opts, 'title_sort', None) is not None: mi.title_sort = opts.title_sort elif getattr(opts, 'title', None) is not None: mi.title_sort = title_sort(opts.title) if getattr(opts, 'tags', None) is not None: mi.tags = [t.strip() for t in opts.tags.split(',')] if getattr(opts, 'series', None) is not None: mi.series = opts.series.strip() if getattr(opts, 'series_index', None) is not None: mi.series_index = float(opts.series_index.strip()) if getattr(opts, 'pubdate', None) is not None: mi.pubdate = parse_date(opts.pubdate, assume_utc=False, as_utc=False) if getattr(opts, 'identifiers', None): val = { k.strip(): v.strip() for k, v in (x.partition(':')[0::2] for x in opts.identifiers) } if val: orig = mi.get_identifiers() orig.update(val) val = {k: v for k, v in orig.iteritems() if k and v} mi.set_identifiers(val) if getattr(opts, 'cover', None) is not None: ext = os.path.splitext(opts.cover)[1].replace('.', '').upper() mi.cover_data = (ext, open(opts.cover, 'rb').read()) with force_identifiers: set_metadata(stream, mi, stream_type)
def do_set_metadata(opts, mi, stream, stream_type): mi = MetaInformation(mi) for x in ('guide', 'toc', 'manifest', 'spine'): setattr(mi, x, None) from_opf = getattr(opts, 'from_opf', None) if from_opf is not None: from calibre.ebooks.metadata.opf2 import OPF opf_mi = OPF(open(from_opf, 'rb')).to_book_metadata() mi.smart_update(opf_mi) for pref in config().option_set.preferences: if pref.name in ('to_opf', 'from_opf', 'authors', 'title_sort', 'author_sort', 'get_cover', 'cover', 'tags', 'lrf_bookid', 'identifiers'): continue val = getattr(opts, pref.name, None) if val is not None: setattr(mi, pref.name, val) if getattr(opts, 'authors', None) is not None: mi.authors = string_to_authors(opts.authors) mi.author_sort = authors_to_sort_string(mi.authors) if getattr(opts, 'author_sort', None) is not None: mi.author_sort = opts.author_sort if getattr(opts, 'title_sort', None) is not None: mi.title_sort = opts.title_sort elif getattr(opts, 'title', None) is not None: mi.title_sort = title_sort(opts.title) if getattr(opts, 'tags', None) is not None: mi.tags = [t.strip() for t in opts.tags.split(',')] if getattr(opts, 'series', None) is not None: mi.series = opts.series.strip() if getattr(opts, 'series_index', None) is not None: mi.series_index = float(opts.series_index.strip()) if getattr(opts, 'pubdate', None) is not None: mi.pubdate = parse_date(opts.pubdate, assume_utc=False, as_utc=False) if getattr(opts, 'identifiers', None): val = {k.strip():v.strip() for k, v in (x.partition(':')[0::2] for x in opts.identifiers)} if val: orig = mi.get_identifiers() orig.update(val) val = {k:v for k, v in iteritems(orig) if k and v} mi.set_identifiers(val) if getattr(opts, 'cover', None) is not None: ext = os.path.splitext(opts.cover)[1].replace('.', '').upper() mi.cover_data = (ext, open(opts.cover, 'rb').read()) with force_identifiers: set_metadata(stream, mi, stream_type)
def get_format(self, id, format): format = format.upper() fm = self.db.format_metadata(id, format, allow_cache=False) if not fm: raise web.HTTPError( 404, 'book: %d does not have format: %s' % (id, format)) mi = newmi = self.db.get_metadata(id, index_is_id=True) self.set_header('Last-Modified', self.last_modified(max(fm['mtime'], mi.last_modified))) fmt = self.db.format(id, format, index_is_id=True, as_file=True, mode='rb') if fmt is None: raise web.HTTPError( 404, 'book: %d does not have format: %s' % (id, format)) mt = guess_type('dummy.' + format.lower())[0] if mt is None: mt = 'application/octet-stream' self.set_header('Content-Type', mt) if format == 'EPUB': # Get the original metadata # Get any EPUB plugboards for the content server plugboards = self.db.prefs.get('plugboards', {}) cpb = find_plugboard(plugboard_content_server_value, 'epub', plugboards) if cpb: # Transform the metadata via the plugboard newmi = mi.deepcopy_metadata() newmi.template_to_attribute(mi, cpb) if format in ('MOBI', 'EPUB'): # Write the updated file set_metadata(fmt, newmi, format.lower()) fmt.seek(0) fmt.seek(0, 2) self.set_header('Content-Lenght', fmt.tell()) fmt.seek(0) au = authors_to_string( newmi.authors if newmi.authors else [_('Unknown')]) title = newmi.title if newmi.title else _('Unknown') fname = u'%s - %s_%s.%s' % (title[:30], au[:30], id, format.lower()) fname = ascii_filename(fname).replace('"', '_') self.set_header('Content-Disposition', b'attachment; filename="%s"' % fname) return fmt
def update_metadata(self): ''' Set the metadata in the files in the selected book's record to match the current metadata in the database. ''' from calibre.ebooks.metadata.meta import set_metadata from calibre.gui2 import error_dialog, info_dialog # Get currently selected books rows = self.gui.library_view.selectionModel().selectedRows() if not rows or len(rows) == 0: return error_dialog(self.gui, 'Cannot update metadata', 'No books selected', show=True) # Map the rows to book ids ids = list(map(self.gui.library_view.model().id, rows)) for book_id in ids: # Get the current metadata for this book from the db mi = self.db.get_metadata(book_id, index_is_id=True, get_cover=True, cover_as_data=True) fmts = self.db.formats(book_id, index_is_id=True) if not fmts: continue for fmt in fmts.split(','): fmt = fmt.lower() # Get a python file object for the format. This will be either # an in memory file or a temporary on disk file ffile = self.db.format(book_id, fmt, index_is_id=True, as_file=True) # Set metadata in the format set_metadata(ffile, mi, fmt) ffile.seek(0) # Now replace the file in the calibre library with the updated # file. We dont use add_format_with_hooks as the hooks were # already run when the file was first added to calibre. ffile.name = 'xxx' # add_format() will not work if the file # path of the file being added is the same # as the path of the file being replaced self.db.add_format(book_id, fmt, ffile, index_is_id=True) info_dialog(self, 'Updated files', 'Updated the metadata in the files of %d book(s)' % len(ids), show=True)
def do_tweak(self, book_id): if self.gui.current_view() is not self.gui.library_view: return error_dialog(self.gui, _('Cannot Edit Book'), _( 'Editing of books on the device is not supported'), show=True) from calibre.ebooks.oeb.polish.main import SUPPORTED db = self.gui.library_view.model().db fmts = db.formats(book_id, index_is_id=True) or '' fmts = [x.upper().strip() for x in fmts.split(',')] tweakable_fmts = set(fmts).intersection(SUPPORTED) if not tweakable_fmts: return error_dialog(self.gui, _('Cannot Edit Book'), _('The book must be in the %s formats to edit.' '\n\nFirst convert the book to one of these formats.') % (_(' or '.join(SUPPORTED))), show=True) from calibre.gui2.tweak_book import tprefs tprefs.refresh() # In case they were changed in a Tweak Book process if len(tweakable_fmts) > 1: if tprefs['choose_tweak_fmt']: d = Choose(sorted(tweakable_fmts, key=tprefs.defaults['tweak_fmt_order'].index), self.gui) if d.exec_() != d.Accepted: return tweakable_fmts = {d.fmt} else: fmts = [f for f in tprefs['tweak_fmt_order'] if f in tweakable_fmts] if not fmts: fmts = [f for f in tprefs.defaults['tweak_fmt_order'] if f in tweakable_fmts] tweakable_fmts = {fmts[0]} fmt = tuple(tweakable_fmts)[0] path = db.new_api.format_abspath(book_id, fmt) if path is None: return error_dialog(self.gui, _('File missing'), _( 'The %s format is missing from the calibre library. You should run' ' library maintenance.') % fmt, show=True) tweak = 'ebook-edit' self.gui.setCursor(Qt.BusyCursor) if tprefs['update_metadata_from_calibre']: from calibre.ebooks.metadata.opf2 import pretty_print from calibre.ebooks.metadata.meta import set_metadata from calibre.customize.ui import apply_null_metadata mi = db.new_api.get_metadata(book_id, get_cover=True) with pretty_print, apply_null_metadata, open(path, 'r+b') as f: set_metadata(f, mi, stream_type=fmt.lower()) notify = '%d:%s:%s:%s' % (book_id, fmt, db.library_id, db.library_path) try: self.gui.job_manager.launch_gui_app(tweak, kwargs=dict(path=path, notify=notify)) time.sleep(2) finally: self.gui.unsetCursor()
def run(self, path_to_ebook): from calibre.ebooks.metadata.meta import get_metadata, set_metadata file = open(path_to_ebook, 'r+b') ext = os.path.splitext(path_to_ebook)[-1][1:].lower() mi = get_metadata(file, ext) genresonbook = [element.lower() for element in mi.tags] mi.tags = self.new_genre_list(genresonbook) set_metadata(file, mi, ext) print(mi) print(genresonbook) return path_to_ebook
def do_tweak(self, book_id): from calibre.utils.config_base import tweaks if not tweaks.get('test_tweak_book', False): return self.gui.iactions['Unpack Book'].do_tweak(book_id) from calibre.ebooks.oeb.polish.main import SUPPORTED db = self.gui.library_view.model().db fmts = db.formats(book_id, index_is_id=True) or '' fmts = [x.upper().strip() for x in fmts.split(',')] tweakable_fmts = set(fmts).intersection(SUPPORTED) if not tweakable_fmts: return error_dialog(self.gui, _('Cannot Tweak Book'), _('The book must be in the %s formats to tweak.' '\n\nFirst convert the book to one of these formats.') % (_(' or '.join(SUPPORTED))), show=True) from calibre.gui2.tweak_book import tprefs if len(tweakable_fmts) > 1: if tprefs['choose_tweak_fmt']: d = Choose(sorted(tweakable_fmts, key=tprefs.defaults['tweak_fmt_order'].index), self.gui) if d.exec_() != d.Accepted: return tweakable_fmts = {d.fmt} else: fmts = [f for f in tprefs['tweak_fmt_order'] if f in tweakable_fmts] if not fmts: fmts = [f for f in tprefs.defaults['tweak_fmt_order'] if f in tweakable_fmts] tweakable_fmts = {fmts[0]} fmt = tuple(tweakable_fmts)[0] path = db.new_api.format_abspath(book_id, fmt) if path is None: return error_dialog(self.gui, _('File missing'), _( 'The %s format is missing from the calibre library. You should run' ' library maintenance.') % fmt, show=True) tweak = 'ebook-tweak' self.gui.setCursor(Qt.BusyCursor) if tprefs['update_metadata_from_calibre']: from calibre.ebooks.metadata.opf2 import pretty_print from calibre.ebooks.metadata.meta import set_metadata mi = db.new_api.get_metadata(book_id) with pretty_print, open(path, 'r+b') as f: set_metadata(f, mi, stream_type=fmt.lower()) try: self.gui.job_manager.launch_gui_app(tweak, kwargs=dict(args=[tweak, path])) time.sleep(2) finally: self.gui.unsetCursor()
def update_metadata(self): """ Set the metadata in the files in the selected book's record to match the current metadata in the database. """ from calibre.ebooks.metadata.meta import set_metadata from calibre.gui2 import error_dialog, info_dialog # Get currently selected books rows = self.gui.library_view.selectionModel().selectedRows() if not rows or len(rows) == 0: return error_dialog(self.gui, "Cannot update metadata", "No books selected", show=True) # Map the rows to book ids ids = list(map(self.gui.library_view.model().id, rows)) db = self.db.new_api for book_id in ids: # Get the current metadata for this book from the db mi = db.get_metadata(book_id, get_cover=True, cover_as_data=True) fmts = db.formats(book_id) if not fmts: continue for fmt in fmts: fmt = fmt.lower() # Get a python file object for the format. This will be either # an in memory file or a temporary on disk file ffile = db.format(book_id, fmt, as_file=True) ffile.seek(0) # Set metadata in the format set_metadata(ffile, mi, fmt) ffile.seek(0) # Now replace the file in the calibre library with the updated # file. We dont use add_format_with_hooks as the hooks were # already run when the file was first added to calibre. db.add_format(book_id, fmt, ffile, run_hooks=False) info_dialog( self, "Updated files", "Updated the metadata in the files of %d book(s)" % len(ids), show=True, )
def update_metadata(self): ''' Set the metadata in the files in the selected book's record to match the current metadata in the database. ''' from calibre.ebooks.metadata.meta import set_metadata from calibre.gui2 import error_dialog, info_dialog # Get currently selected books rows = self.gui.library_view.selectionModel().selectedRows() if not rows or len(rows) == 0: return error_dialog(self.gui, 'Cannot update metadata', 'No books selected', show=True) # Map the rows to book ids ids = list(map(self.gui.library_view.model().id, rows)) for book_id in ids: # Get the current metadata for this book from the db mi = self.db.get_metadata(book_id, index_is_id=True, get_cover=True, cover_as_data=True) fmts = self.db.formats(book_id, index_is_id=True) if not fmts: continue for fmt in fmts.split(','): fmt = fmt.lower() # Get a python file object for the format. This will be either # an in memory file or a temporary on disk file ffile = self.db.format(book_id, fmt, index_is_id=True, as_file=True) # Set metadata in the format set_metadata(ffile, mi, fmt) ffile.seek(0) # Now replace the file in the calibre library with the updated # file. We dont use add_format_with_hooks as the hooks were # already run when the file was first added to calibre. ffile.name = 'xxx' # add_format() will not work if the file # path of the file being added is the same # as the path of the file being replaced self.db.add_format(book_id, fmt, ffile, index_is_id=True) info_dialog(self, 'Updated files', 'Updated the metadata in the files of %d book(s)'%len(ids), show=True)
def _populate_book_from_calibre_id(self, book, db=None): mi = db.get_metadata(book['calibre_id'], index_is_id=True) #book = {} book['good'] = True book['calibre_id'] = mi.id book['title'] = mi.title book['authors'] = mi.authors book['author_sort'] = mi.author_sort book['tags'] = mi.tags book['series'] = mi.series book['comments'] = mi.comments book['publisher'] = mi.publisher book['pubdate'] = mi.pubdate if book['series']: book['series_index'] = mi.series_index else: book['series_index'] = None book['languages'] = mi.languages book['error'] = '' if db.has_format(mi.id,'EPUB',index_is_id=True): book['epub'] = BytesIO(db.format(mi.id,'EPUB',index_is_id=True)) from calibre.ebooks.oeb.polish.container import get_container container = get_container(db.format_abspath(mi.id,'EPUB',index_is_id=True)) if container.opf_version_parsed.major >= 3: book['good'] = False; book['error'] = _("%s by %s is EPUB3, EpubMerge only supports EPUB2.")%(mi.title,', '.join(mi.authors)) else: if prefs['keepmeta']: # save calibre metadata inside epub if keeping unmerge # data. set_metadata(book['epub'], mi, stream_type='epub') book['epub_size'] = len(book['epub'].getvalue()) else: book['good'] = False; book['error'] = _("%s by %s doesn't have an EPUB.")%(mi.title,', '.join(mi.authors))
def _populate_book_from_calibre_id(self, book, db=None, tdir=None): mi = db.get_metadata(book['calibre_id'], index_is_id=True) #book = {} book['good'] = True book['calibre_id'] = mi.id book['title'] = mi.title book['authors'] = mi.authors book['author_sort'] = mi.author_sort book['tags'] = mi.tags book['series'] = mi.series book['comments'] = mi.comments book['publisher'] = mi.publisher book['pubdate'] = mi.pubdate if book['series']: book['series_index'] = mi.series_index else: book['series_index'] = None book['languages'] = mi.languages book['error'] = '' if db.has_format(mi.id,'EPUB',index_is_id=True): if prefs['keepmeta']: # save calibre metadata inside epub if keeping unmerge # data. tmp = PersistentTemporaryFile(prefix='input_%s_'%mi.id, suffix='.epub', dir=tdir) db.copy_format_to(mi.id,'EPUB',tmp,index_is_id=True) set_metadata(tmp, mi, stream_type='epub') book['epub'] = tmp.name else: # don't need metadata, use epub directly book['epub'] = db.format_abspath(mi.id,'EPUB',index_is_id=True) book['epub_size'] = os.stat(book['epub']).st_size else: book['good'] = False; book['error'] = _("%s by %s doesn't have an EPUB.")%(mi.title,', '.join(mi.authors))
stream = SpooledTemporaryFile(20*1024*1024, '_save_to_disk.'+(fmt or 'tmp')) with open(fp, 'rb') as f: shutil.copyfileobj(f, stream) stream.seek(0) written = True if opts.update_metadata: try: if cpb: newmi = mi.deepcopy_metadata() newmi.template_to_attribute(mi, cpb) else: newmi = mi if cover: newmi.cover_data = ('jpg', cover) set_metadata(stream, newmi, fmt) except: if DEBUG: traceback.print_exc() stream.seek(0) fmt_path = base_path+'.'+str(fmt) with open(fmt_path, 'wb') as f: shutil.copyfileobj(stream, f) return not written, id_, mi.title def _sanitize_args(root, opts): if opts is None: opts = config().parse() root = os.path.abspath(root)
stream = SpooledTemporaryFile(20 * 1024 * 1024, '_save_to_disk.' + (fmt or 'tmp')) with open(fp, 'rb') as f: shutil.copyfileobj(f, stream) stream.seek(0) written = True if opts.update_metadata: try: if cpb: newmi = mi.deepcopy_metadata() newmi.template_to_attribute(mi, cpb) else: newmi = mi if cover: newmi.cover_data = ('jpg', cover) set_metadata(stream, newmi, fmt) except: if DEBUG: traceback.print_exc() stream.seek(0) fmt_path = base_path + '.' + str(fmt) with open(fmt_path, 'wb') as f: shutil.copyfileobj(stream, f) return not written, id_, mi.title def _sanitize_args(root, opts): if opts is None: opts = config().parse() root = os.path.abspath(root)
def do_tweak(self, book_id): from calibre.ebooks.oeb.polish.main import SUPPORTED db = self.gui.library_view.model().db fmts = db.formats(book_id, index_is_id=True) or '' fmts = [x.upper().strip() for x in fmts.split(',')] tweakable_fmts = set(fmts).intersection(SUPPORTED) if not tweakable_fmts: return error_dialog( self.gui, _('Cannot Edit Book'), _('The book must be in the %s formats to edit.' '\n\nFirst convert the book to one of these formats.') % (_(' or '.join(SUPPORTED))), show=True) from calibre.gui2.tweak_book import tprefs tprefs.refresh() # In case they were changed in a Tweak Book process if len(tweakable_fmts) > 1: if tprefs['choose_tweak_fmt']: d = Choose( sorted(tweakable_fmts, key=tprefs.defaults['tweak_fmt_order'].index), self.gui) if d.exec_() != d.Accepted: return tweakable_fmts = {d.fmt} else: fmts = [ f for f in tprefs['tweak_fmt_order'] if f in tweakable_fmts ] if not fmts: fmts = [ f for f in tprefs.defaults['tweak_fmt_order'] if f in tweakable_fmts ] tweakable_fmts = {fmts[0]} fmt = tuple(tweakable_fmts)[0] path = db.new_api.format_abspath(book_id, fmt) if path is None: return error_dialog( self.gui, _('File missing'), _('The %s format is missing from the calibre library. You should run' ' library maintenance.') % fmt, show=True) tweak = 'ebook-edit' self.gui.setCursor(Qt.BusyCursor) if tprefs['update_metadata_from_calibre']: from calibre.ebooks.metadata.opf2 import pretty_print from calibre.ebooks.metadata.meta import set_metadata mi = db.new_api.get_metadata(book_id) with pretty_print, open(path, 'r+b') as f: set_metadata(f, mi, stream_type=fmt.lower()) notify = '%d:%s:%s:%s' % (book_id, fmt, db.library_id, db.library_path) try: self.gui.job_manager.launch_gui_app(tweak, kwargs=dict(path=path, notify=notify)) time.sleep(2) finally: self.gui.unsetCursor()
def copy_func(dest): db.copy_format_to(book_id, fmt, dest) if update_metadata: set_metadata(dest, mi, fmt) dest.seek(0)