forked from jgoguen/calibre-kobo-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.py
123 lines (109 loc) · 6.35 KB
/
common.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2013, Joel Goguen <[email protected]>'
__docformat__ = 'markdown en'
# Be careful editing this! This file has to work in two different packages at once,
# so don't import anything from calibre_plugins.kobotouch_extended or
# calibre_plugins.koboconversion
import os
import re
from calibre.constants import config_dir
from calibre.ebooks.metadata.book.base import NULL_VALUES
from calibre.ebooks.oeb.polish.container import OPF_NAMESPACES
from calibre.ebooks.oeb.polish.container import EpubContainer
from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils.logging import default_log
kobo_js_re = re.compile(r'.*/?kobo.*\.js$', re.IGNORECASE)
XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'
configdir = os.path.join(config_dir, 'plugins')
reference_kepub = os.path.join(configdir, 'reference.kepub.epub')
plugin_version = (2, 2, 21)
plugin_minimum_calibre_version = (1, 3, 0)
def modify_epub(container, filename, metadata=None, opts={}):
print(str(opts))
# Search for the ePub cover
found_cover = False
opf = container.opf
cover_meta_node = opf.xpath('./opf:metadata/opf:meta[@name="cover"]', namespaces=OPF_NAMESPACES)
if len(cover_meta_node) > 0:
cover_meta_node = cover_meta_node[0]
cover_id = cover_meta_node.attrib["content"] if "content" in cover_meta_node.attrib else None
if cover_id is not None:
print("KoboTouchExtended:common:modify_epub:Found cover image ID '{0}'".format(cover_id))
cover_node = opf.xpath('./opf:manifest/opf:item[@id="{0}"]'.format(cover_id), namespaces=OPF_NAMESPACES)
if len(cover_node) > 0:
cover_node = cover_node[0]
if "properties" not in cover_node.attrib or cover_node.attrib["properties"] != "cover-image":
print("KoboTouchExtended:common:modify_epub:Setting cover-image property")
cover_node.set("properties", "cover-image")
container.dirty(container.opf_name)
found_cover = True
# It's possible that the cover image can't be detected this way. Try looking for the cover image ID in the OPF manifest.
if not found_cover:
print("KoboTouchExtended:common:modify_epub:Looking for cover image in OPF manifest")
node_list = opf.xpath('./opf:manifest/opf:item[(@id="cover" or starts-with(@id, "cover")) and starts-with(@media-type, "image")]', namespaces=OPF_NAMESPACES)
if len(node_list) > 0:
node = node_list[0]
if "properties" not in node.attrib or node.attrib["properties"] != 'cover-image':
print("KoboTouchExtended:common:modify_epub:Setting cover-image")
node.set("properties", "cover-image")
container.dirty(container.opf_name)
found_cover = True
# Because of the changes made to the markup here, cleanup needs to be done before any other content file processing
container.forced_cleanup()
if 'clean_markup' in opts and opts['clean_markup'] is True:
container.clean_markup()
# Hyphenate files?
if 'hyphenate' in opts and opts['hyphenate'] is True:
if ('replace_lang' not in opts or opts['replace_lang'] is not True) or (metadata is not None and metadata.language == NULL_VALUES['language']):
print("KoboTouchExtended:common:modify_epub:WARNING - Hyphenation is enabled but not overriding content file language. Hyphenation may use the wrong dictionary.")
hyphenation_css = PersistentTemporaryFile(suffix='_hyphenate', prefix='kepub_')
hyphenation_css.write(get_resources('css/hyphenation.css'))
hyphenation_css.close()
css_path = os.path.basename(container.copy_file_to_container(hyphenation_css.name, name='kte-css/hyphenation.css'))
container.add_content_file_reference("kte-css/{0}".format(css_path))
# Override content file language
if 'replace_lang' in opts and opts['replace_lang'] is True and (metadata is not None and metadata.language != NULL_VALUES["language"]):
# First override for the OPF file
lang_node = container.opf_xpath('//opf:metadata/dc:language')
if len(lang_node) > 0:
print("KoboTouchExtended:common:modify_epub:Overriding OPF language")
lang_node = lang_node[0]
lang_node.text = metadata.language
else:
print("KoboTouchExtended:common:modify_epub:Setting OPF language")
metadata_node = container.opf_xpath('//opf:metadata')[0]
lang_node = metadata_node.makeelement("{%s}language" % OPF_NAMESPACES['dc'])
lang_node.text = metadata.language
container.insert_into_xml(metadata_node, lang_node)
container.dirty(container.opf_name)
# Now override for content files
for name in container.get_html_names():
print("KoboTouchExtended:common:modify_epub:Overriding content file language :: {0}".format(name))
root = container.parsed(name)
root.attrib["{%s}lang" % XML_NAMESPACE] = metadata.language
root.attrib["lang"] = metadata.language
# Now smarten punctuation
if 'smarten_punctuation' in opts and opts['smarten_punctuation'] is True:
container.smarten_punctuation()
if 'extended_kepub_features' in opts and opts['extended_kepub_features'] is True:
if metadata is not None:
print("KoboTouchExtended:common:modify_epub:Adding extended Kobo features to {0} by {1}".format(metadata.title, ' and '.join(metadata.authors)))
# Add the Kobo span tags
container.add_kobo_spans()
skip_js = False
# Check to see if there's already a kobo*.js in the ePub
for name in container.name_path_map:
if kobo_js_re.match(name):
skip_js = True
break
if not skip_js:
if os.path.isfile(reference_kepub):
reference_container = EpubContainer(reference_kepub, default_log)
for name in reference_container.name_path_map:
if kobo_js_re.match(name):
jsname = container.copy_file_to_container(os.path.join(reference_container.root, name), name='kobo.js')
container.add_content_file_reference(jsname)
break
os.unlink(filename)
container.commit(filename)