115 lines
3.5 KiB
Python
115 lines
3.5 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
openslides.utils.main
|
||
~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Some functions for OpenSlides.
|
||
|
||
:copyright: 2011–2013 by OpenSlides team, see AUTHORS.
|
||
:license: GNU GPL, see LICENSE for more details.
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import ctypes
|
||
|
||
|
||
UNIX_VERSION = 'Unix Version'
|
||
WINDOWS_VERSION = 'Windows Version'
|
||
WINDOWS_PORTABLE_VERSION = 'Windows Portable Version'
|
||
|
||
|
||
def filesystem2unicode(path):
|
||
"""
|
||
Transforms a path string to unicode according to the filesystem's encoding.
|
||
"""
|
||
# TODO: Delete this function after switch to Python 3.
|
||
if not isinstance(path, unicode):
|
||
filesystem_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
|
||
path = path.decode(filesystem_encoding)
|
||
return path
|
||
|
||
|
||
def detect_openslides_type():
|
||
"""
|
||
Returns the type of this version.
|
||
"""
|
||
if sys.platform == 'win32':
|
||
if os.path.basename(sys.executable).lower() == 'openslides.exe':
|
||
# Note: sys.executable is the path of the *interpreter*
|
||
# the portable version embeds python so it *is* the interpreter.
|
||
# The wrappers generated by pip and co. will spawn the usual
|
||
# python(w).exe, so there is no danger of mistaking them
|
||
# for the portable even though they may also be called
|
||
# openslides.exe
|
||
openslides_type = WINDOWS_PORTABLE_VERSION
|
||
else:
|
||
openslides_type = WINDOWS_VERSION
|
||
else:
|
||
openslides_type = UNIX_VERSION
|
||
return openslides_type
|
||
|
||
|
||
def is_portable():
|
||
"""
|
||
Helper function just for the GUI.
|
||
"""
|
||
# TODO: Remove this function.
|
||
return detect_openslides_type() == WINDOWS_PORTABLE_VERSION
|
||
|
||
|
||
def get_win32_app_data_path():
|
||
"""
|
||
Returns the path to Windows' AppData directory.
|
||
"""
|
||
shell32 = ctypes.WinDLL("shell32.dll")
|
||
SHGetFolderPath = shell32.SHGetFolderPathW
|
||
SHGetFolderPath.argtypes = (
|
||
ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_uint32,
|
||
ctypes.c_wchar_p)
|
||
SHGetFolderPath.restype = ctypes.c_uint32
|
||
|
||
CSIDL_LOCAL_APPDATA = 0x001c
|
||
MAX_PATH = 260
|
||
|
||
buf = ctypes.create_unicode_buffer(MAX_PATH)
|
||
res = SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, buf)
|
||
if res != 0:
|
||
raise Exception("Could not deterime APPDATA path")
|
||
|
||
return buf.value
|
||
|
||
|
||
def get_win32_portable_path():
|
||
"""
|
||
Returns the path to the Windows portable version.
|
||
"""
|
||
# NOTE: sys.executable will be the path to openslides.exe
|
||
# since it is essentially a small wrapper that embeds the
|
||
# python interpreter
|
||
portable_path = filesystem2unicode(os.path.dirname(os.path.abspath(sys.executable)))
|
||
try:
|
||
fd, test_file = tempfile.mkstemp(dir=portable_path)
|
||
except OSError:
|
||
raise Exception('Portable directory is not writeable. Please choose another directory for settings and local files.')
|
||
finally:
|
||
os.close(fd)
|
||
os.unlink(test_file)
|
||
return portable_path
|
||
|
||
|
||
def get_portable_paths(name):
|
||
"""
|
||
Returns the paths for the Windows portable version on runtime for the
|
||
SQLite3 database and the media directory. The argument 'name' can be
|
||
'database' or 'media'.
|
||
"""
|
||
if name == 'database':
|
||
path = os.path.join(get_win32_portable_path(), 'openslides', 'database.sqlite')
|
||
elif name == 'media':
|
||
path = os.path.join(get_win32_portable_path(), 'openslides', 'media', '')
|
||
else:
|
||
raise TypeError('Unknow type %s' % name)
|
||
return path
|