From 34d3ce25aa9cad874549cbf4e539e745e343582e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 22 Jul 2011 20:16:05 -0600 Subject: [PATCH] ... --- src/calibre/ebooks/mobi/writer2/indexer.py | 36 +++++++++++++++---- src/calibre/ebooks/mobi/writer2/main.py | 9 +++-- src/calibre/ebooks/mobi/writer2/serializer.py | 1 + 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/calibre/ebooks/mobi/writer2/indexer.py b/src/calibre/ebooks/mobi/writer2/indexer.py index c28b91e63a..e586c446b4 100644 --- a/src/calibre/ebooks/mobi/writer2/indexer.py +++ b/src/calibre/ebooks/mobi/writer2/indexer.py @@ -12,6 +12,7 @@ from cStringIO import StringIO from collections import OrderedDict from calibre.ebooks import normalize +from calibre.ebook.mobi.writer2 import RECORD_SIZE from calibre.ebooks.mobi.utils import encint def utf8_text(text): @@ -37,7 +38,6 @@ def align_block(raw, multiple=4, pad=b'\0'): if extra == 0: return raw return raw + pad*(multiple - extra) - class CNCX(object): # {{{ ''' @@ -53,17 +53,15 @@ class CNCX(object): # {{{ for item in toc: if item is self.toc: continue - label = item.title - klass = item.klass + self.strings[item.title] = 0 if opts.mobi_periodical: + self.strings[item.klass] = 0 if item.description: self.strings[item.description] = 0 if item.author: self.string[item.author] = 0 - self.strings[label] = self.strings[klass] = 0 self.records = [] - offset = 0 buf = StringIO() for key in tuple(self.strings.iterkeys()): @@ -92,17 +90,41 @@ class CNCX(object): # {{{ class Indexer(object): - def __init__(self, serializer, number_of_text_records, opts, oeb): + def __init__(self, serializer, number_of_text_records, + size_of_last_text_record, opts, oeb): self.serializer = serializer self.number_of_text_records = number_of_text_records + self.text_size = (RECORD_SIZE * (self.number_of_text_records-1) + + size_of_last_text_record) self.oeb = oeb self.log = oeb.log self.opts = opts - self.cncx = CNCX(oeb.toc, opts) + self.is_periodical = opts.mobi_periodical + self.is_flat_periodical = False + if opts.mobi_periodical: + periodical_node = iter(oeb.toc).next() + sections = tuple(periodical_node) + self.is_flat_periodical = len(sections) == 1 self.records = [] + self.cncx = CNCX(oeb.toc, opts) + + if self.is_periodical: + self.create_periodical_index() + else: + raise NotImplementedError() + + def create_periodical_index(self): + periodical_node = iter(self.oeb.toc).next() + sections = tuple(periodical_node) + periodical_node_offset = self.serializer.body_start_offset + periodical_node_size = (self.serializer.body_end_offset - + periodical_node_offset) + periodical_node_size + sections + def create_header(self): buf = StringIO() diff --git a/src/calibre/ebooks/mobi/writer2/main.py b/src/calibre/ebooks/mobi/writer2/main.py index 088326a876..ea67007168 100644 --- a/src/calibre/ebooks/mobi/writer2/main.py +++ b/src/calibre/ebooks/mobi/writer2/main.py @@ -20,6 +20,7 @@ from calibre.utils.filenames import ascii_filename from calibre.ebooks.mobi.writer2 import (PALMDOC, UNCOMPRESSED, RECORD_SIZE) from calibre.ebooks.mobi.utils import (rescale_image, encint, encode_trailing_data) +from calibre.ebooks.mobi.writer2.indexer import Indexer EXTH_CODES = { 'creator': 100, @@ -87,6 +88,11 @@ class MobiWriter(object): # Indexing {{{ def generate_index(self): self.primary_index_record_idx = None + try: + self.indexer = Indexer(self.serializer, self.last_text_record_idx, + self.opts, self.oeb) + except: + self.log.exception('Failed to generate MOBI index:') # }}} def write_uncrossable_breaks(self): # {{{ @@ -202,7 +208,6 @@ class MobiWriter(object): record.write(overlap) record.write(pack(b'>B', len(overlap))) - self.last_text_record_idx = nrecords def read_text_record(self, text): @@ -265,8 +270,6 @@ class MobiWriter(object): # EOF record self.records.append('\xE9\x8E\x0D\x0A') - self.generate_end_records() - record0 = StringIO() # The MOBI Header record0.write(pack(b'>HHIHHHH', diff --git a/src/calibre/ebooks/mobi/writer2/serializer.py b/src/calibre/ebooks/mobi/writer2/serializer.py index d6878bee4a..881937ce73 100644 --- a/src/calibre/ebooks/mobi/writer2/serializer.py +++ b/src/calibre/ebooks/mobi/writer2/serializer.py @@ -143,6 +143,7 @@ class Serializer(object): spine.extend([item for item in self.oeb.spine if not item.linear]) for item in spine: self.serialize_item(item) + self.body_end_offset = buf.tell() buf.write(b'') def serialize_item(self, item):