Merge pull request #1789 from ostcar/update_requirements

Update requirements
This commit is contained in:
Oskar Hahn 2016-01-09 12:22:41 +01:00
commit 4b69c57c78
29 changed files with 281 additions and 129 deletions

View File

@ -6,7 +6,6 @@ cache:
- $HOME/virtualenv/python$TRAVIS_PYTHON_VERSION/lib/python$TRAVIS_PYTHON_VERSION/site-packages/
- $HOME/virtualenv/python$TRAVIS_PYTHON_VERSION/bin/
python:
- "3.3"
- "3.4"
- "3.5"
install:

View File

@ -29,7 +29,7 @@ Other:
- New OpenSlides logo.
- New design for web interface.
- Added multiple countdown support.
- Changed supported Python version to >= 3.3.
- Changed supported Python version to >= 3.4.
- Used Django 1.7 as lowest requirement.
- Added Django's application configuration. Refactored loading of signals
and projector elements/slides.
@ -56,6 +56,7 @@ Other:
- Used setup.cfg for development tools.
- Removed code for Windows portable version with GUI. Used new repository for
this.
- Django 1.9 is supported
Translations:
- Added DE and FR translations.

View File

@ -26,7 +26,7 @@ Installation on GNU/Linux or Mac OS X
1. Check requirements
Make sure that you have installed Python Programming Language 3 (>= 3.3)
Make sure that you have installed Python Programming Language 3 (>= 3.4)
on your system. You will also need the Python development headers.
For example for Ubuntu run::
@ -73,7 +73,7 @@ portable version you should observe the following install steps.*
1. Check requirements
Make sure that you have installed Python Programming Language 3 (>= 3.3)
Make sure that you have installed Python Programming Language 3 (>= 3.4)
and Setuptools on your system.
a. Download and run the latest `Python 3.4 32-bit MSI installer
@ -170,7 +170,7 @@ Installation and start of the development version
1. Check requirements
You need to have `Python 3 (>=3.3) <https://www.python.org/>`_, `Node.js
You need to have `Python 3 (>=3.4) <https://www.python.org/>`_, `Node.js
(>=0.10) <https://nodejs.org/>`_ and `Git <http://git-scm.com/>`_
installed. See also step 1 in the correspondent instruction in section
III.

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.1 on 2016-01-09 11:45
from __future__ import unicode_literals
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('agenda', '0005_auto_20151210_0016'),
]
operations = [
migrations.AlterField(
model_name='item',
name='content_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='contenttypes.ContentType'),
),
migrations.AlterField(
model_name='item',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='agenda.Item'),
),
]

View File

@ -190,7 +190,12 @@ class Item(RESTModelMixin, models.Model):
The intended duration for the topic.
"""
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
parent = models.ForeignKey(
'self',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='children')
"""
The parent item in the agenda tree.
"""
@ -200,7 +205,11 @@ class Item(RESTModelMixin, models.Model):
Weight to sort the item in the agenda.
"""
content_type = models.ForeignKey(ContentType, null=True, blank=True)
content_type = models.ForeignKey(
ContentType,
on_delete=models.SET_NULL,
null=True,
blank=True)
"""
Field for generic relation to a related object. Type of the object.
"""
@ -318,12 +327,17 @@ class Speaker(RESTModelMixin, models.Model):
objects = SpeakerManager()
user = models.ForeignKey(settings.AUTH_USER_MODEL)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
"""
ForeinKey to the user who speaks.
"""
item = models.ForeignKey(Item, related_name='speakers')
item = models.ForeignKey(
Item,
on_delete=models.CASCADE,
related_name='speakers')
"""
ForeinKey to the agenda item to which the user want to speak.
"""

View File

@ -1,10 +1,9 @@
from django.conf.urls import patterns, url
from django.conf.urls import url
from . import views
urlpatterns = patterns(
'',
urlpatterns = [
url(r'^print/$',
views.AgendaPDF.as_view(),
name='agenda_pdf'),
)
]

View File

@ -1,4 +1,4 @@
from cgi import escape
from html import escape
from django.contrib.auth import get_user_model
from django.db import transaction

View File

