Browse files

allow multiple domains and languages for makemessages command; add op…

…tion to pass in multiple language to the compilemessages command
  • Loading branch information...
1 parent c28e700 commit 4fbb940bdbc26976d021791b21c4271fa229655c @jakul jakul committed with jakul Jun 7, 2012
View
50 django/core/management/commands/compilemessages.py
@@ -24,34 +24,38 @@ def compile_messages(stderr, locale=None):
raise CommandError("This script should be run from the Django Git checkout or your project or app tree, or with the settings module specified.")
for basedir in basedirs:
+ dirs = [basedir]
if locale:
- basedir = os.path.join(basedir, locale, 'LC_MESSAGES')
- for dirpath, dirnames, filenames in os.walk(basedir):
- for f in filenames:
- if f.endswith('.po'):
- stderr.write('processing file %s in %s\n' % (f, dirpath))
- fn = os.path.join(dirpath, f)
- if has_bom(fn):
- raise CommandError("The %s file has a BOM (Byte Order Mark). Django only supports .po files encoded in UTF-8 and without any BOM." % fn)
- pf = os.path.splitext(fn)[0]
- # Store the names of the .mo and .po files in an environment
- # variable, rather than doing a string replacement into the
- # command, so that we can take advantage of shell quoting, to
- # quote any malicious characters/escaping.
- # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html
- os.environ['djangocompilemo'] = pf + '.mo'
- os.environ['djangocompilepo'] = pf + '.po'
- if sys.platform == 'win32': # Different shell-variable syntax
- cmd = 'msgfmt --check-format -o "%djangocompilemo%" "%djangocompilepo%"'
- else:
- cmd = 'msgfmt --check-format -o "$djangocompilemo" "$djangocompilepo"'
- os.system(cmd)
+ dirs = [os.path.join(basedir, l, 'LC_MESSAGES') for l in (locale if isinstance(locale, list) else [locale])]
+
+
+ for dir in dirs:
+ for dirpath, dirnames, filenames in os.walk(dir):
+ for f in filenames:
+ if f.endswith('.po'):
+ stderr.write('processing file %s in %s\n' % (f, dirpath))
+ fn = os.path.join(dirpath, f)
+ if has_bom(fn):
+ raise CommandError("The %s file has a BOM (Byte Order Mark). Django only supports .po files encoded in UTF-8 and without any BOM." % fn)
+ pf = os.path.splitext(fn)[0]
+ # Store the names of the .mo and .po files in an environment
+ # variable, rather than doing a string replacement into the
+ # command, so that we can take advantage of shell quoting, to
+ # quote any malicious characters/escaping.
+ # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html
+ os.environ['djangocompilemo'] = pf + '.mo'
+ os.environ['djangocompilepo'] = pf + '.po'
+ if sys.platform == 'win32': # Different shell-variable syntax
+ cmd = 'msgfmt --check-format -o "%djangocompilemo%" "%djangocompilepo%"'
+ else:
+ cmd = 'msgfmt --check-format -o "$djangocompilemo" "$djangocompilepo"'
+ os.system(cmd)
class Command(BaseCommand):
option_list = BaseCommand.option_list + (
- make_option('--locale', '-l', dest='locale',
- help='The locale to process. Default is to process all.'),
+ make_option('--locale', '-l', dest='locale', action="append",
+ help='A locale to process. Default is to process all.'),
)
help = 'Compiles .po files to .mo files for use with builtin gettext support.'
View
52 django/core/management/commands/makemessages.py
@@ -248,7 +248,7 @@ def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
raise CommandError(
"errors happened while running msgattrib\n%s" % errors)
-def make_messages(locale=None, domain='django', verbosity=1, all=False,
+def make_messages(locale=None, domain=None, verbosity=1, all=False,
extensions=None, symlinks=False, ignore_patterns=None, no_wrap=False,
no_location=False, no_obsolete=False, stdout=sys.stdout):
"""
@@ -283,10 +283,15 @@ def make_messages(locale=None, domain='django', verbosity=1, all=False,
"is not created automatically, you have to create it by hand "
"if you want to enable i18n for your project or application.")
- if domain not in ('django', 'djangojs'):
+ if domain is None:
+ domains = ['django']
+ else:
+ domains = [domain] if not isinstance(domain, list) else domain
+
+ if any(d not in ('django', 'djangojs') for d in domains):
raise CommandError("currently makemessages only supports domains 'django' and 'djangojs'")
- if (locale is None and not all) or domain is None:
+ if (locale is None and not all) or not domains:
message = "Type '%s help %s' for usage information." % (os.path.basename(sys.argv[0]), sys.argv[1])
raise CommandError(message)
@@ -302,7 +307,7 @@ def make_messages(locale=None, domain='django', verbosity=1, all=False,
locales = []
if locale is not None:
- locales.append(locale)
+ locales += locale.split(',') if not isinstance(locale, list) else locale
elif all:
locale_dirs = filter(os.path.isdir, glob.glob('%s/*' % localedir))
locales = [os.path.basename(l) for l in locale_dirs]
@@ -317,28 +322,31 @@ def make_messages(locale=None, domain='django', verbosity=1, all=False,
if not os.path.isdir(basedir):
os.makedirs(basedir)
- pofile = os.path.join(basedir, '%s.po' % domain)
- potfile = os.path.join(basedir, '%s.pot' % domain)
-
- if os.path.exists(potfile):
- os.unlink(potfile)
-
- for dirpath, file in find_files(".", ignore_patterns, verbosity,
- stdout, symlinks=symlinks):
- process_file(file, dirpath, potfile, domain, verbosity, extensions,
- wrap, location, stdout)
-
- if os.path.exists(potfile):
- write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
- not invoked_for_django, wrap, location, no_obsolete)
+ for domain in domains:
+ if verbosity > 1:
+ stdout.write("processing domain %s\n" % domain)
+ pofile = os.path.join(basedir, '%s.po' % domain)
+ potfile = os.path.join(basedir, '%s.pot' % domain)
+
+ if os.path.exists(potfile):
+ os.unlink(potfile)
+
+ for dirpath, file in find_files(".", ignore_patterns, verbosity,
+ stdout, symlinks=symlinks):
+ process_file(file, dirpath, potfile, domain, verbosity, extensions,
+ wrap, location, stdout)
+
+ if os.path.exists(potfile):
+ write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
+ not invoked_for_django, wrap, location, no_obsolete)
class Command(NoArgsCommand):
option_list = NoArgsCommand.option_list + (
- make_option('--locale', '-l', default=None, dest='locale',
- help='Creates or updates the message files for the given locale (e.g. pt_BR).'),
- make_option('--domain', '-d', default='django', dest='domain',
- help='The domain of the message files (default: "django").'),
+ make_option('--locale', '-l', default=None, dest='locale', action='append',
+ help='Creates or updates the message files for the given locale(s) (e.g. pt_BR).'),
+ make_option('--domain', '-d', default=None, dest='domain', action='append',
+ help='The domain(s) of the message files (default: "django").'),
make_option('--all', '-a', action='store_true', dest='all',
default=False, help='Updates the message files for all existing locales.'),
make_option('--extension', '-e', dest='extensions',
View
19 docs/ref/django-admin.txt
@@ -104,12 +104,12 @@ compilemessages
Compiles .po files created with ``makemessages`` to .mo files for use with
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 to specify the locale(s) to process.
If not provided, all locales are processed.
Example usage::
- django-admin.py compilemessages --locale=br_PT
+ django-admin.py compilemessages --locale=pt_BR --locale=fr
createcachetable
----------------
@@ -422,11 +422,16 @@ Separate multiple extensions with commas or use -e or --extension multiple times
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 to specify the locale(s) to process.
Example usage::
- django-admin.py makemessages --locale=br_PT
+ django-admin.py makemessages --locale=pt_BR --locale=fr
+
+You can also use commas to separate multiple locales::
+
+ django-admin.py makemessages --locale=de,fr,pt_BR
+
.. django-admin-option:: --domain
@@ -436,6 +441,12 @@ Currently supported:
* ``django`` for all ``*.py``, ``*.html`` and ``*.txt`` files (default)
* ``djangojs`` for ``*.js`` files
+
+Example usage::
+
+ django-admin.py makemessages --domain=django --domain=djangojs
+
+
.. django-admin-option:: --symlinks
Use the ``--symlinks`` or ``-s`` option to follow symlinks to directories when
View
42 tests/regressiontests/i18n/commands/compilemessages.py
@@ -0,0 +1,42 @@
+from StringIO import StringIO
+from django.test import TestCase
+import os
+from django.core.management.commands import compilemessages
+from django.conf import settings
+
+class CompileMessagesFunctionTestCase(TestCase):
+ MO_FILE_DE = None
+ MO_FILE_FR = None
+
+ def setUp(self):
+ self._old_locale_paths = settings.LOCALE_PATHS
+ self.stderr = StringIO()
+ self.localedir = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), 'locale'
+ )
+ settings.LOCALE_PATHS = [self.localedir]
+ self.MO_FILE_DE = os.path.join(self.localedir, 'de/LC_MESSAGES/django.mo')
+ self.MO_FILE_FR = os.path.join(self.localedir, 'fr/LC_MESSAGES/django.mo')
+
+ def tearDown(self):
+ settings.LOCALE_PATHS = self._old_locale_paths
+ self.stderr.close()
+ self._rmfile(os.path.join(self.localedir, self.MO_FILE_DE))
+ 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):
+ command = compilemessages.Command()
+ command.execute(locale='de', stderr=self.stderr)
+
+ self.assertTrue(os.path.exists(self.MO_FILE_DE))
+
+ def test_multiple_locales(self):
+ command = compilemessages.Command()
+ command.execute(locale=['de', 'fr'], stderr=self.stderr)
+
+ self.assertTrue(os.path.exists(self.MO_FILE_DE))
+ self.assertTrue(os.path.exists(self.MO_FILE_FR))
View
30 tests/regressiontests/i18n/commands/makemessages.py
@@ -0,0 +1,30 @@
+import os
+from .extraction import ExtractorTests
+from django.core import management
+
+class MakeMessagesFunctionTestCase(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
2 tests/regressiontests/i18n/tests.py
@@ -30,9 +30,11 @@
JavascriptExtractorTests, IgnoredExtractorTests, SymlinkExtractorTests,
CopyPluralFormsExtractorTests, NoWrapExtractorTests,
NoLocationExtractorTests)
+ from .commands.makemessages import MakeMessagesFunctionTestCase
if can_run_compilation_tests:
from .commands.compilation import (PoFileTests, PoFileContentsTests,
PercentRenderingTests)
+ from .commands.compilemessages import CompileMessagesFunctionTestCase
from .contenttypes.tests import ContentTypeTests
from .forms import I18nForm, SelectDateForm, SelectDateWidget, CompanyForm
from .models import Company, TestModel

0 comments on commit 4fbb940

Please sign in to comment.