Rework default settings handling (fixes #409)
This commit is contained in:
parent
b75c9f32db
commit
c405e9b648
@ -13,13 +13,15 @@
|
|||||||
# for python 2.5 support
|
# for python 2.5 support
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import optparse
|
|
||||||
import socket
|
|
||||||
import time
|
|
||||||
import threading
|
|
||||||
import base64
|
import base64
|
||||||
|
import ctypes
|
||||||
|
import optparse
|
||||||
|
import os
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
|
||||||
import django.conf
|
import django.conf
|
||||||
@ -28,14 +30,15 @@ from django.core.management import execute_from_command_line
|
|||||||
CONFIG_TEMPLATE = """#!/usr/bin/env python
|
CONFIG_TEMPLATE = """#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import openslides.main
|
||||||
from openslides.global_settings import *
|
from openslides.global_settings import *
|
||||||
|
|
||||||
# Use 'DEBUG = True' to get more details for server errors
|
# Use 'DEBUG = True' to get more details for server errors
|
||||||
# (Default for relaeses: 'False')
|
# (Default for releases: 'False')
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
TEMPLATE_DEBUG = DEBUG
|
TEMPLATE_DEBUG = DEBUG
|
||||||
|
|
||||||
DBPATH = %(dbpath)r
|
DBPATH = %(dbpath)s
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
@ -64,6 +67,10 @@ INSTALLED_APPS += INSTALLED_PLUGINS
|
|||||||
|
|
||||||
KEY_LENGTH = 30
|
KEY_LENGTH = 30
|
||||||
|
|
||||||
|
# sentinel used to signal that the database ought to be stored
|
||||||
|
# relative to the portable's directory
|
||||||
|
_portable_db_path = object()
|
||||||
|
|
||||||
|
|
||||||
_fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
|
_fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
|
||||||
def _fs2unicode(s):
|
def _fs2unicode(s):
|
||||||
@ -71,8 +78,7 @@ def _fs2unicode(s):
|
|||||||
return s
|
return s
|
||||||
return s.decode(_fs_encoding)
|
return s.decode(_fs_encoding)
|
||||||
|
|
||||||
|
def process_options(argv = None):
|
||||||
def main(argv=None, opt_defaults=None, database_path=None):
|
|
||||||
if argv is None:
|
if argv is None:
|
||||||
argv = sys.argv[1:]
|
argv = sys.argv[1:]
|
||||||
|
|
||||||
@ -90,21 +96,48 @@ def main(argv=None, opt_defaults=None, database_path=None):
|
|||||||
parser.add_option(
|
parser.add_option(
|
||||||
"--no-reload", action="store_true", help="Do not reload the development server")
|
"--no-reload", action="store_true", help="Do not reload the development server")
|
||||||
|
|
||||||
if not opt_defaults is None:
|
|
||||||
parser.set_defaults(**opt_defaults)
|
|
||||||
|
|
||||||
opts, args = parser.parse_args(argv)
|
opts, args = parser.parse_args(argv)
|
||||||
if args:
|
if args:
|
||||||
sys.stderr.write("This command does not take arguments!\n\n")
|
sys.stderr.write("This command does not take arguments!\n\n")
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
return opts
|
||||||
|
|
||||||
|
def main(argv=None):
|
||||||
|
opts = process_options(argv)
|
||||||
|
_main(opts)
|
||||||
|
|
||||||
|
def win32_portable_main(argv=None):
|
||||||
|
"""special entry point for the win32 portable version"""
|
||||||
|
|
||||||
|
opts = process_options(argv)
|
||||||
|
|
||||||
|
database_path = None
|
||||||
|
|
||||||
|
if opts.settings is None:
|
||||||
|
portable_dir = get_portable_path()
|
||||||
|
try:
|
||||||
|
fd, test_file = tempfile.mkstemp(dir=portable_dir)
|
||||||
|
except OSError:
|
||||||
|
portable_dir_writeable = False
|
||||||
|
else:
|
||||||
|
portable_dir_writeable = True
|
||||||
|
os.close(fd)
|
||||||
|
os.unlink(test_file)
|
||||||
|
|
||||||
|
if portable_dir_writeable:
|
||||||
|
opts.settings = os.path.join(portable_dir,
|
||||||
|
"openslides", "settings.py")
|
||||||
|
database_path = _portable_db_path
|
||||||
|
|
||||||
|
_main(opts, database_path=database_path)
|
||||||
|
|
||||||
|
def _main(opts, database_path=None):
|
||||||
# Find the path to the settings
|
# Find the path to the settings
|
||||||
settings_path = opts.settings
|
settings_path = opts.settings
|
||||||
if settings_path is None:
|
if settings_path is None:
|
||||||
config_home = os.environ.get('XDG_CONFIG_HOME', \
|
settings_path = get_user_config_path('openslides', 'settings.py')
|
||||||
os.path.join(os.path.expanduser('~'), '.config'))
|
|
||||||
settings_path = os.path.join(config_home, 'openslides', 'settings.py')
|
|
||||||
|
|
||||||
# Create settings if necessary
|
# Create settings if necessary
|
||||||
if not os.path.exists(settings_path):
|
if not os.path.exists(settings_path):
|
||||||
@ -141,14 +174,17 @@ def main(argv=None, opt_defaults=None, database_path=None):
|
|||||||
def create_settings(settings_path, database_path=None):
|
def create_settings(settings_path, database_path=None):
|
||||||
settings_module = os.path.dirname(settings_path)
|
settings_module = os.path.dirname(settings_path)
|
||||||
|
|
||||||
if database_path is None:
|
if database_path is _portable_db_path:
|
||||||
data_home = os.environ.get('XDG_DATA_HOME', \
|
database_path = get_portable_db_path()
|
||||||
os.path.join(os.path.expanduser('~'), '.local', 'share'))
|
dbpath_value = 'openslides.main.get_portable_db_path()'
|
||||||
database_path = os.path.join(data_home, 'openslides', 'database.sqlite')
|
else:
|
||||||
|
if database_path is None:
|
||||||
|
database_path = get_user_data_path('openslides', 'database.sqlite')
|
||||||
|
dbpath_value = repr(_fs2unicode(database_path))
|
||||||
|
|
||||||
settings_content = CONFIG_TEMPLATE % dict(
|
settings_content = CONFIG_TEMPLATE % dict(
|
||||||
default_key=base64.b64encode(os.urandom(KEY_LENGTH)),
|
default_key=base64.b64encode(os.urandom(KEY_LENGTH)),
|
||||||
dbpath=_fs2unicode(database_path))
|
dbpath=dbpath_value)
|
||||||
|
|
||||||
if not os.path.exists(settings_module):
|
if not os.path.exists(settings_module):
|
||||||
os.makedirs(settings_module)
|
os.makedirs(settings_module)
|
||||||
@ -269,51 +305,56 @@ def start_browser(url):
|
|||||||
t = threading.Thread(target=f)
|
t = threading.Thread(target=f)
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
def win32_portable_main(argv=None):
|
def get_user_config_path(*args):
|
||||||
"""special entry point for the win32 portable version"""
|
if sys.platform == "win32":
|
||||||
import tempfile
|
return win32_get_app_data_path(*args)
|
||||||
|
|
||||||
|
config_home = os.environ.get('XDG_CONFIG_HOME', \
|
||||||
|
os.path.join(os.path.expanduser('~'), '.config'))
|
||||||
|
|
||||||
|
return os.path.join(_fs2unicode(config_home), *args)
|
||||||
|
|
||||||
|
def get_user_data_path(*args):
|
||||||
|
if sys.platform == "win32":
|
||||||
|
return win32_get_app_data_path(*args)
|
||||||
|
|
||||||
|
data_home = os.environ.get('XDG_DATA_HOME', \
|
||||||
|
os.path.join(os.path.expanduser('~'), '.local', 'share'))
|
||||||
|
|
||||||
|
return os.path.join(_fs2unicode(data_home), *args)
|
||||||
|
|
||||||
|
def get_portable_path(*args):
|
||||||
# NOTE: sys.executable will be the path to openslides.exe
|
# NOTE: sys.executable will be the path to openslides.exe
|
||||||
# since it is essentially a small wrapper that embeds the
|
# since it is essentially a small wrapper that embeds the
|
||||||
# python interpreter
|
# python interpreter
|
||||||
portable_dir = os.path.dirname(os.path.abspath(sys.executable))
|
|
||||||
try:
|
|
||||||
fd, test_file = tempfile.mkstemp(dir=portable_dir)
|
|
||||||
except OSError:
|
|
||||||
portable_dir_writeable = False
|
|
||||||
else:
|
|
||||||
portable_dir_writeable = True
|
|
||||||
os.close(fd)
|
|
||||||
os.unlink(test_file)
|
|
||||||
|
|
||||||
if portable_dir_writeable:
|
exename = os.path.basename(sys.executable).lower()
|
||||||
default_settings = os.path.join(portable_dir, "openslides",
|
if exename != "openslides.exe":
|
||||||
"openslides_personal_settings.py")
|
raise Exception("Cannot determine portable path when "
|
||||||
database_path = os.path.join(portable_dir, "openslides",
|
"not running as portable")
|
||||||
"database.sqlite")
|
|
||||||
else:
|
|
||||||
import ctypes
|
|
||||||
|
|
||||||
shell32 = ctypes.WinDLL("shell32.dll")
|
portable_dir = _fs2unicode(os.path.dirname(os.path.abspath(sys.executable)))
|
||||||
SHGetFolderPath = shell32.SHGetFolderPathW
|
return os.path.join(portable_dir, *args)
|
||||||
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
|
def get_portable_db_path():
|
||||||
MAX_PATH = 260
|
return get_portable_path('openslides', 'database.sqlite')
|
||||||
|
|
||||||
buf = ctypes.create_unicode_buffer(MAX_PATH)
|
def win32_get_app_data_path(*args):
|
||||||
res = SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, 0, buf)
|
shell32 = ctypes.WinDLL("shell32.dll")
|
||||||
if res != 0:
|
SHGetFolderPath = shell32.SHGetFolderPathW
|
||||||
raise Exception("Could not deterime APPDATA path")
|
SHGetFolderPath.argtypes = (ctypes.c_void_p, ctypes.c_int,
|
||||||
default_settings = os.path.join(buf.value, "openslides",
|
ctypes.c_void_p, ctypes.c_uint32, ctypes.c_wchar_p)
|
||||||
"openslides_personal_settings.py")
|
SHGetFolderPath.restype = ctypes.c_uint32
|
||||||
database_path = os.path.join(buf.value, "openslides",
|
|
||||||
"database.sqlite")
|
|
||||||
|
|
||||||
main(argv, opt_defaults={ "settings": default_settings },
|
CSIDL_LOCAL_APPDATA = 0x001c
|
||||||
database_path=database_path)
|
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 os.path.join(buf.value, *args)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
Loading…
Reference in New Issue
Block a user