This commit is contained in:
Kovid Goyal 2010-03-05 13:25:20 -07:00
commit 1274225932
2 changed files with 19 additions and 19 deletions

View File

@ -185,6 +185,7 @@ class Bookmark():
from calibre.ebooks.metadata.mobi import StreamSlicer from calibre.ebooks.metadata.mobi import StreamSlicer
user_notes = {} user_notes = {}
if self.bookmark_extension == 'mbp': if self.bookmark_extension == 'mbp':
MAGIC_MOBI_CONSTANT = 150
with open(path,'rb') as f: with open(path,'rb') as f:
stream = StringIO(f.read()) stream = StringIO(f.read())
data = StreamSlicer(stream) data = StreamSlicer(stream)
@ -192,7 +193,7 @@ class Bookmark():
bpar_offset, = unpack('>I', data[0x4e:0x52]) bpar_offset, = unpack('>I', data[0x4e:0x52])
lrlo = bpar_offset + 0x0c lrlo = bpar_offset + 0x0c
self.last_read = int(unpack('>I', data[lrlo:lrlo+4])[0]) self.last_read = int(unpack('>I', data[lrlo:lrlo+4])[0])
self.last_read_location = self.last_read/150 + 1 self.last_read_location = self.last_read/MAGIC_MOBI_CONSTANT + 1
entries, = unpack('>I', data[0x4a:0x4e]) entries, = unpack('>I', data[0x4a:0x4e])
# Store the annotations/locations # Store the annotations/locations
@ -204,7 +205,6 @@ class Bookmark():
# Walk bookmark entries # Walk bookmark entries
#print " --- %s --- " % path #print " --- %s --- " % path
#print " last_read_location: %d" % self.magicKindleLocationCalculator(last_read_location)
current_entry = 1 current_entry = 1
sig = data[eo:eo+4] sig = data[eo:eo+4]
previous_block = None previous_block = None
@ -229,14 +229,11 @@ class Bookmark():
text = data[eo+8:eo+8+rec_len].decode('utf-16-be') text = data[eo+8:eo+8+rec_len].decode('utf-16-be')
if entry_type: if entry_type:
displayed_location = location/150 + 1 displayed_location = location/MAGIC_MOBI_CONSTANT + 1
user_notes[location] = dict(id=self.id, user_notes[location] = dict(id=self.id,
displayed_location=displayed_location, displayed_location=displayed_location,
type=entry_type, type=entry_type,
text=text) text=text)
#print " %2d: %s %s" % (current_entry, entry_type,'at %d' % location if location else '')
#if current_block == 'text_block':
#self.textdump(text)
eo += rec_len + 8 eo += rec_len + 8
current_entry += 1 current_entry += 1
@ -246,17 +243,19 @@ class Bookmark():
while sig == 'BKMK': while sig == 'BKMK':
# Fix start location for Highlights using BKMK data # Fix start location for Highlights using BKMK data
end_loc, = unpack('>I', data[eo+0x10:eo+0x14]) end_loc, = unpack('>I', data[eo+0x10:eo+0x14])
if end_loc in user_notes and user_notes[end_loc]['type'] != 'Note': if end_loc in user_notes and user_notes[end_loc]['type'] == 'Highlight':
start, = unpack('>I', data[eo+8:eo+12]) start, = unpack('>I', data[eo+8:eo+12])
user_notes[start] = user_notes[end_loc] user_notes[start] = user_notes[end_loc]
user_notes.pop(end_loc) user_notes.pop(end_loc)
#print "changing start location of %d to %d" % (end_loc,start) elif end_loc in user_notes and user_notes[end_loc]['type'] == 'Note':
# Skip duplicate bookmarks for notes
pass
else: else:
# If a bookmark coincides with a user annotation, the locs could # If a bookmark coincides with a user annotation, the locs could
# be the same - cheat by nudging -1 # be the same - cheat by nudging -1
# Skip bookmark for last_read_location # Skip bookmark for last_read_location
if end_loc != self.last_read: if end_loc != self.last_read:
displayed_location = end_loc/150 + 1 displayed_location = end_loc/MAGIC_MOBI_CONSTANT + 1
user_notes[end_loc - 1] = dict(id=self.id, user_notes[end_loc - 1] = dict(id=self.id,
displayed_location=displayed_location, displayed_location=displayed_location,
type='Bookmark', type='Bookmark',
@ -267,12 +266,13 @@ class Bookmark():
elif self.bookmark_extension == 'tan': elif self.bookmark_extension == 'tan':
# TAN bookmarks # TAN bookmarks
MAGIC_TOPAZ_CONSTANT = 33.33
self.timestamp = os.path.getmtime(path) self.timestamp = os.path.getmtime(path)
with open(path,'rb') as f: with open(path,'rb') as f:
stream = StringIO(f.read()) stream = StringIO(f.read())
data = StreamSlicer(stream) data = StreamSlicer(stream)
self.last_read = int(unpack('>I', data[5:9])[0]) self.last_read = int(unpack('>I', data[5:9])[0])
self.last_read_location = self.last_read/33.33 + 1 self.last_read_location = self.last_read/MAGIC_TOPAZ_CONSTANT + 1
entries, = unpack('>I', data[9:13]) entries, = unpack('>I', data[9:13])
current_entry = 0 current_entry = 0
e_base = 0x0d e_base = 0x0d
@ -294,7 +294,7 @@ class Bookmark():
if self.book_format in ['tpz','azw1']: if self.book_format in ['tpz','azw1']:
# *** This needs fine-tuning # *** This needs fine-tuning
displayed_location = location/33.33 + 1 displayed_location = location/MAGIC_TOPAZ_CONSTANT + 1
elif self.book_format == 'pdf': elif self.book_format == 'pdf':
# *** This needs testing # *** This needs testing
displayed_location = location displayed_location = location

View File

@ -13,8 +13,8 @@ from calibre.customize import CatalogPlugin
from calibre.customize.conversion import OptionRecommendation, DummyReporter from calibre.customize.conversion import OptionRecommendation, DummyReporter
from calibre.ebooks.BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag, NavigableString from calibre.ebooks.BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag, NavigableString
from calibre.ptempfile import PersistentTemporaryDirectory from calibre.ptempfile import PersistentTemporaryDirectory
from calibre.utils.logging import Log
from calibre.utils.date import isoformat, now as nowf from calibre.utils.date import isoformat, now as nowf
from calibre.utils.logging import default_log as log
FIELDS = ['all', 'author_sort', 'authors', 'comments', FIELDS = ['all', 'author_sort', 'authors', 'comments',
'cover', 'formats', 'id', 'isbn', 'pubdate', 'publisher', 'rating', 'cover', 'formats', 'id', 'isbn', 'pubdate', 'publisher', 'rating',
@ -54,7 +54,6 @@ class CSV_XML(CatalogPlugin):
"Applies to: CSV, XML output formats"))] "Applies to: CSV, XML output formats"))]
def run(self, path_to_output, opts, db, notification=DummyReporter()): def run(self, path_to_output, opts, db, notification=DummyReporter()):
log = Log()
self.fmt = path_to_output.rpartition('.')[2] self.fmt = path_to_output.rpartition('.')[2]
self.notification = notification self.notification = notification
@ -349,7 +348,7 @@ class EPUB_MOBI(CatalogPlugin):
self.number_as_float = 0.0 self.number_as_float = 0.0
self.text = '' self.text = ''
self.verbose = verbose self.verbose = verbose
self.log = Log() self.log = log
self.numberTranslate() self.numberTranslate()
def stringFromInt(self, intToTranslate): def stringFromInt(self, intToTranslate):
@ -3853,6 +3852,8 @@ class EPUB_MOBI(CatalogPlugin):
lost_cr.group(2), lost_cr.group(2),
lost_cr.group(3))) lost_cr.group(3)))
# Extract pre-built elements - annotations, etc. # Extract pre-built elements - annotations, etc.
if not isinstance(comments, unicode):
comments = comments.decode('utf-8', 'replace')
soup = BeautifulSoup(comments) soup = BeautifulSoup(comments)
elems = soup.findAll('div') elems = soup.findAll('div')
for elem in elems: for elem in elems:
@ -3860,11 +3861,13 @@ class EPUB_MOBI(CatalogPlugin):
# Reconstruct comments w/o <div>s # Reconstruct comments w/o <div>s
comments = soup.renderContents() comments = soup.renderContents()
if not isinstance(comments, unicode):
comments = comments.decode('utf-8', 'replace')
# Convert \n\n to <p>s # Convert \n\n to <p>s
if re.search('\n\n', comments): if re.search('\n\n', comments):
soup = BeautifulSoup() soup = BeautifulSoup()
split_ps = comments.split('\n\n') split_ps = comments.split(u'\n\n')
tsc = 0 tsc = 0
for p in split_ps: for p in split_ps:
pTag = Tag(soup,'p') pTag = Tag(soup,'p')
@ -3929,9 +3932,6 @@ class EPUB_MOBI(CatalogPlugin):
return result.renderContents(encoding=None) return result.renderContents(encoding=None)
def magicKindleLocationCalculator(self,offset):
return offset/150 + 1
def processSpecialTags(self, tags, this_title, opts): def processSpecialTags(self, tags, this_title, opts):
tag_list = [] tag_list = []
for tag in tags: for tag in tags:
@ -3970,7 +3970,7 @@ class EPUB_MOBI(CatalogPlugin):
self.opts.log.info('%s not implemented' % self.error) self.opts.log.info('%s not implemented' % self.error)
def run(self, path_to_output, opts, db, notification=DummyReporter()): def run(self, path_to_output, opts, db, notification=DummyReporter()):
opts.log = log = Log() opts.log = log
opts.fmt = self.fmt = path_to_output.rpartition('.')[2] opts.fmt = self.fmt = path_to_output.rpartition('.')[2]
# Add local options # Add local options