This commit is contained in:
Kovid Goyal 2021-10-21 10:38:56 +05:30
commit f9694a218c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
741 changed files with 3715 additions and 4350 deletions

View File

@ -9,7 +9,6 @@ import sys
from datetime import datetime from datetime import datetime
from urllib.request import urlopen from urllib.request import urlopen
from polyglot.builtins import filter
from setup import download_securely from setup import download_securely

View File

@ -13,7 +13,7 @@ from functools import partial
from setup import Command, __appname__, __version__, require_git_master, build_cache_dir, edit_file, dump_json from setup import Command, __appname__, __version__, require_git_master, build_cache_dir, edit_file, dump_json
from setup.parallel_build import batched_parallel_jobs from setup.parallel_build import batched_parallel_jobs
from polyglot.builtins import codepoint_to_chr, iteritems, range from polyglot.builtins import codepoint_to_chr, iteritems
is_ci = os.environ.get('CI', '').lower() == 'true' is_ci = os.environ.get('CI', '').lower() == 'true'

View File

@ -1,11 +1,10 @@
''' E-book management software''' ''' E-book management software'''
__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'
import sys, os, re, time, random, warnings import sys, os, re, time, random, warnings
from polyglot.builtins import codepoint_to_chr, unicode_type, range, hasenv, native_string_type from polyglot.builtins import codepoint_to_chr, hasenv, native_string_type
from math import floor from math import floor
from functools import partial from functools import partial
@ -13,7 +12,7 @@ if not hasenv('CALIBRE_SHOW_DEPRECATION_WARNINGS'):
warnings.simplefilter('ignore', DeprecationWarning) warnings.simplefilter('ignore', DeprecationWarning)
try: try:
os.getcwd() os.getcwd()
except EnvironmentError: except OSError:
os.chdir(os.path.expanduser('~')) os.chdir(os.path.expanduser('~'))
from calibre.constants import (iswindows, ismacos, islinux, isfrozen, from calibre.constants import (iswindows, ismacos, islinux, isfrozen,
@ -71,7 +70,7 @@ def get_types_map():
def to_unicode(raw, encoding='utf-8', errors='strict'): def to_unicode(raw, encoding='utf-8', errors='strict'):
if isinstance(raw, unicode_type): if isinstance(raw, str):
return raw return raw
return raw.decode(encoding, errors) return raw.decode(encoding, errors)
@ -259,7 +258,7 @@ def get_parsed_proxy(typ='http', debug=True):
traceback.print_exc() traceback.print_exc()
else: else:
if debug: if debug:
prints('Using http proxy', unicode_type(ans)) prints('Using http proxy', str(ans))
return ans return ans
@ -372,7 +371,7 @@ class CurrentDir:
def __exit__(self, *args): def __exit__(self, *args):
try: try:
os.chdir(self.cwd) os.chdir(self.cwd)
except EnvironmentError: except OSError:
# The previous CWD no longer exists # The previous CWD no longer exists
pass pass
@ -419,7 +418,7 @@ def strftime(fmt, t=None):
fmt = fmt.decode('mbcs' if iswindows else 'utf-8', 'replace') fmt = fmt.decode('mbcs' if iswindows else 'utf-8', 'replace')
ans = time.strftime(fmt, t) ans = time.strftime(fmt, t)
if early_year: if early_year:
ans = ans.replace('_early year hack##', unicode_type(orig_year)) ans = ans.replace('_early year hack##', str(orig_year))
return ans return ans
@ -531,7 +530,7 @@ def force_unicode(obj, enc=preferred_encoding):
def as_unicode(obj, enc=preferred_encoding): def as_unicode(obj, enc=preferred_encoding):
if not isbytestring(obj): if not isbytestring(obj):
try: try:
obj = unicode_type(obj) obj = str(obj)
except Exception: except Exception:
try: try:
obj = native_string_type(obj) obj = native_string_type(obj)
@ -554,7 +553,7 @@ def human_readable(size, sep=' '):
if size < (1 << ((i + 1) * 10)): if size < (1 << ((i + 1) * 10)):
divisor, suffix = (1 << (i * 10)), candidate divisor, suffix = (1 << (i * 10)), candidate
break break
size = unicode_type(float(size)/divisor) size = str(float(size)/divisor)
if size.find(".") > -1: if size.find(".") > -1:
size = size[:size.find(".")+2] size = size[:size.find(".")+2]
if size.endswith('.0'): if size.endswith('.0'):

View File

@ -1,12 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
# vim:fileencoding=utf-8 # vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
from polyglot.builtins import map, unicode_type, environ_item, hasenv, getenv from polyglot.builtins import environ_item, hasenv
import sys, locale, codecs, os, collections, collections.abc import sys, locale, codecs, os, collections, collections.abc
__appname__ = 'calibre' __appname__ = 'calibre'
numeric_version = (5, 29, 0) numeric_version = (5, 29, 0)
__version__ = '.'.join(map(unicode_type, numeric_version)) __version__ = '.'.join(map(str, numeric_version))
git_version = None git_version = None
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>" __author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
@ -118,18 +118,18 @@ def _get_cache_dir():
confcache = os.path.join(config_dir, 'caches') confcache = os.path.join(config_dir, 'caches')
try: try:
os.makedirs(confcache) os.makedirs(confcache)
except EnvironmentError as err: except OSError as err:
if err.errno != errno.EEXIST: if err.errno != errno.EEXIST:
raise raise
if isportable: if isportable:
return confcache return confcache
ccd = getenv('CALIBRE_CACHE_DIRECTORY') ccd = os.getenv('CALIBRE_CACHE_DIRECTORY')
if ccd is not None: if ccd is not None:
ans = os.path.abspath(ccd) ans = os.path.abspath(ccd)
try: try:
os.makedirs(ans) os.makedirs(ans)
return ans return ans
except EnvironmentError as err: except OSError as err:
if err.errno == errno.EEXIST: if err.errno == errno.EEXIST:
return ans return ans
@ -141,7 +141,7 @@ def _get_cache_dir():
elif ismacos: elif ismacos:
candidate = os.path.join(os.path.expanduser('~/Library/Caches'), __appname__) candidate = os.path.join(os.path.expanduser('~/Library/Caches'), __appname__)
else: else:
candidate = getenv('XDG_CACHE_HOME', '~/.cache') candidate = os.getenv('XDG_CACHE_HOME', '~/.cache')
candidate = os.path.join(os.path.expanduser(candidate), candidate = os.path.join(os.path.expanduser(candidate),
__appname__) __appname__)
if isinstance(candidate, bytes): if isinstance(candidate, bytes):
@ -151,7 +151,7 @@ def _get_cache_dir():
candidate = confcache candidate = confcache
try: try:
os.makedirs(candidate) os.makedirs(candidate)
except EnvironmentError as err: except OSError as err:
if err.errno != errno.EEXIST: if err.errno != errno.EEXIST:
candidate = confcache candidate = confcache
return candidate return candidate
@ -340,7 +340,7 @@ if plugins is None:
CONFIG_DIR_MODE = 0o700 CONFIG_DIR_MODE = 0o700
cconfd = getenv('CALIBRE_CONFIG_DIRECTORY') cconfd = os.getenv('CALIBRE_CONFIG_DIRECTORY')
if cconfd is not None: if cconfd is not None:
config_dir = os.path.abspath(cconfd) config_dir = os.path.abspath(cconfd)
elif iswindows: elif iswindows:
@ -354,7 +354,7 @@ elif iswindows:
elif ismacos: elif ismacos:
config_dir = os.path.expanduser('~/Library/Preferences/calibre') config_dir = os.path.expanduser('~/Library/Preferences/calibre')
else: else:
bdir = os.path.abspath(os.path.expanduser(getenv('XDG_CONFIG_HOME', '~/.config'))) bdir = os.path.abspath(os.path.expanduser(os.getenv('XDG_CONFIG_HOME', '~/.config')))
config_dir = os.path.join(bdir, 'calibre') config_dir = os.path.join(bdir, 'calibre')
try: try:
os.makedirs(config_dir, mode=CONFIG_DIR_MODE) os.makedirs(config_dir, mode=CONFIG_DIR_MODE)
@ -386,7 +386,7 @@ if getattr(sys, 'frozen', False):
else: else:
is_running_from_develop = running_in_develop_mode() is_running_from_develop = running_in_develop_mode()
in_develop_mode = getenv('CALIBRE_ENABLE_DEVELOP_MODE') == '1' in_develop_mode = os.getenv('CALIBRE_ENABLE_DEVELOP_MODE') == '1'
def get_version(): def get_version():
@ -415,7 +415,7 @@ def get_appname_for_display():
def get_portable_base(): def get_portable_base():
'Return path to the directory that contains calibre-portable.exe or None' 'Return path to the directory that contains calibre-portable.exe or None'
if isportable: if isportable:
return os.path.dirname(os.path.dirname(getenv('CALIBRE_PORTABLE_BUILD'))) return os.path.dirname(os.path.dirname(os.getenv('CALIBRE_PORTABLE_BUILD')))
def get_windows_username(): def get_windows_username():

View File

@ -1,4 +1,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
@ -6,7 +5,6 @@ import os, sys, zipfile, importlib, enum
from calibre.constants import numeric_version, iswindows, ismacos from calibre.constants import numeric_version, iswindows, ismacos
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from polyglot.builtins import unicode_type
if iswindows: if iswindows:
platform = 'windows' platform = 'windows'
@ -207,7 +205,7 @@ class Plugin: # {{{
config_dialog.exec_() config_dialog.exec_()
if config_dialog.result() == QDialog.DialogCode.Accepted: if config_dialog.result() == QDialog.DialogCode.Accepted:
sc = unicode_type(sc.text()).strip() sc = str(sc.text()).strip()
customize_plugin(self, sc) customize_plugin(self, sc)
geom = bytearray(config_dialog.saveGeometry()) geom = bytearray(config_dialog.saveGeometry())

View File

@ -1814,7 +1814,7 @@ class StoreWeightlessBooksStore(StoreBase):
class StoreWHSmithUKStore(StoreBase): class StoreWHSmithUKStore(StoreBase):
name = 'WH Smith UK' name = 'WH Smith UK'
author = 'Charles Haley' author = 'Charles Haley'
description = u"Shop for savings on Books, discounted Magazine subscriptions and great prices on Stationery, Toys & Games" description = "Shop for savings on Books, discounted Magazine subscriptions and great prices on Stationery, Toys & Games"
actual_plugin = 'calibre.gui2.store.stores.whsmith_uk_plugin:WHSmithUKStore' actual_plugin = 'calibre.gui2.store.stores.whsmith_uk_plugin:WHSmithUKStore'
headquarters = 'UK' headquarters = 'UK'

View File

@ -7,7 +7,6 @@ import re, os, shutil, numbers
from calibre import CurrentDir from calibre import CurrentDir
from calibre.customize import Plugin from calibre.customize import Plugin
from polyglot.builtins import unicode_type
class ConversionOption: class ConversionOption:
@ -81,7 +80,7 @@ class OptionRecommendation:
self.option.choices: self.option.choices:
raise ValueError('OpRec: %s: Recommended value not in choices'% raise ValueError('OpRec: %s: Recommended value not in choices'%
self.option.name) self.option.name)
if not (isinstance(self.recommended_value, (numbers.Number, bytes, unicode_type)) or self.recommended_value is None): if not (isinstance(self.recommended_value, (numbers.Number, bytes, str)) or self.recommended_value is None):
raise ValueError('OpRec: %s:'%self.option.name + repr( raise ValueError('OpRec: %s:'%self.option.name + repr(
self.recommended_value) + ' is not a string or a number') self.recommended_value) + ' is not a string or a number')
@ -342,7 +341,7 @@ class OutputFormatPlugin(Plugin):
@property @property
def is_periodical(self): def is_periodical(self):
return self.oeb.metadata.publication_type and \ return self.oeb.metadata.publication_type and \
unicode_type(self.oeb.metadata.publication_type[0]).startswith('periodical:') str(self.oeb.metadata.publication_type[0]).startswith('periodical:')
def specialize_options(self, log, opts, input_fmt): def specialize_options(self, log, opts, input_fmt):
''' '''

View File

@ -5,7 +5,6 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
from calibre.customize import Plugin as _Plugin from calibre.customize import Plugin as _Plugin
from polyglot.builtins import zip
FONT_SIZES = [('xx-small', 1), FONT_SIZES = [('xx-small', 1),
('x-small', None), ('x-small', None),
@ -32,8 +31,8 @@ class Plugin(_Plugin):
self.fsizes = [] self.fsizes = []
for (name, num), size in zip(FONT_SIZES, fsizes): for (name, num), size in zip(FONT_SIZES, fsizes):
self.fsizes.append((name, num, float(size))) self.fsizes.append((name, num, float(size)))
self.fnames = dict((name, sz) for name, _, sz in self.fsizes if name) self.fnames = {name: sz for name, _, sz in self.fsizes if name}
self.fnums = dict((num, sz) for _, num, sz in self.fsizes if num) self.fnums = {num: sz for _, num, sz in self.fsizes if num}
self.width_pts = self.width * 72./self.dpi self.width_pts = self.width * 72./self.dpi
self.height_pts = self.height * 72./self.dpi self.height_pts = self.height * 72./self.dpi
@ -487,7 +486,7 @@ class SonyReaderOutput(OutputProfile):
dpi = 168.451 dpi = 168.451
fbase = 12 fbase = 12
fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24] fsizes = [7.5, 9, 10, 12, 15.5, 20, 22, 24]
unsupported_unicode_chars = [u'\u201f', u'\u201b'] unsupported_unicode_chars = ['\u201f', '\u201b']
epub_periodical_format = 'sony' epub_periodical_format = 'sony'
# periodical_date_in_title = False # periodical_date_in_title = False

View File

@ -1,4 +1,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
@ -22,7 +21,7 @@ from calibre.utils.config import (make_config_dir, Config, ConfigProxy,
plugin_dir, OptionParser) plugin_dir, OptionParser)
from calibre.ebooks.metadata.sources.base import Source from calibre.ebooks.metadata.sources.base import Source
from calibre.constants import DEBUG, numeric_version, system_plugins_loc from calibre.constants import DEBUG, numeric_version, system_plugins_loc
from polyglot.builtins import iteritems, itervalues, unicode_type from polyglot.builtins import iteritems, itervalues
builtin_names = frozenset(p.name for p in builtin_plugins) builtin_names = frozenset(p.name for p in builtin_plugins)
BLACKLISTED_PLUGINS = frozenset({'Marvin XD', 'iOS reader applications'}) BLACKLISTED_PLUGINS = frozenset({'Marvin XD', 'iOS reader applications'})
@ -769,8 +768,7 @@ initialize_plugins()
def initialized_plugins(): def initialized_plugins():
for plugin in _initialized_plugins: yield from _initialized_plugins
yield plugin
# }}} # }}}
@ -781,12 +779,12 @@ def build_plugin(path):
from calibre import prints from calibre import prints
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils.zipfile import ZipFile, ZIP_STORED from calibre.utils.zipfile import ZipFile, ZIP_STORED
path = unicode_type(path) path = str(path)
names = frozenset(os.listdir(path)) names = frozenset(os.listdir(path))
if '__init__.py' not in names: if '__init__.py' not in names:
prints(path, ' is not a valid plugin') prints(path, ' is not a valid plugin')
raise SystemExit(1) raise SystemExit(1)
t = PersistentTemporaryFile(u'.zip') t = PersistentTemporaryFile('.zip')
with ZipFile(t, 'w', ZIP_STORED) as zf: with ZipFile(t, 'w', ZIP_STORED) as zf:
zf.add_dir(path, simple_filter=lambda x:x in {'.git', '.bzr', '.svn', '.hg'}) zf.add_dir(path, simple_filter=lambda x:x in {'.git', '.bzr', '.svn', '.hg'})
t.close() t.close()
@ -852,7 +850,7 @@ def main(args=sys.argv):
for plugin in initialized_plugins(): for plugin in initialized_plugins():
type_len, name_len = max(type_len, len(plugin.type)), max(name_len, len(plugin.name)) type_len, name_len = max(type_len, len(plugin.type)), max(name_len, len(plugin.name))
fmt = '%-{}s%-{}s%-15s%-15s%s'.format(type_len+1, name_len+1) fmt = '%-{}s%-{}s%-15s%-15s%s'.format(type_len+1, name_len+1)
print(fmt%tuple(('Type|Name|Version|Disabled|Site Customization'.split('|')))) print(fmt%tuple('Type|Name|Version|Disabled|Site Customization'.split('|')))
print() print()
for plugin in initialized_plugins(): for plugin in initialized_plugins():
print(fmt%( print(fmt%(

View File

@ -22,7 +22,7 @@ from calibre import as_unicode
from calibre.customize import ( from calibre.customize import (
InvalidPlugin, Plugin, PluginNotFound, numeric_version, platform InvalidPlugin, Plugin, PluginNotFound, numeric_version, platform
) )
from polyglot.builtins import itervalues, map, reload, string_or_bytes, unicode_type from polyglot.builtins import itervalues, reload, string_or_bytes
# PEP 302 based plugin loading mechanism, works around the bug in zipimport in # PEP 302 based plugin loading mechanism, works around the bug in zipimport in
# python 2.x that prevents importing from zip files in locations whose paths # python 2.x that prevents importing from zip files in locations whose paths
@ -307,7 +307,7 @@ class CalibrePluginFinder:
if ans.minimum_calibre_version > numeric_version: if ans.minimum_calibre_version > numeric_version:
raise InvalidPlugin( raise InvalidPlugin(
'The plugin at %s needs a version of calibre >= %s' % 'The plugin at %s needs a version of calibre >= %s' %
(as_unicode(path_to_zip_file), '.'.join(map(unicode_type, (as_unicode(path_to_zip_file), '.'.join(map(str,
ans.minimum_calibre_version)))) ans.minimum_calibre_version))))
if platform not in ans.supported_platforms: if platform not in ans.supported_platforms:
@ -340,9 +340,9 @@ class CalibrePluginFinder:
break break
else: else:
if self._identifier_pat.match(plugin_name) is None: if self._identifier_pat.match(plugin_name) is None:
raise InvalidPlugin(( raise InvalidPlugin(
'The plugin at %r uses an invalid import name: %r' % 'The plugin at %r uses an invalid import name: %r' %
(path_to_zip_file, plugin_name))) (path_to_zip_file, plugin_name))
pynames = [x for x in names if x.endswith('.py')] pynames = [x for x in names if x.endswith('.py')]

View File

@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
SPOOL_SIZE = 30*1024*1024 SPOOL_SIZE = 30*1024*1024
import numbers import numbers
from polyglot.builtins import iteritems, range from polyglot.builtins import iteritems
def _get_next_series_num_for_list(series_indices, unwrap=True): def _get_next_series_num_for_list(series_indices, unwrap=True):
@ -77,10 +77,10 @@ def get_data_as_dict(self, prefix=None, authors_as_string=False, ids=None, conve
prefix = backend.library_path prefix = backend.library_path
fdata = backend.custom_column_num_map fdata = backend.custom_column_num_map
FIELDS = set(['title', 'sort', 'authors', 'author_sort', 'publisher', FIELDS = {'title', 'sort', 'authors', 'author_sort', 'publisher',
'rating', 'timestamp', 'size', 'tags', 'comments', 'series', 'rating', 'timestamp', 'size', 'tags', 'comments', 'series',
'series_index', 'uuid', 'pubdate', 'last_modified', 'identifiers', 'series_index', 'uuid', 'pubdate', 'last_modified', 'identifiers',
'languages']).union(set(fdata)) 'languages'}.union(set(fdata))
for x, data in iteritems(fdata): for x, data in iteritems(fdata):
if data['datatype'] == 'series': if data['datatype'] == 'series':
FIELDS.add('%d_index'%x) FIELDS.add('%d_index'%x)

View File

@ -16,7 +16,7 @@ from calibre import prints
from calibre.constants import filesystem_encoding, ismacos, iswindows from calibre.constants import filesystem_encoding, ismacos, iswindows
from calibre.ebooks import BOOK_EXTENSIONS from calibre.ebooks import BOOK_EXTENSIONS
from calibre.utils.filenames import make_long_path_useable from calibre.utils.filenames import make_long_path_useable
from polyglot.builtins import itervalues, map as it_map, unicode_type from polyglot.builtins import itervalues
def splitext(path): def splitext(path):
@ -71,7 +71,7 @@ def metadata_extensions():
# but not actually added) # but not actually added)
global _metadata_extensions global _metadata_extensions
if _metadata_extensions is None: if _metadata_extensions is None:
_metadata_extensions = frozenset(it_map(unicode_type, BOOK_EXTENSIONS)) | {'opf'} _metadata_extensions = frozenset(BOOK_EXTENSIONS) | {'opf'}
return _metadata_extensions return _metadata_extensions
@ -93,7 +93,7 @@ def listdir(root, sort_by_mtime=False):
def safe_mtime(x): def safe_mtime(x):
try: try:
return os.path.getmtime(x) return os.path.getmtime(x)
except EnvironmentError: except OSError:
return time.time() return time.time()
items = sorted(items, key=safe_mtime) items = sorted(items, key=safe_mtime)
@ -146,7 +146,7 @@ def find_books_in_directory(dirpath, single_book_per_directory, compiled_rules=(
for path in listdir_impl(dirpath, sort_by_mtime=True): for path in listdir_impl(dirpath, sort_by_mtime=True):
key, ext = splitext(path) key, ext = splitext(path)
if allow_path(path, ext, compiled_rules): if allow_path(path, ext, compiled_rules):
books[icu_lower(key) if isinstance(key, unicode_type) else key.lower()][ext] = path books[icu_lower(key) if isinstance(key, str) else key.lower()][ext] = path
for formats in itervalues(books): for formats in itervalues(books):
if formats_ok(formats): if formats_ok(formats):
@ -230,8 +230,7 @@ def cdb_find_in_dir(dirpath, single_book_per_directory, compiled_rules):
def cdb_recursive_find(root, single_book_per_directory=True, compiled_rules=()): def cdb_recursive_find(root, single_book_per_directory=True, compiled_rules=()):
root = os.path.abspath(root) root = os.path.abspath(root)
for dirpath in os.walk(root): for dirpath in os.walk(root):
for formats in cdb_find_in_dir(dirpath[0], single_book_per_directory, compiled_rules): yield from cdb_find_in_dir(dirpath[0], single_book_per_directory, compiled_rules)
yield formats
def add_catalog(cache, path, title, dbapi=None): def add_catalog(cache, path, title, dbapi=None):

View File

@ -50,8 +50,7 @@ from calibre.utils.formatter_functions import (
from calibre.utils.icu import sort_key from calibre.utils.icu import sort_key
from calibre.utils.img import save_cover_data_to from calibre.utils.img import save_cover_data_to
from polyglot.builtins import ( from polyglot.builtins import (
cmp, iteritems, itervalues, native_string_type, reraise, string_or_bytes, cmp, iteritems, itervalues, native_string_type, reraise, string_or_bytes
unicode_type
) )
# }}} # }}}
@ -108,7 +107,7 @@ class DBPrefs(dict): # {{{
dict.__setitem__(self, key, val) dict.__setitem__(self, key, val)
def raw_to_object(self, raw): def raw_to_object(self, raw):
if not isinstance(raw, unicode_type): if not isinstance(raw, str):
raw = raw.decode(preferred_encoding) raw = raw.decode(preferred_encoding)
return json.loads(raw, object_hook=from_json) return json.loads(raw, object_hook=from_json)
@ -152,18 +151,18 @@ class DBPrefs(dict): # {{{
self.__setitem__(key, val) self.__setitem__(key, val)
def get_namespaced(self, namespace, key, default=None): def get_namespaced(self, namespace, key, default=None):
key = u'namespaced:%s:%s'%(namespace, key) key = 'namespaced:%s:%s'%(namespace, key)
try: try:
return dict.__getitem__(self, key) return dict.__getitem__(self, key)
except KeyError: except KeyError:
return default return default
def set_namespaced(self, namespace, key, val): def set_namespaced(self, namespace, key, val):
if u':' in key: if ':' in key:
raise KeyError('Colons are not allowed in keys') raise KeyError('Colons are not allowed in keys')
if u':' in namespace: if ':' in namespace:
raise KeyError('Colons are not allowed in the namespace') raise KeyError('Colons are not allowed in the namespace')
key = u'namespaced:%s:%s'%(namespace, key) key = 'namespaced:%s:%s'%(namespace, key)
self[key] = val self[key] = val
def write_serialized(self, library_path): def write_serialized(self, library_path):
@ -262,7 +261,7 @@ def IdentifiersConcat():
'''String concatenation aggregator for the identifiers map''' '''String concatenation aggregator for the identifiers map'''
def step(ctxt, key, val): def step(ctxt, key, val):
ctxt.append(u'%s:%s'%(key, val)) ctxt.append('%s:%s'%(key, val))
def finalize(ctxt): def finalize(ctxt):
try: try:
@ -352,7 +351,7 @@ class Connection(apsw.Connection): # {{{
self.createscalarfunction('title_sort', title_sort, 1) self.createscalarfunction('title_sort', title_sort, 1)
self.createscalarfunction('author_to_author_sort', self.createscalarfunction('author_to_author_sort',
_author_to_author_sort, 1) _author_to_author_sort, 1)
self.createscalarfunction('uuid4', lambda: unicode_type(uuid.uuid4()), self.createscalarfunction('uuid4', lambda: str(uuid.uuid4()),
0) 0)
# Dummy functions for dynamically created filters # Dummy functions for dynamically created filters
@ -403,7 +402,7 @@ def set_global_state(backend):
def rmtree_with_retry(path, sleep_time=1): def rmtree_with_retry(path, sleep_time=1):
try: try:
shutil.rmtree(path) shutil.rmtree(path)
except EnvironmentError as e: except OSError as e:
if e.errno == errno.ENOENT and not os.path.exists(path): if e.errno == errno.ENOENT and not os.path.exists(path):
return return
time.sleep(sleep_time) # In case something has temporarily locked a file time.sleep(sleep_time) # In case something has temporarily locked a file
@ -646,10 +645,10 @@ class DB:
prints('found user category case overlap', catmap[uc]) prints('found user category case overlap', catmap[uc])
cat = catmap[uc][0] cat = catmap[uc][0]
suffix = 1 suffix = 1
while icu_lower((cat + unicode_type(suffix))) in catmap: while icu_lower(cat + str(suffix)) in catmap:
suffix += 1 suffix += 1
prints('Renaming user category %s to %s'%(cat, cat+unicode_type(suffix))) prints('Renaming user category %s to %s'%(cat, cat+str(suffix)))
user_cats[cat + unicode_type(suffix)] = user_cats[cat] user_cats[cat + str(suffix)] = user_cats[cat]
del user_cats[cat] del user_cats[cat]
cats_changed = True cats_changed = True
if cats_changed: if cats_changed:
@ -755,25 +754,25 @@ class DB:
if d['is_multiple']: if d['is_multiple']:
if x is None: if x is None:
return [] return []
if isinstance(x, (unicode_type, bytes)): if isinstance(x, (str, bytes)):
x = x.split(d['multiple_seps']['ui_to_list']) x = x.split(d['multiple_seps']['ui_to_list'])
x = [y.strip() for y in x if y.strip()] x = [y.strip() for y in x if y.strip()]
x = [y.decode(preferred_encoding, 'replace') if not isinstance(y, x = [y.decode(preferred_encoding, 'replace') if not isinstance(y,
unicode_type) else y for y in x] str) else y for y in x]
return [u' '.join(y.split()) for y in x] return [' '.join(y.split()) for y in x]
else: else:
return x if x is None or isinstance(x, unicode_type) else \ return x if x is None or isinstance(x, str) else \
x.decode(preferred_encoding, 'replace') x.decode(preferred_encoding, 'replace')
def adapt_datetime(x, d): def adapt_datetime(x, d):
if isinstance(x, (unicode_type, bytes)): if isinstance(x, (str, bytes)):
if isinstance(x, bytes): if isinstance(x, bytes):
x = x.decode(preferred_encoding, 'replace') x = x.decode(preferred_encoding, 'replace')
x = parse_date(x, assume_utc=False, as_utc=False) x = parse_date(x, assume_utc=False, as_utc=False)
return x return x
def adapt_bool(x, d): def adapt_bool(x, d):
if isinstance(x, (unicode_type, bytes)): if isinstance(x, (str, bytes)):
if isinstance(x, bytes): if isinstance(x, bytes):
x = x.decode(preferred_encoding, 'replace') x = x.decode(preferred_encoding, 'replace')
x = x.lower() x = x.lower()
@ -796,7 +795,7 @@ class DB:
def adapt_number(x, d): def adapt_number(x, d):
if x is None: if x is None:
return None return None
if isinstance(x, (unicode_type, bytes)): if isinstance(x, (str, bytes)):
if isinstance(x, bytes): if isinstance(x, bytes):
x = x.decode(preferred_encoding, 'replace') x = x.decode(preferred_encoding, 'replace')
if x.lower() == 'none': if x.lower() == 'none':
@ -825,7 +824,7 @@ class DB:
else: else:
is_category = False is_category = False
is_m = v['multiple_seps'] is_m = v['multiple_seps']
tn = 'custom_column_{0}'.format(v['num']) tn = 'custom_column_{}'.format(v['num'])
self.field_metadata.add_custom_field(label=v['label'], self.field_metadata.add_custom_field(label=v['label'],
table=tn, column='value', datatype=v['datatype'], table=tn, column='value', datatype=v['datatype'],
colnum=v['num'], name=v['name'], display=v['display'], colnum=v['num'], name=v['name'], display=v['display'],
@ -888,7 +887,7 @@ class DB:
# account for the series index column. Field_metadata knows that # account for the series index column. Field_metadata knows that
# the series index is one larger than the series. If you change # the series index is one larger than the series. If you change
# it here, be sure to change it there as well. # it here, be sure to change it there as well.
self.FIELD_MAP[unicode_type(data['num'])+'_index'] = base = base+1 self.FIELD_MAP[str(data['num'])+'_index'] = base = base+1
self.field_metadata.set_field_record_index(label_+'_index', base, self.field_metadata.set_field_record_index(label_+'_index', base,
prefer_custom=True) prefer_custom=True)
@ -1311,7 +1310,7 @@ class DB:
if getattr(self, '_library_id_', None) is None: if getattr(self, '_library_id_', None) is None:
ans = self.conn.get('SELECT uuid FROM library_id', all=False) ans = self.conn.get('SELECT uuid FROM library_id', all=False)
if ans is None: if ans is None:
ans = unicode_type(uuid.uuid4()) ans = str(uuid.uuid4())
self.library_id = ans self.library_id = ans
else: else:
self._library_id_ = ans self._library_id_ = ans
@ -1319,7 +1318,7 @@ class DB:
@library_id.setter @library_id.setter
def library_id(self, val): def library_id(self, val):
self._library_id_ = unicode_type(val) self._library_id_ = str(val)
self.execute(''' self.execute('''
DELETE FROM library_id; DELETE FROM library_id;
INSERT INTO library_id (uuid) VALUES (?); INSERT INTO library_id (uuid) VALUES (?);
@ -1429,7 +1428,7 @@ class DB:
path = os.path.abspath(os.path.join(self.library_path, path, 'cover.jpg')) path = os.path.abspath(os.path.join(self.library_path, path, 'cover.jpg'))
try: try:
return utcfromtimestamp(os.stat(path).st_mtime) return utcfromtimestamp(os.stat(path).st_mtime)
except EnvironmentError: except OSError:
pass # Cover doesn't exist pass # Cover doesn't exist
def copy_cover_to(self, path, dest, windows_atomic_move=None, use_hardlink=False, report_file_size=None): def copy_cover_to(self, path, dest, windows_atomic_move=None, use_hardlink=False, report_file_size=None):
@ -1445,11 +1444,11 @@ class DB:
if os.access(path, os.R_OK): if os.access(path, os.R_OK):
try: try:
f = lopen(path, 'rb') f = lopen(path, 'rb')
except (IOError, OSError): except OSError:
time.sleep(0.2) time.sleep(0.2)
try: try:
f = lopen(path, 'rb') f = lopen(path, 'rb')
except (IOError, OSError) as e: except OSError as e:
# Ensure the path that caused this error is reported # Ensure the path that caused this error is reported
raise Exception('Failed to open %r with error: %s' % (path, e)) raise Exception('Failed to open %r with error: %s' % (path, e))
@ -1479,13 +1478,13 @@ class DB:
path = os.path.abspath(os.path.join(self.library_path, path, 'cover.jpg')) path = os.path.abspath(os.path.join(self.library_path, path, 'cover.jpg'))
try: try:
stat = os.stat(path) stat = os.stat(path)
except EnvironmentError: except OSError:
return False, None, None return False, None, None
if abs(timestamp - stat.st_mtime) < 0.1: if abs(timestamp - stat.st_mtime) < 0.1:
return True, None, None return True, None, None
try: try:
f = lopen(path, 'rb') f = lopen(path, 'rb')
except (IOError, OSError): except OSError:
time.sleep(0.2) time.sleep(0.2)
f = lopen(path, 'rb') f = lopen(path, 'rb')
with f: with f:
@ -1520,7 +1519,7 @@ class DB:
if os.path.exists(path): if os.path.exists(path):
try: try:
os.remove(path) os.remove(path)
except (IOError, OSError): except OSError:
time.sleep(0.2) time.sleep(0.2)
os.remove(path) os.remove(path)
else: else:
@ -1530,7 +1529,7 @@ class DB:
else: else:
try: try:
save_cover_data_to(data, path) save_cover_data_to(data, path)
except (IOError, OSError): except OSError:
time.sleep(0.2) time.sleep(0.2)
save_cover_data_to(data, path) save_cover_data_to(data, path)
@ -1616,7 +1615,7 @@ class DB:
# wrong in the rest of this function, at least the file is # wrong in the rest of this function, at least the file is
# not deleted # not deleted
os.rename(old_path, dest) os.rename(old_path, dest)
except EnvironmentError as e: except OSError as e:
if getattr(e, 'errno', None) != errno.ENOENT: if getattr(e, 'errno', None) != errno.ENOENT:
# Failing to rename the old format will at worst leave a # Failing to rename the old format will at worst leave a
# harmless orphan, so log and ignore the error # harmless orphan, so log and ignore the error
@ -1728,11 +1727,11 @@ class DB:
try: try:
with lopen(path, 'wb') as f: with lopen(path, 'wb') as f:
f.write(raw) f.write(raw)
except EnvironmentError: except OSError:
exc_info = sys.exc_info() exc_info = sys.exc_info()
try: try:
os.makedirs(os.path.dirname(path)) os.makedirs(os.path.dirname(path))
except EnvironmentError as err: except OSError as err:
if err.errno == errno.EEXIST: if err.errno == errno.EEXIST:
# Parent directory already exists, re-raise original exception # Parent directory already exists, re-raise original exception
reraise(*exc_info) reraise(*exc_info)
@ -1811,8 +1810,7 @@ class DB:
return frozenset(r[0] for r in self.execute('SELECT book FROM books_plugin_data WHERE name=?', (name,))) return frozenset(r[0] for r in self.execute('SELECT book FROM books_plugin_data WHERE name=?', (name,)))
def annotations_for_book(self, book_id, fmt, user_type, user): def annotations_for_book(self, book_id, fmt, user_type, user):
for x in annotations_for_book(self.conn, book_id, fmt, user_type, user): yield from annotations_for_book(self.conn, book_id, fmt, user_type, user)
yield x
def search_annotations(self, def search_annotations(self,
fts_engine_query, use_stemming, highlight_start, highlight_end, snippet_size, annotation_type, fts_engine_query, use_stemming, highlight_start, highlight_end, snippet_size, annotation_type,
@ -2026,7 +2024,7 @@ class DB:
def map_data(x): def map_data(x):
if not isinstance(x, string_or_bytes): if not isinstance(x, string_or_bytes):
x = native_string_type(x) x = native_string_type(x)
x = x.encode('utf-8') if isinstance(x, unicode_type) else x x = x.encode('utf-8') if isinstance(x, str) else x
x = pickle_binary_string(x) x = pickle_binary_string(x)
return x return x
options = [(book_id, fmt.upper(), map_data(data)) for book_id, data in iteritems(options)] options = [(book_id, fmt.upper(), map_data(data)) for book_id, data in iteritems(options)]
@ -2067,7 +2065,7 @@ class DB:
copyfile_using_links(src, dest, dest_is_dir=False) copyfile_using_links(src, dest, dest_is_dir=False)
old_files.add(src) old_files.add(src)
x = path_map[x] x = path_map[x]
if not isinstance(x, unicode_type): if not isinstance(x, str):
x = x.decode(filesystem_encoding, 'replace') x = x.decode(filesystem_encoding, 'replace')
progress(x, i+1, total) progress(x, i+1, total)
@ -2081,18 +2079,18 @@ class DB:
for loc in old_dirs: for loc in old_dirs:
try: try:
rmtree_with_retry(loc) rmtree_with_retry(loc)
except EnvironmentError as e: except OSError as e:
if os.path.exists(loc): if os.path.exists(loc):
prints('Failed to delete:', loc, 'with error:', as_unicode(e)) prints('Failed to delete:', loc, 'with error:', as_unicode(e))
for loc in old_files: for loc in old_files:
try: try:
os.remove(loc) os.remove(loc)
except EnvironmentError as e: except OSError as e:
if e.errno != errno.ENOENT: if e.errno != errno.ENOENT:
prints('Failed to delete:', loc, 'with error:', as_unicode(e)) prints('Failed to delete:', loc, 'with error:', as_unicode(e))
try: try:
os.rmdir(odir) os.rmdir(odir)
except EnvironmentError: except OSError:
pass pass
self.conn # Connect to the moved metadata.db self.conn # Connect to the moved metadata.db
progress(_('Completed'), total, total) progress(_('Completed'), total, total)

View File

@ -47,9 +47,7 @@ from calibre.utils.config import prefs, tweaks
from calibre.utils.date import UNDEFINED_DATE, now as nowf, utcnow from calibre.utils.date import UNDEFINED_DATE, now as nowf, utcnow
from calibre.utils.icu import sort_key from calibre.utils.icu import sort_key
from calibre.utils.localization import canonicalize_lang from calibre.utils.localization import canonicalize_lang
from polyglot.builtins import ( from polyglot.builtins import cmp, iteritems, itervalues, string_or_bytes
cmp, iteritems, itervalues, string_or_bytes, unicode_type, zip
)
def api(f): def api(f):
@ -581,14 +579,14 @@ class Cache:
@read_api @read_api
def get_item_id(self, field, item_name): def get_item_id(self, field, item_name):
' Return the item id for item_name (case-insensitive) ' ' Return the item id for item_name (case-insensitive) '
rmap = {icu_lower(v) if isinstance(v, unicode_type) else v:k for k, v in iteritems(self.fields[field].table.id_map)} rmap = {icu_lower(v) if isinstance(v, str) else v:k for k, v in iteritems(self.fields[field].table.id_map)}
return rmap.get(icu_lower(item_name) if isinstance(item_name, unicode_type) else item_name, None) return rmap.get(icu_lower(item_name) if isinstance(item_name, str) else item_name, None)
@read_api @read_api
def get_item_ids(self, field, item_names): def get_item_ids(self, field, item_names):
' Return the item id for item_name (case-insensitive) ' ' Return the item id for item_name (case-insensitive) '
rmap = {icu_lower(v) if isinstance(v, unicode_type) else v:k for k, v in iteritems(self.fields[field].table.id_map)} rmap = {icu_lower(v) if isinstance(v, str) else v:k for k, v in iteritems(self.fields[field].table.id_map)}
return {name:rmap.get(icu_lower(name) if isinstance(name, unicode_type) else name, None) for name in item_names} return {name:rmap.get(icu_lower(name) if isinstance(name, str) else name, None) for name in item_names}
@read_api @read_api
def author_data(self, author_ids=None): def author_data(self, author_ids=None):
@ -1329,7 +1327,7 @@ class Cache:
try: try:
return self.backend.read_backup(path) return self.backend.read_backup(path)
except EnvironmentError: except OSError:
return None return None
@write_api @write_api

View File

@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
import copy import copy
from functools import partial from functools import partial
from polyglot.builtins import iteritems, unicode_type, map, native_string_type from polyglot.builtins import iteritems, native_string_type
from calibre.ebooks.metadata import author_to_author_sort from calibre.ebooks.metadata import author_to_author_sort
from calibre.utils.config_base import tweaks from calibre.utils.config_base import tweaks
@ -44,7 +44,7 @@ class Tag:
@property @property
def string_representation(self): def string_representation(self):
return u'%s:%s:%s:%s:%s'%(self.name, self.count, self.id, self.state, self.category) return '%s:%s:%s:%s:%s'%(self.name, self.count, self.id, self.state, self.category)
def __str__(self): def __str__(self):
return self.string_representation return self.string_representation
@ -101,8 +101,8 @@ def clean_user_categories(dbcache):
if len(comps) == 0: if len(comps) == 0:
i = 1 i = 1
while True: while True:
if unicode_type(i) not in user_cats: if str(i) not in user_cats:
new_cats[unicode_type(i)] = user_cats[k] new_cats[str(i)] = user_cats[k]
break break
i += 1 i += 1
else: else:

View File

@ -21,7 +21,6 @@ from calibre.ptempfile import TemporaryDirectory
from calibre.srv.changes import books_added, formats_added from calibre.srv.changes import books_added, formats_added
from calibre.utils.localization import canonicalize_lang from calibre.utils.localization import canonicalize_lang
from calibre.utils.short_uuid import uuid4 from calibre.utils.short_uuid import uuid4
from polyglot.builtins import unicode_type
readonly = False readonly = False
version = 0 # change this if you change signature of implementation() version = 0 # change this if you change signature of implementation()
@ -264,7 +263,7 @@ def do_add(
try: try:
with lopen(mi.cover, 'rb') as f: with lopen(mi.cover, 'rb') as f:
cover_data = f.read() cover_data = f.read()
except EnvironmentError: except OSError:
pass pass
book_title, ids, mids, dups = dbctx.run( book_title, ids, mids, dups = dbctx.run(
@ -296,9 +295,9 @@ def do_add(
prints(' ', path) prints(' ', path)
if added_ids: if added_ids:
prints(_('Added book ids: %s') % (', '.join(map(unicode_type, added_ids)))) prints(_('Added book ids: %s') % (', '.join(map(str, added_ids))))
if merged_ids: if merged_ids:
prints(_('Merged book ids: %s') % (', '.join(map(unicode_type, merged_ids)))) prints(_('Merged book ids: %s') % (', '.join(map(str, merged_ids))))
def option_parser(get_parser, args): def option_parser(get_parser, args):
@ -463,8 +462,8 @@ def main(opts, args, dbctx):
lcodes = [canonicalize_lang(x) for x in (opts.languages or '').split(',')] lcodes = [canonicalize_lang(x) for x in (opts.languages or '').split(',')]
lcodes = [x for x in lcodes if x] lcodes = [x for x in lcodes if x]
identifiers = (x.partition(':')[::2] for x in opts.identifier) identifiers = (x.partition(':')[::2] for x in opts.identifier)
identifiers = dict((k.strip(), v.strip()) for k, v in identifiers identifiers = {k.strip(): v.strip() for k, v in identifiers
if k.strip() and v.strip()) if k.strip() and v.strip()}
if opts.empty: if opts.empty:
do_add_empty( do_add_empty(
dbctx, opts.title, aut, opts.isbn, tags, opts.series, opts.series_index, dbctx, opts.title, aut, opts.isbn, tags, opts.series, opts.series_index,

View File

@ -54,7 +54,7 @@ class BackupProgress:
else: else:
self.count += 1 self.count += 1
prints( prints(
u'%.1f%% %s - %s' % ((self.count * 100) / float(self.total), book_id, '%.1f%% %s - %s' % ((self.count * 100) / float(self.total), book_id,
getattr(mi, 'title', 'Unknown')) getattr(mi, 'title', 'Unknown'))
) )

View File

@ -11,7 +11,7 @@ from textwrap import TextWrapper
from calibre.db.cli.utils import str_width from calibre.db.cli.utils import str_width
from calibre.ebooks.metadata import authors_to_string from calibre.ebooks.metadata import authors_to_string
from calibre.utils.date import isoformat from calibre.utils.date import isoformat
from polyglot.builtins import as_bytes, iteritems, map, unicode_type from polyglot.builtins import as_bytes, iteritems
readonly = True readonly = True
version = 0 # change this if you change signature of implementation() version = 0 # change this if you change signature of implementation()
@ -123,10 +123,10 @@ def prepare_output_table(fields, book_ids, data, metadata):
ans.append(row) ans.append(row)
for field in fields: for field in fields:
if field == 'id': if field == 'id':
row.append(unicode_type(book_id)) row.append(str(book_id))
continue continue
val = data.get(field.replace('*', '#'), {}).get(book_id) val = data.get(field.replace('*', '#'), {}).get(book_id)
row.append(unicode_type(val).replace('\n', ' ')) row.append(str(val).replace('\n', ' '))
return ans return ans
@ -308,7 +308,7 @@ List the books available in the calibre database.
def main(opts, args, dbctx): def main(opts, args, dbctx):
afields = set(FIELDS) | {'id'} afields = set(FIELDS) | {'id'}
if opts.fields.strip(): if opts.fields.strip():
fields = [unicode_type(f.strip().lower()) for f in opts.fields.split(',')] fields = [str(f.strip().lower()) for f in opts.fields.split(',')]
else: else:
fields = [] fields = []

View File

@ -8,7 +8,7 @@ import sys
from textwrap import TextWrapper from textwrap import TextWrapper
from calibre import prints from calibre import prints
from polyglot.builtins import as_bytes, map, unicode_type from polyglot.builtins import as_bytes
readonly = True readonly = True
version = 0 # change this if you change signature of implementation() version = 0 # change this if you change signature of implementation()
@ -78,7 +78,7 @@ def do_list(fields, data, opts):
widths = list(map(lambda x: 0, fields)) widths = list(map(lambda x: 0, fields))
for i in data: for i in data:
for j, field in enumerate(fields): for j, field in enumerate(fields):
widths[j] = max(widths[j], max(len(field), len(unicode_type(i[field])))) widths[j] = max(widths[j], max(len(field), len(str(i[field]))))
screen_width = geometry()[0] screen_width = geometry()[0]
if not screen_width: if not screen_width:
@ -109,7 +109,7 @@ def do_list(fields, data, opts):
for record in data: for record in data:
text = [ text = [
wrappers[i].wrap(unicode_type(record[field])) wrappers[i].wrap(str(record[field]))
for i, field in enumerate(fields) for i, field in enumerate(fields)
] ]
lines = max(map(len, text)) lines = max(map(len, text))
@ -167,11 +167,11 @@ def main(opts, args, dbctx):
is_rating = category_metadata(category)['datatype'] == 'rating' is_rating = category_metadata(category)['datatype'] == 'rating'
for tag in category_data[category]: for tag in category_data[category]:
if is_rating: if is_rating:
tag.name = unicode_type(len(tag.name)) tag.name = str(len(tag.name))
data.append({ data.append({
'category': category, 'category': category,
'tag_name': tag.name, 'tag_name': tag.name,
'count': unicode_type(tag.count), 'count': str(tag.count),
'rating': fmtr(tag.avg_rating), 'rating': fmtr(tag.avg_rating),
}) })
else: else:
@ -179,7 +179,7 @@ def main(opts, args, dbctx):
data.append({ data.append({
'category': category, 'category': category,
'tag_name': _('CATEGORY ITEMS'), 'tag_name': _('CATEGORY ITEMS'),
'count': unicode_type(len(category_data[category])), 'count': str(len(category_data[category])),
'rating': '' 'rating': ''
}) })

View File

@ -6,7 +6,6 @@
import sys import sys
from calibre import prints from calibre import prints
from calibre.db.legacy import LibraryDatabase from calibre.db.legacy import LibraryDatabase
from polyglot.builtins import raw_input
readonly = False readonly = False
version = 0 # change this if you change signature of implementation() version = 0 # change this if you change signature of implementation()
@ -39,7 +38,7 @@ columns with the custom_columns command.
def input_unicode(prompt): def input_unicode(prompt):
ans = raw_input(prompt) ans = input(prompt)
if isinstance(ans, bytes): if isinstance(ans, bytes):
ans = ans.decode(sys.stdin.encoding) ans = ans.decode(sys.stdin.encoding)
return ans return ans

View File

@ -10,7 +10,7 @@ from calibre.ebooks.metadata.book.base import field_from_string
from calibre.ebooks.metadata.book.serialize import read_cover from calibre.ebooks.metadata.book.serialize import read_cover
from calibre.ebooks.metadata.opf import get_metadata from calibre.ebooks.metadata.opf import get_metadata
from calibre.srv.changes import metadata from calibre.srv.changes import metadata
from polyglot.builtins import iteritems, unicode_type, getcwd from polyglot.builtins import iteritems
readonly = False readonly = False
version = 0 # change this if you change signature of implementation() version = 0 # change this if you change signature of implementation()
@ -147,7 +147,7 @@ def main(opts, args, dbctx):
with lopen(opf, 'rb') as stream: with lopen(opf, 'rb') as stream:
mi = get_metadata(stream)[0] mi = get_metadata(stream)[0]
if mi.cover: if mi.cover:
mi.cover = os.path.join(os.path.dirname(opf), os.path.relpath(mi.cover, getcwd())) mi.cover = os.path.join(os.path.dirname(opf), os.path.relpath(mi.cover, os.getcwd()))
final_mi = dbctx.run('set_metadata', 'opf', book_id, read_cover(mi)) final_mi = dbctx.run('set_metadata', 'opf', book_id, read_cover(mi))
if not final_mi: if not final_mi:
raise SystemExit(_('No book with id: %s in the database') % book_id) raise SystemExit(_('No book with id: %s in the database') % book_id)
@ -181,5 +181,5 @@ def main(opts, args, dbctx):
if not final_mi: if not final_mi:
raise SystemExit(_('No book with id: %s in the database') % book_id) raise SystemExit(_('No book with id: %s in the database') % book_id)
prints(unicode_type(final_mi)) prints(str(final_mi))
return 0 return 0

View File

@ -3,11 +3,11 @@
# License: GPLv3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
import os
import sys import sys
from calibre import prints from calibre import prints
from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.ebooks.metadata.opf2 import OPFCreator
from polyglot.builtins import unicode_type, getcwd
readonly = True readonly = True
version = 0 # change this if you change signature of implementation() version = 0 # change this if you change signature of implementation()
@ -49,9 +49,9 @@ def main(opts, args, dbctx):
raise SystemExit('Id #%d is not present in database.' % id) raise SystemExit('Id #%d is not present in database.' % id)
if opts.as_opf: if opts.as_opf:
stdout = getattr(sys.stdout, 'buffer', sys.stdout) stdout = getattr(sys.stdout, 'buffer', sys.stdout)
mi = OPFCreator(getcwd(), mi) mi = OPFCreator(os.getcwd(), mi)
mi.render(stdout) mi.render(stdout)
else: else:
prints(unicode_type(mi)) prints(str(mi))
return 0 return 0

View File

@ -3,8 +3,6 @@
# License: GPLv3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
from polyglot.builtins import map
import unicodedata import unicodedata
eaw = unicodedata.east_asian_width eaw = unicodedata.east_asian_width

View File

@ -88,7 +88,7 @@ class DeleteService(Thread):
basename = '%d - %s' % (c, os.path.basename(path)) basename = '%d - %s' % (c, os.path.basename(path))
try: try:
shutil.move(path, dest) shutil.move(path, dest)
except EnvironmentError: except OSError:
if os.path.isdir(path): if os.path.isdir(path):
# shutil.move may have partially copied the directory, # shutil.move may have partially copied the directory,
# so the subsequent call to move() will fail as the # so the subsequent call to move() will fail as the

View File

@ -18,7 +18,7 @@ from calibre.utils.config_base import tweaks
from calibre.utils.icu import sort_key from calibre.utils.icu import sort_key
from calibre.utils.date import UNDEFINED_DATE, clean_date_for_sort, parse_date from calibre.utils.date import UNDEFINED_DATE, clean_date_for_sort, parse_date
from calibre.utils.localization import calibre_langcode_to_name from calibre.utils.localization import calibre_langcode_to_name
from polyglot.builtins import iteritems, unicode_type from polyglot.builtins import iteritems
def bool_sort_key(bools_are_tristate): def bool_sort_key(bools_are_tristate):
@ -85,7 +85,7 @@ class Field:
self._sort_key = lambda x: sort_key(author_to_author_sort(x)) self._sort_key = lambda x: sort_key(author_to_author_sort(x))
self.sort_sort_key = False self.sort_sort_key = False
self.default_value = {} if name == 'identifiers' else () if self.is_multiple else None self.default_value = {} if name == 'identifiers' else () if self.is_multiple else None
self.category_formatter = unicode_type self.category_formatter = str
if dt == 'rating': if dt == 'rating':
if self.metadata['display'].get('allow_half_stars', False): if self.metadata['display'].get('allow_half_stars', False):
self.category_formatter = lambda x: rating_to_stars(x, True) self.category_formatter = lambda x: rating_to_stars(x, True)
@ -328,8 +328,7 @@ class CompositeField(OneToOneField):
for v in vals: for v in vals:
if v: if v:
val_map[v].add(book_id) val_map[v].add(book_id)
for val, book_ids in iteritems(val_map): yield from iteritems(val_map)
yield val, book_ids
def iter_counts(self, candidates, get_metadata=None): def iter_counts(self, candidates, get_metadata=None):
val_map = defaultdict(set) val_map = defaultdict(set)
@ -343,8 +342,7 @@ class CompositeField(OneToOneField):
else: else:
length = 0 length = 0
val_map[length].add(book_id) val_map[length].add(book_id)
for val, book_ids in iteritems(val_map): yield from iteritems(val_map)
yield val, book_ids
def get_composite_categories(self, tag_class, book_rating_map, book_ids, def get_composite_categories(self, tag_class, book_rating_map, book_ids,
is_multiple, get_metadata): is_multiple, get_metadata):
@ -437,8 +435,7 @@ class OnDeviceField(OneToOneField):
val_map = defaultdict(set) val_map = defaultdict(set)
for book_id in candidates: for book_id in candidates:
val_map[self.for_book(book_id, default_value=default_value)].add(book_id) val_map[self.for_book(book_id, default_value=default_value)].add(book_id)
for val, book_ids in iteritems(val_map): yield from iteritems(val_map)
yield val, book_ids
class LazySortMap: class LazySortMap:
@ -562,8 +559,7 @@ class ManyToManyField(Field):
cbm = self.table.book_col_map cbm = self.table.book_col_map
for book_id in candidates: for book_id in candidates:
val_map[len(cbm.get(book_id, ()))].add(book_id) val_map[len(cbm.get(book_id, ()))].add(book_id)
for count, book_ids in iteritems(val_map): yield from iteritems(val_map)
yield count, book_ids
@property @property
def book_value_map(self): def book_value_map(self):

View File

@ -14,7 +14,7 @@ from copy import deepcopy
from calibre.ebooks.metadata.book.base import Metadata, SIMPLE_GET, TOP_LEVEL_IDENTIFIERS, NULL_VALUES, ALL_METADATA_FIELDS from calibre.ebooks.metadata.book.base import Metadata, SIMPLE_GET, TOP_LEVEL_IDENTIFIERS, NULL_VALUES, ALL_METADATA_FIELDS
from calibre.ebooks.metadata.book.formatter import SafeFormat from calibre.ebooks.metadata.book.formatter import SafeFormat
from calibre.utils.date import utcnow from calibre.utils.date import utcnow
from polyglot.builtins import unicode_type, native_string_type from polyglot.builtins import native_string_type
# Lazy format metadata retrieval {{{ # Lazy format metadata retrieval {{{
''' '''
@ -46,7 +46,7 @@ class MutableBase:
@resolved @resolved
def __unicode__(self): def __unicode__(self):
return unicode_type(self._values) return str(self._values)
@resolved @resolved
def __len__(self): def __len__(self):

View File

@ -6,7 +6,7 @@ __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
import os, traceback, weakref import os, traceback, weakref
from polyglot.builtins import iteritems, zip from polyglot.builtins import iteritems
from collections.abc import MutableMapping from collections.abc import MutableMapping
from calibre import force_unicode, isbytestring from calibre import force_unicode, isbytestring
@ -29,7 +29,7 @@ def cleanup_tags(tags):
tags = [x.strip().replace(',', ';') for x in tags if x.strip()] tags = [x.strip().replace(',', ';') for x in tags if x.strip()]
tags = [x.decode(preferred_encoding, 'replace') tags = [x.decode(preferred_encoding, 'replace')
if isbytestring(x) else x for x in tags] if isbytestring(x) else x for x in tags]
tags = [u' '.join(x.split()) for x in tags] tags = [' '.join(x.split()) for x in tags]
ans, seen = [], set() ans, seen = [], set()
for tag in tags: for tag in tags:
if tag.lower() not in seen: if tag.lower() not in seen:
@ -684,8 +684,7 @@ class LibraryDatabase:
self.new_api.refresh_ondevice() self.new_api.refresh_ondevice()
def tags_older_than(self, tag, delta, must_have_tag=None, must_have_authors=None): def tags_older_than(self, tag, delta, must_have_tag=None, must_have_authors=None):
for book_id in sorted(self.new_api.tags_older_than(tag, delta=delta, must_have_tag=must_have_tag, must_have_authors=must_have_authors)): yield from sorted(self.new_api.tags_older_than(tag, delta=delta, must_have_tag=must_have_tag, must_have_authors=must_have_authors))
yield book_id
def sizeof_format(self, index, fmt, index_is_id=False): def sizeof_format(self, index, fmt, index_is_id=False):
book_id = index if index_is_id else self.id(index) book_id = index if index_is_id else self.id(index)
@ -848,8 +847,7 @@ class LibraryDatabase:
# Private interface {{{ # Private interface {{{
def __iter__(self): def __iter__(self):
for row in self.data.iterall(): yield from self.data.iterall()
yield row
def _get_next_series_num_for_list(self, series_indices): def _get_next_series_num_for_list(self, series_indices):
return _get_next_series_num_for_list(series_indices) return _get_next_series_num_for_list(series_indices)

View File

@ -17,7 +17,7 @@ from calibre.db.cache import Cache
from calibre.constants import filesystem_encoding from calibre.constants import filesystem_encoding
from calibre.utils.date import utcfromtimestamp from calibre.utils.date import utcfromtimestamp
from calibre import isbytestring, force_unicode from calibre import isbytestring, force_unicode
from polyglot.builtins import iteritems, filter from polyglot.builtins import iteritems
NON_EBOOK_EXTENSIONS = frozenset(( NON_EBOOK_EXTENSIONS = frozenset((
'jpg', 'jpeg', 'gif', 'png', 'bmp', 'jpg', 'jpeg', 'gif', 'png', 'bmp',
@ -42,7 +42,7 @@ class Restorer(Cache):
class Restore(Thread): class Restore(Thread):
def __init__(self, library_path, progress_callback=None): def __init__(self, library_path, progress_callback=None):
super(Restore, self).__init__() super().__init__()
if isbytestring(library_path): if isbytestring(library_path):
library_path = library_path.decode(filesystem_encoding) library_path = library_path.decode(filesystem_encoding)
self.src_library_path = os.path.abspath(library_path) self.src_library_path = os.path.abspath(library_path)
@ -107,7 +107,7 @@ class Restore(Thread):
try: try:
tdir = TemporaryDirectory('_rlib', dir=basedir) tdir = TemporaryDirectory('_rlib', dir=basedir)
tdir.__enter__() tdir.__enter__()
except EnvironmentError: except OSError:
# In case we dont have permissions to create directories in the # In case we dont have permissions to create directories in the
# parent folder of the src library # parent folder of the src library
tdir = TemporaryDirectory('_rlib') tdir = TemporaryDirectory('_rlib')
@ -279,7 +279,7 @@ class Restore(Thread):
if os.path.exists(dbpath): if os.path.exists(dbpath):
try: try:
os.rename(dbpath, save_path) os.rename(dbpath, save_path)
except EnvironmentError: except OSError:
time.sleep(30) # Wait a little for dropbox or the antivirus or whatever to release the file time.sleep(30) # Wait a little for dropbox or the antivirus or whatever to release the file
shutil.copyfile(dbpath, save_path) shutil.copyfile(dbpath, save_path)
os.remove(dbpath) os.remove(dbpath)

View File

@ -10,7 +10,7 @@ import os
from calibre import prints from calibre import prints
from calibre.utils.date import isoformat, DEFAULT_DATE from calibre.utils.date import isoformat, DEFAULT_DATE
from polyglot.builtins import itervalues, unicode_type from polyglot.builtins import itervalues
class SchemaUpgrade: class SchemaUpgrade:
@ -598,10 +598,10 @@ class SchemaUpgrade:
existing = frozenset(map(int, custom_recipes)) existing = frozenset(map(int, custom_recipes))
if id_ in existing: if id_ in existing:
id_ = max(existing) + 1000 id_ = max(existing) + 1000
id_ = unicode_type(id_) id_ = str(id_)
fname = custom_recipe_filename(id_, title) fname = custom_recipe_filename(id_, title)
custom_recipes[id_] = (title, fname) custom_recipes[id_] = (title, fname)
if isinstance(script, unicode_type): if isinstance(script, str):
script = script.encode('utf-8') script = script.encode('utf-8')
with open(os.path.join(bdir, fname), 'wb') as f: with open(os.path.join(bdir, fname), 'wb') as f:
f.write(script) f.write(script)

View File

@ -18,7 +18,7 @@ from calibre.utils.date import parse_date, UNDEFINED_DATE, now, dt_as_local
from calibre.utils.icu import primary_contains, sort_key from calibre.utils.icu import primary_contains, sort_key
from calibre.utils.localization import lang_map, canonicalize_lang from calibre.utils.localization import lang_map, canonicalize_lang
from calibre.utils.search_query_parser import SearchQueryParser, ParseException from calibre.utils.search_query_parser import SearchQueryParser, ParseException
from polyglot.builtins import iteritems, unicode_type, string_or_bytes from polyglot.builtins import iteritems, string_or_bytes
CONTAINS_MATCH = 0 CONTAINS_MATCH = 0
EQUALS_MATCH = 1 EQUALS_MATCH = 1
@ -149,7 +149,7 @@ class DateSearch: # {{{
if query == 'false': if query == 'false':
for v, book_ids in field_iter(): for v, book_ids in field_iter():
if isinstance(v, (bytes, unicode_type)): if isinstance(v, (bytes, str)):
if isinstance(v, bytes): if isinstance(v, bytes):
v = v.decode(preferred_encoding, 'replace') v = v.decode(preferred_encoding, 'replace')
v = parse_date(v) v = parse_date(v)
@ -159,7 +159,7 @@ class DateSearch: # {{{
if query == 'true': if query == 'true':
for v, book_ids in field_iter(): for v, book_ids in field_iter():
if isinstance(v, (bytes, unicode_type)): if isinstance(v, (bytes, str)):
if isinstance(v, bytes): if isinstance(v, bytes):
v = v.decode(preferred_encoding, 'replace') v = v.decode(preferred_encoding, 'replace')
v = parse_date(v) v = parse_date(v)
@ -413,7 +413,7 @@ class SavedSearchQueries: # {{{
return self._db() return self._db()
def force_unicode(self, x): def force_unicode(self, x):
if not isinstance(x, unicode_type): if not isinstance(x, str):
x = x.decode(preferred_encoding, 'replace') x = x.decode(preferred_encoding, 'replace')
return x return x

View File

@ -12,7 +12,7 @@ from collections import defaultdict
from calibre.utils.date import parse_date, UNDEFINED_DATE, utc_tz from calibre.utils.date import parse_date, UNDEFINED_DATE, utc_tz
from calibre.ebooks.metadata import author_to_author_sort from calibre.ebooks.metadata import author_to_author_sort
from polyglot.builtins import iteritems, itervalues, range from polyglot.builtins import iteritems, itervalues
from calibre_extensions.speedup import parse_date as _c_speedup from calibre_extensions.speedup import parse_date as _c_speedup
@ -103,7 +103,7 @@ class OneToOneTable(Table):
def read(self, db): def read(self, db):
idcol = 'id' if self.metadata['table'] == 'books' else 'book' idcol = 'id' if self.metadata['table'] == 'books' else 'book'
query = db.execute('SELECT {0}, {1} FROM {2}'.format(idcol, query = db.execute('SELECT {}, {} FROM {}'.format(idcol,
self.metadata['column'], self.metadata['table'])) self.metadata['column'], self.metadata['table']))
if self.unserialize is None: if self.unserialize is None:
try: try:
@ -111,7 +111,7 @@ class OneToOneTable(Table):
except UnicodeDecodeError: except UnicodeDecodeError:
# The db is damaged, try to work around it by ignoring # The db is damaged, try to work around it by ignoring
# failures to decode utf-8 # failures to decode utf-8
query = db.execute('SELECT {0}, cast({1} as blob) FROM {2}'.format(idcol, query = db.execute('SELECT {}, cast({} as blob) FROM {}'.format(idcol,
self.metadata['column'], self.metadata['table'])) self.metadata['column'], self.metadata['table']))
self.book_col_map = {k:bytes(val).decode('utf-8', 'replace') for k, val in query} self.book_col_map = {k:bytes(val).decode('utf-8', 'replace') for k, val in query}
else: else:
@ -205,7 +205,7 @@ class ManyToOneTable(Table):
self.read_maps(db) self.read_maps(db)
def read_id_maps(self, db): def read_id_maps(self, db):
query = db.execute('SELECT id, {0} FROM {1}'.format( query = db.execute('SELECT id, {} FROM {}'.format(
self.metadata['column'], self.metadata['table'])) self.metadata['column'], self.metadata['table']))
if self.unserialize is None: if self.unserialize is None:
self.id_map = dict(query) self.id_map = dict(query)
@ -217,7 +217,7 @@ class ManyToOneTable(Table):
cbm = self.col_book_map cbm = self.col_book_map
bcm = self.book_col_map bcm = self.book_col_map
for book, item_id in db.execute( for book, item_id in db.execute(
'SELECT book, {0} FROM {1}'.format( 'SELECT book, {} FROM {}'.format(
self.metadata['link_column'], self.link_table)): self.metadata['link_column'], self.link_table)):
cbm[item_id].add(book) cbm[item_id].add(book)
bcm[book] = item_id bcm[book] = item_id
@ -230,7 +230,7 @@ class ManyToOneTable(Table):
book_ids = self.col_book_map.pop(item_id, ()) book_ids = self.col_book_map.pop(item_id, ())
for book_id in book_ids: for book_id in book_ids:
self.book_col_map.pop(book_id, None) self.book_col_map.pop(book_id, None)
db.executemany('DELETE FROM {0} WHERE {1}=?'.format( db.executemany('DELETE FROM {} WHERE {}=?'.format(
self.link_table, self.metadata['link_column']), tuple((x,) for x in extra_item_ids)) self.link_table, self.metadata['link_column']), tuple((x,) for x in extra_item_ids))
def fix_case_duplicates(self, db): def fix_case_duplicates(self, db):
@ -250,7 +250,7 @@ class ManyToOneTable(Table):
db.executemany('UPDATE {0} SET {1}=? WHERE {1}=?'.format( db.executemany('UPDATE {0} SET {1}=? WHERE {1}=?'.format(
self.link_table, self.metadata['link_column']), self.link_table, self.metadata['link_column']),
tuple((main_id, x) for x in v)) tuple((main_id, x) for x in v))
db.executemany('DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), db.executemany('DELETE FROM {} WHERE id=?'.format(self.metadata['table']),
tuple((x,) for x in v)) tuple((x,) for x in v))
def remove_books(self, book_ids, db): def remove_books(self, book_ids, db):
@ -270,7 +270,7 @@ class ManyToOneTable(Table):
clean.add(item_id) clean.add(item_id)
if clean: if clean:
db.executemany( db.executemany(
'DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), 'DELETE FROM {} WHERE id=?'.format(self.metadata['table']),
[(x,) for x in clean]) [(x,) for x in clean])
return clean return clean
@ -296,7 +296,7 @@ class ManyToOneTable(Table):
# this is a many-to-one mapping we know that we can delete # this is a many-to-one mapping we know that we can delete
# links without checking the item ID # links without checking the item ID
db.executemany( db.executemany(
'DELETE FROM {0} WHERE book=?'.format(self.link_table), tuple((x,) for x in books_to_delete)) 'DELETE FROM {} WHERE book=?'.format(self.link_table), tuple((x,) for x in books_to_delete))
affected_books |= books_to_delete affected_books |= books_to_delete
else: else:
# Process normally any items where the VL was not significant # Process normally any items where the VL was not significant
@ -314,8 +314,8 @@ class ManyToOneTable(Table):
self.book_col_map.pop(book_id, None) self.book_col_map.pop(book_id, None)
affected_books.update(book_ids) affected_books.update(book_ids)
item_ids = tuple((x,) for x in item_ids) item_ids = tuple((x,) for x in item_ids)
db.executemany('DELETE FROM {0} WHERE {1}=?'.format(self.link_table, self.metadata['link_column']), item_ids) db.executemany('DELETE FROM {} WHERE {}=?'.format(self.link_table, self.metadata['link_column']), item_ids)
db.executemany('DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), item_ids) db.executemany('DELETE FROM {} WHERE id=?'.format(self.metadata['table']), item_ids)
return affected_books return affected_books
def rename_item(self, item_id, new_name, db): def rename_item(self, item_id, new_name, db):
@ -327,7 +327,7 @@ class ManyToOneTable(Table):
if existing_item is None or existing_item == item_id: if existing_item is None or existing_item == item_id:
# A simple rename will do the trick # A simple rename will do the trick
self.id_map[item_id] = new_name self.id_map[item_id] = new_name
db.execute('UPDATE {0} SET {1}=? WHERE id=?'.format(table, col), (new_name, item_id)) db.execute('UPDATE {} SET {}=? WHERE id=?'.format(table, col), (new_name, item_id))
else: else:
# We have to replace # We have to replace
new_id = existing_item new_id = existing_item
@ -353,9 +353,9 @@ class RatingTable(ManyToOneTable):
bad_ids = {item_id for item_id, rating in iteritems(self.id_map) if rating == 0} bad_ids = {item_id for item_id, rating in iteritems(self.id_map) if rating == 0}
if bad_ids: if bad_ids:
self.id_map = {item_id:rating for item_id, rating in iteritems(self.id_map) if rating != 0} self.id_map = {item_id:rating for item_id, rating in iteritems(self.id_map) if rating != 0}
db.executemany('DELETE FROM {0} WHERE {1}=?'.format(self.link_table, self.metadata['link_column']), db.executemany('DELETE FROM {} WHERE {}=?'.format(self.link_table, self.metadata['link_column']),
tuple((x,) for x in bad_ids)) tuple((x,) for x in bad_ids))
db.execute('DELETE FROM {0} WHERE {1}=0'.format( db.execute('DELETE FROM {} WHERE {}=0'.format(
self.metadata['table'], self.metadata['column'])) self.metadata['table'], self.metadata['column']))
@ -389,7 +389,7 @@ class ManyToManyTable(ManyToOneTable):
book_ids = self.col_book_map.pop(item_id, ()) book_ids = self.col_book_map.pop(item_id, ())
for book_id in book_ids: for book_id in book_ids:
self.book_col_map[book_id] = tuple(iid for iid in self.book_col_map.pop(book_id, ()) if iid not in extra_item_ids) self.book_col_map[book_id] = tuple(iid for iid in self.book_col_map.pop(book_id, ()) if iid not in extra_item_ids)
db.executemany('DELETE FROM {0} WHERE {1}=?'.format( db.executemany('DELETE FROM {} WHERE {}=?'.format(
self.link_table, self.metadata['link_column']), tuple((x,) for x in extra_item_ids)) self.link_table, self.metadata['link_column']), tuple((x,) for x in extra_item_ids))
def remove_books(self, book_ids, db): def remove_books(self, book_ids, db):
@ -409,7 +409,7 @@ class ManyToManyTable(ManyToOneTable):
clean.add(item_id) clean.add(item_id)
if clean and self.do_clean_on_remove: if clean and self.do_clean_on_remove:
db.executemany( db.executemany(
'DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), 'DELETE FROM {} WHERE id=?'.format(self.metadata['table']),
[(x,) for x in clean]) [(x,) for x in clean])
return clean return clean
@ -436,7 +436,7 @@ class ManyToManyTable(ManyToOneTable):
# Delete book/item pairs from the link table. We don't need to do # Delete book/item pairs from the link table. We don't need to do
# anything with the main table because books with the old ID are # anything with the main table because books with the old ID are
# still in the library. # still in the library.
db.executemany('DELETE FROM {0} WHERE {1}=? and {2}=?'.format( db.executemany('DELETE FROM {} WHERE {}=? and {}=?'.format(
self.link_table, 'book', self.metadata['link_column']), self.link_table, 'book', self.metadata['link_column']),
[(b, i) for b in affected_books for i in item_ids]) [(b, i) for b in affected_books for i in item_ids])
# Take care of any items where the VL was not significant # Take care of any items where the VL was not significant
@ -453,8 +453,8 @@ class ManyToManyTable(ManyToOneTable):
self.book_col_map[book_id] = tuple(x for x in self.book_col_map.get(book_id, ()) if x != item_id) self.book_col_map[book_id] = tuple(x for x in self.book_col_map.get(book_id, ()) if x != item_id)
affected_books.update(book_ids) affected_books.update(book_ids)
item_ids = tuple((x,) for x in item_ids) item_ids = tuple((x,) for x in item_ids)
db.executemany('DELETE FROM {0} WHERE {1}=?'.format(self.link_table, self.metadata['link_column']), item_ids) db.executemany('DELETE FROM {} WHERE {}=?'.format(self.link_table, self.metadata['link_column']), item_ids)
db.executemany('DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), item_ids) db.executemany('DELETE FROM {} WHERE id=?'.format(self.metadata['table']), item_ids)
return affected_books return affected_books
def rename_item(self, item_id, new_name, db): def rename_item(self, item_id, new_name, db):
@ -466,7 +466,7 @@ class ManyToManyTable(ManyToOneTable):
if existing_item is None or existing_item == item_id: if existing_item is None or existing_item == item_id:
# A simple rename will do the trick # A simple rename will do the trick
self.id_map[item_id] = new_name self.id_map[item_id] = new_name
db.execute('UPDATE {0} SET {1}=? WHERE id=?'.format(table, col), (new_name, item_id)) db.execute('UPDATE {} SET {}=? WHERE id=?'.format(table, col), (new_name, item_id))
else: else:
# We have to replace # We have to replace
new_id = existing_item new_id = existing_item
@ -478,7 +478,7 @@ class ManyToManyTable(ManyToOneTable):
for book_id in books: for book_id in books:
self.book_col_map[book_id] = tuple((existing_item if x == item_id else x) for x in self.book_col_map.get(book_id, ()) if x != existing_item) self.book_col_map[book_id] = tuple((existing_item if x == item_id else x) for x in self.book_col_map.get(book_id, ()) if x != existing_item)
self.col_book_map[existing_item].update(books) self.col_book_map[existing_item].update(books)
db.executemany('DELETE FROM {0} WHERE book=? AND {1}=?'.format(self.link_table, lcol), [ db.executemany('DELETE FROM {} WHERE book=? AND {}=?'.format(self.link_table, lcol), [
(book_id, existing_item) for book_id in books]) (book_id, existing_item) for book_id in books])
db.execute('UPDATE {0} SET {1}=? WHERE {1}=?; DELETE FROM {2} WHERE id=?'.format( db.execute('UPDATE {0} SET {1}=? WHERE {1}=?; DELETE FROM {2} WHERE id=?'.format(
self.link_table, lcol, table), (existing_item, item_id, item_id)) self.link_table, lcol, table), (existing_item, item_id, item_id))
@ -515,11 +515,11 @@ class ManyToManyTable(ManyToOneTable):
tuple((main_id, x, book_id) for x in v)) tuple((main_id, x, book_id) for x in v))
else: else:
# duplicates # duplicates
db.execute('DELETE FROM {0} WHERE book=?'.format(self.link_table), (book_id,)) db.execute('DELETE FROM {} WHERE book=?'.format(self.link_table), (book_id,))
db.executemany( db.executemany(
'INSERT INTO {0} (book,{1}) VALUES (?,?)'.format(self.link_table, self.metadata['link_column']), 'INSERT INTO {} (book,{}) VALUES (?,?)'.format(self.link_table, self.metadata['link_column']),
tuple((book_id, x) for x in vals)) tuple((book_id, x) for x in vals))
db.executemany('DELETE FROM {0} WHERE id=?'.format(self.metadata['table']), db.executemany('DELETE FROM {} WHERE id=?'.format(self.metadata['table']),
tuple((x,) for x in v)) tuple((x,) for x in v))

View File

@ -9,7 +9,6 @@ __docformat__ = 'restructuredtext en'
import unittest, os, shutil, tempfile, atexit, gc, time import unittest, os, shutil, tempfile, atexit, gc, time
from functools import partial from functools import partial
from io import BytesIO from io import BytesIO
from polyglot.builtins import map, unicode_type
rmtree = partial(shutil.rmtree, ignore_errors=True) rmtree = partial(shutil.rmtree, ignore_errors=True)
@ -33,7 +32,7 @@ class BaseTest(unittest.TestCase):
gc.collect(), gc.collect() gc.collect(), gc.collect()
try: try:
shutil.rmtree(self.library_path) shutil.rmtree(self.library_path)
except EnvironmentError: except OSError:
# Try again in case something transient has a file lock on windows # Try again in case something transient has a file lock on windows
gc.collect(), gc.collect() gc.collect(), gc.collect()
time.sleep(2) time.sleep(2)
@ -82,7 +81,7 @@ class BaseTest(unittest.TestCase):
atexit.register(rmtree, self.clone_dir) atexit.register(rmtree, self.clone_dir)
self.clone_count = 0 self.clone_count = 0
self.clone_count += 1 self.clone_count += 1
dest = os.path.join(self.clone_dir, unicode_type(self.clone_count)) dest = os.path.join(self.clone_dir, str(self.clone_count))
shutil.copytree(library_path, dest) shutil.copytree(library_path, dest)
return dest return dest

View File

@ -12,7 +12,7 @@ from operator import itemgetter
from calibre.library.field_metadata import fm_as_dict from calibre.library.field_metadata import fm_as_dict
from calibre.db.tests.base import BaseTest from calibre.db.tests.base import BaseTest
from polyglot.builtins import iteritems, range, unicode_type, zip from polyglot.builtins import iteritems
from polyglot import reprlib from polyglot import reprlib
# Utils {{{ # Utils {{{
@ -62,7 +62,7 @@ def run_funcs(self, db, ndb, funcs):
if meth[0] in {'!', '@', '#', '+', '$', '-', '%'}: if meth[0] in {'!', '@', '#', '+', '$', '-', '%'}:
if meth[0] != '+': if meth[0] != '+':
fmt = {'!':dict, '@':lambda x:frozenset(x or ()), '#':lambda x:set((x or '').split(',')), fmt = {'!':dict, '@':lambda x:frozenset(x or ()), '#':lambda x:set((x or '').split(',')),
'$':lambda x:set(tuple(y) for y in x), '-':lambda x:None, '$':lambda x:{tuple(y) for y in x}, '-':lambda x:None,
'%':lambda x: set((x or '').split(','))}[meth[0]] '%':lambda x: set((x or '').split(','))}[meth[0]]
else: else:
fmt = args[-1] fmt = args[-1]
@ -116,7 +116,7 @@ class LegacyTest(BaseTest):
for label, loc in iteritems(db.FIELD_MAP): for label, loc in iteritems(db.FIELD_MAP):
if isinstance(label, numbers.Integral): if isinstance(label, numbers.Integral):
label = '#'+db.custom_column_num_map[label]['label'] label = '#'+db.custom_column_num_map[label]['label']
label = unicode_type(label) label = str(label)
ans[label] = tuple(db.get_property(i, index_is_id=True, loc=loc) ans[label] = tuple(db.get_property(i, index_is_id=True, loc=loc)
for i in db.all_ids()) for i in db.all_ids())
if label in ('id', 'title', '#tags'): if label in ('id', 'title', '#tags'):
@ -282,7 +282,7 @@ class LegacyTest(BaseTest):
old = db.get_data_as_dict(prefix='test-prefix') old = db.get_data_as_dict(prefix='test-prefix')
new = ndb.get_data_as_dict(prefix='test-prefix') new = ndb.get_data_as_dict(prefix='test-prefix')
for o, n in zip(old, new): for o, n in zip(old, new):
o = {unicode_type(k) if isinstance(k, bytes) else k:set(v) if isinstance(v, list) else v for k, v in iteritems(o)} o = {str(k) if isinstance(k, bytes) else k:set(v) if isinstance(v, list) else v for k, v in iteritems(o)}
n = {k:set(v) if isinstance(v, list) else v for k, v in iteritems(n)} n = {k:set(v) if isinstance(v, list) else v for k, v in iteritems(n)}
self.assertEqual(o, n) self.assertEqual(o, n)
@ -516,7 +516,7 @@ class LegacyTest(BaseTest):
T = partial(ET, 'get_all_custom_book_data', old=old, legacy=legacy) T = partial(ET, 'get_all_custom_book_data', old=old, legacy=legacy)
T((name, object())) T((name, object()))
T = partial(ET, 'delete_all_custom_book_data', old=old, legacy=legacy) T = partial(ET, 'delete_all_custom_book_data', old=old, legacy=legacy)
T((name)) T(name)
T = partial(ET, 'get_all_custom_book_data', old=old, legacy=legacy) T = partial(ET, 'get_all_custom_book_data', old=old, legacy=legacy)
T((name, object())) T((name, object()))

View File

@ -9,7 +9,6 @@ import time, random
from threading import Thread from threading import Thread
from calibre.db.tests.base import BaseTest from calibre.db.tests.base import BaseTest
from calibre.db.locking import SHLock, RWLockWrapper, LockingError from calibre.db.locking import SHLock, RWLockWrapper, LockingError
from polyglot.builtins import range
def wait_for(period): def wait_for(period):

View File

@ -13,7 +13,7 @@ from time import time
from calibre.utils.date import utc_tz from calibre.utils.date import utc_tz
from calibre.utils.localization import calibre_langcode_to_name from calibre.utils.localization import calibre_langcode_to_name
from calibre.db.tests.base import BaseTest from calibre.db.tests.base import BaseTest
from polyglot.builtins import iteritems, itervalues, range from polyglot.builtins import iteritems, itervalues
def p(x): def p(x):

View File

@ -15,7 +15,7 @@ from calibre.ebooks.metadata.book.base import Metadata
from calibre.utils.date import UNDEFINED_DATE from calibre.utils.date import UNDEFINED_DATE
from calibre.db.tests.base import BaseTest, IMG from calibre.db.tests.base import BaseTest, IMG
from calibre.db.backend import FTSQueryError from calibre.db.backend import FTSQueryError
from polyglot.builtins import iteritems, itervalues, unicode_type from polyglot.builtins import iteritems, itervalues
class WritingTest(BaseTest): class WritingTest(BaseTest):
@ -664,11 +664,11 @@ class WritingTest(BaseTest):
def test_set_author_data(self): # {{{ def test_set_author_data(self): # {{{
cache = self.init_cache() cache = self.init_cache()
adata = cache.author_data() adata = cache.author_data()
ldata = {aid:unicode_type(aid) for aid in adata} ldata = {aid:str(aid) for aid in adata}
self.assertEqual({1,2,3}, cache.set_link_for_authors(ldata)) self.assertEqual({1,2,3}, cache.set_link_for_authors(ldata))
for c in (cache, self.init_cache()): for c in (cache, self.init_cache()):
self.assertEqual(ldata, {aid:d['link'] for aid, d in iteritems(c.author_data())}) self.assertEqual(ldata, {aid:d['link'] for aid, d in iteritems(c.author_data())})
self.assertEqual({3}, cache.set_link_for_authors({aid:'xxx' if aid == max(adata) else unicode_type(aid) for aid in adata}), self.assertEqual({3}, cache.set_link_for_authors({aid:'xxx' if aid == max(adata) else str(aid) for aid in adata}),
'Setting the author link to the same value as before, incorrectly marked some books as dirty') 'Setting the author link to the same value as before, incorrectly marked some books as dirty')
sdata = {aid:'%s, changed' % aid for aid in adata} sdata = {aid:'%s, changed' % aid for aid in adata}
self.assertEqual({1,2,3}, cache.set_sort_for_authors(sdata)) self.assertEqual({1,2,3}, cache.set_sort_for_authors(sdata))

View File

@ -8,7 +8,7 @@ __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
import os, errno, sys, re import os, errno, sys, re
from locale import localeconv from locale import localeconv
from collections import OrderedDict, namedtuple from collections import OrderedDict, namedtuple
from polyglot.builtins import iteritems, itervalues, map, unicode_type, string_or_bytes, filter from polyglot.builtins import iteritems, itervalues, string_or_bytes
from threading import Lock from threading import Lock
from calibre import as_unicode, prints from calibre import as_unicode, prints
@ -18,7 +18,7 @@ from calibre.utils.localization import canonicalize_lang
def force_to_bool(val): def force_to_bool(val):
if isinstance(val, (bytes, unicode_type)): if isinstance(val, (bytes, str)):
if isinstance(val, bytes): if isinstance(val, bytes):
val = val.decode(preferred_encoding, 'replace') val = val.decode(preferred_encoding, 'replace')
try: try:
@ -136,7 +136,7 @@ class ThumbnailCache:
def _do_delete(self, path): def _do_delete(self, path):
try: try:
os.remove(path) os.remove(path)
except EnvironmentError as err: except OSError as err:
self.log('Failed to delete cached thumbnail file:', as_unicode(err)) self.log('Failed to delete cached thumbnail file:', as_unicode(err))
def _load_index(self): def _load_index(self):
@ -153,7 +153,7 @@ class ThumbnailCache:
def listdir(*args): def listdir(*args):
try: try:
return os.listdir(os.path.join(*args)) return os.listdir(os.path.join(*args))
except EnvironmentError: except OSError:
return () # not a directory or no permission or whatever return () # not a directory or no permission or whatever
entries = ('/'.join((parent, subdir, entry)) entries = ('/'.join((parent, subdir, entry))
for parent in listdir(self.location) for parent in listdir(self.location)
@ -164,13 +164,13 @@ class ThumbnailCache:
try: try:
with open(os.path.join(self.location, 'invalidate'), 'rb') as f: with open(os.path.join(self.location, 'invalidate'), 'rb') as f:
raw = f.read().decode('utf-8') raw = f.read().decode('utf-8')
except EnvironmentError as err: except OSError as err:
if getattr(err, 'errno', None) != errno.ENOENT: if getattr(err, 'errno', None) != errno.ENOENT:
self.log('Failed to read thumbnail invalidate data:', as_unicode(err)) self.log('Failed to read thumbnail invalidate data:', as_unicode(err))
else: else:
try: try:
os.remove(os.path.join(self.location, 'invalidate')) os.remove(os.path.join(self.location, 'invalidate'))
except EnvironmentError as err: except OSError as err:
self.log('Failed to remove thumbnail invalidate data:', as_unicode(err)) self.log('Failed to remove thumbnail invalidate data:', as_unicode(err))
else: else:
def record(line): def record(line):
@ -198,7 +198,7 @@ class ThumbnailCache:
self.total_size += size self.total_size += size
else: else:
self._do_delete(path) self._do_delete(path)
except EnvironmentError as err: except OSError as err:
self.log('Failed to read thumbnail cache dir:', as_unicode(err)) self.log('Failed to read thumbnail cache dir:', as_unicode(err))
self.items = OrderedDict(sorted(items, key=lambda x:order.get(x[0], 0))) self.items = OrderedDict(sorted(items, key=lambda x:order.get(x[0], 0)))
@ -227,10 +227,10 @@ class ThumbnailCache:
def _write_order(self): def _write_order(self):
if hasattr(self, 'items'): if hasattr(self, 'items'):
try: try:
data = '\n'.join(group_id + ' ' + unicode_type(book_id) for (group_id, book_id) in self.items) data = '\n'.join(group_id + ' ' + str(book_id) for (group_id, book_id) in self.items)
with lopen(os.path.join(self.location, 'order'), 'wb') as f: with lopen(os.path.join(self.location, 'order'), 'wb') as f:
f.write(data.encode('utf-8')) f.write(data.encode('utf-8'))
except EnvironmentError as err: except OSError as err:
self.log('Failed to save thumbnail cache order:', as_unicode(err)) self.log('Failed to save thumbnail cache order:', as_unicode(err))
def _read_order(self): def _read_order(self):
@ -281,14 +281,14 @@ class ThumbnailCache:
try: try:
with open(path, 'wb') as f: with open(path, 'wb') as f:
f.write(data) f.write(data)
except EnvironmentError as err: except OSError as err:
d = os.path.dirname(path) d = os.path.dirname(path)
if not os.path.exists(d): if not os.path.exists(d):
try: try:
os.makedirs(d) os.makedirs(d)
with open(path, 'wb') as f: with open(path, 'wb') as f:
f.write(data) f.write(data)
except EnvironmentError as err: except OSError as err:
self.log('Failed to write cached thumbnail:', path, as_unicode(err)) self.log('Failed to write cached thumbnail:', path, as_unicode(err))
return self._apply_size() return self._apply_size()
else: else:
@ -326,7 +326,7 @@ class ThumbnailCache:
if entry.thumbnail_size != self.thumbnail_size: if entry.thumbnail_size != self.thumbnail_size:
try: try:
os.remove(entry.path) os.remove(entry.path)
except EnvironmentError as err: except OSError as err:
if getattr(err, 'errno', None) != errno.ENOENT: if getattr(err, 'errno', None) != errno.ENOENT:
self.log('Failed to remove cached thumbnail:', entry.path, as_unicode(err)) self.log('Failed to remove cached thumbnail:', entry.path, as_unicode(err))
self.total_size -= entry.size self.total_size -= entry.size
@ -335,7 +335,7 @@ class ThumbnailCache:
try: try:
with open(entry.path, 'rb') as f: with open(entry.path, 'rb') as f:
data = f.read() data = f.read()
except EnvironmentError as err: except OSError as err:
self.log('Failed to read cached thumbnail:', entry.path, as_unicode(err)) self.log('Failed to read cached thumbnail:', entry.path, as_unicode(err))
return None, None return None, None
return data, entry.timestamp return data, entry.timestamp
@ -350,7 +350,7 @@ class ThumbnailCache:
raw = '\n'.join('%s %d' % (self.group_id, book_id) for book_id in book_ids) raw = '\n'.join('%s %d' % (self.group_id, book_id) for book_id in book_ids)
with open(os.path.join(self.location, 'invalidate'), 'ab') as f: with open(os.path.join(self.location, 'invalidate'), 'ab') as f:
f.write(raw.encode('ascii')) f.write(raw.encode('ascii'))
except EnvironmentError as err: except OSError as err:
self.log('Failed to write invalidate thumbnail record:', as_unicode(err)) self.log('Failed to write invalidate thumbnail record:', as_unicode(err))
@property @property
@ -364,7 +364,7 @@ class ThumbnailCache:
with self.lock: with self.lock:
try: try:
os.remove(os.path.join(self.location, 'order')) os.remove(os.path.join(self.location, 'order'))
except EnvironmentError: except OSError:
pass pass
if not hasattr(self, 'total_size'): if not hasattr(self, 'total_size'):
self._load_index() self._load_index()

View File

@ -8,8 +8,7 @@ __docformat__ = 'restructuredtext en'
import weakref, operator, numbers import weakref, operator, numbers
from functools import partial from functools import partial
from polyglot.builtins import (iteritems, itervalues, map, from polyglot.builtins import iteritems, itervalues
unicode_type, range)
from calibre.ebooks.metadata import title_sort from calibre.ebooks.metadata import title_sort
from calibre.utils.config_base import tweaks, prefs from calibre.utils.config_base import tweaks, prefs
@ -175,8 +174,7 @@ class View:
yield TableRow(book_id, self) yield TableRow(book_id, self)
def iterallids(self): def iterallids(self):
for book_id in sorted(self._map): yield from sorted(self._map)
yield book_id
def tablerow_for_id(self, book_id): def tablerow_for_id(self, book_id):
return TableRow(book_id, self) return TableRow(book_id, self)
@ -281,7 +279,7 @@ class View:
def _build_restriction_string(self, restriction): def _build_restriction_string(self, restriction):
if self.base_restriction: if self.base_restriction:
if restriction: if restriction:
return u'(%s) and (%s)' % (self.base_restriction, restriction) return '(%s) and (%s)' % (self.base_restriction, restriction)
else: else:
return self.base_restriction return self.base_restriction
else: else:
@ -297,7 +295,7 @@ class View:
else: else:
q = query q = query
if search_restriction: if search_restriction:
q = u'(%s) and (%s)' % (search_restriction, query) q = '(%s) and (%s)' % (search_restriction, query)
if not q: if not q:
if set_restriction_count: if set_restriction_count:
self.search_restriction_book_count = len(self._map) self.search_restriction_book_count = len(self._map)
@ -374,10 +372,10 @@ class View:
old_marked_ids = set(self.marked_ids) old_marked_ids = set(self.marked_ids)
if not hasattr(id_dict, 'items'): if not hasattr(id_dict, 'items'):
# Simple list. Make it a dict of string 'true' # Simple list. Make it a dict of string 'true'
self.marked_ids = dict.fromkeys(id_dict, u'true') self.marked_ids = dict.fromkeys(id_dict, 'true')
else: else:
# Ensure that all the items in the dict are text # Ensure that all the items in the dict are text
self.marked_ids = {k: unicode_type(v) for k, v in iteritems(id_dict)} self.marked_ids = {k: str(v) for k, v in iteritems(id_dict)}
# This invalidates all searches in the cache even though the cache may # This invalidates all searches in the cache even though the cache may
# be shared by multiple views. This is not ideal, but... # be shared by multiple views. This is not ideal, but...
cmids = set(self.marked_ids) cmids = set(self.marked_ids)

View File

@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
import re import re
from functools import partial from functools import partial
from datetime import datetime from datetime import datetime
from polyglot.builtins import iteritems, itervalues, unicode_type, zip from polyglot.builtins import iteritems, itervalues
from calibre.constants import preferred_encoding from calibre.constants import preferred_encoding
from calibre.ebooks.metadata import author_to_author_sort, title_sort from calibre.ebooks.metadata import author_to_author_sort, title_sort
@ -30,7 +30,7 @@ def sqlite_datetime(x):
def single_text(x): def single_text(x):
if x is None: if x is None:
return x return x
if not isinstance(x, unicode_type): if not isinstance(x, str):
x = x.decode(preferred_encoding, 'replace') x = x.decode(preferred_encoding, 'replace')
x = x.strip() x = x.strip()
return x if x else None return x if x else None
@ -58,7 +58,7 @@ def multiple_text(sep, ui_sep, x):
return () return ()
if isinstance(x, bytes): if isinstance(x, bytes):
x = x.decode(preferred_encoding, 'replace') x = x.decode(preferred_encoding, 'replace')
if isinstance(x, unicode_type): if isinstance(x, str):
x = x.split(sep) x = x.split(sep)
else: else:
x = (y.decode(preferred_encoding, 'replace') if isinstance(y, bytes) x = (y.decode(preferred_encoding, 'replace') if isinstance(y, bytes)
@ -70,7 +70,7 @@ def multiple_text(sep, ui_sep, x):
def adapt_datetime(x): def adapt_datetime(x):
if isinstance(x, (unicode_type, bytes)): if isinstance(x, (str, bytes)):
x = parse_date(x, assume_utc=False, as_utc=False) x = parse_date(x, assume_utc=False, as_utc=False)
if x and is_date_undefined(x): if x and is_date_undefined(x):
x = UNDEFINED_DATE x = UNDEFINED_DATE
@ -78,7 +78,7 @@ def adapt_datetime(x):
def adapt_date(x): def adapt_date(x):
if isinstance(x, (unicode_type, bytes)): if isinstance(x, (str, bytes)):
x = parse_only_date(x) x = parse_only_date(x)
if x is None or is_date_undefined(x): if x is None or is_date_undefined(x):
x = UNDEFINED_DATE x = UNDEFINED_DATE
@ -88,7 +88,7 @@ def adapt_date(x):
def adapt_number(typ, x): def adapt_number(typ, x):
if x is None: if x is None:
return None return None
if isinstance(x, (unicode_type, bytes)): if isinstance(x, (str, bytes)):
if isinstance(x, bytes): if isinstance(x, bytes):
x = x.decode(preferred_encoding, 'replace') x = x.decode(preferred_encoding, 'replace')
if not x or x.lower() == 'none': if not x or x.lower() == 'none':
@ -97,7 +97,7 @@ def adapt_number(typ, x):
def adapt_bool(x): def adapt_bool(x):
if isinstance(x, (unicode_type, bytes)): if isinstance(x, (str, bytes)):
if isinstance(x, bytes): if isinstance(x, bytes):
x = x.decode(preferred_encoding, 'replace') x = x.decode(preferred_encoding, 'replace')
x = x.lower() x = x.lower()
@ -471,7 +471,7 @@ def many_many(book_id_val_map, db, field, allow_case_change, *args):
) )
db.executemany('DELETE FROM %s WHERE book=?'%table.link_table, db.executemany('DELETE FROM %s WHERE book=?'%table.link_table,
((k,) for k in updated)) ((k,) for k in updated))
db.executemany('INSERT INTO {0}(book,{1}) VALUES(?, ?)'.format( db.executemany('INSERT INTO {}(book,{}) VALUES(?, ?)'.format(
table.link_table, m['link_column']), vals) table.link_table, m['link_column']), vals)
if is_authors: if is_authors:
aus_map = {book_id:field.author_sort_for_book(book_id) for book_id aus_map = {book_id:field.author_sort_for_book(book_id) for book_id

View File

@ -12,7 +12,7 @@ from calibre.utils.config import OptionParser
from calibre.constants import iswindows from calibre.constants import iswindows
from calibre import prints from calibre import prints
from calibre.startup import get_debug_executable from calibre.startup import get_debug_executable
from polyglot.builtins import exec_path, raw_input, unicode_type, getcwd from polyglot.builtins import exec_path
def run_calibre_debug(*args, **kw): def run_calibre_debug(*args, **kw):
@ -156,7 +156,7 @@ def debug_device_driver():
from calibre.devices import debug from calibre.devices import debug
debug(ioreg_to_tmp=True, buf=sys.stdout) debug(ioreg_to_tmp=True, buf=sys.stdout)
if iswindows: # no2to3 if iswindows: # no2to3
raw_input('Press Enter to continue...') # no2to3 input('Press Enter to continue...') # no2to3
def add_simple_plugin(path_to_plugin): def add_simple_plugin(path_to_plugin):
@ -164,7 +164,7 @@ def add_simple_plugin(path_to_plugin):
tdir = tempfile.mkdtemp() tdir = tempfile.mkdtemp()
open(os.path.join(tdir, 'custom_plugin.py'), open(os.path.join(tdir, 'custom_plugin.py'),
'wb').write(open(path_to_plugin, 'rb').read()) 'wb').write(open(path_to_plugin, 'rb').read())
odir = getcwd() odir = os.getcwd()
os.chdir(tdir) os.chdir(tdir)
zf = zipfile.ZipFile('plugin.zip', 'w') zf = zipfile.ZipFile('plugin.zip', 'w')
zf.write('custom_plugin.py') zf.write('custom_plugin.py')
@ -204,11 +204,11 @@ def print_basic_debug_info(out=None):
out('Linux:', platform.linux_distribution()) out('Linux:', platform.linux_distribution())
except: except:
pass pass
out('Interface language:', unicode_type(set_translators.lang)) out('Interface language:', str(set_translators.lang))
from calibre.customize.ui import has_external_plugins, initialized_plugins from calibre.customize.ui import has_external_plugins, initialized_plugins
if has_external_plugins(): if has_external_plugins():
from calibre.customize import PluginInstallationType from calibre.customize import PluginInstallationType
names = ('{0} {1}'.format(p.name, p.version) for p in initialized_plugins() names = ('{} {}'.format(p.name, p.version) for p in initialized_plugins()
if getattr(p, 'installation_type', None) is not PluginInstallationType.BUILTIN) if getattr(p, 'installation_type', None) is not PluginInstallationType.BUILTIN)
out('Successfully initialized third party plugins:', ' && '.join(names)) out('Successfully initialized third party plugins:', ' && '.join(names))

View File

@ -1,4 +1,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
@ -8,7 +7,6 @@ Device drivers.
import sys, time, pprint import sys, time, pprint
from functools import partial from functools import partial
from polyglot.builtins import zip, unicode_type
DAY_MAP = dict(Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6) DAY_MAP = dict(Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6)
MONTH_MAP = dict(Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8, Sep=9, Oct=10, Nov=11, Dec=12) MONTH_MAP = dict(Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8, Sep=9, Oct=10, Nov=11, Dec=12)
@ -19,8 +17,8 @@ INVERSE_MONTH_MAP = dict(zip(MONTH_MAP.values(), MONTH_MAP.keys()))
def strptime(src): def strptime(src):
src = src.strip() src = src.strip()
src = src.split() src = src.split()
src[0] = unicode_type(DAY_MAP[src[0][:-1]])+',' src[0] = str(DAY_MAP[src[0][:-1]])+','
src[2] = unicode_type(MONTH_MAP[src[2]]) src[2] = str(MONTH_MAP[src[2]])
return time.strptime(' '.join(src), '%w, %d %m %Y %H:%M:%S %Z') return time.strptime(' '.join(src), '%w, %d %m %Y %H:%M:%S %Z')

View File

@ -1,5 +1,3 @@
__license__ = 'GPL 3' __license__ = 'GPL 3'
__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,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2011, Ken <ken at szboeye.com>' __copyright__ = '2011, Ken <ken at szboeye.com>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@ -17,7 +17,6 @@ from calibre.devices.errors import ArgumentError, DeviceError, DeviceLocked
from calibre.customize.ui import device_plugins from calibre.customize.ui import device_plugins
from calibre.devices.scanner import DeviceScanner from calibre.devices.scanner import DeviceScanner
from calibre.utils.config import device_prefs from calibre.utils.config import device_prefs
from polyglot.builtins import unicode_type
from polyglot.io import PolyglotStringIO from polyglot.io import PolyglotStringIO
MINIMUM_COL_WIDTH = 12 # : Minimum width of columns in ls output MINIMUM_COL_WIDTH = 12 # : Minimum width of columns in ls output
@ -125,7 +124,7 @@ def ls(dev, path, recurse=False, human_readable_size=False, ll=False, cols=0):
maxlen = 0 maxlen = 0
if ll: # Calculate column width for size column if ll: # Calculate column width for size column
for file in files: for file in files:
size = len(unicode_type(file.size)) size = len(str(file.size))
if human_readable_size: if human_readable_size:
file = FileFormatter(file) file = FileFormatter(file)
size = len(file.human_readable_size) size = len(file.human_readable_size)
@ -137,10 +136,10 @@ def ls(dev, path, recurse=False, human_readable_size=False, ll=False, cols=0):
lsoutput.append(name) lsoutput.append(name)
lscoloutput.append(name) lscoloutput.append(name)
if ll: if ll:
size = unicode_type(file.size) size = str(file.size)
if human_readable_size: if human_readable_size:
size = file.human_readable_size size = file.human_readable_size
prints(file.mode_string, ("%"+unicode_type(maxlen)+"s")%size, file.modification_time, name, file=output) prints(file.mode_string, ("%"+str(maxlen)+"s")%size, file.modification_time, name, file=output)
if not ll and len(lsoutput) > 0: if not ll and len(lsoutput) > 0:
trytable = [] trytable = []
for colwidth in range(MINIMUM_COL_WIDTH, cols): for colwidth in range(MINIMUM_COL_WIDTH, cols):
@ -244,7 +243,7 @@ def main():
print("Filesystem\tSize \tUsed \tAvail \tUse%") print("Filesystem\tSize \tUsed \tAvail \tUse%")
for i in range(3): for i in range(3):
print("%-10s\t%s\t%s\t%s\t%s"%(where[i], human_readable(total[i]), human_readable(total[i]-free[i]), human_readable(free[i]), print("%-10s\t%s\t%s\t%s\t%s"%(where[i], human_readable(total[i]), human_readable(total[i]-free[i]), human_readable(free[i]),
unicode_type(0 if total[i]==0 else int(100*(total[i]-free[i])/(total[i]*1.)))+"%")) str(0 if total[i]==0 else int(100*(total[i]-free[i])/(total[i]*1.)))+"%"))
elif command == 'eject': elif command == 'eject':
dev.eject() dev.eject()
elif command == "books": elif command == "books":
@ -302,7 +301,7 @@ def main():
outfile = os.path.join(outfile, path[path.rfind("/")+1:]) outfile = os.path.join(outfile, path[path.rfind("/")+1:])
try: try:
outfile = lopen(outfile, "wb") outfile = lopen(outfile, "wb")
except IOError as e: except OSError as e:
print(e, file=sys.stderr) print(e, file=sys.stderr)
parser.print_help() parser.print_help()
return 1 return 1
@ -312,7 +311,7 @@ def main():
elif args[1].startswith("dev:"): elif args[1].startswith("dev:"):
try: try:
infile = lopen(args[0], "rb") infile = lopen(args[0], "rb")
except IOError as e: except OSError as e:
print(e, file=sys.stderr) print(e, file=sys.stderr)
parser.print_help() parser.print_help()
return 1 return 1

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@

View File

@ -1,5 +1,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
""" """
@ -8,7 +6,6 @@ Defines the errors that the device drivers generate.
G{classtree ProtocolError} G{classtree ProtocolError}
""" """
from polyglot.builtins import unicode_type
class ProtocolError(Exception): class ProtocolError(Exception):
@ -95,7 +92,7 @@ class DeviceBusy(ProtocolError):
def __init__(self, uerr=""): def __init__(self, uerr=""):
ProtocolError.__init__( ProtocolError.__init__(
self, "Device is in use by another application:" self, "Device is in use by another application:"
"\nUnderlying error:" + unicode_type(uerr) "\nUnderlying error:" + str(uerr)
) )
@ -138,9 +135,9 @@ class ControlError(ProtocolError):
def __str__(self): def __str__(self):
if self.query and self.response: if self.query and self.response:
return "Got unexpected response:\n" + \ return "Got unexpected response:\n" + \
"query:\n"+unicode_type(self.query.query)+"\n"+\ "query:\n"+str(self.query.query)+"\n"+\
"expected:\n"+unicode_type(self.query.response)+"\n" +\ "expected:\n"+str(self.query.response)+"\n" +\
"actual:\n"+unicode_type(self.response) "actual:\n"+str(self.response)
if self.desc: if self.desc:
return self.desc return self.desc
return "Unknown control error occurred" return "Unknown control error occurred"

View File

@ -1,5 +1,3 @@
''' '''
Created on 15 May 2010 Created on 15 May 2010
@ -63,7 +61,7 @@ class FOLDER_DEVICE(USBMS):
def __init__(self, path): def __init__(self, path):
if not os.path.isdir(path): if not os.path.isdir(path):
raise IOError('Path is not a folder') raise OSError('Path is not a folder')
path = USBMS.normalize_path(path) path = USBMS.normalize_path(path)
if path.endswith(os.sep): if path.endswith(os.sep):
self._main_prefix = path self._main_prefix = path

View File

@ -1,4 +1,2 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2009, Tijmen Ruizendaal <tijmen at mybebook.com>' __copyright__ = '2009, Tijmen Ruizendaal <tijmen at mybebook.com>'

View File

@ -1,5 +1,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import os import os

View File

@ -15,7 +15,6 @@ import re
from calibre.constants import filesystem_encoding from calibre.constants import filesystem_encoding
from calibre.devices.usbms.driver import USBMS from calibre.devices.usbms.driver import USBMS
from calibre.ebooks.metadata import string_to_authors from calibre.ebooks.metadata import string_to_authors
from polyglot.builtins import unicode_type, map
class JETBOOK(USBMS): class JETBOOK(USBMS):
@ -65,7 +64,7 @@ class JETBOOK(USBMS):
def metadata_from_path(cls, path): def metadata_from_path(cls, path):
def check_unicode(txt): def check_unicode(txt):
if not isinstance(txt, unicode_type): if not isinstance(txt, str):
txt = txt.decode(filesystem_encoding, 'replace') txt = txt.decode(filesystem_encoding, 'replace')
txt = txt.replace('_', ' ') txt = txt.replace('_', ' ')
return txt return txt

View File

@ -1 +0,0 @@

View File

@ -18,7 +18,7 @@ from calibre.ebooks.mobi.reader.headers import MetadataHeader
from calibre.utils.logging import default_log from calibre.utils.logging import default_log
from calibre import prints, fsync from calibre import prints, fsync
from calibre.constants import DEBUG from calibre.constants import DEBUG
from polyglot.builtins import range, as_unicode, as_bytes, unicode_type, map from polyglot.builtins import as_unicode, as_bytes
class APNXBuilder: class APNXBuilder:
@ -33,7 +33,7 @@ class APNXBuilder:
using either the fast or accurate algorithm. using either the fast or accurate algorithm.
''' '''
import uuid import uuid
apnx_meta = {'guid': unicode_type(uuid.uuid4()).replace('-', '')[:8], 'asin': apnx_meta = {'guid': str(uuid.uuid4()).replace('-', '')[:8], 'asin':
'', 'cdetype': 'EBOK', 'format': 'MOBI_7', 'acr': ''} '', 'cdetype': 'EBOK', 'format': 'MOBI_7', 'acr': ''}
with lopen(mobi_file_path, 'rb') as mf: with lopen(mobi_file_path, 'rb') as mf:
@ -53,11 +53,11 @@ class APNXBuilder:
if mh.exth is None or not mh.exth.cdetype: if mh.exth is None or not mh.exth.cdetype:
apnx_meta['cdetype'] = 'EBOK' apnx_meta['cdetype'] = 'EBOK'
else: else:
apnx_meta['cdetype'] = unicode_type(mh.exth.cdetype) apnx_meta['cdetype'] = str(mh.exth.cdetype)
if mh.exth is None or not mh.exth.uuid: if mh.exth is None or not mh.exth.uuid:
apnx_meta['asin'] = '' apnx_meta['asin'] = ''
else: else:
apnx_meta['asin'] = unicode_type(mh.exth.uuid) apnx_meta['asin'] = str(mh.exth.uuid)
# Get the pages depending on the chosen parser # Get the pages depending on the chosen parser
pages = [] pages = []

View File

@ -154,7 +154,7 @@ class Bookmark(): # {{{
split = my_clippings.find('documents') + len('documents/') split = my_clippings.find('documents') + len('documents/')
my_clippings = my_clippings[:split] + "My Clippings.txt" my_clippings = my_clippings[:split] + "My Clippings.txt"
try: try:
with io.open(my_clippings, encoding='utf-8', errors='replace') as f2: with open(my_clippings, encoding='utf-8', errors='replace') as f2:
marker_found = 0 marker_found = 0
text = '' text = ''
search_str1 = '%s' % (mi.title) search_str1 = '%s' % (mi.title)

View File

@ -15,7 +15,7 @@ from calibre.constants import DEBUG, filesystem_encoding
from calibre.devices.kindle.bookmark import Bookmark from calibre.devices.kindle.bookmark import Bookmark
from calibre.devices.usbms.driver import USBMS from calibre.devices.usbms.driver import USBMS
from calibre import strftime, fsync, prints from calibre import strftime, fsync, prints
from polyglot.builtins import unicode_type, as_bytes, as_unicode from polyglot.builtins import as_bytes, as_unicode
''' '''
Notes on collections: Notes on collections:
@ -232,7 +232,7 @@ class KINDLE(USBMS):
pr=percent_read) pr=percent_read)
else: else:
markup = _("%(time)s<br />Last page read: Location %(loc)d (%(pr)d%%)") % dict( markup = _("%(time)s<br />Last page read: Location %(loc)d (%(pr)d%%)") % dict(
time=strftime(u'%x', timestamp.timetuple()), time=strftime('%x', timestamp.timetuple()),
loc=last_read_location, loc=last_read_location,
pr=percent_read) pr=percent_read)
spanTag = BeautifulSoup('<span style="font-weight:bold">' + markup + '</span>').find('span') spanTag = BeautifulSoup('<span style="font-weight:bold">' + markup + '</span>').find('span')
@ -313,7 +313,7 @@ class KINDLE(USBMS):
bm.value.path, index_is_id=True) bm.value.path, index_is_id=True)
elif bm.type == 'kindle_clippings': elif bm.type == 'kindle_clippings':
# Find 'My Clippings' author=Kindle in database, or add # Find 'My Clippings' author=Kindle in database, or add
last_update = 'Last modified %s' % strftime(u'%x %X',bm.value['timestamp'].timetuple()) last_update = 'Last modified %s' % strftime('%x %X',bm.value['timestamp'].timetuple())
mc_id = list(db.data.search_getting_ids('title:"My Clippings"', '', sort_results=False)) mc_id = list(db.data.search_getting_ids('title:"My Clippings"', '', sort_results=False))
if mc_id: if mc_id:
db.add_format_with_hooks(mc_id[0], 'TXT', bm.value['path'], db.add_format_with_hooks(mc_id[0], 'TXT', bm.value['path'],
@ -524,7 +524,7 @@ class KINDLE2(KINDLE):
cache_dir = self.amazon_cover_bug_cache_dir() cache_dir = self.amazon_cover_bug_cache_dir()
try: try:
os.mkdir(cache_dir) os.mkdir(cache_dir)
except EnvironmentError: except OSError:
pass pass
with lopen(os.path.join(cache_dir, os.path.basename(tp)), 'wb') as f: with lopen(os.path.join(cache_dir, os.path.basename(tp)), 'wb') as f:
f.write(coverdata[2]) f.write(coverdata[2])
@ -545,7 +545,7 @@ class KINDLE2(KINDLE):
dest_path = os.path.join(dest_dir, name) dest_path = os.path.join(dest_dir, name)
try: try:
dest_stat_result = os.lstat(dest_path) dest_stat_result = os.lstat(dest_path)
except EnvironmentError: except OSError:
needs_sync = True needs_sync = True
else: else:
needs_sync = src_stat_result.st_size != dest_stat_result.st_size needs_sync = src_stat_result.st_size != dest_stat_result.st_size
@ -567,7 +567,7 @@ class KINDLE2(KINDLE):
for tp in (tp1, tp2): for tp in (tp1, tp2):
try: try:
os.remove(tp) os.remove(tp)
except EnvironmentError as err: except OSError as err:
if err.errno != errno.ENOENT: if err.errno != errno.ENOENT:
prints('Failed to delete thumbnail for {!r} at {!r} with error: {}'.format(path, tp, err)) prints('Failed to delete thumbnail for {!r} at {!r} with error: {}'.format(path, tp, err))
except Exception: except Exception:
@ -610,7 +610,7 @@ class KINDLE2(KINDLE):
cust_col_name = opts.extra_customization[self.OPT_APNX_METHOD_COL] cust_col_name = opts.extra_customization[self.OPT_APNX_METHOD_COL]
if cust_col_name: if cust_col_name:
try: try:
temp = unicode_type(metadata.get(cust_col_name)).lower() temp = str(metadata.get(cust_col_name)).lower()
if temp in self.EXTRA_CUSTOMIZATION_CHOICES[self.OPT_APNX_METHOD]: if temp in self.EXTRA_CUSTOMIZATION_CHOICES[self.OPT_APNX_METHOD]:
method = temp method = temp
else: else:

View File

@ -57,7 +57,7 @@ class Bookmark(): # {{{
'ORDER BY bm.ContentID, bm.chapterprogress' 'ORDER BY bm.ContentID, bm.chapterprogress'
) )
debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapters: contentId={0}".format(self.contentId)) debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapters: contentId={}".format(self.contentId))
cursor.execute(kepub_chapter_query, book_query_values) cursor.execute(kepub_chapter_query, book_query_values)
kepub_chapters = {} kepub_chapters = {}
if self.kepub: if self.kepub:
@ -69,7 +69,7 @@ class Bookmark(): # {{{
'chapter_title': chapter_row['Title'], 'chapter_title': chapter_row['Title'],
'chapter_index': chapter_row['VolumeIndex'] 'chapter_index': chapter_row['VolumeIndex']
} }
debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapter: kepub chapters={0}".format(kepub_chapters)) debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapter: kepub chapters={}".format(kepub_chapters))
except: except:
debug_print("Kobo::Bookmark::get_bookmark_data - No chapters found") debug_print("Kobo::Bookmark::get_bookmark_data - No chapters found")
@ -83,20 +83,20 @@ class Bookmark(): # {{{
# For kepubs on newer firmware, the title needs to come from an 899 row. # For kepubs on newer firmware, the title needs to come from an 899 row.
if self.kepub: if self.kepub:
chapter_contentID = row['ContentID'] chapter_contentID = row['ContentID']
debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter chapter_contentID='{0}'".format(chapter_contentID)) debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter chapter_contentID='{}'".format(chapter_contentID))
filename_index = chapter_contentID.find('!') filename_index = chapter_contentID.find('!')
book_contentID_part = chapter_contentID[:filename_index] book_contentID_part = chapter_contentID[:filename_index]
debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter book_contentID_part='{0}'".format(book_contentID_part)) debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter book_contentID_part='{}'".format(book_contentID_part))
file_contentID_part = chapter_contentID[filename_index + 1:] file_contentID_part = chapter_contentID[filename_index + 1:]
filename_index = file_contentID_part.find('!') filename_index = file_contentID_part.find('!')
opf_reference = file_contentID_part[:filename_index] opf_reference = file_contentID_part[:filename_index]
debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter opf_reference='{0}'".format(opf_reference)) debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter opf_reference='{}'".format(opf_reference))
file_contentID_part = file_contentID_part[filename_index + 1:] file_contentID_part = file_contentID_part[filename_index + 1:]
debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter file_contentID_part='{0}'".format(file_contentID_part)) debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub: chapter file_contentID_part='{}'".format(file_contentID_part))
# from urllib import quote # from urllib import quote
# file_contentID_part = quote(file_contentID_part) # file_contentID_part = quote(file_contentID_part)
chapter_contentID = book_contentID_part + "!" + opf_reference + "!" + file_contentID_part chapter_contentID = book_contentID_part + "!" + opf_reference + "!" + file_contentID_part
debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapter chapter_contentID='{0}'".format(chapter_contentID)) debug_print("Kobo::Bookmark::get_bookmark_data - getting kepub chapter chapter_contentID='{}'".format(chapter_contentID))
kepub_chapter = kepub_chapters.get(chapter_contentID, None) kepub_chapter = kepub_chapters.get(chapter_contentID, None)
if kepub_chapter is not None: if kepub_chapter is not None:
chapter_title = kepub_chapter['chapter_title'] chapter_title = kepub_chapter['chapter_title']

View File

@ -1,4 +1,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2010-2012, , Timothy Legge <timlegge at gmail.com> and David Forrester <davidfor@internode.on.net>' __copyright__ = '2010-2012, , Timothy Legge <timlegge at gmail.com> and David Forrester <davidfor@internode.on.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
@ -29,7 +28,7 @@ class Book(Book_):
if show_debug: if show_debug:
debug_print("Book::__init__ - title=", title, 'authors=', authors) debug_print("Book::__init__ - title=", title, 'authors=', authors)
debug_print("Book::__init__ - other=", other) debug_print("Book::__init__ - other=", other)
super(Book, self).__init__(prefix, lpath, size, other) super().__init__(prefix, lpath, size, other)
if title is not None and len(title) > 0: if title is not None and len(title) > 0:
self.title = title self.title = title
@ -117,7 +116,7 @@ class Book(Book_):
ans = '\n'.join(ans) ans = '\n'.join(ans)
return super(Book,self).__str__() + "\n" + ans return super().__str__() + "\n" + ans
class ImageWrapper: class ImageWrapper:
@ -129,7 +128,7 @@ class ImageWrapper:
class KTCollectionsBookList(CollectionsBookList): class KTCollectionsBookList(CollectionsBookList):
def __init__(self, oncard, prefix, settings): def __init__(self, oncard, prefix, settings):
super(KTCollectionsBookList, self).__init__(oncard, prefix, settings) super().__init__(oncard, prefix, settings)
self.set_device_managed_collections([]) self.set_device_managed_collections([])
def get_collections(self, collection_attributes): def get_collections(self, collection_attributes):

View File

@ -33,7 +33,7 @@ from calibre import prints, fsync
from calibre.ptempfile import PersistentTemporaryFile, better_mktemp from calibre.ptempfile import PersistentTemporaryFile, better_mktemp
from calibre.constants import DEBUG from calibre.constants import DEBUG
from calibre.utils.config_base import prefs from calibre.utils.config_base import prefs
from polyglot.builtins import iteritems, itervalues, unicode_type, string_or_bytes from polyglot.builtins import iteritems, itervalues, string_or_bytes
EPUB_EXT = '.epub' EPUB_EXT = '.epub'
KEPUB_EXT = '.kepub' KEPUB_EXT = '.kepub'
@ -47,7 +47,7 @@ def qhash(inputstr):
instr = b"" instr = b""
if isinstance(inputstr, bytes): if isinstance(inputstr, bytes):
instr = inputstr instr = inputstr
elif isinstance(inputstr, unicode_type): elif isinstance(inputstr, str):
instr = inputstr.encode("utf8") instr = inputstr.encode("utf8")
else: else:
return -1 return -1
@ -203,7 +203,7 @@ class KOBO(USBMS):
try: try:
with lopen(self.normalize_path(self._main_prefix + '.kobo/version'), 'rb') as f: with lopen(self.normalize_path(self._main_prefix + '.kobo/version'), 'rb') as f:
fwversion = f.readline().split(b',')[2] fwversion = f.readline().split(b',')[2]
fwversion = tuple((int(x) for x in fwversion.split(b'.'))) fwversion = tuple(int(x) for x in fwversion.split(b'.'))
except Exception: except Exception:
debug_print("Kobo::get_firmware_version - didn't get firmware version from file'") debug_print("Kobo::get_firmware_version - didn't get firmware version from file'")
fwversion = (0,0,0) fwversion = (0,0,0)
@ -377,7 +377,7 @@ class KOBO(USBMS):
try: try:
cursor.execute(query) cursor.execute(query)
except Exception as e: except Exception as e:
err = unicode_type(e) err = str(e)
if not (any_in(err, '___ExpirationStatus', 'FavouritesIndex', 'Accessibility', 'IsDownloaded')): if not (any_in(err, '___ExpirationStatus', 'FavouritesIndex', 'Accessibility', 'IsDownloaded')):
raise raise
query= ('select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' query= ('select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, '
@ -483,13 +483,13 @@ class KOBO(USBMS):
cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0, ___ExpirationStatus=3 ' cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0, ___ExpirationStatus=3 '
'where BookID is Null and ContentID =?',t) 'where BookID is Null and ContentID =?',t)
except Exception as e: except Exception as e:
if 'no such column' not in unicode_type(e): if 'no such column' not in str(e):
raise raise
try: try:
cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0 ' cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0 '
'where BookID is Null and ContentID =?',t) 'where BookID is Null and ContentID =?',t)
except Exception as e: except Exception as e:
if 'no such column' not in unicode_type(e): if 'no such column' not in str(e):
raise raise
cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\' ' cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\' '
'where BookID is Null and ContentID =?',t) 'where BookID is Null and ContentID =?',t)
@ -833,7 +833,7 @@ class KOBO(USBMS):
cursor.execute(query) cursor.execute(query)
except Exception as e: except Exception as e:
debug_print(' Database Exception: Unable to reset Shortlist list') debug_print(' Database Exception: Unable to reset Shortlist list')
if 'no such column' not in unicode_type(e): if 'no such column' not in str(e):
raise raise
finally: finally:
cursor.close() cursor.close()
@ -847,7 +847,7 @@ class KOBO(USBMS):
cursor.execute('update content set FavouritesIndex=1 where BookID is Null and ContentID = ?', t) cursor.execute('update content set FavouritesIndex=1 where BookID is Null and ContentID = ?', t)
except Exception as e: except Exception as e:
debug_print(' Database Exception: Unable set book as Shortlist') debug_print(' Database Exception: Unable set book as Shortlist')
if 'no such column' not in unicode_type(e): if 'no such column' not in str(e):
raise raise
finally: finally:
cursor.close() cursor.close()
@ -1138,7 +1138,7 @@ class KOBO(USBMS):
def get_annotations(self, path_map): def get_annotations(self, path_map):
from calibre.devices.kobo.bookmark import Bookmark from calibre.devices.kobo.bookmark import Bookmark
EPUB_FORMATS = [u'epub'] EPUB_FORMATS = ['epub']
epub_formats = set(EPUB_FORMATS) epub_formats = set(EPUB_FORMATS)
def get_storage(): def get_storage():
@ -1519,21 +1519,21 @@ class KOBOTOUCH(KOBO):
self.plugboards = self.plugboard_func = None self.plugboards = self.plugboard_func = None
def initialize(self): def initialize(self):
super(KOBOTOUCH, self).initialize() super().initialize()
self.bookshelvelist = [] self.bookshelvelist = []
def get_device_information(self, end_session=True): def get_device_information(self, end_session=True):
self.set_device_name() self.set_device_name()
return super(KOBOTOUCH, self).get_device_information(end_session) return super().get_device_information(end_session)
def open_linux(self): def open_linux(self):
super(KOBOTOUCH, self).open_linux() super().open_linux()
self.swap_drives_if_needed() self.swap_drives_if_needed()
def open_osx(self): def open_osx(self):
# Just dump some info to the logs. # Just dump some info to the logs.
super(KOBOTOUCH, self).open_osx() super().open_osx()
# Wrap some debugging output in a try/except so that it is unlikely to break things completely. # Wrap some debugging output in a try/except so that it is unlikely to break things completely.
try: try:
@ -1808,7 +1808,7 @@ class KOBOTOUCH(KOBO):
debug_print('KoboTouch:update_booklist - book file does not exist. ContentID="%s"'%ContentID) debug_print('KoboTouch:update_booklist - book file does not exist. ContentID="%s"'%ContentID)
except Exception as e: except Exception as e:
debug_print("KoboTouch:update_booklist - exception creating book: '%s'"%unicode_type(e)) debug_print("KoboTouch:update_booklist - exception creating book: '%s'"%str(e))
debug_print(" prefix: ", prefix, "lpath: ", lpath, "title: ", title, "authors: ", authors, debug_print(" prefix: ", prefix, "lpath: ", lpath, "title: ", title, "authors: ", authors,
"MimeType: ", MimeType, "DateCreated: ", DateCreated, "ContentType: ", ContentType, "ImageID: ", ImageID) "MimeType: ", MimeType, "DateCreated: ", DateCreated, "ContentType: ", ContentType, "ImageID: ", ImageID)
raise raise
@ -1870,7 +1870,7 @@ class KOBOTOUCH(KOBO):
bookshelves.append(row['ShelfName']) bookshelves.append(row['ShelfName'])
cursor.close() cursor.close()
# debug_print("KoboTouch:get_bookshelvesforbook - count bookshelves=" + unicode_type(count_bookshelves)) # debug_print("KoboTouch:get_bookshelvesforbook - count bookshelves=" + str(count_bookshelves))
return bookshelves return bookshelves
self.debug_index = 0 self.debug_index = 0
@ -1963,7 +1963,7 @@ class KOBOTOUCH(KOBO):
try: try:
cursor.execute(query) cursor.execute(query)
except Exception as e: except Exception as e:
err = unicode_type(e) err = str(e)
if not (any_in(err, '___ExpirationStatus', 'FavouritesIndex', 'Accessibility', 'IsDownloaded', 'Series', 'ExternalId')): if not (any_in(err, '___ExpirationStatus', 'FavouritesIndex', 'Accessibility', 'IsDownloaded', 'Series', 'ExternalId')):
raise raise
query= ('SELECT Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' query= ('SELECT Title, Attribution, DateCreated, ContentID, MimeType, ContentType, '
@ -2049,7 +2049,7 @@ class KOBOTOUCH(KOBO):
path = ContentID path = ContentID
if not externalId: if not externalId:
return super(KOBOTOUCH, self).path_from_contentid(ContentID, ContentType, MimeType, oncard) return super().path_from_contentid(ContentID, ContentType, MimeType, oncard)
if oncard == 'cardb': if oncard == 'cardb':
print('path from_contentid cardb') print('path from_contentid cardb')
@ -2099,13 +2099,13 @@ class KOBOTOUCH(KOBO):
from css_parser import parseFile as cssparseFile from css_parser import parseFile as cssparseFile
try: try:
extra_sheet = cssparseFile(extra_css_path) extra_sheet = cssparseFile(extra_css_path)
debug_print("KoboTouch:get_extra_css: Using extra CSS in {0} ({1} rules)".format(extra_css_path, len(extra_sheet.cssRules))) debug_print("KoboTouch:get_extra_css: Using extra CSS in {} ({} rules)".format(extra_css_path, len(extra_sheet.cssRules)))
if len(extra_sheet.cssRules) ==0: if len(extra_sheet.cssRules) ==0:
debug_print("KoboTouch:get_extra_css: Extra CSS file has no valid rules. CSS will not be modified.") debug_print("KoboTouch:get_extra_css: Extra CSS file has no valid rules. CSS will not be modified.")
extra_sheet = None extra_sheet = None
except Exception as e: except Exception as e:
debug_print("KoboTouch:get_extra_css: Problem parsing extra CSS file {0}".format(extra_css_path)) debug_print("KoboTouch:get_extra_css: Problem parsing extra CSS file {}".format(extra_css_path))
debug_print("KoboTouch:get_extra_css: Exception {0}".format(e)) debug_print("KoboTouch:get_extra_css: Exception {}".format(e))
# create dictionary of features enabled in kobo extra css # create dictionary of features enabled in kobo extra css
self.extra_css_options = {} self.extra_css_options = {}
@ -2136,16 +2136,16 @@ class KOBOTOUCH(KOBO):
self.extra_sheet = self.get_extra_css() self.extra_sheet = self.get_extra_css()
i = 0 i = 0
for file, n, mi in zip(files, names, metadata): for file, n, mi in zip(files, names, metadata):
debug_print("KoboTouch:upload_books: Processing book: {0} by {1}".format(mi.title, " and ".join(mi.authors))) debug_print("KoboTouch:upload_books: Processing book: {} by {}".format(mi.title, " and ".join(mi.authors)))
debug_print("KoboTouch:upload_books: file=%s, name=%s" % (file, n)) debug_print("KoboTouch:upload_books: file=%s, name=%s" % (file, n))
self.report_progress(i / float(len(files)), "Processing book: {0} by {1}".format(mi.title, " and ".join(mi.authors))) self.report_progress(i / float(len(files)), "Processing book: {} by {}".format(mi.title, " and ".join(mi.authors)))
mi.kte_calibre_name = n mi.kte_calibre_name = n
self._modify_epub(file, mi) self._modify_epub(file, mi)
i += 1 i += 1
self.report_progress(0, 'Working...') self.report_progress(0, 'Working...')
result = super(KOBOTOUCH, self).upload_books(files, names, on_card, end_session, metadata) result = super().upload_books(files, names, on_card, end_session, metadata)
# debug_print('KoboTouch:upload_books - result=', result) # debug_print('KoboTouch:upload_books - result=', result)
if self.dbversion >= 53: if self.dbversion >= 53:
@ -2174,12 +2174,12 @@ class KOBOTOUCH(KOBO):
cursor.close() cursor.close()
except Exception as e: except Exception as e:
debug_print('KoboTouch:upload_books - Exception: %s'%unicode_type(e)) debug_print('KoboTouch:upload_books - Exception: %s'%str(e))
return result return result
def _modify_epub(self, book_file, metadata, container=None): def _modify_epub(self, book_file, metadata, container=None):
debug_print("KoboTouch:_modify_epub:Processing {0} - {1}".format(metadata.author_sort, metadata.title)) debug_print("KoboTouch:_modify_epub:Processing {} - {}".format(metadata.author_sort, metadata.title))
# Currently only modifying CSS, so if no stylesheet, don't do anything # Currently only modifying CSS, so if no stylesheet, don't do anything
if not self.extra_sheet: if not self.extra_sheet:
@ -2200,9 +2200,9 @@ class KOBOTOUCH(KOBO):
# future css mods may be epub/kepub specific, so pass file extension arg # future css mods may be epub/kepub specific, so pass file extension arg
fileext = os.path.splitext(book_file)[-1].lower() fileext = os.path.splitext(book_file)[-1].lower()
debug_print("KoboTouch:_modify_epub: Modifying {0}".format(cssname)) debug_print("KoboTouch:_modify_epub: Modifying {}".format(cssname))
if self._modify_stylesheet(newsheet, fileext): if self._modify_stylesheet(newsheet, fileext):
debug_print("KoboTouch:_modify_epub:CSS rules {0} -> {1} ({2})".format(oldrules, len(newsheet.cssRules), cssname)) debug_print("KoboTouch:_modify_epub:CSS rules {} -> {} ({})".format(oldrules, len(newsheet.cssRules), cssname))
container.dirty(cssname) container.dirty(cssname)
is_dirty = True is_dirty = True
@ -2256,8 +2256,8 @@ class KOBOTOUCH(KOBO):
container = get_container(book_file) container = get_container(book_file)
container.css_preprocessor = DummyCSSPreProcessor() container.css_preprocessor = DummyCSSPreProcessor()
except Exception as e: except Exception as e:
debug_print("KoboTouch:create_container: exception from get_container {0} - {1}".format(metadata.author_sort, metadata.title)) debug_print("KoboTouch:create_container: exception from get_container {} - {}".format(metadata.author_sort, metadata.title))
debug_print("KoboTouch:create_container: exception is: {0}".format(e)) debug_print("KoboTouch:create_container: exception is: {}".format(e))
else: else:
commit_container = False commit_container = False
debug_print("KoboTouch:create_container: received container") debug_print("KoboTouch:create_container: received container")
@ -2277,7 +2277,7 @@ class KOBOTOUCH(KOBO):
pass pass
def delete_via_sql(self, ContentID, ContentType): def delete_via_sql(self, ContentID, ContentType):
imageId = super(KOBOTOUCH, self).delete_via_sql(ContentID, ContentType) imageId = super().delete_via_sql(ContentID, ContentType)
if self.dbversion >= 53: if self.dbversion >= 53:
debug_print('KoboTouch:delete_via_sql: ContentID="%s"'%ContentID, 'ContentType="%s"'%ContentType) debug_print('KoboTouch:delete_via_sql: ContentID="%s"'%ContentID, 'ContentType="%s"'%ContentType)
@ -2318,7 +2318,7 @@ class KOBOTOUCH(KOBO):
debug_print('KoboTouch:delete_via_sql: finished SQL') debug_print('KoboTouch:delete_via_sql: finished SQL')
debug_print('KoboTouch:delete_via_sql: After SQL, no exception') debug_print('KoboTouch:delete_via_sql: After SQL, no exception')
except Exception as e: except Exception as e:
debug_print('KoboTouch:delete_via_sql - Database Exception: %s'%unicode_type(e)) debug_print('KoboTouch:delete_via_sql - Database Exception: %s'%str(e))
debug_print('KoboTouch:delete_via_sql: imageId="%s"'%imageId) debug_print('KoboTouch:delete_via_sql: imageId="%s"'%imageId)
if imageId is None: if imageId is None:
@ -2383,7 +2383,7 @@ class KOBOTOUCH(KOBO):
def get_content_type_from_path(self, path): def get_content_type_from_path(self, path):
ContentType = 6 ContentType = 6
if self.fwversion < (1, 9, 17): if self.fwversion < (1, 9, 17):
ContentType = super(KOBOTOUCH, self).get_content_type_from_path(path) ContentType = super().get_content_type_from_path(path)
return ContentType return ContentType
def get_content_type_from_extension(self, extension): def get_content_type_from_extension(self, extension):
@ -2391,7 +2391,7 @@ class KOBOTOUCH(KOBO):
# With new firmware, ContentType appears to be 6 for all types of sideloaded books. # With new firmware, ContentType appears to be 6 for all types of sideloaded books.
ContentType = 6 ContentType = 6
if self.fwversion < (1,9,17): if self.fwversion < (1,9,17):
ContentType = super(KOBOTOUCH, self).get_content_type_from_extension(extension) ContentType = super().get_content_type_from_extension(extension)
return ContentType return ContentType
def set_plugboards(self, plugboards, pb_func): def set_plugboards(self, plugboards, pb_func):
@ -2451,7 +2451,7 @@ class KOBOTOUCH(KOBO):
if self.manage_collections: if self.manage_collections:
if collections: if collections:
# debug_print("KoboTouch:update_device_database_collections - length collections=" + unicode_type(len(collections))) # debug_print("KoboTouch:update_device_database_collections - length collections=" + str(len(collections)))
# Need to reset the collections outside the particular loops # Need to reset the collections outside the particular loops
# otherwise the last item will not be removed # otherwise the last item will not be removed
@ -2621,7 +2621,7 @@ class KOBOTOUCH(KOBO):
self.keep_cover_aspect, self.letterbox_fs_covers, self.png_covers, self.keep_cover_aspect, self.letterbox_fs_covers, self.png_covers,
letterbox_color=self.letterbox_fs_covers_color) letterbox_color=self.letterbox_fs_covers_color)
except Exception as e: except Exception as e:
debug_print('KoboTouch: FAILED to upload cover=%s Exception=%s'%(filepath, unicode_type(e))) debug_print('KoboTouch: FAILED to upload cover=%s Exception=%s'%(filepath, str(e)))
def imageid_from_contentid(self, ContentID): def imageid_from_contentid(self, ContentID):
ImageID = ContentID.replace('/', '_') ImageID = ContentID.replace('/', '_')
@ -2831,7 +2831,7 @@ class KOBOTOUCH(KOBO):
f.write(data) f.write(data)
fsync(f) fsync(f)
except Exception as e: except Exception as e:
err = unicode_type(e) err = str(e)
debug_print("KoboTouch:_upload_cover - Exception string: %s"%err) debug_print("KoboTouch:_upload_cover - Exception string: %s"%err)
raise raise
@ -2978,7 +2978,7 @@ class KOBOTOUCH(KOBO):
# count_bookshelves = i + 1 # count_bookshelves = i + 1
cursor.close() cursor.close()
# debug_print("KoboTouch:get_bookshelflist - count bookshelves=" + unicode_type(count_bookshelves)) # debug_print("KoboTouch:get_bookshelflist - count bookshelves=" + str(count_bookshelves))
return bookshelves return bookshelves
@ -3062,7 +3062,7 @@ class KOBOTOUCH(KOBO):
cursor.execute(addquery, add_values) cursor.execute(addquery, add_values)
elif result['_IsDeleted'] == 'true': elif result['_IsDeleted'] == 'true':
debug_print("KoboTouch:check_for_bookshelf - Shelf '%s' is deleted - undeleting. result['_IsDeleted']='%s'" % ( debug_print("KoboTouch:check_for_bookshelf - Shelf '%s' is deleted - undeleting. result['_IsDeleted']='%s'" % (
bookshelf_name, unicode_type(result['_IsDeleted']))) bookshelf_name, str(result['_IsDeleted'])))
cursor.execute(updatequery, test_values) cursor.execute(updatequery, test_values)
cursor.close() cursor.close()
@ -3329,7 +3329,7 @@ class KOBOTOUCH(KOBO):
@classmethod @classmethod
def _config(cls): def _config(cls):
c = super(KOBOTOUCH, cls)._config() c = super()._config()
c.add_opt('manage_collections', default=True) c.add_opt('manage_collections', default=True)
c.add_opt('collections_columns', default='') c.add_opt('collections_columns', default='')
@ -3819,7 +3819,7 @@ class KOBOTOUCH(KOBO):
try: try:
is_debugging = len(self.debugging_title) > 0 and title.lower().find(self.debugging_title.lower()) >= 0 or len(title) == 0 is_debugging = len(self.debugging_title) > 0 and title.lower().find(self.debugging_title.lower()) >= 0 or len(title) == 0
except: except:
debug_print(("KoboTouch::is_debugging_title - Exception checking debugging title for title '{0}'.").format(title)) debug_print(("KoboTouch::is_debugging_title - Exception checking debugging title for title '{}'.").format(title))
is_debugging = False is_debugging = False
return is_debugging return is_debugging
@ -3864,7 +3864,7 @@ class KOBOTOUCH(KOBO):
def __str__(self, *args, **kwargs): def __str__(self, *args, **kwargs):
options = ', '.join(['%s: %s' % (x.name, self.get_pref(x.name)) for x in self._config().preferences]) options = ', '.join(['%s: %s' % (x.name, self.get_pref(x.name)) for x in self._config().preferences])
return u"Driver:%s, Options - %s" % (self.name, options) return "Driver:%s, Options - %s" % (self.name, options)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -16,7 +16,6 @@ from calibre.devices.usbms.driver import debug_print
from calibre.gui2 import error_dialog from calibre.gui2 import error_dialog
from calibre.gui2.widgets2 import ColorButton from calibre.gui2.widgets2 import ColorButton
from calibre.gui2.dialogs.template_dialog import TemplateDialog from calibre.gui2.dialogs.template_dialog import TemplateDialog
from polyglot.builtins import unicode_type
def wrap_msg(msg): def wrap_msg(msg):
@ -40,7 +39,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig):
must_read_metadata, supports_use_author_sort, must_read_metadata, supports_use_author_sort,
extra_customization_message, device, extra_customization_choices=None, parent=None): extra_customization_message, device, extra_customization_choices=None, parent=None):
super(KOBOTOUCHConfig, self).__init__(device_settings, all_formats, supports_subdirs, super().__init__(device_settings, all_formats, supports_subdirs,
must_read_metadata, supports_use_author_sort, must_read_metadata, supports_use_author_sort,
extra_customization_message, device, extra_customization_choices, parent) extra_customization_message, device, extra_customization_choices, parent)
@ -66,7 +65,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig):
return self._device() return self._device()
def validate(self): def validate(self):
validated = super(KOBOTOUCHConfig, self).validate() validated = super().validate()
validated &= self.tab2.validate() validated &= self.tab2.validate()
return validated return validated
@ -96,7 +95,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig):
def commit(self): def commit(self):
debug_print("KOBOTOUCHConfig::commit: start") debug_print("KOBOTOUCHConfig::commit: start")
p = super(KOBOTOUCHConfig, self).commit() p = super().commit()
p['manage_collections'] = self.manage_collections p['manage_collections'] = self.manage_collections
p['create_collections'] = self.create_collections p['create_collections'] = self.create_collections
@ -128,7 +127,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig):
p['support_newer_firmware'] = self.support_newer_firmware p['support_newer_firmware'] = self.support_newer_firmware
p['debugging_title'] = self.debugging_title p['debugging_title'] = self.debugging_title
p['driver_version'] = '.'.join([unicode_type(i) for i in self.device.version]) p['driver_version'] = '.'.join([str(i) for i in self.device.version])
return p return p
@ -136,7 +135,7 @@ class KOBOTOUCHConfig(TabbedDeviceConfig):
class Tab1Config(DeviceConfigTab): # {{{ class Tab1Config(DeviceConfigTab): # {{{
def __init__(self, parent, device): def __init__(self, parent, device):
super(Tab1Config, self).__init__(parent) super().__init__(parent)
self.l = QVBoxLayout(self) self.l = QVBoxLayout(self)
self.setLayout(self.l) self.setLayout(self.l)
@ -160,7 +159,7 @@ class Tab1Config(DeviceConfigTab): # {{{
class Tab2Config(DeviceConfigTab): # {{{ class Tab2Config(DeviceConfigTab): # {{{
def __init__(self, parent, device): def __init__(self, parent, device):
super(Tab2Config, self).__init__(parent) super().__init__(parent)
self.l = QVBoxLayout(self) self.l = QVBoxLayout(self)
self.setLayout(self.l) self.setLayout(self.l)
@ -188,7 +187,7 @@ class Tab2Config(DeviceConfigTab): # {{{
class BookUploadsGroupBox(DeviceOptionsGroupBox): class BookUploadsGroupBox(DeviceOptionsGroupBox):
def __init__(self, parent, device): def __init__(self, parent, device):
super(BookUploadsGroupBox, self).__init__(parent, device) super().__init__(parent, device)
self.setTitle(_("Uploading of books")) self.setTitle(_("Uploading of books"))
self.options_layout = QGridLayout() self.options_layout = QGridLayout()
@ -230,7 +229,7 @@ class BookUploadsGroupBox(DeviceOptionsGroupBox):
class CollectionsGroupBox(DeviceOptionsGroupBox): class CollectionsGroupBox(DeviceOptionsGroupBox):
def __init__(self, parent, device): def __init__(self, parent, device):
super(CollectionsGroupBox, self).__init__(parent, device) super().__init__(parent, device)
self.setTitle(_("Collections")) self.setTitle(_("Collections"))
self.options_layout = QGridLayout() self.options_layout = QGridLayout()
@ -297,7 +296,7 @@ class CollectionsGroupBox(DeviceOptionsGroupBox):
class CoversGroupBox(DeviceOptionsGroupBox): class CoversGroupBox(DeviceOptionsGroupBox):
def __init__(self, parent, device): def __init__(self, parent, device):
super(CoversGroupBox, self).__init__(parent, device) super().__init__(parent, device)
self.setTitle(_("Upload covers")) self.setTitle(_("Upload covers"))
self.options_layout = QGridLayout() self.options_layout = QGridLayout()
@ -416,7 +415,7 @@ class CoversGroupBox(DeviceOptionsGroupBox):
class DeviceListGroupBox(DeviceOptionsGroupBox): class DeviceListGroupBox(DeviceOptionsGroupBox):
def __init__(self, parent, device): def __init__(self, parent, device):
super(DeviceListGroupBox, self).__init__(parent, device) super().__init__(parent, device)
self.setTitle(_("Show as on device")) self.setTitle(_("Show as on device"))
self.options_layout = QGridLayout() self.options_layout = QGridLayout()
@ -466,7 +465,7 @@ class DeviceListGroupBox(DeviceOptionsGroupBox):
class AdvancedGroupBox(DeviceOptionsGroupBox): class AdvancedGroupBox(DeviceOptionsGroupBox):
def __init__(self, parent, device): def __init__(self, parent, device):
super(AdvancedGroupBox, self).__init__(parent, device, _("Advanced options")) super().__init__(parent, device, _("Advanced options"))
# self.setTitle(_("Advanced Options")) # self.setTitle(_("Advanced Options"))
self.options_layout = QGridLayout() self.options_layout = QGridLayout()
@ -480,7 +479,7 @@ class AdvancedGroupBox(DeviceOptionsGroupBox):
'to perform full read-write functionality - Here be Dragons!! ' 'to perform full read-write functionality - Here be Dragons!! '
'Enable only if you are comfortable with restoring your kobo ' 'Enable only if you are comfortable with restoring your kobo '
'to factory defaults and testing software. ' 'to factory defaults and testing software. '
'This driver supports firmware V2.x.x and DBVersion up to ') + unicode_type( 'This driver supports firmware V2.x.x and DBVersion up to ') + str(
device.supported_dbversion), device.get_pref('support_newer_firmware') device.supported_dbversion), device.get_pref('support_newer_firmware')
) )
@ -515,7 +514,7 @@ class AdvancedGroupBox(DeviceOptionsGroupBox):
class MetadataGroupBox(DeviceOptionsGroupBox): class MetadataGroupBox(DeviceOptionsGroupBox):
def __init__(self, parent, device): def __init__(self, parent, device):
super(MetadataGroupBox, self).__init__(parent, device) super().__init__(parent, device)
self.setTitle(_("Update metadata on the device")) self.setTitle(_("Update metadata on the device"))
self.options_layout = QGridLayout() self.options_layout = QGridLayout()
@ -638,7 +637,7 @@ class TemplateConfig(QWidget): # {{{
@property @property
def template(self): def template(self):
return unicode_type(self.t.text()).strip() return str(self.t.text()).strip()
@template.setter @template.setter
def template(self, template): def template(self, template):
@ -660,7 +659,7 @@ class TemplateConfig(QWidget): # {{{
except Exception as err: except Exception as err:
error_dialog(self, _('Invalid template'), error_dialog(self, _('Invalid template'),
'<p>'+_('The template "%s" is invalid:')%tmpl + '<p>'+_('The template "%s" is invalid:')%tmpl +
'<br>'+unicode_type(err), show=True) '<br>'+str(err), show=True)
return False return False
# }}} # }}}

View File

@ -1,4 +1,3 @@
__license__ = 'GPL 3' __license__ = 'GPL 3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@ -46,7 +46,7 @@ class Book(Metadata):
Metadata.__init__(self, _('Unknown'), other=other) Metadata.__init__(self, _('Unknown'), other=other)
self.storage_id, self.lpath = storage_id, lpath self.storage_id, self.lpath = storage_id, lpath
self.lpath = self.path = self.lpath.replace(os.sep, '/') self.lpath = self.path = self.lpath.replace(os.sep, '/')
self.mtp_relpath = tuple([icu_lower(x) for x in self.lpath.split('/')]) self.mtp_relpath = tuple(icu_lower(x) for x in self.lpath.split('/'))
self.datetime = utcnow().timetuple() self.datetime = utcnow().timetuple()
self.thumbail = None self.thumbail = None

View File

@ -16,7 +16,7 @@ from calibre.devices.mtp.base import debug
from calibre.devices.mtp.defaults import DeviceDefaults from calibre.devices.mtp.defaults import DeviceDefaults
from calibre.ptempfile import SpooledTemporaryFile, PersistentTemporaryDirectory from calibre.ptempfile import SpooledTemporaryFile, PersistentTemporaryDirectory
from calibre.utils.filenames import shorten_components_to from calibre.utils.filenames import shorten_components_to
from polyglot.builtins import iteritems, itervalues, unicode_type, zip, as_bytes from polyglot.builtins import iteritems, itervalues, as_bytes
BASE = importlib.import_module('calibre.devices.mtp.%s.driver'%( BASE = importlib.import_module('calibre.devices.mtp.%s.driver'%(
'windows' if iswindows else 'unix')).MTP_DEVICE 'windows' if iswindows else 'unix')).MTP_DEVICE
@ -76,7 +76,7 @@ class MTP_DEVICE(BASE):
def is_folder_ignored(self, storage_or_storage_id, path, def is_folder_ignored(self, storage_or_storage_id, path,
ignored_folders=None): ignored_folders=None):
storage_id = unicode_type(getattr(storage_or_storage_id, 'object_id', storage_id = str(getattr(storage_or_storage_id, 'object_id',
storage_or_storage_id)) storage_or_storage_id))
lpath = tuple(icu_lower(name) for name in path) lpath = tuple(icu_lower(name) for name in path)
if ignored_folders is None: if ignored_folders is None:
@ -168,14 +168,14 @@ class MTP_DEVICE(BASE):
traceback.print_exc() traceback.print_exc()
dinfo = {} dinfo = {}
if dinfo.get('device_store_uuid', None) is None: if dinfo.get('device_store_uuid', None) is None:
dinfo['device_store_uuid'] = unicode_type(uuid.uuid4()) dinfo['device_store_uuid'] = str(uuid.uuid4())
if dinfo.get('device_name', None) is None: if dinfo.get('device_name', None) is None:
dinfo['device_name'] = self.current_friendly_name dinfo['device_name'] = self.current_friendly_name
if name is not None: if name is not None:
dinfo['device_name'] = name dinfo['device_name'] = name
dinfo['location_code'] = location_code dinfo['location_code'] = location_code
dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None) dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None)
dinfo['calibre_version'] = '.'.join([unicode_type(i) for i in numeric_version]) dinfo['calibre_version'] = '.'.join([str(i) for i in numeric_version])
dinfo['date_last_connected'] = isoformat(now()) dinfo['date_last_connected'] = isoformat(now())
dinfo['mtp_prefix'] = storage.storage_prefix dinfo['mtp_prefix'] = storage.storage_prefix
raw = as_bytes(json.dumps(dinfo, default=to_json)) raw = as_bytes(json.dumps(dinfo, default=to_json))

