mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Remove some of the crazier aspects of the LitReader refactoring.
This commit is contained in:
parent
391e94a075
commit
83470f3d6b
@ -516,7 +516,9 @@ class TOC(object):
|
||||
|
||||
|
||||
class OEBBook(object):
|
||||
def __init__(self, opfpath, container=None):
|
||||
def __init__(self, opfpath=None, container=None):
|
||||
if not opfpath:
|
||||
opfpath = 'content.opf'
|
||||
if not container:
|
||||
container = DirContainer(os.path.dirname(opfpath))
|
||||
opfpath = os.path.basename(opfpath)
|
||||
|
@ -16,7 +16,7 @@ from lxml import etree
|
||||
from calibre.ebooks.lit import LitError
|
||||
from calibre.ebooks.lit.maps import OPF_MAP, HTML_MAP
|
||||
import calibre.ebooks.lit.mssha1 as mssha1
|
||||
from calibre.ebooks.lit.oeb import urlnormalize
|
||||
from calibre.ebooks.lit.oeb import XML_PARSER, urlnormalize
|
||||
from calibre.ebooks import DRMError
|
||||
from calibre import plugins
|
||||
lzx, lxzerror = plugins['lzx']
|
||||
@ -111,6 +111,8 @@ def consume_sized_utf8_string(bytes, zpad=False):
|
||||
pos += 1
|
||||
return u''.join(result), bytes[pos:]
|
||||
|
||||
def encode(string):
|
||||
return unicode(string).encode('ascii', 'xmlcharrefreplace')
|
||||
|
||||
class UnBinary(object):
|
||||
AMPERSAND_RE = re.compile(
|
||||
@ -126,39 +128,17 @@ class UnBinary(object):
|
||||
self.dir = os.path.dirname(path)
|
||||
buf = StringIO()
|
||||
self.binary_to_text(bin, buf)
|
||||
raw = buf.getvalue().lstrip().decode('utf-8')
|
||||
raw = self.escape_reserved(raw)
|
||||
self.tree = self.fixup_tree(raw)
|
||||
self.raw = buf.getvalue().lstrip().decode('utf-8')
|
||||
self.escape_reserved()
|
||||
self._tree = None
|
||||
|
||||
def fixup_node(self, node, in_head=False):
|
||||
in_head = in_head or (node.tag == 'head')
|
||||
if self.is_html and not in_head:
|
||||
text = node.text
|
||||
if text and text.isspace() and len(node) > 0:
|
||||
node.text = None
|
||||
span = etree.SubElement(node, 'span')
|
||||
span.text = text
|
||||
text = node.tail
|
||||
if text and text.isspace():
|
||||
node.tail = None
|
||||
if self.is_html and not in_head:
|
||||
span = etree.Element('span')
|
||||
span.text = text
|
||||
node.addnext(span)
|
||||
for child in node.iterchildren():
|
||||
if isinstance(child.tag, basestring):
|
||||
self.fixup_node(child, in_head)
|
||||
return node
|
||||
|
||||
def fixup_tree(self, raw):
|
||||
return self.fixup_node(etree.fromstring(raw))
|
||||
|
||||
def escape_reserved(self, raw):
|
||||
def escape_reserved(self):
|
||||
raw = self.raw
|
||||
raw = self.AMPERSAND_RE.sub(r'&', raw)
|
||||
raw = self.OPEN_ANGLE_RE.sub(r'<', raw)
|
||||
raw = self.CLOSE_ANGLE_RE.sub(r'>', raw)
|
||||
raw = self.DOUBLE_ANGLE_RE.sub(r'\1', raw)
|
||||
return raw
|
||||
self.raw = raw
|
||||
|
||||
def item_path(self, internal_id):
|
||||
try:
|
||||
@ -176,6 +156,17 @@ class UnBinary(object):
|
||||
relpath = (['..'] * (len(base) - index)) + target[index:]
|
||||
return '/'.join(relpath)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.raw
|
||||
|
||||
def tree():
|
||||
def fget(self):
|
||||
if not self._tree:
|
||||
self._tree = etree.fromstring(self.raw, parser=XML_PARSER)
|
||||
return self._tree
|
||||
return property(fget=fget)
|
||||
tree = tree()
|
||||
|
||||
def binary_to_text(self, bin, buf, index=0, depth=0):
|
||||
tag_name = current_map = None
|
||||
dynamic_tag = errors = 0
|
||||
@ -197,7 +188,7 @@ class UnBinary(object):
|
||||
c = '>>'
|
||||
elif c == '<':
|
||||
c = '<<'
|
||||
buf.write(c.encode('ascii', 'xmlcharrefreplace'))
|
||||
buf.write(encode(c))
|
||||
|
||||
elif state == 'get flags':
|
||||
if oc == 0:
|
||||
@ -227,7 +218,7 @@ class UnBinary(object):
|
||||
tag_name = '?'+unichr(tag)+'?'
|
||||
current_map = self.tag_to_attr_map[tag]
|
||||
print 'WARNING: tag %s unknown' % unichr(tag)
|
||||
buf.write(unicode(tag_name).encode('utf-8'))
|
||||
buf.write(encode(tag_name))
|
||||
elif flags & FLAG_CLOSING:
|
||||
if depth == 0:
|
||||
raise LitError('Extra closing tag')
|
||||
@ -246,8 +237,7 @@ class UnBinary(object):
|
||||
is_goingdown = False
|
||||
if not tag_name:
|
||||
raise LitError('Tag ends before it begins.')
|
||||
buf.write(u''.join(
|
||||
('</', tag_name, '>')).encode('utf-8'))
|
||||
buf.write(encode(u''.join(('</', tag_name, '>'))))
|
||||
dynamic_tag = 0
|
||||
tag_name = None
|
||||
state = 'text'
|
||||
@ -267,7 +257,7 @@ class UnBinary(object):
|
||||
in_censorship = True
|
||||
state = 'get value length'
|
||||
continue
|
||||
buf.write(' ' + unicode(attr).encode('utf-8') + '=')
|
||||
buf.write(' ' + encode(attr) + '=')
|
||||
if attr in ['href', 'src']:
|
||||
state = 'get href length'
|
||||
else:
|
||||
@ -297,8 +287,7 @@ class UnBinary(object):
|
||||
state = 'get attr'
|
||||
elif count > 0:
|
||||
if not in_censorship:
|
||||
buf.write(c.encode(
|
||||
'ascii', 'xmlcharrefreplace'))
|
||||
buf.write(encode(c))
|
||||
count -= 1
|
||||
if count == 0:
|
||||
if not in_censorship:
|
||||
@ -318,7 +307,7 @@ class UnBinary(object):
|
||||
tag_name += c
|
||||
count -= 1
|
||||
if count == 0:
|
||||
buf.write(unicode(tag_name).encode('utf-8'))
|
||||
buf.write(encode(tag_name))
|
||||
state = 'get attr'
|
||||
|
||||
elif state == 'get attr length':
|
||||
@ -329,7 +318,7 @@ class UnBinary(object):
|
||||
state = 'get custom attr'
|
||||
|
||||
elif state == 'get custom attr':
|
||||
buf.write(unicode(c).encode('utf-8'))
|
||||
buf.write(encode(c))
|
||||
count -= 1
|
||||
if count == 0:
|
||||
buf.write('=')
|
||||
@ -351,7 +340,7 @@ class UnBinary(object):
|
||||
if frag:
|
||||
path = '#'.join((path, frag))
|
||||
path = urlnormalize(path)
|
||||
self.buf.write((u'"%s"' % path).encode('utf-8'))
|
||||
buf.write(encode(u'"%s"' % path))
|
||||
state = 'get attr'
|
||||
return index
|
||||
|
||||
@ -820,19 +809,6 @@ class LitReader(object):
|
||||
def namelist(self):
|
||||
return self._litfile.paths.keys()
|
||||
|
||||
def _read_meta(self):
|
||||
path = 'content.opf'
|
||||
raw = self._litfile.get_file('/meta')
|
||||
try:
|
||||
unbin = UnBinary(raw, path, self._litfile.manifest, OPF_MAP)
|
||||
except LitError:
|
||||
if 'PENGUIN group' not in raw: raise
|
||||
print "WARNING: attempting PENGUIN malformed OPF fix"
|
||||
raw = raw.replace(
|
||||
'PENGUIN group', '\x00\x01\x18\x00PENGUIN group', 1)
|
||||
unbin = UnBinary(raw, path, self._litfile.manifest, OPF_MAP)
|
||||
return unbin.tree
|
||||
|
||||
def read_xml(self, name):
|
||||
entry = self._litfile.paths[name] if name else None
|
||||
if entry is None:
|
||||
@ -856,8 +832,12 @@ class LitReader(object):
|
||||
internal = '/'.join(('/data', entry.internal, 'content'))
|
||||
raw = self._litfile.get_file(internal)
|
||||
unbin = UnBinary(raw, name, self._litfile.manifest, HTML_MAP)
|
||||
content = HTML_DECL + etree.tostring(
|
||||
unbin.tree, encoding='ascii', pretty_print=pretty_print)
|
||||
content = HTML_DECL
|
||||
if pretty_print:
|
||||
content += etree.tostring(unbin.tree,
|
||||
encoding='ascii', pretty_print=True)
|
||||
else:
|
||||
content += unicode(unbin)
|
||||
else:
|
||||
internal = '/'.join(('/data', entry.internal))
|
||||
content = self._litfile.get_file(internal)
|
||||
@ -881,6 +861,19 @@ class LitReader(object):
|
||||
with open(path, 'wb') as f:
|
||||
f.write(self.read(name, pretty_print=pretty_print))
|
||||
|
||||
def _read_meta(self):
|
||||
path = 'content.opf'
|
||||
raw = self._litfile.get_file('/meta')
|
||||
try:
|
||||
unbin = UnBinary(raw, path, self._litfile.manifest, OPF_MAP)
|
||||
except LitError:
|
||||
if 'PENGUIN group' not in raw: raise
|
||||
print "WARNING: attempting PENGUIN malformed OPF fix"
|
||||
raw = raw.replace(
|
||||
'PENGUIN group', '\x00\x01\x18\x00PENGUIN group', 1)
|
||||
unbin = UnBinary(raw, path, self._litfile.manifest, OPF_MAP)
|
||||
return unbin.tree
|
||||
|
||||
|
||||
def option_parser():
|
||||
from calibre.utils.config import OptionParser
|
||||
|
Loading…
x
Reference in New Issue
Block a user