From e0223c950bcdcad1b57f532dcae811a5856f7eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20J=C3=A4ckel?= Date: Sat, 11 Jan 2014 15:47:15 +0100 Subject: [PATCH] Added possibility to use custom templates and static files in user data path directory. --- CHANGELOG | 2 + openslides/__main__.py | 5 +- openslides/global_settings.py | 15 ------ openslides/utils/main.py | 87 +++++--------------------------- openslides/utils/settings.py.tpl | 39 ++++++++------ tests/settings.py | 38 ++++++++------ tests/utils/test_main.py | 30 +++-------- 7 files changed, 68 insertions(+), 148 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 29d9f02e3..37ca1540c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -23,6 +23,8 @@ Other: - Enhanced http error pages. - Moved dashboard and select widgets view from projector to core app. - 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) diff --git a/openslides/__main__.py b/openslides/__main__.py index ad3daef33..11c5cb9c8 100644 --- a/openslides/__main__.py +++ b/openslides/__main__.py @@ -19,7 +19,6 @@ from openslides.utils.main import ( get_default_settings_path, get_default_user_data_path, get_port, - get_user_data_path_values_with_path, setup_django_settings_module, start_browser, write_settings) @@ -328,7 +327,9 @@ def create_dev_settings(settings, args): """ settings = os.path.join(os.getcwd(), 'settings.py') 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' write_settings(settings, **context) print('Settings file at %s successfully created.' % settings) diff --git a/openslides/global_settings.py b/openslides/global_settings.py index 8028aff5c..e39cc681d 100644 --- a/openslides/global_settings.py +++ b/openslides/global_settings.py @@ -6,7 +6,6 @@ from django.utils.translation import ugettext_lazy from openslides.utils.main import filesystem2unicode - SITE_ROOT = os.path.realpath(os.path.dirname(__file__)) 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/" 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 = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', @@ -81,14 +74,6 @@ MIDDLEWARE_CLASSES = ( 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 = ( 'django.contrib.auth', 'django.contrib.contenttypes', diff --git a/openslides/utils/main.py b/openslides/utils/main.py index a4f553208..5485c5e0c 100644 --- a/openslides/utils/main.py +++ b/openslides/utils/main.py @@ -13,7 +13,6 @@ from base64 import b64encode from django.core.exceptions import ImproperlyConfigured from django.conf import ENVIRONMENT_VARIABLE - UNIX_VERSION = 'Unix Version' WINDOWS_VERSION = 'Windows 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): """ - 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. """ # Setup path for user specific data (SQLite3 database, media, search index, ...): # Take it either from command line or get default path + default_context = {} if user_data_path: - default_context = get_user_data_path_values( - user_data_path=user_data_path, - default=False) + default_context['openslides_user_data_path'] = repr(user_data_path) + default_context['import_function'] = '' else: openslides_type = detect_openslides_type() - user_data_path = get_default_user_data_path(openslides_type) - default_context = get_user_data_path_values( - user_data_path=user_data_path, - default=True, - openslides_type=openslides_type) + if openslides_type == WINDOWS_PORTABLE_VERSION: + default_context['openslides_user_data_path'] = 'get_win32_portable_path()' + default_context['import_function'] = 'from openslides.utils.main import get_win32_portable_path' + else: + 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' return default_context @@ -204,54 +206,6 @@ def get_win32_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): """ 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) -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): """ Checks if the port for the server is available and returns it the port. If diff --git a/openslides/utils/settings.py.tpl b/openslides/utils/settings.py.tpl index 31bc5537b..5e1dac515 100644 --- a/openslides/utils/settings.py.tpl +++ b/openslides/utils/settings.py.tpl @@ -3,29 +3,28 @@ # Settings file for OpenSlides # -%(import_function)s +import os 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 DEBUG = %(debug)s 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 = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': %(database_path_value)s, + 'NAME': os.path.join(OPENSLIDES_USER_DATA_PATH, 'database.sqlite'), 'USER': '', 'PASSWORD': '', 'HOST': '', - 'PORT': '', - } -} - -# Set timezone -TIME_ZONE = 'Europe/Berlin' - -# Make this unique, and don't share it with anybody. -SECRET_KEY = %(secret_key)r + 'PORT': ''}} # Add OpenSlides plugins to this list (see example entry in comment) INSTALLED_PLUGINS = ( @@ -34,9 +33,17 @@ INSTALLED_PLUGINS = ( INSTALLED_APPS += INSTALLED_PLUGINS -# Absolute path to the directory that holds media. -# Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = %(media_path_value)s +# Some other settings +TIME_ZONE = 'Europe/Berlin' -# Path to Whoosh search index -HAYSTACK_CONNECTIONS['default']['PATH'] = %(whoosh_index_path_value)s +MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, 'media', '') + +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'))) diff --git a/tests/settings.py b/tests/settings.py index 238a91e36..f9b58b5ac 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -3,13 +3,20 @@ # Settings file for OpenSlides' tests # - +import os 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 DEBUG = True 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 = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', @@ -17,31 +24,30 @@ DATABASES = { 'USER': '', 'PASSWORD': '', 'HOST': '', - 'PORT': '', - } -} + 'PORT': ''}} -# Set timezone -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) +# Add OpenSlides plugins to this list INSTALLED_PLUGINS = ( 'tests.person_api', ) INSTALLED_APPS += INSTALLED_PLUGINS -# Absolute path to the directory that holds media. -# Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = os.path.realpath(os.path.dirname(__file__)) +# Some other settings +TIME_ZONE = 'Europe/Berlin' + +MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, '') -# Path to Whoosh search index -# Use RAM storage 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 PASSWORD_HASHERS = ( 'django.contrib.auth.hashers.MD5PasswordHasher', diff --git a/tests/utils/test_main.py b/tests/utils/test_main.py index e829f44a0..d1d8d11c3 100644 --- a/tests/utils/test_main.py +++ b/tests/utils/test_main.py @@ -15,11 +15,10 @@ from openslides.__main__ import ( from openslides.utils.main import ( get_browser_url, get_database_path_from_settings, + get_default_settings_context, get_default_settings_path, get_default_user_data_path, get_port, - get_portable_paths, - get_user_data_path_values, PortIsBlockedError, setup_django_settings_module, start_browser, @@ -36,20 +35,11 @@ class TestFunctions(TestCase): self.assertIn( os.path.join('.config', 'openslides', 'settings.py'), get_default_settings_path(UNIX_VERSION)) - def test_get_user_data_path_values_case_one(self): - values = get_user_data_path_values('/test_path_dfhvndshfgsef', default=False) - self.assertEqual(values['import_function'], '') - self.assertIn('database.sqlite', values['database_path_value']) - self.assertIn('media', values['media_path_value']) - 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')"}) + @patch('openslides.utils.main.detect_openslides_type') + def test_get_default_settings_context_portable(self, detect_mock): + detect_mock.return_value = WINDOWS_PORTABLE_VERSION + context = get_default_settings_context() + self.assertEqual(context['openslides_user_data_path'], 'get_win32_portable_path()') def test_setup_django_settings_module(self): 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): 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): """