forked from CGM_Public/pretix_original
Select correct locale and timezone
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
Django>=1.7
|
Django>=1.7
|
||||||
|
pytz
|
||||||
django-bootstrap3
|
django-bootstrap3
|
||||||
django-compressor
|
django-compressor
|
||||||
BeautifulSoup4
|
BeautifulSoup4
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
ignore = E128
|
ignore = E128
|
||||||
max-line-length = 160
|
max-line-length = 160
|
||||||
exclude = tests,migrations,.ropeproject,static
|
exclude = tests,migrations,.ropeproject,static
|
||||||
max-complexity = 12
|
max-complexity = 16
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ INSTALLED_APPS = (
|
|||||||
|
|
||||||
MIDDLEWARE_CLASSES = (
|
MIDDLEWARE_CLASSES = (
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
'django.middleware.locale.LocaleMiddleware',
|
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
||||||
|
'tixlbase.middleware.LocaleMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
'tixlcontrol.middleware.PermissionMiddleware',
|
'tixlcontrol.middleware.PermissionMiddleware',
|
||||||
@@ -85,7 +85,7 @@ DATABASES = {
|
|||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/dev/topics/i18n/
|
# https://docs.djangoproject.com/en/dev/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = 'en'
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class TixlUserAdmin(UserAdmin):
|
|||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {'fields': ('identifier', 'event', 'username', 'password')}),
|
(None, {'fields': ('identifier', 'event', 'username', 'password')}),
|
||||||
(_('Personal info'), {'fields': ('familyname', 'givenname', 'email')}),
|
(_('Personal info'), {'fields': ('familyname', 'givenname', 'email')}),
|
||||||
|
(_('Locale'), {'fields': ('locale', 'timezone')}),
|
||||||
(_('Permissions'), {'fields': ('is_active', 'is_staff',
|
(_('Permissions'), {'fields': ('is_active', 'is_staff',
|
||||||
'groups', 'user_permissions')}),
|
'groups', 'user_permissions')}),
|
||||||
)
|
)
|
||||||
|
|||||||
118
src/tixlbase/middleware.py
Normal file
118
src/tixlbase/middleware.py
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
import pytz
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.urlresolvers import resolve
|
||||||
|
from django.middleware.locale import LocaleMiddleware as BaseLocaleMiddleware
|
||||||
|
from django.utils.translation.trans_real import (
|
||||||
|
get_supported_language_variant,
|
||||||
|
parse_accept_lang_header,
|
||||||
|
language_code_re,
|
||||||
|
check_for_language,
|
||||||
|
_supported
|
||||||
|
)
|
||||||
|
from django.utils.translation import LANGUAGE_SESSION_KEY
|
||||||
|
from django.utils import translation, timezone
|
||||||
|
from collections import OrderedDict
|
||||||
|
from django.utils.cache import patch_vary_headers
|
||||||
|
|
||||||
|
from tixlbase.models import Event
|
||||||
|
|
||||||
|
|
||||||
|
class LocaleMiddleware(BaseLocaleMiddleware):
|
||||||
|
|
||||||
|
"""
|
||||||
|
This middleware sets the correct locale and timezone
|
||||||
|
for a request.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def process_request(self, request):
|
||||||
|
url = resolve(request.path_info)
|
||||||
|
if 'event' in url.kwargs and 'organizer' in url.kwargs:
|
||||||
|
try:
|
||||||
|
request.event = Event.objects.get(
|
||||||
|
slug=url.kwargs['event'],
|
||||||
|
organizer__slug=url.kwargs['organizer'],
|
||||||
|
)
|
||||||
|
except Event.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
language = get_language_from_request(request)
|
||||||
|
translation.activate(language)
|
||||||
|
request.LANGUAGE_CODE = translation.get_language()
|
||||||
|
|
||||||
|
tzname = None
|
||||||
|
if request.user.is_authenticated():
|
||||||
|
tzname = request.user.timezone
|
||||||
|
if hasattr(request, 'event'):
|
||||||
|
tzname = request.event.timezone
|
||||||
|
if tzname:
|
||||||
|
try:
|
||||||
|
timezone.activate(pytz.timezone(tzname))
|
||||||
|
except pytz.UnknownTimeZoneError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
timezone.deactivate()
|
||||||
|
|
||||||
|
def process_response(self, request, response):
|
||||||
|
language = translation.get_language()
|
||||||
|
patch_vary_headers(response, ('Accept-Language',))
|
||||||
|
if 'Content-Language' not in response:
|
||||||
|
response['Content-Language'] = language
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def get_language_from_request(request):
|
||||||
|
"""
|
||||||
|
Analyzes the request to find what language the user wants the system to
|
||||||
|
show. Only languages listed in settings.LANGUAGES are taken into account.
|
||||||
|
If the user requests a sublanguage where we have a main language, we send
|
||||||
|
out the main language.
|
||||||
|
"""
|
||||||
|
global _supported
|
||||||
|
if _supported is None:
|
||||||
|
_supported = OrderedDict(settings.LANGUAGES)
|
||||||
|
|
||||||
|
# Priority 1: User settings
|
||||||
|
if request.user.is_authenticated():
|
||||||
|
lang_code = request.user.locale
|
||||||
|
if lang_code in _supported and lang_code is not None and check_for_language(lang_code):
|
||||||
|
return lang_code
|
||||||
|
|
||||||
|
# Priority 2: Anonymous user settings (session, cookie)
|
||||||
|
if hasattr(request, 'session'):
|
||||||
|
lang_code = request.session.get(LANGUAGE_SESSION_KEY)
|
||||||
|
if lang_code in _supported and lang_code is not None and check_for_language(lang_code):
|
||||||
|
return lang_code
|
||||||
|
|
||||||
|
lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
|
||||||
|
try:
|
||||||
|
return get_supported_language_variant(lang_code)
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Priority 3: Event default
|
||||||
|
if hassattr(request, 'event'):
|
||||||
|
lang_code = request.event.locale
|
||||||
|
try:
|
||||||
|
return get_supported_language_variant(lang_code)
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Priority 4: Browser default
|
||||||
|
accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
|
||||||
|
for accept_lang, unused in parse_accept_lang_header(accept):
|
||||||
|
if accept_lang == '*':
|
||||||
|
break
|
||||||
|
|
||||||
|
if not language_code_re.search(accept_lang):
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
return get_supported_language_variant(accept_lang)
|
||||||
|
except LookupError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
return get_supported_language_variant(settings.LANGUAGE_CODE)
|
||||||
|
except LookupError:
|
||||||
|
return settings.LANGUAGE_CODE
|
||||||
26
src/tixlbase/migrations/0007_auto_20140914_1301.py
Normal file
26
src/tixlbase/migrations/0007_auto_20140914_1301.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('tixlbase', '0006_auto_20140912_1855'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='locale',
|
||||||
|
field=models.CharField(choices=[('de', 'German'), ('en', 'English')], max_length=50, default='en'),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='timezone',
|
||||||
|
field=models.CharField(max_length=100, default='UTC'),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
]
|
||||||
30
src/tixlbase/migrations/0008_auto_20140914_1304.py
Normal file
30
src/tixlbase/migrations/0008_auto_20140914_1304.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('tixlbase', '0007_auto_20140914_1301'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='event',
|
||||||
|
name='timezone',
|
||||||
|
field=models.CharField(max_length=100, default='UTC', verbose_name='Default timezone'),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='user',
|
||||||
|
name='locale',
|
||||||
|
field=models.CharField(max_length=50, verbose_name='Language', default='en', choices=[('de', 'German'), ('en', 'English')]),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='user',
|
||||||
|
name='timezone',
|
||||||
|
field=models.CharField(max_length=100, default='UTC', verbose_name='Timezone'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -83,6 +83,13 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||||||
verbose_name=('Is site admin'))
|
verbose_name=('Is site admin'))
|
||||||
date_joined = models.DateTimeField(auto_now_add=True,
|
date_joined = models.DateTimeField(auto_now_add=True,
|
||||||
verbose_name=_('Date joined'))
|
verbose_name=_('Date joined'))
|
||||||
|
locale = models.CharField(max_length=50,
|
||||||
|
choices=settings.LANGUAGES,
|
||||||
|
default=settings.LANGUAGE_CODE,
|
||||||
|
verbose_name=_('Language'))
|
||||||
|
timezone = models.CharField(max_length=100,
|
||||||
|
default=settings.TIME_ZONE,
|
||||||
|
verbose_name=('Timezone'))
|
||||||
|
|
||||||
objects = UserManager()
|
objects = UserManager()
|
||||||
|
|
||||||
@@ -215,6 +222,9 @@ class Event(models.Model):
|
|||||||
locale = models.CharField(max_length=10,
|
locale = models.CharField(max_length=10,
|
||||||
choices=settings.LANGUAGES,
|
choices=settings.LANGUAGES,
|
||||||
verbose_name=_("Default locale"))
|
verbose_name=_("Default locale"))
|
||||||
|
timezone = models.CharField(max_length=100,
|
||||||
|
default=settings.TIME_ZONE,
|
||||||
|
verbose_name=_('Default timezone'))
|
||||||
currency = models.CharField(max_length=10,
|
currency = models.CharField(max_length=10,
|
||||||
verbose_name=_("Default currency"))
|
verbose_name=_("Default currency"))
|
||||||
date_from = models.DateTimeField(verbose_name=_("Event start time"))
|
date_from = models.DateTimeField(verbose_name=_("Event start time"))
|
||||||
|
|||||||
Reference in New Issue
Block a user