View File

@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
import weakref, sys, json import weakref, sys, json
from collections import deque from collections import deque
from operator import attrgetter from operator import attrgetter
from polyglot.builtins import itervalues, map, unicode_type from polyglot.builtins import itervalues
from datetime import datetime from datetime import datetime
from calibre import human_readable, prints, force_unicode from calibre import human_readable, prints, force_unicode
@ -73,7 +73,7 @@ class FileOrFolder:
def __repr__(self): def __repr__(self):
name = 'Folder' if self.is_folder else 'File' name = 'Folder' if self.is_folder else 'File'
try: try:
path = unicode_type(self.full_path) path = str(self.full_path)
except: except:
path = '' path = ''
datum = 'size=%s'%(self.size) datum = 'size=%s'%(self.size)
@ -108,10 +108,8 @@ class FileOrFolder:
return tuple(parts) return tuple(parts)
def __iter__(self): def __iter__(self):
for e in self.folders: yield from self.folders
yield e yield from self.files
for e in self.files:
yield e
def add_child(self, entry): def add_child(self, entry):
ans = FileOrFolder(entry, self.fs_cache()) ans = FileOrFolder(entry, self.fs_cache())

View File

@ -12,7 +12,6 @@ from calibre.constants import iswindows, islinux
from calibre.utils.icu import lower from calibre.utils.icu import lower
from calibre.devices.mtp.driver import MTP_DEVICE from calibre.devices.mtp.driver import MTP_DEVICE
from calibre.devices.scanner import DeviceScanner from calibre.devices.scanner import DeviceScanner
from polyglot.builtins import range
class ProgressCallback: class ProgressCallback:

