Updated settings files. Fixed timezone support.

This commit is contained in:
Norman Jäckel 2016-09-08 11:13:21 +02:00
parent 2753af3585
commit d7936c53e3
10 changed files with 221 additions and 132 deletions

View File

@ -34,6 +34,7 @@ Users:
- Added new matrix-interface for managing groups and their permissions. - Added new matrix-interface for managing groups and their permissions.
Other: Other:
- Django 1.10 is now supported. Dropped support for Django 1.8 and 1.9.
- Removed config cache to support multiple threads or processes. - Removed config cache to support multiple threads or processes.
- Fixed bug, that the last change of a config value was not send via autoupdate. - Fixed bug, that the last change of a config value was not send via autoupdate.
- Added template hooks for plugins (in item detail view and motion poll form). - Added template hooks for plugins (in item detail view and motion poll form).

View File

@ -1,11 +1,11 @@
from collections import defaultdict from collections import defaultdict
from datetime import datetime
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db import models, transaction from django.db import models, transaction
from django.utils import timezone
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy from django.utils.translation import ugettext_lazy
@ -415,7 +415,7 @@ class Speaker(RESTModelMixin, models.Model):
else: else:
current_speaker.end_speech() current_speaker.end_speech()
self.weight = None self.weight = None
self.begin_time = datetime.now() self.begin_time = timezone.now()
self.save() self.save()
if config['agenda_couple_countdown_and_speakers']: if config['agenda_couple_countdown_and_speakers']:
Countdown.control(action='reset') Countdown.control(action='reset')
@ -425,7 +425,7 @@ class Speaker(RESTModelMixin, models.Model):
""" """
The speech is finished. Set the time to now. The speech is finished. Set the time to now.
""" """
self.end_time = datetime.now() self.end_time = timezone.now()
self.save() self.save()
if config['agenda_couple_countdown_and_speakers']: if config['agenda_couple_countdown_and_speakers']:
Countdown.control(action='stop') Countdown.control(action='stop')

View File

@ -778,7 +778,7 @@ class MediaEncoder(utils_views.APIView):
:return: dictionary with the string representation (content) and the name of the file :return: dictionary with the string representation (content) and the name of the file
for the pdfMake.vfs structure for the pdfMake.vfs structure
""" """
path = os.path.join(settings.SITE_ROOT, 'static/fonts', os.path.basename(file_path)) path = os.path.join(settings.MODULE_DIR, 'static', 'fonts', os.path.basename(file_path))
try: try:
with open(path, "rb") as file: with open(path, "rb") as file:
string_representation = "{}".format(base64.b64encode(file.read()).decode()) string_representation = "{}".format(base64.b64encode(file.read()).decode())

View File

