~ubuntu-branches/ubuntu/karmic/calibre/karmic

« back to all changes in this revision

Viewing changes to src/calibre/ebooks/epub/iterator.py

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-04-05 18:42:16 UTC
  • mfrom: (1.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20090405184216-cyb0x4edrwjcaw33
Tags: 0.5.9+dfsg-1
* New upstream release. (Closes: #525339)
* manpages-installation.patch: Encode generated manpages as UTF-8, to avoid
  UnicodeDecodeErrors when writing them out to files.
* debian/control: Demote calibre dependency of calibre-bin to Recommends:,
  which is sufficient and avoids a circular dependency. (Closes: #522059)
* debian/control: Drop build dependency help2man, current version does not
  need it any more.
* debian/control: Drop versioned build dependency on python-mechanize,
  current sid version is enough.
* debian/rules: Copy "setup.py install" command from cdbs'
  python-distutils.mk, since the current version broke this. This is a
  hackish workaround until #525436 gets fixed.
* debian/rules: Drop using $(wildcard ), use `ls`; the former does not work
  any more.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 
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
31
31
    return count
32
32
 
33
33
class UnsupportedFormatError(Exception):
34
 
    
 
34
 
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())
37
37
 
38
38
class SpineItem(unicode):
39
 
    
 
39
 
40
40
    def __new__(cls, *args):
 
41
        args = list(args)
 
42
        args[0] = args[0].partition('#')[0]
41
43
        obj = super(SpineItem, cls).__new__(cls, *args)
42
44
        path = args[0]
43
45
        raw = open(path, 'rb').read()
63
65
    return ext in list(MAP.keys())+['html', 'opf']
64
66
 
65
67
class EbookIterator(object):
66
 
    
 
68
 
67
69
    CHARACTERS_PER_PAGE = 1000
68
 
    
 
70
 
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]
80
 
    
 
83
 
81
84
    def search(self, text, index):
82
85
        text = text.lower()
83
86
        for i, path in enumerate(self.spine):
84
87
            if i > index:
85
88
                if text in open(path, 'rb').read().decode(path.encoding).lower():
86
89
                    return i
87
 
    
 
90
 
88
91
    def find_embedded_fonts(self):
89
92
        '''
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.
91
94
        '''
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
109
112
                                else:
110
113
                                    print 'Loaded embedded font:', repr(family)
111
 
    
 
114
 
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]
119
 
        
 
122
 
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)]
125
 
        
 
129
 
 
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))
 
133
 
 
134
 
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):
129
138
            s.pages = p
130
139
        start = 1
131
 
        
132
 
        
 
140
 
 
141
 
133
142
        for s in self.spine:
134
143
            s.start_page = start
135
144
            start += s.pages
136
145
            s.max_page = s.start_page + s.pages - 1
137
146
        self.toc = self.opf.toc
138
 
        
 
147
 
139
148
        self.find_embedded_fonts()
140
 
        self.read_bookmarks() 
141
 
        
 
149
        self.read_bookmarks()
 
150
 
142
151
        return self
143
 
    
 
152
 
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))
150
 
    
 
159
 
151
160
    def serialize_bookmarks(self, bookmarks):
152
161
        dat = []
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')
156
 
    
 
165
 
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]
165
174
            if saved:
166
175
                raw = saved
167
 
        self.parse_bookmarks(raw) 
168
 
                    
 
176
        self.parse_bookmarks(raw)
 
177
 
169
178
    def save_bookmarks(self, bookmarks=None):
170
179
        if bookmarks is None:
171
180
            bookmarks = self.bookmarks
184
193
            zipf.writestr('META-INF/calibre_bookmarks.txt', dat)
185
194
        else:
186
195
            self.config['bookmarks_'+self.pathtoebook] = dat
187
 
    
 
196
 
188
197
    def add_bookmark(self, bm):
189
198
        dups = []
190
199
        for x in self.bookmarks:
194
203
            self.bookmarks.remove(x)
195
204
        self.bookmarks.append(bm)
196
205
        self.save_bookmarks()
197
 
        
 
206
 
198
207
    def __exit__(self, *args):
199
 
        self._tdir.__exit__(*args)
 
 
b'\\ No newline at end of file'
 
208
        self._tdir.__exit__(*args)