1#!/usr/local/bin/python3.8 2# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai 3# License: GPLv3 Copyright: 2009, Kovid Goyal <kovid at kovidgoyal.net> 4 5import os 6import shutil 7 8from calibre.customize.ui import run_plugins_on_import 9from calibre.ebooks.metadata.meta import metadata_from_formats 10from calibre.ebooks.metadata.opf2 import metadata_to_opf 11from calibre.utils.filenames import samefile 12 13 14def serialize_metadata_for(paths, tdir, group_id): 15 mi = metadata_from_formats(paths) 16 mi.cover = None 17 cdata = None 18 if mi.cover_data: 19 cdata = mi.cover_data[-1] 20 mi.cover_data = (None, None) 21 if not mi.application_id: 22 mi.application_id = '__calibre_dummy__' 23 opf = metadata_to_opf(mi, default_lang='und') 24 has_cover = False 25 if cdata: 26 with open(os.path.join(tdir, '%s.cdata' % group_id), 'wb') as f: 27 f.write(cdata) 28 has_cover = True 29 return mi, opf, has_cover 30 31 32def read_metadata_bulk(get_opf, get_cover, paths): 33 mi = metadata_from_formats(paths) 34 mi.cover = None 35 cdata = None 36 if mi.cover_data: 37 cdata = mi.cover_data[-1] 38 mi.cover_data = (None, None) 39 if not mi.application_id: 40 mi.application_id = '__calibre_dummy__' 41 ans = {'opf': None, 'cdata': None} 42 if get_opf: 43 ans['opf'] = metadata_to_opf(mi, default_lang='und') 44 if get_cover: 45 ans['cdata'] = cdata 46 return ans 47 48 49def run_import_plugins(paths, group_id, tdir): 50 final_paths = [] 51 for path in paths: 52 if not os.access(path, os.R_OK): 53 continue 54 try: 55 nfp = run_plugins_on_import(path) 56 except Exception: 57 nfp = None 58 import traceback 59 traceback.print_exc() 60 if nfp and os.access(nfp, os.R_OK) and not samefile(nfp, path): 61 # Ensure that the filename is preserved so that 62 # reading metadata from filename is not broken 63 name = os.path.splitext(os.path.basename(path))[0] 64 ext = os.path.splitext(nfp)[1] 65 path = os.path.join(tdir, str(group_id), name + ext) 66 os.makedirs(os.path.dirname(path), exist_ok=True) 67 try: 68 os.replace(nfp, path) 69 except OSError: 70 shutil.copyfile(nfp, path) 71 final_paths.append(path) 72 return final_paths 73 74 75def has_book(mi, data_for_has_book): 76 return mi.title and icu_lower(mi.title.strip()) in data_for_has_book 77 78 79def read_metadata(paths, group_id, tdir, common_data=None): 80 paths = run_import_plugins(paths, group_id, tdir) 81 mi, opf, has_cover = serialize_metadata_for(paths, tdir, group_id) 82 duplicate_info = None 83 if isinstance(common_data, (set, frozenset)): 84 duplicate_info = has_book(mi, common_data) 85 return paths, opf, has_cover, duplicate_info 86