2013-09-08 14:30:26 +02:00
|
|
|
|
#!/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
|
2013-10-12 21:30:34 +02:00
|
|
|
|
import tempfile
|
2013-09-08 14:30:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UNIX_VERSION = 'Unix Version'
|
|
|
|
|
WINDOWS_VERSION = 'Windows Version'
|
|
|
|
|
WINDOWS_PORTABLE_VERSION = 'Windows Portable Version'
|
|
|
|
|
|
2013-10-12 21:30:34 +02:00
|
|
|
|
class PortableDirNotWritable(Exception):
|
|
|
|
|
pass
|
2013-09-08 14:30:26 +02:00
|
|
|
|
|
|
|
|
|
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:
|
2013-10-12 21:30:34 +02:00
|
|
|
|
raise PortableDirNotWritable(
|
|
|
|
|
'Portable directory is not writeable. '
|
|
|
|
|
'Please choose another directory for settings and local files.')
|
|
|
|
|
else:
|
2013-09-08 14:30:26 +02:00
|
|
|
|
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
|