laurent@361: #! /usr/bin/env python
laurent@361: # -*- coding: iso-8859-1 -*-
laurent@361: # 
laurent@361: #   PYTHON MODULE:     MKI18N.PY
laurent@361: #                      =========
laurent@361: # 
laurent@361: #   Abstract:         Make Internationalization (i18n) files for an application.
laurent@361: # 
laurent@361: #   Copyright Pierre Rouleau. 2003. Released to public domain.
laurent@361: # 
laurent@361: #   Last update: Saturday, November 8, 2003. @ 15:55:18.
laurent@361: # 
laurent@361: #   File: ROUP2003N01::C:/dev/python/mki18n.py
laurent@361: # 
laurent@361: #   RCS $Header: //software/official/MKS/MKS_SI/TV_NT/dev/Python/rcs/mki18n.py 1.5 2003/11/05 19:40:04 PRouleau Exp $
laurent@361: # 
laurent@361: #   Update history:
laurent@361: # 
laurent@361: #   - File created: Saturday, June 7, 2003. by Pierre Rouleau
laurent@361: #   - 10/06/03 rcs : RCS Revision 1.1  2003/06/10 10:06:12  PRouleau
laurent@361: #   - 10/06/03 rcs : RCS Initial revision
laurent@361: #   - 23/08/03 rcs : RCS Revision 1.2  2003/06/10 10:54:27  PRouleau
laurent@361: #   - 23/08/03 P.R.: [code:fix] : The strings encoded in this file are encode in iso-8859-1 format.  Added the encoding
laurent@361: #                    notification to Python to comply with Python's 2.3 PEP 263.
laurent@361: #   - 23/08/03 P.R.: [feature:new] : Added the '-e' switch which is used to force the creation of the empty English .mo file.
laurent@361: #   - 22/10/03 P.R.: [code] : incorporated utility functions in here to make script self sufficient.
laurent@361: #   - 05/11/03 rcs : RCS Revision 1.4  2003/10/22 06:39:31  PRouleau
laurent@361: #   - 05/11/03 P.R.: [code:fix] : included the unixpath() in this file.
laurent@361: #   - 08/11/03 rcs : RCS Revision 1.5  2003/11/05 19:40:04  PRouleau
laurent@361: # 
laurent@361: #   RCS $Log: $
laurent@361: # 
laurent@361: # 
laurent@361: # -----------------------------------------------------------------------------
laurent@361: """                                
laurent@361: mki18n allows you to internationalize your software.  You can use it to 
laurent@361: create the GNU .po files (Portable Object) and the compiled .mo files
laurent@361: (Machine Object).
laurent@361: 
laurent@361: mki18n module can be used from the command line or from within a script (see 
laurent@361: the Usage at the end of this page).
laurent@361: 
laurent@361:     Table of Contents
laurent@361:     -----------------
laurent@361:     
laurent@361:     makePO()             -- Build the Portable Object file for the application --
laurent@361:     catPO()              -- Concatenate one or several PO files with the application domain files. --
laurent@361:     makeMO()             -- Compile the Portable Object files into the Machine Object stored in the right location. --
laurent@361:     printUsage           -- Displays how to use this script from the command line --
laurent@361: 
laurent@361:     Scriptexecution      -- Runs when invoked from the command line --
laurent@361: 
laurent@361: 
laurent@361: NOTE:  this module uses GNU gettext utilities.
laurent@361: 
laurent@361: You can get the gettext tools from the following sites:
laurent@361: 
laurent@361:    - `GNU FTP site for gettetx`_ where several versions (0.10.40, 0.11.2, 0.11.5 and 0.12.1) are available.
laurent@361:      Note  that you need to use `GNU libiconv`_ to use this. Get it from the `GNU
laurent@361:      libiconv  ftp site`_ and get version 1.9.1 or later. Get the Windows .ZIP
laurent@361:      files and install the packages inside c:/gnu. All binaries will be stored
laurent@361:      inside  c:/gnu/bin.  Just  put c:/gnu/bin inside your PATH. You will need
laurent@361:      the following files: 
laurent@361: 
laurent@361:       - `gettext-runtime-0.12.1.bin.woe32.zip`_ 
laurent@361:       - `gettext-tools-0.12.1.bin.woe32.zip`_
laurent@361:       - `libiconv-1.9.1.bin.woe32.zip`_ 
laurent@361: 
laurent@361: 
laurent@361: .. _GNU libiconv:                            http://www.gnu.org/software/libiconv/
laurent@361: .. _GNU libiconv ftp site:                   http://www.ibiblio.org/pub/gnu/libiconv/
laurent@361: .. _gettext-runtime-0.12.1.bin.woe32.zip:    ftp://ftp.gnu.org/gnu/gettext/gettext-runtime-0.12.1.bin.woe32.zip           
laurent@361: .. _gettext-tools-0.12.1.bin.woe32.zip:      ftp://ftp.gnu.org/gnu/gettext/gettext-tools-0.12.1.bin.woe32.zip 
laurent@361: .. _libiconv-1.9.1.bin.woe32.zip:            http://www.ibiblio.org/pub/gnu/libiconv/libiconv-1.9.1.bin.woe32.zip
laurent@361: 
laurent@361: """
laurent@361: # -----------------------------------------------------------------------------
laurent@361: # Module Import
laurent@361: # -------------
laurent@361: # 
laurent@361: import os
laurent@361: import sys
laurent@361: import wx
laurent@361: import re
laurent@361: 
laurent@361: # -----------------------------------------------------------------------------
laurent@361: # Global variables
laurent@361: # ----------------
laurent@361: #
laurent@361: 
laurent@361: __author__ = "Pierre Rouleau"
laurent@361: __version__= "$Revision: 1.5 $"
laurent@361: 
laurent@361: # -----------------------------------------------------------------------------
laurent@361: 
laurent@361: def getlanguageDict():
laurent@361:     languageDict = {}
laurent@361:     
laurent@361:     for lang in [x for x in dir(wx) if x.startswith("LANGUAGE")]:
laurent@361:         i = wx.Locale(wx.LANGUAGE_DEFAULT).GetLanguageInfo(getattr(wx, lang))
laurent@361:         if i:
laurent@361:             languageDict[i.CanonicalName] = i.Description
laurent@361: 
laurent@361:     return languageDict
laurent@361: 
laurent@361: XSD_STRING_MODEL = re.compile("<xsd\:(?:element|attribute) name=\"([^\"]*)\"[^\>]*\>")
laurent@361: 
laurent@361: # -----------------------------------------------------------------------------
laurent@361: # m a k e P O ( )         -- Build the Portable Object file for the application --
laurent@361: # ^^^^^^^^^^^^^^^
laurent@361: #
laurent@361: def makePO(applicationDirectoryPath,  applicationDomain=None, verbose=0) :
laurent@361:     """Build the Portable Object Template file for the application.
laurent@361: 
laurent@361:     makePO builds the .pot file for the application stored inside 
laurent@361:     a specified directory by running xgettext for all application source 
laurent@361:     files.  It finds the name of all files by looking for a file called 'app.fil'. 
laurent@361:     If this file does not exists, makePo raises an IOError exception.
laurent@361:     By default the application domain (the application
laurent@361:     name) is the same as the directory name but it can be overridden by the
laurent@361:     'applicationDomain' argument.
laurent@361: 
laurent@361:     makePO always creates a new file called messages.pot.  If it finds files 
laurent@361:     of the form app_xx.po where 'app' is the application name and 'xx' is one 
laurent@361:     of the ISO 639 two-letter language codes, makePO resynchronizes those 
laurent@361:     files with the latest extracted strings (now contained in messages.pot). 
laurent@361:     This process updates all line location number in the language-specific
laurent@361:     .po files and may also create new entries for translation (or comment out 
laurent@361:     some).  The .po file is not changed, instead a new file is created with 
laurent@361:     the .new extension appended to the name of the .po file.
laurent@361: 
laurent@361:     By default the function does not display what it is doing.  Set the 
laurent@361:     verbose argument to 1 to force it to print its commands.
laurent@361:     """
laurent@361: 
laurent@361:     if applicationDomain is None:
laurent@361:         applicationName = fileBaseOf(applicationDirectoryPath,withPath=0)
laurent@361:     else:
laurent@361:         applicationName = applicationDomain
laurent@361:     currentDir = os.getcwd()
laurent@361:     os.chdir(applicationDirectoryPath)                    
laurent@361:     if not os.path.exists('app.fil'):
laurent@361:         raise IOError(2,'No module file: app.fil')
laurent@361: 
laurent@361:     # Steps:                                  
laurent@361:     #  Use xgettext to parse all application modules
laurent@361:     #  The following switches are used:
laurent@361:     #  
laurent@361:     #   -s                          : sort output by string content (easier to use when we need to merge several .po files)
laurent@361:     #   --files-from=app.fil        : The list of files is taken from the file: app.fil
laurent@361:     #   --output=                   : specifies the name of the output file (using a .pot extension)
laurent@361:     cmd = 'xgettext -s --no-wrap --language=Python --files-from=app.fil --output=messages.pot'
laurent@361:     if verbose: print cmd
laurent@361:     os.system(cmd)                                                
laurent@361: 
laurent@361:     appfil_file = open("app.fil", 'r')
laurent@361:     messages_file = open("messages.pot", 'a')
laurent@361:     messages_file.write("""
laurent@361: #: Extra XSD strings
laurent@361: """)
laurent@361:     words_found = {}
laurent@361:     for filepath in appfil_file.xreadlines():
laurent@361:         code_file = open(filepath.strip(), 'r')
laurent@361:         for match in XSD_STRING_MODEL.finditer(code_file.read()):
laurent@361: 				    word = match.group(1)
laurent@361: 				    if not words_found.get(word, False):
laurent@361: 				        words_found[word] = True
laurent@361: 				        messages_file.write("""
laurent@361: msgid "%s"
laurent@361: msgstr ""
laurent@361: """%word)
laurent@361:         code_file.close()
laurent@361:     messages_file.close()
laurent@361:     appfil_file.close()
laurent@361:     
laurent@361:     languageDict = getlanguageDict()
laurent@361: 
laurent@361:     for langCode in languageDict.keys():
laurent@361:         if langCode == 'en':
laurent@361:             pass
laurent@361:         else:
laurent@361:             langPOfileName = "%s_%s.po" % (applicationName , langCode)
laurent@361:             if os.path.exists(langPOfileName):
laurent@361:                 cmd = 'msgmerge -s --no-wrap "%s" messages.pot > "%s.new"' % (langPOfileName, langPOfileName)
laurent@361:                 if verbose: print cmd
laurent@361:                 os.system(cmd)
laurent@361:     os.chdir(currentDir)
laurent@361: 
laurent@361: # -----------------------------------------------------------------------------
laurent@361: # c a t P O ( )         -- Concatenate one or several PO files with the application domain files. --
laurent@361: # ^^^^^^^^^^^^^
laurent@361: #
laurent@361: def catPO(applicationDirectoryPath, listOf_extraPo, applicationDomain=None, targetDir=None, verbose=0) :
laurent@361:     """Concatenate one or several PO files with the application domain files.
laurent@361:     """
laurent@361: 
laurent@361:     if applicationDomain is None:
laurent@361:         applicationName = fileBaseOf(applicationDirectoryPath,withPath=0)
laurent@361:     else:
laurent@361:         applicationName = applicationDomain
laurent@361:     currentDir = os.getcwd()
laurent@361:     os.chdir(applicationDirectoryPath)
laurent@361: 
laurent@361:     languageDict = getlanguageDict()
laurent@361: 
laurent@361:     for langCode in languageDict.keys():
laurent@361:         if langCode == 'en':
laurent@361:             pass
laurent@361:         else:
laurent@361:             langPOfileName = "%s_%s.po" % (applicationName , langCode)
laurent@361:             if os.path.exists(langPOfileName):
laurent@361:                 fileList = ''
laurent@361:                 for fileName in listOf_extraPo:
laurent@361:                     fileList += ("%s_%s.po " % (fileName,langCode))
laurent@361:                 cmd = "msgcat -s --no-wrap %s %s > %s.cat" % (langPOfileName, fileList, langPOfileName)
laurent@361:                 if verbose: print cmd
laurent@361:                 os.system(cmd)
laurent@361:                 if targetDir is None:
laurent@361:                     pass
laurent@361:                 else:
laurent@361:                     mo_targetDir = "%s/%s/LC_MESSAGES" % (targetDir,langCode)
laurent@361:                     cmd = "msgfmt --output-file=%s/%s.mo %s_%s.po.cat" % (mo_targetDir,applicationName,applicationName,langCode)
laurent@361:                     if verbose: print cmd
laurent@361:                     os.system(cmd)
laurent@361:     os.chdir(currentDir)
laurent@361: 
laurent@361: # -----------------------------------------------------------------------------
laurent@361: # m a k e M O ( )         -- Compile the Portable Object files into the Machine Object stored in the right location. --
laurent@361: # ^^^^^^^^^^^^^^^
laurent@361: # 
laurent@361: def makeMO(applicationDirectoryPath,targetDir='./locale',applicationDomain=None, verbose=0, forceEnglish=0) :
laurent@361:     """Compile the Portable Object files into the Machine Object stored in the right location.
laurent@361: 
laurent@361:     makeMO converts all translated language-specific PO files located inside 
laurent@361:     the  application directory into the binary .MO files stored inside the 
laurent@361:     LC_MESSAGES sub-directory for the found locale files.
laurent@361: 
laurent@361:     makeMO searches for all files that have a name of the form 'app_xx.po' 
laurent@361:     inside the application directory specified by the first argument.  The 
laurent@361:     'app' is the application domain name (that can be specified by the 
laurent@361:     applicationDomain argument or is taken from the directory name). The 'xx' 
laurent@361:     corresponds to one of the ISO 639 two-letter language codes.
laurent@361: 
laurent@361:     makeMo stores the resulting files inside a sub-directory of `targetDir`
laurent@361:     called xx/LC_MESSAGES where 'xx' corresponds to the 2-letter language
laurent@361:     code.
laurent@361:     """
laurent@361:     if targetDir is None:
laurent@361:         targetDir = './locale'
laurent@361:     if verbose:
laurent@361:         print "Target directory for .mo files is: %s" % targetDir
laurent@361: 
laurent@361:     if applicationDomain is None:
laurent@361:         applicationName = fileBaseOf(applicationDirectoryPath,withPath=0)
laurent@361:     else:
laurent@361:         applicationName = applicationDomain
laurent@361:     currentDir = os.getcwd()
laurent@361:     os.chdir(applicationDirectoryPath)
laurent@361: 
laurent@361:     languageDict = getlanguageDict()
laurent@361: 
laurent@361:     for langCode in languageDict.keys():
laurent@361:         if (langCode == 'en') and (forceEnglish==0):
laurent@361:             pass
laurent@361:         else:
laurent@361:             langPOfileName = "%s_%s.po" % (applicationName , langCode)
laurent@361:             if os.path.exists(langPOfileName):
laurent@361:                 mo_targetDir = "%s/%s/LC_MESSAGES" % (targetDir,langCode)
laurent@361:                 if not os.path.exists(mo_targetDir):
laurent@361:                     mkdir(mo_targetDir)
laurent@361:                 cmd = 'msgfmt --output-file="%s/%s.mo" "%s_%s.po"' % (mo_targetDir,applicationName,applicationName,langCode)
laurent@361:                 if verbose: print cmd
laurent@361:                 os.system(cmd)
laurent@361:     os.chdir(currentDir)
laurent@361:    
laurent@361: # -----------------------------------------------------------------------------
laurent@361: # p r i n t U s a g e         -- Displays how to use this script from the command line --
laurent@361: # ^^^^^^^^^^^^^^^^^^^
laurent@361: #
laurent@361: def printUsage(errorMsg=None) :
laurent@361:     """Displays how to use this script from the command line."""
laurent@361:     print """
laurent@361:     ##################################################################################
laurent@361:     #   mki18n :   Make internationalization files.                                  #
laurent@361:     #              Uses the GNU gettext system to create PO (Portable Object) files  #
laurent@361:     #              from source code, coimpile PO into MO (Machine Object) files.     #
laurent@361:     #              Supports C,C++,Python source files.                               #
laurent@361:     #                                                                                #
laurent@361:     #   Usage: mki18n {OPTION} [appDirPath]                                          #
laurent@361:     #                                                                                #
laurent@361:     #   Options:                                                                     #
laurent@361:     #     -e               : When -m is used, forces English .mo file creation       #
laurent@361:     #     -h               : prints this help                                        #
laurent@361:     #     -m               : make MO from existing PO files                          #
laurent@361:     #     -p               : make PO, update PO files: Creates a new messages.pot    #
laurent@361:     #                        file. Creates a dom_xx.po.new for every existing        #
laurent@361:     #                        language specific .po file. ('xx' stands for the ISO639 #
laurent@361:     #                        two-letter language code and 'dom' stands for the       #
laurent@361:     #                        application domain name).  mki18n requires that you     #
laurent@361:     #                        write a 'app.fil' file  which contains the list of all  #
laurent@361:     #                        source code to parse.                                   #
laurent@361:     #     -v               : verbose (prints comments while running)                 #
laurent@361:     #     --domain=appName : specifies the application domain name.  By default      #
laurent@361:     #                        the directory name is used.                             #
laurent@361:     #     --moTarget=dir : specifies the directory where .mo files are stored.       #
laurent@361:     #                      If not specified, the target is './locale'                #
laurent@361:     #                                                                                #
laurent@361:     #   You must specify one of the -p or -m option to perform the work.  You can    #
laurent@361:     #   specify the path of the target application.  If you leave it out mki18n      #
laurent@361:     #   will use the current directory as the application main directory.            #        
laurent@361:     #                                                                                #
laurent@361:     ##################################################################################"""
laurent@361:     if errorMsg:
laurent@361:         print "\n   ERROR: %s" % errorMsg
laurent@361: 
laurent@361: # -----------------------------------------------------------------------------
laurent@361: # f i l e B a s e O f ( )         -- Return base name of filename --
laurent@361: # ^^^^^^^^^^^^^^^^^^^^^^^
laurent@361: # 
laurent@361: def fileBaseOf(filename,withPath=0) :
laurent@361:    """fileBaseOf(filename,withPath) ---> string
laurent@361: 
laurent@361:    Return base name of filename.  The returned string never includes the extension.
laurent@361:    Use os.path.basename() to return the basename with the extension.  The 
laurent@361:    second argument is optional.  If specified and if set to 'true' (non zero) 
laurent@361:    the string returned contains the full path of the file name.  Otherwise the 
laurent@361:    path is excluded.
laurent@361: 
laurent@361:    [Example]
laurent@361:    >>> fn = 'd:/dev/telepath/tvapp/code/test.html'
laurent@361:    >>> fileBaseOf(fn)
laurent@361:    'test'
laurent@361:    >>> fileBaseOf(fn)
laurent@361:    'test'
laurent@361:    >>> fileBaseOf(fn,1)
laurent@361:    'd:/dev/telepath/tvapp/code/test'
laurent@361:    >>> fileBaseOf(fn,0)
laurent@361:    'test'
laurent@361:    >>> fn = 'abcdef'
laurent@361:    >>> fileBaseOf(fn)
laurent@361:    'abcdef'
laurent@361:    >>> fileBaseOf(fn,1)
laurent@361:    'abcdef'
laurent@361:    >>> fn = "abcdef."
laurent@361:    >>> fileBaseOf(fn)
laurent@361:    'abcdef'
laurent@361:    >>> fileBaseOf(fn,1)
laurent@361:    'abcdef'
laurent@361:    """            
laurent@361:    pos = filename.rfind('.')             
laurent@361:    if pos > 0:
laurent@361:       filename = filename[:pos]
laurent@361:    if withPath:
laurent@361:       return filename
laurent@361:    else:
laurent@361:       return os.path.basename(filename)
laurent@361: # -----------------------------------------------------------------------------
laurent@361: # m k d i r ( )         -- Create a directory (and possibly the entire tree) --
laurent@361: # ^^^^^^^^^^^^^
laurent@361: # 
laurent@361: def mkdir(directory) :
laurent@361:    """Create a directory (and possibly the entire tree).
laurent@361: 
laurent@361:    The os.mkdir() will fail to create a directory if one of the
laurent@361:    directory in the specified path does not exist.  mkdir()
laurent@361:    solves this problem.  It creates every intermediate directory
laurent@361:    required to create the final path. Under Unix, the function 
laurent@361:    only supports forward slash separator, but under Windows and MacOS
laurent@361:    the function supports the forward slash and the OS separator (backslash
laurent@361:    under windows).
laurent@361:    """ 
laurent@361: 
laurent@361:    # translate the path separators
laurent@361:    directory = unixpath(directory)
laurent@361:    # build a list of all directory elements
laurent@361:    aList = filter(lambda x: len(x)>0, directory.split('/'))
laurent@361:    theLen = len(aList)                     
laurent@361:    # if the first element is a Windows-style disk drive
laurent@361:    # concatenate it with the first directory
laurent@361:    if aList[0].endswith(':'):
laurent@361:       if theLen > 1:
laurent@361:          aList[1] = aList[0] + '/' + aList[1]
laurent@361:          del aList[0]      
laurent@361:          theLen -= 1         
laurent@361:    # if the original directory starts at root,
laurent@361:    # make sure the first element of the list 
laurent@361:    # starts at root too
laurent@361:    if directory[0] == '/':     
laurent@361:       aList[0] = '/' + aList[0]
laurent@361:    # Now iterate through the list, check if the 
laurent@361:    # directory exists and if not create it
laurent@361:    theDir = ''
laurent@361:    for i in range(theLen):
laurent@361:       theDir += aList[i]
laurent@361:       if not os.path.exists(theDir):
laurent@361:          os.mkdir(theDir)
laurent@361:       theDir += '/'   
laurent@361:       
laurent@361: # -----------------------------------------------------------------------------
laurent@361: # u n i x p a t h ( )         -- Return a path name that contains Unix separator. --
laurent@361: # ^^^^^^^^^^^^^^^^^^^
laurent@361: # 
laurent@361: def unixpath(thePath) :
laurent@361:    r"""Return a path name that contains Unix separator.
laurent@361: 
laurent@361:    [Example]
laurent@361:    >>> unixpath(r"d:\test")
laurent@361:    'd:/test'
laurent@361:    >>> unixpath("d:/test/file.txt")
laurent@361:    'd:/test/file.txt'
laurent@361:    >>> 
laurent@361:    """
laurent@361:    thePath = os.path.normpath(thePath)
laurent@361:    if os.sep == '/':
laurent@361:       return thePath
laurent@361:    else:
laurent@361:       return thePath.replace(os.sep,'/')
laurent@361: 
laurent@361: # ----------------------------------------------------------------------------- 
laurent@361: 
laurent@361: # S c r i p t   e x e c u t i o n               -- Runs when invoked from the command line --
laurent@361: # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
laurent@361: # 
laurent@361: if __name__ == "__main__":
laurent@361:     import getopt     # command line parsing
laurent@361:     argc = len(sys.argv)
laurent@361:     if argc == 1:
laurent@361:         printUsage('Missing argument: specify at least one of -m or -p (or both).')
laurent@361:         sys.exit(1)
laurent@361:     # If there is some arguments, parse the command line
laurent@361:     validOptions     = "ehmpv"
laurent@361:     validLongOptions = ['domain=', 'moTarget=']             
laurent@361:     option = {}
laurent@361:     option['forceEnglish'] = 0
laurent@361:     option['mo'] = 0
laurent@361:     option['po'] = 0        
laurent@361:     option['verbose'] = 0
laurent@361:     option['domain'] = None
laurent@361:     option['moTarget'] = None
laurent@361:     try:
laurent@361:         optionList,pargs = getopt.getopt(sys.argv[1:],validOptions,validLongOptions)
laurent@361:     except getopt.GetoptError, e:
laurent@361:         printUsage(e[0])
laurent@361:         sys.exit(1)       
laurent@361:     for (opt,val) in optionList:
laurent@361:         if  (opt == '-h'):    
laurent@361:             printUsage()
laurent@361:             sys.exit(0) 
laurent@361:         elif (opt == '-e'):         option['forceEnglish'] = 1
laurent@361:         elif (opt == '-m'):         option['mo'] = 1
laurent@361:         elif (opt == '-p'):         option['po'] = 1
laurent@361:         elif (opt == '-v'):         option['verbose'] = 1
laurent@361:         elif (opt == '--domain'):   option['domain'] = val
laurent@361:         elif (opt == '--moTarget'): option['moTarget'] = val
laurent@361:     if len(pargs) == 0:
laurent@361:         appDirPath = os.getcwd()
laurent@361:         if option['verbose']:
laurent@361:             print "No project directory given. Using current one:  %s" % appDirPath
laurent@361:     elif len(pargs) == 1:
laurent@361:         appDirPath = pargs[0]
laurent@361:     else:
laurent@361:         printUsage('Too many arguments (%u).  Use double quotes if you have space in directory name' % len(pargs))
laurent@361:         sys.exit(1)
laurent@361:     if option['domain'] is None:
laurent@361:         # If no domain specified, use the name of the target directory
laurent@361:         option['domain'] = fileBaseOf(appDirPath)
laurent@361:     if option['verbose']:
laurent@361:         print "Application domain used is: '%s'" % option['domain']
laurent@361:     if option['po']:
laurent@361:         try:
laurent@361:             makePO(appDirPath,option['domain'],option['verbose'])
laurent@361:         except IOError, e:
laurent@361:             printUsage(e[1] + '\n   You must write a file app.fil that contains the list of all files to parse.')
laurent@361:     if option['mo']:
laurent@361:         makeMO(appDirPath,option['moTarget'],option['domain'],option['verbose'],option['forceEnglish'])
laurent@361:     sys.exit(1)            
laurent@361:             
laurent@361: 
laurent@361: # -----------------------------------------------------------------------------