@ -1,7 +1,8 @@
from collections import OrderedDict
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext_lazy, ugettext_noop
from openslides.agenda.models import Item, Speaker
@ -34,9 +35,11 @@ class AssignmentRelatedUser(RESTModelMixin, models.Model):
assignment = models.ForeignKey(
'Assignment',
db_index=True,
on_delete=models.CASCADE,
related_name='assignment_related_users')
user = models.ForeignKey(settings.AUTH_USER_MODEL, db_index=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
status = models.IntegerField(
choices=STATUSES,
default=STATUS_CANDIDATE)
@ -272,7 +275,7 @@ class Assignment(RESTModelMixin, models.Model):
Returns a table represented as a list with all candidates from all
related polls and their vote results.
"""
vote_results_dict = SortedDict()
vote_results_dict = OrderedDict()
polls = self.polls.all()
if only_published:
@ -331,7 +334,10 @@ class Assignment(RESTModelMixin, models.Model):
class AssignmentVote(RESTModelMixin, BaseVote):
option = models.ForeignKey('AssignmentOption', related_name='votes')
option = models.ForeignKey(
'AssignmentOption',
on_delete=models.CASCADE,
related_name='votes')
class Meta:
default_permissions = ()
@ -344,8 +350,13 @@ class AssignmentVote(RESTModelMixin, BaseVote):
class AssignmentOption(RESTModelMixin, BaseOption):
poll = models.ForeignKey('AssignmentPoll', related_name='options')
candidate = models.ForeignKey(settings.AUTH_USER_MODEL)
poll = models.ForeignKey(
'AssignmentPoll',
on_delete=models.CASCADE,
related_name='options')
candidate = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
vote_class = AssignmentVote
class Meta:
@ -366,7 +377,10 @@ class AssignmentPoll(RESTModelMixin, CollectDefaultVotesMixin,
slide_callback_name = 'assignmentpoll'
option_class = AssignmentOption
assignment = models.ForeignKey(Assignment, related_name='polls')
assignment = models.ForeignKey(
Assignment,
on_delete=models.CASCADE,
related_name='polls')
yesnoabstain = models.BooleanField(default=False)
description = models.CharField(
max_length=79,

View File

@ -1,9 +1,8 @@
from django.conf.urls import patterns, url
from django.conf.urls import url
from . import views
urlpatterns = patterns(
'',
urlpatterns = [
url(r'^print/$',
views.AssignmentPDF.as_view(),
name='assignments_pdf'),
@ -15,4 +14,4 @@ urlpatterns = patterns(
url(r'^poll/(?P<poll_pk>\d+)/print/$',
views.AssignmentPollPDF.as_view(),
name='assignmentpoll_pdf'),
)
]

View File

@ -1,4 +1,4 @@
from cgi import escape
from html import escape
from django.conf import settings
from django.contrib.auth import get_user_model

View File

@ -1,12 +1,13 @@
import errno
import os
import socket
import sys
from datetime import datetime
from django.core.exceptions import ImproperlyConfigured
from django.conf import settings
from django.core.management.commands.runserver import Command as _Command
from django.utils import translation
from django.utils.encoding import force_text
from django.utils import six
from django.utils.encoding import force_text, get_system_encoding
from openslides.utils.autoupdate import run_tornado
@ -17,32 +18,34 @@ class Command(_Command):
Only the line to run tornado has changed from the django default
implementation.
The Code is from django 1.9
"""
# TODO: do not start tornado when the settings says so
def inner_run(self, *args, **options):
from django.conf import settings
# From the base class:
self.stdout.write("Performing system checks...\n\n")
self.validate(display_num_errors=True)
try:
self.check_migrations()
except ImproperlyConfigured:
pass
now = datetime.now().strftime('%B %d, %Y - %X')
# If an exception was silenced in ManagementUtility.execute in order
# to be raised in the child process, raise it now.
# OPENSLIDES: We do not use the django autoreload command
# autoreload.raise_last_exception()
# OPENSLIDES: This line is not needed by tornado
# threading = options.get('use_threading')
shutdown_message = options.get('shutdown_message', '')
quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C'
self.stdout.write("Performing system checks...\n\n")
self.check(display_num_errors=True)
self.check_migrations()
now = datetime.now().strftime('%B %d, %Y - %X')
if six.PY2:
now = now.decode(get_system_encoding())
self.stdout.write(now)
self.stdout.write((
"%(started_at)s\n"
"Django version %(version)s, using settings %(settings)r\n"
"Starting development server at http://%(addr)s:%(port)s/\n"
"Quit the server with %(quit_command)s.\n"
) % {
"started_at": now,
"version": self.get_version(),
"settings": settings.SETTINGS_MODULE,
"addr": '[%s]' % self.addr if self._raw_ipv6 else self.addr,
@ -50,8 +53,6 @@ class Command(_Command):
"quit_command": quit_command,
})
translation.activate(settings.LANGUAGE_CODE)
try:
handler = self.get_handler(*args, **options)
run_tornado(
@ -64,14 +65,15 @@ class Command(_Command):
ERRORS = {
errno.EACCES: "You don't have permission to access that port.",
errno.EADDRINUSE: "That port is already in use.",
errno.EADDRNOTAVAIL: "That IP address can't be assigned-to.",
errno.EADDRNOTAVAIL: "That IP address can't be assigned to.",
}
try:
error_text = ERRORS[e.errno]
except KeyError:
error_text = force_text(e)
self.stderr.write("Error: %s" % error_text)
sys.exit(0)
# Need to use an OS exit because sys.exit doesn't work in a thread
os._exit(1)
except KeyboardInterrupt:
if shutdown_message:
self.stdout.write(shutdown_message)

View File

@ -217,6 +217,7 @@ class ChatMessage(RESTModelMixin, models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
verbose_name=ugettext_lazy('User'))
class Meta:

View File

@ -54,12 +54,6 @@ STATICFILES_FINDERS = (
STATICFILES_DIRS = [
os.path.join(SITE_ROOT, 'static')]
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',

View File

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.1 on 2016-01-09 11:45
from __future__ import unicode_literals
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mediafiles', '0004_auto_20151210_0016'),
]
operations = [
migrations.AlterField(
model_name='mediafile',
name='uploader',
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to=settings.AUTH_USER_MODEL,
verbose_name='Uploaded by'),
),
]

View File

@ -21,7 +21,12 @@ class Mediafile(RESTModelMixin, models.Model):
title = models.CharField(max_length=255, unique=True, blank=True, verbose_name=ugettext_lazy('Title'))
"""A string representing the title of the file."""
uploader = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, verbose_name=ugettext_lazy('Uploaded by'))
uploader = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name=ugettext_lazy('Uploaded by'))
"""A user the uploader of a file."""
timestamp = models.DateTimeField(auto_now_add=True)

