Made (make|compile)messages commands accept multiple locales at once.

Thanks Craig Blaszczyk for the initial patch. Refs #17181.
This commit is contained in:
Craig Blaszczyk 2012-06-07 11:23:25 +02:00 committed by Ramiro Morales
parent 295650bd01
commit 6158c79dbe
8 changed files with 171 additions and 14 deletions

View File

@ -98,6 +98,7 @@ answer newbie questions, and generally made Django that much better:
Mark Biggers <biggers@utsl.com> Mark Biggers <biggers@utsl.com>
Paul Bissex <http://e-scribe.com/> Paul Bissex <http://e-scribe.com/>
Simon Blanchard Simon Blanchard
Craig Blaszczyk <masterjakul@gmail.com>
David Blewett <david@dawninglight.net> David Blewett <david@dawninglight.net>
Matt Boersma <matt@sprout.org> Matt Boersma <matt@sprout.org>
Artem Gnilov <boobsd@gmail.com> Artem Gnilov <boobsd@gmail.com>

View File

@ -28,10 +28,14 @@ def compile_messages(stderr, locale=None):
for basedir in basedirs: for basedir in basedirs:
if locale: if locale:
basedir = os.path.join(basedir, locale, 'LC_MESSAGES') dirs = [os.path.join(basedir, l, 'LC_MESSAGES') for l in (locale if isinstance(locale, list) else [locale])]
for dirpath, dirnames, filenames in os.walk(basedir): else:
dirs = [basedir]
for ldir in dirs:
for dirpath, dirnames, filenames in os.walk(ldir):
for f in filenames: for f in filenames:
if f.endswith('.po'): if not f.endswith('.po'):
continue
stderr.write('processing file %s in %s\n' % (f, dirpath)) stderr.write('processing file %s in %s\n' % (f, dirpath))
fn = os.path.join(dirpath, f) fn = os.path.join(dirpath, f)
if has_bom(fn): if has_bom(fn):
@ -53,8 +57,8 @@ def compile_messages(stderr, locale=None):
class Command(BaseCommand): class Command(BaseCommand):
option_list = BaseCommand.option_list + ( option_list = BaseCommand.option_list + (
make_option('--locale', '-l', dest='locale', make_option('--locale', '-l', dest='locale', action='append',
help='The locale to process. Default is to process all.'), help='locale(s) to process (e.g. de_AT). Default is to process all. Can be used multiple times, accepts a comma-separated list of locale names.'),
) )
help = 'Compiles .po files to .mo files for use with builtin gettext support.' help = 'Compiles .po files to .mo files for use with builtin gettext support.'

View File

