general: switch i18n to django (#6735)
This commit is contained in:
parent
079ccafc75
commit
0de5efb88a
|
@ -1,9 +1,7 @@
|
|||
include ChangeLog
|
||||
include MANIFEST.in
|
||||
include VERSION
|
||||
include wcs.cfg-sample
|
||||
include po/Makefile
|
||||
include po/*.po
|
||||
include po/*.pot
|
||||
recursive-include wcs/locale *.po *.mo
|
||||
recursive-include extra/ *.py
|
||||
recursive-include data/web/ *.html *.css *.png
|
||||
recursive-include data/themes/default/ *.html *.css *.png *.gif *.jpg *.js *.ezt *.xml
|
||||
|
|
38
po/Makefile
38
po/Makefile
|
@ -1,38 +0,0 @@
|
|||
POFILES=$(wildcard *.po)
|
||||
MOFILES=$(POFILES:.po=.mo)
|
||||
PYFILES=$(shell find ../wcs -name '*.py' | grep -v vendor)
|
||||
|
||||
all: $(MOFILES)
|
||||
|
||||
install: all
|
||||
for file in $(MOFILES); do \
|
||||
lang=`echo $$file | sed 's/\.mo//'`; \
|
||||
install -d $(prefix)/usr/share/locale/$$lang/LC_MESSAGES/; \
|
||||
install -m 0644 $$file $(prefix)/usr/share/locale/$$lang/LC_MESSAGES/wcs.mo; \
|
||||
done
|
||||
|
||||
wcs.pot: $(PYFILES)
|
||||
@echo "Rebuilding the pot file"
|
||||
rm -f wcs.pot tmp.*.pot
|
||||
cnt=0;
|
||||
for file in $(PYFILES); do \
|
||||
cnt=$$(expr $$cnt + 1); \
|
||||
bn=$$cnt.`basename $$file`; \
|
||||
xgettext --keyword=N_ --keyword=C_ -c -L Python -o tmp.$$bn.pot $$file; \
|
||||
done
|
||||
msgcat tmp.*.pot > wcs.pot
|
||||
rm tmp.*.pot
|
||||
|
||||
%.mo: %.po
|
||||
msgfmt -o $@ $<
|
||||
|
||||
%.po: wcs.pot
|
||||
@echo -n "Merging wcs.pot and $@"
|
||||
@msgmerge $@ wcs.pot -o $@.new
|
||||
@if [ "`diff $@ $@.new | grep '[<>]' | wc -l`" -ne 2 ]; then \
|
||||
mv -f $@.new $@; \
|
||||
else \
|
||||
rm -f $@.new; \
|
||||
fi
|
||||
@msgfmt --statistics $@
|
||||
|
67
setup.py
67
setup.py
|
@ -2,20 +2,24 @@
|
|||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from distutils.core import setup
|
||||
from distutils import cmd
|
||||
from distutils.command.install_data import install_data as _install_data
|
||||
from distutils.cmd import Command
|
||||
from distutils.command.build import build as _build
|
||||
from distutils.command.sdist import sdist
|
||||
from setuptools.command.install_lib import install_lib as _install_lib
|
||||
from setuptools import setup
|
||||
|
||||
local_cfg = None
|
||||
if os.path.exists('wcs/wcs_cfg.py'):
|
||||
local_cfg = file('wcs/wcs_cfg.py').read()
|
||||
os.unlink('wcs/wcs_cfg.py')
|
||||
|
||||
class build_trans(cmd.Command):
|
||||
description = 'Compile .po files into .mo files'
|
||||
|
||||
class compile_translations(Command):
|
||||
description = 'compile message catalogs to MO files via django compilemessages'
|
||||
user_options = []
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
|
@ -23,30 +27,27 @@ class build_trans(cmd.Command):
|
|||
pass
|
||||
|
||||
def run(self):
|
||||
po_dir = os.path.join(os.path.dirname(os.curdir), 'po')
|
||||
for path, names, filenames in os.walk(po_dir):
|
||||
for f in filenames:
|
||||
if f.endswith('.po'):
|
||||
lang = f[:-3]
|
||||
src = os.path.join(path, f)
|
||||
dest_path = os.path.join('build', 'locale', lang, 'LC_MESSAGES')
|
||||
dest = os.path.join(dest_path, 'wcs.mo')
|
||||
if not os.path.exists(dest_path):
|
||||
os.makedirs(dest_path)
|
||||
if not os.path.exists(dest):
|
||||
print 'Compiling %s' % src
|
||||
subprocess.call(['msgfmt', src, '--output-file', dest])
|
||||
else:
|
||||
src_mtime = os.stat(src)[8]
|
||||
dest_mtime = os.stat(dest)[8]
|
||||
if src_mtime > dest_mtime:
|
||||
print 'Compiling %s' % src
|
||||
subprocess.call(['msgfmt', src, '--output-file', dest])
|
||||
try:
|
||||
from django.core.management import call_command
|
||||
for path, dirs, files in os.walk('wcs'):
|
||||
if 'locale' not in dirs:
|
||||
continue
|
||||
curdir = os.getcwd()
|
||||
os.chdir(os.path.realpath(path))
|
||||
call_command('compilemessages')
|
||||
os.chdir(curdir)
|
||||
except ImportError:
|
||||
sys.stderr.write('!!! Please install Django >= 1.4 to build translations\n')
|
||||
|
||||
|
||||
class build(_build):
|
||||
sub_commands = _build.sub_commands + [('build_trans', None)]
|
||||
sub_commands = [('compile_translations', None)] + _build.sub_commands
|
||||
|
||||
|
||||
class install_lib(_install_lib):
|
||||
def run(self):
|
||||
_build.run(self)
|
||||
self.run_command('compile_translations')
|
||||
_install_lib.run(self)
|
||||
|
||||
|
||||
class eo_sdist(sdist):
|
||||
|
@ -65,15 +66,6 @@ class eo_sdist(sdist):
|
|||
os.remove('VERSION')
|
||||
|
||||
|
||||
class install_data(_install_data):
|
||||
def run(self):
|
||||
for lang in os.listdir('build/locale/'):
|
||||
lang_dir = os.path.join('share', 'locale', lang, 'LC_MESSAGES')
|
||||
lang_file = os.path.join('build', 'locale', lang, 'LC_MESSAGES', 'wcs.mo')
|
||||
self.data_files.append( (lang_dir, [lang_file]) )
|
||||
_install_data.run(self)
|
||||
|
||||
|
||||
def data_tree(destdir, sourcedir):
|
||||
extensions = ['.css', '.png', '.jpeg', '.jpg', '.gif', '.xml', '.html',
|
||||
'.js', '.ezt', '.dat', '.eot', '.svg', '.ttf', '.woff']
|
||||
|
@ -103,8 +95,8 @@ def get_version():
|
|||
|
||||
cmdclass = {
|
||||
'build': build,
|
||||
'build_trans': build_trans,
|
||||
'install_data': install_data,
|
||||
'compile_translations': compile_translations,
|
||||
'install_lib': install_lib,
|
||||
'sdist': eo_sdist
|
||||
}
|
||||
|
||||
|
@ -122,6 +114,7 @@ setup(
|
|||
'wcs.qommon.vendor'],
|
||||
cmdclass = cmdclass,
|
||||
scripts = ['wcsctl.py'],
|
||||
include_package_data=True,
|
||||
data_files = data_tree('share/wcs/web/', 'data/web/') + \
|
||||
data_tree('share/wcs/themes/', 'data/themes/') + \
|
||||
data_tree('share/wcs/vendor/', 'data/vendor/') + \
|
||||
|
|
|
@ -130,11 +130,6 @@ def test_register_cronjobs():
|
|||
def test_get_default_position():
|
||||
assert pub.get_default_position() == '50.84;4.36'
|
||||
|
||||
def test_install_lang():
|
||||
pub = create_temporary_pub()
|
||||
pub.install_lang('xx')
|
||||
assert pub.gettext.__self__.__class__.__name__ == 'NullTranslations'
|
||||
|
||||
def test_import_config_zip():
|
||||
pub = create_temporary_pub()
|
||||
pub.cfg['sp'] = {'what': 'ever'}
|
||||
|
|
|
@ -31,7 +31,6 @@ import traceback
|
|||
import __builtin__
|
||||
__builtin__.__dict__['N_'] = lambda x: x
|
||||
|
||||
import gettext
|
||||
import linecache
|
||||
from StringIO import StringIO
|
||||
import xml.etree.ElementTree as ET
|
||||
|
@ -41,6 +40,10 @@ try:
|
|||
except ImportError:
|
||||
raven = None
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils import translation
|
||||
from django.utils.translation import gettext, ngettext
|
||||
|
||||
from quixote.publish import Publisher, get_request, get_response, get_publisher, redirect
|
||||
from http_request import HTTPRequest
|
||||
from http_response import HTTPResponse, AfterJob
|
||||
|
@ -390,25 +393,13 @@ class QommonPublisher(Publisher, object):
|
|||
def render_response(self, content):
|
||||
return template.decorate(content, self.get_request().response)
|
||||
|
||||
def get_translation(self, lang):
|
||||
'''Retrieve a translation object for the given language and
|
||||
the current theme site.'''
|
||||
current_theme = self.cfg.get('branding', {}).get('theme', 'default')
|
||||
theme_directory = template.get_theme_directory(current_theme)
|
||||
if theme_directory:
|
||||
app_translation_path = os.path.join(theme_directory, '%s.mo' % lang)
|
||||
if os.path.exists(app_translation_path):
|
||||
trans = gettext.GNUTranslations(file(app_translation_path))
|
||||
trans.add_fallback(self.translations[lang])
|
||||
return trans
|
||||
return self.translations[lang]
|
||||
def install_lang(self, request):
|
||||
lang = request.language
|
||||
if lang is None or not lang in [x[0] for x in settings.LANGUAGES]:
|
||||
lang = 'en'
|
||||
translation.activate(lang)
|
||||
request.LANGUAGE_CODE = lang
|
||||
|
||||
def install_lang(self, lang=None):
|
||||
if lang is None or not self.translations.has_key(lang):
|
||||
lang = (os.environ.get('LANG') or 'en')[:2]
|
||||
if not self.translations.has_key(lang):
|
||||
lang = 'en'
|
||||
translation = self.get_translation(lang)
|
||||
self.gettext = translation.gettext
|
||||
self.ngettext = translation.ngettext
|
||||
|
||||
|
@ -635,7 +626,7 @@ class QommonPublisher(Publisher, object):
|
|||
return redirect(request.get_path() + new_query_string)
|
||||
|
||||
request.language = self.get_site_language()
|
||||
self.install_lang(request.language)
|
||||
self.install_lang(request)
|
||||
self.substitutions.feed(self)
|
||||
self.substitutions.feed(request)
|
||||
for extra_source in self.extra_sources:
|
||||
|
@ -810,7 +801,6 @@ class QommonPublisher(Publisher, object):
|
|||
return
|
||||
cls._initialized = True
|
||||
cls.load_extra_dirs()
|
||||
cls.load_translations()
|
||||
if cls.register_cron:
|
||||
cls.register_cronjobs()
|
||||
|
||||
|
@ -867,30 +857,6 @@ class QommonPublisher(Publisher, object):
|
|||
cls.translation_domains.append(name)
|
||||
|
||||
supported_languages = None
|
||||
@classmethod
|
||||
def load_translations(cls):
|
||||
cls.translations = {
|
||||
'C': gettext.NullTranslations(),
|
||||
'en': gettext.NullTranslations(),
|
||||
}
|
||||
|
||||
for lang in cls.supported_languages or []:
|
||||
try:
|
||||
cls.translations[lang] = gettext.translation(cls.APP_NAME, languages=[lang])
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
if cls.translation_domains:
|
||||
for domain in cls.translation_domains:
|
||||
for lang in cls.supported_languages or []:
|
||||
if not lang in cls.translations.keys():
|
||||
continue
|
||||
try:
|
||||
trans = gettext.translation(domain, languages=[lang])
|
||||
except IOError:
|
||||
continue
|
||||
cls.translations[lang]._catalog.update(trans._catalog)
|
||||
|
||||
cfg = None
|
||||
def write_cfg(self):
|
||||
s = cPickle.dumps(self.cfg)
|
||||
|
|
|
@ -34,19 +34,23 @@ TIME_ZONE = 'Europe/Brussels'
|
|||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
LANGUAGES = (('en', 'English'), ('fr', 'French'))
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = False
|
||||
USE_I18N = True
|
||||
|
||||
# If you set this to False, Django will not format dates, numbers and
|
||||
# calendars according to the current locale.
|
||||
USE_L10N = False
|
||||
USE_L10N = True
|
||||
|
||||
# If you set this to False, Django will not use timezone-aware datetimes.
|
||||
USE_TZ = True
|
||||
|
||||
LOCALE_PATHS = (os.path.join(PROJECT_PATH, 'wcs', 'locale'), )
|
||||
|
||||
# Absolute filesystem path to the directory that will hold user-uploaded files.
|
||||
# Example: "/var/www/example.com/media/"
|
||||
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')
|
||||
|
|
Loading…
Reference in New Issue