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