| Home | Trees | Indices | Help |
|
|---|
|
|
1 # test-file: test_command_i18n.py 2 3 """Command-line user interface for i18n administration.""" 4 5 import re 6 import glob 7 import os 8 import os.path 9 import atexit 10 import optparse 11 import tempfile 12 13 try: 14 # try the python 2.5 way 15 from xml.etree.cElementTree import ElementTree, XML 16 except ImportError: 17 # then try the python 2.4 way 18 from elementtree.ElementTree import ElementTree 19 20 import formencode 21 import turbogears 22 import turbogears.i18n 23 from turbogears.toolbox.admi18n import pygettext, msgfmt, catalog 24 from turbogears.toolbox.admi18n.catalog import quote, normalize 25 from turbogears.command.base import silent_os_remove 26 from turbogears.util import get_model, load_project_config, get_package_name 27 from pkg_resources import resource_filename 28 import kid 29 3234 if os.path.exists(dest): 35 os.remove(dest) 36 data = open(src, 'rb').read() 37 open(dest, 'wb').write(data)38 39 _str_literal = r"""(?:'((?:[^']|\\')*)'|"((?:[^"]|\\")*)")""" 40 _py_i18n_re = re.compile(r"\b_\s*\(\s*[uU]?[rR]?%s\s*\)" % _str_literal) 41 _js_i18n_re = re.compile(r"\b_\s*\(\s*%s\s*\)" % _str_literal) 4244 "Manages i18n data via command-line interface." 45 46 desc = "Manage i18n data" 47 need_project = True 48 config = True 49 50 name = None 51 package = None 52 __version__ = "0.2" 53 __author__ = "Max Ischenko, U{http://maxischenko.in.ua}" 54 __email__ = "ischenko@gmail.com" 55 __copyright__ = "Copyright 2005-2006 Max Ischenko" 56 __license__ = "MIT" 5759 # I don't have the slightest idea 60 # why this isn't working with the config=True from above !?!! 61 self.config = True 62 63 parser = optparse.OptionParser(usage=""" 64 %prog [options] <command> 65 66 Available commands: 67 add <locale> Creates a message catalog for specified locale 68 collect Scan source files to gather translatable strings in a .pot file 69 merge Sync message catalog in different languages with .pot file 70 compile Compile message catalog (.po -> .mo) 71 create_js_messages Create message catalogs for JS usage 72 clean Delete backups and compiled files 73 """, version="%prog " + self.__version__) 74 parser.add_option("-f", "--force", default=False, 75 action="store_true", dest="force_ops", 76 help="Force potentially damaging actions") 77 parser.add_option("-a", "--ascii", default=False, 78 action="store_true", dest="ascii_output", 79 help="Escape non-ascii characters") 80 parser.add_option("-K", "--no-kid-support", default=True, 81 action="store_false", dest="kid_support", 82 help="Do not extract messages from Kid templates") 83 parser.add_option("", "--loose-kid-support", 84 action="store_true", dest="loose_kid_support", 85 help="Extract ALL messages from Kid templates" \ 86 " (this is default)") 87 parser.add_option("", "--strict-kid-support", 88 action="store_false", dest="loose_kid_support", 89 help="Extract only messages marked with lang attribute " \ 90 "from Kid templates") 91 parser.add_option("", "--src-dir", default=None, 92 action="store", dest="source_dir", 93 help="Directory that contains source files") 94 parser.add_option("", "--no-js-support", default=True, 95 action="store_false", dest="js_support", 96 help="Extract messages from js-files.") 97 parser.add_option("", "--js-base-dir", 98 action="store", dest="js_base_dir", 99 default="static/javascript", 100 help="Base directory of javascript files for generated message-files.") 101 parser.set_defaults(loose_kid_support=True, js_support=True) 102 self.parser = parser103105 """Chooses the config file, trying to guess whether this is a 106 development or installed project.""" 107 108 # defaults 109 self.locale_dir = 'locales' 110 self.domain = 'messages' 111 112 # check whether user specified custom settings 113 if self.config: 114 load_project_config() 115 116 if turbogears.config.get("i18n.locale_dir"): 117 self.locale_dir = turbogears.config.get("i18n.locale_dir") 118 print 'Use %s as a locale directory' % self.locale_dir 119 if turbogears.config.get('i18n.domain'): 120 self.domain = turbogears.config.get("i18n.domain") 121 print 'Use %s as a message domain' % self.domain 122 123 if os.path.exists(self.locale_dir) and \ 124 not os.path.isdir(self.locale_dir): 125 raise ProgramError, \ 126 ('%s is not a directory' % self.locale_dir) 127 128 if not os.path.exists(self.locale_dir): 129 os.makedirs(self.locale_dir)130132 return self.parser.parse_args()133135 self.load_project_config() 136 (options, args) = self.parse_args() 137 if not args: 138 self.parser.error("No command specified") 139 self.options = options 140 command, args = args[0], args[1:] 141 if 'collect' == command: 142 self.scan_source_files() 143 elif 'add' == command: 144 self.add_languages(args) 145 elif 'compile' == command: 146 self.compile_message_catalogs() 147 elif 'merge' == command: 148 self.merge_message_catalogs() 149 elif 'clean' == command: 150 self.clean_generated_files() 151 elif 'create_js_messages' == command: 152 self.create_js_messages() 153 else: 154 self.parser.error("Command not recognized")155157 self.load_project_config() 158 languages = [] 159 # we assume the the structure of messages is always 160 # <self.locale_dir>/<lang>/LC_MESSAGES ... 161 # to extract the languages known to the app 162 locale_dir_prefix = self.locale_dir.split(os.sep) 163 for fname in self.list_message_catalogs(): 164 languages.append(fname.split(os.sep)[len(locale_dir_prefix):][0]) 165 import turbogears.i18n.utils as utils 166 srcdir = self.options.source_dir or get_package_name() 167 def list_js_files(): 168 for root, dirs, files in os.walk(srcdir): 169 if os.path.basename(root).lower() in ('cvs', '.svn'): 170 continue 171 for fname in files: 172 name,ext = os.path.splitext(fname) 173 srcfile = os.path.join