| 1 : |
aolivares |
3 |
#! /usr/bin/env python
|
| 2 : |
|
|
# -*- coding: iso-8859-1 -*-
|
| 3 : |
|
|
#
|
| 4 : |
|
|
# PYTHON MODULE: MKI18N.PY
|
| 5 : |
|
|
# =========
|
| 6 : |
|
|
#
|
| 7 : |
|
|
# Abstract: Make Internationalization (i18n) files for an application.
|
| 8 : |
|
|
# Copyright Pierre Rouleau. 2003. Released to public domain.
|
| 9 : |
|
|
# Last update: Saturday, November 8, 2003. @ 15:55:18.
|
| 10 : |
|
|
# File: ROUP2003N01::C:/dev/python/mki18n.py
|
| 11 : |
|
|
#
|
| 12 : |
|
|
# Update history:
|
| 13 : |
|
|
# - File updated: Thursday, January 22, 2008 by Cody Precord
|
| 14 : |
|
|
# - File created: Saturday, June 7, 2003. by Pierre Rouleau
|
| 15 : |
|
|
# - 01/22/08 CJP : Allow specifying where the po files can be output to and
|
| 16 : |
|
|
# where to find them when compiling mo files.
|
| 17 : |
|
|
# - 07/12/07 CJP : Make it work with current wx code and clean up code
|
| 18 : |
|
|
# - 10/06/03 rcs : RCS Revision 1.1 2003/06/10 10:06:12 PRouleau
|
| 19 : |
|
|
# - 10/06/03 rcs : RCS Initial revision
|
| 20 : |
|
|
# - 23/08/03 rcs : RCS Revision 1.2 2003/06/10 10:54:27 PRouleau
|
| 21 : |
|
|
# - 23/08/03 P.R.: [code:fix] : The strings encoded in this file are encode
|
| 22 : |
|
|
# in iso-8859-1 format. Added the encoding
|
| 23 : |
|
|
# notification to Python to comply with Python's 2.3 PEP 263.
|
| 24 : |
|
|
# - 23/08/03 P.R.: [feature:new] : Added the '-e' switch which is used to
|
| 25 : |
|
|
# force the creation of the empty English
|
| 26 : |
|
|
# .mo file.
|
| 27 : |
|
|
# - 22/10/03 P.R.: [code] : incorporated utility functions in here
|
| 28 : |
|
|
# to make script self sufficient.
|
| 29 : |
|
|
# - 05/11/03 rcs : RCS Revision 1.4 2003/10/22 06:39:31 PRouleau
|
| 30 : |
|
|
# - 05/11/03 P.R.: [code:fix] : included the unixpath() in this file.
|
| 31 : |
|
|
# - 08/11/03 rcs : RCS Revision 1.5 2003/11/05 19:40:04 PRouleau
|
| 32 : |
|
|
#
|
| 33 : |
|
|
# RCS $Log: $
|
| 34 : |
|
|
#
|
| 35 : |
|
|
#
|
| 36 : |
|
|
# -----------------------------------------------------------------------------
|
| 37 : |
|
|
"""
|
| 38 : |
|
|
mki18n allows you to internationalize your software. You can use it to
|
| 39 : |
|
|
create the GNU .po files (Portable Object) and the compiled .mo files
|
| 40 : |
|
|
(Machine Object).
|
| 41 : |
|
|
|
| 42 : |
|
|
mki18n module can be used from the command line or from within a script (see
|
| 43 : |
|
|
the Usage at the end of this page).
|
| 44 : |
|
|
|
| 45 : |
|
|
Table of Contents
|
| 46 : |
|
|
-----------------
|
| 47 : |
|
|
makePO() -- Build the Portable Object file for the application --
|
| 48 : |
|
|
catPO() -- Concatenate one or several PO files with the application
|
| 49 : |
|
|
domain files.
|
| 50 : |
|
|
makeMO() -- Compile the Portable Object files into the Machine Object
|
| 51 : |
|
|
stored in the right location.
|
| 52 : |
|
|
printUsage -- Displays how to use this script from the command line --
|
| 53 : |
|
|
Scriptexecution -- Runs when invoked from the command line --
|
| 54 : |
|
|
|
| 55 : |
|
|
NOTE: this module uses GNU gettext utilities.
|
| 56 : |
|
|
|
| 57 : |
|
|
You can get the gettext tools from the following sites:
|
| 58 : |
|
|
|
| 59 : |
|
|
- `GNU FTP site for gettetx`_ where several versions
|
| 60 : |
|
|
(0.10.40, 0.11.2, 0.11.5 and 0.12.1) are available.
|
| 61 : |
|
|
Note that you need to use `GNU libiconv`_ to use this. Get it from the
|
| 62 : |
|
|
`GNU
|
| 63 : |
|
|
libiconv ftp site`_ and get version 1.9.1 or later. Get the Windows .ZIP
|
| 64 : |
|
|
files and install the packages inside c:/gnu. All binaries will be stored
|
| 65 : |
|
|
inside c:/gnu/bin. Just put c:/gnu/bin inside your PATH. You will need
|
| 66 : |
|
|
the following files:
|
| 67 : |
|
|
|
| 68 : |
|
|
- `gettext-runtime-0.12.1.bin.woe32.zip`_
|
| 69 : |
|
|
- `gettext-tools-0.12.1.bin.woe32.zip`_
|
| 70 : |
|
|
- `libiconv-1.9.1.bin.woe32.zip`_
|
| 71 : |
|
|
|
| 72 : |
|
|
|
| 73 : |
|
|
.. _GNU libiconv: http://www.gnu.org/software/libiconv/
|
| 74 : |
|
|
.. _GNU libiconv ftp site: http://www.ibiblio.org/pub/gnu/libiconv/
|
| 75 : |
|
|
.. _gettext-runtime-0.12.1.bin.woe32.zip:
|
| 76 : |
|
|
ftp://ftp.gnu.org/gnu/gettext/gettext-runtime-0.12.1.bin.woe32.zip
|
| 77 : |
|
|
.. _gettext-tools-0.12.1.bin.woe32.zip:
|
| 78 : |
|
|
.. ftp://ftp.gnu.org/gnu/gettext/gettext-tools-0.12.1.bin.woe32.zip
|
| 79 : |
|
|
.. _libiconv-1.9.1.bin.woe32.zip:
|
| 80 : |
|
|
http://www.ibiblio.org/pub/gnu/libiconv/libiconv-1.9.1.bin.woe32.zip
|
| 81 : |
|
|
|
| 82 : |
|
|
"""
|
| 83 : |
|
|
# -----------------------------------------------------------------------------
|
| 84 : |
|
|
# Module Import
|
| 85 : |
|
|
# -------------
|
| 86 : |
|
|
#
|
| 87 : |
|
|
import os
|
| 88 : |
|
|
import sys
|
| 89 : |
|
|
import wx
|
| 90 : |
|
|
# -----------------------------------------------------------------------------
|
| 91 : |
|
|
# Global variables
|
| 92 : |
|
|
# ----------------
|
| 93 : |
|
|
#
|
| 94 : |
|
|
|
| 95 : |
|
|
__author__ = "Pierre Rouleau"
|
| 96 : |
|
|
__version__ = "$Revision: 543 $"
|
| 97 : |
|
|
|
| 98 : |
|
|
# -----------------------------------------------------------------------------
|
| 99 : |
|
|
|
| 100 : |
|
|
def getlanguageDict():
|
| 101 : |
|
|
"""Get a dictionary of the available languages from wx"""
|
| 102 : |
|
|
lang_dict = {}
|
| 103 : |
|
|
app = wx.App()
|
| 104 : |
|
|
for lang in [x for x in dir(wx) if x.startswith("LANGUAGE")]:
|
| 105 : |
|
|
i = wx.Locale(wx.LANGUAGE_DEFAULT).GetLanguageInfo(getattr(wx, lang))
|
| 106 : |
|
|
if i:
|
| 107 : |
|
|
lang_dict[i.CanonicalName] = i.Description
|
| 108 : |
|
|
return lang_dict
|
| 109 : |
|
|
|
| 110 : |
|
|
# -----------------------------------------------------------------------------
|
| 111 : |
|
|
# m a k e P O ( ) -- Build the Portable Object file for the application --
|
| 112 : |
|
|
# ^^^^^^^^^^^^^^^
|
| 113 : |
|
|
#
|
| 114 : |
|
|
def makePO(app_dir, app_domain=None, verbose=0, src='app.fil', out='messages', podir=''):
|
| 115 : |
|
|
"""Build the Portable Object Template file for the application.
|
| 116 : |
|
|
|
| 117 : |
|
|
makePO builds the .pot file for the application stored inside
|
| 118 : |
|
|
a specified directory by running xgettext for all application source
|
| 119 : |
|
|
files. It finds the name of all files by looking for a file called
|
| 120 : |
|
|
'app.fil'.
|
| 121 : |
|
|
If this file does not exists, makePo raises an IOError exception.
|
| 122 : |
|
|
By default the application domain (the application
|
| 123 : |
|
|
name) is the same as the directory name but it can be overridden by the
|
| 124 : |
|
|
'applicationDomain' argument.
|
| 125 : |
|
|
|
| 126 : |
|
|
makePO always creates a new file called messages.pot. If it finds files
|
| 127 : |
|
|
of the form app_xx.po where 'app' is the application name and 'xx' is one
|
| 128 : |
|
|
of the ISO 639 two-letter language codes, makePO resynchronizes those
|
| 129 : |
|
|
files with the latest extracted strings (now contained in messages.pot).
|
| 130 : |
|
|
This process updates all line location number in the language-specific
|
| 131 : |
|
|
.po files and may also create new entries for translation (or comment out
|
| 132 : |
|
|
some). The .po file is not changed, instead a new file is created with
|
| 133 : |
|
|
the .new extension appended to the name of the .po file.
|
| 134 : |
|
|
|
| 135 : |
|
|
By default the function does not display what it is doing. Set the
|
| 136 : |
|
|
verbose argument to 1 to force it to print its commands.
|
| 137 : |
|
|
|
| 138 : |
|
|
"""
|
| 139 : |
|
|
if app_domain is None:
|
| 140 : |
|
|
app_name = fileBaseOf(app_dir, withPath=0)
|
| 141 : |
|
|
else:
|
| 142 : |
|
|
app_name = app_domain
|
| 143 : |
|
|
|
| 144 : |
|
|
curr_dir = os.getcwd()
|
| 145 : |
|
|
os.chdir(app_dir)
|
| 146 : |
|
|
if not os.path.exists(src):
|
| 147 : |
|
|
raise IOError(2,'No module file: %s' % src)
|
| 148 : |
|
|
|
| 149 : |
|
|
# Steps:
|
| 150 : |
|
|
# Use xgettext to parse all application modules
|
| 151 : |
|
|
# The following switches are used:
|
| 152 : |
|
|
#
|
| 153 : |
|
|
# -s : sort output by string content
|
| 154 : |
|
|
# (easier to use when we need to merge several .po files)
|
| 155 : |
|
|
# --files-from=app.fil : The list of files is taken from the file: app.fil
|
| 156 : |
|
|
# --output= : specifies the name of the output file
|
| 157 : |
|
|
# (using a .pot extension)
|
| 158 : |
|
|
cmd = "xgettext -s --no-wrap --from-code=utf-8 --files-from=%s --output=%s.pot" % (src, out)
|
| 159 : |
|
|
if verbose:
|
| 160 : |
|
|
print cmd
|
| 161 : |
|
|
os.system(cmd)
|
| 162 : |
|
|
lang_dict = getlanguageDict()
|
| 163 : |
|
|
for lang_code in lang_dict.keys():
|
| 164 : |
|
|
if lang_code == 'en':
|
| 165 : |
|
|
pass
|
| 166 : |
|
|
else:
|
| 167 : |
|
|
lang_po_filename = "%s/%s_%s.po" % (podir, app_name, lang_code)
|
| 168 : |
|
|
if os.path.exists(lang_po_filename):
|
| 169 : |
|
|
cmd = 'msgmerge -s --no-wrap "%s" messages.pot > "%s.new"' % \
|
| 170 : |
|
|
(lang_po_filename, lang_po_filename)
|
| 171 : |
|
|
if verbose:
|
| 172 : |
|
|
print cmd
|
| 173 : |
|
|
os.system(cmd)
|
| 174 : |
|
|
os.chdir(curr_dir)
|
| 175 : |
|
|
|
| 176 : |
|
|
# -----------------------------------------------------------------------------
|
| 177 : |
|
|
# c a t P O ( )
|
| 178 : |
|
|
# -- Concatenate one or several PO files with the application domain files. --
|
| 179 : |
|
|
# ^^^^^^^^^^^^^
|
| 180 : |
|
|
#
|
| 181 : |
|
|
def catPO(app_dir, listOf_extraPo, app_domain=None, \
|
| 182 : |
|
|
target_dir=None, verbose=0) :
|
| 183 : |
|
|
"""Concatenate one or several PO files with the application domain files.
|
| 184 : |
|
|
"""
|
| 185 : |
|
|
|
| 186 : |
|
|
if app_domain is None:
|
| 187 : |
|
|
app_name = fileBaseOf(app_dir, withPath=0)
|
| 188 : |
|
|
else:
|
| 189 : |
|
|
app_name = app_domain
|
| 190 : |
|
|
curr_dir = os.getcwd()
|
| 191 : |
|
|
os.chdir(app_dir)
|
| 192 : |
|
|
|
| 193 : |
|
|
lang_dict = getlanguageDict()
|
| 194 : |
|
|
|
| 195 : |
|
|
for lang_code in lang_dict.keys():
|
| 196 : |
|
|
if lang_code == 'en':
|
| 197 : |
|
|
pass
|
| 198 : |
|
|
else:
|
| 199 : |
|
|
lang_po_fname = "%s_%s.po" % (app_name, lang_code)
|
| 200 : |
|
|
if os.path.exists(lang_po_fname):
|
| 201 : |
|
|
fileList = ''
|
| 202 : |
|
|
for fname in listOf_extraPo:
|
| 203 : |
|
|
fileList += ("%s_%s.po " % (fname, lang_code))
|
| 204 : |
|
|
cmd = "msgcat -s --no-wrap %s %s > %s.cat" % (lang_po_fname, \
|
| 205 : |
|
|
fileList, \
|
| 206 : |
|
|
lang_po_fname)
|
| 207 : |
|
|
if verbose:
|
| 208 : |
|
|
print cmd
|
| 209 : |
|
|
os.system(cmd)
|
| 210 : |
|
|
if target_dir is None:
|
| 211 : |
|
|
pass
|
| 212 : |
|
|
else:
|
| 213 : |
|
|
mo_targetDir = "%s/%s/LC_MESSAGES" % (target_dir, lang_code)
|
| 214 : |
|
|
cmd = "msgfmt --output-file=%s/%s.mo %s_%s.po.cat" % \
|
| 215 : |
|
|
(mo_targetDir, app_name, app_name, lang_code)
|
| 216 : |
|
|
if verbose:
|
| 217 : |
|
|
print cmd
|
| 218 : |
|
|
os.system(cmd)
|
| 219 : |
|
|
os.chdir(curr_dir)
|
| 220 : |
|
|
|
| 221 : |
|
|
# -----------------------------------------------------------------------------
|
| 222 : |
|
|
# m a k e M O ( ) Compile the POfiles into the MO stored in the right location.
|
| 223 : |
|
|
# ^^^^^^^^^^^^^^^
|
| 224 : |
|
|
#
|
| 225 : |
|
|
def makeMO(applicationDirectoryPath, targetDir='./locale',
|
| 226 : |
|
|
applicationDomain=None, verbose=0, forceEnglish=0, podir='') :
|
| 227 : |
|
|
"""Compile the Portable Object files into the Machine Object stored in the
|
| 228 : |
|
|
right location.
|
| 229 : |
|
|
|
| 230 : |
|
|
makeMO converts all translated language-specific PO files located inside
|
| 231 : |
|
|
the application directory into the binary .MO files stored inside the
|
| 232 : |
|
|
LC_MESSAGES sub-directory for the found locale files.
|
| 233 : |
|
|
|
| 234 : |
|
|
makeMO searches for all files that have a name of the form 'app_xx.po'
|
| 235 : |
|
|
inside the application directory specified by the first argument. The
|
| 236 : |
|
|
'app' is the application domain name (that can be specified by the
|
| 237 : |
|
|
applicationDomain argument or is taken from the directory name). The 'xx'
|
| 238 : |
|
|
corresponds to one of the ISO 639 two-letter language codes.
|
| 239 : |
|
|
|
| 240 : |
|
|
makeMo stores the resulting files inside a sub-directory of `targetDir`
|
| 241 : |
|
|
called xx/LC_MESSAGES where 'xx' corresponds to the 2-letter language
|
| 242 : |
|
|
code.
|
| 243 : |
|
|
"""
|
| 244 : |
|
|
if targetDir is None:
|
| 245 : |
|
|
targetDir = './locale'
|
| 246 : |
|
|
if verbose:
|
| 247 : |
|
|
print "Target directory for .mo files is: %s" % targetDir
|
| 248 : |
|
|
|
| 249 : |
|
|
if applicationDomain is None:
|
| 250 : |
|
|
applicationName = fileBaseOf(applicationDirectoryPath, withPath=0)
|
| 251 : |
|
|
else:
|
| 252 : |
|
|
applicationName = applicationDomain
|
| 253 : |
|
|
currentDir = os.getcwd()
|
| 254 : |
|
|
os.chdir(applicationDirectoryPath)
|
| 255 : |
|
|
|
| 256 : |
|
|
languageDict = getlanguageDict()
|
| 257 : |
|
|
|
| 258 : |
|
|
for langCode in languageDict.keys():
|
| 259 : |
|
|
if (langCode == 'en') and (forceEnglish==0):
|
| 260 : |
|
|
pass
|
| 261 : |
|
|
else:
|
| 262 : |
|
|
langPOfileName = "%s/%s_%s.po" % (podir, applicationName, langCode)
|
| 263 : |
|
|
if os.path.exists(langPOfileName):
|
| 264 : |
|
|
mo_targetDir = "%s/%s/LC_MESSAGES" % (targetDir, langCode)
|
| 265 : |
|
|
if not os.path.exists(mo_targetDir):
|
| 266 : |
|
|
mkdir(mo_targetDir)
|
| 267 : |
|
|
cmd = 'msgfmt --output-file="%s/%s.mo" "%s/%s_%s.po"' % \
|
| 268 : |
|
|
(mo_targetDir, applicationName, podir, applicationName, langCode)
|
| 269 : |
|
|
if verbose:
|
| 270 : |
|
|
print cmd
|
| 271 : |
|
|
os.system(cmd)
|
| 272 : |
|
|
os.chdir(currentDir)
|
| 273 : |
|
|
|
| 274 : |
|
|
# -----------------------------------------------------------------------------
|
| 275 : |
|
|
|
| 276 : |
|
|
def printUsage(errorMsg=None):
|
| 277 : |
|
|
"""Displays how to use this script from the command line."""
|
| 278 : |
|
|
print """
|
| 279 : |
|
|
###########################################################################
|
| 280 : |
|
|
# mki18n : Make internationalization files. #
|
| 281 : |
|
|
# Uses the GNU gettext system to create PO (Portable Object) #
|
| 282 : |
|
|
# files from source code, compile PO into MO (Machine Object) #
|
| 283 : |
|
|
# files. #
|
| 284 : |
|
|
# Supports C, C++, and Python source files. #
|
| 285 : |
|
|
# #
|
| 286 : |
|
|
# Usage: mki18n {OPTION} [appDirPath] #
|
| 287 : |
|
|
# #
|
| 288 : |
|
|
# Options: #
|
| 289 : |
|
|
# -h : prints this help #
|
| 290 : |
|
|
# -m : make MO from existing PO files #
|
| 291 : |
|
|
# -p : make PO, update PO files: Creates a new #
|
| 292 : |
|
|
# messages.pot file. Creates a dom_xx.po.new for #
|
| 293 : |
|
|
# every existing language specific .po file. #
|
| 294 : |
|
|
# ('xx' stands for the ISO639 two-letter language #
|
| 295 : |
|
|
# code and 'dom' stands for the application domain #
|
| 296 : |
|
|
# name). #
|
| 297 : |
|
|
# --domain=appName : Specify a specific folder to generate for the #
|
| 298 : |
|
|
# default is to check and generate for all folders #
|
| 299 : |
|
|
# found in the same directory as this one. #
|
| 300 : |
|
|
# #
|
| 301 : |
|
|
# You must specify one of the -p or -m option to perform the work. You #
|
| 302 : |
|
|
# can specify the path of the target application. If you leave it out #
|
| 303 : |
|
|
# mki18n will use the current directory as the application main #
|
| 304 : |
|
|
# directory. #
|
| 305 : |
|
|
###########################################################################
|
| 306 : |
|
|
"""
|
| 307 : |
|
|
if errorMsg:
|
| 308 : |
|
|
print "\n ERROR: %s" % errorMsg
|
| 309 : |
|
|
|
| 310 : |
|
|
# -----------------------------------------------------------------------------
|
| 311 : |
|
|
# f i l e B a s e O f ( ) -- Return base name of filename --
|
| 312 : |
|
|
# ^^^^^^^^^^^^^^^^^^^^^^^
|
| 313 : |
|
|
#
|
| 314 : |
|
|
def fileBaseOf(filename, withPath=0) :
|
| 315 : |
|
|
"""fileBaseOf(filename,withPath) ---> string
|
| 316 : |
|
|
|
| 317 : |
|
|
Return base name of filename. The returned string never includes the
|
| 318 : |
|
|
extension.
|
| 319 : |
|
|
Use os.path.basename() to return the basename with the extension. The
|
| 320 : |
|
|
second argument is optional. If specified and if set to 'true' (non zero)
|
| 321 : |
|
|
the string returned contains the full path of the file name. Otherwise the
|
| 322 : |
|
|
path is excluded.
|
| 323 : |
|
|
|
| 324 : |
|
|
"""
|
| 325 : |
|
|
pos = filename.rfind('.')
|
| 326 : |
|
|
if pos > 0:
|
| 327 : |
|
|
filename = filename[:pos]
|
| 328 : |
|
|
if withPath:
|
| 329 : |
|
|
return filename
|
| 330 : |
|
|
else:
|
| 331 : |
|
|
return os.path.basename(filename)
|
| 332 : |
|
|
|
| 333 : |
|
|
# -----------------------------------------------------------------------------
|
| 334 : |
|
|
# m k d i r ( ) -- Create a directory (and possibly the entire tree) --
|
| 335 : |
|
|
# ^^^^^^^^^^^^^
|
| 336 : |
|
|
#
|
| 337 : |
|
|
def mkdir(directory) :
|
| 338 : |
|
|
"""Create a directory (and possibly the entire tree).
|
| 339 : |
|
|
|
| 340 : |
|
|
The os.mkdir() will fail to create a directory if one of the
|
| 341 : |
|
|
directory in the specified path does not exist. mkdir()
|
| 342 : |
|
|
solves this problem. It creates every intermediate directory
|
| 343 : |
|
|
required to create the final path. Under Unix, the function
|
| 344 : |
|
|
only supports forward slash separator, but under Windows and MacOS
|
| 345 : |
|
|
the function supports the forward slash and the OS separator (backslash
|
| 346 : |
|
|
under windows).
|
| 347 : |
|
|
"""
|
| 348 : |
|
|
# translate the path separators
|
| 349 : |
|
|
directory = unixpath(directory)
|
| 350 : |
|
|
|
| 351 : |
|
|
# build a list of all directory elements
|
| 352 : |
|
|
elem_list = filter(lambda x: len(x) > 0, directory.split('/'))
|
| 353 : |
|
|
the_len = len(elem_list)
|
| 354 : |
|
|
|
| 355 : |
|
|
# if the first element is a Windows-style disk drive
|
| 356 : |
|
|
# concatenate it with the first directory
|
| 357 : |
|
|
if elem_list[0].endswith(':'):
|
| 358 : |
|
|
if the_len > 1:
|
| 359 : |
|
|
elem_list[1] = elem_list[0] + '/' + elem_list[1]
|
| 360 : |
|
|
del elem_list[0]
|
| 361 : |
|
|
the_len -= 1
|
| 362 : |
|
|
|
| 363 : |
|
|
# if the original directory starts at root,
|
| 364 : |
|
|
# make sure the first element of the list
|
| 365 : |
|
|
# starts at root too
|
| 366 : |
|
|
if directory[0] == '/':
|
| 367 : |
|
|
elem_list[0] = '/' + elem_list[0]
|
| 368 : |
|
|
|
| 369 : |
|
|
# Now iterate through the list, check if the
|
| 370 : |
|
|
# directory exists and if not create it
|
| 371 : |
|
|
the_dir = ''
|
| 372 : |
|
|
for i in range(the_len):
|
| 373 : |
|
|
the_dir += elem_list[i]
|
| 374 : |
|
|
if not os.path.exists(the_dir):
|
| 375 : |
|
|
os.mkdir(the_dir)
|
| 376 : |
|
|
the_dir += '/'
|
| 377 : |
|
|
|
| 378 : |
|
|
# -----------------------------------------------------------------------------
|
| 379 : |
|
|
# u n i x p a t h ( ) -- Return a path name that contains Unix separator. --
|
| 380 : |
|
|
# ^^^^^^^^^^^^^^^^^^^
|
| 381 : |
|
|
#
|
| 382 : |
|
|
def unixpath(path) :
|
| 383 : |
|
|
r"""Return a path name that contains Unix separator.
|
| 384 : |
|
|
|
| 385 : |
|
|
[Example]
|
| 386 : |
|
|
>>> unixpath(r"d:\test")
|
| 387 : |
|
|
'd:/test'
|
| 388 : |
|
|
>>> unixpath("d:/test/file.txt")
|
| 389 : |
|
|
'd:/test/file.txt'
|
| 390 : |
|
|
>>>
|
| 391 : |
|
|
"""
|
| 392 : |
|
|
path = os.path.normpath(path)
|
| 393 : |
|
|
if os.sep == '/':
|
| 394 : |
|
|
return path
|
| 395 : |
|
|
else:
|
| 396 : |
|
|
return path.replace(os.sep, '/')
|
| 397 : |
|
|
|
| 398 : |
|
|
# -----------------------------------------------------------------------------
|
| 399 : |
|
|
# S c r i p t e x e c u t i o n -- Runs when invoked from the command line --
|
| 400 : |
|
|
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 401 : |
|
|
#
|
| 402 : |
|
|
if __name__ == "__main__":
|
| 403 : |
|
|
import getopt # command line parsing
|
| 404 : |
|
|
argc = len(sys.argv)
|
| 405 : |
|
|
if argc == 1:
|
| 406 : |
|
|
printUsage('Missing argument: specify at least one of -m or -p '
|
| 407 : |
|
|
'(or both).')
|
| 408 : |
|
|
sys.exit(1)
|
| 409 : |
|
|
# If there is some arguments, parse the command line
|
| 410 : |
|
|
valid_opts = "ehmpv"
|
| 411 : |
|
|
valid_lopts = ['domain=', 'moTarget=', 'podir=']
|
| 412 : |
|
|
option = {}
|
| 413 : |
|
|
option['forceEnglish'] = 0
|
| 414 : |
|
|
option['mo'] = 0
|
| 415 : |
|
|
option['po'] = 0
|
| 416 : |
|
|
option['verbose'] = 0
|
| 417 : |
|
|
option['domain'] = None
|
| 418 : |
|
|
option['moTarget'] = None
|
| 419 : |
|
|
try:
|
| 420 : |
|
|
optionList, pargs = getopt.getopt(sys.argv[1:], valid_opts, valid_lopts)
|
| 421 : |
|
|
except getopt.GetoptError, e:
|
| 422 : |
|
|
printUsage(e[0])
|
| 423 : |
|
|
sys.exit(1)
|
| 424 : |
|
|
for (opt, val) in optionList:
|
| 425 : |
|
|
if (opt == '-h'):
|
| 426 : |
|
|
printUsage()
|
| 427 : |
|
|
sys.exit(0)
|
| 428 : |
|
|
elif (opt == '-e'):
|
| 429 : |
|
|
option['forceEnglish'] = 1
|
| 430 : |
|
|
elif (opt == '-m'):
|
| 431 : |
|
|
option['mo'] = 1
|
| 432 : |
|
|
elif (opt == '-p'):
|
| 433 : |
|
|
option['po'] = 1
|
| 434 : |
|
|
elif (opt == '-v'):
|
| 435 : |
|
|
option['verbose'] = 1
|
| 436 : |
|
|
elif (opt == '--domain'):
|
| 437 : |
|
|
option['domain'] = val
|
| 438 : |
|
|
elif (opt == '--moTarget'):
|
| 439 : |
|
|
option['moTarget'] = val
|
| 440 : |
|
|
elif (opt == '--podir'):
|
| 441 : |
|
|
option['podir'] = val
|
| 442 : |
|
|
|
| 443 : |
|
|
if len(pargs) == 0:
|
| 444 : |
|
|
app_dir_path = os.getcwd()
|
| 445 : |
|
|
if option['verbose']:
|
| 446 : |
|
|
print "No project directory given. Using current one: %s" % \
|
| 447 : |
|
|
app_dir_path
|
| 448 : |
|
|
elif len(pargs) == 1:
|
| 449 : |
|
|
app_dir_path = pargs[0]
|
| 450 : |
|
|
else:
|
| 451 : |
|
|
printUsage(('Too many arguments (%u). Use double quotes if you have '
|
| 452 : |
|
|
'space in directory name') % len(pargs))
|
| 453 : |
|
|
sys.exit(1)
|
| 454 : |
|
|
|
| 455 : |
|
|
if option['domain'] is None:
|
| 456 : |
|
|
# If no domain specified, use the name of the target directory
|
| 457 : |
|
|
option['domain'] = fileBaseOf(app_dir_path)
|
| 458 : |
|
|
|
| 459 : |
|
|
if option['verbose']:
|
| 460 : |
|
|
print "Application domain used is: '%s'" % option['domain']
|
| 461 : |
|
|
|
| 462 : |
|
|
if option['po']:
|
| 463 : |
|
|
try:
|
| 464 : |
|
|
makePO(app_dir_path, option['domain'], option['verbose'], podir=option['podir'])
|
| 465 : |
|
|
except IOError, e:
|
| 466 : |
|
|
printUsage(e[1] + ('\n You must write a file app.fil that '
|
| 467 : |
|
|
'containsthe list of all files to parse.'))
|
| 468 : |
|
|
if option['mo']:
|
| 469 : |
|
|
makeMO(app_dir_path, option['moTarget'], option['domain'],
|
| 470 : |
|
|
option['verbose'], option['forceEnglish'], podir=option['podir'])
|
| 471 : |
|
|
sys.exit(1)
|
| 472 : |
|
|
|
| 473 : |
|
|
# -----------------------------------------------------------------------------
|