summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorRamiro Morales <cramm0@gmail.com>2013-01-25 13:23:33 -0300
committerRamiro Morales <cramm0@gmail.com>2013-01-25 13:23:33 -0300
commit2babab0bb351ff7a13fd23795f5e926a9bf95d22 (patch)
treedcdffc1d0964d88d71980b7bd07e4ced495e9300 /django
parentb9c8bbf3726a1956be1db70ffd3bef04a2e5311a (diff)
Patch by Claude for #16084.
Diffstat (limited to 'django')
-rw-r--r--django/core/management/commands/makemessages.py139
1 files changed, 91 insertions, 48 deletions
diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
index 4550605af2..b086e5f2dd 100644
--- a/django/core/management/commands/makemessages.py
+++ b/django/core/management/commands/makemessages.py
@@ -19,25 +19,28 @@ STATUS_OK = 0
@total_ordering
class TranslatableFile(object):
- def __init__(self, dirpath, file_name):
+ def __init__(self, dirpath, file_name, locale_dir):
self.file = file_name
self.dirpath = dirpath
+ self.locale_dir = locale_dir
def __repr__(self):
return "<TranslatableFile: %s>" % os.sep.join([self.dirpath, self.file])
def __eq__(self, other):
- return self.dirpath == other.dirpath and self.file == other.file
+ return self.path == other.path
def __lt__(self, other):
- if self.dirpath == other.dirpath:
- return self.file < other.file
- return self.dirpath < other.dirpath
+ return self.path < other.path
- def process(self, command, potfile, domain, keep_pot=False):
+ @property
+ def path(self):
+ return os.path.join(self.dirpath, self.file)
+
+ def process(self, command, domain):
"""
- Extract translatable literals from self.file for :param domain:
- creating or updating the :param potfile: POT file.
+ Extract translatable literals from self.file for :param domain:,
+ creating or updating the POT file.
Uses the xgettext GNU gettext utility.
"""
@@ -91,8 +94,6 @@ class TranslatableFile(object):
if status != STATUS_OK:
if is_templatized:
os.unlink(work_file)
- if not keep_pot and os.path.exists(potfile):
- os.unlink(potfile)
raise CommandError(
"errors happened while running xgettext on %s\n%s" %
(self.file, errors))
@@ -100,11 +101,14 @@ class TranslatableFile(object):
# Print warnings
command.stdout.write(errors)
if msgs:
+ # Write/append messages to pot file
+ potfile = os.path.join(self.locale_dir, '%s.pot' % str(domain))
if is_templatized:
old = '#: ' + work_file[2:]
new = '#: ' + orig_file[2:]
msgs = msgs.replace(old, new)
write_pot_file(potfile, msgs)
+
if is_templatized:
os.unlink(work_file)
@@ -232,21 +236,21 @@ class Command(NoArgsCommand):
settings.configure(USE_I18N = True)
self.invoked_for_django = False
+ self.locale_paths = []
+ self.default_locale_path = None
if os.path.isdir(os.path.join('conf', 'locale')):
- localedir = os.path.abspath(os.path.join('conf', 'locale'))
+ self.locale_paths = [os.path.abspath(os.path.join('conf', 'locale'))]
+ self.default_locale_path = self.locale_paths[0]
self.invoked_for_django = True
# Ignoring all contrib apps
self.ignore_patterns += ['contrib/*']
- elif os.path.isdir('locale'):
- localedir = os.path.abspath('locale')
else:
- raise CommandError("This script should be run from the Django Git "
- "tree or your project or app tree. If you did indeed run it "
- "from the Git checkout or your project or application, "
- "maybe you are just missing the conf/locale (in the django "
- "tree) or locale (for project and application) directory? It "
- "is not created automatically, you have to create it by hand "
- "if you want to enable i18n for your project or application.")
+ self.locale_paths.extend(list(settings.LOCALE_PATHS))
+ # Allow to run makemessages inside an app dir
+ if os.path.isdir('locale'):
+ self.locale_paths.append(os.path.abspath('locale'))
+ if self.locale_paths:
+ self.default_locale_path = self.locale_paths[0]
# We require gettext version 0.15 or newer.
output, errors, status = _popen('xgettext --version')
@@ -261,24 +265,25 @@ class Command(NoArgsCommand):
"gettext 0.15 or newer. You are using version %s, please "
"upgrade your gettext toolset." % match.group())
- potfile = self.build_pot_file(localedir)
+ try:
+ potfiles = self.build_potfiles()
- # Build po files for each selected locale
- locales = []
- if locale is not None:
- locales += locale.split(',') if not isinstance(locale, list) else locale
- elif process_all:
- locale_dirs = filter(os.path.isdir, glob.glob('%s/*' % localedir))
- locales = [os.path.basename(l) for l in locale_dirs]
+ # Build po files for each selected locale
+ locales = []
+ if locale is not None:
+ locales = locale.split(',') if not isinstance(locale, list) else locale
+ elif process_all:
+ locale_dirs = filter(os.path.isdir, glob.glob('%s/*' % self.default_locale_path))
+ locales = [os.path.basename(l) for l in locale_dirs]
- try:
for locale in locales:
if self.verbosity > 0:
self.stdout.write("processing locale %s\n" % locale)
- self.write_po_file(potfile, locale)
+ for potfile in potfiles:
+ self.write_po_file(potfile, locale)
finally:
- if not self.keep_pot and os.path.exists(potfile):
- os.unlink(potfile)
+ if not self.keep_pot:
+ self.remove_potfiles()
def build_pot_file(self, localedir):
file_list = self.find_files(".")
@@ -292,9 +297,41 @@ class Command(NoArgsCommand):
f.process(self, potfile, self.domain, self.keep_pot)
return potfile
+ def build_potfiles(self):
+ """Build pot files and apply msguniq to them"""
+ file_list = self.find_files(".")
+ self.remove_potfiles()
+ for f in file_list:
+ f.process(self, self.domain)
+
+ potfiles = []
+ for path in self.locale_paths:
+ potfile = os.path.join(path, '%s.pot' % str(self.domain))
+ if not os.path.exists(potfile):
+ continue
+ msgs, errors, status = _popen('msguniq %s %s --to-code=utf-8 "%s"' %
+ (self.wrap, self.location, potfile))
+ if errors:
+ if status != STATUS_OK:
+ raise CommandError(
+ "errors happened while running msguniq\n%s" % errors)
+ elif self.verbosity > 0:
+ self.stdout.write(errors)
+ with open(potfile, 'w') as fp:
+ fp.write(msgs)
+ potfiles.append(potfile)
+ return potfiles
+
+ def remove_potfiles(self):
+ for path in self.locale_paths:
+ pot_path = os.path.join(path, '%s.pot' % str(self.domain))
+ if os.path.exists(pot_path):
+ os.unlink(pot_path)
+
def find_files(self, root):
"""
- Helper method to get all files in the given root.
+ Helper function to get all files in the given root. Also check that there
+ is a matching locale dir for each file.
"""
def is_ignored(path, ignore_patterns):
@@ -315,12 +352,26 @@ class Command(NoArgsCommand):
dirnames.remove(dirname)
if self.verbosity > 1:
self.stdout.write('ignoring directory %s\n' % dirname)
+ elif dirname == 'locale':
+ dirnames.remove(dirname)
+ self.locale_paths.insert(0, os.path.join(os.path.abspath(dirpath), dirname))
for filename in filenames:
- if is_ignored(os.path.normpath(os.path.join(dirpath, filename)), self.ignore_patterns):
+ file_path = os.path.normpath(os.path.join(dirpath, filename))
+ if is_ignored(file_path, self.ignore_patterns):
if self.verbosity > 1:
self.stdout.write('ignoring file %s in %s\n' % (filename, dirpath))
else:
- all_files.append(TranslatableFile(dirpath, filename))
+ locale_dir = None
+ for path in self.locale_paths:
+ if os.path.abspath(dirpath).startswith(os.path.dirname(path)):
+ locale_dir = path
+ break
+ if not locale_dir:
+ locale_dir = self.default_locale_path
+ if not locale_dir:
+ raise CommandError(
+ "Unable to find a locale path to store translations for file %s" % file_path)
+ all_files.append(TranslatableFile(dirpath, filename, locale_dir))
return sorted(all_files)
def write_po_file(self, potfile, locale):
@@ -328,16 +379,8 @@ class Command(NoArgsCommand):
Creates or updates the PO file for self.domain and :param locale:.
Uses contents of the existing :param potfile:.
- Uses mguniq, msgmerge, and msgattrib GNU gettext utilities.
+ Uses msgmerge, and msgattrib GNU gettext utilities.
"""
- msgs, errors, status = _popen('msguniq %s %s --to-code=utf-8 "%s"' %
- (self.wrap, self.location, potfile))
- if errors:
- if status != STATUS_OK:
- raise CommandError(
- "errors happened while running msguniq\n%s" % errors)
- elif self.verbosity > 0:
- self.stdout.write(errors)
basedir = os.path.join(os.path.dirname(potfile), locale, 'LC_MESSAGES')
if not os.path.isdir(basedir):
@@ -345,8 +388,6 @@ class Command(NoArgsCommand):
pofile = os.path.join(basedir, '%s.po' % str(self.domain))
if os.path.exists(pofile):
- with open(potfile, 'w') as fp:
- fp.write(msgs)
msgs, errors, status = _popen('msgmerge %s %s -q "%s" "%s"' %
(self.wrap, self.location, pofile, potfile))
if errors:
@@ -355,8 +396,10 @@ class Command(NoArgsCommand):
"errors happened while running msgmerge\n%s" % errors)
elif self.verbosity > 0:
self.stdout.write(errors)
- elif not self.invoked_for_django:
- msgs = self.copy_plural_forms(msgs, locale)
+ else:
+ msgs = open(potfile, 'r').read()
+ if not self.invoked_for_django:
+ msgs = self.copy_plural_forms(msgs, locale)
msgs = msgs.replace(
"#. #-#-#-#-# %s.pot (PACKAGE VERSION) #-#-#-#-#\n" % self.domain, "")
with open(pofile, 'w') as fp: