def main(args=sys.argv, name=''): log = Log() parser = option_parser(name) add_options(parser) opts, args = parser.parse_args(args) args = args[1:] if len(args) < 2: print 'Error: Two or more PDF files are required.\n' print_help(parser, log) return 1 bad_pdfs = is_valid_pdfs(args) if bad_pdfs != []: for pdf in bad_pdfs: print 'Error: Could not read file `%s`.' % pdf return 1 enc = False for pdf in args: if is_encrypted(pdf): enc = True print 'Error: file `%s` is encrypted.' % pdf if enc: return 1 mi = metadata_from_formats([args[0]]) merge_files(args, opts.output, mi) return 0
def format_group(db, notify_changes, is_remote, args): formats, add_duplicates, cover_data = args with add_ctx(), TemporaryDirectory( 'add-multiple') as tdir, run_import_plugins_before_metadata(tdir): if is_remote: paths = [] for name, data in formats: with lopen(os.path.join(tdir, os.path.basename(name)), 'wb') as f: f.write(data) paths.append(f.name) else: paths = list(formats) paths = run_import_plugins(paths) mi = metadata_from_formats(paths) if mi.title is None: return None, set(), False if cover_data and not mi.cover_data or not mi.cover_data[1]: mi.cover_data = 'jpeg', cover_data ids, dups = db.add_books([(mi, create_format_map(paths))], add_duplicates=add_duplicates, run_hooks=False) if is_remote: notify_changes(books_added(ids)) db.dump_metadata() return mi.title, ids, bool(dups)
def import_book_directory(db, dirpath, callback=None, added_ids=None, compiled_rules=(), add_duplicates=False): from calibre.ebooks.metadata.meta import metadata_from_formats dirpath = os.path.abspath(dirpath) formats = None for formats in find_books_in_directory(dirpath, True, compiled_rules=compiled_rules): break if not formats: return mi = metadata_from_formats(formats) if mi.title is None: return ids, dups = db.new_api.add_books([(mi, create_format_map(formats))], add_duplicates=add_duplicates) if dups: return [(mi, formats)] book_id = next(iter(ids)) if added_ids is not None: added_ids.add(book_id) if callable(callback): callback(mi.title)
def import_book_directory_multiple(db, dirpath, callback=None, added_ids=None, compiled_rules=(), add_duplicates=False): from calibre.ebooks.metadata.meta import metadata_from_formats duplicates = [] for formats in find_books_in_directory(dirpath, False, compiled_rules=compiled_rules): mi = metadata_from_formats(formats) if mi.title is None: continue ids, dups = db.new_api.add_books([(mi, create_format_map(formats))], add_duplicates=add_duplicates) if dups: duplicates.append((mi, formats)) continue book_id = next(iter(ids)) if added_ids is not None: added_ids.add(book_id) if callable(callback): if callback(mi.title): break return duplicates
def _from_formats(self, id, args, kwargs): from calibre.ebooks.metadata.meta import metadata_from_formats try: mi = metadata_from_formats(*args, **kwargs) except: mi = MetaInformation('', [_('Unknown')]) self.emit(SIGNAL('metadataf(PyQt_PyObject, PyQt_PyObject)'), id, mi)
def main(args=sys.argv, name=''): log = Log() parser = option_parser(name) add_options(parser) opts, args = parser.parse_args(args) args = args[1:] if len(args) < 1: print 'Error: A PDF file is required.\n' print_help(parser, log) return 1 if not is_valid_pdf(args[0]): print 'Error: Could not read file `%s`.' % args[0] return 1 if is_encrypted(args[0]): print 'Error: file `%s` is encrypted.' % args[0] return 1 mi = metadata_from_formats([args[0]]) reverse(args[0], opts.output, mi) return 0
def metadata_from_formats(cls, fmts): from calibre.ebooks.metadata.meta import metadata_from_formats from calibre.customize.ui import quick_metadata with quick_metadata: return metadata_from_formats(fmts, force_read_metadata=True, pattern=cls.build_template_regexp())
def format_group(db, notify_changes, is_remote, args): formats, add_duplicates, oautomerge, request_id, cover_data = args with add_ctx(), TemporaryDirectory( 'add-multiple') as tdir, run_import_plugins_before_metadata(tdir): updated_ids = {} if is_remote: paths = [] for name, data in formats: with lopen(os.path.join(tdir, os.path.basename(name)), 'wb') as f: f.write(data) paths.append(f.name) else: paths = list(formats) paths = run_import_plugins(paths) mi = metadata_from_formats(paths) if mi.title is None: return None, set(), set(), False if cover_data and not mi.cover_data or not mi.cover_data[1]: mi.cover_data = 'jpeg', cover_data format_map = create_format_map(paths) added_ids, updated_ids, duplicates = do_adding( db, request_id, notify_changes, is_remote, mi, format_map, add_duplicates, oautomerge) return mi.title, set(added_ids), set(updated_ids), bool(duplicates)
def main(args=sys.argv, name=''): log = Log() parser = option_parser(name) add_options(parser) opts, args = parser.parse_args(args) args = args[1:] if len(args) < 2: print 'Error: A PDF file and decryption password is required.\n' print_help(parser, log) return 1 if not is_valid_pdf(args[0]): print 'Error: Could not read file `%s`.' % args[0] return 1 if is_encrypted(args[0]): print 'Error: file `%s` is already encrypted.' % args[0] return 1 mi = metadata_from_formats([args[0]]) encrypt(args[0], opts.output, args[1], mi) return 0
def _from_formats(self, id, args, kwargs): from calibre.ebooks.metadata.meta import metadata_from_formats try: mi = metadata_from_formats(*args, **kwargs) except: mi = MetaInformation('', [_('Unknown')]) self.metadataf.emit(id, mi)
def main(args=sys.argv, name=''): log = Log() parser = option_parser(name) add_options(parser) opts, args = parser.parse_args(args) pdf, pages, page_ranges, unknown = split_args(args[1:]) if pdf == '' and (pages == [] or page_ranges == []): print 'Error: PDF and where to split is required.\n' print_help(parser, log) return 1 if unknown != []: for arg in unknown: print 'Error: Unknown argument `%s`' % arg print_help(parser, log) return 1 if not is_valid_pdf(pdf): print 'Error: Could not read file `%s`.' % pdf return 1 if is_encrypted(pdf): print 'Error: file `%s` is encrypted.' % args[0] return 1 pages, page_ranges = clean_page_list(pdf, pages, page_ranges) mi = metadata_from_formats([pdf]) split_pdf(pdf, pages, page_ranges, os.path.splitext(opts.output)[0], mi) return 0
def add(self, path=None, identifier=None): db = self.db print "Library database object is (%s)" % (db) # If file is not a correct zip, something went wrong, so continue with next file with zipfile.ZipFile(path, 'r') as zipf: if zipf.testzip() is not None: os.remove(path) pass # Now we know that the ebook is cached locally and is a valid zip file... print "Book Path: %s" % (path) formats = [path] print " Formats: %s" % (formats) mi = metadata_from_formats(formats) print " Obtained Metadata: %s" % (mi) internal_book_id = None if db.has_book(mi): print " Book already available in DB, would have to enhance with %s id %s" % ( self.indentifier_name, identifier) book_ids = db.books_with_same_title(mi) print " books_with_same_title: %s" % (book_ids) # Now, we should iterate over all books and try to match author as well.... # Well, next time :-) try: internal_book_id = book_ids.pop() print " ID of pre-existing book: %s" % ( internal_book_id) except: print "Unexpected error:", sys.exc_info()[0] pass else: print " New Book, trying to add it to database" internal_book_id = db.import_book(mi, formats) print " ID of new book: %s" % (internal_book_id) if internal_book_id is not None: print " Enhancing book #%s with %s id '%s'" % ( internal_book_id, self.indentifier_name, identifier) identifiers = db.get_identifiers(internal_book_id, index_is_id=True) print " Old Identifiers: %s" % (identifiers) identifiers[self.indentifier_name] = identifier db.set_identifiers(internal_book_id, identifiers, notify=True, commit=True) identifiers = db.get_identifiers(internal_book_id, index_is_id=True) print " New Identifiers: %s" % (identifiers)
def read_metadata_bulk(get_opf, get_cover, paths): mi = metadata_from_formats(paths) mi.cover = None cdata = None if mi.cover_data: cdata = mi.cover_data[-1] mi.cover_data = (None, None) if not mi.application_id: mi.application_id = '__calibre_dummy__' ans = {'opf': None, 'cdata': None} if get_opf: ans['opf'] = metadata_to_opf(mi, default_lang='und') if get_cover: ans['cdata'] = cdata return ans
def serialize_metadata_for(paths, tdir, group_id): mi = metadata_from_formats(paths) mi.cover = None cdata = None if mi.cover_data: cdata = mi.cover_data[-1] mi.cover_data = (None, None) if not mi.application_id: mi.application_id = '__calibre_dummy__' opf = metadata_to_opf(mi, default_lang='und') has_cover = False if cdata: with open(os.path.join(tdir, '%s.cdata' % group_id), 'wb') as f: f.write(cdata) has_cover = True return mi, opf, has_cover
def serialize_metadata_for(formats, tdir, id_): from calibre.ebooks.metadata.meta import metadata_from_formats from calibre.ebooks.metadata.opf2 import metadata_to_opf mi = metadata_from_formats(formats) mi.cover = None cdata = None if mi.cover_data: cdata = mi.cover_data[-1] mi.cover_data = None if not mi.application_id: mi.application_id = '__calibre_dummy__' with open(os.path.join(tdir, '%s.opf'%id_), 'wb') as f: f.write(metadata_to_opf(mi, default_lang='und')) if cdata: with open(os.path.join(tdir, str(id_)), 'wb') as f: f.write(cdata)
def serialize_metadata_for(formats, tdir, id_): from calibre.ebooks.metadata.meta import metadata_from_formats from calibre.ebooks.metadata.opf2 import metadata_to_opf mi = metadata_from_formats(formats) mi.cover = None cdata = None if mi.cover_data: cdata = mi.cover_data[-1] mi.cover_data = None if not mi.application_id: mi.application_id = '__calibre_dummy__' with open(os.path.join(tdir, '%s.opf' % id_), 'wb') as f: f.write(metadata_to_opf(mi, default_lang='und')) if cdata: with open(os.path.join(tdir, str(id_)), 'wb') as f: f.write(cdata)
def import_book_directory(db, dirpath, callback=None, added_ids=None): from calibre.ebooks.metadata.meta import metadata_from_formats dirpath = os.path.abspath(dirpath) formats = find_books_in_directory(dirpath, True) formats = list(formats)[0] if not formats: return mi = metadata_from_formats(formats) if mi.title is None: return if db.has_book(mi): return [(mi, formats)] book_id = db.import_book(mi, formats) if added_ids is not None: added_ids.add(book_id) if callable(callback): callback(mi.title)
def add(self, path = None, identifier = None): db = self.db print "Library database object is (%s)" % (db) # If file is not a correct zip, something went wrong, so continue with next file with zipfile.ZipFile(path, 'r') as zipf: if zipf.testzip() is not None: os.remove(path) pass # Now we know that the ebook is cached locally and is a valid zip file... print "Book Path: %s" % (path) formats = [ path ] print " Formats: %s" % (formats) mi = metadata_from_formats(formats) print " Obtained Metadata: %s" % (mi) internal_book_id = None if db.has_book(mi): print " Book already available in DB, would have to enhance with %s id %s" % (self.indentifier_name, identifier) book_ids = db.books_with_same_title(mi) print " books_with_same_title: %s" % (book_ids) # Now, we should iterate over all books and try to match author as well.... # Well, next time :-) try: internal_book_id = book_ids.pop() print " ID of pre-existing book: %s" % (internal_book_id) except: print "Unexpected error:", sys.exc_info()[0] pass else: print " New Book, trying to add it to database" internal_book_id = db.import_book(mi, formats) print " ID of new book: %s" % (internal_book_id) if internal_book_id is not None: print " Enhancing book #%s with %s id '%s'" % (internal_book_id, self.indentifier_name, identifier) identifiers = db.get_identifiers(internal_book_id, index_is_id=True) print " Old Identifiers: %s" % (identifiers) identifiers[self.indentifier_name] = identifier db.set_identifiers(internal_book_id, identifiers, notify=True, commit=True) identifiers = db.get_identifiers(internal_book_id, index_is_id=True) print " New Identifiers: %s" % (identifiers)
def import_book_directory_multiple(db, dirpath, callback=None, added_ids=None): from calibre.ebooks.metadata.meta import metadata_from_formats duplicates = [] for formats in find_books_in_directory(dirpath, False): mi = metadata_from_formats(formats) if mi.title is None: continue if db.has_book(mi): duplicates.append((mi, formats)) continue book_id = db.import_book(mi, formats) if added_ids is not None: added_ids.add(book_id) if callable(callback): if callback(mi.title): break return duplicates
def format_group(db, notify_changes, is_remote, args): formats, add_duplicates = args with add_ctx(), TemporaryDirectory('add-multiple') as tdir, run_import_plugins_before_metadata(tdir): if is_remote: paths = [] for name, data in formats: with lopen(os.path.join(tdir, name), 'wb') as f: f.write(data) paths.append(f.name) else: paths = list(formats) paths = run_import_plugins(paths) mi = metadata_from_formats(paths) if mi.title is None: return None, set(), False ids, dups = db.add_books([(mi, create_format_map(paths))], add_duplicates=add_duplicates, run_hooks=False) if is_remote: notify_changes(books_added(ids)) db.dump_metadata() return mi.title, ids, bool(dups)
def unmerge(self): if len(self.gui.library_view.get_selected_ids()) != 1: d = error_dialog(self.gui, _('Select One Book'), _('Please select exactly one book to UnMerge.'), show_copy_button=False) d.exec_() else: db=self.gui.current_db book_id=self.gui.library_view.get_selected_ids()[0] if db.has_format(book_id,'EPUB',index_is_id=True): epub = StringIO(db.format(book_id,'EPUB',index_is_id=True)) else: d = error_dialog(self.gui, _('Cannot UnMerge Non-Epubs'), _('To UnMerge the source must be Epub(s) created by EpubMerge with Keep UnMerge Metadata enabled.'), show_copy_button=False) d.exec_() remove_dir(tdir) return tdir = PersistentTemporaryDirectory(prefix='epubmerge_') print("tdir:%s"%tdir) outfilenames = self.do_unmerge(epub,tdir) if not outfilenames: d = error_dialog(self.gui, _('No UnMerge data found'), _('To UnMerge the source must be Epub(s) created by EpubMerge with Keep UnMerge Metadata enabled.'), show_copy_button=False) d.exec_() return #db.import_book_directory_multiple(tdir) XXX #self.gui.library_view.model().books_added(len(outfilenames)) added_list=[] updated_list=[] for formats in db.find_books_in_directory(tdir, False): #print("formats:%s"%formats) mi = metadata_from_formats(formats) #print("mi:%s"%mi) state = 'add' identicalbooks = db.find_identical_books(mi) if identicalbooks: if len(identicalbooks) == 1: text = _("You already have a book <i>%s</i> by <i>%s</i>. You may Add a new book of the same title, Overwrite the Epub in the existing book, or Discard this Epub.")%(mi.title,", ".join(mi.authors)) over=True else: text = _("You already have more than one book <i>%s</i> by <i>%s</i>. You may Add a new book of the same title, or Discard this Epub.")%(mi.title,", ".join(mi.authors)) over=False d = AddOverDiscardDialog(self.gui,self.qaction.icon(),text,over=over) d.exec_() state=d.state if not state or state == 'discard': continue elif state == 'add': book_id = db.create_book_entry(mi, add_duplicates=True) added_list.append(book_id) else: book_id = identicalbooks.pop() db.add_format_with_hooks(book_id, 'EPUB', formats[0], index_is_id=True) updated_list.append(book_id) if len(added_list): self.gui.library_view.model().books_added(len(added_list)) if len(updated_list): self.gui.library_view.model().refresh_ids(updated_list) remove_dir(tdir)
def unmerge(self): db = self.gui.current_db applyall = False state = 'add' for book_id in self.gui.library_view.get_selected_ids(): unmerge_mi = db.get_metadata(book_id, index_is_id=True) # if len(self.gui.library_view.get_selected_ids()) != 1: # d = error_dialog(self.gui, # _('Select One Book'), # _('Please select exactly one book to UnMerge.'), # show_copy_button=False) # d.exec_() # else: # book_id=[0] if db.has_format(book_id, 'EPUB', index_is_id=True): epub = StringIO(db.format(book_id, 'EPUB', index_is_id=True)) else: d = error_dialog( self.gui, _('Cannot UnMerge Non-Epubs'), unmerge_mi.title + '<br>' + _('To UnMerge the source must be Epub(s) created by EpubMerge with Keep UnMerge Metadata enabled.' ), show_copy_button=False) d.exec_() continue tdir = PersistentTemporaryDirectory(prefix='epubmerge_') logger.debug("tdir:%s" % tdir) outfilenames = self.do_unmerge(epub, tdir) if not outfilenames: d = error_dialog( self.gui, _('No UnMerge data found'), unmerge_mi.title + '<br>' + _('To UnMerge the source must be Epub(s) created by EpubMerge with Keep UnMerge Metadata enabled.' ), show_copy_button=False) d.exec_() remove_dir(tdir) continue #db.import_book_directory_multiple(tdir) XXX #self.gui.library_view.model().books_added(len(outfilenames)) added_list = [] updated_list = [] for formats in db.find_books_in_directory(tdir, False): #logger.debug("formats:%s"%formats) mi = metadata_from_formats(formats) #logger.debug("mi:%s"%mi) identicalbooks = db.find_identical_books(mi) if identicalbooks: if len(identicalbooks) == 1: text = unmerge_mi.title + '<br>' + _( "You already have a book <i>%s</i> by <i>%s</i>. You may Add a new book of the same title, Overwrite the Epub in the existing book, or Discard this Epub." ) % (mi.title, ", ".join(mi.authors)) over = True else: text = unmerge_mi.title + '<br>' + _( "You already have more than one book <i>%s</i> by <i>%s</i>. You may Add a new book of the same title, or Discard this Epub." ) % (mi.title, ", ".join(mi.authors)) over = False #logger.debug("applyall:%s over:%s state:%s"%(applyall,over, state)) if applyall and (over or state in ('add', 'discard')): # use previous state. pass else: d = AddOverDiscardDialog(self.gui, self.qaction.icon(), text, over=over) d.exec_() state = d.state applyall = d.get_applyall() if state == 'add' or len(identicalbooks) == 0: book_id = db.create_book_entry(mi, add_duplicates=True) added_list.append(book_id) elif state == 'discard': continue elif state == 'over': book_id = identicalbooks.pop() db.add_format_with_hooks(book_id, 'EPUB', formats[0], index_is_id=True) updated_list.append(book_id) if len(added_list): self.gui.library_view.model().books_added(len(added_list)) if len(updated_list): self.gui.library_view.model().refresh_ids(updated_list) remove_dir(tdir)