1# -*- coding: utf-8 -*- 2import os 3from distutils.dist import Distribution 4from subprocess import call 5 6from django.core.management.base import LabelCommand, CommandError 7from django.conf import settings 8 9 10__all__ = ['Command'] 11 12 13class Command(LabelCommand): 14 15 args = '[makemessages] [compilemessages]' 16 17 def add_arguments(self, parser): 18 super(Command, self).add_arguments(parser) 19 parser.add_argument( 20 '--locale', '-l', default=[], dest='locale', action='append', 21 help=( 22 'Creates or updates the message files for the given locale(s)' 23 ' (e.g pt_BR). Can be used multiple times.' 24 ), 25 ) 26 parser.add_argument( 27 '--domain', '-d', default='django', dest='domain', 28 help='The domain of the message files (default: "django").', 29 ), 30 parser.add_argument( 31 '--mapping-file', '-F', default=None, dest='mapping_file', 32 help='Mapping file', 33 ) 34 35 def handle_label(self, command, **options): 36 if command not in ('makemessages', 'compilemessages'): 37 raise CommandError( 38 "You must either apply 'makemessages' or 'compilemessages'" 39 ) 40 41 if command == 'makemessages': 42 self.handle_makemessages(**options) 43 if command == 'compilemessages': 44 self.handle_compilemessages(**options) 45 46 def handle_makemessages(self, **options): 47 locale_paths = list(settings.LOCALE_PATHS) 48 domain = options.pop('domain') 49 locales = options.pop('locale') 50 51 # support for mapping file specification via setup.cfg 52 # TODO: Try to support all possible options. 53 distribution = Distribution() 54 distribution.parse_config_files(distribution.find_config_files()) 55 56 mapping_file = options.pop('mapping_file', None) 57 has_extract = 'extract_messages' in distribution.command_options 58 if mapping_file is None and has_extract: 59 opts = distribution.command_options['extract_messages'] 60 try: 61 mapping_file = opts['mapping_file'][1] 62 except (IndexError, KeyError): 63 mapping_file = None 64 65 for path in locale_paths: 66 potfile = os.path.join(path, '%s.pot' % domain) 67 68 if not os.path.exists(path): 69 os.makedirs(path) 70 71 if not os.path.exists(potfile): 72 with open(potfile, 'wb') as fobj: 73 fobj.write(b'') 74 75 cmd = ['pybabel', 'extract', '-o', potfile] 76 77 if mapping_file is not None: 78 cmd.extend(['-F', mapping_file]) 79 80 cmd.append(os.path.dirname(os.path.relpath(path))) 81 82 call(cmd) 83 84 for locale in locales: 85 pofile = os.path.join( 86 os.path.dirname(potfile), 87 locale, 88 'LC_MESSAGES', 89 '%s.po' % domain) 90 91 if not os.path.isdir(os.path.dirname(pofile)): 92 os.makedirs(os.path.dirname(pofile)) 93 94 if not os.path.exists(pofile): 95 with open(pofile, 'wb') as fobj: 96 fobj.write(b'') 97 98 cmd = ['pybabel', 'update', '-D', domain, 99 '-i', potfile, 100 '-d', os.path.relpath(path), 101 '-l', locale] 102 call(cmd) 103 104 def handle_compilemessages(self, **options): 105 locale_paths = list(settings.LOCALE_PATHS) 106 domain = options.pop('domain') 107 locales = options.pop('locale') 108 109 for path in locale_paths: 110 for locale in locales: 111 po_file = os.path.join( 112 path, locale, 'LC_MESSAGES', domain + '.po' 113 ) 114 if os.path.exists(po_file): 115 cmd = ['pybabel', 'compile', '-D', domain, 116 '-d', path, '-l', locale] 117 call(cmd) 118