13
13
from calibre.ebooks.epub.from_any import MAP
14
14
from calibre.ebooks.epub.from_html import TITLEPAGE
15
from calibre.ebooks.epub import config
15
from calibre.ebooks.epub import config
16
16
from calibre.ebooks.metadata.opf2 import OPF
17
17
from calibre.ptempfile import TemporaryDirectory
18
18
from calibre.ebooks.chardet import xml_to_unicode
33
33
class UnsupportedFormatError(Exception):
35
35
def __init__(self, fmt):
36
Exception.__init__(self, _('%s format books are not supported')%fmt.upper())
36
Exception.__init__(self, _('%s format books are not supported')%fmt.upper())
38
38
class SpineItem(unicode):
40
40
def __new__(cls, *args):
42
args[0] = args[0].partition('#')[0]
41
43
obj = super(SpineItem, cls).__new__(cls, *args)
43
45
raw = open(path, 'rb').read()
63
65
return ext in list(MAP.keys())+['html', 'opf']
65
67
class EbookIterator(object):
67
69
CHARACTERS_PER_PAGE = 1000
69
71
def __init__(self, pathtoebook):
72
pathtoebook = pathtoebook.strip()
70
73
self.pathtoebook = os.path.abspath(pathtoebook)
71
74
self.config = DynamicConfig(name='iterator')
72
75
ext = os.path.splitext(pathtoebook)[1].replace('.', '').lower()
77
80
if ext not in map.keys():
78
81
raise UnsupportedFormatError(ext)
79
82
self.to_opf = map[ext]
81
84
def search(self, text, index):
82
85
text = text.lower()
83
86
for i, path in enumerate(self.spine):
85
88
if text in open(path, 'rb').read().decode(path.encoding).lower():
88
91
def find_embedded_fonts(self):
90
This will become unnecessary once Qt WebKit supports the @font-face rule.
93
This will become unnecessary once Qt WebKit supports the @font-face rule.
92
95
for item in self.opf.manifest:
93
96
if item.mime_type and 'css' in item.mime_type.lower():
108
111
print 'WARNING: Family aliasing not supported:', block
110
113
print 'Loaded embedded font:', repr(family)
112
115
def __enter__(self):
113
116
self._tdir = TemporaryDirectory('_ebook_iter')
114
117
self.base = self._tdir.__enter__()
116
119
self.pathtoopf = self.to_opf(self.pathtoebook, self.base, opts)
117
120
self.opf = OPF(self.pathtoopf, os.path.dirname(self.pathtoopf))
118
121
self.spine = [SpineItem(i.path) for i in self.opf.spine]
120
123
cover = self.opf.cover
121
if os.path.splitext(self.pathtoebook)[1].lower() in ('.lit', '.mobi', '.prc') and cover:
124
if os.path.splitext(self.pathtoebook)[1].lower() in \
125
('.lit', '.mobi', '.prc') and cover:
122
126
cfile = os.path.join(os.path.dirname(self.spine[0]), 'calibre_ei_cover.html')
123
127
open(cfile, 'wb').write(TITLEPAGE%cover)
124
128
self.spine[0:0] = [SpineItem(cfile)]
130
if self.opf.path_to_html_toc is not None and \
131
self.opf.path_to_html_toc not in self.spine:
132
self.spine.append(SpineItem(self.opf.path_to_html_toc))
126
135
sizes = [i.character_count for i in self.spine]
127
136
self.pages = [math.ceil(i/float(self.CHARACTERS_PER_PAGE)) for i in sizes]
128
137
for p, s in zip(self.pages, self.spine):
133
142
for s in self.spine:
134
143
s.start_page = start
136
145
s.max_page = s.start_page + s.pages - 1
137
146
self.toc = self.opf.toc
139
148
self.find_embedded_fonts()
140
self.read_bookmarks()
149
self.read_bookmarks()
144
153
def parse_bookmarks(self, raw):
145
154
for line in raw.splitlines():
146
155
if line.count('^') > 0:
147
156
tokens = line.rpartition('^')
148
157
title, ref = tokens[0], tokens[2]
149
158
self.bookmarks.append((title, ref))
151
160
def serialize_bookmarks(self, bookmarks):
153
162
for title, bm in bookmarks:
154
163
dat.append(u'%s^%s'%(title, bm))
155
164
return (u'\n'.join(dat) +'\n').encode('utf-8')
157
166
def read_bookmarks(self):
158
167
self.bookmarks = []
159
168
bmfile = os.path.join(self.base, 'META-INF', 'calibre_bookmarks.txt')
164
173
saved = self.config['bookmarks_'+self.pathtoebook]
167
self.parse_bookmarks(raw)
176
self.parse_bookmarks(raw)
169
178
def save_bookmarks(self, bookmarks=None):
170
179
if bookmarks is None:
171
180
bookmarks = self.bookmarks
194
203
self.bookmarks.remove(x)
195
204
self.bookmarks.append(bm)
196
205
self.save_bookmarks()
198
207
def __exit__(self, *args):
199
self._tdir.__exit__(*args)
b'\\ No newline at end of file'
208
self._tdir.__exit__(*args)