mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
py3: Misc fixes
Fixes #953 (py3: misc fixes trying to start calibre.gui_launch)
This commit is contained in:
parent
0e8543030a
commit
3bece11b09
@ -88,7 +88,7 @@ def build_linkcheck(base):
|
|||||||
|
|
||||||
|
|
||||||
def build_man_pages(language, base):
|
def build_man_pages(language, base):
|
||||||
os.environ[b'CALIBRE_BUILD_MAN_PAGES'] = b'1'
|
os.environ['CALIBRE_BUILD_MAN_PAGES'] = '1'
|
||||||
sphinx_build(language, base, builder='man', bdir=language, very_quiet=True)
|
sphinx_build(language, base, builder='man', bdir=language, very_quiet=True)
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ def sanitize_path():
|
|||||||
paths = r'{0}\private\python\DLLs {0}\private\python\Lib\site-packages\pywin32_system32 {0}\bin {0}\qt\bin C:\Windows\System32'.format(
|
paths = r'{0}\private\python\DLLs {0}\private\python\Lib\site-packages\pywin32_system32 {0}\bin {0}\qt\bin C:\Windows\System32'.format(
|
||||||
sw
|
sw
|
||||||
).split() + needed_paths
|
).split() + needed_paths
|
||||||
os.environ[b'PATH'] = os.pathsep.join(paths).encode('ascii')
|
os.environ['PATH'] = os.pathsep.join(paths)
|
||||||
print('PATH:', os.environ[b'PATH'])
|
print('PATH:', os.environ[b'PATH'])
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,57 +112,28 @@ def confirm_config_name(name):
|
|||||||
return name + '_again'
|
return name + '_again'
|
||||||
|
|
||||||
|
|
||||||
_filename_sanitize = re.compile(r'[\xae\0\\|\?\*<":>\+/]')
|
_filename_sanitize_unicode = frozenset((u'\\', u'|', u'?', u'*', u'<',
|
||||||
_filename_sanitize_unicode = frozenset([u'\\', u'|', u'?', u'*', u'<',
|
u'"', u':', u'>', u'+', u'/') + tuple(map(codepoint_to_chr, range(32))))
|
||||||
u'"', u':', u'>', u'+', u'/'] + list(map(codepoint_to_chr, range(32))))
|
|
||||||
|
|
||||||
|
|
||||||
def sanitize_file_name(name, substitute='_', as_unicode=False):
|
def sanitize_file_name(name, substitute=u'_'):
|
||||||
'''
|
'''
|
||||||
Sanitize the filename `name`. All invalid characters are replaced by `substitute`.
|
Sanitize the filename `name`. All invalid characters are replaced by `substitute`.
|
||||||
The set of invalid characters is the union of the invalid characters in Windows,
|
The set of invalid characters is the union of the invalid characters in Windows,
|
||||||
OS X and Linux. Also removes leading and trailing whitespace.
|
macOS and Linux. Also removes leading and trailing whitespace.
|
||||||
**WARNING:** This function also replaces path separators, so only pass file names
|
|
||||||
and not full paths to it.
|
|
||||||
*NOTE:* This function always returns byte strings, not unicode objects. The byte strings
|
|
||||||
are encoded in the filesystem encoding of the platform, or UTF-8.
|
|
||||||
'''
|
|
||||||
if isinstance(name, unicode_type):
|
|
||||||
name = name.encode(filesystem_encoding, 'ignore')
|
|
||||||
one = _filename_sanitize.sub(substitute, name)
|
|
||||||
one = re.sub(r'\s', ' ', one).strip()
|
|
||||||
bname, ext = os.path.splitext(one)
|
|
||||||
one = re.sub(r'^\.+$', '_', bname)
|
|
||||||
if as_unicode:
|
|
||||||
one = one.decode(filesystem_encoding)
|
|
||||||
one = one.replace('..', substitute)
|
|
||||||
one += ext
|
|
||||||
# Windows doesn't like path components that end with a period
|
|
||||||
if one and one[-1] in ('.', ' '):
|
|
||||||
one = one[:-1]+'_'
|
|
||||||
# Names starting with a period are hidden on Unix
|
|
||||||
if one.startswith('.'):
|
|
||||||
one = '_' + one[1:]
|
|
||||||
return one
|
|
||||||
|
|
||||||
|
|
||||||
def sanitize_file_name_unicode(name, substitute='_'):
|
|
||||||
'''
|
|
||||||
Sanitize the filename `name`. All invalid characters are replaced by `substitute`.
|
|
||||||
The set of invalid characters is the union of the invalid characters in Windows,
|
|
||||||
OS X and Linux. Also removes leading and trailing whitespace.
|
|
||||||
**WARNING:** This function also replaces path separators, so only pass file names
|
**WARNING:** This function also replaces path separators, so only pass file names
|
||||||
and not full paths to it.
|
and not full paths to it.
|
||||||
'''
|
'''
|
||||||
if isbytestring(name):
|
if isbytestring(name):
|
||||||
return sanitize_file_name(name, substitute=substitute, as_unicode=True)
|
name = name.decode(filesystem_encoding, 'replace')
|
||||||
chars = [substitute if c in _filename_sanitize_unicode else c for c in
|
if isbytestring(substitute):
|
||||||
name]
|
substitute = substitute.decode(filesystem_encoding, 'replace')
|
||||||
|
chars = (substitute if c in _filename_sanitize_unicode else c for c in name)
|
||||||
one = u''.join(chars)
|
one = u''.join(chars)
|
||||||
one = re.sub(r'\s', ' ', one).strip()
|
one = re.sub(r'\s', u' ', one).strip()
|
||||||
bname, ext = os.path.splitext(one)
|
bname, ext = os.path.splitext(one)
|
||||||
one = re.sub(r'^\.+$', '_', bname)
|
one = re.sub(r'^\.+$', u'_', bname)
|
||||||
one = one.replace('..', substitute)
|
one = one.replace(u'..', substitute)
|
||||||
one += ext
|
one += ext
|
||||||
# Windows doesn't like path components that end with a period or space
|
# Windows doesn't like path components that end with a period or space
|
||||||
if one and one[-1] in ('.', ' '):
|
if one and one[-1] in ('.', ' '):
|
||||||
@ -173,14 +144,7 @@ def sanitize_file_name_unicode(name, substitute='_'):
|
|||||||
return one
|
return one
|
||||||
|
|
||||||
|
|
||||||
def sanitize_file_name2(name, substitute='_'):
|
sanitize_file_name2 = sanitize_file_name_unicode = sanitize_file_name
|
||||||
'''
|
|
||||||
Sanitize filenames removing invalid chars. Keeps unicode names as unicode
|
|
||||||
and bytestrings as bytestrings
|
|
||||||
'''
|
|
||||||
if isbytestring(name):
|
|
||||||
return sanitize_file_name(name, substitute=substitute)
|
|
||||||
return sanitize_file_name_unicode(name, substitute=substitute)
|
|
||||||
|
|
||||||
|
|
||||||
def prints(*args, **kwargs):
|
def prints(*args, **kwargs):
|
||||||
|
@ -1759,7 +1759,7 @@ class OPFTest(unittest.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.stream = io.BytesIO(
|
self.stream = io.BytesIO(
|
||||||
'''\
|
b'''\
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<package version="2.0" xmlns="http://www.idpf.org/2007/opf" >
|
<package version="2.0" xmlns="http://www.idpf.org/2007/opf" >
|
||||||
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
|
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
|
||||||
|
@ -11,7 +11,7 @@ import os, tempfile, time
|
|||||||
from threading import Event
|
from threading import Event
|
||||||
|
|
||||||
from calibre.customize.ui import all_metadata_plugins
|
from calibre.customize.ui import all_metadata_plugins
|
||||||
from calibre import prints, sanitize_file_name2
|
from calibre import prints, sanitize_file_name
|
||||||
from calibre.ebooks.metadata import check_isbn
|
from calibre.ebooks.metadata import check_isbn
|
||||||
from calibre.ebooks.metadata.sources.base import create_log, get_cached_cover_urls
|
from calibre.ebooks.metadata.sources.base import create_log, get_cached_cover_urls
|
||||||
from calibre.ebooks.metadata.sources.prefs import msprefs
|
from calibre.ebooks.metadata.sources.prefs import msprefs
|
||||||
@ -320,7 +320,7 @@ def test_identify_plugin(name, tests, modify_plugin=lambda plugin:None, # {{{
|
|||||||
elif results:
|
elif results:
|
||||||
cdata = results[0]
|
cdata = results[0]
|
||||||
cover = os.path.join(tdir, plugin.name.replace(' ',
|
cover = os.path.join(tdir, plugin.name.replace(' ',
|
||||||
'')+'-%s-cover.jpg'%sanitize_file_name2(mi.title.replace(' ',
|
'')+'-%s-cover.jpg'%sanitize_file_name(mi.title.replace(' ',
|
||||||
'_')))
|
'_')))
|
||||||
with open(cover, 'wb') as f:
|
with open(cover, 'wb') as f:
|
||||||
f.write(cdata[-1])
|
f.write(cdata[-1])
|
||||||
|
@ -17,7 +17,7 @@ from io import BytesIO
|
|||||||
from multiprocessing.dummy import Pool
|
from multiprocessing.dummy import Pool
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
from calibre import as_unicode, sanitize_file_name2
|
from calibre import as_unicode, sanitize_file_name as sanitize_file_name_base
|
||||||
from calibre.ebooks.oeb.base import OEB_DOCS, OEB_STYLES, barename, iterlinks
|
from calibre.ebooks.oeb.base import OEB_DOCS, OEB_STYLES, barename, iterlinks
|
||||||
from calibre.ebooks.oeb.polish.utils import guess_type
|
from calibre.ebooks.oeb.polish.utils import guess_type
|
||||||
from calibre.ptempfile import TemporaryDirectory
|
from calibre.ptempfile import TemporaryDirectory
|
||||||
@ -97,7 +97,7 @@ class ProgressTracker(object):
|
|||||||
|
|
||||||
def sanitize_file_name(x):
|
def sanitize_file_name(x):
|
||||||
from calibre.ebooks.oeb.polish.check.parsing import make_filename_safe
|
from calibre.ebooks.oeb.polish.check.parsing import make_filename_safe
|
||||||
x = sanitize_file_name2(x)
|
x = sanitize_file_name_base(x)
|
||||||
while '..' in x:
|
while '..' in x:
|
||||||
x = x.replace('..', '.')
|
x = x.replace('..', '.')
|
||||||
return make_filename_safe(x)
|
return make_filename_safe(x)
|
||||||
|
@ -12,7 +12,7 @@ from polyglot.builtins import iteritems, itervalues, map
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
from collections import Counter, defaultdict
|
from collections import Counter, defaultdict
|
||||||
|
|
||||||
from calibre import sanitize_file_name_unicode
|
from calibre import sanitize_file_name
|
||||||
from calibre.ebooks.chardet import strip_encoding_declarations
|
from calibre.ebooks.chardet import strip_encoding_declarations
|
||||||
from calibre.ebooks.oeb.polish.css import iter_declarations, remove_property_value
|
from calibre.ebooks.oeb.polish.css import iter_declarations, remove_property_value
|
||||||
from calibre.ebooks.oeb.polish.utils import extract
|
from calibre.ebooks.oeb.polish.utils import extract
|
||||||
@ -207,7 +207,7 @@ def rename_files(container, file_map):
|
|||||||
|
|
||||||
def replace_file(container, name, path, basename, force_mt=None):
|
def replace_file(container, name, path, basename, force_mt=None):
|
||||||
dirname, base = name.rpartition('/')[0::2]
|
dirname, base = name.rpartition('/')[0::2]
|
||||||
nname = sanitize_file_name_unicode(basename)
|
nname = sanitize_file_name(basename)
|
||||||
if dirname:
|
if dirname:
|
||||||
nname = dirname + '/' + nname
|
nname = dirname + '/' + nname
|
||||||
with open(path, 'rb') as src:
|
with open(path, 'rb') as src:
|
||||||
|
@ -13,7 +13,7 @@ from calibre.gui2 import choose_dir, error_dialog, warning_dialog
|
|||||||
from calibre.gui2.tools import generate_catalog
|
from calibre.gui2.tools import generate_catalog
|
||||||
from calibre.utils.config import dynamic
|
from calibre.utils.config import dynamic
|
||||||
from calibre.gui2.actions import InterfaceAction
|
from calibre.gui2.actions import InterfaceAction
|
||||||
from calibre import sanitize_file_name_unicode
|
from calibre import sanitize_file_name
|
||||||
from polyglot.builtins import range
|
from polyglot.builtins import range
|
||||||
|
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ class GenerateCatalogAction(InterfaceAction):
|
|||||||
title=job.catalog_title, fmt=job.fmt.lower()))
|
title=job.catalog_title, fmt=job.fmt.lower()))
|
||||||
if export_dir:
|
if export_dir:
|
||||||
destination = os.path.join(export_dir, '%s.%s' % (
|
destination = os.path.join(export_dir, '%s.%s' % (
|
||||||
sanitize_file_name_unicode(job.catalog_title), job.fmt.lower()))
|
sanitize_file_name(job.catalog_title), job.fmt.lower()))
|
||||||
try:
|
try:
|
||||||
shutil.copyfile(job.catalog_file_path, destination)
|
shutil.copyfile(job.catalog_file_path, destination)
|
||||||
except EnvironmentError as err:
|
except EnvironmentError as err:
|
||||||
|
@ -13,7 +13,7 @@ from PyQt5.Qt import (QMenu, Qt, QInputDialog, QToolButton, QDialog,
|
|||||||
QDialogButtonBox, QGridLayout, QLabel, QLineEdit, QIcon, QSize,
|
QDialogButtonBox, QGridLayout, QLabel, QLineEdit, QIcon, QSize,
|
||||||
QCoreApplication, pyqtSignal, QVBoxLayout, QTimer, QAction)
|
QCoreApplication, pyqtSignal, QVBoxLayout, QTimer, QAction)
|
||||||
|
|
||||||
from calibre import isbytestring, sanitize_file_name_unicode
|
from calibre import isbytestring, sanitize_file_name
|
||||||
from calibre.constants import (filesystem_encoding, iswindows, get_portable_base, isportable)
|
from calibre.constants import (filesystem_encoding, iswindows, get_portable_base, isportable)
|
||||||
from calibre.utils.config import prefs, tweaks
|
from calibre.utils.config import prefs, tweaks
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
@ -418,7 +418,7 @@ class ChooseLibraryAction(InterfaceAction):
|
|||||||
'Choose a new name for the library <b>%s</b>. ')%name + '<p>'+_(
|
'Choose a new name for the library <b>%s</b>. ')%name + '<p>'+_(
|
||||||
'Note that the actual library folder will be renamed.'),
|
'Note that the actual library folder will be renamed.'),
|
||||||
text=old_name)
|
text=old_name)
|
||||||
newname = sanitize_file_name_unicode(unicode_type(newname))
|
newname = sanitize_file_name(unicode_type(newname))
|
||||||
if not ok or not newname or newname == old_name:
|
if not ok or not newname or newname == old_name:
|
||||||
return
|
return
|
||||||
newloc = os.path.join(base, newname)
|
newloc = os.path.join(base, newname)
|
||||||
|
@ -254,7 +254,7 @@
|
|||||||
<customwidget>
|
<customwidget>
|
||||||
<class>RegexEdit</class>
|
<class>RegexEdit</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QWidget</extends>
|
||||||
<header>regex_builder.h</header>
|
<header>calibre/gui2/convert/regex_builder.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
|
@ -24,7 +24,7 @@ from calibre.gui2 import (config, error_dialog, Dispatcher, dynamic,
|
|||||||
warning_dialog, info_dialog, choose_dir, FunctionDispatcher,
|
warning_dialog, info_dialog, choose_dir, FunctionDispatcher,
|
||||||
show_restart_warning, gprefs, question_dialog)
|
show_restart_warning, gprefs, question_dialog)
|
||||||
from calibre.ebooks.metadata import authors_to_string
|
from calibre.ebooks.metadata import authors_to_string
|
||||||
from calibre import preferred_encoding, prints, force_unicode, as_unicode, sanitize_file_name2
|
from calibre import preferred_encoding, prints, force_unicode, as_unicode, sanitize_file_name
|
||||||
from calibre.utils.filenames import ascii_filename
|
from calibre.utils.filenames import ascii_filename
|
||||||
from calibre.devices.errors import (FreeSpaceError, WrongDestinationError,
|
from calibre.devices.errors import (FreeSpaceError, WrongDestinationError,
|
||||||
BlacklistedDevice)
|
BlacklistedDevice)
|
||||||
@ -627,7 +627,7 @@ class DeviceManager(Thread): # {{{
|
|||||||
def _save_books(self, paths, target):
|
def _save_books(self, paths, target):
|
||||||
'''Copy books from device to disk'''
|
'''Copy books from device to disk'''
|
||||||
for path in paths:
|
for path in paths:
|
||||||
name = sanitize_file_name2(os.path.basename(path))
|
name = sanitize_file_name(os.path.basename(path))
|
||||||
dest = os.path.join(target, name)
|
dest = os.path.join(target, name)
|
||||||
if os.path.abspath(dest) != os.path.abspath(path):
|
if os.path.abspath(dest) != os.path.abspath(path):
|
||||||
with lopen(dest, 'wb') as f:
|
with lopen(dest, 'wb') as f:
|
||||||
|
@ -9,7 +9,7 @@ from PyQt5.Qt import (Qt, QDialog, QDialogButtonBox, QSyntaxHighlighter, QFont,
|
|||||||
QRegExp, QApplication, QTextCharFormat, QColor, QCursor,
|
QRegExp, QApplication, QTextCharFormat, QColor, QCursor,
|
||||||
QIcon, QSize)
|
QIcon, QSize)
|
||||||
|
|
||||||
from calibre import sanitize_file_name_unicode
|
from calibre import sanitize_file_name
|
||||||
from calibre.constants import config_dir
|
from calibre.constants import config_dir
|
||||||
from calibre.gui2 import gprefs
|
from calibre.gui2 import gprefs
|
||||||
from calibre.gui2.dialogs.template_dialog_ui import Ui_TemplateDialog
|
from calibre.gui2.dialogs.template_dialog_ui import Ui_TemplateDialog
|
||||||
@ -359,7 +359,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
|
|||||||
all_files=False, select_only_single_file=True)
|
all_files=False, select_only_single_file=True)
|
||||||
if path:
|
if path:
|
||||||
icon_path = path[0]
|
icon_path = path[0]
|
||||||
icon_name = sanitize_file_name_unicode(
|
icon_name = sanitize_file_name(
|
||||||
os.path.splitext(
|
os.path.splitext(
|
||||||
os.path.basename(icon_path))[0]+'.png')
|
os.path.basename(icon_path))[0]+'.png')
|
||||||
if icon_name not in self.icon_file_names:
|
if icon_name not in self.icon_file_names:
|
||||||
|
@ -357,7 +357,7 @@ def run_in_debug_mode():
|
|||||||
import tempfile, subprocess
|
import tempfile, subprocess
|
||||||
fd, logpath = tempfile.mkstemp('.txt')
|
fd, logpath = tempfile.mkstemp('.txt')
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
os.environ[b'CALIBRE_RESTARTING_FROM_GUI'] = b'1'
|
os.environ['CALIBRE_RESTARTING_FROM_GUI'] = environ_item('1')
|
||||||
run_calibre_debug(
|
run_calibre_debug(
|
||||||
'--gui-debug', logpath, stdout=lopen(logpath, 'w'),
|
'--gui-debug', logpath, stdout=lopen(logpath, 'w'),
|
||||||
stderr=subprocess.STDOUT, stdin=lopen(os.devnull, 'r'))
|
stderr=subprocess.STDOUT, stdin=lopen(os.devnull, 'r'))
|
||||||
@ -405,7 +405,7 @@ def run_gui(opts, args, listener, app, gui_debug=None):
|
|||||||
prints('Restarting with:', app)
|
prints('Restarting with:', app)
|
||||||
subprocess.Popen('sleep 3s; open ' + shellquote(app), shell=True)
|
subprocess.Popen('sleep 3s; open ' + shellquote(app), shell=True)
|
||||||
else:
|
else:
|
||||||
os.environ[b'CALIBRE_RESTARTING_FROM_GUI'] = b'1'
|
os.environ['CALIBRE_RESTARTING_FROM_GUI'] = environ_item('1')
|
||||||
if iswindows and hasattr(winutil, 'prepare_for_restart'):
|
if iswindows and hasattr(winutil, 'prepare_for_restart'):
|
||||||
winutil.prepare_for_restart()
|
winutil.prepare_for_restart()
|
||||||
args = ['-g'] if os.path.splitext(e)[0].endswith('-debug') else []
|
args = ['-g'] if os.path.splitext(e)[0].endswith('-debug') else []
|
||||||
@ -509,7 +509,7 @@ def create_listener():
|
|||||||
|
|
||||||
|
|
||||||
def main(args=sys.argv):
|
def main(args=sys.argv):
|
||||||
if os.environ.pop(b'CALIBRE_RESTARTING_FROM_GUI', None) == b'1':
|
if os.environ.pop('CALIBRE_RESTARTING_FROM_GUI', None) == environ_item('1'):
|
||||||
time.sleep(2) # give the parent process time to cleanup and close
|
time.sleep(2) # give the parent process time to cleanup and close
|
||||||
if iswindows and 'CALIBRE_REPAIR_CORRUPTED_DB' in os.environ:
|
if iswindows and 'CALIBRE_REPAIR_CORRUPTED_DB' in os.environ:
|
||||||
windows_repair()
|
windows_repair()
|
||||||
|
@ -15,7 +15,7 @@ from PyQt5.Qt import (QWidget, QDialog, QLabel, QGridLayout, QComboBox, QSize,
|
|||||||
QListView, QAbstractListModel, pyqtSignal, QSizePolicy, QSpacerItem,
|
QListView, QAbstractListModel, pyqtSignal, QSizePolicy, QSpacerItem,
|
||||||
QApplication, QStandardItem, QStandardItemModel, QCheckBox, QMenu)
|
QApplication, QStandardItem, QStandardItemModel, QCheckBox, QMenu)
|
||||||
|
|
||||||
from calibre import prepare_string_for_xml, sanitize_file_name_unicode, as_unicode
|
from calibre import prepare_string_for_xml, sanitize_file_name, as_unicode
|
||||||
from calibre.constants import config_dir
|
from calibre.constants import config_dir
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
from calibre.gui2 import error_dialog, choose_files, pixmap_to_data, gprefs, choose_save_file
|
from calibre.gui2 import error_dialog, choose_files, pixmap_to_data, gprefs, choose_save_file
|
||||||
@ -501,7 +501,7 @@ class RuleEditor(QDialog): # {{{
|
|||||||
'''.format(c=c, bg1=bg1, bg2=bg2, st=_('Sample text')))
|
'''.format(c=c, bg1=bg1, bg2=bg2, st=_('Sample text')))
|
||||||
|
|
||||||
def sanitize_icon_file_name(self, icon_path):
|
def sanitize_icon_file_name(self, icon_path):
|
||||||
n = lower(sanitize_file_name_unicode(
|
n = lower(sanitize_file_name(
|
||||||
os.path.splitext(
|
os.path.splitext(
|
||||||
os.path.basename(icon_path))[0]+'.png'))
|
os.path.basename(icon_path))[0]+'.png'))
|
||||||
return n.replace("'", '_')
|
return n.replace("'", '_')
|
||||||
|
@ -16,7 +16,7 @@ from PyQt5.Qt import (
|
|||||||
QLinearGradient, QPalette, QColor, QPen, QBrush, QFont
|
QLinearGradient, QPalette, QColor, QPen, QBrush, QFont
|
||||||
)
|
)
|
||||||
|
|
||||||
from calibre import sanitize_file_name_unicode
|
from calibre import sanitize_file_name
|
||||||
from calibre.constants import config_dir
|
from calibre.constants import config_dir
|
||||||
from calibre.ebooks.metadata import rating_to_stars
|
from calibre.ebooks.metadata import rating_to_stars
|
||||||
from calibre.gui2.tag_browser.model import (TagTreeItem, TAG_SEARCH_STATES,
|
from calibre.gui2.tag_browser.model import (TagTreeItem, TAG_SEARCH_STATES,
|
||||||
@ -375,7 +375,7 @@ class TagsView(QTreeView): # {{{
|
|||||||
d = os.path.join(config_dir, 'tb_icons')
|
d = os.path.join(config_dir, 'tb_icons')
|
||||||
if not os.path.exists(d):
|
if not os.path.exists(d):
|
||||||
os.makedirs(d)
|
os.makedirs(d)
|
||||||
with open(os.path.join(d, 'icon_' + sanitize_file_name_unicode(key)+'.png'), 'wb') as f:
|
with open(os.path.join(d, 'icon_' + sanitize_file_name(key)+'.png'), 'wb') as f:
|
||||||
f.write(pixmap_to_data(p, format='PNG'))
|
f.write(pixmap_to_data(p, format='PNG'))
|
||||||
path = os.path.basename(f.name)
|
path = os.path.basename(f.name)
|
||||||
self._model.set_custom_category_icon(key, unicode_type(path))
|
self._model.set_custom_category_icon(key, unicode_type(path))
|
||||||
|
@ -18,7 +18,7 @@ from PyQt5.Qt import (
|
|||||||
QVBoxLayout, QWidget, pyqtSignal
|
QVBoxLayout, QWidget, pyqtSignal
|
||||||
)
|
)
|
||||||
|
|
||||||
from calibre import human_readable, plugins, sanitize_file_name_unicode
|
from calibre import human_readable, plugins, sanitize_file_name
|
||||||
from calibre.ebooks.oeb.base import OEB_DOCS, OEB_STYLES
|
from calibre.ebooks.oeb.base import OEB_DOCS, OEB_STYLES
|
||||||
from calibre.ebooks.oeb.polish.container import OEB_FONTS, guess_type
|
from calibre.ebooks.oeb.polish.container import OEB_FONTS, guess_type
|
||||||
from calibre.ebooks.oeb.polish.cover import (
|
from calibre.ebooks.oeb.polish.cover import (
|
||||||
@ -73,7 +73,7 @@ def name_is_ok(name, show_error):
|
|||||||
norm = name.replace('\\', '/')
|
norm = name.replace('\\', '/')
|
||||||
parts = name.split('/')
|
parts = name.split('/')
|
||||||
for x in parts:
|
for x in parts:
|
||||||
if sanitize_file_name_unicode(x) != x:
|
if sanitize_file_name(x) != x:
|
||||||
return show_error(_('The file name contains invalid characters')) and False
|
return show_error(_('The file name contains invalid characters')) and False
|
||||||
if current_container().has_name(norm):
|
if current_container().has_name(norm):
|
||||||
return show_error(_('This file name already exists in the book')) and False
|
return show_error(_('This file name already exists in the book')) and False
|
||||||
@ -81,7 +81,7 @@ def name_is_ok(name, show_error):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_bulk_rename_settings(parent, number, msg=None, sanitize=sanitize_file_name_unicode,
|
def get_bulk_rename_settings(parent, number, msg=None, sanitize=sanitize_file_name,
|
||||||
leading_zeros=True, prefix=None, category='text', allow_spine_order=False): # {{{
|
leading_zeros=True, prefix=None, category='text', allow_spine_order=False): # {{{
|
||||||
d = QDialog(parent)
|
d = QDialog(parent)
|
||||||
d.setWindowTitle(_('Bulk rename items'))
|
d.setWindowTitle(_('Bulk rename items'))
|
||||||
|
@ -13,7 +13,7 @@ from PyQt5.Qt import (
|
|||||||
QFormLayout, QLineEdit, QToolButton, QHBoxLayout, QLabel, QIcon, QPrinter,
|
QFormLayout, QLineEdit, QToolButton, QHBoxLayout, QLabel, QIcon, QPrinter,
|
||||||
QPageSize, QComboBox, QDoubleSpinBox, QCheckBox, QProgressDialog, QTimer)
|
QPageSize, QComboBox, QDoubleSpinBox, QCheckBox, QProgressDialog, QTimer)
|
||||||
|
|
||||||
from calibre import sanitize_file_name2
|
from calibre import sanitize_file_name
|
||||||
from calibre.ptempfile import PersistentTemporaryFile
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
from calibre.ebooks.conversion.plugins.pdf_output import PAPER_SIZES
|
from calibre.ebooks.conversion.plugins.pdf_output import PAPER_SIZES
|
||||||
from calibre.gui2 import elided_text, error_dialog, choose_save_file, Application, open_local_file, dynamic
|
from calibre.gui2 import elided_text, error_dialog, choose_save_file, Application, open_local_file, dynamic
|
||||||
@ -31,7 +31,7 @@ class PrintDialog(Dialog):
|
|||||||
|
|
||||||
def __init__(self, book_title, parent=None, prefs=vprefs):
|
def __init__(self, book_title, parent=None, prefs=vprefs):
|
||||||
self.book_title = book_title
|
self.book_title = book_title
|
||||||
self.default_file_name = sanitize_file_name2(book_title[:75] + '.pdf')
|
self.default_file_name = sanitize_file_name(book_title[:75] + '.pdf')
|
||||||
self.paper_size_map = {a:getattr(QPageSize, a.capitalize()) for a in PAPER_SIZES}
|
self.paper_size_map = {a:getattr(QPageSize, a.capitalize()) for a in PAPER_SIZES}
|
||||||
Dialog.__init__(self, _('Print to PDF'), 'print-to-pdf', prefs=prefs, parent=parent)
|
Dialog.__init__(self, _('Print to PDF'), 'print-to-pdf', prefs=prefs, parent=parent)
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ class PrintDialog(Dialog):
|
|||||||
def data(self):
|
def data(self):
|
||||||
fpath = self.file_name.text().strip()
|
fpath = self.file_name.text().strip()
|
||||||
head, tail = os.path.split(fpath)
|
head, tail = os.path.split(fpath)
|
||||||
tail = sanitize_file_name2(tail)
|
tail = sanitize_file_name(tail)
|
||||||
fpath = tail
|
fpath = tail
|
||||||
if head:
|
if head:
|
||||||
fpath = os.path.join(head, tail)
|
fpath = os.path.join(head, tail)
|
||||||
|
@ -17,7 +17,7 @@ from calibre.constants import preferred_encoding
|
|||||||
from calibre.ebooks.metadata import fmt_sidx
|
from calibre.ebooks.metadata import fmt_sidx
|
||||||
from calibre.ebooks.metadata import title_sort
|
from calibre.ebooks.metadata import title_sort
|
||||||
from calibre.utils.date import as_local_time
|
from calibre.utils.date import as_local_time
|
||||||
from calibre import strftime, prints, sanitize_file_name_unicode
|
from calibre import strftime, prints, sanitize_file_name
|
||||||
from calibre.db.lazy import FormatsList
|
from calibre.db.lazy import FormatsList
|
||||||
from polyglot.builtins import unicode_type
|
from polyglot.builtins import unicode_type
|
||||||
|
|
||||||
@ -279,7 +279,7 @@ def save_book_to_disk(book_id, db, root, opts, length):
|
|||||||
def get_path_components(opts, mi, book_id, path_length):
|
def get_path_components(opts, mi, book_id, path_length):
|
||||||
try:
|
try:
|
||||||
components = get_components(opts.template, mi, book_id, opts.timefmt, path_length,
|
components = get_components(opts.template, mi, book_id, opts.timefmt, path_length,
|
||||||
ascii_filename if opts.asciiize else sanitize_file_name_unicode,
|
ascii_filename if opts.asciiize else sanitize_file_name,
|
||||||
to_lowercase=opts.to_lowercase,
|
to_lowercase=opts.to_lowercase,
|
||||||
replace_whitespace=opts.replace_whitespace, safe_format=False,
|
replace_whitespace=opts.replace_whitespace, safe_format=False,
|
||||||
last_has_extension=False, single_dir=opts.single_dir)
|
last_has_extension=False, single_dir=opts.single_dir)
|
||||||
|
@ -8,7 +8,7 @@ import os
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from calibre import as_unicode, sanitize_file_name_unicode
|
from calibre import as_unicode, sanitize_file_name
|
||||||
from calibre.db.cli import module_for_cmd
|
from calibre.db.cli import module_for_cmd
|
||||||
from calibre.ebooks.metadata.meta import get_metadata
|
from calibre.ebooks.metadata.meta import get_metadata
|
||||||
from calibre.srv.changes import books_added, books_deleted, metadata
|
from calibre.srv.changes import books_added, books_deleted, metadata
|
||||||
@ -77,7 +77,7 @@ def cdb_add_book(ctx, rd, job_id, add_duplicates, filename, library_id):
|
|||||||
raise HTTPForbidden('Cannot use the add book interface with a user who has per library restrictions')
|
raise HTTPForbidden('Cannot use the add book interface with a user who has per library restrictions')
|
||||||
if not filename:
|
if not filename:
|
||||||
raise HTTPBadRequest('An empty filename is not allowed')
|
raise HTTPBadRequest('An empty filename is not allowed')
|
||||||
sfilename = sanitize_file_name_unicode(filename)
|
sfilename = sanitize_file_name(filename)
|
||||||
fmt = os.path.splitext(sfilename)[1]
|
fmt = os.path.splitext(sfilename)[1]
|
||||||
fmt = fmt[1:] if fmt else None
|
fmt = fmt[1:] if fmt else None
|
||||||
if not fmt:
|
if not fmt:
|
||||||
|
@ -12,7 +12,7 @@ from threading import Lock
|
|||||||
from polyglot.builtins import map
|
from polyglot.builtins import map
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from calibre import fit_image, sanitize_file_name_unicode
|
from calibre import fit_image, sanitize_file_name
|
||||||
from calibre.constants import config_dir, iswindows
|
from calibre.constants import config_dir, iswindows
|
||||||
from calibre.db.errors import NoSuchFormat
|
from calibre.db.errors import NoSuchFormat
|
||||||
from calibre.ebooks.covers import cprefs, override_prefs, scale_cover, generate_cover, set_use_roman
|
from calibre.ebooks.covers import cprefs, override_prefs, scale_cover, generate_cover, set_use_roman
|
||||||
@ -166,7 +166,7 @@ def book_filename(rd, book_id, mi, fmt, as_encoded_unicode=False):
|
|||||||
fname = '%s - %s_%s.%s' % (title[:30], au[:30], book_id, ext)
|
fname = '%s - %s_%s.%s' % (title[:30], au[:30], book_id, ext)
|
||||||
if as_encoded_unicode:
|
if as_encoded_unicode:
|
||||||
# See https://tools.ietf.org/html/rfc6266
|
# See https://tools.ietf.org/html/rfc6266
|
||||||
fname = sanitize_file_name_unicode(fname).encode('utf-8')
|
fname = sanitize_file_name(fname).encode('utf-8')
|
||||||
fname = quote(fname).decode('ascii')
|
fname = quote(fname).decode('ascii')
|
||||||
else:
|
else:
|
||||||
fname = ascii_filename(fname).replace('"', '_')
|
fname = ascii_filename(fname).replace('"', '_')
|
||||||
|
@ -21,22 +21,21 @@ def ascii_text(orig):
|
|||||||
udc = get_udc()
|
udc = get_udc()
|
||||||
try:
|
try:
|
||||||
ascii = udc.decode(orig)
|
ascii = udc.decode(orig)
|
||||||
except:
|
except Exception:
|
||||||
if isinstance(orig, unicode_type):
|
if isinstance(orig, unicode_type):
|
||||||
orig = orig.encode('ascii', 'replace')
|
orig = orig.encode('ascii', 'replace')
|
||||||
ascii = orig.decode(preferred_encoding,
|
ascii = orig.decode(preferred_encoding, 'replace')
|
||||||
'replace').encode('ascii', 'replace')
|
if isinstance(ascii, bytes):
|
||||||
|
ascii = ascii.decode('ascii', 'replace')
|
||||||
return ascii
|
return ascii
|
||||||
|
|
||||||
|
|
||||||
def ascii_filename(orig, substitute='_'):
|
def ascii_filename(orig, substitute=u'_'):
|
||||||
ans = []
|
if isinstance(substitute, bytes):
|
||||||
orig = ascii_text(orig).replace('?', '_')
|
substitute = substitute.decode(filesystem_encoding)
|
||||||
for x in orig:
|
orig = ascii_text(orig).replace(u'?', u'_')
|
||||||
if ord(x) < 32:
|
ans = u''.join(x if ord(x) >= 32 else substitute for x in orig)
|
||||||
x = substitute
|
return sanitize_file_name(ans, substitute=substitute)
|
||||||
ans.append(x)
|
|
||||||
return sanitize_file_name(''.join(ans), substitute=substitute)
|
|
||||||
|
|
||||||
|
|
||||||
def shorten_component(s, by_what):
|
def shorten_component(s, by_what):
|
||||||
|
@ -10,10 +10,10 @@ import os, errno
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
from calibre import force_unicode
|
from calibre import force_unicode
|
||||||
from calibre.constants import iswindows, get_windows_username, islinux
|
from calibre.constants import iswindows, get_windows_username, islinux, filesystem_encoding, ispy3
|
||||||
from calibre.utils.filenames import ascii_filename
|
from calibre.utils.filenames import ascii_filename
|
||||||
|
|
||||||
ADDRESS = VADDRESS = None
|
VADDRESS = None
|
||||||
|
|
||||||
|
|
||||||
def eintr_retry_call(func, *args, **kwargs):
|
def eintr_retry_call(func, *args, **kwargs):
|
||||||
@ -27,10 +27,9 @@ def eintr_retry_call(func, *args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
def gui_socket_address():
|
def gui_socket_address():
|
||||||
global ADDRESS
|
if gui_socket_address.ans is None:
|
||||||
if ADDRESS is None:
|
|
||||||
if iswindows:
|
if iswindows:
|
||||||
ADDRESS = r'\\.\pipe\CalibreGUI'
|
gui_socket_address.ans = r'\\.\pipe\CalibreGUI'
|
||||||
try:
|
try:
|
||||||
user = get_windows_username()
|
user = get_windows_username()
|
||||||
except:
|
except:
|
||||||
@ -38,25 +37,26 @@ def gui_socket_address():
|
|||||||
if user:
|
if user:
|
||||||
user = ascii_filename(user).replace(' ', '_')
|
user = ascii_filename(user).replace(' ', '_')
|
||||||
if user:
|
if user:
|
||||||
ADDRESS += '-' + user[:100] + 'x'
|
gui_socket_address.ans += '-' + user[:100] + 'x'
|
||||||
else:
|
else:
|
||||||
user = os.environ.get('USER', '')
|
user = os.environ.get('USER', '')
|
||||||
if not user:
|
if not user:
|
||||||
user = os.path.basename(os.path.expanduser('~'))
|
user = os.path.basename(os.path.expanduser('~'))
|
||||||
if islinux:
|
if islinux:
|
||||||
ADDRESS = (u'\0%s-calibre-gui.socket' % ascii_filename(force_unicode(user))).encode('ascii')
|
gui_socket_address.ans = (u'\0%s-calibre-gui.socket' % ascii_filename(force_unicode(user)))
|
||||||
else:
|
else:
|
||||||
from tempfile import gettempdir
|
from tempfile import gettempdir
|
||||||
tmp = gettempdir()
|
tmp = gettempdir()
|
||||||
ADDRESS = os.path.join(tmp, user+'-calibre-gui.socket')
|
gui_socket_address.ans = os.path.join(tmp, user+'-calibre-gui.socket')
|
||||||
return ADDRESS
|
if not ispy3 and not isinstance(gui_socket_address.ans, bytes):
|
||||||
|
gui_socket_address.ans = gui_socket_address.ans.encode(filesystem_encoding)
|
||||||
|
return gui_socket_address.ans
|
||||||
|
|
||||||
|
|
||||||
def viewer_socket_address():
|
def viewer_socket_address():
|
||||||
global VADDRESS
|
if viewer_socket_address.ans is None:
|
||||||
if VADDRESS is None:
|
|
||||||
if iswindows:
|
if iswindows:
|
||||||
VADDRESS = r'\\.\pipe\CalibreViewer'
|
viewer_socket_address.ans = r'\\.\pipe\CalibreViewer'
|
||||||
try:
|
try:
|
||||||
user = get_windows_username()
|
user = get_windows_username()
|
||||||
except:
|
except:
|
||||||
@ -64,18 +64,23 @@ def viewer_socket_address():
|
|||||||
if user:
|
if user:
|
||||||
user = ascii_filename(user).replace(' ', '_')
|
user = ascii_filename(user).replace(' ', '_')
|
||||||
if user:
|
if user:
|
||||||
VADDRESS += '-' + user[:100] + 'x'
|
viewer_socket_address.ans += '-' + user[:100] + 'x'
|
||||||
else:
|
else:
|
||||||
user = os.environ.get('USER', '')
|
user = os.environ.get('USER', '')
|
||||||
if not user:
|
if not user:
|
||||||
user = os.path.basename(os.path.expanduser('~'))
|
user = os.path.basename(os.path.expanduser('~'))
|
||||||
if islinux:
|
if islinux:
|
||||||
VADDRESS = (u'\0%s-calibre-viewer.socket' % ascii_filename(force_unicode(user))).encode('ascii')
|
viewer_socket_address.ans = (u'\0%s-calibre-viewer.socket' % ascii_filename(force_unicode(user)))
|
||||||
else:
|
else:
|
||||||
from tempfile import gettempdir
|
from tempfile import gettempdir
|
||||||
tmp = gettempdir()
|
tmp = gettempdir()
|
||||||
VADDRESS = os.path.join(tmp, user+'-calibre-viewer.socket')
|
viewer_socket_address.ans = os.path.join(tmp, user+'-calibre-viewer.socket')
|
||||||
return VADDRESS
|
if not ispy3 and not isinstance(viewer_socket_address.ans, bytes):
|
||||||
|
viewer_socket_address.ans = viewer_socket_address.ans.encode(filesystem_encoding)
|
||||||
|
return viewer_socket_address.ans
|
||||||
|
|
||||||
|
|
||||||
|
gui_socket_address.ans = viewer_socket_address.ans = None
|
||||||
|
|
||||||
|
|
||||||
class RC(Thread):
|
class RC(Thread):
|
||||||
|
@ -8,7 +8,7 @@ import binascii
|
|||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
from tempfile import SpooledTemporaryFile
|
from tempfile import SpooledTemporaryFile
|
||||||
|
|
||||||
from calibre import sanitize_file_name2
|
from calibre import sanitize_file_name
|
||||||
from calibre.constants import filesystem_encoding
|
from calibre.constants import filesystem_encoding
|
||||||
from calibre.ebooks.chardet import detect
|
from calibre.ebooks.chardet import detect
|
||||||
from polyglot.builtins import unicode_type, string_or_bytes
|
from polyglot.builtins import unicode_type, string_or_bytes
|
||||||
@ -1137,7 +1137,7 @@ class ZipFile:
|
|||||||
os.makedirs(upperdirs)
|
os.makedirs(upperdirs)
|
||||||
except: # Added by Kovid
|
except: # Added by Kovid
|
||||||
targetpath = os.path.join(base_target,
|
targetpath = os.path.join(base_target,
|
||||||
sanitize_file_name2(fname))
|
sanitize_file_name(fname))
|
||||||
upperdirs = os.path.dirname(targetpath)
|
upperdirs = os.path.dirname(targetpath)
|
||||||
if upperdirs and not os.path.exists(upperdirs):
|
if upperdirs and not os.path.exists(upperdirs):
|
||||||
os.makedirs(upperdirs)
|
os.makedirs(upperdirs)
|
||||||
@ -1158,7 +1158,7 @@ class ZipFile:
|
|||||||
except:
|
except:
|
||||||
# Try sanitizing the file name to remove invalid characters
|
# Try sanitizing the file name to remove invalid characters
|
||||||
components = list(os.path.split(targetpath))
|
components = list(os.path.split(targetpath))
|
||||||
components[-1] = sanitize_file_name2(components[-1])
|
components[-1] = sanitize_file_name(components[-1])
|
||||||
targetpath = os.sep.join(components)
|
targetpath = os.sep.join(components)
|
||||||
with open(targetpath, 'wb') as target:
|
with open(targetpath, 'wb') as target:
|
||||||
shutil.copyfileobj(source, target)
|
shutil.copyfileobj(source, target)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user