Merge pull request #1169 from normanjaeckel/Loader

Added possibility to use custom templates and static files in user data ...
This commit is contained in:
Norman Jäckel 2014-01-12 03:48:09 -08:00
commit bc9bbb7280
7 changed files with 68 additions and 148 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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',

View File

@ -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

View File

@ -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')))

View File

@ -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',

View File

@ -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):
""" """