%PDF- %PDF-
| Direktori : /usr/lib/calibre/calibre/ebooks/oeb/iterator/ |
| Current File : //usr/lib/calibre/calibre/ebooks/oeb/iterator/bookmarks.py |
#!/usr/bin/env python3
__license__ = 'GPL v3'
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import os, numbers
from io import BytesIO
from calibre.utils.zipfile import safe_replace
from polyglot.builtins import as_unicode
BM_FIELD_SEP = '*|!|?|*'
BM_LEGACY_ESC = 'esc-text-%&*#%(){}ads19-end-esc'
def parse_bookmarks(raw):
raw = as_unicode(raw)
for line in raw.splitlines():
if '^' in line:
tokens = line.rpartition('^')
title, ref = tokens[0], tokens[2]
try:
spine, _, pos = ref.partition('#')
spine = int(spine.strip())
except Exception:
continue
yield {'type':'legacy', 'title':title, 'spine':spine, 'pos':pos}
elif BM_FIELD_SEP in line:
try:
title, spine, pos = line.strip().split(BM_FIELD_SEP)
spine = int(spine)
except Exception:
continue
# Unescape from serialization
pos = pos.replace(BM_LEGACY_ESC, '^')
# Check for pos being a scroll fraction
try:
pos = float(pos)
except Exception:
pass
yield {'type':'cfi', 'title':title, 'pos':pos, 'spine':spine}
class BookmarksMixin:
def __init__(self, copy_bookmarks_to_file=True):
self.copy_bookmarks_to_file = copy_bookmarks_to_file
def parse_bookmarks(self, raw):
for bm in parse_bookmarks(raw):
self.bookmarks.append(bm)
def serialize_bookmarks(self, bookmarks):
dat = []
for bm in bookmarks:
if bm['type'] == 'legacy':
rec = '%s^%d#%s'%(bm['title'], bm['spine'], bm['pos'])
else:
pos = bm['pos']
if isinstance(pos, numbers.Number):
pos = str(pos)
else:
pos = pos.replace('^', BM_LEGACY_ESC)
rec = BM_FIELD_SEP.join([bm['title'], str(bm['spine']), pos])
dat.append(rec)
return ('\n'.join(dat) +'\n')
def read_bookmarks(self):
self.bookmarks = []
raw = self.config['bookmarks_'+self.pathtoebook] or ''
if not raw:
# Look for bookmarks saved inside the ebook
bmfile = os.path.join(self.base, 'META-INF', 'calibre_bookmarks.txt')
if os.path.exists(bmfile):
with open(bmfile, 'rb') as f:
raw = f.read()
if isinstance(raw, bytes):
raw = raw.decode('utf-8')
self.parse_bookmarks(raw)
def save_bookmarks(self, bookmarks=None, no_copy_to_file=False):
if bookmarks is None:
bookmarks = self.bookmarks
dat = self.serialize_bookmarks(bookmarks)
self.config['bookmarks_'+self.pathtoebook] = dat
if not no_copy_to_file and self.copy_bookmarks_to_file and os.path.splitext(
self.pathtoebook)[1].lower() == '.epub' and os.access(self.pathtoebook, os.W_OK):
try:
with open(self.pathtoebook, 'r+b') as zf:
safe_replace(zf, 'META-INF/calibre_bookmarks.txt',
BytesIO(dat.encode('utf-8')),
add_missing=True)
except OSError:
return
def add_bookmark(self, bm, no_copy_to_file=False):
self.bookmarks = [x for x in self.bookmarks if x['title'] !=
bm['title']]
self.bookmarks.append(bm)
self.save_bookmarks(no_copy_to_file=no_copy_to_file)
def set_bookmarks(self, bookmarks):
self.bookmarks = bookmarks