From 3b8d6e22ce4e561de4bb5dd04116d8e3dfdf430b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 17 May 2014 07:41:21 +0530 Subject: [PATCH] A more complete fix for non ascii usernames on windows when using the export file dialog. See #1298071 ([Edit book]: Crash exporting image) --- src/calibre/gui2/__init__.py | 15 ++++++++------- src/calibre/utils/filenames.py | 16 +++++++++++++++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 1828957232..2df4d0aa03 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -20,6 +20,7 @@ from calibre.utils.config import Config, ConfigProxy, dynamic, JSONConfig from calibre.ebooks.metadata import MetaInformation from calibre.utils.date import UNDEFINED_DATE from calibre.utils.localization import get_lang +from calibre.utils.filenames import expanduser # Setup gprefs {{{ gprefs = JSONConfig('gui') @@ -598,7 +599,7 @@ def select_initial_dir(q): if os.path.exists(c): return c q = c - return os.path.expanduser('~') + return expanduser(u'~') class FileDialog(QObject): def __init__(self, title=_('Choose Files'), @@ -608,7 +609,7 @@ class FileDialog(QObject): modal=True, name='', mode=QFileDialog.ExistingFiles, - default_dir='~', + default_dir=u'~', no_save_dir=False, combine_file_and_saved_dir=False ): @@ -632,20 +633,20 @@ class FileDialog(QObject): if combine_file_and_saved_dir: bn = os.path.basename(default_dir) prev = dynamic.get(self.dialog_name, - os.path.expanduser(u'~')) + expanduser(u'~')) if os.path.exists(prev): if os.path.isfile(prev): prev = os.path.dirname(prev) else: - prev = os.path.expanduser(u'~') + prev = expanduser(u'~') initial_dir = os.path.join(prev, bn) elif no_save_dir: - initial_dir = os.path.expanduser(default_dir) + initial_dir = expanduser(default_dir) else: initial_dir = dynamic.get(self.dialog_name, - os.path.expanduser(default_dir)) + expanduser(default_dir)) if not isinstance(initial_dir, basestring): - initial_dir = os.path.expanduser(default_dir) + initial_dir = expanduser(default_dir) if not initial_dir or (not os.path.exists(initial_dir) and not ( mode == QFileDialog.AnyFile and (no_save_dir or combine_file_and_saved_dir))): initial_dir = select_initial_dir(initial_dir) diff --git a/src/calibre/utils/filenames.py b/src/calibre/utils/filenames.py index e9a589fe8a..959be49c8d 100644 --- a/src/calibre/utils/filenames.py +++ b/src/calibre/utils/filenames.py @@ -489,4 +489,18 @@ def remove_dir_if_empty(path, ignore_metadata_caches=False): return raise - +if iswindows: + # Python's expanduser is broken for non-ASCII usernames + def expanduser(path): + if isinstance(path, bytes): + path = path.decode(filesystem_encoding) + if path[:1] != u'~': + return path + i, n = 1, len(path) + while i < n and path[i] not in u'/\\': + i += 1 + from win32com.shell import shell, shellcon + userhome = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, None, 0) + return userhome + path[i:] +else: + expanduser = os.path.expanduser