@ -304,7 +304,7 @@ def make_messages(locale=None, domain='django', verbosity=1, all=False,
locales = [] locales = []
if locale is not None: if locale is not None:
locales.append(str(locale)) locales += locale.split(',') if not isinstance(locale, list) else locale
elif all: elif all:
locale_dirs = filter(os.path.isdir, glob.glob('%s/*' % localedir)) locale_dirs = filter(os.path.isdir, glob.glob('%s/*' % localedir))
locales = [os.path.basename(l) for l in locale_dirs] locales = [os.path.basename(l) for l in locale_dirs]
@ -341,8 +341,8 @@ def make_messages(locale=None, domain='django', verbosity=1, all=False,
class Command(NoArgsCommand): class Command(NoArgsCommand):
option_list = NoArgsCommand.option_list + ( option_list = NoArgsCommand.option_list + (
make_option('--locale', '-l', default=None, dest='locale', make_option('--locale', '-l', default=None, dest='locale', action='append',
help='Creates or updates the message files for the given locale (e.g. pt_BR).'), help='Creates or updates the message files for the given locale(s) (e.g. pt_BR). Can be used multiple times, accepts a comma-separated list of locale names.'),
make_option('--domain', '-d', default='django', dest='domain', make_option('--domain', '-d', default='django', dest='domain',
help='The domain of the message files (default: "django").'), help='The domain of the message files (default: "django").'),
make_option('--all', '-a', action='store_true', dest='all', make_option('--all', '-a', action='store_true', dest='all',

View File

@ -107,12 +107,21 @@ compilemessages
Compiles .po files created with ``makemessages`` to .mo files for use with Compiles .po files created with ``makemessages`` to .mo files for use with
the builtin gettext support. See :doc:`/topics/i18n/index`. the builtin gettext support. See :doc:`/topics/i18n/index`.
Use the :djadminopt:`--locale` option to specify the locale to process. Use the :djadminopt:`--locale` option (or its shorter version ``-l``) to
If not provided, all locales are processed. specify the locale(s) to process. If not provided, all locales are processed.
Example usage:: Example usage::
django-admin.py compilemessages --locale=pt_BR django-admin.py compilemessages --locale=pt_BR
django-admin.py compilemessages --locale=pt_BR --locale=fr
django-admin.py compilemessages -l pt_BR
django-admin.py compilemessages -l pt_BR -l fr
django-admin.py compilemessages --locale=pt_BR,fr
django-admin.py compilemessages -l pt_BR,fr
.. versionchanged:: 1.6
Added the ability to specify multiple locales.
createcachetable createcachetable
---------------- ----------------
@ -422,11 +431,24 @@ Separate multiple extensions with commas or use -e or --extension multiple times
django-admin.py makemessages --locale=de --extension=html,txt --extension xml django-admin.py makemessages --locale=de --extension=html,txt --extension xml
Use the :djadminopt:`--locale` option to specify the locale to process. Use the :djadminopt:`--locale` option (or its shorter version ``-l``) to
specify the locale(s) to process.
Example usage:: Example usage::
django-admin.py makemessages --locale=pt_BR django-admin.py makemessages --locale=pt_BR
django-admin.py makemessages --locale=pt_BR --locale=fr
django-admin.py makemessages -l pt_BR
django-admin.py makemessages -l pt_BR -l fr
You can also use commas to separate multiple locales::
django-admin.py makemessages --locale=de,fr,pt_BR
django-admin.py makemessages -l de,fr,pt_BR
.. versionchanged:: 1.6
Added the ability to specify multiple locales.
.. django-admin-option:: --domain .. django-admin-option:: --domain

View File

@ -68,3 +68,34 @@ class PercentRenderingTests(MessageCompilationTests):
t = Template('{% load i18n %}{% trans "Completed 50%% of all the tasks" %}') t = Template('{% load i18n %}{% trans "Completed 50%% of all the tasks" %}')
rendered = t.render(Context({})) rendered = t.render(Context({}))
self.assertEqual(rendered, 'IT translation of Completed 50%% of all the tasks') self.assertEqual(rendered, 'IT translation of Completed 50%% of all the tasks')
@override_settings(LOCALE_PATHS=(os.path.join(test_dir, 'locale'),))
class MultipleLocaleCompilationTests(MessageCompilationTests):
MO_FILE_HR = None
MO_FILE_FR = None
def setUp(self):
super(MultipleLocaleCompilationTests, self).setUp()
self.localedir = os.path.join(test_dir, 'locale')
self.MO_FILE_HR = os.path.join(self.localedir, 'hr/LC_MESSAGES/django.mo')
self.MO_FILE_FR = os.path.join(self.localedir, 'fr/LC_MESSAGES/django.mo')
self.addCleanup(self._rmfile, os.path.join(self.localedir, self.MO_FILE_HR))
self.addCleanup(self._rmfile, os.path.join(self.localedir, self.MO_FILE_FR))
def _rmfile(self, filepath):
if os.path.exists(filepath):
os.remove(filepath)
def test_one_locale(self):
os.chdir(test_dir)
call_command('compilemessages', locale='hr', stderr=StringIO())
self.assertTrue(os.path.exists(self.MO_FILE_HR))
def test_multiple_locales(self):
os.chdir(test_dir)
call_command('compilemessages', locale=['hr', 'fr'], stderr=StringIO())
self.assertTrue(os.path.exists(self.MO_FILE_HR))
self.assertTrue(os.path.exists(self.MO_FILE_FR))

View File

@ -327,3 +327,30 @@ class KeepPotFileExtractorTests(ExtractorTests):
management.call_command('makemessages', locale=LOCALE, verbosity=0, management.call_command('makemessages', locale=LOCALE, verbosity=0,
keep_pot=True) keep_pot=True)
self.assertTrue(os.path.exists(self.POT_FILE)) self.assertTrue(os.path.exists(self.POT_FILE))
class MultipleLocaleExtractionTests(ExtractorTests):
PO_FILE_PT = 'locale/pt/LC_MESSAGES/django.po'
PO_FILE_DE = 'locale/de/LC_MESSAGES/django.po'
LOCALES = ['pt', 'de', 'ch']
def tearDown(self):
os.chdir(self.test_dir)
for locale in self.LOCALES:
try:
self._rmrf('locale/%s' % locale)
except OSError:
pass
os.chdir(self._cwd)
def test_multiple_locales(self):
os.chdir(self.test_dir)
management.call_command('makemessages', locale=['pt','de'], verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE_PT))
self.assertTrue(os.path.exists(self.PO_FILE_DE))
def test_comma_separated_locales(self):
os.chdir(self.test_dir)
management.call_command('makemessages', locale='pt,de,ch', verbosity=0)
self.assertTrue(os.path.exists(self.PO_FILE_PT))
self.assertTrue(os.path.exists(self.PO_FILE_DE))

View File

@ -0,0 +1,71 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-12-04 04:59-0600\n"
"PO-Revision-Date: 2013-01-16 22:53-0300\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#. Translators: Django template comment for translators
#: templates/test.html:9
#, python-format
msgid "I think that 100%% is more that 50%% of anything."
msgstr ""
#: templates/test.html:10
#, python-format
msgid "I think that 100%% is more that 50%% of %(obj)s."
msgstr ""
#: templates/test.html:70
#, python-format
msgid "Literal with a percent symbol at the end %%"
msgstr ""
#: templates/test.html:71
#, python-format
msgid "Literal with a percent %% symbol in the middle"
msgstr ""
#: templates/test.html:72
#, python-format
msgid "Completed 50%% of all the tasks"
msgstr ""
#: templates/test.html:73
#, python-format
msgctxt "ctx0"
msgid "Completed 99%% of all the tasks"
msgstr ""
#: templates/test.html:74
#, python-format
msgid "Shouldn't double escape this sequence: %% (two percent signs)"
msgstr ""
#: templates/test.html:75
#, python-format
msgctxt "ctx1"
msgid "Shouldn't double escape this sequence %% either"
msgstr ""
#: templates/test.html:76
#, python-format
msgid "Looks like a str fmt spec %%s but shouldn't be interpreted as such"
msgstr "Translation of the above string"
#: templates/test.html:77
#, python-format
msgid "Looks like a str fmt spec %% o but shouldn't be interpreted as such"
msgstr "Translation contains %% for the above string"

View File

@ -32,10 +32,11 @@ if can_run_extraction_tests:
from .commands.extraction import (ExtractorTests, BasicExtractorTests, from .commands.extraction import (ExtractorTests, BasicExtractorTests,
JavascriptExtractorTests, IgnoredExtractorTests, SymlinkExtractorTests, JavascriptExtractorTests, IgnoredExtractorTests, SymlinkExtractorTests,
CopyPluralFormsExtractorTests, NoWrapExtractorTests, CopyPluralFormsExtractorTests, NoWrapExtractorTests,
NoLocationExtractorTests, KeepPotFileExtractorTests) NoLocationExtractorTests, KeepPotFileExtractorTests,
MultipleLocaleExtractionTests)
if can_run_compilation_tests: if can_run_compilation_tests:
from .commands.compilation import (PoFileTests, PoFileContentsTests, from .commands.compilation import (PoFileTests, PoFileContentsTests,
PercentRenderingTests) PercentRenderingTests, MultipleLocaleCompilationTests)
from .contenttypes.tests import ContentTypeTests from .contenttypes.tests import ContentTypeTests
from .forms import I18nForm, SelectDateForm, SelectDateWidget, CompanyForm from .forms import I18nForm, SelectDateForm, SelectDateWidget, CompanyForm
from .models import Company, TestModel from .models import Company, TestModel