View File

@ -15,7 +15,6 @@ from calibre.constants import islinux, ismacos
from calibre.ptempfile import SpooledTemporaryFile from calibre.ptempfile import SpooledTemporaryFile
from calibre.devices.errors import OpenFailed, DeviceError, BlacklistedDevice, OpenActionNeeded from calibre.devices.errors import OpenFailed, DeviceError, BlacklistedDevice, OpenActionNeeded
from calibre.devices.mtp.base import MTPDeviceBase, synchronous, debug from calibre.devices.mtp.base import MTPDeviceBase, synchronous, debug
from polyglot.builtins import unicode_type
MTPDevice = namedtuple('MTPDevice', 'busnum devnum vendor_id product_id ' MTPDevice = namedtuple('MTPDevice', 'busnum devnum vendor_id product_id '
'bcd serial manufacturer product') 'bcd serial manufacturer product')
@ -76,7 +75,7 @@ class MTP_DEVICE(MTPDeviceBase):
traceback.print_stack() traceback.print_stack()
return False return False
if debug is not None and ans: if debug is not None and ans:
debug('Device {0} claims to be an MTP device in the IOKit registry'.format(d)) debug('Device {} claims to be an MTP device in the IOKit registry'.format(d))
return bool(ans) return bool(ans)
def set_debug_level(self, lvl): def set_debug_level(self, lvl):
@ -222,7 +221,7 @@ class MTP_DEVICE(MTPDeviceBase):
try: try:
storage = sorted(self.dev.storage_info, key=operator.itemgetter('id')) storage = sorted(self.dev.storage_info, key=operator.itemgetter('id'))
except self.libmtp.MTPError as e: except self.libmtp.MTPError as e:
if "The device has no storage information." in unicode_type(e): if "The device has no storage information." in str(e):
# This happens on newer Android devices while waiting for # This happens on newer Android devices while waiting for
# the user to allow access. Apparently what happens is # the user to allow access. Apparently what happens is
# that when the user clicks allow, the device disconnects # that when the user clicks allow, the device disconnects
@ -317,7 +316,7 @@ class MTP_DEVICE(MTPDeviceBase):
storage.append({'id':sid, 'size':capacity, storage.append({'id':sid, 'size':capacity,
'is_folder':True, 'name':name, 'can_delete':False, 'is_folder':True, 'name':name, 'can_delete':False,
'is_system':True}) 'is_system':True})
self._currently_getting_sid = unicode_type(sid) self._currently_getting_sid = str(sid)
items, errs = self.dev.get_filesystem(sid, items, errs = self.dev.get_filesystem(sid,
partial(self._filesystem_callback, {})) partial(self._filesystem_callback, {}))
all_items.extend(items), all_errs.extend(errs) all_items.extend(items), all_errs.extend(errs)

