Ticket #17181: multiple_locales_and_domains.diff

File multiple_locales_and_domains.diff, 20.1 KB (added by aminland, 3 years ago)
  • django/core/management/commands/compilemessages.py

    diff --git a/django/core/management/commands/compilemessages.py b/django/core/management/commands/compilemessages.py
    index b5eaeb1..17ddd17 100644
    a b def compile_messages(stderr, locale=None): 
    2424        raise CommandError("This script should be run from the Django SVN tree or your project or app tree, or with the settings module specified.")
    2525
    2626    for basedir in basedirs:
     27        dirs = [basedir]
    2728        if locale:
    28             basedir = os.path.join(basedir, locale, 'LC_MESSAGES')
    29         for dirpath, dirnames, filenames in os.walk(basedir):
    30             for f in filenames:
    31                 if f.endswith('.po'):
    32                     stderr.write('processing file %s in %s\n' % (f, dirpath))
    33                     fn = os.path.join(dirpath, f)
    34                     if has_bom(fn):
    35                         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)
    36                     pf = os.path.splitext(fn)[0]
    37                     # Store the names of the .mo and .po files in an environment
    38                     # variable, rather than doing a string replacement into the
    39                     # command, so that we can take advantage of shell quoting, to
    40                     # quote any malicious characters/escaping.
    41                     # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html
    42                     os.environ['djangocompilemo'] = pf + '.mo'
    43                     os.environ['djangocompilepo'] = pf + '.po'
    44                     if sys.platform == 'win32': # Different shell-variable syntax
    45                         cmd = 'msgfmt --check-format -o "%djangocompilemo%" "%djangocompilepo%"'
    46                     else:
    47                         cmd = 'msgfmt --check-format -o "$djangocompilemo" "$djangocompilepo"'
    48                     os.system(cmd)
     29            dirs = [os.path.join(basedir, l, 'LC_MESSAGES') for l in (locale if isinstance(locale, list) else [locale])]
     30           
     31        for dir in dirs:
     32            for dirpath, dirnames, filenames in os.walk(dir):
     33                for f in filenames:
     34                    if f.endswith('.po'):
     35                        stderr.write('processing file %s in %s\n' % (f, dirpath))
     36                        fn = os.path.join(dirpath, f)
     37                        if has_bom(fn):
     38                            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)
     39                        pf = os.path.splitext(fn)[0]
     40                        # Store the names of the .mo and .po files in an environment
     41                        # variable, rather than doing a string replacement into the
     42                        # command, so that we can take advantage of shell quoting, to
     43                        # quote any malicious characters/escaping.
     44                        # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html
     45                        os.environ['djangocompilemo'] = pf + '.mo'
     46                        os.environ['djangocompilepo'] = pf + '.po'
     47                        if sys.platform == 'win32': # Different shell-variable syntax
     48                            cmd = 'msgfmt --check-format -o "%djangocompilemo%" "%djangocompilepo%"'
     49                        else:
     50                            cmd = 'msgfmt --check-format -o "$djangocompilemo" "$djangocompilepo"'
     51                        os.system(cmd)
    4952
    5053
    5154class Command(BaseCommand):
    5255    option_list = BaseCommand.option_list + (
    53         make_option('--locale', '-l', dest='locale',
    54             help='The locale to process. Default is to process all.'),
     56        make_option('--locale', '-l', dest='locale', action="append",
     57            help='A locale to process. Default is to process all.'),
    5558    )
    5659    help = 'Compiles .po files to .mo files for use with builtin gettext support.'
    5760
  • django/core/management/commands/makemessages.py

    diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
    old mode 100755
    new mode 100644
    index 9d0dc68..9761bb3
    a b def make_messages(locale=None, domain='django', verbosity='1', all=False, 
    141141    else:
    142142        raise CommandError("This script should be run from the Django SVN tree or your project or app tree. If you did indeed run it from the SVN 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.")
    143143
    144     if domain not in ('django', 'djangojs'):
     144    if domain is None:
     145            domains = ['django']
     146    else:
     147        domains = [domain] if not isinstance(domain, list) else domain
     148
     149    if any(d not in ('django', 'djangojs') for d in domains):
    145150        raise CommandError("currently makemessages only supports domains 'django' and 'djangojs'")
    146151
    147     if (locale is None and not all) or domain is None:
     152    if (locale is None and not all) or not domains:
    148153        message = "Type '%s help %s' for usage information." % (os.path.basename(sys.argv[0]), sys.argv[1])
    149154        raise CommandError(message)
    150155
    def make_messages(locale=None, domain='django', verbosity='1', all=False, 
    158163
    159164    languages = []
    160165    if locale is not None:
    161         languages.append(locale)
     166        languages += [locale] if not isinstance(locale, list) else locale
    162167    elif all:
    163168        locale_dirs = filter(os.path.isdir, glob.glob('%s/*' % localedir))
    164169        languages = [os.path.basename(l) for l in locale_dirs]
    165170
    166171    wrap = no_wrap and '--no-wrap' or ''
    167 
    168     for locale in languages:
    169         if verbosity > 0:
    170             print "processing language", locale
    171         basedir = os.path.join(localedir, locale, 'LC_MESSAGES')
    172         if not os.path.isdir(basedir):
    173             os.makedirs(basedir)
    174 
    175         pofile = os.path.join(basedir, '%s.po' % domain)
    176         potfile = os.path.join(basedir, '%s.pot' % domain)
    177 
    178         if os.path.exists(potfile):
    179             os.unlink(potfile)
    180 
    181         for dirpath, file in find_files(".", ignore_patterns, verbosity, symlinks=symlinks):
    182             file_base, file_ext = os.path.splitext(file)
    183             if domain == 'djangojs' and file_ext in extensions:
    184                 if verbosity > 1:
    185                     sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
    186                 src = open(os.path.join(dirpath, file), "rU").read()
    187                 src = pythonize_re.sub('\n#', src)
    188                 thefile = '%s.py' % file
    189                 f = open(os.path.join(dirpath, thefile), "w")
    190                 try:
    191                     f.write(src)
    192                 finally:
    193                     f.close()
    194                 cmd = (
    195                     'xgettext -d %s -L Perl %s --keyword=gettext_noop '
    196                     '--keyword=gettext_lazy --keyword=ngettext_lazy:1,2 '
    197                     '--keyword=pgettext:1c,2 --keyword=npgettext:1c,2,3 '
    198                     '--from-code UTF-8 --add-comments=Translators -o - "%s"' % (
    199                         domain, wrap, os.path.join(dirpath, thefile)
    200                     )
    201                 )
    202                 msgs, errors = _popen(cmd)
    203                 if errors:
    204                     os.unlink(os.path.join(dirpath, thefile))
    205                     if os.path.exists(potfile):
    206                         os.unlink(potfile)
    207                     raise CommandError(
    208                         "errors happened while running xgettext on %s\n%s" %
    209                         (file, errors))
    210                 if msgs:
    211                     old = '#: ' + os.path.join(dirpath, thefile)[2:]
    212                     new = '#: ' + os.path.join(dirpath, file)[2:]
    213                     msgs = msgs.replace(old, new)
    214                     if os.path.exists(potfile):
    215                         # Strip the header
    216                         msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
    217                     else:
    218                         msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
    219                     f = open(potfile, 'ab')
    220                     try:
    221                         f.write(msgs)
    222                     finally:
    223                         f.close()
    224                 os.unlink(os.path.join(dirpath, thefile))
    225             elif domain == 'django' and (file_ext == '.py' or file_ext in extensions):
    226                 thefile = file
    227                 orig_file = os.path.join(dirpath, file)
    228                 if file_ext in extensions:
    229                     src = open(orig_file, "rU").read()
     172    for domain in domains:
     173        for locale in languages:
     174            if verbosity > 0:
     175                print "processing domain %s for language %s" % (domain, locale)
     176            basedir = os.path.join(localedir, locale, 'LC_MESSAGES')
     177            if not os.path.isdir(basedir):
     178                os.makedirs(basedir)
     179   
     180            pofile = os.path.join(basedir, '%s.po' % domain)
     181            potfile = os.path.join(basedir, '%s.pot' % domain)
     182   
     183            if os.path.exists(potfile):
     184                os.unlink(potfile)
     185   
     186            for dirpath, file in find_files(".", ignore_patterns, verbosity, symlinks=symlinks):
     187                file_base, file_ext = os.path.splitext(file)
     188                if domain == 'djangojs' and file_ext in extensions:
     189                    if verbosity > 1:
     190                        sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
     191                    src = open(os.path.join(dirpath, file), "rU").read()
     192                    src = pythonize_re.sub('\n#', src)
    230193                    thefile = '%s.py' % file
    231194                    f = open(os.path.join(dirpath, thefile), "w")
    232195                    try:
    233                         f.write(templatize(src, orig_file[2:]))
     196                        f.write(src)
    234197                    finally:
    235198                        f.close()
    236                 if verbosity > 1:
    237                     sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
    238                 cmd = (
    239                     'xgettext -d %s -L Python %s --keyword=gettext_noop '
    240                     '--keyword=gettext_lazy --keyword=__ --keyword=ngettext_lazy:1,2 '
    241                     '--keyword=ugettext_noop --keyword=ugettext_lazy '
    242                     '--keyword=ungettext_lazy:1,2 --keyword=pgettext:1c,2 '
    243                     '--keyword=npgettext:1c,2,3 --keyword=pgettext_lazy:1c,2 '
    244                     '--keyword=npgettext_lazy:1c,2,3 --from-code UTF-8 '
    245                     '--add-comments=Translators -o - "%s"' % (
    246                         domain, wrap, os.path.join(dirpath, thefile))
    247                 )
    248                 msgs, errors = _popen(cmd)
    249                 if errors:
    250                     if thefile != file:
     199                    cmd = (
     200                        'xgettext -d %s -L Perl %s --keyword=gettext_noop '
     201                        '--keyword=gettext_lazy --keyword=ngettext_lazy:1,2 '
     202                        '--keyword=pgettext:1c,2 --keyword=npgettext:1c,2,3 '
     203                        '--from-code UTF-8 --add-comments=Translators -o - "%s"' % (
     204                            domain, wrap, os.path.join(dirpath, thefile)
     205                        )
     206                    )
     207                    msgs, errors = _popen(cmd)
     208                    if errors:
    251209                        os.unlink(os.path.join(dirpath, thefile))
    252                     if os.path.exists(potfile):
    253                         os.unlink(potfile)
    254                     raise CommandError(
    255                         "errors happened while running xgettext on %s\n%s" %
    256                         (file, errors))
    257                 if msgs:
    258                     if thefile != file:
     210                        if os.path.exists(potfile):
     211                            os.unlink(potfile)
     212                        raise CommandError(
     213                            "errors happened while running xgettext on %s\n%s" %
     214                            (file, errors))
     215                    if msgs:
    259216                        old = '#: ' + os.path.join(dirpath, thefile)[2:]
    260                         new = '#: ' + orig_file[2:]
     217                        new = '#: ' + os.path.join(dirpath, file)[2:]
    261218                        msgs = msgs.replace(old, new)
    262                     if os.path.exists(potfile):
    263                         # Strip the header
    264                         msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
    265                     else:
    266                         msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
    267                     f = open(potfile, 'ab')
     219                        if os.path.exists(potfile):
     220                            # Strip the header
     221                            msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
     222                        else:
     223                            msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
     224                        f = open(potfile, 'ab')
     225                        try:
     226                            f.write(msgs)
     227                        finally:
     228                            f.close()
     229                    os.unlink(os.path.join(dirpath, thefile))
     230                elif domain == 'django' and (file_ext == '.py' or file_ext in extensions):
     231                    thefile = file
     232                    orig_file = os.path.join(dirpath, file)
     233                    if file_ext in extensions:
     234                        src = open(orig_file, "rU").read()
     235                        thefile = '%s.py' % file
     236                        f = open(os.path.join(dirpath, thefile), "w")
     237                        try:
     238                            f.write(templatize(src, orig_file[2:]))
     239                        finally:
     240                            f.close()
     241                    if verbosity > 1:
     242                        sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
     243                    cmd = (
     244                        'xgettext -d %s -L Python %s --keyword=gettext_noop '
     245                        '--keyword=gettext_lazy --keyword=__ --keyword=ngettext_lazy:1,2 '
     246                        '--keyword=ugettext_noop --keyword=ugettext_lazy '
     247                        '--keyword=ungettext_lazy:1,2 --keyword=pgettext:1c,2 '
     248                        '--keyword=npgettext:1c,2,3 --keyword=pgettext_lazy:1c,2 '
     249                        '--keyword=npgettext_lazy:1c,2,3 --from-code UTF-8 '
     250                        '--add-comments=Translators -o - "%s"' % (
     251                            domain, wrap, os.path.join(dirpath, thefile))
     252                    )
     253                    msgs, errors = _popen(cmd)
     254                    if errors:
     255                        if thefile != file:
     256                            os.unlink(os.path.join(dirpath, thefile))
     257                        if os.path.exists(potfile):
     258                            os.unlink(potfile)
     259                        raise CommandError(
     260                            "errors happened while running xgettext on %s\n%s" %
     261                            (file, errors))
     262                    if msgs:
     263                        if thefile != file:
     264                            old = '#: ' + os.path.join(dirpath, thefile)[2:]
     265                            new = '#: ' + orig_file[2:]
     266                            msgs = msgs.replace(old, new)
     267                        if os.path.exists(potfile):
     268                            # Strip the header
     269                            msgs = '\n'.join(dropwhile(len, msgs.split('\n')))
     270                        else:
     271                            msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8')
     272                        f = open(potfile, 'ab')
     273                        try:
     274                            f.write(msgs)
     275                        finally:
     276                            f.close()
     277                    if thefile != file:
     278                        os.unlink(os.path.join(dirpath, thefile))
     279   
     280            if os.path.exists(potfile):
     281                msgs, errors = _popen('msguniq %s --to-code=utf-8 "%s"' %
     282                                      (wrap, potfile))
     283                if errors:
     284                    os.unlink(potfile)
     285                    raise CommandError(
     286                        "errors happened while running msguniq\n%s" % errors)
     287                if os.path.exists(pofile):
     288                    f = open(potfile, 'w')
    268289                    try:
    269290                        f.write(msgs)
    270291                    finally:
    271292                        f.close()
    272                 if thefile != file:
    273                     os.unlink(os.path.join(dirpath, thefile))
    274 
    275         if os.path.exists(potfile):
    276             msgs, errors = _popen('msguniq %s --to-code=utf-8 "%s"' %
    277                                   (wrap, potfile))
    278             if errors:
    279                 os.unlink(potfile)
    280                 raise CommandError(
    281                     "errors happened while running msguniq\n%s" % errors)
    282             if os.path.exists(pofile):
    283                 f = open(potfile, 'w')
     293                    msgs, errors = _popen('msgmerge %s -q "%s" "%s"' %
     294                                          (wrap, pofile, potfile))
     295                    if errors:
     296                        os.unlink(potfile)
     297                        raise CommandError(
     298                            "errors happened while running msgmerge\n%s" % errors)
     299                elif not invoked_for_django:
     300                    msgs = copy_plural_forms(msgs, locale, domain, verbosity)
     301                msgs = msgs.replace(
     302                    "#. #-#-#-#-#  %s.pot (PACKAGE VERSION)  #-#-#-#-#\n" % domain, "")
     303                f = open(pofile, 'wb')
    284304                try:
    285305                    f.write(msgs)
    286306                finally:
    287307                    f.close()
    288                 msgs, errors = _popen('msgmerge %s -q "%s" "%s"' %
    289                                       (wrap, pofile, potfile))
    290                 if errors:
    291                     os.unlink(potfile)
    292                     raise CommandError(
    293                         "errors happened while running msgmerge\n%s" % errors)
    294             elif not invoked_for_django:
    295                 msgs = copy_plural_forms(msgs, locale, domain, verbosity)
    296             msgs = msgs.replace(
    297                 "#. #-#-#-#-#  %s.pot (PACKAGE VERSION)  #-#-#-#-#\n" % domain, "")
    298             f = open(pofile, 'wb')
    299             try:
    300                 f.write(msgs)
    301             finally:
    302                 f.close()
    303             os.unlink(potfile)
    304             if no_obsolete:
    305                 msgs, errors = _popen('msgattrib %s -o "%s" --no-obsolete "%s"' %
    306                                       (wrap, pofile, pofile))
    307                 if errors:
    308                     raise CommandError(
    309                         "errors happened while running msgattrib\n%s" % errors)
     308                os.unlink(potfile)
     309                if no_obsolete:
     310                    msgs, errors = _popen('msgattrib %s -o "%s" --no-obsolete "%s"' %
     311                                          (wrap, pofile, pofile))
     312                    if errors:
     313                        raise CommandError(
     314                            "errors happened while running msgattrib\n%s" % errors)
    310315
    311316
    312317class Command(NoArgsCommand):
    313318    option_list = NoArgsCommand.option_list + (
    314         make_option('--locale', '-l', default=None, dest='locale',
     319        make_option('--locale', '-l', default=None, dest='locale', action="append",
    315320            help='Creates or updates the message files for the given locale (e.g. pt_BR).'),
    316         make_option('--domain', '-d', default='django', dest='domain',
     321        make_option('--domain', '-d', default=None, dest='domain', action="append",
    317322            help='The domain of the message files (default: "django").'),
    318323        make_option('--all', '-a', action='store_true', dest='all',
    319324            default=False, help='Updates the message files for all existing locales.'),
Back to Top