@ -2,16 +2,55 @@ import os
from openslides.utils.plugins import collect_plugins from openslides.utils.plugins import collect_plugins
SITE_ROOT = os.path.realpath(os.path.dirname(__file__)) MODULE_DIR = os.path.realpath(os.path.dirname(os.path.abspath(__file__)))
AUTH_USER_MODEL = 'users.User'
AUTHENTICATION_BACKENDS = ('openslides.users.auth.CustomizedModelBackend',) # Application definition
# Uses a db session backend, that saves the user_id directly in the db INSTALLED_APPS = [
SESSION_ENGINE = 'openslides.core.session_backend' 'openslides.core',
'openslides.users',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.staticfiles',
'rest_framework',
'channels',
'openslides.agenda',
'openslides.motions',
'openslides.assignments',
'openslides.mediafiles',
]
SESSION_COOKIE_NAME = 'OpenSlidesSessionID' INSTALLED_PLUGINS = collect_plugins() # Adds all automaticly collected plugins
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'openslides.urls'
ALLOWED_HOSTS = ['*']
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGE_CODE = 'en'
LANGUAGES = ( LANGUAGES = (
('en', 'English'), ('en', 'English'),
@ -22,83 +61,44 @@ LANGUAGES = (
('cs', 'Český'), ('cs', 'Český'),
) )
# If you set this to False, Django will make some optimizations so as not TIME_ZONE = 'UTC'
# to load the internationalization machinery.
USE_I18N = True USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale
USE_L10N = True USE_L10N = True
LOCALE_PATHS = ( USE_TZ = True
os.path.join(SITE_ROOT, 'locale'),
)
# URL that handles the media served from MEDIA_ROOT. Make sure to use a LOCALE_PATHS = [
# trailing slash if there is a path component (optional in other cases). os.path.join(MODULE_DIR, 'locale'),
# Examples: "http://media.lawrence.com", "http://example.com/media/" ]
MEDIA_URL = '/media/'
# Absolute path to the directory that holds static media from ``collectstatic``
# Example: "/home/media/static.lawrence.com/"
STATIC_ROOT = os.path.join(SITE_ROOT, '../collected-site-static')
# URL that handles the media served from STATIC_ROOT. Make sure to use a # Static files (CSS, JavaScript, Images)
# trailing slash if there is a path component (optional in other cases). # https://docs.djangoproject.com/en/1.10/howto/static-files/
# Examples: "http://static.lawrence.com", "http://example.com/static/"
STATIC_URL = '/static/' STATIC_URL = '/static/'
STATICFILES_FINDERS = ( STATIC_ROOT = os.path.join(MODULE_DIR, '..', 'collected-static')
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
STATICFILES_DIRS = [ STATICFILES_DIRS = [
os.path.join(SITE_ROOT, 'static')] os.path.join(MODULE_DIR, 'static'),
]
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'openslides.users.auth.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
ROOT_URLCONF = 'openslides.urls'
INSTALLED_APPS = (
'openslides.core',
'openslides.users',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'rest_framework',
'channels',
'openslides.poll', # TODO: try to remove this line
'openslides.agenda',
'openslides.motions',
'openslides.assignments',
'openslides.mediafiles',
)
CACHES = { # Sessions and user authentication
'default': { # https://docs.djangoproject.com/en/1.10/topics/http/sessions/
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # https://docs.djangoproject.com/en/1.10/topics/auth/
'LOCATION': 'openslidecache'
}
}
# Hosts/domain names that are valid for this site; required if DEBUG is False AUTH_USER_MODEL = 'users.User'
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = ['*']
# Adds all automaticly collected plugins AUTHENTICATION_BACKENDS = [
INSTALLED_PLUGINS = collect_plugins() 'openslides.users.auth.CustomizedModelBackend',
]
SESSION_ENGINE = 'openslides.core.session_backend'
SESSION_COOKIE_NAME = 'OpenSlidesSessionID'
PASSWORD_HASHERS = [ PASSWORD_HASHERS = [
'django.contrib.auth.hashers.PBKDF2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
@ -106,12 +106,30 @@ PASSWORD_HASHERS = [
'django.contrib.auth.hashers.Argon2PasswordHasher', 'django.contrib.auth.hashers.Argon2PasswordHasher',
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
'django.contrib.auth.hashers.BCryptPasswordHasher', 'django.contrib.auth.hashers.BCryptPasswordHasher',
'django.contrib.auth.hashers.MD5PasswordHasher', # MD5 is only used for inital passwords. 'django.contrib.auth.hashers.MD5PasswordHasher', # MD5 is only used for initial passwords.
] ]
TEST_RUNNER = 'openslides.utils.test.OpenSlidesDiscoverRunner'
# Config for the REST Framework # Files
# https://docs.djangoproject.com/en/1.10/topics/files/
MEDIA_URL = '/media/'
# Cache
# https://docs.djangoproject.com/en/1.10/topics/cache/
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'openslides-cache'
}
}
# Django REST framework
# http://www.django-rest-framework.org/api-guide/settings/
REST_FRAMEWORK = { REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ( 'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.SessionAuthentication',
@ -119,7 +137,10 @@ REST_FRAMEWORK = {
) )
} }
# Config for channels
# Django Channels
# http://channels.readthedocs.io/en/latest/
CHANNEL_LAYERS = { CHANNEL_LAYERS = {
'default': { 'default': {
'BACKEND': 'asgiref.inmemory.ChannelLayer', 'BACKEND': 'asgiref.inmemory.ChannelLayer',

View File

@ -15,13 +15,13 @@ from openslides.core.config import config
# register new truetype fonts # register new truetype fonts
pdfmetrics.registerFont(TTFont( pdfmetrics.registerFont(TTFont(
'Ubuntu', path_join(settings.SITE_ROOT, 'core/static/fonts/Ubuntu-R.ttf'))) 'Ubuntu', path_join(settings.MODULE_DIR, 'core', 'static', 'fonts', 'Ubuntu-R.ttf')))
pdfmetrics.registerFont(TTFont( pdfmetrics.registerFont(TTFont(
'Ubuntu-Bold', path_join(settings.SITE_ROOT, 'core/static/fonts/Ubuntu-B.ttf'))) 'Ubuntu-Bold', path_join(settings.MODULE_DIR, 'core', 'static', 'fonts', 'Ubuntu-B.ttf')))
pdfmetrics.registerFont(TTFont( pdfmetrics.registerFont(TTFont(
'Ubuntu-Italic', path_join(settings.SITE_ROOT, 'core/static/fonts/Ubuntu-RI.ttf'))) 'Ubuntu-Italic', path_join(settings.MODULE_DIR, 'core', 'static', 'fonts', 'Ubuntu-RI.ttf')))
pdfmetrics.registerFont(TTFont( pdfmetrics.registerFont(TTFont(
'circlefont', path_join(settings.SITE_ROOT, 'core/static/fonts/circle.ttf'))) 'circlefont', path_join(settings.MODULE_DIR, 'core', 'static', 'fonts', 'circle.ttf')))
pdfmetrics.registerFontFamily('Ubuntu', normal='Ubuntu', bold='Ubuntu-Bold', italic='Ubuntu-Italic') pdfmetrics.registerFontFamily('Ubuntu', normal='Ubuntu', bold='Ubuntu-Bold', italic='Ubuntu-Italic')

View File

@ -1,11 +1,11 @@
""" """
Settings file for OpenSlides Settings file for OpenSlides.
For more information on this file, see For more information on this file, see
https://docs.djangoproject.com/en/1.9/topics/settings/ https://docs.djangoproject.com/en/1.10/topics/settings/
For the full list of settings and their values, see For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.9/ref/settings/ https://docs.djangoproject.com/en/1.10/ref/settings/
""" """
import os import os
@ -17,18 +17,8 @@ from openslides.global_settings import *
OPENSLIDES_USER_DATA_PATH = %(openslides_user_data_path)s OPENSLIDES_USER_DATA_PATH = %(openslides_user_data_path)s
# SECURITY WARNING: Keep the secret key used in production secret!
SECRET_KEY = %(secret_key)r
# Use 'DEBUG = True' to get more details for server errors.
# SECURITY WARNING: Don't run with debug turned on in production!
DEBUG = %(debug)s
# OpenSlides plugins # OpenSlides plugins
# Add plugins to this list (see example entry in comment). # Add plugins to this list (see example entry in comment).
INSTALLED_PLUGINS += ( INSTALLED_PLUGINS += (
@ -38,26 +28,44 @@ INSTALLED_PLUGINS += (
INSTALLED_APPS += INSTALLED_PLUGINS INSTALLED_APPS += INSTALLED_PLUGINS
# Important settings for production use
# https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
# SECURITY WARNING: Keep the secret key used in production secret!
SECRET_KEY = %(secret_key)r
# Use 'DEBUG = True' to get more details for server errors.
# SECURITY WARNING: Don't run with debug turned on in production!
DEBUG = %(debug)s
# Database # Database
# Change this to use MySQL or PostgreSQL. # https://docs.djangoproject.com/en/1.10/ref/settings/#databases
# See https://docs.djangoproject.com/en/1.9/ref/settings/#databases
# Change this setting to use e. g. PostgreSQL or MySQL.
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(OPENSLIDES_USER_DATA_PATH, 'database.sqlite') 'NAME': os.path.join(OPENSLIDES_USER_DATA_PATH, 'db.sqlite3'),
} }
} }
# Big Mode # Django Channels
# Uncomment the following lines to activate redis as channel and cache backend.
# You have to install a redis server and the python packages asgi_redis and # Unless you have only a small assembly uncomment the following lines to
# django-redis for this to work. # activate Redis as backend for Django Channels and Cache. You have to install
# See https://channels.readthedocs.io/en/latest/backends.html#redis # a Redis server and the python packages asgi_redis and django-redis.
# https://niwinz.github.io/django-redis/latest/#_user_guide
# https://channels.readthedocs.io/en/latest/backends.html#redis
# CHANNEL_LAYERS['default']['BACKEND'] = 'asgi_redis.RedisChannelLayer' # CHANNEL_LAYERS['default']['BACKEND'] = 'asgi_redis.RedisChannelLayer'
# https://niwinz.github.io/django-redis/latest/#_user_guide
# CACHES = { # CACHES = {
# "default": { # "default": {
# "BACKEND": "django_redis.cache.RedisCache", # "BACKEND": "django_redis.cache.RedisCache",
@ -69,16 +77,25 @@ DATABASES = {
# } # }
# Some other settings # Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
TIME_ZONE = 'Europe/Berlin' TIME_ZONE = 'Europe/Berlin'
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, 'media', '')
TEMPLATE_DIRS = ( # Static files (CSS, JavaScript, Images)
os.path.join(OPENSLIDES_USER_DATA_PATH, 'templates'), # https://docs.djangoproject.com/en/1.10/howto/static-files/
)
STATICFILES_DIRS = [os.path.join(OPENSLIDES_USER_DATA_PATH, 'static')] + STATICFILES_DIRS STATICFILES_DIRS = [os.path.join(OPENSLIDES_USER_DATA_PATH, 'static')] + STATICFILES_DIRS
# Files
# https://docs.djangoproject.com/en/1.10/topics/files/
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, 'media', '')
# Whoosh search library
# https://whoosh.readthedocs.io/en/latest/
SEARCH_INDEX = os.path.join(OPENSLIDES_USER_DATA_PATH, 'search_index') SEARCH_INDEX = os.path.join(OPENSLIDES_USER_DATA_PATH, 'search_index')

View File

@ -1,5 +1,5 @@
# Requirements for OpenSlides in production in alphabetical order # Requirements for OpenSlides in production in alphabetical order
Django>=1.9,<1.11,!=1.10.0 Django>=1.10.1,<1.11
beautifulsoup4>=4.5,<4.6 beautifulsoup4>=4.5,<4.6
channels>=0.15,<1.0 channels>=0.15,<1.0
djangorestframework>=3.4,<3.5 djangorestframework>=3.4,<3.5

View File

@ -149,7 +149,7 @@ class RetrieveMotion(TestCase):
self.motion.create_poll() self.motion.create_poll()
def test_number_of_queries(self): def test_number_of_queries(self):
with self.assertNumQueries(17): with self.assertNumQueries(16):
self.client.get(reverse('motion-detail', args=[self.motion.pk])) self.client.get(reverse('motion-detail', args=[self.motion.pk]))

View File

@ -1,19 +1,19 @@
""" """
Settings file for OpenSlides' tests Settings file for OpenSlides' tests.
""" """
import os import os
from openslides.global_settings import * # noqa from openslides.global_settings import * # noqa
# Path to the directory for user specific data files # Path to the directory for user specific data files
OPENSLIDES_USER_DATA_PATH = os.path.realpath(os.path.dirname(__file__))
OPENSLIDES_USER_DATA_PATH = os.path.realpath(os.path.dirname(os.path.abspath(__file__)))
# SECURITY WARNING: Keep the secret key used in production secret!
SECRET_KEY = 'secret'
# OpenSlides plugins # OpenSlides plugins
# Add plugins to this list. # Add plugins to this list.
INSTALLED_PLUGINS += ( # noqa INSTALLED_PLUGINS += ( # noqa
@ -23,9 +23,18 @@ INSTALLED_PLUGINS += ( # noqa
INSTALLED_APPS += INSTALLED_PLUGINS # noqa INSTALLED_APPS += INSTALLED_PLUGINS # noqa
# Important settings for production use
# https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
SECRET_KEY = 'secret'
DEBUG = False
# Database # Database
# Change this to use MySQL or PostgreSQL. # https://docs.djangoproject.com/en/1.10/ref/settings/#databases
# See https://docs.djangoproject.com/en/1.7/ref/settings/#databases
# Change this setting to use e. g. PostgreSQL or MySQL.
DATABASES = { DATABASES = {
'default': { 'default': {
@ -34,20 +43,36 @@ DATABASES = {
} }
# Some other settings # Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
TIME_ZONE = 'Europe/Berlin' TIME_ZONE = 'Europe/Berlin'
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, '')
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
STATICFILES_DIRS.insert(0, os.path.join(OPENSLIDES_USER_DATA_PATH, 'static')) # noqa STATICFILES_DIRS.insert(0, os.path.join(OPENSLIDES_USER_DATA_PATH, 'static')) # noqa
# Files
# https://docs.djangoproject.com/en/1.10/topics/files/
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, '')
# Whoosh search library
# https://whoosh.readthedocs.io/en/latest/
SEARCH_INDEX = 'ram' SEARCH_INDEX = 'ram'
# Special test settings # Special settings only for testing
TEST_RUNNER = 'openslides.utils.test.OpenSlidesDiscoverRunner'
# Use a faster password hasher. # Use a faster password hasher.
PASSWORD_HASHERS = ( PASSWORD_HASHERS = [
'django.contrib.auth.hashers.MD5PasswordHasher', 'django.contrib.auth.hashers.MD5PasswordHasher',
) ]

View File

@ -1,19 +1,19 @@
""" """
Settings file for OpenSlides' tests Settings file for OpenSlides' tests.
""" """
import os import os
from openslides.global_settings import * # noqa from openslides.global_settings import * # noqa
# Path to the directory for user specific data files # Path to the directory for user specific data files
OPENSLIDES_USER_DATA_PATH = os.path.realpath(os.path.dirname(__file__))
OPENSLIDES_USER_DATA_PATH = os.path.realpath(os.path.dirname(os.path.abspath(__file__)))
# SECURITY WARNING: Keep the secret key used in production secret!
SECRET_KEY = 'secret'
# OpenSlides plugins # OpenSlides plugins
# Add plugins to this list. # Add plugins to this list.
INSTALLED_PLUGINS += ( # noqa INSTALLED_PLUGINS += ( # noqa
@ -23,9 +23,18 @@ INSTALLED_PLUGINS += ( # noqa
INSTALLED_APPS += INSTALLED_PLUGINS # noqa INSTALLED_APPS += INSTALLED_PLUGINS # noqa
# Important settings for production use
# https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
SECRET_KEY = 'secret'
DEBUG = False
# Database # Database
# Change this to use MySQL or PostgreSQL. # https://docs.djangoproject.com/en/1.10/ref/settings/#databases
# See https://docs.djangoproject.com/en/1.7/ref/settings/#databases
# Change this setting to use e. g. PostgreSQL or MySQL.
DATABASES = { DATABASES = {
'default': { 'default': {
@ -34,20 +43,36 @@ DATABASES = {
} }
# Some other settings # Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
TIME_ZONE = 'Europe/Berlin' TIME_ZONE = 'Europe/Berlin'
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, '')
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
STATICFILES_DIRS.insert(0, os.path.join(OPENSLIDES_USER_DATA_PATH, 'static')) # noqa STATICFILES_DIRS.insert(0, os.path.join(OPENSLIDES_USER_DATA_PATH, 'static')) # noqa
# Files
# https://docs.djangoproject.com/en/1.10/topics/files/
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, '')
# Whoosh search library
# https://whoosh.readthedocs.io/en/latest/
SEARCH_INDEX = 'ram' SEARCH_INDEX = 'ram'
# Special test settings # Special settings only for testing
TEST_RUNNER = 'openslides.utils.test.OpenSlidesDiscoverRunner'
# Use a faster password hasher. # Use a faster password hasher.
PASSWORD_HASHERS = ( PASSWORD_HASHERS = [
'django.contrib.auth.hashers.MD5PasswordHasher', 'django.contrib.auth.hashers.MD5PasswordHasher',
) ]