This commit is contained in:
Kovid Goyal 2019-07-07 10:31:51 +05:30
commit 134692af38
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
34 changed files with 160 additions and 154 deletions

View File

@ -150,7 +150,7 @@ class OverDrive(Source):
fix_slashes = re.compile(r'\\/') fix_slashes = re.compile(r'\\/')
thumbimage = fix_slashes.sub('/', thumbimage) thumbimage = fix_slashes.sub('/', thumbimage)
worldcatlink = fix_slashes.sub('/', worldcatlink) worldcatlink = fix_slashes.sub('/', worldcatlink)
cover_url = re.sub('(?P<img>(Ima?g(eType-)?))200', '\\g<img>100', thumbimage) cover_url = re.sub(r'(?P<img>(Ima?g(eType-)?))200', r'\g<img>100', thumbimage)
social_metadata_url = base_url+'TitleInfo.aspx?ReserveID='+reserveid+'&FormatID='+formatid social_metadata_url = base_url+'TitleInfo.aspx?ReserveID='+reserveid+'&FormatID='+formatid
series_num = '' series_num = ''
if not series: if not series:
@ -235,7 +235,7 @@ class OverDrive(Source):
xreq.add_header('Referer', q_init_search) xreq.add_header('Referer', q_init_search)
xreq.add_header('Accept', 'application/json, text/javascript, */*') xreq.add_header('Accept', 'application/json, text/javascript, */*')
raw = br.open_novisit(xreq).read() raw = br.open_novisit(xreq).read()
for m in re.finditer(type(u'')(r'"iTotalDisplayRecords":(?P<displayrecords>\d+).*?"iTotalRecords":(?P<totalrecords>\d+)'), raw): for m in re.finditer(type('')(r'"iTotalDisplayRecords":(?P<displayrecords>\d+).*?"iTotalRecords":(?P<totalrecords>\d+)'), raw):
if int(m.group('totalrecords')) == 0: if int(m.group('totalrecords')) == 0:
return '' return ''
elif int(m.group('displayrecords')) >= 1: elif int(m.group('displayrecords')) >= 1:
@ -256,9 +256,9 @@ class OverDrive(Source):
def sort_ovrdrv_results(self, raw, log, title=None, title_tokens=None, author=None, author_tokens=None, ovrdrv_id=None): def sort_ovrdrv_results(self, raw, log, title=None, title_tokens=None, author=None, author_tokens=None, ovrdrv_id=None):
close_matches = [] close_matches = []
raw = re.sub('.*?\\[\\[(?P<content>.*?)\\]\\].*', '[[\\g<content>]]', raw) raw = re.sub(r'.*?\[\[(?P<content>.*?)\]\].*', r'[[\g<content>]]', raw)
results = json.loads(raw) results = json.loads(raw)
# log.error('raw results are:'+str(results)) # log.error('raw results are:'+type('')(results))
# The search results are either from a keyword search or a multi-format list from a single ID, # The search results are either from a keyword search or a multi-format list from a single ID,
# sort through the results for closest match/format # sort through the results for closest match/format
if results: if results:
@ -336,7 +336,7 @@ class OverDrive(Source):
req.add_header('Referer', search_url) req.add_header('Referer', search_url)
req.add_header('Accept', 'application/json, text/javascript, */*') req.add_header('Accept', 'application/json, text/javascript, */*')
raw = br.open_novisit(req) raw = br.open_novisit(req)
raw = str(list(raw)) raw = type('')(list(raw))
clean_cj = mechanize.CookieJar() clean_cj = mechanize.CookieJar()
br.set_cookiejar(clean_cj) br.set_cookiejar(clean_cj)
return self.sort_ovrdrv_results(raw, log, None, None, None, ovrdrv_id) return self.sort_ovrdrv_results(raw, log, None, None, None, ovrdrv_id)
@ -443,7 +443,7 @@ class OverDrive(Source):
mi.language = lang mi.language = lang
if ebook_isbn: if ebook_isbn:
# print "ebook isbn is "+str(ebook_isbn[0]) # print("ebook isbn is "+type('')(ebook_isbn[0]))
isbn = check_isbn(ebook_isbn[0].strip()) isbn = check_isbn(ebook_isbn[0].strip())
if isbn: if isbn:
self.cache_isbn_to_identifier(isbn, ovrdrv_id) self.cache_isbn_to_identifier(isbn, ovrdrv_id)

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'

View File

@ -8,7 +8,7 @@ __copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
from struct import unpack_from from struct import unpack_from
from calibre.ebooks.mobi.debug.headers import EXTHHeader from calibre.ebooks.mobi.debug.headers import EXTHHeader
from polyglot.builtins import filter from polyglot.builtins import filter, unicode_type
class ContainerHeader(object): class ContainerHeader(object):
@ -63,4 +63,4 @@ class ContainerHeader(object):
a('Null bytes after EXTH: %d' % self.null_bytes_after_exth) a('Null bytes after EXTH: %d' % self.null_bytes_after_exth)
if len(self.bytes_after_exth) != self.null_bytes_after_exth: if len(self.bytes_after_exth) != self.null_bytes_after_exth:
a('Non-null bytes present after EXTH header!!!!') a('Non-null bytes present after EXTH header!!!!')
return '\n'.join(ans) + '\n\n' + str(self.exth) + '\n\n' + ('Title: %s' % self.title) return '\n'.join(ans) + '\n\n' + unicode_type(self.exth) + '\n\n' + ('Title: %s' % self.title)

View File

@ -13,7 +13,7 @@ from calibre.ebooks.mobi.reader.headers import NULL_INDEX
from calibre.ebooks.mobi.langcodes import main_language, sub_language from calibre.ebooks.mobi.langcodes import main_language, sub_language
from calibre.ebooks.mobi.debug import format_bytes from calibre.ebooks.mobi.debug import format_bytes
from calibre.ebooks.mobi.utils import get_trailing_data from calibre.ebooks.mobi.utils import get_trailing_data
from polyglot.builtins import iteritems, range, as_bytes from polyglot.builtins import as_bytes, iteritems, range, unicode_type
# PalmDB {{{ # PalmDB {{{
@ -42,7 +42,7 @@ class PalmDOCAttributes(object):
self.val)) self.val))
def __str__(self): def __str__(self):
attrs = '\n\t'.join([str(x) for x in self.attributes]) attrs = '\n\t'.join([unicode_type(x) for x in self.attributes])
return 'PalmDOC Attributes: %s\n\t%s'%(bin(self.val), attrs) return 'PalmDOC Attributes: %s\n\t%s'%(bin(self.val), attrs)
@ -84,7 +84,7 @@ class PalmDB(object):
def __str__(self): def __str__(self):
ans = ['*'*20 + ' PalmDB Header '+ '*'*20] ans = ['*'*20 + ' PalmDB Header '+ '*'*20]
ans.append('Name: %r'%self.name) ans.append('Name: %r'%self.name)
ans.append(str(self.attributes)) ans.append(unicode_type(self.attributes))
ans.append('Version: %s'%self.version) ans.append('Version: %s'%self.version)
ans.append('Creation date: %s (%s)'%(self.creation_date.isoformat(), ans.append('Creation date: %s (%s)'%(self.creation_date.isoformat(),
self.creation_date_raw)) self.creation_date_raw))
@ -255,7 +255,7 @@ class EXTHHeader(object):
ans.append('Number of EXTH records: %d'%self.count) ans.append('Number of EXTH records: %d'%self.count)
ans.append('EXTH records...') ans.append('EXTH records...')
for r in self.records: for r in self.records:
ans.append(str(r)) ans.append(unicode_type(r))
return '\n'.join(ans) return '\n'.join(ans)
# }}} # }}}
@ -496,7 +496,7 @@ class MOBIHeader(object): # {{{
ans = '\n'.join(ans) ans = '\n'.join(ans)
if self.has_exth: if self.has_exth:
ans += '\n\n' + str(self.exth) ans += '\n\n' + unicode_type(self.exth)
ans += '\n\nBytes after EXTH (%d bytes): %s'%( ans += '\n\nBytes after EXTH (%d bytes): %s'%(
len(self.bytes_after_exth), len(self.bytes_after_exth),
format_bytes(self.bytes_after_exth)) format_bytes(self.bytes_after_exth))

View File

