diff options
| author | Ramiro Morales <cramm0@gmail.com> | 2013-01-25 13:23:33 -0300 |
|---|---|---|
| committer | Ramiro Morales <cramm0@gmail.com> | 2013-01-25 13:23:33 -0300 |
| commit | 2babab0bb351ff7a13fd23795f5e926a9bf95d22 (patch) | |
| tree | dcdffc1d0964d88d71980b7bd07e4ced495e9300 /django | |
| parent | b9c8bbf3726a1956be1db70ffd3bef04a2e5311a (diff) | |
Patch by Claude for #16084.
Diffstat (limited to 'django')
| -rw-r--r-- | django/core/management/commands/makemessages.py | 139 |
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: |