View File

@ -31,7 +31,7 @@ class MTPDetect:
try: try:
with lopen(x, 'rb') as f: with lopen(x, 'rb') as f:
return f.read() return f.read()
except EnvironmentError: except OSError:
pass pass
ipath = os.path.join(self.base, '{0}-*/{0}-*/interface'.format(dev.busnum)) ipath = os.path.join(self.base, '{0}-*/{0}-*/interface'.format(dev.busnum))
@ -44,7 +44,7 @@ class MTPDetect:
try: try:
if raw and int(raw) == dev.devnum: if raw and int(raw) == dev.devnum:
if debug is not None: if debug is not None:
debug('Unknown device {0} claims to be an MTP device' debug('Unknown device {} claims to be an MTP device'
.format(dev)) .format(dev))
return True return True
except (ValueError, TypeError): except (ValueError, TypeError):

View File

@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
import time, threading, traceback import time, threading, traceback
from functools import wraps, partial from functools import wraps, partial
from polyglot.builtins import iteritems, itervalues, unicode_type, zip from polyglot.builtins import iteritems, itervalues
from itertools import chain from itertools import chain
from calibre import as_unicode, prints, force_unicode from calibre import as_unicode, prints, force_unicode
@ -268,7 +268,7 @@ class MTP_DEVICE(MTPDeviceBase):
break break
storage = {'id':storage_id, 'size':capacity, 'name':name, storage = {'id':storage_id, 'size':capacity, 'name':name,
'is_folder':True, 'can_delete':False, 'is_system':True} 'is_folder':True, 'can_delete':False, 'is_system':True}
self._currently_getting_sid = unicode_type(storage_id) self._currently_getting_sid = str(storage_id)
id_map = self.dev.get_filesystem(storage_id, partial( id_map = self.dev.get_filesystem(storage_id, partial(
self._filesystem_callback, {})) self._filesystem_callback, {}))
for x in itervalues(id_map): for x in itervalues(id_map):

