Merge pull request #1212 from normanjaeckel/ConfigTrans
Inserted command line option to translate config strings during database...
This commit is contained in:
commit
69c73a7ae0
@ -20,6 +20,7 @@ Other:
|
||||
- Changed api for plugins. Used entry points to detect them automaticly.
|
||||
- Renamed config api classes.
|
||||
- Renamed some classes of the poll api.
|
||||
- Inserted command line option to translate config strings during database setup.
|
||||
- Inserted api for the personal info widget.
|
||||
- Changed api for main menu entries.
|
||||
- Enhanced http error pages.
|
||||
|
@ -21,6 +21,7 @@ from openslides.utils.main import (
|
||||
get_port,
|
||||
setup_django_settings_module,
|
||||
start_browser,
|
||||
translate_customizable_strings,
|
||||
write_settings)
|
||||
|
||||
|
||||
@ -87,7 +88,7 @@ def parse_args():
|
||||
'start',
|
||||
help='Setup settings and database, start tornado webserver, launch the '
|
||||
'default web browser and open the webinterface.')
|
||||
add_general_arguments(subcommand_start, ('settings', 'user_data_path', 'address', 'port'))
|
||||
add_general_arguments(subcommand_start, ('settings', 'user_data_path', 'language', 'address', 'port'))
|
||||
subcommand_start.add_argument(
|
||||
'--no-browser',
|
||||
action='store_true',
|
||||
@ -113,7 +114,7 @@ def parse_args():
|
||||
subcommand_syncdb = subparsers.add_parser(
|
||||
'syncdb',
|
||||
help='Create or update database tables.')
|
||||
add_general_arguments(subcommand_syncdb, ('settings', 'user_data_path'))
|
||||
add_general_arguments(subcommand_syncdb, ('settings', 'user_data_path', 'language'))
|
||||
subcommand_syncdb.set_defaults(callback=syncdb)
|
||||
|
||||
# Subcommand createsuperuser
|
||||
@ -191,6 +192,11 @@ def add_general_arguments(subcommand, arguments):
|
||||
'when a new settings file is created. The given path is only '
|
||||
'written into the new settings file. Default according to the '
|
||||
'OpenSlides is at the moment %s' % get_default_user_data_path(openslides_type)))
|
||||
general_arguments['language'] = (
|
||||
('-l', '--language'),
|
||||
dict(help='Language code. All customizable strings will be translated '
|
||||
'during database setup. See https://www.transifex.com/projects/p/openslides/ '
|
||||
'for supported languages.'))
|
||||
general_arguments['address'] = (
|
||||
('-a', '--address',),
|
||||
dict(default='0.0.0.0', help='IP address to listen on. Default is %(default)s.'))
|
||||
@ -250,6 +256,8 @@ def syncdb(settings, args):
|
||||
print('Clearing old search index...')
|
||||
execute_from_command_line(["", "clear_index", "--noinput"])
|
||||
execute_from_command_line(["", "syncdb", "--noinput"])
|
||||
if args.language:
|
||||
translate_customizable_strings(args.language)
|
||||
return 0
|
||||
|
||||
|
||||
|
@ -43,6 +43,7 @@ def setup_assignment_config(sender, **kwargs):
|
||||
assignment_pdf_title = ConfigVariable(
|
||||
name='assignment_pdf_title',
|
||||
default_value=_('Elections'),
|
||||
translatable=True,
|
||||
form_field=forms.CharField(
|
||||
widget=forms.TextInput(),
|
||||
required=False,
|
||||
|
@ -53,8 +53,8 @@ class ConfigHandler(object):
|
||||
|
||||
def setup_cache(self):
|
||||
"""
|
||||
Loads all config variables from the database and by sending a
|
||||
signal to get the default into the cache.
|
||||
Loads all config variables from the database by sending a signal to
|
||||
save the default to the cache.
|
||||
"""
|
||||
self._cache = {}
|
||||
for receiver, config_collection in config_signal.send(sender='setup_cache'):
|
||||
@ -73,6 +73,15 @@ class ConfigHandler(object):
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_all_translatable(self):
|
||||
"""
|
||||
Generator to get all config variables as strings when their values are
|
||||
intended to be translated.
|
||||
"""
|
||||
for receiver, config_collection in config_signal.send(sender='get_all_translatable'):
|
||||
for config_variable in config_collection.variables:
|
||||
if config_variable.translatable:
|
||||
yield config_variable.name
|
||||
|
||||
config = ConfigHandler()
|
||||
"""
|
||||
@ -162,10 +171,13 @@ class ConfigVariable(object):
|
||||
arguments 'name' and 'default_value' are required. The keyword
|
||||
argument 'form_field' has to be set if the variable should appear
|
||||
on the ConfigView. The argument 'on_change' can get a callback
|
||||
which is called every time, the variable is changed.
|
||||
which is called every time, the variable is changed. If the argument
|
||||
'translatable' is set, OpenSlides is able to translate the value during
|
||||
setup of the database if the admin uses the respective command line option.
|
||||
"""
|
||||
def __init__(self, name, default_value, form_field=None, on_change=None):
|
||||
def __init__(self, name, default_value, form_field=None, on_change=None, translatable=False):
|
||||
self.name = name
|
||||
self.default_value = default_value
|
||||
self.form_field = form_field
|
||||
self.on_change = on_change
|
||||
self.translatable = translatable
|
||||
|
@ -29,6 +29,7 @@ def setup_general_config(sender, **kwargs):
|
||||
event_description = ConfigVariable(
|
||||
name='event_description',
|
||||
default_value=_('Presentation and assembly system'),
|
||||
translatable=True,
|
||||
form_field=forms.CharField(
|
||||
widget=forms.TextInput(),
|
||||
label=ugettext_lazy('Short description of event'),
|
||||
@ -104,6 +105,7 @@ def setup_general_config(sender, **kwargs):
|
||||
welcome_title = ConfigVariable(
|
||||
name='welcome_title',
|
||||
default_value=_('Welcome to OpenSlides'),
|
||||
translatable=True,
|
||||
form_field=forms.CharField(
|
||||
widget=forms.TextInput(),
|
||||
label=ugettext_lazy('Title'),
|
||||
@ -113,6 +115,7 @@ def setup_general_config(sender, **kwargs):
|
||||
welcome_text = ConfigVariable(
|
||||
name='welcome_text',
|
||||
default_value=_('[Place for your welcome text.]'),
|
||||
translatable=True,
|
||||
form_field=forms.CharField(
|
||||
widget=forms.Textarea(),
|
||||
label=ugettext_lazy('Welcome text'),
|
||||
|
@ -40,6 +40,7 @@ def setup_motion_config(sender, **kwargs):
|
||||
motion_preamble = ConfigVariable(
|
||||
name='motion_preamble',
|
||||
default_value=_('The assembly may decide,'),
|
||||
translatable=True,
|
||||
form_field=forms.CharField(
|
||||
widget=forms.TextInput(),
|
||||
required=False,
|
||||
@ -66,6 +67,7 @@ def setup_motion_config(sender, **kwargs):
|
||||
motion_pdf_title = ConfigVariable(
|
||||
name='motion_pdf_title',
|
||||
default_value=_('Motions'),
|
||||
translatable=True,
|
||||
form_field=forms.CharField(
|
||||
widget=forms.TextInput(),
|
||||
required=False,
|
||||
|
@ -23,6 +23,7 @@ def setup_participant_config(sender, **kwargs):
|
||||
participant_pdf_welcometitle = ConfigVariable(
|
||||
name='participant_pdf_welcometitle',
|
||||
default_value=_('Welcome to OpenSlides!'),
|
||||
translatable=True,
|
||||
form_field=forms.CharField(
|
||||
widget=forms.Textarea(),
|
||||
required=False,
|
||||
@ -31,6 +32,7 @@ def setup_participant_config(sender, **kwargs):
|
||||
participant_pdf_welcometext = ConfigVariable(
|
||||
name='participant_pdf_welcometext',
|
||||
default_value=_('[Place for your welcome and help text.]'),
|
||||
translatable=True,
|
||||
form_field=forms.CharField(
|
||||
widget=forms.Textarea(),
|
||||
required=False,
|
||||
|
@ -12,6 +12,8 @@ import webbrowser
|
||||
from base64 import b64encode
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.conf import ENVIRONMENT_VARIABLE
|
||||
from django.utils.translation import activate, check_for_language, get_language
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
UNIX_VERSION = 'Unix Version'
|
||||
WINDOWS_VERSION = 'Windows Version'
|
||||
@ -301,3 +303,16 @@ def get_database_path_from_settings():
|
||||
if default.get('ENGINE') != 'django.db.backends.sqlite3':
|
||||
database_path = None
|
||||
return database_path
|
||||
|
||||
|
||||
def translate_customizable_strings(language_code):
|
||||
"""
|
||||
Translates all translatable config values and saves them into database.
|
||||
"""
|
||||
if check_for_language(language_code):
|
||||
from openslides.config.api import config
|
||||
current_language = get_language()
|
||||
activate(language_code)
|
||||
for name in config.get_all_translatable():
|
||||
config[name] = _(config[name])
|
||||
activate(current_language)
|
||||
|
@ -12,6 +12,7 @@ from openslides.__main__ import (
|
||||
runserver,
|
||||
start,
|
||||
syncdb)
|
||||
from openslides.config.api import config
|
||||
from openslides.utils.main import (
|
||||
get_browser_url,
|
||||
get_database_path_from_settings,
|
||||
@ -22,6 +23,7 @@ from openslides.utils.main import (
|
||||
PortIsBlockedError,
|
||||
setup_django_settings_module,
|
||||
start_browser,
|
||||
translate_customizable_strings,
|
||||
UNIX_VERSION,
|
||||
WINDOWS_PORTABLE_VERSION)
|
||||
from openslides.utils.test import TestCase
|
||||
@ -91,6 +93,11 @@ class TestFunctions(TestCase):
|
||||
def test_get_database_path_from_settings_memory(self):
|
||||
self.assertEqual(get_database_path_from_settings(), ':memory:')
|
||||
|
||||
def test_translate_customizable_strings(self):
|
||||
self.assertEqual(config['event_description'], 'Presentation and assembly system')
|
||||
translate_customizable_strings('de')
|
||||
self.assertEqual(config['event_description'], u'Präsentations- und Versammlungssystem')
|
||||
|
||||
|
||||
class TestOtherFunctions(TestCase):
|
||||
"""
|
||||
@ -127,6 +134,7 @@ class TestOtherFunctions(TestCase):
|
||||
def test_syncdb(self, mock_execute_from_command_line, mock_os, mock_exists):
|
||||
mock_exists.return_value = True
|
||||
mock_args = MagicMock()
|
||||
mock_args.language = None
|
||||
syncdb(settings=None, args=mock_args)
|
||||
self.assertTrue(mock_execute_from_command_line.called)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user