View File

@ -1,10 +0,0 @@
{% load i18n %}
{% load highlight %}
{% if perms.mediafiles.can_see %}
<li>
<a href="{{ result.object.get_absolute_url }}">{{ result.object }}</a><br>
<span class="app">{% trans "File" %}</a></span><br>
{% highlight result.text with request.GET.q %}
</li>
{% endif %}

View File

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.1 on 2016-01-09 11:45
from __future__ import unicode_literals
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('motions', '0005_auto_20151210_0019'),
]
operations = [
migrations.AlterField(
model_name='motion',
name='category',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='motions.Category'),
),
migrations.AlterField(
model_name='motion',
name='parent',
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name='amendments',
to='motions.Motion'),
),
migrations.AlterField(
model_name='motion',
name='state',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='motions.State'),
),
migrations.AlterField(
model_name='motionlog',
name='person',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='workflow',
name='first_state',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='motions.State'),
),
]

View File

@ -35,9 +35,11 @@ class Motion(RESTModelMixin, models.Model):
Name of the callback for the slide-system.
"""
active_version = models.ForeignKey('MotionVersion', null=True,
related_name="active_version",
on_delete=models.SET_NULL)
active_version = models.ForeignKey(
'MotionVersion',
on_delete=models.SET_NULL,
null=True,
related_name="active_version")
"""
Points to a specific version.
@ -46,7 +48,10 @@ class Motion(RESTModelMixin, models.Model):
version. Like the sighted versions on Wikipedia.
"""
state = models.ForeignKey('State', null=True) # TODO: Check whether null=True is necessary.
state = models.ForeignKey(
'State',
on_delete=models.SET_NULL,
null=True) # TODO: Check whether null=True is necessary.
"""
The related state object.
@ -66,7 +71,11 @@ class Motion(RESTModelMixin, models.Model):
Needed to find the next free motion identifier.
"""
category = models.ForeignKey('Category', null=True, blank=True)
category = models.ForeignKey(
'Category',
on_delete=models.SET_NULL,
null=True,
blank=True)
"""
ForeignKey to one category of motions.
"""
@ -76,7 +85,12 @@ class Motion(RESTModelMixin, models.Model):
Many to many relation to mediafile objects.
"""
parent = models.ForeignKey('self', null=True, blank=True, related_name='amendments')
parent = models.ForeignKey(
'self',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='amendments')
"""
Field for amendments to reference to the motion that should be altered.
@ -557,7 +571,10 @@ class MotionVersion(RESTModelMixin, models.Model):
A MotionVersion object saves some date of the motion.
"""
motion = models.ForeignKey(Motion, related_name='versions')
motion = models.ForeignKey(
Motion,
on_delete=models.CASCADE,
related_name='versions')
"""The motion to which the version belongs."""
version_number = models.PositiveIntegerField(default=1)
@ -623,7 +640,10 @@ class Category(RESTModelMixin, models.Model):
class MotionLog(RESTModelMixin, models.Model):
"""Save a logmessage for a motion."""
motion = models.ForeignKey(Motion, related_name='log_messages')
motion = models.ForeignKey(
Motion,
on_delete=models.CASCADE,
related_name='log_messages')
"""The motion to witch the object belongs."""
message_list = JSONField()
@ -631,7 +651,10 @@ class MotionLog(RESTModelMixin, models.Model):
The log message. It should be a list of strings in English.
"""
person = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
person = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
null=True)
"""A user object, who created the log message. Optional."""
time = models.DateTimeField(auto_now=True)
@ -665,7 +688,9 @@ class MotionVote(RESTModelMixin, BaseVote):
There should allways be three MotionVote objects for each poll,
one for 'yes', 'no', and 'abstain'."""
option = models.ForeignKey('MotionOption')
option = models.ForeignKey(
'MotionOption',
on_delete=models.CASCADE)
"""The option object, to witch the vote belongs."""
class Meta:
@ -683,7 +708,9 @@ class MotionOption(RESTModelMixin, BaseOption):
There should be one MotionOption object for each poll."""
poll = models.ForeignKey('MotionPoll')
poll = models.ForeignKey(
'MotionPoll',
on_delete=models.CASCADE)
"""The poll object, to witch the object belongs."""
vote_class = MotionVote
@ -705,7 +732,10 @@ class MotionPoll(RESTModelMixin, CollectDefaultVotesMixin, BasePoll):
slide_callback_name = 'motionpoll'
"""Name of the callback for the slide-system."""
motion = models.ForeignKey(Motion, related_name='polls')
motion = models.ForeignKey(
Motion,
on_delete=models.CASCADE,
related_name='polls')
"""The motion to witch the object belongs."""
option_class = MotionOption
@ -759,7 +789,10 @@ class State(RESTModelMixin, models.Model):
action_word = models.CharField(max_length=255)
"""An alternative string to be used for a button to switch to this state."""
workflow = models.ForeignKey('Workflow', related_name='states')
workflow = models.ForeignKey(
'Workflow',
on_delete=models.CASCADE,
related_name='states')
"""A many-to-one relation to a workflow."""
next_states = models.ManyToManyField('self', symmetrical=False)
@ -850,7 +883,11 @@ class Workflow(RESTModelMixin, models.Model):
name = models.CharField(max_length=255)
"""A string representing the workflow."""
first_state = models.OneToOneField(State, related_name='+', null=True)
first_state = models.OneToOneField(
State,
on_delete=models.SET_NULL,
related_name='+',
null=True)
"""A one-to-one relation to a state, the starting point for the workflow."""
class Meta:

View File

@ -1,5 +1,5 @@
import random
from cgi import escape
from html import escape
from operator import attrgetter
from bs4 import BeautifulSoup

View File

@ -1,9 +1,8 @@
from django.conf.urls import patterns, url
from django.conf.urls import url
from . import views
urlpatterns = patterns(
'',
urlpatterns = [
url(r'^pdf/$',
views.MotionPDFView.as_view(print_all_motions=True),
name='motions_pdf'),
@ -11,4 +10,4 @@ urlpatterns = patterns(
url(r'^(?P<pk>\d+)/pdf/$',
views.MotionPDFView.as_view(print_all_motions=False),
name='motions_single_pdf'),
)
]

View File

@ -1,4 +1,4 @@
from django.conf.urls import include, patterns, url
from django.conf.urls import include, url
from django.views.generic import RedirectView
from openslides.utils.plugins import get_all_plugin_urlpatterns
@ -6,8 +6,7 @@ from openslides.utils.rest_api import router
urlpatterns = get_all_plugin_urlpatterns()
urlpatterns += patterns(
'',
urlpatterns += [
url(r'^(?P<url>.*[^/])$', RedirectView.as_view(url='/%(url)s/', permanent=True)),
url(r'^rest/', include(router.urls)),
url(r'^agenda/', include('openslides.agenda.urls')),
@ -18,4 +17,4 @@ urlpatterns += patterns(
# The urls.py of the core app has to be the last entry. It contains the
# main entry points for OpenSlides' browser clients.
url(r'^', include('openslides.core.urls')),
)
]

View File

@ -1,10 +1,8 @@
from django.conf.urls import patterns, url
from django.conf.urls import url
from . import views
urlpatterns = patterns(
'',
urlpatterns = [
# Auth
url(r'^login/$',
views.UserLoginView.as_view(),
@ -30,4 +28,4 @@ urlpatterns = patterns(
url(r'^passwords/print/$',
views.UsersPasswordsPDF.as_view(),
name='user_passwordspdf'),
)
]

View File

@ -1,9 +1,9 @@
import os
import pkgutil
import sys
from importlib import import_module
from django.conf import settings
from django.utils.importlib import import_module
from pkg_resources import iter_entry_points
from openslides.utils.main import (

View File

@ -2,6 +2,6 @@
-r requirements_production.txt
# Requirements for development and tests in alphabetical order
coverage==4.0a5
coverage
flake8
isort

View File

@ -1,12 +1,12 @@
# Requirements for OpenSlides in production in alphabetical order
Django>=1.7.1,<1.9
beautifulsoup4>=4.1,<4.5
djangorestframework>=3.2.0,<3.3.0
Django>=1.8,<1.10
beautifulsoup4>=4.4,<4.5
djangorestframework>=3.2.0,<3.4.0
html5lib>=0.9,<1.0
jsonfield>=0.9.19,<1.1
natsort>=3.2,<4.1
reportlab>=3.0,<3.3
roman>=2.0,<2.1
setuptools>=2.2,<19.0
setuptools>=2.2,<20.0
sockjs-tornado>=1.0,<1.1
Whoosh>=2.7.0,<2.8

View File

@ -20,16 +20,23 @@ class HandleConfigTest(TestCase):
self.assertEqual(config['integer_var'], 3)
self.assertEqual(config['choices_var'], '1')
self.assertEqual(config['none_config_var'], None)
self.assertRaisesMessage(expected_exception=ConfigNotFound,
expected_message='The config variable unknown_config_var was not found.',
callable_obj=self.get_config_var, key='unknown_config_var')
with self.assertRaisesMessage(
ConfigNotFound,
'The config variable unknown_config_var was not found.'):
self.get_config_var('unknown_config_var')
def test_get_multiple_config_var_error(self):
config_signal.connect(set_simple_config_view_multiple_vars, dispatch_uid='set_simple_config_view_multiple_vars_for_testing')
self.assertRaisesMessage(expected_exception=ConfigError,
expected_message='Too many values for config variable multiple_config_var found.',
callable_obj=config.setup_cache)
config_signal.disconnect(set_simple_config_view_multiple_vars, dispatch_uid='set_simple_config_view_multiple_vars_for_testing')
config_signal.connect(
set_simple_config_view_multiple_vars,
dispatch_uid='set_simple_config_view_multiple_vars_for_testing')
with self.assertRaisesMessage(
ConfigError,
'Too many values for config variable multiple_config_var found.'):
config.setup_cache()
config_signal.disconnect(
set_simple_config_view_multiple_vars,
dispatch_uid='set_simple_config_view_multiple_vars_for_testing')
def test_database_queries(self):
"""
@ -67,13 +74,16 @@ class HandleConfigTest(TestCase):
message.
"""
# TODO: use right exception
self.assertRaisesMessage(
with self.assertRaisesMessage(
Exception,
'Change callback dhcnfg34dlg06kdg successfully called.',
self.set_config_var,
'Change callback dhcnfg34dlg06kdg successfully called.'):
self.set_config_var(
key='var_with_callback_ghvnfjd5768gdfkwg0hm2',
value='new_string_kbmbnfhdgibkdjshg452bc')
self.assertEqual(config['var_with_callback_ghvnfjd5768gdfkwg0hm2'], 'new_string_kbmbnfhdgibkdjshg452bc')
self.assertEqual(
config['var_with_callback_ghvnfjd5768gdfkwg0hm2'],
'new_string_kbmbnfhdgibkdjshg452bc')
@receiver(config_signal, dispatch_uid='set_grouped_config_view_for_testing')

View File

@ -40,10 +40,6 @@ TIME_ZONE = 'Europe/Berlin'
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, '')
TEMPLATE_DIRS = (
os.path.join(OPENSLIDES_USER_DATA_PATH, 'templates'),
)
STATICFILES_DIRS.insert(0, os.path.join(OPENSLIDES_USER_DATA_PATH, 'static'))
SEARCH_INDEX = 'ram'

View File

@ -40,10 +40,6 @@ TIME_ZONE = 'Europe/Berlin'
MEDIA_ROOT = os.path.join(OPENSLIDES_USER_DATA_PATH, '')
TEMPLATE_DIRS = (
os.path.join(OPENSLIDES_USER_DATA_PATH, 'templates'),
)
STATICFILES_DIRS.insert(0, os.path.join(OPENSLIDES_USER_DATA_PATH, 'static'))
SEARCH_INDEX = 'ram'