View File

@ -111,7 +111,7 @@ class NOOK_COLOR(NOOK):
self.EBOOK_DIR_MAIN = 'NOOK/My Files' self.EBOOK_DIR_MAIN = 'NOOK/My Files'
try: try:
os.makedirs(os.path.join(self._main_prefix, *self.EBOOK_DIR_MAIN.split('/'))) os.makedirs(os.path.join(self._main_prefix, *self.EBOOK_DIR_MAIN.split('/')))
except EnvironmentError as err: except OSError as err:
if err.errno != errno.EEXIST: if err.errno != errno.EEXIST:
self.EBOOK_DIR_MAIN = 'NOOK' self.EBOOK_DIR_MAIN = 'NOOK'

View File

@ -1 +0,0 @@

View File

@ -110,7 +110,7 @@ class PALADIN(USBMS):
for i, row in enumerate(cursor): for i, row in enumerate(cursor):
try: try:
comp_date = int(os.path.getmtime(self.normalize_path(prefix + row[0])) * 1000) comp_date = int(os.path.getmtime(self.normalize_path(prefix + row[0])) * 1000)
except (OSError, IOError, TypeError): except (OSError, TypeError):
# In case the db has incorrect path info # In case the db has incorrect path info
continue continue
device_date = int(row[1]) device_date = int(row[1])