@ -368,7 +368,7 @@ class IndexEntry(object): # {{{
self.index, len(self.tags))] self.index, len(self.tags))]
for tag in self.tags: for tag in self.tags:
if tag.value is not None: if tag.value is not None:
ans.append('\t'+str(tag)) ans.append('\t'+unicode_type(tag))
if self.first_child_index != -1: if self.first_child_index != -1:
ans.append('\tNumber of children: %d'%(self.last_child_index - ans.append('\tNumber of children: %d'%(self.last_child_index -
self.first_child_index + 1)) self.first_child_index + 1))
@ -421,7 +421,7 @@ class IndexRecord(object): # {{{
len(w), not bool(w.replace(b'\0', b'')))) len(w), not bool(w.replace(b'\0', b''))))
for entry in self.indices: for entry in self.indices:
offset = entry.offset offset = entry.offset
a(str(entry)) a(unicode_type(entry))
t = self.alltext t = self.alltext
if offset is not None and self.alltext is not None: if offset is not None and self.alltext is not None:
a('\tHTML before offset: %r'%t[offset-50:offset]) a('\tHTML before offset: %r'%t[offset-50:offset])
@ -608,7 +608,7 @@ class TBSIndexing(object): # {{{
return as_bytes('0'*(4-len(ans)) + ans) return as_bytes('0'*(4-len(ans)) + ans)
def repr_extra(x): def repr_extra(x):
return str({bin4(k):v for k, v in iteritems(extra)}) return unicode_type({bin4(k):v for k, v in iteritems(extra)})
tbs_type = 0 tbs_type = 0
is_periodical = self.doc_type in (257, 258, 259) is_periodical = self.doc_type in (257, 258, 259)
@ -788,14 +788,14 @@ class MOBIFile(object): # {{{
self.index_record.indices, self.mobi_header.type_raw) self.index_record.indices, self.mobi_header.type_raw)
def print_header(self, f=sys.stdout): def print_header(self, f=sys.stdout):
print(str(self.palmdb).encode('utf-8'), file=f) print(unicode_type(self.palmdb).encode('utf-8'), file=f)
print(file=f) print(file=f)
print('Record headers:', file=f) print('Record headers:', file=f)
for i, r in enumerate(self.records): for i, r in enumerate(self.records):
print('%6d. %s'%(i, r.header), file=f) print('%6d. %s'%(i, r.header), file=f)
print(file=f) print(file=f)
print(str(self.mobi_header).encode('utf-8'), file=f) print(unicode_type(self.mobi_header).encode('utf-8'), file=f)
# }}} # }}}
@ -820,19 +820,19 @@ def inspect_mobi(mobi_file, ddir):
if f.index_header is not None: if f.index_header is not None:
f.index_record.alltext = alltext f.index_record.alltext = alltext
with open(os.path.join(ddir, 'index.txt'), 'wb') as out: with open(os.path.join(ddir, 'index.txt'), 'wb') as out:
print(str(f.index_header), file=out) print(unicode_type(f.index_header), file=out)
print('\n\n', file=out) print('\n\n', file=out)
if f.secondary_index_header is not None: if f.secondary_index_header is not None:
print(str(f.secondary_index_header).encode('utf-8'), file=out) print(unicode_type(f.secondary_index_header).encode('utf-8'), file=out)
print('\n\n', file=out) print('\n\n', file=out)
if f.secondary_index_record is not None: if f.secondary_index_record is not None:
print(str(f.secondary_index_record).encode('utf-8'), file=out) print(unicode_type(f.secondary_index_record).encode('utf-8'), file=out)
print('\n\n', file=out) print('\n\n', file=out)
print(str(f.cncx).encode('utf-8'), file=out) print(unicode_type(f.cncx).encode('utf-8'), file=out)
print('\n\n', file=out) print('\n\n', file=out)
print(str(f.index_record), file=out) print(unicode_type(f.index_record), file=out)
with open(os.path.join(ddir, 'tbs_indexing.txt'), 'wb') as out: with open(os.path.join(ddir, 'tbs_indexing.txt'), 'wb') as out:
print(str(f.tbs_indexing), file=out) print(unicode_type(f.tbs_indexing), file=out)
f.tbs_indexing.dump(ddir) f.tbs_indexing.dump(ddir)
for tdir, attr in [('text', 'text_records'), ('images', 'image_records'), for tdir, attr in [('text', 'text_records'), ('images', 'image_records'),

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import absolute_import, division, print_function, unicode_literals from __future__ import absolute_import, division, print_function, unicode_literals
from polyglot.builtins import map
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
@ -18,7 +17,7 @@ from calibre.ebooks.mobi.utils import read_font_record, decode_tbs, RECORD_SIZE
from calibre.ebooks.mobi.debug import format_bytes from calibre.ebooks.mobi.debug import format_bytes
from calibre.ebooks.mobi.reader.headers import NULL_INDEX from calibre.ebooks.mobi.reader.headers import NULL_INDEX
from calibre.utils.imghdr import what from calibre.utils.imghdr import what
from polyglot.builtins import zip, iteritems, itervalues from polyglot.builtins import iteritems, itervalues, map, unicode_type, zip
class FDST(object): class FDST(object):
@ -95,14 +94,14 @@ class MOBIFile(object):
self.read_tbs() self.read_tbs()
def print_header(self, f=sys.stdout): def print_header(self, f=sys.stdout):
print(str(self.mf.palmdb).encode('utf-8'), file=f) print(unicode_type(self.mf.palmdb).encode('utf-8'), file=f)
print(file=f) print(file=f)
print('Record headers:', file=f) print('Record headers:', file=f)
for i, r in enumerate(self.mf.records): for i, r in enumerate(self.mf.records):
print('%6d. %s'%(i, r.header), file=f) print('%6d. %s'%(i, r.header), file=f)
print(file=f) print(file=f)
print(str(self.mf.mobi8_header).encode('utf-8'), file=f) print(unicode_type(self.mf.mobi8_header).encode('utf-8'), file=f)
def read_fdst(self): def read_fdst(self):
self.fdst = None self.fdst = None
@ -314,23 +313,23 @@ def inspect_mobi(mobi_file, ddir):
for i, container in enumerate(f.containers): for i, container in enumerate(f.containers):
with open(os.path.join(ddir, 'container%d.txt' % (i + 1)), 'wb') as cf: with open(os.path.join(ddir, 'container%d.txt' % (i + 1)), 'wb') as cf:
cf.write(str(container).encode('utf-8')) cf.write(unicode_type(container).encode('utf-8'))
if f.fdst: if f.fdst:
with open(os.path.join(ddir, 'fdst.record'), 'wb') as fo: with open(os.path.join(ddir, 'fdst.record'), 'wb') as fo:
fo.write(str(f.fdst).encode('utf-8')) fo.write(unicode_type(f.fdst).encode('utf-8'))
with open(os.path.join(ddir, 'skel.record'), 'wb') as fo: with open(os.path.join(ddir, 'skel.record'), 'wb') as fo:
fo.write(str(f.skel_index).encode('utf-8')) fo.write(unicode_type(f.skel_index).encode('utf-8'))
with open(os.path.join(ddir, 'chunks.record'), 'wb') as fo: with open(os.path.join(ddir, 'chunks.record'), 'wb') as fo:
fo.write(str(f.sect_index).encode('utf-8')) fo.write(unicode_type(f.sect_index).encode('utf-8'))
with open(os.path.join(ddir, 'ncx.record'), 'wb') as fo: with open(os.path.join(ddir, 'ncx.record'), 'wb') as fo:
fo.write(str(f.ncx_index).encode('utf-8')) fo.write(unicode_type(f.ncx_index).encode('utf-8'))
with open(os.path.join(ddir, 'guide.record'), 'wb') as fo: with open(os.path.join(ddir, 'guide.record'), 'wb') as fo:
fo.write(str(f.guide_index).encode('utf-8')) fo.write(unicode_type(f.guide_index).encode('utf-8'))
with open(os.path.join(ddir, 'tbs.txt'), 'wb') as fo: with open(os.path.join(ddir, 'tbs.txt'), 'wb') as fo:
fo.write(('\n'.join(f.indexing_data)).encode('utf-8')) fo.write(('\n'.join(f.indexing_data)).encode('utf-8'))

View File

@ -1,4 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@ -1,8 +1,8 @@
from __future__ import absolute_import, division, print_function, unicode_literals
''' '''
Transform XHTML/OPS-ish content into Mobipocket HTML 3.2. Transform XHTML/OPS-ish content into Mobipocket HTML 3.2.
''' '''
from __future__ import with_statement
from __future__ import print_function
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.cam>' __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.cam>'
@ -54,7 +54,7 @@ def asfloat(value):
def isspace(text): def isspace(text):
if not text: if not text:
return True return True
if u'\xa0' in text: if '\xa0' in text:
return False return False
return text.isspace() return text.isspace()
@ -139,7 +139,7 @@ class MobiMLizer(object):
self.mobimlize_elem(body, stylizer, BlockState(nbody), self.mobimlize_elem(body, stylizer, BlockState(nbody),
[FormatState()]) [FormatState()])
item.data = nroot item.data = nroot
# print etree.tostring(nroot) # print(etree.tostring(nroot))
def mobimlize_font(self, ptsize): def mobimlize_font(self, ptsize):
return self.fnums[self.fmap[ptsize]] return self.fnums[self.fmap[ptsize]]
@ -156,9 +156,9 @@ class MobiMLizer(object):
text = unicode_type(text) text = unicode_type(text)
if pre_wrap: if pre_wrap:
# Replace n consecutive spaces with n-1 NBSP + space # Replace n consecutive spaces with n-1 NBSP + space
text = re.sub(r' {2,}', lambda m:(u'\xa0'*(len(m.group())-1) + u' '), text) text = re.sub(r' {2,}', lambda m:('\xa0'*(len(m.group())-1) + ' '), text)
else: else:
text = text.replace(u' ', u'\xa0') text = text.replace(' ', '\xa0')
text = text.replace('\r\n', '\n') text = text.replace('\r\n', '\n')
text = text.replace('\r', '\n') text = text.replace('\r', '\n')
@ -201,7 +201,7 @@ class MobiMLizer(object):
bstate.nested.append(para) bstate.nested.append(para)
if tag == 'li' and len(istates) > 1: if tag == 'li' and len(istates) > 1:
istates[-2].list_num += 1 istates[-2].list_num += 1
para.attrib['value'] = str(istates[-2].list_num) para.attrib['value'] = unicode_type(istates[-2].list_num)
elif tag in NESTABLE_TAGS and istate.rendered: elif tag in NESTABLE_TAGS and istate.rendered:
para = wrapper = bstate.nested[-1] para = wrapper = bstate.nested[-1]
elif not self.opts.mobi_ignore_margins and left > 0 and indent >= 0: elif not self.opts.mobi_ignore_margins and left > 0 and indent >= 0:
@ -210,7 +210,7 @@ class MobiMLizer(object):
para = wrapper para = wrapper
emleft = int(round(left / self.profile.fbase)) - ems emleft = int(round(left / self.profile.fbase)) - ems
emleft = min((emleft, 10)) emleft = min((emleft, 10))
while emleft > ems/2.0: while emleft > ems / 2:
para = etree.SubElement(para, XHTML('blockquote')) para = etree.SubElement(para, XHTML('blockquote'))
emleft -= ems emleft -= ems
else: else:
@ -287,7 +287,7 @@ class MobiMLizer(object):
if fsize != 3: if fsize != 3:
inline = etree.SubElement(inline, XHTML('font'), inline = etree.SubElement(inline, XHTML('font'),
size=str(fsize)) size=unicode_type(fsize))
if istate.family == 'monospace': if istate.family == 'monospace':
inline = etree.SubElement(inline, XHTML('tt')) inline = etree.SubElement(inline, XHTML('tt'))
if istate.italic: if istate.italic:
@ -390,17 +390,17 @@ class MobiMLizer(object):
lspace = margin + padding lspace = margin + padding
if lspace > 0: if lspace > 0:
spaces = int(round((lspace * 3) / style['font-size'])) spaces = int(round((lspace * 3) / style['font-size']))
elem.text = (u'\xa0' * spaces) + (elem.text or '') elem.text = ('\xa0' * spaces) + (elem.text or '')
margin = asfloat(style['margin-right']) margin = asfloat(style['margin-right'])
padding = asfloat(style['padding-right']) padding = asfloat(style['padding-right'])
rspace = margin + padding rspace = margin + padding
if rspace > 0: if rspace > 0:
spaces = int(round((rspace * 3) / style['font-size'])) spaces = int(round((rspace * 3) / style['font-size']))
if len(elem) == 0: if len(elem) == 0:
elem.text = (elem.text or '') + (u'\xa0' * spaces) elem.text = (elem.text or '') + ('\xa0' * spaces)
else: else:
last = elem[-1] last = elem[-1]
last.text = (last.text or '') + (u'\xa0' * spaces) last.text = (last.text or '') + ('\xa0' * spaces)
if bstate.content and style['page-break-before'] in PAGE_BREAKS: if bstate.content and style['page-break-before'] in PAGE_BREAKS:
bstate.pbreak = True bstate.pbreak = True
istate.fsize = self.mobimlize_font(style['font-size']) istate.fsize = self.mobimlize_font(style['font-size'])
@ -446,10 +446,10 @@ class MobiMLizer(object):
# See #7520 for test case # See #7520 for test case
try: try:
pixs = int(round(float(value) / pixs = int(round(float(value) /
(72./self.profile.dpi))) (72/self.profile.dpi)))
except: except:
continue continue
result = str(pixs) result = unicode_type(pixs)
istate.attrib[prop] = result istate.attrib[prop] = result
if 'width' not in istate.attrib or 'height' not in istate.attrib: if 'width' not in istate.attrib or 'height' not in istate.attrib:
href = self.current_spine_item.abshref(elem.attrib['src']) href = self.current_spine_item.abshref(elem.attrib['src'])
@ -466,22 +466,22 @@ class MobiMLizer(object):
else: else:
if 'width' not in istate.attrib and 'height' not in \ if 'width' not in istate.attrib and 'height' not in \
istate.attrib: istate.attrib:
istate.attrib['width'] = str(width) istate.attrib['width'] = unicode_type(width)
istate.attrib['height'] = str(height) istate.attrib['height'] = unicode_type(height)
else: else:
ar = float(width)/float(height) ar = width / height
if 'width' not in istate.attrib: if 'width' not in istate.attrib:
try: try:
width = int(istate.attrib['height'])*ar width = int(istate.attrib['height'])*ar
except: except:
pass pass
istate.attrib['width'] = str(int(width)) istate.attrib['width'] = unicode_type(int(width))
else: else:
try: try:
height = int(istate.attrib['width'])/ar height = int(istate.attrib['width'])/ar
except: except:
pass pass
istate.attrib['height'] = str(int(height)) istate.attrib['height'] = unicode_type(int(height))
item.unload_data_from_memory() item.unload_data_from_memory()
elif tag == 'hr' and asfloat(style['width']) > 0 and style._get('width') not in {'100%', 'auto'}: elif tag == 'hr' and asfloat(style['width']) > 0 and style._get('width') not in {'100%', 'auto'}:
raww = style._get('width') raww = style._get('width')
@ -515,11 +515,11 @@ class MobiMLizer(object):
t = elem.text t = elem.text
if not t: if not t:
t = '' t = ''
elem.text = u'\u201c' + t elem.text = '\u201c' + t
t = elem.tail t = elem.tail
if not t: if not t:
t = '' t = ''
elem.tail = u'\u201d' + t elem.tail = '\u201d' + t
text = None text = None
if elem.text: if elem.text:
if istate.preserve or istate.pre_wrap: if istate.preserve or istate.pre_wrap:
@ -602,7 +602,7 @@ class MobiMLizer(object):
bstate.pbreak = True bstate.pbreak = True
if isblock: if isblock:
para = bstate.para para = bstate.para
if para is not None and para.text == u'\xa0' and len(para) < 1: if para is not None and para.text == '\xa0' and len(para) < 1:
if style.height > 2: if style.height > 2:
para.getparent().replace(para, etree.Element(XHTML('br'))) para.getparent().replace(para, etree.Element(XHTML('br')))
else: else:

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import (absolute_import, print_function) from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
@ -294,14 +294,14 @@ class MetadataHeader(BookHeader):
def kf8_type(self): def kf8_type(self):
if (self.mobi_version == 8 and getattr(self, 'skelidx', NULL_INDEX) != if (self.mobi_version == 8 and getattr(self, 'skelidx', NULL_INDEX) !=
NULL_INDEX): NULL_INDEX):
return u'standalone' return 'standalone'
kf8_header_index = getattr(self.exth, 'kf8_header', None) kf8_header_index = getattr(self.exth, 'kf8_header', None)
if kf8_header_index is None: if kf8_header_index is None:
return None return None
try: try:
if self.section_data(kf8_header_index-1) == b'BOUNDARY': if self.section_data(kf8_header_index-1) == b'BOUNDARY':
return u'joint' return 'joint'
except: except:
pass pass
return None return None

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import (absolute_import, print_function) from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
@ -169,7 +169,7 @@ class MobiReader(object):
self.processed_html = self.processed_html.replace('</</', '</') self.processed_html = self.processed_html.replace('</</', '</')
self.processed_html = re.sub(r'</([a-zA-Z]+)<', r'</\1><', self.processed_html = re.sub(r'</([a-zA-Z]+)<', r'</\1><',
self.processed_html) self.processed_html)
self.processed_html = self.processed_html.replace(u'\ufeff', '') self.processed_html = self.processed_html.replace('\ufeff', '')
# Remove tags of the form <xyz: ...> as they can cause issues further # Remove tags of the form <xyz: ...> as they can cause issues further
# along the pipeline # along the pipeline
self.processed_html = re.sub(r'</{0,1}[a-zA-Z]+:\s+[^>]*>', '', self.processed_html = re.sub(r'</{0,1}[a-zA-Z]+:\s+[^>]*>', '',
@ -356,15 +356,15 @@ class MobiReader(object):
# Swap inline and block level elements, and order block level elements according to priority # Swap inline and block level elements, and order block level elements according to priority
# - lxml and beautifulsoup expect/assume a specific order based on xhtml spec # - lxml and beautifulsoup expect/assume a specific order based on xhtml spec
self.processed_html = re.sub( self.processed_html = re.sub(
r'(?i)(?P<styletags>(<(h\d+|i|b|u|em|small|big|strong|tt)>\s*){1,})(?P<para><p[^>]*>)', '\\g<para>'+'\\g<styletags>', self.processed_html) r'(?i)(?P<styletags>(<(h\d+|i|b|u|em|small|big|strong|tt)>\s*){1,})(?P<para><p[^>]*>)', r'\g<para>'+r'\g<styletags>', self.processed_html)
self.processed_html = re.sub( self.processed_html = re.sub(
r'(?i)(?P<para></p[^>]*>)\s*(?P<styletags>(</(h\d+|i|b|u|em|small|big|strong|tt)>\s*){1,})', '\\g<styletags>'+'\\g<para>', self.processed_html) r'(?i)(?P<para></p[^>]*>)\s*(?P<styletags>(</(h\d+|i|b|u|em|small|big|strong|tt)>\s*){1,})', r'\g<styletags>'+r'\g<para>', self.processed_html)
self.processed_html = re.sub( self.processed_html = re.sub(
r'(?i)(?P<blockquote>(</(blockquote|div)[^>]*>\s*){1,})(?P<para></p[^>]*>)', '\\g<para>'+'\\g<blockquote>', self.processed_html) r'(?i)(?P<blockquote>(</(blockquote|div)[^>]*>\s*){1,})(?P<para></p[^>]*>)', r'\g<para>'+r'\g<blockquote>', self.processed_html)
self.processed_html = re.sub( self.processed_html = re.sub(
r'(?i)(?P<para><p[^>]*>)\s*(?P<blockquote>(<(blockquote|div)[^>]*>\s*){1,})', '\\g<blockquote>'+'\\g<para>', self.processed_html) r'(?i)(?P<para><p[^>]*>)\s*(?P<blockquote>(<(blockquote|div)[^>]*>\s*){1,})', r'\g<blockquote>'+r'\g<para>', self.processed_html)
bods = htmls = 0 bods = htmls = 0
for x in re.finditer(u'</body>|</html>', self.processed_html): for x in re.finditer('</body>|</html>', self.processed_html):
if x == '</body>': if x == '</body>':
bods +=1 bods +=1
else: else:
@ -442,7 +442,7 @@ class MobiReader(object):
# Paragraph spacer # Paragraph spacer
# Insert nbsp so that the element is never # Insert nbsp so that the element is never
# discarded by a renderer # discarded by a renderer
tag.text = u'\u00a0' # nbsp tag.text = '\u00a0' # nbsp
styles.append('height: %s' % styles.append('height: %s' %
self.ensure_unit(height)) self.ensure_unit(height))
else: else:
@ -642,11 +642,11 @@ class MobiReader(object):
mi = MetaInformation(self.book_header.title, [_('Unknown')]) mi = MetaInformation(self.book_header.title, [_('Unknown')])
opf = OPFCreator(os.path.dirname(htmlfile), mi) opf = OPFCreator(os.path.dirname(htmlfile), mi)
if hasattr(self.book_header.exth, 'cover_offset'): if hasattr(self.book_header.exth, 'cover_offset'):
opf.cover = u'images/%05d.jpg' % (self.book_header.exth.cover_offset + 1) opf.cover = 'images/%05d.jpg' % (self.book_header.exth.cover_offset + 1)
elif mi.cover is not None: elif mi.cover is not None:
opf.cover = mi.cover opf.cover = mi.cover
else: else:
opf.cover = u'images/%05d.jpg' % 1 opf.cover = 'images/%05d.jpg' % 1
if not os.path.exists(os.path.join(os.path.dirname(htmlfile), if not os.path.exists(os.path.join(os.path.dirname(htmlfile),
* opf.cover.split('/'))): * opf.cover.split('/'))):
opf.cover = None opf.cover = None
@ -656,7 +656,7 @@ class MobiReader(object):
if cover is not None: if cover is not None:
cover = cover.replace('/', os.sep) cover = cover.replace('/', os.sep)
if os.path.exists(cover): if os.path.exists(cover):
ncover = u'images'+os.sep+u'calibre_cover.jpg' ncover = 'images'+os.sep+'calibre_cover.jpg'
if os.path.exists(ncover): if os.path.exists(ncover):
os.remove(ncover) os.remove(ncover)
shutil.copyfile(cover, ncover) shutil.copyfile(cover, ncover)
@ -664,9 +664,9 @@ class MobiReader(object):
opf.cover = ncover.replace(os.sep, '/') opf.cover = ncover.replace(os.sep, '/')
manifest = [(htmlfile, 'application/xhtml+xml'), manifest = [(htmlfile, 'application/xhtml+xml'),
(os.path.abspath(u'styles.css'), 'text/css')] (os.path.abspath('styles.css'), 'text/css')]
bp = os.path.dirname(htmlfile) bp = os.path.dirname(htmlfile)
added = set([]) added = set()
for i in getattr(self, 'image_names', []): for i in getattr(self, 'image_names', []):
path = os.path.join(bp, 'images', i) path = os.path.join(bp, 'images', i)
added.add(path) added.add(path)
@ -699,9 +699,9 @@ class MobiReader(object):
continue continue
if reached and x.tag == 'a': if reached and x.tag == 'a':
href = x.get('href', '') href = x.get('href', '')
if href and re.match('\\w+://', href) is None: if href and re.match(r'\w+://', href) is None:
try: try:
text = u' '.join([t.strip() for t in text = ' '.join([t.strip() for t in
x.xpath('descendant::text()')]) x.xpath('descendant::text()')])
except: except:
text = '' text = ''

View File

@ -107,7 +107,7 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False,
break break
if uuid is None: if uuid is None:
from uuid import uuid4 from uuid import uuid4
uuid = str(uuid4()) uuid = unicode_type(uuid4())
if isinstance(uuid, unicode_type): if isinstance(uuid, unicode_type):
uuid = uuid.encode('utf-8') uuid = uuid.encode('utf-8')
@ -137,9 +137,9 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False,
# Add a publication date entry # Add a publication date entry
if metadata['date']: if metadata['date']:
datestr = str(metadata['date'][0]) datestr = unicode_type(metadata['date'][0])
elif metadata['timestamp']: elif metadata['timestamp']:
datestr = str(metadata['timestamp'][0]) datestr = unicode_type(metadata['timestamp'][0])
if datestr is None: if datestr is None:
raise ValueError("missing date or timestamp") raise ValueError("missing date or timestamp")

View File

@ -289,7 +289,7 @@ class KF8Book(object):
self.extra_data_flags |= 0b10 self.extra_data_flags |= 0b10
self.uid = random.randint(0, 0xffffffff) self.uid = random.randint(0, 0xffffffff)
self.language_code = iana2mobi(str(metadata.language[0])) self.language_code = iana2mobi(unicode_type(metadata.language[0]))
self.exth_flags = 0b1010000 self.exth_flags = 0b1010000
if writer.opts.mobi_periodical: if writer.opts.mobi_periodical:
self.exth_flags |= 0b1000 self.exth_flags |= 0b1000

View File

@ -1,4 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
@ -6,4 +8,3 @@ __docformat__ = 'restructuredtext en'
''' '''
Handle the Open Document Format Handle the Open Document Format
''' '''

View File

@ -1,2 +1,4 @@
from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>' __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'

View File

@ -920,7 +920,7 @@ class Manifest(object):
""" """
def __init__(self, oeb, id, href, media_type, def __init__(self, oeb, id, href, media_type,
fallback=None, loader=str, data=None): fallback=None, loader=unicode_type, data=None):
if href: if href:
href = unicode_type(href) href = unicode_type(href)
self.oeb = oeb self.oeb = oeb
@ -937,7 +937,7 @@ class Manifest(object):
self._data = data self._data = data
def __repr__(self): def __repr__(self):
return u'Item(id=%r, href=%r, media_type=%r)' \ return 'Item(id=%r, href=%r, media_type=%r)' \
% (self.id, self.href, self.media_type) % (self.id, self.href, self.media_type)
# Parsing {{{ # Parsing {{{
@ -1024,8 +1024,8 @@ class Manifest(object):
- XML content is parsed and returned as an lxml.etree element. - XML content is parsed and returned as an lxml.etree element.
- CSS and CSS-variant content is parsed and returned as a css_parser - CSS and CSS-variant content is parsed and returned as a css_parser
CSS DOM stylesheet. CSS DOM stylesheet.
- All other content is returned as a :class:`str` object with no - All other content is returned as a :class:`str` or :class:`bytes`
special parsing. object with no special parsing.
""" """
data = self._data data = self._data
if data is None: if data is None:
@ -1642,7 +1642,7 @@ class TOC(object):
po = node.play_order po = node.play_order
if po == 0: if po == 0:
po = 1 po = 1
attrib = {'id': id, 'playOrder': str(po)} attrib = {'id': id, 'playOrder': unicode_type(po)}
if node.klass: if node.klass:
attrib['class'] = node.klass attrib['class'] = node.klass
point = element(parent, NCX('navPoint'), attrib=attrib) point = element(parent, NCX('navPoint'), attrib=attrib)
@ -1925,7 +1925,7 @@ class OEBBook(object):
for i, elem in enumerate(xpath(ncx, '//*[@playOrder and ./ncx:content[@src]]')): for i, elem in enumerate(xpath(ncx, '//*[@playOrder and ./ncx:content[@src]]')):
href = urlnormalize(selector(elem)[0]) href = urlnormalize(selector(elem)[0])
order = playorder.get(href, i) order = playorder.get(href, i)
elem.attrib['playOrder'] = str(order) elem.attrib['playOrder'] = unicode_type(order)
return return
def _to_ncx(self): def _to_ncx(self):
@ -1938,12 +1938,12 @@ class OEBBook(object):
etree.SubElement(head, NCX('meta'), etree.SubElement(head, NCX('meta'),
name='dtb:uid', content=unicode_type(self.uid)) name='dtb:uid', content=unicode_type(self.uid))
etree.SubElement(head, NCX('meta'), etree.SubElement(head, NCX('meta'),
name='dtb:depth', content=str(self.toc.depth())) name='dtb:depth', content=unicode_type(self.toc.depth()))
generator = ''.join(['calibre (', __version__, ')']) generator = ''.join(['calibre (', __version__, ')'])
etree.SubElement(head, NCX('meta'), etree.SubElement(head, NCX('meta'),
name='dtb:generator', content=generator) name='dtb:generator', content=generator)
etree.SubElement(head, NCX('meta'), etree.SubElement(head, NCX('meta'),
name='dtb:totalPageCount', content=str(len(self.pages))) name='dtb:totalPageCount', content=unicode_type(len(self.pages)))
maxpnum = etree.SubElement(head, NCX('meta'), maxpnum = etree.SubElement(head, NCX('meta'),
name='dtb:maxPageNumber', content='0') name='dtb:maxPageNumber', content='0')
title = etree.SubElement(ncx, NCX('docTitle')) title = etree.SubElement(ncx, NCX('docTitle'))
@ -1954,7 +1954,7 @@ class OEBBook(object):
if len(self.pages) > 0: if len(self.pages) > 0:
plist = self.pages.to_ncx(ncx) plist = self.pages.to_ncx(ncx)
value = max(int(x) for x in xpath(plist, '//@value')) value = max(int(x) for x in xpath(plist, '//@value'))
maxpnum.attrib['content'] = str(value) maxpnum.attrib['content'] = unicode_type(value)
self._update_playorder(ncx) self._update_playorder(ncx)
return ncx return ncx

View File

@ -6,13 +6,13 @@ __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
import numbers import numbers
from polyglot.builtins import iteritems, zip, string_or_bytes
from functools import wraps from functools import wraps
from css_parser.css import PropertyValue from css_parser.css import PropertyValue
from css_parser import profile as cssprofiles, CSSParser from css_parser import profile as cssprofiles, CSSParser
from tinycss.fonts3 import parse_font, serialize_font_family from tinycss.fonts3 import parse_font, serialize_font_family
from calibre.ebooks.oeb.base import css_text from calibre.ebooks.oeb.base import css_text
from polyglot.builtins import iteritems, string_or_bytes, unicode_type, zip
DEFAULTS = {'azimuth': 'center', 'background-attachment': 'scroll', # {{{ DEFAULTS = {'azimuth': 'center', 'background-attachment': 'scroll', # {{{
'background-color': 'transparent', 'background-image': 'none', 'background-color': 'transparent', 'background-image': 'none',
@ -393,7 +393,7 @@ def test_normalization(return_tests=False): # {{{
tuple('0 0 0 0'.split()) : '0', tuple('0 0 0 0'.split()) : '0',
}): }):
for prefix in ('margin', 'padding'): for prefix in ('margin', 'padding'):
css = {'%s-%s' % (prefix, x) : str(y)+'pt' if isinstance(y, numbers.Number) else y for x, y in zip(('left', 'top', 'right', 'bottom'), s)} css = {'%s-%s' % (prefix, x) : unicode_type(y)+'pt' if isinstance(y, numbers.Number) else y for x, y in zip(('left', 'top', 'right', 'bottom'), s)}
css = '; '.join(('%s:%s' % (k, v) for k, v in iteritems(css))) css = '; '.join(('%s:%s' % (k, v) for k, v in iteritems(css)))
style = parseStyle(css) style = parseStyle(css)
condense_rule(style) condense_rule(style)

View File

@ -10,7 +10,7 @@ import shutil, re, os
from calibre.ebooks.oeb.base import OPF, OEB_DOCS, XPath, XLINK, xml2text from calibre.ebooks.oeb.base import OPF, OEB_DOCS, XPath, XLINK, xml2text
from calibre.ebooks.oeb.polish.replace import replace_links, get_recommended_folders from calibre.ebooks.oeb.polish.replace import replace_links, get_recommended_folders
from calibre.utils.imghdr import identify from calibre.utils.imghdr import identify
from polyglot.builtins import iteritems from polyglot.builtins import iteritems, unicode_type
def set_azw3_cover(container, cover_path, report, options=None): def set_azw3_cover(container, cover_path, report, options=None):
@ -384,8 +384,8 @@ def create_epub_cover(container, cover_path, existing_image, options=None):
ar = 'xMidYMid meet' if keep_aspect else 'none' ar = 'xMidYMid meet' if keep_aspect else 'none'
templ = CoverManager.SVG_TEMPLATE.replace('__ar__', ar) templ = CoverManager.SVG_TEMPLATE.replace('__ar__', ar)
templ = templ.replace('__viewbox__', '0 0 %d %d'%(width, height)) templ = templ.replace('__viewbox__', '0 0 %d %d'%(width, height))
templ = templ.replace('__width__', str(width)) templ = templ.replace('__width__', unicode_type(width))
templ = templ.replace('__height__', str(height)) templ = templ.replace('__height__', unicode_type(height))
folder = recommended_folders[tname] folder = recommended_folders[tname]
if folder: if folder:
tname = folder + '/' + tname tname = folder + '/' + tname

View File

@ -13,6 +13,7 @@ import html5_parser
from calibre import xml_replace_entities from calibre import xml_replace_entities
from calibre.ebooks.chardet import xml_to_unicode, strip_encoding_declarations from calibre.ebooks.chardet import xml_to_unicode, strip_encoding_declarations
from calibre.utils.cleantext import clean_xml_chars from calibre.utils.cleantext import clean_xml_chars
from polyglot.builtins import unicode_type
XHTML_NS = 'http://www.w3.org/1999/xhtml' XHTML_NS = 'http://www.w3.org/1999/xhtml'
@ -83,7 +84,7 @@ def parse(raw, decoder=None, log=None, line_numbers=True, linenumber_attribute=N
if linenumber_attribute: if linenumber_attribute:
for elem in ans.iter(LxmlElement): for elem in ans.iter(LxmlElement):
if elem.sourceline is not None: if elem.sourceline is not None:
elem.set(linenumber_attribute, str(elem.sourceline)) elem.set(linenumber_attribute, unicode_type(elem.sourceline))
return ans return ans
except Exception: except Exception:
if log is not None: if log is not None:

View File

@ -12,7 +12,7 @@ from calibre.ebooks.oeb.base import barename, XPNSMAP, XPath, OPF, XHTML, OEB_DO
from calibre.ebooks.oeb.polish.errors import MalformedMarkup from calibre.ebooks.oeb.polish.errors import MalformedMarkup
from calibre.ebooks.oeb.polish.toc import node_from_loc from calibre.ebooks.oeb.polish.toc import node_from_loc
from calibre.ebooks.oeb.polish.replace import LinkRebaser from calibre.ebooks.oeb.polish.replace import LinkRebaser
from polyglot.builtins import iteritems from polyglot.builtins import iteritems, unicode_type
from polyglot.urllib import urlparse from polyglot.urllib import urlparse
@ -282,7 +282,7 @@ def multisplit(container, name, xpath, before=True):
raise AbortError('Cannot split on the <body> tag') raise AbortError('Cannot split on the <body> tag')
for i, tag in enumerate(nodes): for i, tag in enumerate(nodes):
tag.set('calibre-split-point', str(i)) tag.set('calibre-split-point', unicode_type(i))
current = name current = name
all_names = [name] all_names = [name]

View File

@ -9,7 +9,6 @@ __docformat__ = 'restructuredtext en'
import re import re
from collections import Counter, OrderedDict from collections import Counter, OrderedDict
from functools import partial from functools import partial
from polyglot.builtins import iteritems, map, unicode_type
from operator import itemgetter from operator import itemgetter
from lxml import etree from lxml import etree
@ -24,6 +23,7 @@ from calibre.ebooks.oeb.polish.opf import set_guide_item, get_book_language
from calibre.ebooks.oeb.polish.pretty import pretty_html_tree from calibre.ebooks.oeb.polish.pretty import pretty_html_tree
from calibre.translations.dynamic import translate from calibre.translations.dynamic import translate
from calibre.utils.localization import get_lang, canonicalize_lang, lang_as_iso639_1 from calibre.utils.localization import get_lang, canonicalize_lang, lang_as_iso639_1
from polyglot.builtins import iteritems, map, unicode_type
from polyglot.urllib import urlparse from polyglot.urllib import urlparse
ns = etree.FunctionNamespace('calibre_xpath_extensions') ns = etree.FunctionNamespace('calibre_xpath_extensions')
@ -104,7 +104,7 @@ class TOC(object):
def get_lines(self, lvl=0): def get_lines(self, lvl=0):
frag = ('#'+self.frag) if self.frag else '' frag = ('#'+self.frag) if self.frag else ''
ans = [(u'\t'*lvl) + u'TOC: %s --> %s%s'%(self.title, self.dest, frag)] ans = [('\t'*lvl) + 'TOC: %s --> %s%s'%(self.title, self.dest, frag)]
for child in self: for child in self:
ans.extend(child.get_lines(lvl+1)) ans.extend(child.get_lines(lvl+1))
return ans return ans
@ -580,7 +580,7 @@ def create_ncx(toc, to_href, btitle, lang, uid):
etree.SubElement(head, NCX('meta'), etree.SubElement(head, NCX('meta'),
name='dtb:uid', content=unicode_type(uid)) name='dtb:uid', content=unicode_type(uid))
etree.SubElement(head, NCX('meta'), etree.SubElement(head, NCX('meta'),
name='dtb:depth', content=str(toc.depth)) name='dtb:depth', content=unicode_type(toc.depth))
generator = ''.join(['calibre (', __version__, ')']) generator = ''.join(['calibre (', __version__, ')'])
etree.SubElement(head, NCX('meta'), etree.SubElement(head, NCX('meta'),
name='dtb:generator', content=generator) name='dtb:generator', content=generator)
@ -598,7 +598,7 @@ def create_ncx(toc, to_href, btitle, lang, uid):
for child in toc_parent: for child in toc_parent:
play_order['c'] += 1 play_order['c'] += 1
point = etree.SubElement(xml_parent, NCX('navPoint'), id='num_%d' % play_order['c'], point = etree.SubElement(xml_parent, NCX('navPoint'), id='num_%d' % play_order['c'],
playOrder=str(play_order['c'])) playOrder=unicode_type(play_order['c']))
label = etree.SubElement(point, NCX('navLabel')) label = etree.SubElement(point, NCX('navLabel'))
title = child.title title = child.title
if title: if title:
@ -764,7 +764,7 @@ def commit_nav_toc(container, toc, lang=None, landmarks=None, previous_nav=None)
for entry in toc.page_list: for entry in toc.page_list:
if container.has_name(entry['dest']) and container.mime_map[entry['dest']] in OEB_DOCS: if container.has_name(entry['dest']) and container.mime_map[entry['dest']] in OEB_DOCS:
a = create_li(ol, entry) a = create_li(ol, entry)
a.text = str(entry['pagenum']) a.text = unicode_type(entry['pagenum'])
pretty_xml_tree(nav) pretty_xml_tree(nav)
collapse_li(nav) collapse_li(nav)
container.replace(tocname, root) container.replace(tocname, root)

View File

@ -1,8 +1,7 @@
""" """
Container-/OPF-based input OEBBook reader. Container-/OPF-based input OEBBook reader.
""" """
from __future__ import with_statement from __future__ import absolute_import, division, print_function, unicode_literals
from __future__ import print_function
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>' __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
@ -150,7 +149,7 @@ class OEBReader(object):
dict(a=__appname__, v=__version__) dict(a=__appname__, v=__version__)
meta_info_to_oeb_metadata(mi, self.oeb.metadata, self.logger) meta_info_to_oeb_metadata(mi, self.oeb.metadata, self.logger)
m = self.oeb.metadata m = self.oeb.metadata
m.add('identifier', str(uuid.uuid4()), id='uuid_id', scheme='uuid') m.add('identifier', unicode_type(uuid.uuid4()), id='uuid_id', scheme='uuid')
self.oeb.uid = self.oeb.metadata.identifier[-1] self.oeb.uid = self.oeb.metadata.identifier[-1]
if not m.title: if not m.title:
m.add('title', self.oeb.translate(__('Unknown'))) m.add('title', self.oeb.translate(__('Unknown')))
@ -198,8 +197,8 @@ class OEBReader(object):
try: try:
data = item.data data = item.data
except: except:
self.oeb.log.exception(u'Failed to read from manifest ' self.oeb.log.exception('Failed to read from manifest '
u'entry with id: %s, ignoring'%item.id) 'entry with id: %s, ignoring'%item.id)
invalid.add(item) invalid.add(item)
continue continue
if data is None: if data is None:
@ -234,7 +233,7 @@ class OEBReader(object):
if not scheme and href not in known: if not scheme and href not in known:
new.add(href) new.add(href)
unchecked.clear() unchecked.clear()
warned = set([]) warned = set()
for href in new: for href in new:
known.add(href) known.add(href)
is_invalid = False is_invalid = False
@ -276,13 +275,13 @@ class OEBReader(object):
media_type = media_type.lower() media_type = media_type.lower()
fallback = elem.get('fallback') fallback = elem.get('fallback')
if href in manifest.hrefs: if href in manifest.hrefs:
self.logger.warn(u'Duplicate manifest entry for %r' % href) self.logger.warn('Duplicate manifest entry for %r' % href)
continue continue
if not self.oeb.container.exists(href): if not self.oeb.container.exists(href):
self.logger.warn(u'Manifest item %r not found' % href) self.logger.warn('Manifest item %r not found' % href)
continue continue
if id in manifest.ids: if id in manifest.ids:
self.logger.warn(u'Duplicate manifest id %r' % id) self.logger.warn('Duplicate manifest id %r' % id)
id, href = manifest.generate(id, href) id, href = manifest.generate(id, href)
manifest.add(id, href, media_type, fallback) manifest.add(id, href, media_type, fallback)
invalid = self._manifest_prune_invalid() invalid = self._manifest_prune_invalid()
@ -333,7 +332,7 @@ class OEBReader(object):
for elem in xpath(opf, '/o2:package/o2:spine/o2:itemref'): for elem in xpath(opf, '/o2:package/o2:spine/o2:itemref'):
idref = elem.get('idref') idref = elem.get('idref')
if idref not in manifest.ids: if idref not in manifest.ids:
self.logger.warn(u'Spine item %r not found' % idref) self.logger.warn('Spine item %r not found' % idref)
continue continue
item = manifest.ids[idref] item = manifest.ids[idref]
if item.media_type.lower() in OEB_DOCS and hasattr(item.data, 'xpath') and not getattr(item.data, 'tag', '').endswith('}ncx'): if item.media_type.lower() in OEB_DOCS and hasattr(item.data, 'xpath') and not getattr(item.data, 'tag', '').endswith('}ncx'):
@ -365,7 +364,7 @@ class OEBReader(object):
corrected_href = href corrected_href = href
break break
if corrected_href is None: if corrected_href is None:
self.logger.warn(u'Guide reference %r not found' % ref_href) self.logger.warn('Guide reference %r not found' % ref_href)
continue continue
ref_href = corrected_href ref_href = corrected_href
typ = elem.get('type') typ = elem.get('type')

View File

@ -3,7 +3,7 @@
''' '''
CSS property propagation class. CSS property propagation class.
''' '''
from __future__ import with_statement from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>' __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
@ -32,7 +32,8 @@ _html_css_stylesheet = None
def html_css_stylesheet(): def html_css_stylesheet():
global _html_css_stylesheet global _html_css_stylesheet
if _html_css_stylesheet is None: if _html_css_stylesheet is None:
html_css = open(P('templates/html.css'), 'rb').read() with open(P('templates/html.css'), 'rb') as f:
html_css = f.read()
_html_css_stylesheet = parseString(html_css, validate=False) _html_css_stylesheet = parseString(html_css, validate=False)
return _html_css_stylesheet return _html_css_stylesheet
@ -74,7 +75,7 @@ def media_ok(raw):
return mq.negated ^ matched return mq.negated ^ matched
try: try:
for mq in CSSMedia3Parser().parse_stylesheet(u'@media %s {}' % raw).rules[0].media: for mq in CSSMedia3Parser().parse_stylesheet('@media %s {}' % raw).rules[0].media:
if query_ok(mq): if query_ok(mq):
return True return True
return False return False
@ -219,14 +220,14 @@ class Stylizer(object):
log=logging.getLogger('calibre.css')) log=logging.getLogger('calibre.css'))
for elem in style_tags: for elem in style_tags:
if (elem.tag == XHTML('style') and elem.get('type', CSS_MIME) in OEB_STYLES and media_ok(elem.get('media'))): if (elem.tag == XHTML('style') and elem.get('type', CSS_MIME) in OEB_STYLES and media_ok(elem.get('media'))):
text = elem.text if elem.text else u'' text = elem.text if elem.text else ''
for x in elem: for x in elem:
t = getattr(x, 'text', None) t = getattr(x, 'text', None)
if t: if t:
text += u'\n\n' + force_unicode(t, u'utf-8') text += '\n\n' + force_unicode(t, 'utf-8')
t = getattr(x, 'tail', None) t = getattr(x, 'tail', None)
if t: if t:
text += u'\n\n' + force_unicode(t, u'utf-8') text += '\n\n' + force_unicode(t, 'utf-8')
if text: if text:
text = oeb.css_preprocessor(text) text = oeb.css_preprocessor(text)
# We handle @import rules separately # We handle @import rules separately
@ -295,7 +296,7 @@ class Stylizer(object):
self.flatten_style = self.oeb.stylizer_rules.flatten_style self.flatten_style = self.oeb.stylizer_rules.flatten_style
self._styles = {} self._styles = {}
pseudo_pat = re.compile(u':{1,2}(%s)' % ('|'.join(INAPPROPRIATE_PSEUDO_CLASSES)), re.I) pseudo_pat = re.compile(':{1,2}(%s)' % ('|'.join(INAPPROPRIATE_PSEUDO_CLASSES)), re.I)
select = Select(tree, ignore_inappropriate_pseudo_classes=True) select = Select(tree, ignore_inappropriate_pseudo_classes=True)
for _, _, cssdict, text, _ in self.rules: for _, _, cssdict, text, _ in self.rules:
@ -309,7 +310,7 @@ class Stylizer(object):
if fl is not None: if fl is not None:
fl = fl.group(1) fl = fl.group(1)
if fl == 'first-letter' and getattr(self.oeb, if fl == 'first-letter' and getattr(self.oeb,
'plumber_output_format', '').lower() in {u'mobi', u'docx'}: 'plumber_output_format', '').lower() in {'mobi', 'docx'}:
# Fake first-letter # Fake first-letter
for elem in matches: for elem in matches:
for x in elem.iter('*'): for x in elem.iter('*'):
@ -323,8 +324,8 @@ class Stylizer(object):
punctuation_chars.append(text[0]) punctuation_chars.append(text[0])
text = text[1:] text = text[1:]
special_text = u''.join(punctuation_chars) + \ special_text = ''.join(punctuation_chars) + \
(text[0] if text else u'') (text[0] if text else '')
span = x.makeelement('{%s}span' % XHTML_NS) span = x.makeelement('{%s}span' % XHTML_NS)
span.text = special_text span.text = special_text
span.set('data-fake-first-letter', '1') span.set('data-fake-first-letter', '1')
@ -486,7 +487,7 @@ class Style(object):
return unit_convert(value, base, font, self._profile.dpi, body_font_size=self._stylizer.body_font_size) return unit_convert(value, base, font, self._profile.dpi, body_font_size=self._stylizer.body_font_size)
def pt_to_px(self, value): def pt_to_px(self, value):
return (self._profile.dpi / 72.0) * value return (self._profile.dpi / 72) * value
@property @property
def backgroundColor(self): def backgroundColor(self):
@ -590,7 +591,7 @@ class Style(object):
x = self._style.get(attr) x = self._style.get(attr)
if x is not None: if x is not None:
if x == 'auto': if x == 'auto':
ans = self._unit_convert(str(img_size) + 'px', base=base) ans = self._unit_convert(unicode_type(img_size) + 'px', base=base)
else: else:
x = self._unit_convert(x, base=base) x = self._unit_convert(x, base=base)
if isinstance(x, numbers.Number): if isinstance(x, numbers.Number):
@ -602,7 +603,7 @@ class Style(object):
if isinstance(x, numbers.Number): if isinstance(x, numbers.Number):
ans = x ans = x
if ans is None: if ans is None:
ans = self._unit_convert(str(img_size) + 'px', base=base) ans = self._unit_convert(unicode_type(img_size) + 'px', base=base)
maa = self._style.get('max-' + attr) maa = self._style.get('max-' + attr)
if maa is not None: if maa is not None:
x = self._unit_convert(maa, base=base) x = self._unit_convert(maa, base=base)

