OpenSlides/openslides/utils/main.py

120 lines
3.6 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
openslides.utils.main
~~~~~~~~~~~~~~~~~~~~~
Some functions for OpenSlides.
:copyright: 20112013 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
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
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:
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