View File

@ -1,5 +1,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'

View File

@ -1,5 +1,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@ -17,7 +17,6 @@ from calibre.ebooks.chardet import xml_to_unicode
from calibre.ebooks.metadata import authors_to_string, title_sort, \ from calibre.ebooks.metadata import authors_to_string, title_sort, \
authors_to_sort_string authors_to_sort_string
from polyglot.binary import from_base64_bytes from polyglot.binary import from_base64_bytes
from polyglot.builtins import unicode_type, zip
''' '''
cacheExt.xml cacheExt.xml
@ -66,8 +65,8 @@ INVERSE_MONTH_MAP = dict(zip(MONTH_MAP.values(), MONTH_MAP.keys()))
def strptime(src): def strptime(src):
src = src.strip() src = src.strip()
src = src.split() src = src.split()
src[0] = unicode_type(DAY_MAP[src[0][:-1]])+',' src[0] = str(DAY_MAP[src[0][:-1]])+','
src[2] = unicode_type(MONTH_MAP[src[2]]) src[2] = str(MONTH_MAP[src[2]])
return time.strptime(' '.join(src), '%w, %d %m %Y %H:%M:%S %Z') return time.strptime(' '.join(src), '%w, %d %m %Y %H:%M:%S %Z')
@ -84,7 +83,7 @@ def strftime(epoch, zone=time.localtime):
def uuid(): def uuid():
from uuid import uuid4 from uuid import uuid4
return unicode_type(uuid4()).replace('-', '', 1).upper() return str(uuid4()).replace('-', '', 1).upper()
# }}} # }}}
@ -197,8 +196,8 @@ class XMLCache:
playlist.set('title', title) playlist.set('title', title)
if title in seen: if title in seen:
for i in range(2, 1000): for i in range(2, 1000):
if title+unicode_type(i) not in seen: if title+str(i) not in seen:
title = title+unicode_type(i) title = title+str(i)
playlist.set('title', title) playlist.set('title', title)
seen.add(title) seen.add(title)
break break
@ -271,7 +270,7 @@ class XMLCache:
nsmap=root.nsmap, attrib={ nsmap=root.nsmap, attrib={
'uuid' : uuid(), 'uuid' : uuid(),
'title': title, 'title': title,
'id' : unicode_type(self.max_id(root)+1), 'id' : str(self.max_id(root)+1),
'sourceid': '1' 'sourceid': '1'
}) })
root.append(ans) root.append(ans)
@ -310,13 +309,13 @@ class XMLCache:
def ensure_media_xml_base_ids(root): def ensure_media_xml_base_ids(root):
for num, tag in enumerate(('library', 'watchSpecial')): for num, tag in enumerate(('library', 'watchSpecial')):
for x in root.xpath('//*[local-name()="%s"]'%tag): for x in root.xpath('//*[local-name()="%s"]'%tag):
x.set('id', unicode_type(num)) x.set('id', str(num))
def rebase_ids(root, base, sourceid, pl_sourceid): def rebase_ids(root, base, sourceid, pl_sourceid):
'Rebase all ids and also make them consecutive' 'Rebase all ids and also make them consecutive'
for item in root.xpath('//*[@sourceid]'): for item in root.xpath('//*[@sourceid]'):
sid = pl_sourceid if item.tag.endswith('playlist') else sourceid sid = pl_sourceid if item.tag.endswith('playlist') else sourceid
item.set('sourceid', unicode_type(sid)) item.set('sourceid', str(sid))
# Only rebase ids of nodes that are immediate children of the # Only rebase ids of nodes that are immediate children of the
# record root (that way playlist/itemnodes are unaffected # record root (that way playlist/itemnodes are unaffected
items = root.xpath('child::*[@id]') items = root.xpath('child::*[@id]')
@ -326,8 +325,8 @@ class XMLCache:
old = int(item.get('id')) old = int(item.get('id'))
new = base + i new = base + i
if old != new: if old != new:
item.set('id', unicode_type(new)) item.set('id', str(new))
idmap[unicode_type(old)] = unicode_type(new) idmap[str(old)] = str(new)
return idmap return idmap
self.prune_empty_playlists() self.prune_empty_playlists()
@ -356,7 +355,7 @@ class XMLCache:
last_bl = max(self.roots.keys()) last_bl = max(self.roots.keys())
max_id = self.max_id(self.roots[last_bl]) max_id = self.max_id(self.roots[last_bl])
self.roots[0].set('nextID', unicode_type(max_id+1)) self.roots[0].set('nextID', str(max_id+1))
debug_print('Finished running fix_ids()') debug_print('Finished running fix_ids()')
# }}} # }}}
@ -513,7 +512,7 @@ class XMLCache:
# Ensure each book has an ID. # Ensure each book has an ID.
for rec in records: for rec in records:
if rec.get('id', None) is None: if rec.get('id', None) is None:
rec.set('id', unicode_type(self.max_id(root)+1)) rec.set('id', str(self.max_id(root)+1))
ids = [x.get('id', None) for x in records] ids = [x.get('id', None) for x in records]
# Given that we set the ids, there shouldn't be any None's. But # Given that we set the ids, there shouldn't be any None's. But
# better to be safe... # better to be safe...
@ -570,7 +569,7 @@ class XMLCache:
id_ = self.max_id(root)+1 id_ = self.max_id(root)+1
attrib = { attrib = {
'page':'0', 'part':'0','pageOffset':'0','scale':'0', 'page':'0', 'part':'0','pageOffset':'0','scale':'0',
'id':unicode_type(id_), 'sourceid':'1', 'path':lpath} 'id':str(id_), 'sourceid':'1', 'path':lpath}
ans = root.makeelement('{%s}text'%namespace, attrib=attrib, nsmap=root.nsmap) ans = root.makeelement('{%s}text'%namespace, attrib=attrib, nsmap=root.nsmap)
root.append(ans) root.append(ans)
return ans return ans
@ -589,7 +588,7 @@ class XMLCache:
if thumbnail and thumbnail[-1]: if thumbnail and thumbnail[-1]:
ans.text = '\n' + '\t\t' ans.text = '\n' + '\t\t'
t = root.makeelement('{%s}thumbnail'%namespace, t = root.makeelement('{%s}thumbnail'%namespace,
attrib={'width':unicode_type(thumbnail[0]), 'height':unicode_type(thumbnail[1])}, attrib={'width':str(thumbnail[0]), 'height':str(thumbnail[1])},
nsmap=root.nsmap) nsmap=root.nsmap)
t.text = 'main_thumbnail.jpg' t.text = 'main_thumbnail.jpg'
ans.append(t) ans.append(t)
@ -658,7 +657,7 @@ class XMLCache:
date = strftime(timestamp, zone=tz) date = strftime(timestamp, zone=tz)
record.set('date', clean(date)) record.set('date', clean(date))
try: try:
record.set('size', clean(unicode_type(os.stat(path).st_size))) record.set('size', clean(str(os.stat(path).st_size)))
except: except:
record.set('size', '0') record.set('size', '0')
title = book.title if book.title else _('Unknown') title = book.title if book.title else _('Unknown')
@ -688,7 +687,7 @@ class XMLCache:
record.set('sourceid', '1') record.set('sourceid', '1')
if 'id' not in record.attrib: if 'id' not in record.attrib:
num = self.max_id(record.getroottree().getroot()) num = self.max_id(record.getroottree().getroot())
record.set('id', unicode_type(num+1)) record.set('id', str(num+1))
return (gtz_count, ltz_count, use_tz_var) return (gtz_count, ltz_count, use_tz_var)
# }}} # }}}
@ -759,7 +758,7 @@ class XMLCache:
return m return m
def book_by_lpath(self, lpath, root): def book_by_lpath(self, lpath, root):
matches = root.xpath(u'//*[local-name()="text" and @path="%s"]'%lpath) matches = root.xpath('//*[local-name()="text" and @path="%s"]'%lpath)
if matches: if matches:
return matches[0] return matches[0]

