Merge pull request #1169 from normanjaeckel/Loader
Added possibility to use custom templates and static files in user data ...
This commit is contained in:
commit
bc9bbb7280
@ -23,6 +23,8 @@ Other:
|
|||||||
- Enhanced http error pages.
|
- Enhanced http error pages.
|
||||||
- Moved dashboard and select widgets view from projector to core app.
|
- Moved dashboard and select widgets view from projector to core app.
|
||||||
- Created a poll description field for each assignment-poll.
|
- Created a poll description field for each assignment-poll.
|
||||||
|
- Added possibility to use custom templates and static files in user data path
|
||||||
|
directory.
|
||||||
|
|
||||||
|
|
||||||
Version 1.5.1 (unreleased)
|
Version 1.5.1 (unreleased)
|
||||||
|
@ -19,7 +19,6 @@ from openslides.utils.main import (
|
|||||||
get_default_settings_path,
|
get_default_settings_path,
|
||||||
get_default_user_data_path,
|
get_default_user_data_path,
|
||||||
get_port,
|
get_port,
|
||||||
get_user_data_path_values_with_path,
|
|
||||||
setup_django_settings_module,
|
setup_django_settings_module,
|
||||||
start_browser,
|
start_browser,
|
||||||
write_settings)
|
write_settings)
|
||||||
@ -328,7 +327,9 @@ def create_dev_settings(settings, args):
|
|||||||
"""
|
"""
|
||||||
settings = os.path.join(os.getcwd(), 'settings.py')
|
settings = os.path.join(os.getcwd(), 'settings.py')
|
||||||
if not os.path.exists(settings):
|
if not os.path.exists(settings):
|
||||||
context = get_user_data_path_values_with_path(os.getcwd())
|
context = {}
|
||||||
|
context['openslides_user_data_path'] = repr(os.getcwd())
|
||||||
|
context['import_function'] = ''
|
||||||
context['debug'] = 'True'
|
context['debug'] = 'True'
|
||||||
write_settings(settings, **context)
|
write_settings(settings, **context)
|
||||||
print('Settings file at %s successfully created.' % settings)
|
print('Settings file at %s successfully created.' % settings)
|
||||||
|
@ -6,7 +6,6 @@ from django.utils.translation import ugettext_lazy
|
|||||||
|
|
||||||
from openslides.utils.main import filesystem2unicode
|
from openslides.utils.main import filesystem2unicode
|
||||||
|
|
||||||
|
|
||||||
SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
|
SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = (
|
AUTHENTICATION_BACKENDS = (
|
||||||
@ -52,12 +51,6 @@ STATIC_ROOT = filesystem2unicode(os.path.join(SITE_ROOT, '../collected-site-stat
|
|||||||
# Examples: "http://static.lawrence.com", "http://example.com/static/"
|
# Examples: "http://static.lawrence.com", "http://example.com/static/"
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
# Additional directories containing static files (not application specific)
|
|
||||||
# Examples: "/home/media/lawrence.com/extra-static/"
|
|
||||||
STATICFILES_DIRS = (
|
|
||||||
filesystem2unicode(os.path.join(SITE_ROOT, 'static')),
|
|
||||||
)
|
|
||||||
|
|
||||||
STATICFILES_FINDERS = (
|
STATICFILES_FINDERS = (
|
||||||
'django.contrib.staticfiles.finders.FileSystemFinder',
|
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||||
@ -81,14 +74,6 @@ MIDDLEWARE_CLASSES = (
|
|||||||
|
|
||||||
ROOT_URLCONF = 'openslides.urls'
|
ROOT_URLCONF = 'openslides.urls'
|
||||||
|
|
||||||
TEMPLATE_DIRS = (
|
|
||||||
# Put strings here, like "/home/html/django_templates" or
|
|
||||||
# "C:/www/django/templates".
|
|
||||||
# Always use forward slashes, even on Windows.
|
|
||||||
# Don't forget to use absolute paths, not relative paths.
|
|
||||||
filesystem2unicode(os.path.join(SITE_ROOT, 'templates')),
|
|
||||||
)
|
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
INSTALLED_APPS = (
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
|
@ -13,7 +13,6 @@ from base64 import b64encode
|
|||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.conf import ENVIRONMENT_VARIABLE
|
from django.conf import ENVIRONMENT_VARIABLE
|
||||||
|
|
||||||
|
|
||||||
UNIX_VERSION = 'Unix Version'
|
UNIX_VERSION = 'Unix Version'
|
||||||
WINDOWS_VERSION = 'Windows Version'
|
WINDOWS_VERSION = 'Windows Version'
|
||||||
WINDOWS_PORTABLE_VERSION = 'Windows Portable Version'
|
WINDOWS_PORTABLE_VERSION = 'Windows Portable Version'
|
||||||
@ -121,23 +120,26 @@ def ensure_settings(settings, args):
|
|||||||
|
|
||||||
def get_default_settings_context(user_data_path=None):
|
def get_default_settings_context(user_data_path=None):
|
||||||
"""
|
"""
|
||||||
Returns the default context values for the settings template.
|
Returns the default context values for the settings template:
|
||||||
|
'openslides_user_data_path', 'import_function' and 'debug'.
|
||||||
|
|
||||||
The argument 'user_data_path' is a given path for user specific data or None.
|
The argument 'user_data_path' is a given path for user specific data or None.
|
||||||
"""
|
"""
|
||||||
# Setup path for user specific data (SQLite3 database, media, search index, ...):
|
# Setup path for user specific data (SQLite3 database, media, search index, ...):
|
||||||
# Take it either from command line or get default path
|
# Take it either from command line or get default path
|
||||||
|
default_context = {}
|
||||||
if user_data_path:
|
if user_data_path:
|
||||||
default_context = get_user_data_path_values(
|
default_context['openslides_user_data_path'] = repr(user_data_path)
|
||||||
user_data_path=user_data_path,
|
default_context['import_function'] = ''
|
||||||
default=False)
|
|
||||||
else:
|
else:
|
||||||
openslides_type = detect_openslides_type()
|
openslides_type = detect_openslides_type()
|
||||||
user_data_path = get_default_user_data_path(openslides_type)
|
if openslides_type == WINDOWS_PORTABLE_VERSION:
|
||||||
default_context = get_user_data_path_values(
|
default_context['openslides_user_data_path'] = 'get_win32_portable_path()'
|
||||||
user_data_path=user_data_path,
|
default_context['import_function'] = 'from openslides.utils.main import get_win32_portable_path'
|
||||||
default=True,
|
else:
|
||||||
openslides_type=openslides_type)
|
path = get_default_user_data_path(openslides_type)
|
||||||
|
default_context['openslides_user_data_path'] = repr(os.path.join(path, 'openslides'))
|
||||||
|
default_context['import_function'] = ''
|
||||||
default_context['debug'] = 'False'
|
default_context['debug'] = 'False'
|
||||||
return default_context
|
return default_context
|
||||||
|
|
||||||
@ -204,54 +206,6 @@ def get_win32_portable_path():
|
|||||||
return portable_path
|
return portable_path
|
||||||
|
|
||||||
|
|
||||||
def get_user_data_path_values(user_data_path, default=False, openslides_type=None):
|
|
||||||
"""
|
|
||||||
Returns a dictionary of the user specific data path values for the new
|
|
||||||
settings file.
|
|
||||||
|
|
||||||
The argument 'user_data_path' is a path to the directory where OpenSlides
|
|
||||||
should store the user specific data like SQLite3 database, media and search
|
|
||||||
index.
|
|
||||||
|
|
||||||
The argument 'default' is a simple flag. If it is True and the OpenSlides
|
|
||||||
type is the Windows portable version, the returned dictionary contains
|
|
||||||
strings of callable functions for the settings file, else it contains
|
|
||||||
string paths.
|
|
||||||
|
|
||||||
The argument 'openslides_type' can to be one of the three types mentioned in
|
|
||||||
openslides.utils.main.
|
|
||||||
"""
|
|
||||||
if default and openslides_type == WINDOWS_PORTABLE_VERSION:
|
|
||||||
user_data_path_values = {}
|
|
||||||
user_data_path_values['import_function'] = 'from openslides.utils.main import get_portable_paths'
|
|
||||||
user_data_path_values['database_path_value'] = "get_portable_paths('database')"
|
|
||||||
user_data_path_values['media_path_value'] = "get_portable_paths('media')"
|
|
||||||
user_data_path_values['whoosh_index_path_value'] = "get_portable_paths('whoosh_index')"
|
|
||||||
else:
|
|
||||||
user_data_path_values = get_user_data_path_values_with_path(user_data_path, 'openslides')
|
|
||||||
return user_data_path_values
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_data_path_values_with_path(*paths):
|
|
||||||
"""
|
|
||||||
Returns a dictionary of the user specific data path values for the new
|
|
||||||
settings file. Therefor it uses the given arguments as parts of the path.
|
|
||||||
"""
|
|
||||||
final_path = os.path.abspath(os.path.join(*paths))
|
|
||||||
user_data_path_values = {}
|
|
||||||
user_data_path_values['import_function'] = ''
|
|
||||||
variables = (('database_path_value', 'database.sqlite'),
|
|
||||||
('media_path_value', 'media'),
|
|
||||||
('whoosh_index_path_value', 'whoosh_index'))
|
|
||||||
for key, value in variables:
|
|
||||||
path_list = [final_path, value]
|
|
||||||
if '.' not in value:
|
|
||||||
path_list.append('')
|
|
||||||
user_data_path_values[key] = repr(
|
|
||||||
filesystem2unicode(os.path.join(*path_list)))
|
|
||||||
return user_data_path_values
|
|
||||||
|
|
||||||
|
|
||||||
def write_settings(settings_path, template=None, **context):
|
def write_settings(settings_path, template=None, **context):
|
||||||
"""
|
"""
|
||||||
Creates the settings file at the given path using the given values for the
|
Creates the settings file at the given path using the given values for the
|
||||||
@ -269,23 +223,6 @@ def write_settings(settings_path, template=None, **context):
|
|||||||
settings_file.write(content)
|
settings_file.write(content)
|
||||||
|
|
||||||
|
|
||||||
def get_portable_paths(name):
|
|
||||||
"""
|
|
||||||
Returns the paths for the Windows portable version on runtime for the
|
|
||||||
SQLite3 database, the media directory and the search index. The argument
|
|
||||||
'name' can be 'database', 'media' or 'whoosh_index'.
|
|
||||||
"""
|
|
||||||
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', '')
|
|
||||||
elif name == 'whoosh_index':
|
|
||||||
path = os.path.join(get_win32_portable_path(), 'openslides', 'whoosh_index', '')
|
|
||||||
else:
|
|
||||||
raise TypeError('Unknown type %s' % name)
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def get_port(address, port):
|
def get_port(address, port):
|
||||||
"""
|
"""
|
||||||
Checks if the port for the server is available and returns it the port. If
|
Checks if the port for the server is available and returns it the port. If
|
||||||
|
@ -3,29 +3,28 @@
|
|||||||
# Settings file for OpenSlides
|
# Settings file for OpenSlides
|
||||||
#
|
#
|
||||||
|
|
||||||
%(import_function)s
|
import os
|
||||||
from openslides.global_settings import *
|
from openslides.global_settings import *
|
||||||
|
%(import_function)s
|
||||||
|
# Path to the directory for user specific data files
|
||||||
|
OPENSLIDES_USER_DATA_PATH = %(openslides_user_data_path)s
|
||||||
|
|
||||||
# Use 'DEBUG = True' to get more details for server errors. Default for releases: False
|
# Use 'DEBUG = True' to get more details for server errors. Default for releases: False
|
||||||
DEBUG = %(debug)s
|
DEBUG = %(debug)s
|
||||||
TEMPLATE_DEBUG = DEBUG
|
TEMPLATE_DEBUG = DEBUG
|
||||||
|
|
||||||
|
# Make this unique, and don't share it with anybody.
|
||||||
|
SECRET_KEY = %(secret_key)r
|
||||||
|
|
||||||
|
# Database settings. Change this to use MySQL or PostgreSQL
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
'NAME': %(database_path_value)s,
|
'NAME': os.path.join(OPENSLIDES_USER_DATA_PATH, 'database.sqlite'),
|
||||||
'USER': '',
|
'USER': '',
|
||||||
'PASSWORD': '',
|
'PASSWORD': '',
|
||||||
'HOST': '',
|
'HOST': '',
|
||||||
'PORT': '',
|
'PORT': ''}}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set timezone
|
|
||||||
TIME_ZONE = 'Europe/Berlin'
|
|
||||||
|
|
||||||
# Make this unique, and don't share it with anybody.
|
|
||||||
SECRET_KEY = %(secret_key)r
|
|
||||||
|
|
||||||
# Add OpenSlides plugins to this list (see example entry in comment)
|
# Add OpenSlides plugins to this list (see example entry in comment)
|
||||||
INSTALLED_PLUGINS = (
|
INSTALLED_PLUGINS = (
|
||||||
@ -34,9 +33,17 @@ INSTALLED_PLUGINS = (
|
|||||||
|
|
||||||
INSTALLED_APPS += INSTALLED_PLUGINS
|
INSTALLED_APPS += INSTALLED_PLUGINS
|
||||||
|
|
||||||
# Absolute path to the directory that holds media.
|
# Some other settings
|
||||||
# Example: "/home/media/media.lawrence.com/"
|
TIME_ZONE = 'Europe/Berlin'
|
||||||
MEDIA_ROOT = %(media_path_value)s
|
|
||||||
|
|
||||||
# Path to Whoosh search index
|
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, 'media', '')
|
||||||
HAYSTACK_CONNECTIONS['default']['PATH'] = %(whoosh_index_path_value)s
|
|
||||||
|
HAYSTACK_CONNECTIONS['default']['PATH'] = os.path.join(OPENSLIDES_USER_DATA_PATH, 'whoosh_index', '')
|
||||||
|
|
||||||
|
TEMPLATE_DIRS = (
|
||||||
|
os.path.join(OPENSLIDES_USER_DATA_PATH, 'templates'),
|
||||||
|
filesystem2unicode(os.path.join(SITE_ROOT, 'templates')))
|
||||||
|
|
||||||
|
STATICFILES_DIRS = (
|
||||||
|
os.path.join(OPENSLIDES_USER_DATA_PATH, 'static'),
|
||||||
|
filesystem2unicode(os.path.join(SITE_ROOT, 'static')))
|
||||||
|
@ -3,13 +3,20 @@
|
|||||||
# Settings file for OpenSlides' tests
|
# Settings file for OpenSlides' tests
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
from openslides.global_settings import * # noqa
|
from openslides.global_settings import * # noqa
|
||||||
|
|
||||||
|
# Path to the directory for user specific data files
|
||||||
|
OPENSLIDES_USER_DATA_PATH = os.path.realpath(os.path.dirname(__file__))
|
||||||
|
|
||||||
# Use 'DEBUG = True' to get more details for server errors. Default for releases: False
|
# Use 'DEBUG = True' to get more details for server errors. Default for releases: False
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
TEMPLATE_DEBUG = DEBUG
|
TEMPLATE_DEBUG = DEBUG
|
||||||
|
|
||||||
|
# Make this unique, and don't share it with anybody.
|
||||||
|
SECRET_KEY = 'secred'
|
||||||
|
|
||||||
|
# Database settings. Change this to use MySQL or PostgreSQL
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
@ -17,31 +24,30 @@ DATABASES = {
|
|||||||
'USER': '',
|
'USER': '',
|
||||||
'PASSWORD': '',
|
'PASSWORD': '',
|
||||||
'HOST': '',
|
'HOST': '',
|
||||||
'PORT': '',
|
'PORT': ''}}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set timezone
|
# Add OpenSlides plugins to this list
|
||||||
TIME_ZONE = 'Europe/Berlin'
|
|
||||||
|
|
||||||
# Make this unique, and don't share it with anybody.
|
|
||||||
SECRET_KEY = 'secred'
|
|
||||||
|
|
||||||
# Add OpenSlides plugins to this list (see example entry in comment)
|
|
||||||
INSTALLED_PLUGINS = (
|
INSTALLED_PLUGINS = (
|
||||||
'tests.person_api',
|
'tests.person_api',
|
||||||
)
|
)
|
||||||
|
|
||||||
INSTALLED_APPS += INSTALLED_PLUGINS
|
INSTALLED_APPS += INSTALLED_PLUGINS
|
||||||
|
|
||||||
# Absolute path to the directory that holds media.
|
# Some other settings
|
||||||
# Example: "/home/media/media.lawrence.com/"
|
TIME_ZONE = 'Europe/Berlin'
|
||||||
MEDIA_ROOT = os.path.realpath(os.path.dirname(__file__))
|
|
||||||
|
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, '')
|
||||||
|
|
||||||
# Path to Whoosh search index
|
|
||||||
# Use RAM storage
|
|
||||||
HAYSTACK_CONNECTIONS['default']['STORAGE'] = 'ram'
|
HAYSTACK_CONNECTIONS['default']['STORAGE'] = 'ram'
|
||||||
|
|
||||||
|
TEMPLATE_DIRS = (
|
||||||
|
os.path.join(OPENSLIDES_USER_DATA_PATH, 'templates'),
|
||||||
|
filesystem2unicode(os.path.join(SITE_ROOT, 'templates')))
|
||||||
|
|
||||||
|
STATICFILES_DIRS = (
|
||||||
|
os.path.join(OPENSLIDES_USER_DATA_PATH, 'static'),
|
||||||
|
filesystem2unicode(os.path.join(SITE_ROOT, 'static')))
|
||||||
|
|
||||||
# Use a faster passwort hasher
|
# Use a faster passwort hasher
|
||||||
PASSWORD_HASHERS = (
|
PASSWORD_HASHERS = (
|
||||||
'django.contrib.auth.hashers.MD5PasswordHasher',
|
'django.contrib.auth.hashers.MD5PasswordHasher',
|
||||||
|
@ -15,11 +15,10 @@ from openslides.__main__ import (
|
|||||||
from openslides.utils.main import (
|
from openslides.utils.main import (
|
||||||
get_browser_url,
|
get_browser_url,
|
||||||
get_database_path_from_settings,
|
get_database_path_from_settings,
|
||||||
|
get_default_settings_context,
|
||||||
get_default_settings_path,
|
get_default_settings_path,
|
||||||
get_default_user_data_path,
|
get_default_user_data_path,
|
||||||
get_port,
|
get_port,
|
||||||
get_portable_paths,
|
|
||||||
get_user_data_path_values,
|
|
||||||
PortIsBlockedError,
|
PortIsBlockedError,
|
||||||
setup_django_settings_module,
|
setup_django_settings_module,
|
||||||
start_browser,
|
start_browser,
|
||||||
@ -36,20 +35,11 @@ class TestFunctions(TestCase):
|
|||||||
self.assertIn(
|
self.assertIn(
|
||||||
os.path.join('.config', 'openslides', 'settings.py'), get_default_settings_path(UNIX_VERSION))
|
os.path.join('.config', 'openslides', 'settings.py'), get_default_settings_path(UNIX_VERSION))
|
||||||
|
|
||||||
def test_get_user_data_path_values_case_one(self):
|
@patch('openslides.utils.main.detect_openslides_type')
|
||||||
values = get_user_data_path_values('/test_path_dfhvndshfgsef', default=False)
|
def test_get_default_settings_context_portable(self, detect_mock):
|
||||||
self.assertEqual(values['import_function'], '')
|
detect_mock.return_value = WINDOWS_PORTABLE_VERSION
|
||||||
self.assertIn('database.sqlite', values['database_path_value'])
|
context = get_default_settings_context()
|
||||||
self.assertIn('media', values['media_path_value'])
|
self.assertEqual(context['openslides_user_data_path'], 'get_win32_portable_path()')
|
||||||
self.assertIn('whoosh_index', values['whoosh_index_path_value'])
|
|
||||||
|
|
||||||
def test_get_user_data_path_values_case_two(self):
|
|
||||||
self.assertEqual(
|
|
||||||
get_user_data_path_values('test_path_dfhvndshfgsef', default=True, openslides_type=WINDOWS_PORTABLE_VERSION),
|
|
||||||
{'import_function': 'from openslides.utils.main import get_portable_paths',
|
|
||||||
'database_path_value': "get_portable_paths('database')",
|
|
||||||
'media_path_value': "get_portable_paths('media')",
|
|
||||||
'whoosh_index_path_value': "get_portable_paths('whoosh_index')"})
|
|
||||||
|
|
||||||
def test_setup_django_settings_module(self):
|
def test_setup_django_settings_module(self):
|
||||||
setup_django_settings_module('test_dir_dhvnghfjdh456fzheg2f/test_path_bngjdhc756dzwncshdfnx.py')
|
setup_django_settings_module('test_dir_dhvnghfjdh456fzheg2f/test_path_bngjdhc756dzwncshdfnx.py')
|
||||||
@ -101,14 +91,6 @@ class TestFunctions(TestCase):
|
|||||||
def test_get_database_path_from_settings_memory(self):
|
def test_get_database_path_from_settings_memory(self):
|
||||||
self.assertEqual(get_database_path_from_settings(), ':memory:')
|
self.assertEqual(get_database_path_from_settings(), ':memory:')
|
||||||
|
|
||||||
@patch('openslides.utils.main.get_win32_portable_path')
|
|
||||||
def test_get_portable_paths(self, mock_get_win32_portable_path):
|
|
||||||
mock_get_win32_portable_path.return_value = '/test_path_AhgheeGee1eixaeYe1ra'
|
|
||||||
self.assertEqual(get_portable_paths('database'), '/test_path_AhgheeGee1eixaeYe1ra/openslides/database.sqlite')
|
|
||||||
self.assertEqual(get_portable_paths('media'), '/test_path_AhgheeGee1eixaeYe1ra/openslides/media/')
|
|
||||||
self.assertEqual(get_portable_paths('whoosh_index'), '/test_path_AhgheeGee1eixaeYe1ra/openslides/whoosh_index/')
|
|
||||||
self.assertRaisesMessage(TypeError, 'Unknown type unknown_string', get_portable_paths, 'unknown_string')
|
|
||||||
|
|
||||||
|
|
||||||
class TestOtherFunctions(TestCase):
|
class TestOtherFunctions(TestCase):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user