<
From version < 2.1 >
edited by Adel Atallah
on 2018/05/07 11:25
To version < 3.1 >
edited by Adel Atallah
on 2018/05/07 15:37
>
Change comment: There is no comment for this version

Summary

Details

Page properties
Title
... ... @@ -1,0 +1,1 @@
1 +Weblate Configuration
Parent
... ... @@ -1,0 +1,1 @@
1 +Community.DevelopmentPractices
Content
... ... @@ -1,0 +1,949 @@
1 +Weblate is an open source web-based translation tool written in Python. We use it as an alternative to [[l10n.xwiki.org>>http://l10n.xwiki.org]].
2 +
3 +{{toc/}}
4 +
5 += How to install =
6 +
7 +== Prerequisite ==
8 +
9 +* Python (2.7 in our setup)
10 +* Python virtualenv
11 +* Dependencies [[listed here>>https://docs.weblate.org/en/latest/admin/install.html#python-dependencies]]
12 +* Postgresql
13 +* Memcached
14 +* [[hub>>https://hub.github.com/]]
15 +
16 +__Quick setup:__
17 +
18 +For debian users: {{box}}apt-get install memcached golang postgresql build-essential python virtualenv zlib1g-dev{{/box}}
19 +Python dependencies:
20 +
21 +{{code}}
22 +pip install --upgrade pip
23 +pip install -U setuptools
24 +pip install Babel certifi chardet defusedxml diff-match-patch Django django-appconf django-compressor django-crispy-forms djangorestframework filelock idna lxml oauthlib phply Pillow ply psycopg2 psycopg2-binary pydns PyJWT pyLibravatar python-bidi python-dateutil python-memcached python-openid pytz pyuca PyYAML rcssmin requests requests-oauthlib rjsmin setuptools siphashc six social-auth-app-django social-auth-core translate-toolkit ua-parser urllib3 user-agents Whoosh Weblate
25 +{{/code}}
26 +
27 +
28 +== Installation ==
29 +
30 +Most of the installation process can be found on the [[official documentation>>https://docs.weblate.org/en/latest/admin/install.html]]. We chose the [[virtualenv method>>https://docs.weblate.org/en/latest/admin/install.html#installing-in-virtualenv]] to install all the python dependencies.
31 +
32 +Let's call (% class="mark" %)##$VIRTUALENV##(%%) the path of the virtual environment (it could be {{box}}~~/weblate{{/box}} for instance).
33 +
34 +After the installation, you can find weblate's files and other installed modules at {{box}}$VIRTUALENV/local/lib/python2.7/site-packages/{{/box}} (your python version may vary).
35 +
36 +Note that if you use virtualenv, you'll have to use the {{box}}weblate{{/box}} command instead of {{box}}./manage.py{{/box}} that you may found on weblate's documentation.
37 +
38 +== Configuration ==
39 +
40 +Most of the configuration is made by editing the file {{box}}$VIRTUALENV/local/lib/python2.7/site-packages/weblate/settings.py{{/box}}. Here is a sample configuration file:
41 +
42 +{{code}}
43 +# -*- coding: utf-8 -*-
44 +#
45 +# Copyright © 2012 - 2018 Michal Čihař <[email protected]>
46 +#
47 +# This file is part of Weblate <https://weblate.org/>
48 +#
49 +# This program is free software: you can redistribute it and/or modify
50 +# it under the terms of the GNU General Public License as published by
51 +# the Free Software Foundation, either version 3 of the License, or
52 +# (at your option) any later version.
53 +#
54 +# This program is distributed in the hope that it will be useful,
55 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
56 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
57 +# GNU General Public License for more details.
58 +#
59 +# You should have received a copy of the GNU General Public License
60 +# along with this program.  If not, see <https://www.gnu.org/licenses/>.
61 +#
62 +
63 +from __future__ import unicode_literals
64 +import platform
65 +import os
66 +from logging.handlers import SysLogHandler
67 +from social_core.backends.oauth import BaseOAuth2
68 +
69 +#
70 +# Django settings for Weblate project.
71 +#
72 +
73 +DEBUG = False
74 +
75 +ADMINS = (
76 +    # ('Your Name', '[email protected]'),
77 +)
78 +
79 +MANAGERS = ADMINS
80 +
81 +DATABASES = {
82 +    'default': {
83 +        # Use 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
84 +        'ENGINE': 'django.db.backends.postgresql_psycopg2',
85 +        # Database name or path to database file if using sqlite3.
86 +        'NAME': '[DATABASE_NAME]',
87 +        # Database user, not used with sqlite3.
88 +        'USER': '[DATABASE_USERNAME]',
89 +        # Database password, not used with sqlite3.
90 +        'PASSWORD': '[DATABASE_PASSWORD]',
91 +        # Set to empty string for localhost. Not used with sqlite3.
92 +        'HOST': '[DATABASE_HOST]',
93 +        # Set to empty string for default. Not used with sqlite3.
94 +        'PORT': '',
95 +        # Customizations for databases
96 +        'OPTIONS': {
97 +            # Uncomment for MySQL older than 5.7:
98 +            # 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
99 +            # Set emoji capable charset for MySQL:
100 +            # 'charset': 'utf8mb4',
101 +        },
102 +    }
103 +}
104 +
105 +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
106 +
107 +# Data directory
108 +DATA_DIR = os.path.join(BASE_DIR, 'data')
109 +
110 +# Local time zone for this installation. Choices can be found here:
111 +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
112 +# although not all choices may be available on all operating systems.
113 +# In a Windows environment this must be set to your system time zone.
114 +TIME_ZONE = 'UTC'
115 +
116 +# Language code for this installation. All choices can be found here:
117 +# http://www.i18nguy.com/unicode/language-identifiers.html
118 +LANGUAGE_CODE = 'en-us'
119 +
120 +LANGUAGES = (
121 +    ('ar', 'العربية'),
122 +    ('az', 'Azərbaycan'),
123 +    ('be', 'Беларуская'),
124 +    ('[email protected]', 'Biełaruskaja'),
125 +    ('bg', 'Български'),
126 +    ('br', 'Brezhoneg'),
127 +    ('ca', 'Català'),
128 +    ('cs', 'Čeština'),
129 +    ('da', 'Dansk'),
130 +    ('de', 'Deutsch'),
131 +    ('en', 'English'),
132 +    ('en-gb', 'English (United Kingdom)'),
133 +    ('el', '&Epsilon;λληνικά'),
134 +    ('es', 'Español'),
135 +    ('fi', 'Suomi'),
136 +    ('fr', 'Français'),
137 +    ('fy', 'Frysk'),
138 +    ('gl', 'Galego'),
139 +    ('he', 'עברית'),
140 +    ('hu', 'Magyar'),
141 +    ('id', 'Indonesia'),
142 +    ('it', 'Italiano'),
143 +    ('ja', '日本語'),
144 +    ('ko', '한국어'),
145 +    ('ksh', 'Kölsch'),
146 +    ('nb', 'Norsk bokmål'),
147 +    ('nl', 'Nederlands'),
148 +    ('pl', 'Polski'),
149 +    ('pt', 'Português'),
150 +    ('pt-br', 'Português brasileiro'),
151 +    ('ru', 'Русский'),
152 +    ('sk', 'Slovenčina'),
153 +    ('sl', 'Slovenščina'),
154 +    ('sr', 'Српски'),
155 +    ('sv', 'Svenska'),
156 +    ('tr', 'Türkçe'),
157 +    ('uk', 'Українська'),
158 +    ('zh-hans', '简体字'),
159 +    ('zh-hant', '正體字'),
160 +)
161 +
162 +SITE_ID = 1
163 +
164 +# If you set this to False, Django will make some optimizations so as not
165 +# to load the internationalization machinery.
166 +USE_I18N = True
167 +
168 +# If you set this to False, Django will not format dates, numbers and
169 +# calendars according to the current locale.
170 +USE_L10N = True
171 +
172 +# If you set this to False, Django will not use timezone-aware datetimes.
173 +USE_TZ = True
174 +
175 +# URL prefix to use, please see documentation for more details
176 +URL_PREFIX = ''
177 +
178 +# Absolute filesystem path to the directory that will hold user-uploaded files.
179 +# Example: "/home/media/media.lawrence.com/media/"
180 +MEDIA_ROOT = os.path.join(DATA_DIR, 'media')
181 +
182 +# URL that handles the media served from MEDIA_ROOT. Make sure to use a
183 +# trailing slash.
184 +# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
185 +MEDIA_URL = '{0}/media/'.format(URL_PREFIX)
186 +
187 +# Absolute path to the directory static files should be collected to.
188 +# Don't put anything in this directory yourself; store your static files
189 +# in apps' "static/" subdirectories and in STATICFILES_DIRS.
190 +# Example: "/home/media/media.lawrence.com/static/"
191 +STATIC_ROOT = os.path.join(DATA_DIR, 'static')
192 +
193 +# URL prefix for static files.
194 +# Example: "http://media.lawrence.com/static/"
195 +STATIC_URL = '{0}/static/'.format(URL_PREFIX)
196 +
197 +# Additional locations of static files
198 +STATICFILES_DIRS = (
199 +    # Put strings here, like "/home/html/static" or "C:/www/django/static".
200 +    # Always use forward slashes, even on Windows.
201 +    # Don't forget to use absolute paths, not relative paths.
202 +)
203 +
204 +# List of finder classes that know how to find static files in
205 +# various locations.
206 +STATICFILES_FINDERS = (
207 +    'django.contrib.staticfiles.finders.FileSystemFinder',
208 +    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
209 +    'compressor.finders.CompressorFinder',
210 +)
211 +
212 +# Make this unique, and don't share it with anybody.
213 +# You can generate it using examples/generate-secret-key
214 +SECRET_KEY = ''
215 +
216 +TEMPLATES = [
217 +    {
218 +        'BACKEND': 'django.template.backends.django.DjangoTemplates',
219 +        'DIRS': [
220 +            os.path.join(BASE_DIR, 'weblate', 'templates'),
221 +        ],
222 +        'OPTIONS': {
223 +            'context_processors': [
224 +                'django.contrib.auth.context_processors.auth',
225 +                'django.template.context_processors.debug',
226 +                'django.template.context_processors.i18n',
227 +                'django.template.context_processors.request',
228 +                'django.template.context_processors.csrf',
229 +                'django.contrib.messages.context_processors.messages',
230 +                'weblate.trans.context_processors.weblate_context',
231 +            ],
232 +            'loaders': [
233 +                ('django.template.loaders.cached.Loader', [
234 +                    'django.template.loaders.filesystem.Loader',
235 +                    'django.template.loaders.app_directories.Loader',
236 +                ]),
237 +            ],
238 +        },
239 +    },
240 +]
241 +
242 +
243 +
244 +# GitHub username for sending pull requests.
245 +# Please see the documentation for more details.
246 +GITHUB_USERNAME = '[GITHUB_USERNAME]'
247 +
248 +# Authentication configuration
249 +AUTHENTICATION_BACKENDS = (
250 +    'social_core.backends.email.EmailAuth',
251 +    # 'social_core.backends.google.GoogleOAuth2',
252 +    'social_core.backends.github.GithubOAuth2',
253 +    # 'social_core.backends.bitbucket.BitbucketOAuth',
254 +    # 'social_core.backends.suse.OpenSUSEOpenId',
255 +    # 'social_core.backends.ubuntu.UbuntuOpenId',
256 +    # 'social_core.backends.fedora.FedoraOpenId',
257 +    # 'social_core.backends.facebook.FacebookOAuth2',
258 +    'weblate.accounts.auth.WeblateUserBackend',
259 +    'weblate.settings.XWikiOAuth2',
260 +)
261 +
262 +# Social auth backends setup
263 +SOCIAL_AUTH_GITHUB_KEY = '[SOCIAL_AUTH_GITHUB_KEY]'
264 +SOCIAL_AUTH_GITHUB_SECRET = '[SOCIAL_AUTH_GITHUB_SECRET]'
265 +SOCIAL_AUTH_GITHUB_SCOPE = ['user:email']
266 +
267 +SOCIAL_AUTH_BITBUCKET_KEY = ''
268 +SOCIAL_AUTH_BITBUCKET_SECRET = ''
269 +SOCIAL_AUTH_BITBUCKET_VERIFIED_EMAILS_ONLY = True
270 +
271 +SOCIAL_AUTH_FACEBOOK_KEY = ''
272 +SOCIAL_AUTH_FACEBOOK_SECRET = ''
273 +SOCIAL_AUTH_FACEBOOK_SCOPE = ['email', 'public_profile']
274 +
275 +SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = ''
276 +SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = ''
277 +
278 +class XWikiOAuth2(BaseOAuth2):
279 +    name = 'XWiki'
280 +    ID_KEY = 'sub'
281 +    XWIKI_URL = 'https://www.xwiki.org/xwiki'
282 +    AUTHORIZATION_URL = '{0}/oidc/authorization'.format(XWIKI_URL)
283 +    ACCESS_TOKEN_URL = '{0}/oidc/token'.format(XWIKI_URL)
284 +    REDIRECT_STATE = False
285 +    ACCESS_TOKEN_METHOD = 'POST'
286 +    EXTRA_DATA = [
287 +        ('refresh_token', 'refresh_token', True),
288 +    ]
289 +
290 +    def get_user_details(self, response):
291 +        username = response.get('sub').split('.')[-1]
292 +        fullname, first_name, last_name = self.get_user_names(response.get('name'))
293 +        return {
294 +            'username': username,
295 +            'email': response.get('email'),
296 +            'fullname': fullname,
297 +            'first_name': first_name,
298 +            'last_name': last_name
299 +        }
300 +
301 +    def user_data(self, access_token, *args, **kwargs):
302 +        return self.get_json(
303 +            '{0}/oidc/userinfo'.format(self.XWIKI_URL),
304 +            params={'access_token': access_token}
305 +        )
306 +
307 +SOCIAL_AUTH_XWIKI_KEY = '[SOCIAL_AUTH_XWIKI_KEY]'
308 +
309 +# Social auth settings
310 +SOCIAL_AUTH_PIPELINE = (
311 +    'social_core.pipeline.social_auth.social_details',
312 +    'social_core.pipeline.social_auth.social_uid',
313 +    'social_core.pipeline.social_auth.auth_allowed',
314 +    'social_core.pipeline.social_auth.social_user',
315 +    'weblate.accounts.pipeline.store_params',
316 +    'weblate.accounts.pipeline.verify_open',
317 +    'social_core.pipeline.user.get_username',
318 +    'weblate.accounts.pipeline.require_email',
319 +    'social_core.pipeline.mail.mail_validation',
320 +    'weblate.accounts.pipeline.revoke_mail_code',
321 +    'weblate.accounts.pipeline.ensure_valid',
322 +    'weblate.accounts.pipeline.remove_account',
323 +    'social_core.pipeline.social_auth.associate_by_email',
324 +    'weblate.accounts.pipeline.reauthenticate',
325 +    'weblate.accounts.pipeline.verify_username',
326 +    'social_core.pipeline.user.create_user',
327 +    'social_core.pipeline.social_auth.associate_user',
328 +    'social_core.pipeline.social_auth.load_extra_data',
329 +    'weblate.accounts.pipeline.cleanup_next',
330 +    'weblate.accounts.pipeline.user_full_name',
331 +    'weblate.accounts.pipeline.store_email',
332 +    'weblate.accounts.pipeline.notify_connect',
333 +    'weblate.accounts.pipeline.password_reset',
334 +)
335 +SOCIAL_AUTH_DISCONNECT_PIPELINE = (
336 +    'social_core.pipeline.disconnect.allowed_to_disconnect',
337 +    'social_core.pipeline.disconnect.get_entries',
338 +    'social_core.pipeline.disconnect.revoke_tokens',
339 +    'weblate.accounts.pipeline.cycle_session',
340 +    'weblate.accounts.pipeline.adjust_primary_mail',
341 +    'weblate.accounts.pipeline.notify_disconnect',
342 +    'social_core.pipeline.disconnect.disconnect',
343 +    'weblate.accounts.pipeline.cleanup_next',
344 +)
345 +
346 +# Custom authentication strategy
347 +SOCIAL_AUTH_STRATEGY = 'weblate.accounts.strategy.WeblateStrategy'
348 +
349 +# Raise exceptions so that we can handle them later
350 +SOCIAL_AUTH_RAISE_EXCEPTIONS = True
351 +
352 +SOCIAL_AUTH_EMAIL_VALIDATION_FUNCTION = \
353 +    'weblate.accounts.pipeline.send_validation'
354 +SOCIAL_AUTH_EMAIL_VALIDATION_URL = \
355 +    '{0}/accounts/email-sent/'.format(URL_PREFIX)
356 +SOCIAL_AUTH_LOGIN_ERROR_URL = \
357 +    '{0}/accounts/login/'.format(URL_PREFIX)
358 +SOCIAL_AUTH_EMAIL_FORM_URL = \
359 +    '{0}/accounts/email/'.format(URL_PREFIX)
360 +SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = \
361 +    '{0}/accounts/profile/#auth'.format(URL_PREFIX)
362 +SOCIAL_AUTH_PROTECTED_USER_FIELDS = ('email',)
363 +SOCIAL_AUTH_SLUGIFY_USERNAMES = True
364 +SOCIAL_AUTH_SLUGIFY_FUNCTION = 'weblate.accounts.pipeline.slugify_username'
365 +
366 +# Password validation configuration
367 +AUTH_PASSWORD_VALIDATORS = [
368 +    {
369 +        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
370 +    },
371 +    {
372 +        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
373 +        'OPTIONS': {
374 +            'min_length': 6,
375 +        }
376 +    },
377 +    {
378 +        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
379 +    },
380 +    {
381 +        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
382 +    },
383 +    {
384 +        'NAME': 'weblate.accounts.password_validation.CharsPasswordValidator',
385 +    },
386 +    {
387 +        'NAME': 'weblate.accounts.password_validation.PastPasswordsValidator',
388 +    },
389 +    # Optional password strength validation by django-zxcvbn-password
390 +    # {
391 +    #     'NAME': 'zxcvbn_password.ZXCVBNValidator',
392 +    #     'OPTIONS': {
393 +    #         'min_score': 3,
394 +    #         'user_attributes': ('username', 'email', 'first_name')
395 +    #     }
396 +    # },
397 +]
398 +
399 +# Middleware
400 +MIDDLEWARE = [
401 +    'django.middleware.security.SecurityMiddleware',
402 +    'django.contrib.sessions.middleware.SessionMiddleware',
403 +    'django.middleware.common.CommonMiddleware',
404 +    'django.middleware.locale.LocaleMiddleware',
405 +    'django.middleware.csrf.CsrfViewMiddleware',
406 +    'weblate.accounts.middleware.AuthenticationMiddleware',
407 +    'django.contrib.messages.middleware.MessageMiddleware',
408 +    'django.middleware.clickjacking.XFrameOptionsMiddleware',
409 +    'social_django.middleware.SocialAuthExceptionMiddleware',
410 +    'weblate.accounts.middleware.RequireLoginMiddleware',
411 +    'weblate.middleware.SecurityMiddleware',
412 +    'weblate.wladmin.middleware.ConfigurationErrorsMiddleware',
413 +]
414 +
415 +ROOT_URLCONF = 'weblate.urls'
416 +
417 +# Django and Weblate apps
418 +INSTALLED_APPS = (
419 +    'django.contrib.auth',
420 +    'django.contrib.contenttypes',
421 +    'django.contrib.sessions',
422 +    'django.contrib.sites',
423 +    'django.contrib.messages',
424 +    'django.contrib.staticfiles',
425 +    'django.contrib.admin.apps.SimpleAdminConfig',
426 +    'django.contrib.admindocs',
427 +    'django.contrib.sitemaps',
428 +    'social_django',
429 +    'crispy_forms',
430 +    'compressor',
431 +    'rest_framework',
432 +    'rest_framework.authtoken',
433 +    'weblate.addons',
434 +    'weblate.trans',
435 +    'weblate.lang',
436 +    'weblate.langdata',
437 +    'weblate.memory',
438 +    'weblate.permissions',
439 +    'weblate.screenshots',
440 +    'weblate.accounts',
441 +    'weblate.utils',
442 +    'weblate.wladmin',
443 +    'weblate',
444 +
445 +    # Optional: Git exporter
446 +    # 'weblate.gitexport',
447 +)
448 +
449 +# Path to locales
450 +LOCALE_PATHS = (os.path.join(BASE_DIR, 'weblate', 'locale'), )
451 +
452 +# Custom exception reporter to include some details
453 +DEFAULT_EXCEPTION_REPORTER_FILTER = \
454 +    'weblate.trans.debug.WeblateExceptionReporterFilter'
455 +
456 +# Default logging of Weblate messages
457 +# - to syslog in production (if available)
458 +# - otherwise to console
459 +# - you can also choose 'logfile' to log into separate file
460 +#   after configuring it below
461 +
462 +# Detect if we can connect to syslog
463 +HAVE_SYSLOG = False
464 +if platform.system() != 'Windows':
465 +    try:
466 +        handler = SysLogHandler(
467 +            address='/dev/log', facility=SysLogHandler.LOG_LOCAL2
468 +        )
469 +        handler.close()
470 +        HAVE_SYSLOG = True
471 +    except IOError:
472 +        HAVE_SYSLOG = False
473 +
474 +if DEBUG or not HAVE_SYSLOG:
475 +    DEFAULT_LOG = 'console'
476 +else:
477 +    DEFAULT_LOG = 'syslog'
478 +
479 +# A sample logging configuration. The only tangible logging
480 +# performed by this configuration is to send an email to
481 +# the site admins on every HTTP 500 error when DEBUG=False.
482 +# See http://docs.djangoproject.com/en/stable/topics/logging for
483 +# more details on how to customize your logging configuration.
484 +LOGGING = {
485 +    'version': 1,
486 +    'disable_existing_loggers': True,
487 +    'filters': {
488 +        'require_debug_false': {
489 +            '()': 'django.utils.log.RequireDebugFalse'
490 +        }
491 +    },
492 +    'formatters': {
493 +        'syslog': {
494 +            'format': 'weblate[%(process)d]: %(levelname)s %(message)s'
495 +        },
496 +        'simple': {
497 +            'format': '%(levelname)s %(message)s'
498 +        },
499 +        'logfile': {
500 +            'format': '%(asctime)s %(levelname)s %(message)s'
501 +        },
502 +        'django.server': {
503 +            '()': 'django.utils.log.ServerFormatter',
504 +            'format': '[%(server_time)s] %(message)s',
505 +        }
506 +    },
507 +    'handlers': {
508 +        'mail_admins': {
509 +            'level': 'ERROR',
510 +            'filters': ['require_debug_false'],
511 +            'class': 'django.utils.log.AdminEmailHandler',
512 +            'include_html': True,
513 +        },
514 +        'console': {
515 +            'level': 'DEBUG',
516 +            'class': 'logging.StreamHandler',
517 +            'formatter': 'simple'
518 +        },
519 +        'django.server': {
520 +            'level': 'INFO',
521 +            'class': 'logging.StreamHandler',
522 +            'formatter': 'django.server',
523 +        },
524 +        'syslog': {
525 +            'level': 'DEBUG',
526 +            'class': 'logging.handlers.SysLogHandler',
527 +            'formatter': 'syslog',
528 +            'address': '/dev/log',
529 +            'facility': SysLogHandler.LOG_LOCAL2,
530 +        },
531 +        # Logging to a file
532 +        # 'logfile': {
533 +        #     'level':'DEBUG',
534 +        #     'class':'logging.handlers.RotatingFileHandler',
535 +        #     'filename': "/var/log/weblate/weblate.log",
536 +        #     'maxBytes': 100000,
537 +        #     'backupCount': 3,
538 +        #     'formatter': 'logfile',
539 +        # },
540 +    },
541 +    'loggers': {
542 +        'django.request': {
543 +            'handlers': ['mail_admins', DEFAULT_LOG],
544 +            'level': 'ERROR',
545 +            'propagate': True,
546 +        },
547 +        'django.server': {
548 +            'handlers': ['django.server'],
549 +            'level': 'INFO',
550 +            'propagate': False,
551 +        },
552 +        # Logging database queries
553 +        # 'django.db.backends': {
554 +        #     'handlers': [DEFAULT_LOG],
555 +        #     'level': 'DEBUG',
556 +        # },
557 +        'weblate': {
558 +            'handlers': [DEFAULT_LOG],
559 +            'level': 'DEBUG',
560 +        },
561 +        # Logging VCS operations
562 +        # 'weblate-vcs': {
563 +        #     'handlers': [DEFAULT_LOG],
564 +        #     'level': 'DEBUG',
565 +        # },
566 +        # Python Social Auth logging
567 +        # 'social': {
568 +        #     'handlers': [DEFAULT_LOG],
569 +        #     'level': 'DEBUG',
570 +        # },
571 +    }
572 +}
573 +
574 +# Logging of management commands to console
575 +if (os.environ.get('DJANGO_IS_MANAGEMENT_COMMAND', False) and
576 +        'console' not in LOGGING['loggers']['weblate']['handlers']):
577 +    LOGGING['loggers']['weblate']['handlers'].append('console')
578 +
579 +# Remove syslog setup if it's not present
580 +if not HAVE_SYSLOG:
581 +    del LOGGING['handlers']['syslog']
582 +
583 +# List of machine translations
584 +# MACHINE_TRANSLATION_SERVICES = (
585 +#     'weblate.trans.machine.apertium.ApertiumAPYTranslation',
586 +#     'weblate.trans.machine.deepl.DeepLTranslation',
587 +#     'weblate.trans.machine.glosbe.GlosbeTranslation',
588 +#     'weblate.trans.machine.google.GoogleTranslation',
589 +#     'weblate.trans.machine.microsoft.MicrosoftCognitiveTranslation',
590 +#     'weblate.trans.machine.mymemory.MyMemoryTranslation',
591 +#     'weblate.trans.machine.tmserver.AmagamaTranslation',
592 +#     'weblate.trans.machine.tmserver.TMServerTranslation',
593 +#     'weblate.trans.machine.yandex.YandexTranslation',
594 +#     'weblate.trans.machine.weblatetm.WeblateTranslation',
595 +#     'weblate.trans.machine.saptranslationhub.SAPTranslationHub',
596 +#     'weblate.memory.machine.WeblateMemory',
597 +# )
598 +
599 +# Machine translation API keys
600 +
601 +# URL of the Apertium APy server
602 +MT_APERTIUM_APY = None
603 +
604 +# DeepL API key
605 +MT_DEEPL_KEY = None
606 +
607 +# Microsoft Cognitive Services Translator API, register at
608 +# https://portal.azure.com/
609 +MT_MICROSOFT_COGNITIVE_KEY = None
610 +
611 +# MyMemory identification email, see
612 +# https://mymemory.translated.net/doc/spec.php
613 +MT_MYMEMORY_EMAIL = None
614 +
615 +# Optional MyMemory credentials to access private translation memory
616 +MT_MYMEMORY_USER = None
617 +MT_MYMEMORY_KEY = None
618 +
619 +# Google API key for Google Translate API
620 +MT_GOOGLE_KEY = None
621 +
622 +# API key for Yandex Translate API
623 +MT_YANDEX_KEY = None
624 +
625 +# tmserver URL
626 +MT_TMSERVER = None
627 +
628 +# SAP Translation Hub
629 +MT_SAP_BASE_URL = None
630 +MT_SAP_SANDBOX_APIKEY = None
631 +MT_SAP_USERNAME = None
632 +MT_SAP_PASSWORD = None
633 +MT_SAP_USE_MT = True
634 +
635 +# Title of site to use
636 +SITE_TITLE = 'Weblate'
637 +
638 +# Whether site uses https
639 +ENABLE_HTTPS = False
640 +
641 +# Use HTTPS when creating redirect URLs for social authentication, see
642 +# documentation for more details:
643 +# http://python-social-auth-docs.readthedocs.io/en/latest/configuration/settings.html#processing-redirects-and-urlopen
644 +SOCIAL_AUTH_REDIRECT_IS_HTTPS = ENABLE_HTTPS
645 +
646 +# Make CSRF cookie HttpOnly, see documentation for more details:
647 +# https://docs.djangoproject.com/en/1.11/ref/settings/#csrf-cookie-httponly
648 +CSRF_COOKIE_HTTPONLY = True
649 +CSRF_COOKIE_SECURE = ENABLE_HTTPS
650 +# Store CSRF token in session (since Django 1.11)
651 +CSRF_USE_SESSIONS = True
652 +SESSION_COOKIE_SECURE = ENABLE_HTTPS
653 +# Session cookie age (in seconds)
654 +SESSION_COOKIE_AGE = 1209600
655 +
656 +# URL of login
657 +LOGIN_URL = '{0}/accounts/login/'.format(URL_PREFIX)
658 +
659 +# URL of logout
660 +LOGOUT_URL = '{0}/accounts/logout/'.format(URL_PREFIX)
661 +
662 +# Default location for login
663 +LOGIN_REDIRECT_URL = '{0}/'.format(URL_PREFIX)
664 +
665 +# Anonymous user name
666 +ANONYMOUS_USER_NAME = 'anonymous'
667 +
668 +# Reverse proxy settings
669 +IP_BEHIND_REVERSE_PROXY = False
670 +IP_PROXY_HEADER = 'HTTP_X_FORWARDED_FOR'
671 +IP_PROXY_OFFSET = 0
672 +
673 +# Sending HTML in mails
674 +EMAIL_SEND_HTML = True
675 +
676 +# Subject of emails includes site title
677 +EMAIL_SUBJECT_PREFIX = '[{0}] '.format(SITE_TITLE)
678 +
679 +# Enable remote hooks
680 +ENABLE_HOOKS = True
681 +
682 +# Whether to run hooks in background
683 +BACKGROUND_HOOKS = True
684 +
685 +# Number of nearby messages to show in each direction
686 +NEARBY_MESSAGES = 5
687 +
688 +# Offload indexing
689 +OFFLOAD_INDEXING = True
690 +
691 +# Use simple language codes for default language/country combinations
692 +SIMPLIFY_LANGUAGES = True
693 +
694 +# Render forms using bootstrap
695 +CRISPY_TEMPLATE_PACK = 'bootstrap3'
696 +
697 +# List of quality checks
698 +# CHECK_LIST = (
699 +#     'weblate.trans.checks.same.SameCheck',
700 +#     'weblate.trans.checks.chars.BeginNewlineCheck',
701 +#     'weblate.trans.checks.chars.EndNewlineCheck',
702 +#     'weblate.trans.checks.chars.BeginSpaceCheck',
703 +#     'weblate.trans.checks.chars.EndSpaceCheck',
704 +#     'weblate.trans.checks.chars.EndStopCheck',
705 +#     'weblate.trans.checks.chars.EndColonCheck',
706 +#     'weblate.trans.checks.chars.EndQuestionCheck',
707 +#     'weblate.trans.checks.chars.EndExclamationCheck',
708 +#     'weblate.trans.checks.chars.EndEllipsisCheck',
709 +#     'weblate.trans.checks.chars.EndSemicolonCheck',
710 +#     'weblate.trans.checks.chars.MaxLengthCheck',
711 +#     'weblate.trans.checks.format.PythonFormatCheck',
712 +#     'weblate.trans.checks.format.PythonBraceFormatCheck',
713 +#     'weblate.trans.checks.format.PHPFormatCheck',
714 +#     'weblate.trans.checks.format.CFormatCheck',
715 +#     'weblate.trans.checks.format.PerlFormatCheck',
716 +#     'weblate.trans.checks.format.JavascriptFormatCheck',
717 +#     'weblate.trans.checks.consistency.PluralsCheck',
718 +#     'weblate.trans.checks.consistency.SamePluralsCheck',
719 +#     'weblate.trans.checks.consistency.ConsistencyCheck',
720 +#     'weblate.trans.checks.consistency.TranslatedCheck',
721 +#     'weblate.trans.checks.chars.NewlineCountingCheck',
722 +#     'weblate.trans.checks.markup.BBCodeCheck',
723 +#     'weblate.trans.checks.chars.ZeroWidthSpaceCheck',
724 +#     'weblate.trans.checks.markup.XMLValidityCheck',
725 +#     'weblate.trans.checks.markup.XMLTagsCheck',
726 +#     'weblate.trans.checks.source.OptionalPluralCheck',
727 +#     'weblate.trans.checks.source.EllipsisCheck',
728 +#     'weblate.trans.checks.source.MultipleFailingCheck',
729 +# )
730 +
731 +# List of automatic fixups
732 +# AUTOFIX_LIST = (
733 +#     'weblate.trans.autofixes.whitespace.SameBookendingWhitespace',
734 +#     'weblate.trans.autofixes.chars.ReplaceTrailingDotsWithEllipsis',
735 +#     'weblate.trans.autofixes.chars.RemoveZeroSpace',
736 +#     'weblate.trans.autofixes.chars.RemoveControlChars',
737 +# )
738 +
739 +# List of enabled addons
740 +# WEBLATE_ADDONS = (
741 +#     'weblate.addons.gettext.GenerateMoAddon',
742 +#     'weblate.addons.gettext.UpdateLinguasAddon',
743 +#     'weblate.addons.gettext.UpdateConfigureAddon',
744 +#     'weblate.addons.gettext.MsgmergeAddon',
745 +#     'weblate.addons.gettext.GettextCustomizeAddon',
746 +#     'weblate.addons.cleanup.CleanupAddon',
747 +#     'weblate.addons.flags.SourceEditAddon',
748 +#     'weblate.addons.flags.TargetEditAddon',
749 +#     'weblate.addons.json.JSONCustomizeAddon',
750 +#     'weblate.addons.generate.GenerateFileAddon',
751 +#     'weblate.addons.properties.PropertiesSortAddon',
752 +# )
753 +
754 +
755 +
756 +# List of scripts to use in custom processing
757 +POST_UPDATE_SCRIPTS = (
758 +    '[xwiki-dev-tools]/weblate-scripts/post_update.sh',
759 +)
760 +POST_UPDATE_SCRIPTS = (
761 +    '[xwiki-dev-tools]/xwiki-dev-tools/weblate-scripts/post_update.sh',
762 +)
763 +POST_COMMIT_SCRIPTS = (
764 +    '[xwiki-dev-tools]/xwiki-dev-tools/weblate-scripts/post_commit.sh',
765 +)
766 +PRE_COMMIT_SCRIPTS = (
767 +    '[xwiki-dev-tools]/xwiki-dev-tools/weblate-scripts/pre_commit.sh',
768 +)
769 +
770 +# E-mail address that error messages come from.
771 +SERVER_EMAIL = '[email protected]'
772 +
773 +# Default email address to use for various automated correspondence from
774 +# the site managers. Used for registration emails.
775 +DEFAULT_FROM_EMAIL = '[email protected]'
776 +
777 +# List of URLs your site is supposed to serve
778 +ALLOWED_HOSTS = ["weblate.devxwiki.com"]
779 +
780 +# Example configuration to use memcached for caching
781 +CACHES = {
782 +    'default': {
783 +        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
784 +        'LOCATION': '127.0.0.1:11211',
785 +    },
786 +    'avatar': {
787 +        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
788 +        'LOCATION': os.path.join(DATA_DIR, 'avatar-cache'),
789 +        'TIMEOUT': 3600,
790 +        'OPTIONS': {
791 +            'MAX_ENTRIES': 1000,
792 +        },
793 +    }
794 +}
795 +
796 +# REST framework settings for API
797 +REST_FRAMEWORK = {
798 +    # Use Django's standard `django.contrib.auth` permissions,
799 +    # or allow read-only access for unauthenticated users.
800 +    'DEFAULT_PERMISSION_CLASSES': [
801 +        'rest_framework.permissions.IsAuthenticatedOrReadOnly'
802 +    ],
803 +    'DEFAULT_AUTHENTICATION_CLASSES': (
804 +        'rest_framework.authentication.TokenAuthentication',
805 +        'weblate.api.authentication.BearerAuthentication',
806 +        'rest_framework.authentication.SessionAuthentication',
807 +    ),
808 +    'DEFAULT_THROTTLE_CLASSES': (
809 +        'rest_framework.throttling.AnonRateThrottle',
810 +        'rest_framework.throttling.UserRateThrottle'
811 +    ),
812 +    'DEFAULT_THROTTLE_RATES': {
813 +        'anon': '100/day',
814 +        'user': '1000/day'
815 +    },
816 +    'DEFAULT_PAGINATION_CLASS': (
817 +        'rest_framework.pagination.PageNumberPagination'
818 +    ),
819 +    'PAGE_SIZE': 20,
820 +    'VIEW_DESCRIPTION_FUNCTION': 'weblate.api.views.get_view_description',
821 +    'UNAUTHENTICATED_USER': 'weblate.accounts.models.get_anonymous',
822 +}
823 +
824 +# Example for restricting access to logged in users
825 +# LOGIN_REQUIRED_URLS = (
826 +#     r'/(.*)$',
827 +# )
828 +
829 +# In such case you will want to include some of the exceptions
830 +# LOGIN_REQUIRED_URLS_EXCEPTIONS = (
831 +#    r'/accounts/(.*)$', # Required for login
832 +#    r'/static/(.*)$',   # Required for development mode
833 +#    r'/widgets/(.*)$',  # Allowing public access to widgets
834 +#    r'/data/(.*)$',     # Allowing public access to data exports
835 +#    r'/hooks/(.*)$',    # Allowing public access to notification hooks
836 +#    r'/api/(.*)$',      # Allowing access to API
837 +#    r'/js/i18n/$',      # Javascript localization
838 +#    r'/contact/$',      # Optional for contact form
839 +#    r'/legal/(.*)$',    # Optional for legal app
840 +# )
841 +
842 +# Force sane test runner
843 +TEST_RUNNER = 'django.test.runner.DiscoverRunner'
844 +{{/code}}
845 +
846 +You should replace this parameters:
847 +
848 +* ##[DATABASE_NAME]##
849 +* ##[DATABASE_USERNAME]##
850 +* ##[DATABASE_PASSWORD]##
851 +* ##[DATABASE_HOST]##
852 +* ##[GITHUB_USERNAME]##
853 +* ##[SOCIAL_AUTH_GITHUB_KEY]##
854 +* ##[SOCIAL_AUTH_GITHUB_SECRET]##
855 +* ##[SOCIAL_AUTH_XWIKI_KEY]##: choose a unique string
856 +* ##[xwiki-dev-tools]##: local path of [[https:~~/~~/github.com/xwiki/xwiki-dev-tools>>https://github.com/xwiki/xwiki-dev-tools]]
857 +
858 +Generate a secret key by running {{box}}$VIRTUALENV/share/weblate/examples/generate-secret-key{{/box}}.
859 +
860 +In order for the settings to be found, you'll have to set the ##DJANGO_SETTINGS_MODULE## environment variable. You can do it by adding {{box}}export DJANGO_SETTINGS_MODULE=weblate.settings{{/box}} at the end of {{box}}$VIRTUALENV/bin/activate{{/box}} file.
861 +
862 +Other useful configurations can be found [[here>>https://docs.weblate.org/en/latest/admin/install.html#production-setup]].
863 +
864 +== Database configuration ==
865 +
866 +Postgresql can be configured by following [[this steps>>https://docs.weblate.org/en/latest/admin/install.html#postgresql]].
867 +
868 +== Github configuration ==
869 +
870 +You can configure Weblate to use a github account to make pull requests as [[described here>>https://docs.weblate.org/en/latest/vcs.html#hub-setup]] (##xwikiorgci## can be used).
871 +
872 += Running Weblate =
873 +
874 +Make sure you have sourced the virtualenv activate script ({{box}}source $VIRTUALENV/bin/activate{{/box}}) and run {{box}}weblate runserver{{/box}}.
875 +
876 += How to import translation files =
877 +
878 +Login with an admin account to your weblate instance. You can generate one by running {{box}}weblate createadmin{{/box}}.
879 +
880 +Go to the administration panel by clicking the [[image:image.png||height="16" width="17"]] icon or directly by going to ##/admin##.
881 +
882 +You'll need to create a project frst. We usually create one project for one git repository, for instance we have an ##XWiki Platform## project.
883 +
884 +== Create the main component ==
885 +
886 +You have to create the main component which will be the base of other components. A component is linked to a base translation file and all the related language files (e.g. ##ApplicationResources.properties## is the base translation file and ##ApplicationResources_fr.properties## is a related language file). This main component will be used to clone the git repository so that other components will use a link to this repository instead of making duplicates.
887 +
888 +Here is a configuration example of a main component:
889 +
890 +* Component name: **Help.SupportPanel.Content**
891 +* URL slug: **help-supportpanel-content**
892 +* Project: **XWiki Platform**
893 +* Version control system: **Github**
894 +* Source code repository: **https:~/~/github.com/xwiki/xwiki-platform**
895 +* Repository push URL: **https:~/~/github.com/xwiki/xwiki-platform**
896 +* File mask: **.translation/xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-ui/src/main/resources/Help/SupportPanel/Content_*.properties**
897 +* Monolingual base language file: **.translation/xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-ui/src/main/resources/Help/SupportPanel/Content_en.properties**
898 +* File format: **Java Properties (UTF-8)**
899 +* Additional commit files:
900 +** **xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-ui/src/main/resources/Help/SupportPanel/Content.xml**
901 +** **xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-ui/src/main/resources/Help/SupportPanel/Content.%(language)s.xml**
902 +* Post-update script: **post_update.sh**
903 +* Pre-commit script: **pre_commit.sh**
904 +* Post-commit script: **post_commit.sh**
905 +
906 +After saving this component, Weblate will clone the git repository in {{box}}$VIRTUALENV/lib/python2.7/site-packages/data/vcs/xwiki-platform/help-supportpanel-content{{/box}}. An error should occur saying that the monolingual template file was not found. You need to run the (% class="mark" %)post_update.sh(%%) script a first time to fix this issue. For that, you can run {{box}}WL_PATH=$VIRTUALENV/local/lib/python2.7/site-packages/data/vcs/xwiki-platform/supportpanel xwiki-dev-tools/weblate-scripts/post_update.sh{{/box}}. See the [[readme file>>https://github.com/xwiki/xwiki-dev-tools/blob/master/weblate-scripts/README.md]] of the scripts repository to understand how it works.
907 +
908 +== Create other components ==
909 +
910 +Here is an example of another component based on the previous one:
911 +
912 +* Component name: **AnnotationCode.Translations**
913 +* URL slug: **annotationcode-translations**
914 +* Project: **XWiki Platform**
915 +* Version control system: **Github**
916 +* Source code repository: **weblate:~/~/xwiki-platform/help-supportpanel-content**
917 +* Repository push URL: **none**
918 +* File mask: **.translation/xwiki-platform-core/xwiki-platform-annotations/xwiki-platform-annotation-ui/src/main/resources/AnnotationCode/Translations_*.properties**
919 +* Monolingual base language file: **.translation/xwiki-platform-core/xwiki-platform-annotations/xwiki-platform-annotation-ui/src/main/resources/AnnotationCode/Translations_en.properties**
920 +* File format: **Java Properties (UTF-8)**
921 +* Additional commit files:
922 +** **xwiki-platform-core/xwiki-platform-annotations/xwiki-platform-annotation-ui/src/main/resources/AnnotationCode/Translations.xml**
923 +** **xwiki-platform-core/xwiki-platform-annotations/xwiki-platform-annotation-ui/src/main/resources/AnnotationCode/Translations.%(language)s.xml**
924 +* Post-update script: **none**
925 +* Pre-commit script: **pre_commit.sh**
926 +* Post-commit script: **post_commit.sh**
927 +
928 +There are many components to be created, that's why the (% class="mark" %)generate_components.py(%%) script has been written to generate a json file with all the components to be created, based on a list of translation file.
929 +
930 +The list of translation file looks like this:
931 +
932 +(% class="box" %)
933 +(((
934 +##Help.SupportPanel.Content xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-ui/src/main/resources/Help/SupportPanel/Content.xml
935 +XWiki.XWikiSyntaxGeneralRemarks xwiki-platform-core/xwiki-platform-help/xwiki-platform-help-ui/src/main/resources/XWiki/XWikiSyntaxGeneralRemarks.xml
936 +TemplateMacro xwiki-platform-core/xwiki-platform-template/xwiki-platform-template-api/src/main/resources/ApplicationResources.properties
937 +Localization Macro xwiki-platform-core/xwiki-platform-localization/xwiki-platform-localization-macro/src/main/resources/ApplicationResources.properties
938 +...##
939 +)))
940 +
941 +Running the script will generate the ##components.json## file. It can be imported by running {{box}}weblate import_json components.json ~-~-project xwiki-platform ~-~-main-component help-supportpanel-content{{/box}}.
942 +
943 += How to upgrade Weblate =
944 +
945 +The whole process can be found [[here>>https://docs.weblate.org/en/latest/admin/upgrade.html]].
946 +
947 += Miscellaneous =
948 +
949 +If the offloading indexing (OFFLOAD_INDEXING parameter) is activated (which should be), you'll have to run this command frequently (it can be a cron job) to update the index: {{box}}weblate update_index{{/box}}.

Get Connected