View File

@ -23,7 +23,7 @@ from calibre.devices.usbms.books import CollectionsBookList
from calibre.devices.usbms.books import BookList from calibre.devices.usbms.books import BookList
from calibre.ebooks.metadata import authors_to_sort_string, authors_to_string from calibre.ebooks.metadata import authors_to_sort_string, authors_to_string
from calibre.constants import islinux from calibre.constants import islinux
from polyglot.builtins import unicode_type, long_type from polyglot.builtins import long_type
DBPATH = 'Sony_Reader/database/books.db' DBPATH = 'Sony_Reader/database/books.db'
THUMBPATH = 'Sony_Reader/database/cache/books/%s/thumbnail/main_thumbnail.jpg' THUMBPATH = 'Sony_Reader/database/cache/books/%s/thumbnail/main_thumbnail.jpg'
@ -170,7 +170,7 @@ class PRST1(USBMS):
with closing(sqlite.connect(dbpath)) as connection: with closing(sqlite.connect(dbpath)) as connection:
# Replace undecodable characters in the db instead of erroring out # Replace undecodable characters in the db instead of erroring out
connection.text_factory = lambda x: x if isinstance(x, unicode_type) else x.decode('utf-8', 'replace') connection.text_factory = lambda x: x if isinstance(x, str) else x.decode('utf-8', 'replace')
cursor = connection.cursor() cursor = connection.cursor()
# Query collections # Query collections
@ -199,7 +199,7 @@ class PRST1(USBMS):
for i, row in enumerate(cursor): for i, row in enumerate(cursor):
try: try:
comp_date = int(os.path.getmtime(self.normalize_path(prefix + row[0])) * 1000) comp_date = int(os.path.getmtime(self.normalize_path(prefix + row[0])) * 1000)
except (OSError, IOError, TypeError): except (OSError, TypeError):
# In case the db has incorrect path info # In case the db has incorrect path info
continue continue
device_date = int(row[1]) device_date = int(row[1])

View File

@ -1,4 +1,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
''' '''
@ -13,7 +12,6 @@ from threading import Lock
from calibre import prints, as_unicode from calibre import prints, as_unicode
from calibre.constants import (iswindows, ismacos, islinux, isfreebsd, from calibre.constants import (iswindows, ismacos, islinux, isfreebsd,
isnetbsd) isnetbsd)
from polyglot.builtins import range
osx_scanner = linux_scanner = freebsd_scanner = netbsd_scanner = None osx_scanner = linux_scanner = freebsd_scanner = netbsd_scanner = None
@ -41,12 +39,12 @@ _USBDevice = namedtuple('USBDevice',
class USBDevice(_USBDevice): class USBDevice(_USBDevice):
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
self = super(USBDevice, cls).__new__(cls, *args) self = super().__new__(cls, *args)
self.busnum = self.devnum = -1 self.busnum = self.devnum = -1
return self return self
def __repr__(self): def __repr__(self):
return (u'USBDevice(busnum=%s, devnum=%s, ' return ('USBDevice(busnum=%s, devnum=%s, '
'vendor_id=0x%04x, product_id=0x%04x, bcd=0x%04x, ' 'vendor_id=0x%04x, product_id=0x%04x, bcd=0x%04x, '
'manufacturer=%s, product=%s, serial=%s)')%( 'manufacturer=%s, product=%s, serial=%s)')%(
self.busnum, self.devnum, self.vendor_id, self.product_id, self.busnum, self.devnum, self.vendor_id, self.product_id,
@ -142,15 +140,15 @@ class LinuxScanner:
try: try:
dev.append(read(man).decode('utf-8')) dev.append(read(man).decode('utf-8'))
except Exception: except Exception:
dev.append(u'') dev.append('')
try: try:
dev.append(read(prod_string).decode('utf-8')) dev.append(read(prod_string).decode('utf-8'))
except Exception: except Exception:
dev.append(u'') dev.append('')
try: try:
dev.append(read(serial).decode('utf-8')) dev.append(read(serial).decode('utf-8'))
except Exception: except Exception:
dev.append(u'') dev.append('')
dev = USBDevice(*dev) dev = USBDevice(*dev)
try: try:

View File

@ -47,7 +47,7 @@ from calibre.utils.mdns import (
) )
from calibre.utils.socket_inheritance import set_socket_inherit from calibre.utils.socket_inheritance import set_socket_inherit
from polyglot import queue from polyglot import queue
from polyglot.builtins import as_bytes, iteritems, itervalues, unicode_type from polyglot.builtins import as_bytes, iteritems, itervalues
def synchronous(tlockname): def synchronous(tlockname):
@ -125,13 +125,13 @@ class ConnectionListener(Thread):
content_server_port = '' content_server_port = ''
try: try:
from calibre.srv.opts import server_config from calibre.srv.opts import server_config
content_server_port = unicode_type(server_config().port) content_server_port = str(server_config().port)
except Exception: except Exception:
pass pass
message = (self.driver.ZEROCONF_CLIENT_STRING + ' (on ' + message = (self.driver.ZEROCONF_CLIENT_STRING + ' (on ' +
unicode_type(socket.gethostname().partition('.')[0]) + str(socket.gethostname().partition('.')[0]) +
');' + content_server_port + ');' + content_server_port +
',' + unicode_type(self.driver.port)).encode('utf-8') ',' + str(self.driver.port)).encode('utf-8')
self.driver._debug('received broadcast', packet, message) self.driver._debug('received broadcast', packet, message)
self.driver.broadcast_socket.sendto(message, remote) self.driver.broadcast_socket.sendto(message, remote)
except: except:
@ -164,7 +164,7 @@ class ConnectionListener(Thread):
except socket.timeout: except socket.timeout:
pass pass
except socket.error: except OSError:
x = sys.exc_info()[1] x = sys.exc_info()[1]
self.driver._debug('unexpected socket exception', x.args[0]) self.driver._debug('unexpected socket exception', x.args[0])
self._close_socket(device_socket) self._close_socket(device_socket)
@ -414,7 +414,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
if isinstance(a, dict): if isinstance(a, dict):
printable = {} printable = {}
for k,v in iteritems(a): for k,v in iteritems(a):
if isinstance(v, (bytes, unicode_type)) and len(v) > 50: if isinstance(v, (bytes, str)) and len(v) > 50:
printable[k] = 'too long' printable[k] = 'too long'
else: else:
printable[k] = v printable[k] = v
@ -436,14 +436,14 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
if not isinstance(dinfo, dict): if not isinstance(dinfo, dict):
dinfo = {} dinfo = {}
if dinfo.get('device_store_uuid', None) is None: if dinfo.get('device_store_uuid', None) is None:
dinfo['device_store_uuid'] = unicode_type(uuid.uuid4()) dinfo['device_store_uuid'] = str(uuid.uuid4())
if dinfo.get('device_name') is None: if dinfo.get('device_name') is None:
dinfo['device_name'] = self.get_gui_name() dinfo['device_name'] = self.get_gui_name()
if name is not None: if name is not None:
dinfo['device_name'] = name dinfo['device_name'] = name
dinfo['location_code'] = location_code dinfo['location_code'] = location_code
dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None) dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None)
dinfo['calibre_version'] = '.'.join([unicode_type(i) for i in numeric_version]) dinfo['calibre_version'] = '.'.join([str(i) for i in numeric_version])
dinfo['date_last_connected'] = isoformat(now()) dinfo['date_last_connected'] = isoformat(now())
dinfo['prefix'] = self.PREFIX dinfo['prefix'] = self.PREFIX
return dinfo return dinfo
@ -495,9 +495,9 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
from calibre.library.save_to_disk import config, get_components from calibre.library.save_to_disk import config, get_components
opts = config().parse() opts = config().parse()
if not isinstance(template, unicode_type): if not isinstance(template, str):
template = template.decode('utf-8') template = template.decode('utf-8')
app_id = unicode_type(getattr(mdata, 'application_id', '')) app_id = str(getattr(mdata, 'application_id', ''))
id_ = mdata.get('id', fname) id_ = mdata.get('id', fname)
extra_components = get_components(template, mdata, id_, extra_components = get_components(template, mdata, id_,
timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1, timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1,
@ -623,9 +623,9 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
amt_sent = sock.send(s[sent_len:]) amt_sent = sock.send(s[sent_len:])
sock.settimeout(None) sock.settimeout(None)
if amt_sent <= 0: if amt_sent <= 0:
raise IOError('Bad write on socket') raise OSError('Bad write on socket')
sent_len += amt_sent sent_len += amt_sent
except socket.error as e: except OSError as e:
self._debug('socket error', e, e.errno) self._debug('socket error', e, e.errno)
if e.args[0] != EAGAIN and e.args[0] != EINTR: if e.args[0] != EAGAIN and e.args[0] != EINTR:
self._close_device_socket() self._close_device_socket()
@ -661,7 +661,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
self._debug('timeout communicating with device') self._debug('timeout communicating with device')
self._close_device_socket() self._close_device_socket()
raise TimeoutError('Device did not respond in reasonable time') raise TimeoutError('Device did not respond in reasonable time')
except socket.error: except OSError:
self._debug('device went away') self._debug('device went away')
self._close_device_socket() self._close_device_socket()
raise ControlError(desc='Device closed the network connection') raise ControlError(desc='Device closed the network connection')
@ -689,7 +689,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
self._debug('timeout communicating with device') self._debug('timeout communicating with device')
self._close_device_socket() self._close_device_socket()
raise TimeoutError('Device did not respond in reasonable time') raise TimeoutError('Device did not respond in reasonable time')
except socket.error: except OSError:
self._debug('device went away') self._debug('device went away')
self._close_device_socket() self._close_device_socket()
raise ControlError(desc='Device closed the network connection') raise ControlError(desc='Device closed the network connection')
@ -747,7 +747,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
from calibre.utils.date import now, parse_date from calibre.utils.date import now, parse_date
try: try:
key = self._make_metadata_cache_key(uuid, ext_or_lpath) key = self._make_metadata_cache_key(uuid, ext_or_lpath)
if isinstance(lastmod, unicode_type): if isinstance(lastmod, str):
if lastmod == 'None': if lastmod == 'None':
return None return None
lastmod = parse_date(lastmod) lastmod = parse_date(lastmod)
@ -936,7 +936,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
sock.bind((ip_addr, port)) sock.bind((ip_addr, port))
else: else:
sock.bind(('', port)) sock.bind(('', port))
except socket.error: except OSError:
self._debug('socket error on port', port) self._debug('socket error on port', port)
port = 0 port = 0
except: except:
@ -1213,7 +1213,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
return True return True
except socket.timeout: except socket.timeout:
self._close_device_socket() self._close_device_socket()
except socket.error: except OSError:
x = sys.exc_info()[1] x = sys.exc_info()[1]
self._debug('unexpected socket exception', x.args[0]) self._debug('unexpected socket exception', x.args[0])
self._close_device_socket() self._close_device_socket()
@ -1909,7 +1909,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
'between 50 and 99. Forced to be %d.')%self.DEFAULT_THUMBNAIL_COMPRESSION_QUALITY 'between 50 and 99. Forced to be %d.')%self.DEFAULT_THUMBNAIL_COMPRESSION_QUALITY
self._debug(message) self._debug(message)
self.set_option('thumbnail_compression_quality', self.set_option('thumbnail_compression_quality',
unicode_type(self.DEFAULT_THUMBNAIL_COMPRESSION_QUALITY)) str(self.DEFAULT_THUMBNAIL_COMPRESSION_QUALITY))
try: try:
self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

View File

@ -1,5 +1,3 @@
__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

@ -54,7 +54,7 @@ class CLI:
with dest: with dest:
try: try:
shutil.copyfileobj(infile, dest) shutil.copyfileobj(infile, dest)
except IOError: except OSError:
print('WARNING: First attempt to send file to device failed') print('WARNING: First attempt to send file to device failed')
time.sleep(0.2) time.sleep(0.2)
infile.seek(0) infile.seek(0)

View File

@ -27,7 +27,7 @@ from calibre.devices.errors import DeviceError
from calibre.devices.interface import DevicePlugin from calibre.devices.interface import DevicePlugin
from calibre.devices.usbms.deviceconfig import DeviceConfig from calibre.devices.usbms.deviceconfig import DeviceConfig
from calibre.utils.filenames import ascii_filename as sanitize from calibre.utils.filenames import ascii_filename as sanitize
from polyglot.builtins import iteritems, map, string_or_bytes from polyglot.builtins import iteritems, string_or_bytes
if ismacos: if ismacos:
osx_sanitize_name_pat = re.compile(r'[.-]') osx_sanitize_name_pat = re.compile(r'[.-]')
@ -296,7 +296,7 @@ class Device(DeviceConfig, DevicePlugin):
try: try:
return subprocess.Popen(cmd, return subprocess.Popen(cmd,
stdout=subprocess.PIPE).communicate()[0] stdout=subprocess.PIPE).communicate()[0]
except IOError: # Probably an interrupted system call except OSError: # Probably an interrupted system call
if i == 2: if i == 2:
raise raise
time.sleep(2) time.sleep(2)
@ -310,7 +310,7 @@ class Device(DeviceConfig, DevicePlugin):
try: try:
return subprocess.Popen('mount', return subprocess.Popen('mount',
stdout=subprocess.PIPE).communicate()[0] stdout=subprocess.PIPE).communicate()[0]
except IOError: # Probably an interrupted system call except OSError: # Probably an interrupted system call
if i == 2: if i == 2:
raise raise
time.sleep(2) time.sleep(2)
@ -440,8 +440,7 @@ class Device(DeviceConfig, DevicePlugin):
isfile = os.path.isfile(p) isfile = os.path.isfile(p)
yield p, isfile yield p, isfile
if not isfile: if not isfile:
for y, q in walk(p): yield from walk(p)
yield y, q
def raw2num(raw): def raw2num(raw):
raw = raw.lower() raw = raw.lower()

View File

@ -6,7 +6,6 @@ __copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
from calibre.utils.config_base import Config, ConfigProxy from calibre.utils.config_base import Config, ConfigProxy
from polyglot.builtins import unicode_type
class DeviceConfig: class DeviceConfig:
@ -109,15 +108,15 @@ class DeviceConfig:
if hasattr(config_widget.opt_extra_customization[i], 'isChecked'): if hasattr(config_widget.opt_extra_customization[i], 'isChecked'):
ec.append(config_widget.opt_extra_customization[i].isChecked()) ec.append(config_widget.opt_extra_customization[i].isChecked())
elif hasattr(config_widget.opt_extra_customization[i], 'currentText'): elif hasattr(config_widget.opt_extra_customization[i], 'currentText'):
ec.append(unicode_type(config_widget.opt_extra_customization[i].currentText()).strip()) ec.append(str(config_widget.opt_extra_customization[i].currentText()).strip())
else: else:
ec.append(unicode_type(config_widget.opt_extra_customization[i].text()).strip()) ec.append(str(config_widget.opt_extra_customization[i].text()).strip())
else: else:
ec = unicode_type(config_widget.opt_extra_customization.text()).strip() ec = str(config_widget.opt_extra_customization.text()).strip()
if not ec: if not ec:
ec = None ec = None
proxy['extra_customization'] = ec proxy['extra_customization'] = ec
st = unicode_type(config_widget.opt_save_template.text()) st = str(config_widget.opt_save_template.text())
proxy['save_template'] = st proxy['save_template'] = st
@classmethod @classmethod

View File