View File

@ -1,10 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import with_statement from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
@ -16,7 +17,7 @@ from polyglot.urllib import unquote
class CoverManager(object): class CoverManager(object):
SVG_TEMPLATE = textwrap.dedent(u'''\ SVG_TEMPLATE = textwrap.dedent('''\
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
@ -40,7 +41,7 @@ class CoverManager(object):
</html> </html>
''') ''')
NONSVG_TEMPLATE = textwrap.dedent(u'''\ NONSVG_TEMPLATE = textwrap.dedent('''\
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
@ -103,7 +104,7 @@ class CoverManager(object):
pass pass
img_data = create_cover(title, authors, series, series_index) img_data = create_cover(title, authors, series, series_index)
id, href = self.oeb.manifest.generate('cover', id, href = self.oeb.manifest.generate('cover',
u'cover_image.jpg') 'cover_image.jpg')
item = self.oeb.manifest.add(id, href, guess_type('t.jpg')[0], item = self.oeb.manifest.add(id, href, guess_type('t.jpg')[0],
data=img_data) data=img_data)
m.clear('cover') m.clear('cover')
@ -145,15 +146,15 @@ class CoverManager(object):
self.svg_template = self.svg_template.replace('__viewbox__', self.svg_template = self.svg_template.replace('__viewbox__',
'0 0 %d %d'%(width, height)) '0 0 %d %d'%(width, height))
self.svg_template = self.svg_template.replace('__width__', self.svg_template = self.svg_template.replace('__width__',
str(width)) unicode_type(width))
self.svg_template = self.svg_template.replace('__height__', self.svg_template = self.svg_template.replace('__height__',
str(height)) unicode_type(height))
if href is not None: if href is not None:
templ = self.non_svg_template if self.no_svg_cover \ templ = self.non_svg_template if self.no_svg_cover \
else self.svg_template else self.svg_template
tp = templ%unquote(href) tp = templ%unquote(href)
id, href = m.generate('titlepage', u'titlepage.xhtml') id, href = m.generate('titlepage', 'titlepage.xhtml')
item = m.add(id, href, guess_type('t.xhtml')[0], item = m.add(id, href, guess_type('t.xhtml')[0],
data=etree.fromstring(tp)) data=etree.fromstring(tp))
else: else:

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
@ -96,7 +97,7 @@ class UniqueFilenames(object): # {{{
self.opts = opts self.opts = opts
self.oeb = oeb self.oeb = oeb
self.seen_filenames = set([]) self.seen_filenames = set()
self.rename_map = {} self.rename_map = {}
for item in list(oeb.manifest.items): for item in list(oeb.manifest.items):

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import with_statement from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'

View File

@ -1,7 +1,7 @@
''' '''
HTML-TOC-adding transform. HTML-TOC-adding transform.
''' '''
from __future__ import with_statement from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>' __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
@ -9,6 +9,7 @@ __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
from calibre.ebooks.oeb.base import XML, XHTML, XHTML_NS from calibre.ebooks.oeb.base import XML, XHTML, XHTML_NS
from calibre.ebooks.oeb.base import XHTML_MIME, CSS_MIME from calibre.ebooks.oeb.base import XHTML_MIME, CSS_MIME
from calibre.ebooks.oeb.base import element, XPath from calibre.ebooks.oeb.base import element, XPath
from polyglot.builtins import unicode_type
__all__ = ['HTMLTOCAdder'] __all__ = ['HTMLTOCAdder']
@ -94,7 +95,7 @@ class HTMLTOCAdder(object):
style = 'nested' style = 'nested'
id, css_href = oeb.manifest.generate('tocstyle', 'tocstyle.css') id, css_href = oeb.manifest.generate('tocstyle', 'tocstyle.css')
oeb.manifest.add(id, css_href, CSS_MIME, data=STYLE_CSS[style]) oeb.manifest.add(id, css_href, CSS_MIME, data=STYLE_CSS[style])
language = str(oeb.metadata.language[0]) language = unicode_type(oeb.metadata.language[0])
contents = element(None, XHTML('html'), nsmap={None: XHTML_NS}, contents = element(None, XHTML('html'), nsmap={None: XHTML_NS},
attrib={XML('lang'): language}) attrib={XML('lang'): language})
head = element(contents, XHTML('head')) head = element(contents, XHTML('head'))

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import with_statement from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'

View File

@ -1,7 +1,7 @@
''' '''
CSS case-mangling transform. CSS case-mangling transform.
''' '''
from __future__ import with_statement from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>' __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'

View File

@ -1,7 +1,7 @@
''' '''
SVG rasterization transform. SVG rasterization transform.
''' '''
from __future__ import with_statement from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>' __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
@ -77,7 +77,7 @@ class SVGRasterizer(object):
logger.info('Found SVG image height in %, trying to convert...') logger.info('Found SVG image height in %, trying to convert...')
try: try:
h = float(image.get('height').replace('%', ''))/100. h = float(image.get('height').replace('%', ''))/100.
image.set('height', str(h*sizes[1])) image.set('height', unicode_type(h*sizes[1]))
except: except:
logger.exception('Failed to convert percentage height:', logger.exception('Failed to convert percentage height:',
image.get('height')) image.get('height'))
@ -101,7 +101,7 @@ class SVGRasterizer(object):
buffer = QBuffer(array) buffer = QBuffer(array)
buffer.open(QIODevice.WriteOnly) buffer.open(QIODevice.WriteOnly)
image.save(buffer, format) image.save(buffer, format)
return str(array) return array.data()
def dataize_manifest(self): def dataize_manifest(self):
for item in self.oeb.manifest.values(): for item in self.oeb.manifest.values():
@ -121,10 +121,10 @@ class SVGRasterizer(object):
if abshref not in hrefs: if abshref not in hrefs:
continue continue
linkee = hrefs[abshref] linkee = hrefs[abshref]
data = str(linkee) data = unicode_type(linkee)
ext = what(None, data) or 'jpg' ext = what(None, data) or 'jpg'
with PersistentTemporaryFile(suffix='.'+ext) as pt: with PersistentTemporaryFile(suffix='.'+ext) as pt:
pt.write(data) pt.write(data.encode('utf-8'))
self.temp_files.append(pt.name) self.temp_files.append(pt.name)
elem.attrib[XLINK('href')] = pt.name elem.attrib[XLINK('href')] = pt.name
return svg return svg
@ -182,7 +182,7 @@ class SVGRasterizer(object):
height = style['height'] height = style['height']
width = (width / 72) * self.profile.dpi width = (width / 72) * self.profile.dpi
height = (height / 72) * self.profile.dpi height = (height / 72) * self.profile.dpi
data = QByteArray(str(svgitem)) data = QByteArray(unicode_type(svgitem).encode('utf-8'))
svg = QSvgRenderer(data) svg = QSvgRenderer(data)
size = svg.defaultSize() size = svg.defaultSize()
size.scale(width, height, Qt.KeepAspectRatio) size.scale(width, height, Qt.KeepAspectRatio)
@ -202,7 +202,7 @@ class SVGRasterizer(object):
buffer = QBuffer(array) buffer = QBuffer(array)
buffer.open(QIODevice.WriteOnly) buffer.open(QIODevice.WriteOnly)
image.save(buffer, 'PNG') image.save(buffer, 'PNG')
data = str(array) data = array.data()
manifest = self.oeb.manifest manifest = self.oeb.manifest
href = os.path.splitext(svgitem.href)[0] + '.png' href = os.path.splitext(svgitem.href)[0] + '.png'
id, href = manifest.generate(svgitem.id, href) id, href = manifest.generate(svgitem.id, href)

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import with_statement from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
@ -30,8 +30,8 @@ class RescaleImages(object):
page_width, page_height = self.opts.dest.comic_screen_size page_width, page_height = self.opts.dest.comic_screen_size
else: else:
page_width, page_height = self.opts.dest.width, self.opts.dest.height page_width, page_height = self.opts.dest.width, self.opts.dest.height
page_width -= (self.opts.margin_left + self.opts.margin_right) * self.opts.dest.dpi/72. page_width -= (self.opts.margin_left + self.opts.margin_right) * self.opts.dest.dpi/72
page_height -= (self.opts.margin_top + self.opts.margin_bottom) * self.opts.dest.dpi/72. page_height -= (self.opts.margin_top + self.opts.margin_bottom) * self.opts.dest.dpi/72
for item in self.oeb.manifest: for item in self.oeb.manifest:
if item.media_type.startswith('image'): if item.media_type.startswith('image'):

View File

@ -1,7 +1,7 @@
''' '''
Directory output OEBBook writer. Directory output OEBBook writer.
''' '''
from __future__ import with_statement from __future__ import absolute_import, division, print_function, unicode_literals
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>' __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'

View File

@ -357,7 +357,7 @@ class DisplayPluginModel(QAbstractTableModel):
def _get_display_version(self, version): def _get_display_version(self, version):
if version is None: if version is None:
return '' return ''
return '.'.join([str(v) for v in list(version)]) return '.'.join([unicode_type(v) for v in list(version)])
def _get_status(self, display_plugin): def _get_status(self, display_plugin):
if not display_plugin.is_valid_platform(): if not display_plugin.is_valid_platform():

View File

@ -139,7 +139,7 @@ speedup_fdopen(PyObject *self, PyObject *args) {
if (!PyArg_ParseTuple(args, "iss|i", &fd, &name, &mode, &bufsize)) return NULL; if (!PyArg_ParseTuple(args, "iss|i", &fd, &name, &mode, &bufsize)) return NULL;
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
ans = PyFile_FromFd(fd, name, mode, bufsize, NULL, NULL, NULL, 1); ans = PyFile_FromFd(fd, NULL, mode, bufsize, NULL, NULL, NULL, 1);
#else #else
fp = fdopen(fd, mode); fp = fdopen(fd, mode);
if (fp == NULL) return PyErr_SetFromErrno(PyExc_OSError); if (fp == NULL) return PyErr_SetFromErrno(PyExc_OSError);