Portable build: Fix cache directory not always being auto-created

Also rationalize _get_cache_dir() for all builds. Remove ancient fallback code
for people running from source without updated binaries. Fixes #1747887 [Cannot edit book](https://bugs.launchpad.net/calibre/+bug/1747887)
This commit is contained in:
Kovid Goyal 2018-02-10 08:45:24 +05:30
parent 506c3059bb
commit 5b7569e1db
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -96,11 +96,28 @@ def debug():
def _get_cache_dir(): def _get_cache_dir():
import errno
confcache = os.path.join(config_dir, u'caches') confcache = os.path.join(config_dir, u'caches')
try:
os.makedirs(confcache)
except EnvironmentError as err:
if err.errno != errno.EEXIST:
raise
if isportable: if isportable:
return confcache return confcache
if 'CALIBRE_CACHE_DIRECTORY' in os.environ: if 'CALIBRE_CACHE_DIRECTORY' in os.environ:
return os.path.abspath(os.environ['CALIBRE_CACHE_DIRECTORY']) if iswindows:
ans = get_unicode_windows_env_var(u'CALIBRE_CACHE_DIRECTORY')
else:
ans = os.path.abspath(os.environ['CALIBRE_CACHE_DIRECTORY'])
if isinstance(ans, bytes):
ans = ans.decode(filesystem_encoding)
try:
os.makedirs(ans)
return ans
except EnvironmentError as err:
if err.errno == errno.EEXIST:
return ans
if iswindows: if iswindows:
w = plugins['winutil'][0] w = plugins['winutil'][0]
@ -119,10 +136,10 @@ def _get_cache_dir():
candidate = candidate.decode(filesystem_encoding) candidate = candidate.decode(filesystem_encoding)
except ValueError: except ValueError:
candidate = confcache candidate = confcache
if not os.path.exists(candidate): try:
try: os.makedirs(candidate)
os.makedirs(candidate) except EnvironmentError as err:
except: if err.errno != errno.EEXIST:
candidate = confcache candidate = confcache
return candidate return candidate
@ -274,22 +291,12 @@ def get_version():
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(os.environ['CALIBRE_PORTABLE_BUILD'])) return os.path.dirname(os.path.dirname(get_unicode_windows_env_var(u'CALIBRE_PORTABLE_BUILD')))
def get_unicode_windows_env_var(name): def get_unicode_windows_env_var(name):
winutil = plugins['winutil'][0] getenv = plugins['winutil'][0].getenv
getenv = getattr(winutil, 'getenv', None) return getenv(unicode(name))
if getenv is not None:
return getenv(unicode(name))
import ctypes
name = unicode(name)
n = ctypes.windll.kernel32.GetEnvironmentVariableW(name, None, 0)
if n == 0:
return None
buf = ctypes.create_unicode_buffer(u'\0'*n)
ctypes.windll.kernel32.GetEnvironmentVariableW(name, buf, n)
return buf.value
def get_windows_username(): def get_windows_username():
@ -298,69 +305,25 @@ def get_windows_username():
Note that usernames on windows are case insensitive, the case of the value Note that usernames on windows are case insensitive, the case of the value
returned depends on what the user typed into the login box at login time. returned depends on what the user typed into the login box at login time.
''' '''
winutil = plugins['winutil'][0] username = plugins['winutil'][0].username
username = getattr(winutil, 'username', None) return username()
if username is not None:
return username()
import ctypes
from ctypes import wintypes
try:
advapi32 = ctypes.windll.advapi32
GetUserName = getattr(advapi32, u'GetUserNameW')
GetUserName.argtypes = [wintypes.LPWSTR, ctypes.POINTER(wintypes.DWORD)]
GetUserName.restype = wintypes.BOOL
except AttributeError:
pass
else:
buf = ctypes.create_unicode_buffer(257)
n = wintypes.DWORD(257)
if GetUserName(buf, ctypes.byref(n)):
return buf.value
return get_unicode_windows_env_var(u'USERNAME')
def get_windows_temp_path(): def get_windows_temp_path():
winutil = plugins['winutil'][0] temp_path = plugins['winutil'][0].temp_path
temp_path = getattr(winutil, 'temp_path', None) return temp_path()
if temp_path is not None:
return temp_path()
import ctypes
n = ctypes.windll.kernel32.GetTempPathW(0, None)
if n == 0:
return None
buf = ctypes.create_unicode_buffer(u'\0'*n)
ctypes.windll.kernel32.GetTempPathW(n, buf)
ans = buf.value
return ans if ans else None
def get_windows_user_locale_name(): def get_windows_user_locale_name():
winutil = plugins['winutil'][0] locale_name = plugins['winutil'][0].locale_name
locale_name = getattr(winutil, 'locale_name', None) return locale_name()
if locale_name is not None:
return locale_name()
import ctypes
k32 = ctypes.windll.kernel32
n = 255
buf = ctypes.create_unicode_buffer(u'\0'*n)
n = k32.GetUserDefaultLocaleName(buf, n)
if n == 0:
return None
return u'_'.join(buf.value.split(u'-')[:2])
def get_windows_number_formats(): def get_windows_number_formats():
ans = getattr(get_windows_number_formats, 'ans', None) ans = getattr(get_windows_number_formats, 'ans', None)
if ans is None: if ans is None:
winutil = plugins['winutil'][0] localeconv = plugins['winutil'][0].localeconv
localeconv = getattr(winutil, 'localeconv', None) d = localeconv()
if localeconv is not None: thousands_sep, decimal_point = d['thousands_sep'], d['decimal_point']
d = localeconv()
thousands_sep, decimal_point = d['thousands_sep'], d['decimal_point']
else:
from locale import localeconv
d = localeconv()
thousands_sep, decimal_point = d['thousands_sep'].decode('mbcs'), d['decimal_point'].decode('mbcs')
ans = get_windows_number_formats.ans = thousands_sep, decimal_point ans = get_windows_number_formats.ans = thousands_sep, decimal_point
return ans return ans