@ -21,7 +21,7 @@ from calibre.devices.usbms.cli import CLI
from calibre.devices.usbms.device import Device from calibre.devices.usbms.device import Device
from calibre.devices.usbms.books import BookList, Book from calibre.devices.usbms.books import BookList, Book
from calibre.ebooks.metadata.book.json_codec import JsonCodec from calibre.ebooks.metadata.book.json_codec import JsonCodec
from polyglot.builtins import itervalues, unicode_type, string_or_bytes, zip from polyglot.builtins import itervalues, string_or_bytes
def debug_print(*args, **kw): def debug_print(*args, **kw):
@ -68,8 +68,7 @@ def safe_walk(top, topdown=True, onerror=None, followlinks=False, maxdepth=128):
for name in dirs: for name in dirs:
new_path = join(top, name) new_path = join(top, name)
if followlinks or not islink(new_path): if followlinks or not islink(new_path):
for x in safe_walk(new_path, topdown, onerror, followlinks, maxdepth-1): yield from safe_walk(new_path, topdown, onerror, followlinks, maxdepth-1)
yield x
if not topdown: if not topdown:
yield top, dirs, nondirs yield top, dirs, nondirs
@ -107,14 +106,14 @@ class USBMS(CLI, Device):
if not isinstance(dinfo, dict): if not isinstance(dinfo, dict):
dinfo = {} dinfo = {}
if dinfo.get('device_store_uuid', None) is None: if dinfo.get('device_store_uuid', None) is None:
dinfo['device_store_uuid'] = unicode_type(uuid.uuid4()) dinfo['device_store_uuid'] = str(uuid.uuid4())
if dinfo.get('device_name', None) is None: if dinfo.get('device_name', None) is None:
dinfo['device_name'] = self.get_gui_name() dinfo['device_name'] = self.get_gui_name()
if name is not None: if name is not None:
dinfo['device_name'] = name dinfo['device_name'] = name
dinfo['location_code'] = location_code dinfo['location_code'] = location_code
dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None) dinfo['last_library_uuid'] = getattr(self, 'current_library_uuid', None)
dinfo['calibre_version'] = '.'.join([unicode_type(i) for i in numeric_version]) dinfo['calibre_version'] = '.'.join([str(i) for i in numeric_version])
dinfo['date_last_connected'] = isoformat(now()) dinfo['date_last_connected'] = isoformat(now())
dinfo['prefix'] = prefix.replace('\\', '/') dinfo['prefix'] = prefix.replace('\\', '/')
return dinfo return dinfo
@ -151,8 +150,8 @@ class USBMS(CLI, Device):
if self._main_prefix is not None: if self._main_prefix is not None:
try: try:
self.driveinfo['main'] = self._update_driveinfo_file(self._main_prefix, 'main') self.driveinfo['main'] = self._update_driveinfo_file(self._main_prefix, 'main')
except (IOError, OSError) as e: except OSError as e:
raise IOError(_('Failed to access files in the main memory of' raise OSError(_('Failed to access files in the main memory of'
' your device. You should contact the device' ' your device. You should contact the device'
' manufacturer for support. Common fixes are:' ' manufacturer for support. Common fixes are:'
' try a different USB cable/USB port on your computer.' ' try a different USB cable/USB port on your computer.'
@ -164,8 +163,8 @@ class USBMS(CLI, Device):
self.driveinfo['A'] = self._update_driveinfo_file(self._card_a_prefix, 'A') self.driveinfo['A'] = self._update_driveinfo_file(self._card_a_prefix, 'A')
if self._card_b_prefix is not None: if self._card_b_prefix is not None:
self.driveinfo['B'] = self._update_driveinfo_file(self._card_b_prefix, 'B') self.driveinfo['B'] = self._update_driveinfo_file(self._card_b_prefix, 'B')
except (IOError, OSError) as e: except OSError as e:
raise IOError(_('Failed to access files on the SD card in your' raise OSError(_('Failed to access files on the SD card in your'
' device. This can happen for many reasons. The SD card may be' ' device. This can happen for many reasons. The SD card may be'
' corrupted, it may be too large for your device, it may be' ' corrupted, it may be too large for your device, it may be'
' write-protected, etc. Try a different SD card, or reformat' ' write-protected, etc. Try a different SD card, or reformat'

View File

@ -10,7 +10,6 @@ import os, time, re
from functools import partial from functools import partial
from calibre.devices.errors import DeviceError, WrongDestinationError, FreeSpaceError from calibre.devices.errors import DeviceError, WrongDestinationError, FreeSpaceError
from polyglot.builtins import unicode_type
def sanity_check(on_card, files, card_prefixes, free_space): def sanity_check(on_card, files, card_prefixes, free_space):
@ -60,8 +59,8 @@ def build_template_regexp(template):
template = template.rpartition('/')[2] template = template.rpartition('/')[2]
return re.compile(re.sub('{([^}]*)}', f, template) + r'([_\d]*$)') return re.compile(re.sub('{([^}]*)}', f, template) + r'([_\d]*$)')
except: except:
prints(u'Failed to parse template: %r'%template) prints('Failed to parse template: %r'%template)
template = u'{title} - {authors}' template = '{title} - {authors}'
return re.compile(re.sub('{([^}]*)}', f, template) + r'([_\d]*$)') return re.compile(re.sub('{([^}]*)}', f, template) + r'([_\d]*$)')
@ -91,15 +90,15 @@ def create_upload_path(mdata, fname, template, sanitize,
except: except:
today = time.localtime() today = time.localtime()
date = (today[0], today[1], today[2]) date = (today[0], today[1], today[2])
template = u"{title}_%d-%d-%d" % date template = "{title}_%d-%d-%d" % date
fname = sanitize(fname) fname = sanitize(fname)
ext = path_type.splitext(fname)[1] ext = path_type.splitext(fname)[1]
opts = config().parse() opts = config().parse()
if not isinstance(template, unicode_type): if not isinstance(template, str):
template = template.decode('utf-8') template = template.decode('utf-8')
app_id = unicode_type(getattr(mdata, 'application_id', '')) app_id = str(getattr(mdata, 'application_id', ''))
id_ = mdata.get('id', fname) id_ = mdata.get('id', fname)
extra_components = get_components(template, mdata, id_, extra_components = get_components(template, mdata, id_,
timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1, timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1,

View File

@ -13,7 +13,7 @@ from ctypes import (
) )
from ctypes.wintypes import DWORD, WORD, ULONG, LPCWSTR, HWND, BOOL, LPWSTR, UINT, BYTE, HANDLE, USHORT from ctypes.wintypes import DWORD, WORD, ULONG, LPCWSTR, HWND, BOOL, LPWSTR, UINT, BYTE, HANDLE, USHORT
from pprint import pprint, pformat from pprint import pprint, pformat
from polyglot.builtins import iteritems, itervalues, map, filter from polyglot.builtins import iteritems, itervalues
from calibre import prints, as_unicode from calibre import prints, as_unicode
@ -507,8 +507,7 @@ def iterchildren(parent_devinst):
def iterdescendants(parent_devinst): def iterdescendants(parent_devinst):
for child in iterchildren(parent_devinst): for child in iterchildren(parent_devinst):
yield child yield child
for gc in iterdescendants(child): yield from iterdescendants(child)
yield gc
def iterancestors(devinst): def iterancestors(devinst):

View File

@ -9,13 +9,12 @@ from bs4 import ( # noqa
SoupStrainer, Tag, __version__ SoupStrainer, Tag, __version__
) )
from polyglot.builtins import unicode_type
def parse_html(markup): def parse_html(markup):
from calibre.ebooks.chardet import strip_encoding_declarations, xml_to_unicode, substitute_entites from calibre.ebooks.chardet import strip_encoding_declarations, xml_to_unicode, substitute_entites
from calibre.utils.cleantext import clean_xml_chars from calibre.utils.cleantext import clean_xml_chars
if isinstance(markup, unicode_type): if isinstance(markup, str):
markup = strip_encoding_declarations(markup) markup = strip_encoding_declarations(markup)
markup = substitute_entites(markup) markup = substitute_entites(markup)
else: else:

View File

@ -1,5 +1,3 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
@ -11,7 +9,6 @@ from various formats.
import os, re, numbers, sys import os, re, numbers, sys
from calibre import prints from calibre import prints
from calibre.ebooks.chardet import xml_to_unicode from calibre.ebooks.chardet import xml_to_unicode
from polyglot.builtins import unicode_type
class ConversionError(Exception): class ConversionError(Exception):
@ -82,7 +79,7 @@ def extract_calibre_cover(raw, base, log):
if matches is None: if matches is None:
body = soup.find('body') body = soup.find('body')
if body is not None: if body is not None:
text = u''.join(map(unicode_type, body.findAll(text=True))) text = ''.join(map(str, body.findAll(text=True)))
if text.strip(): if text.strip():
# Body has text, abort # Body has text, abort
return return
@ -152,7 +149,7 @@ def check_ebook_format(stream, current_guess):
def normalize(x): def normalize(x):
if isinstance(x, unicode_type): if isinstance(x, str):
import unicodedata import unicodedata
x = unicodedata.normalize('NFC', x) x = unicodedata.normalize('NFC', x)
return x return x

View File

@ -16,7 +16,6 @@ import os
import re import re
from calibre.ebooks.pdb.formatreader import FormatReader from calibre.ebooks.pdb.formatreader import FormatReader
from polyglot.builtins import getcwd
def unwrap(stream, output_path): def unwrap(stream, output_path):
@ -46,7 +45,7 @@ class Reader(FormatReader):
if mo: if mo:
data = mo.group() data = mo.group()
pdf_n = os.path.join(getcwd(), 'tmp.pdf') pdf_n = os.path.join(os.getcwd(), 'tmp.pdf')
with open(pdf_n, 'wb') as pdf: with open(pdf_n, 'wb') as pdf:
pdf.write(data) pdf.write(data)
from calibre.customize.ui import plugin_for_input_format from calibre.customize.ui import plugin_for_input_format

View File

@ -7,7 +7,6 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import re, codecs, sys import re, codecs, sys
from polyglot.builtins import unicode_type
_encoding_pats = ( _encoding_pats = (
# XML declaration # XML declaration
@ -34,8 +33,7 @@ class LazyEncodingPats:
if pats is None: if pats is None:
pats = tuple(compile_pats(binary)) pats = tuple(compile_pats(binary))
setattr(self, attr, pats) setattr(self, attr, pats)
for pat in pats: yield from pats
yield pat
lazy_encoding_pats = LazyEncodingPats() lazy_encoding_pats = LazyEncodingPats()
@ -52,7 +50,7 @@ def strip_encoding_declarations(raw, limit=50*1024, preserve_newlines=False):
else: else:
sub = lambda m: '\n' * m.group().count('\n') sub = lambda m: '\n' * m.group().count('\n')
else: else:
sub = b'' if is_binary else u'' sub = b'' if is_binary else ''
for pat in lazy_encoding_pats(is_binary): for pat in lazy_encoding_pats(is_binary):
prefix = pat.sub(sub, prefix) prefix = pat.sub(sub, prefix)
raw = prefix + suffix raw = prefix + suffix
@ -140,7 +138,7 @@ def force_encoding(raw, verbose, assume_utf8=False):
def detect_xml_encoding(raw, verbose=False, assume_utf8=False): def detect_xml_encoding(raw, verbose=False, assume_utf8=False):
if not raw or isinstance(raw, unicode_type): if not raw or isinstance(raw, str):
return raw, None return raw, None
for x in ('utf8', 'utf-16-le', 'utf-16-be'): for x in ('utf8', 'utf-16-le', 'utf-16-be'):
bom = getattr(codecs, 'BOM_'+x.upper().replace('-16', '16').replace( bom = getattr(codecs, 'BOM_'+x.upper().replace('-16', '16').replace(
@ -184,7 +182,7 @@ def xml_to_unicode(raw, verbose=False, strip_encoding_pats=False,
return '', None return '', None
raw, encoding = detect_xml_encoding(raw, verbose=verbose, raw, encoding = detect_xml_encoding(raw, verbose=verbose,
assume_utf8=assume_utf8) assume_utf8=assume_utf8)
if not isinstance(raw, unicode_type): if not isinstance(raw, str):
raw = raw.decode(encoding, 'replace') raw = raw.decode(encoding, 'replace')
if strip_encoding_pats: if strip_encoding_pats:

View File

@ -13,7 +13,7 @@ from calibre.ebooks.BeautifulSoup import BeautifulSoup, NavigableString
from calibre.ebooks.chardet import xml_to_unicode from calibre.ebooks.chardet import xml_to_unicode
from calibre.ebooks.metadata.toc import TOC from calibre.ebooks.metadata.toc import TOC
from chm.chm import CHMFile, chmlib from chm.chm import CHMFile, chmlib
from polyglot.builtins import as_unicode, getcwd, unicode_type from polyglot.builtins import as_unicode
def match_string(s1, s2_already_lowered): def match_string(s1, s2_already_lowered):
@ -43,7 +43,7 @@ class CHMReader(CHMFile):
def __init__(self, input, log, input_encoding=None): def __init__(self, input, log, input_encoding=None):
CHMFile.__init__(self) CHMFile.__init__(self)
if isinstance(input, unicode_type): if isinstance(input, str):
enc = 'mbcs' if iswindows else filesystem_encoding enc = 'mbcs' if iswindows else filesystem_encoding
try: try:
input = input.encode(enc) input = input.encode(enc)
@ -113,7 +113,7 @@ class CHMReader(CHMFile):
def get_encoding(self): def get_encoding(self):
return self.encoding_from_system_file or self.encoding_from_lcid or 'cp1252' return self.encoding_from_system_file or self.encoding_from_lcid or 'cp1252'
def _parse_toc(self, ul, basedir=getcwd()): def _parse_toc(self, ul, basedir=os.getcwd()):
toc = TOC(play_order=self._playorder, base_path=basedir, text='') toc = TOC(play_order=self._playorder, base_path=basedir, text='')
self._playorder += 1 self._playorder += 1
for li in ul('li', recursive=False): for li in ul('li', recursive=False):
@ -157,7 +157,7 @@ class CHMReader(CHMFile):
def get_home(self): def get_home(self):
return self.GetFile(self.home) return self.GetFile(self.home)
def ExtractFiles(self, output_dir=getcwd(), debug_dump=False): def ExtractFiles(self, output_dir=os.getcwd(), debug_dump=False):
html_files = set() html_files = set()
for path in self.Contents(): for path in self.Contents():
fpath = path fpath = path
@ -192,7 +192,7 @@ class CHMReader(CHMFile):
with lopen(lpath, 'r+b') as f: with lopen(lpath, 'r+b') as f:
data = f.read() data = f.read()
data = self._reformat(data, lpath) data = self._reformat(data, lpath)
if isinstance(data, unicode_type): if isinstance(data, str):
data = data.encode('utf-8') data = data.encode('utf-8')
f.seek(0) f.seek(0)
f.truncate() f.truncate()
@ -336,5 +336,5 @@ class CHMReader(CHMFile):
if not os.path.isdir(dir): if not os.path.isdir(dir):
os.makedirs(dir) os.makedirs(dir)
def extract_content(self, output_dir=getcwd(), debug_dump=False): def extract_content(self, output_dir=os.getcwd(), debug_dump=False):
self.ExtractFiles(output_dir=output_dir, debug_dump=debug_dump) self.ExtractFiles(output_dir=output_dir, debug_dump=debug_dump)

View File

@ -1,5 +1,3 @@
__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'
@ -16,7 +14,6 @@ from calibre.ptempfile import PersistentTemporaryDirectory
from calibre.utils.icu import numeric_sort_key from calibre.utils.icu import numeric_sort_key
from calibre.utils.ipc.server import Server from calibre.utils.ipc.server import Server
from calibre.utils.ipc.job import ParallelJob from calibre.utils.ipc.job import ParallelJob
from polyglot.builtins import unicode_type, map
from polyglot.queue import Empty from polyglot.queue import Empty
# If the specified screen has either dimension larger than this value, no image # If the specified screen has either dimension larger than this value, no image
@ -29,7 +26,7 @@ def extract_comic(path_to_comic_file):
Un-archive the comic file. Un-archive the comic file.
''' '''
tdir = PersistentTemporaryDirectory(suffix='_comic_extract') tdir = PersistentTemporaryDirectory(suffix='_comic_extract')
if not isinstance(tdir, unicode_type): if not isinstance(tdir, str):
# Needed in case the zip file has wrongly encoded unicode file/dir # Needed in case the zip file has wrongly encoded unicode file/dir
# names # names
tdir = tdir.decode(filesystem_encoding) tdir = tdir.decode(filesystem_encoding)

View File

@ -8,7 +8,6 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import io import io
from struct import pack from struct import pack
from polyglot.builtins import range
from calibre_extensions import cPalmdoc from calibre_extensions import cPalmdoc

View File

@ -6,7 +6,7 @@ __copyright__ = '2009, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import re import re
from polyglot.builtins import int_to_byte, range from polyglot.builtins import int_to_byte
class TCRCompressor: class TCRCompressor:

View File

@ -1,5 +1,3 @@
__license__ = 'GPL 3' __license__ = 'GPL 3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
@ -372,7 +370,7 @@ def main(args=sys.argv):
parser, plumber = create_option_parser(args, log) parser, plumber = create_option_parser(args, log)
opts, leftover_args = parser.parse_args(args) opts, leftover_args = parser.parse_args(args)
if len(leftover_args) > 3: if len(leftover_args) > 3:
log.error('Extra arguments not understood:', u', '.join(leftover_args[3:])) log.error('Extra arguments not understood:', ', '.join(leftover_args[3:]))
return 1 return 1
for x in ('read_metadata_from_opf', 'cover'): for x in ('read_metadata_from_opf', 'cover'):
if getattr(opts, x, None) is not None: if getattr(opts, x, None) is not None:

View File

@ -13,7 +13,6 @@ from calibre.utils.lock import ExclusiveFile
from calibre import sanitize_file_name from calibre import sanitize_file_name
from calibre.customize.conversion import OptionRecommendation from calibre.customize.conversion import OptionRecommendation
from calibre.customize.ui import available_output_formats from calibre.customize.ui import available_output_formats
from polyglot.builtins import unicode_type
config_dir = os.path.join(config_dir, 'conversion') config_dir = os.path.join(config_dir, 'conversion')
@ -71,7 +70,7 @@ class GuiRecommendations(dict):
def __new__(cls, *args): def __new__(cls, *args):
dict.__new__(cls) dict.__new__(cls)
obj = super(GuiRecommendations, cls).__new__(cls, *args) obj = super().__new__(cls, *args)
obj.disabled_options = set() obj.disabled_options = set()
return obj return obj
@ -90,7 +89,7 @@ class GuiRecommendations(dict):
def serialize(self): def serialize(self):
ans = json.dumps(self, indent=2, ensure_ascii=False) ans = json.dumps(self, indent=2, ensure_ascii=False)
if isinstance(ans, unicode_type): if isinstance(ans, str):
ans = ans.encode('utf-8') ans = ans.encode('utf-8')
return b'json:' + ans return b'json:' + ans

View File

@ -5,8 +5,9 @@ __license__ = 'GPL v3'
__copyright__ = '2011, John Schember <john@nachtimwald.com>' __copyright__ = '2011, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os
from calibre.customize.conversion import InputFormatPlugin from calibre.customize.conversion import InputFormatPlugin
from polyglot.builtins import getcwd
class AZW4Input(InputFormatPlugin): class AZW4Input(InputFormatPlugin):
@ -24,6 +25,6 @@ class AZW4Input(InputFormatPlugin):
header = PdbHeaderReader(stream) header = PdbHeaderReader(stream)
reader = Reader(header, stream, log, options) reader = Reader(header, stream, log, options)
opf = reader.extract_content(getcwd()) opf = reader.extract_content(os.getcwd())
return opf return opf

View File

@ -1,5 +1,3 @@
''' CHM File decoding support ''' ''' CHM File decoding support '''
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>,' \ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>,' \
@ -10,7 +8,7 @@ import os
from calibre.customize.conversion import InputFormatPlugin from calibre.customize.conversion import InputFormatPlugin
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
from calibre.constants import filesystem_encoding from calibre.constants import filesystem_encoding
from polyglot.builtins import unicode_type, as_bytes from polyglot.builtins import as_bytes
class CHMInput(InputFormatPlugin): class CHMInput(InputFormatPlugin):
@ -37,7 +35,7 @@ class CHMInput(InputFormatPlugin):
log.debug('Processing CHM...') log.debug('Processing CHM...')
with TemporaryDirectory('_chm2oeb') as tdir: with TemporaryDirectory('_chm2oeb') as tdir:
if not isinstance(tdir, unicode_type): if not isinstance(tdir, str):
tdir = tdir.decode(filesystem_encoding) tdir = tdir.decode(filesystem_encoding)
html_input = plugin_for_input_format('html') html_input = plugin_for_input_format('html')
for opt in html_input.options: for opt in html_input.options:
@ -128,7 +126,7 @@ class CHMInput(InputFormatPlugin):
base = os.path.dirname(os.path.abspath(htmlpath)) base = os.path.dirname(os.path.abspath(htmlpath))
def unquote(x): def unquote(x):
if isinstance(x, unicode_type): if isinstance(x, str):
x = x.encode('utf-8') x = x.encode('utf-8')
return _unquote(x).decode('utf-8') return _unquote(x).decode('utf-8')

View File

@ -1,5 +1,3 @@
__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'
@ -13,7 +11,6 @@ import shutil, textwrap, codecs, os
from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation
from calibre import CurrentDir from calibre import CurrentDir
from calibre.ptempfile import PersistentTemporaryDirectory from calibre.ptempfile import PersistentTemporaryDirectory
from polyglot.builtins import getcwd, map
class ComicInput(InputFormatPlugin): class ComicInput(InputFormatPlugin):
@ -198,7 +195,7 @@ class ComicInput(InputFormatPlugin):
mi = MetaInformation(os.path.basename(stream.name).rpartition('.')[0], mi = MetaInformation(os.path.basename(stream.name).rpartition('.')[0],
[_('Unknown')]) [_('Unknown')])
opf = OPFCreator(getcwd(), mi) opf = OPFCreator(os.getcwd(), mi)
entries = [] entries = []
def href(x): def href(x):

View File

@ -9,7 +9,6 @@ import os
from io import BytesIO from io import BytesIO
from calibre.customize.conversion import InputFormatPlugin from calibre.customize.conversion import InputFormatPlugin
from polyglot.builtins import getcwd
class DJVUInput(InputFormatPlugin): class DJVUInput(InputFormatPlugin):
@ -40,7 +39,7 @@ class DJVUInput(InputFormatPlugin):
for opt in html_input.options: for opt in html_input.options:
setattr(options, opt.option.name, opt.recommended_value) setattr(options, opt.option.name, opt.recommended_value)
options.input_encoding = 'utf-8' options.input_encoding = 'utf-8'
base = getcwd() base = os.getcwd()
htmlfile = os.path.join(base, 'index.html') htmlfile = os.path.join(base, 'index.html')
c = 0 c = 0
while os.path.exists(htmlfile): while os.path.exists(htmlfile):

View File

@ -1,5 +1,3 @@
__license__ = 'GPL 3' __license__ = 'GPL 3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
@ -8,7 +6,6 @@ import os, re, posixpath
from itertools import cycle from itertools import cycle
from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation
from polyglot.builtins import getcwd
ADOBE_OBFUSCATION = 'http://ns.adobe.com/pdf/enc#RC' ADOBE_OBFUSCATION = 'http://ns.adobe.com/pdf/enc#RC'
IDPF_OBFUSCATION = 'http://www.idpf.org/2008/embedding' IDPF_OBFUSCATION = 'http://www.idpf.org/2008/embedding'
@ -246,7 +243,7 @@ class EPUBInput(InputFormatPlugin):
path = attr(r, 'full-path') path = attr(r, 'full-path')
if not path: if not path:
continue continue
path = os.path.join(getcwd(), *path.split('/')) path = os.path.join(os.getcwd(), *path.split('/'))
if os.path.exists(path): if os.path.exists(path):
return path return path
except Exception: except Exception:
@ -260,7 +257,7 @@ class EPUBInput(InputFormatPlugin):
from calibre.ebooks.metadata.opf2 import OPF from calibre.ebooks.metadata.opf2 import OPF
try: try:
zf = ZipFile(stream) zf = ZipFile(stream)
zf.extractall(getcwd()) zf.extractall(os.getcwd())
except: except:
log.exception('EPUB appears to be invalid ZIP file, trying a' log.exception('EPUB appears to be invalid ZIP file, trying a'
' more forgiving ZIP parser') ' more forgiving ZIP parser')
@ -280,7 +277,7 @@ class EPUBInput(InputFormatPlugin):
if opf is None: if opf is None:
raise ValueError('%s is not a valid EPUB file (could not find opf)'%path) raise ValueError('%s is not a valid EPUB file (could not find opf)'%path)
opf = os.path.relpath(opf, getcwd()) opf = os.path.relpath(opf, os.getcwd())
parts = os.path.split(opf) parts = os.path.split(opf)
opf = OPF(opf, os.path.dirname(os.path.abspath(opf))) opf = OPF(opf, os.path.dirname(os.path.abspath(opf)))
@ -405,7 +402,7 @@ class EPUBInput(InputFormatPlugin):
with NamedTemporaryFile(suffix='.ncx', dir=os.path.dirname(nav_path), delete=False) as f: with NamedTemporaryFile(suffix='.ncx', dir=os.path.dirname(nav_path), delete=False) as f:
f.write(etree.tostring(ncx, encoding='utf-8')) f.write(etree.tostring(ncx, encoding='utf-8'))
ncx_href = os.path.relpath(f.name, getcwd()).replace(os.sep, '/') ncx_href = os.path.relpath(f.name, os.getcwd()).replace(os.sep, '/')
ncx_id = opf.create_manifest_item(ncx_href, NCX_MIME, append=True).get('id') ncx_id = opf.create_manifest_item(ncx_href, NCX_MIME, append=True).get('id')
for spine in opf.root.xpath('//*[local-name()="spine"]'): for spine in opf.root.xpath('//*[local-name()="spine"]'):
spine.set('toc', ncx_id) spine.set('toc', ncx_id)

View File

@ -12,7 +12,7 @@ from calibre.customize.conversion import (OutputFormatPlugin,
OptionRecommendation) OptionRecommendation)
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
from calibre import CurrentDir from calibre import CurrentDir
from polyglot.builtins import unicode_type, filter, map, zip, range, as_bytes from polyglot.builtins import as_bytes
block_level_tags = ( block_level_tags = (
'address', 'address',
@ -225,15 +225,15 @@ class EPUBOutput(OutputFormatPlugin):
identifiers = oeb.metadata['identifier'] identifiers = oeb.metadata['identifier']
uuid = None uuid = None
for x in identifiers: for x in identifiers:
if x.get(OPF('scheme'), None).lower() == 'uuid' or unicode_type(x).startswith('urn:uuid:'): if x.get(OPF('scheme'), None).lower() == 'uuid' or str(x).startswith('urn:uuid:'):
uuid = unicode_type(x).split(':')[-1] uuid = str(x).split(':')[-1]
break break
encrypted_fonts = getattr(input_plugin, 'encrypted_fonts', []) encrypted_fonts = getattr(input_plugin, 'encrypted_fonts', [])
if uuid is None: if uuid is None:
self.log.warn('No UUID identifier found') self.log.warn('No UUID identifier found')
from uuid import uuid4 from uuid import uuid4
uuid = unicode_type(uuid4()) uuid = str(uuid4())
oeb.metadata.add('identifier', uuid, scheme='uuid', id=uuid) oeb.metadata.add('identifier', uuid, scheme='uuid', id=uuid)
if encrypted_fonts and not uuid.startswith('urn:uuid:'): if encrypted_fonts and not uuid.startswith('urn:uuid:'):
@ -241,7 +241,7 @@ class EPUBOutput(OutputFormatPlugin):
# for some absurd reason, or it will throw a hissy fit and refuse # for some absurd reason, or it will throw a hissy fit and refuse
# to use the obfuscated fonts. # to use the obfuscated fonts.
for x in identifiers: for x in identifiers:
if unicode_type(x) == uuid: if str(x) == uuid:
x.content = 'urn:uuid:'+uuid x.content = 'urn:uuid:'+uuid
with TemporaryDirectory('_epub_output') as tdir: with TemporaryDirectory('_epub_output') as tdir:
@ -291,7 +291,7 @@ class EPUBOutput(OutputFormatPlugin):
from calibre.ebooks.oeb.polish.cover import fix_conversion_titlepage_links_in_nav from calibre.ebooks.oeb.polish.cover import fix_conversion_titlepage_links_in_nav
try: try:
os.mkdir(os.path.join(tdir, 'META-INF')) os.mkdir(os.path.join(tdir, 'META-INF'))
except EnvironmentError: except OSError:
pass pass
with open(os.path.join(tdir, 'META-INF', 'container.xml'), 'wb') as f: with open(os.path.join(tdir, 'META-INF', 'container.xml'), 'wb') as f:
f.write(simple_container_xml(os.path.basename(opf)).encode('utf-8')) f.write(simple_container_xml(os.path.basename(opf)).encode('utf-8'))
@ -307,7 +307,7 @@ class EPUBOutput(OutputFormatPlugin):
os.remove(f.name) os.remove(f.name)
try: try:
os.rmdir(os.path.join(tdir, 'META-INF')) os.rmdir(os.path.join(tdir, 'META-INF'))
except EnvironmentError: except OSError:
pass pass
def encrypt_fonts(self, uris, tdir, uuid): # {{{ def encrypt_fonts(self, uris, tdir, uuid): # {{{
@ -336,7 +336,7 @@ class EPUBOutput(OutputFormatPlugin):
f.write(bytes(bytearray(data[i] ^ key[i%16] for i in range(1024)))) f.write(bytes(bytearray(data[i] ^ key[i%16] for i in range(1024))))
else: else:
self.log.warn('Font', path, 'is invalid, ignoring') self.log.warn('Font', path, 'is invalid, ignoring')
if not isinstance(uri, unicode_type): if not isinstance(uri, str):
uri = uri.decode('utf-8') uri = uri.decode('utf-8')
fonts.append(''' fonts.append('''
<enc:EncryptedData> <enc:EncryptedData>

Some files were not shown because too many files have changed in this diff Show More