GwR change seek for second instance of 'metadata' in file if > 8096, variable length pad before dkey

This commit is contained in:
GRiker 2010-03-10 07:07:59 -07:00
parent c11dad792c
commit 5aaee86983

View File

@ -115,12 +115,19 @@ class MetadataUpdater(object):
first = raw.find('metadata')
if first < 0:
raise ValueError('Invalid Topaz file')
second = raw.find('metadata', first+10)
if second < 0:
raise ValueError('Invalid Topaz file')
self.md_start = second-1
self.data = StreamSlicer(stream)
self.header_records, = unpack('>B',self.data[4])
self.get_topaz_headers()
# Seek the metadata block
md_block_offset, spam = self.decode_vwi(self.data[first+9:first+13])
md_block_offset += self.base
if self.data[md_block_offset+1:md_block_offset+9] != 'metadata':
raise ValueError('Invalid Topaz file')
else:
self.md_start = md_block_offset
offset = self.get_md_header(self.md_start)
self.metadata = {}
self.md_end = self.get_original_metadata(offset)
@ -195,14 +202,16 @@ class MetadataUpdater(object):
def generate_dkey(self):
for x in self.topaz_headers:
#print "dkey['blocks']: %s" % self.topaz_headers[x]['blocks']
if self.topaz_headers[x]['tag'] == 'dkey':
offset = self.base + self.topaz_headers[x]['blocks'][0]['hdr_offset']
len_uncomp = self.topaz_headers[x]['blocks'][0]['len_uncomp']
break
if self.topaz_headers[x]['blocks']:
offset = self.base + self.topaz_headers[x]['blocks'][0]['hdr_offset']
len_uncomp = self.topaz_headers[x]['blocks'][0]['len_uncomp']
break
else:
return None
dkey = self.topaz_headers[x]
dks = StringIO.StringIO()
dks.write(self.eod)
dks.write(self.base_value)
dks.write(self.encode_vwi(len(dkey['tag'])))
offset += 1
dks.write(dkey['tag'])
@ -243,6 +252,7 @@ class MetadataUpdater(object):
offset = 5
topaz_headers = {}
dkey_offset = 0
for x in range(self.header_records):
marker = self.data[offset]
offset += 1
@ -255,6 +265,8 @@ class MetadataUpdater(object):
blocks = {}
for val in range(num_vals):
hdr_offset, consumed = self.decode_vwi(self.data[offset:offset+4])
if tag == 'dkey':
dkey_offset = hdr_offset
offset += consumed
len_uncomp, consumed = self.decode_vwi(self.data[offset:offset+4])
offset += consumed
@ -267,7 +279,9 @@ class MetadataUpdater(object):
self.eod = self.data[offset]
offset += 1
self.base = offset
self.base_value = self.data[offset]
self.base_value = None
if dkey_offset:
self.base_value = self.data[offset:offset + dkey_offset]
return md_header_offset, topaz_headers
@ -334,8 +348,6 @@ class MetadataUpdater(object):
self.metadata[item]['metadata'] = value
return
self.get_topaz_headers()
try:
from calibre.ebooks.conversion.config import load_defaults
prefs = load_defaults('mobi_output')
@ -359,9 +371,14 @@ class MetadataUpdater(object):
self.stream.seek(0)
self.stream.truncate(0)
self.stream.write(head)
self.stream.write(dkey)
self.stream.write(self.eod)
if self.base_value:
self.stream.write(self.base_value)
if dkey:
self.stream.write(dkey)
self.stream.write(updated_metadata)
self.stream.write(tail)
self.stream.close()
def set_metadata(stream, mi):
mu = MetadataUpdater(stream)