Attachment 'mki18n.py'

Download

   1 #! /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 # 
   9 #   Copyright Pierre Rouleau. 2003. Released to public domain.
  10 # 
  11 #   Last update: Saturday, November 8, 2003. @ 15:55:18.
  12 # 
  13 #   File: ROUP2003N01::C:/dev/python/mki18n.py
  14 # 
  15 #   RCS $Header: //software/official/MKS/MKS_SI/TV_NT/dev/Python/rcs/mki18n.py 1.5 2003/11/05 19:40:04 PRouleau Exp $
  16 # 
  17 #   Update history:
  18 # 
  19 #   - File created: Saturday, June 7, 2003. by Pierre Rouleau
  20 #   - 10/06/03 rcs : RCS Revision 1.1  2003/06/10 10:06:12  PRouleau
  21 #   - 10/06/03 rcs : RCS Initial revision
  22 #   - 23/08/03 rcs : RCS Revision 1.2  2003/06/10 10:54:27  PRouleau
  23 #   - 23/08/03 P.R.: [code:fix] : The strings encoded in this file are encode in iso-8859-1 format.  Added the encoding
  24 #                    notification to Python to comply with Python's 2.3 PEP 263.
  25 #   - 23/08/03 P.R.: [feature:new] : Added the '-e' switch which is used to force the creation of the empty English .mo file.
  26 #   - 22/10/03 P.R.: [code] : incorporated utility functions in here to make script self sufficient.
  27 #   - 05/11/03 rcs : RCS Revision 1.4  2003/10/22 06:39:31  PRouleau
  28 #   - 05/11/03 P.R.: [code:fix] : included the unixpath() in this file.
  29 #   - 08/11/03 rcs : RCS Revision 1.5  2003/11/05 19:40:04  PRouleau
  30 # 
  31 #   RCS $Log: $
  32 # 
  33 # 
  34 # -----------------------------------------------------------------------------
  35 """                                
  36 mki18n allows you to internationalize your software.  You can use it to 
  37 create the GNU .po files (Portable Object) and the compiled .mo files
  38 (Machine Object).
  39 
  40 mki18n module can be used from the command line or from within a script (see 
  41 the Usage at the end of this page).
  42 
  43     Table of Contents
  44     -----------------
  45     
  46     makePO()             -- Build the Portable Object file for the application --
  47     catPO()              -- Concatenate one or several PO files with the application domain files. --
  48     makeMO()             -- Compile the Portable Object files into the Machine Object stored in the right location. --
  49     printUsage           -- Displays how to use this script from the command line --
  50 
  51     Scriptexecution      -- Runs when invoked from the command line --
  52 
  53 
  54 NOTE:  this module uses GNU gettext utilities.
  55 
  56 You can get the gettext tools from the following sites:
  57 
  58    - `GNU FTP site for gettetx`_ where several versions (0.10.40, 0.11.2, 0.11.5 and 0.12.1) are available.
  59      Note  that you need to use `GNU libiconv`_ to use this. Get it from the `GNU
  60      libiconv  ftp site`_ and get version 1.9.1 or later. Get the Windows .ZIP
  61      files and install the packages inside c:/gnu. All binaries will be stored
  62      inside  c:/gnu/bin.  Just  put c:/gnu/bin inside your PATH. You will need
  63      the following files: 
  64 
  65       - `gettext-runtime-0.12.1.bin.woe32.zip`_ 
  66       - `gettext-tools-0.12.1.bin.woe32.zip`_
  67       - `libiconv-1.9.1.bin.woe32.zip`_ 
  68 
  69 
  70 .. _GNU libiconv:                            http://www.gnu.org/software/libiconv/
  71 .. _GNU libiconv ftp site:                   http://www.ibiblio.org/pub/gnu/libiconv/
  72 .. _gettext-runtime-0.12.1.bin.woe32.zip:    ftp://ftp.gnu.org/gnu/gettext/gettext-runtime-0.12.1.bin.woe32.zip           
  73 .. _gettext-tools-0.12.1.bin.woe32.zip:      ftp://ftp.gnu.org/gnu/gettext/gettext-tools-0.12.1.bin.woe32.zip 
  74 .. _libiconv-1.9.1.bin.woe32.zip:            http://www.ibiblio.org/pub/gnu/libiconv/libiconv-1.9.1.bin.woe32.zip
  75 
  76 """
  77 # -----------------------------------------------------------------------------
  78 # Module Import
  79 # -------------
  80 # 
  81 import os
  82 import sys
  83 # -----------------------------------------------------------------------------
  84 # Global variables
  85 # ----------------
  86 # 
  87 
  88 __author__ = "Pierre Rouleau"
  89 __version__= "$Revision: 1.5 $"
  90 
  91 # -----------------------------------------------------------------------------
  92 # Public variables
  93 # ----------------
  94 # 
  95                     # iso639    : natural
  96                     # 2-letter  : language
  97                     # code      : name
  98 iso639_languageDict = { 'aa'    : 'Afar. ',
  99                         'ab'    : 'Abkhazian. ',
 100                         'ae'    : 'Avestan. ',
 101                         'af'    : 'Afrikaans. ',
 102                         'am'    : 'Amharic. ',
 103                         'ar'    : 'Arabic. ',
 104                         'as'    : 'Assamese. ',
 105                         'ay'    : 'Aymara. ',
 106                         'az'    : 'Azerbaijani. ',
 107                         'ba'    : 'Bashkir. ',
 108                         'be'    : 'Byelorussian; Belarusian. ',
 109                         'bg'    : 'Bulgarian. ',
 110                         'bh'    : 'Bihari. ',
 111                         'bi'    : 'Bislama. ',
 112                         'bn'    : 'Bengali; Bangla. ',
 113                         'bo'    : 'Tibetan. ',
 114                         'br'    : 'Breton. ',
 115                         'bs'    : 'Bosnian. ',
 116                         'ca'    : 'Catalan. ',
 117                         'ce'    : 'Chechen. ',
 118                         'ch'    : 'Chamorro. ',
 119                         'co'    : 'Corsican. ',
 120                         'cs'    : 'Czech. ',
 121                         'cu'    : 'Church Slavic. ',
 122                         'cv'    : 'Chuvash. ',
 123                         'cy'    : 'Welsh. ',
 124                         'da'    : 'Danish. ',
 125                         'de'    : 'German. ',
 126                         'dz'    : 'Dzongkha; Bhutani. ',
 127                         'el'    : 'Greek. ',
 128                         'en'    : 'English. ',
 129                         'eo'    : 'Esperanto. ',
 130                         'es'    : 'Spanish. ',
 131                         'et'    : 'Estonian. ',
 132                         'eu'    : 'Basque. ',
 133                         'fa'    : 'Persian. ',
 134                         'fi'    : 'Finnish. ',
 135                         'fj'    : 'Fijian; Fiji. ',
 136                         'fo'    : 'Faroese. ',
 137                         'fr'    : 'French. ',
 138                         'fy'    : 'Frisian. ',
 139                         'ga'    : 'Irish. ',
 140                         'gd'    : 'Scots; Gaelic. ',
 141                         'gl'    : 'Gallegan; Galician. ',
 142                         'gn'    : 'Guarani. ',
 143                         'gu'    : 'Gujarati. ',
 144                         'gv'    : 'Manx. ',
 145                         'ha'    : 'Hausa (?). ',
 146                         'he'    : 'Hebrew (formerly iw). ',
 147                         'hi'    : 'Hindi. ',
 148                         'ho'    : 'Hiri Motu. ',
 149                         'hr'    : 'Croatian. ',
 150                         'hu'    : 'Hungarian. ',
 151                         'hy'    : 'Armenian. ',
 152                         'hz'    : 'Herero. ',
 153                         'ia'    : 'Interlingua. ',
 154                         'id'    : 'Indonesian (formerly in). ',
 155                         'ie'    : 'Interlingue. ',
 156                         'ik'    : 'Inupiak. ',
 157                         'io'    : 'Ido. ',
 158                         'is'    : 'Icelandic. ',
 159                         'it'    : 'Italian. ',
 160                         'iu'    : 'Inuktitut. ',
 161                         'ja'    : 'Japanese. ',
 162                         'jv'    : 'Javanese. ',
 163                         'ka'    : 'Georgian. ',
 164                         'ki'    : 'Kikuyu. ',
 165                         'kj'    : 'Kuanyama. ',
 166                         'kk'    : 'Kazakh. ',
 167                         'kl'    : 'Kalaallisut; Greenlandic. ',
 168                         'km'    : 'Khmer; Cambodian. ',
 169                         'kn'    : 'Kannada. ',
 170                         'ko'    : 'Korean. ',
 171                         'ks'    : 'Kashmiri. ',
 172                         'ku'    : 'Kurdish. ',
 173                         'kv'    : 'Komi. ',
 174                         'kw'    : 'Cornish. ',
 175                         'ky'    : 'Kirghiz. ',
 176                         'la'    : 'Latin. ',
 177                         'lb'    : 'Letzeburgesch. ',
 178                         'ln'    : 'Lingala. ',
 179                         'lo'    : 'Lao; Laotian. ',
 180                         'lt'    : 'Lithuanian. ',
 181                         'lv'    : 'Latvian; Lettish. ',
 182                         'mg'    : 'Malagasy. ',
 183                         'mh'    : 'Marshall. ',
 184                         'mi'    : 'Maori. ',
 185                         'mk'    : 'Macedonian. ',
 186                         'ml'    : 'Malayalam. ',
 187                         'mn'    : 'Mongolian. ',
 188                         'mo'    : 'Moldavian. ',
 189                         'mr'    : 'Marathi. ',
 190                         'ms'    : 'Malay. ',
 191                         'mt'    : 'Maltese. ',
 192                         'my'    : 'Burmese. ',
 193                         'na'    : 'Nauru. ',
 194                         'nb'    : 'Norwegian Bokmål. ',
 195                         'nd'    : 'Ndebele, North. ',
 196                         'ne'    : 'Nepali. ',
 197                         'ng'    : 'Ndonga. ',
 198                         'nl'    : 'Dutch. ',
 199                         'nn'    : 'Norwegian Nynorsk. ',
 200                         'no'    : 'Norwegian. ',
 201                         'nr'    : 'Ndebele, South. ',
 202                         'nv'    : 'Navajo. ',
 203                         'ny'    : 'Chichewa; Nyanja. ',
 204                         'oc'    : 'Occitan; Provençal. ',
 205                         'om'    : '(Afan) Oromo. ',
 206                         'or'    : 'Oriya. ',
 207                         'os'    : 'Ossetian; Ossetic. ',
 208                         'pa'    : 'Panjabi; Punjabi. ',
 209                         'pi'    : 'Pali. ',
 210                         'pl'    : 'Polish. ',
 211                         'ps'    : 'Pashto, Pushto. ',
 212                         'pt'    : 'Portuguese. ',
 213                         'qu'    : 'Quechua. ',
 214                         'rm'    : 'Rhaeto-Romance. ',
 215                         'rn'    : 'Rundi; Kirundi. ',
 216                         'ro'    : 'Romanian. ',
 217                         'ru'    : 'Russian. ',
 218                         'rw'    : 'Kinyarwanda. ',
 219                         'sa'    : 'Sanskrit. ',
 220                         'sc'    : 'Sardinian. ',
 221                         'sd'    : 'Sindhi. ',
 222                         'se'    : 'Northern Sami. ',
 223                         'sg'    : 'Sango; Sangro. ',
 224                         'si'    : 'Sinhalese. ',
 225                         'sk'    : 'Slovak. ',
 226                         'sl'    : 'Slovenian. ',
 227                         'sm'    : 'Samoan. ',
 228                         'sn'    : 'Shona. ',
 229                         'so'    : 'Somali. ',
 230                         'sq'    : 'Albanian. ',
 231                         'sr'    : 'Serbian. ',
 232                         'ss'    : 'Swati; Siswati. ',
 233                         'st'    : 'Sesotho; Sotho, Southern. ',
 234                         'su'    : 'Sundanese. ',
 235                         'sv'    : 'Swedish. ',
 236                         'sw'    : 'Swahili. ',
 237                         'ta'    : 'Tamil. ',
 238                         'te'    : 'Telugu. ',
 239                         'tg'    : 'Tajik. ',
 240                         'th'    : 'Thai. ',
 241                         'ti'    : 'Tigrinya. ',
 242                         'tk'    : 'Turkmen. ',
 243                         'tl'    : 'Tagalog. ',
 244                         'tn'    : 'Tswana; Setswana. ',
 245                         'to'    : 'Tonga (?). ',
 246                         'tr'    : 'Turkish. ',
 247                         'ts'    : 'Tsonga. ',
 248                         'tt'    : 'Tatar. ',
 249                         'tw'    : 'Twi. ',
 250                         'ty'    : 'Tahitian. ',
 251                         'ug'    : 'Uighur. ',
 252                         'uk'    : 'Ukrainian. ',
 253                         'ur'    : 'Urdu. ',
 254                         'uz'    : 'Uzbek. ',
 255                         'vi'    : 'Vietnamese. ',
 256                         'vo'    : 'Volapük; Volapuk. ',
 257                         'wa'    : 'Walloon. ',
 258                         'wo'    : 'Wolof. ',
 259                         'xh'    : 'Xhosa. ',
 260                         'yi'    : 'Yiddish (formerly ji). ',
 261                         'yo'    : 'Yoruba. ',
 262                         'za'    : 'Zhuang. ',
 263                         'zh'    : 'Chinese. ',
 264                         'zu'    : 'Zulu.'
 265                      }
 266 
 267 
 268 # -----------------------------------------------------------------------------
 269 # m a k e P O ( )         -- Build the Portable Object file for the application --
 270 # ^^^^^^^^^^^^^^^
 271 # 
 272 def makePO(applicationDirectoryPath,  applicationDomain=None, verbose=0) :
 273     """Build the Portable Object Template file for the application.
 274 
 275     makePO builds the .pot file for the application stored inside 
 276     a specified directory by running xgettext for all application source 
 277     files.  It finds the name of all files by looking for a file called 'app.fil'. 
 278     If this file does not exists, makePo raises an IOError exception.
 279     By default the application domain (the application
 280     name) is the same as the directory name but it can be overridden by the 
 281     'applicationDomain' argument.
 282 
 283     makePO always creates a new file called messages.pot.  If it finds files 
 284     of the form app_xx.po where 'app' is the application name and 'xx' is one 
 285     of the ISO 639 two-letter language codes, makePO resynchronizes those 
 286     files with the latest extracted strings (now contained in messages.pot). 
 287     This process updates all line location number in the language-specific
 288     .po files and may also create new entries for translation (or comment out 
 289     some).  The .po file is not changed, instead a new file is created with 
 290     the .new extension appended to the name of the .po file.
 291 
 292     By default the function does not display what it is doing.  Set the 
 293     verbose argument to 1 to force it to print its commands.
 294     """
 295 
 296     if applicationDomain is None:
 297         applicationName = fileBaseOf(applicationDirectoryPath,withPath=0)
 298     else:
 299         applicationName = applicationDomain
 300     currentDir = os.getcwd()
 301     os.chdir(applicationDirectoryPath)                    
 302     if not os.path.exists('app.fil'):
 303         raise IOError(2,'No module file: app.fil')
 304 
 305     # Steps:                                  
 306     #  Use xgettext to parse all application modules
 307     #  The following switches are used:
 308     #  
 309     #   -s                          : sort output by string content (easier to use when we need to merge several .po files)
 310     #   --files-from=app.fil        : The list of files is taken from the file: app.fil
 311     #   --output=                   : specifies the name of the output file (using a .pot extension)
 312     cmd = 'xgettext -s --no-wrap --files-from=app.fil --output=messages.pot'
 313     if verbose: print cmd
 314     os.system(cmd)                                                
 315 
 316     for langCode in iso639_languageDict.keys():
 317         if langCode == 'en':
 318             pass
 319         else:
 320             langPOfileName = "%s_%s.po" % (applicationName , langCode)
 321             if os.path.exists(langPOfileName):
 322                 cmd = "msgmerge -s --no-wrap %s messages.pot > %s.new" % (langPOfileName, langPOfileName)
 323                 if verbose: print cmd
 324                 os.system(cmd)
 325     os.chdir(currentDir)
 326 
 327 # -----------------------------------------------------------------------------
 328 # c a t P O ( )         -- Concatenate one or several PO files with the application domain files. --
 329 # ^^^^^^^^^^^^^
 330 # 
 331 def catPO(applicationDirectoryPath, listOf_extraPo, applicationDomain=None, targetDir=None, verbose=0) :
 332     """Concatenate one or several PO files with the application domain files.
 333     """
 334 
 335     if applicationDomain is None:
 336         applicationName = fileBaseOf(applicationDirectoryPath,withPath=0)
 337     else:
 338         applicationName = applicationDomain
 339     currentDir = os.getcwd()
 340     os.chdir(applicationDirectoryPath)                    
 341 
 342     for langCode in iso639_languageDict.keys():
 343         if langCode == 'en':
 344             pass
 345         else:
 346             langPOfileName = "%s_%s.po" % (applicationName , langCode)
 347             if os.path.exists(langPOfileName):                  
 348                 fileList = ''
 349                 for fileName in listOf_extraPo:
 350                     fileList += ("%s_%s.po " % (fileName,langCode))
 351                 cmd = "msgcat -s --no-wrap %s %s > %s.cat" % (langPOfileName, fileList, langPOfileName)
 352                 if verbose: print cmd
 353                 os.system(cmd)
 354                 if targetDir is None:
 355                     pass
 356                 else:
 357                     mo_targetDir = "%s/%s/LC_MESSAGES" % (targetDir,langCode)                      
 358                     cmd = "msgfmt --output-file=%s/%s.mo %s_%s.po.cat" % (mo_targetDir,applicationName,applicationName,langCode)
 359                     if verbose: print cmd
 360                     os.system(cmd)
 361     os.chdir(currentDir)
 362 
 363 # -----------------------------------------------------------------------------
 364 # m a k e M O ( )         -- Compile the Portable Object files into the Machine Object stored in the right location. --
 365 # ^^^^^^^^^^^^^^^
 366 # 
 367 def makeMO(applicationDirectoryPath,targetDir='./locale',applicationDomain=None, verbose=0, forceEnglish=0) :
 368     """Compile the Portable Object files into the Machine Object stored in the right location.
 369 
 370     makeMO converts all translated language-specific PO files located inside 
 371     the  application directory into the binary .MO files stored inside the 
 372     LC_MESSAGES sub-directory for the found locale files.
 373 
 374     makeMO searches for all files that have a name of the form 'app_xx.po' 
 375     inside the application directory specified by the first argument.  The 
 376     'app' is the application domain name (that can be specified by the 
 377     applicationDomain argument or is taken from the directory name). The 'xx' 
 378     corresponds to one of the ISO 639 two-letter language codes.
 379 
 380     makeMo stores the resulting files inside a sub-directory of `targetDir` 
 381     called xx/LC_MESSAGES where 'xx' corresponds to the 2-letter language 
 382     code.
 383     """                       
 384     if targetDir is None:
 385         targetDir = './locale'
 386     if verbose:
 387         print "Target directory for .mo files is: %s" % targetDir
 388             
 389     if applicationDomain is None:
 390         applicationName = fileBaseOf(applicationDirectoryPath,withPath=0)
 391     else:
 392         applicationName = applicationDomain
 393     currentDir = os.getcwd()
 394     os.chdir(applicationDirectoryPath)                    
 395     
 396     for langCode in iso639_languageDict.keys():
 397         if (langCode == 'en') and (forceEnglish==0):
 398             pass
 399         else:
 400             langPOfileName = "%s_%s.po" % (applicationName , langCode)
 401             if os.path.exists(langPOfileName):
 402                 mo_targetDir = "%s/%s/LC_MESSAGES" % (targetDir,langCode)                      
 403                 if not os.path.exists(mo_targetDir):
 404                     mkdir(mo_targetDir)
 405                 cmd = "msgfmt --output-file=%s/%s.mo %s_%s.po" % (mo_targetDir,applicationName,applicationName,langCode)
 406                 if verbose: print cmd
 407                 os.system(cmd)
 408     os.chdir(currentDir)
 409    
 410 # -----------------------------------------------------------------------------
 411 # p r i n t U s a g e         -- Displays how to use this script from the command line --
 412 # ^^^^^^^^^^^^^^^^^^^
 413 #
 414 def printUsage(errorMsg=None) :
 415     """Displays how to use this script from the command line."""
 416     print """
 417     ##################################################################################
 418     #   mki18n :   Make internationalization files.                                  #
 419     #              Uses the GNU gettext system to create PO (Portable Object) files  #
 420     #              from source code, coimpile PO into MO (Machine Object) files.     #        
 421     #              Supports C,C++,Python source files.                               #
 422     #                                                                                #
 423     #   Usage: mki18n {OPTION} [appDirPath]                                          #
 424     #                                                                                #
 425     #   Options:                                                                     #
 426     #     -e               : When -m is used, forces English .mo file creation       #
 427     #     -h               : prints this help                                        #
 428     #     -m               : make MO from existing PO files                          #
 429     #     -p               : make PO, update PO files: Creates a new messages.pot    #
 430     #                        file. Creates a dom_xx.po.new for every existing        #
 431     #                        language specific .po file. ('xx' stands for the ISO639 #
 432     #                        two-letter language code and 'dom' stands for the       #
 433     #                        application domain name).  mki18n requires that you     #
 434     #                        write a 'app.fil' file  which contains the list of all  #
 435     #                        source code to parse.                                   #
 436     #     -v               : verbose (prints comments while running)                 #
 437     #     --domain=appName : specifies the application domain name.  By default      #
 438     #                        the directory name is used.                             #
 439     #     --moTarget=dir : specifies the directory where .mo files are stored.       #
 440     #                      If not specified, the target is './locale'                #
 441     #                                                                                #
 442     #   You must specify one of the -p or -m option to perform the work.  You can    #
 443     #   specify the path of the target application.  If you leave it out mki18n      #
 444     #   will use the current directory as the application main directory.            #        
 445     #                                                                                #
 446     ##################################################################################"""
 447     if errorMsg:
 448         print "\n   ERROR: %s" % errorMsg
 449 
 450 # -----------------------------------------------------------------------------
 451 # f i l e B a s e O f ( )         -- Return base name of filename --
 452 # ^^^^^^^^^^^^^^^^^^^^^^^
 453 # 
 454 def fileBaseOf(filename,withPath=0) :
 455    """fileBaseOf(filename,withPath) ---> string
 456 
 457    Return base name of filename.  The returned string never includes the extension.
 458    Use os.path.basename() to return the basename with the extension.  The 
 459    second argument is optional.  If specified and if set to 'true' (non zero) 
 460    the string returned contains the full path of the file name.  Otherwise the 
 461    path is excluded.
 462 
 463    [Example]
 464    >>> fn = 'd:/dev/telepath/tvapp/code/test.html'
 465    >>> fileBaseOf(fn)
 466    'test'
 467    >>> fileBaseOf(fn)
 468    'test'
 469    >>> fileBaseOf(fn,1)
 470    'd:/dev/telepath/tvapp/code/test'
 471    >>> fileBaseOf(fn,0)
 472    'test'
 473    >>> fn = 'abcdef'
 474    >>> fileBaseOf(fn)
 475    'abcdef'
 476    >>> fileBaseOf(fn,1)
 477    'abcdef'
 478    >>> fn = "abcdef."
 479    >>> fileBaseOf(fn)
 480    'abcdef'
 481    >>> fileBaseOf(fn,1)
 482    'abcdef'
 483    """            
 484    pos = filename.rfind('.')             
 485    if pos > 0:
 486       filename = filename[:pos]
 487    if withPath:
 488       return filename
 489    else:
 490       return os.path.basename(filename)
 491 # -----------------------------------------------------------------------------
 492 # m k d i r ( )         -- Create a directory (and possibly the entire tree) --
 493 # ^^^^^^^^^^^^^
 494 # 
 495 def mkdir(directory) :
 496    """Create a directory (and possibly the entire tree).
 497 
 498    The os.mkdir() will fail to create a directory if one of the 
 499    directory in the specified path does not exist.  mkdir()
 500    solves this problem.  It creates every intermediate directory
 501    required to create the final path. Under Unix, the function 
 502    only supports forward slash separator, but under Windows and MacOS
 503    the function supports the forward slash and the OS separator (backslash
 504    under windows).
 505    """ 
 506 
 507    # translate the path separators
 508    directory = unixpath(directory)
 509    # build a list of all directory elements
 510    aList = filter(lambda x: len(x)>0, directory.split('/'))
 511    theLen = len(aList)                     
 512    # if the first element is a Windows-style disk drive
 513    # concatenate it with the first directory
 514    if aList[0].endswith(':'):
 515       if theLen > 1:
 516          aList[1] = aList[0] + '/' + aList[1]
 517          del aList[0]      
 518          theLen -= 1         
 519    # if the original directory starts at root,
 520    # make sure the first element of the list 
 521    # starts at root too
 522    if directory[0] == '/':     
 523       aList[0] = '/' + aList[0]
 524    # Now iterate through the list, check if the 
 525    # directory exists and if not create it
 526    theDir = ''
 527    for i in range(theLen):
 528       theDir += aList[i]
 529       if not os.path.exists(theDir):
 530          os.mkdir(theDir)
 531       theDir += '/'   
 532       
 533 # -----------------------------------------------------------------------------
 534 # u n i x p a t h ( )         -- Return a path name that contains Unix separator. --
 535 # ^^^^^^^^^^^^^^^^^^^
 536 # 
 537 def unixpath(thePath) :
 538    r"""Return a path name that contains Unix separator.
 539 
 540    [Example]
 541    >>> unixpath(r"d:\test")
 542    'd:/test'
 543    >>> unixpath("d:/test/file.txt")
 544    'd:/test/file.txt'
 545    >>> 
 546    """
 547    thePath = os.path.normpath(thePath)
 548    if os.sep == '/':
 549       return thePath
 550    else:
 551       return thePath.replace(os.sep,'/')
 552 
 553 # ----------------------------------------------------------------------------- 
 554 
 555 # S c r i p t   e x e c u t i o n               -- Runs when invoked from the command line --
 556 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 557 # 
 558 if __name__ == "__main__":
 559     import getopt     # command line parsing
 560     argc = len(sys.argv)
 561     if argc == 1:
 562         printUsage('Missing argument: specify at least one of -m or -p (or both).')
 563         sys.exit(1)
 564     # If there is some arguments, parse the command line
 565     validOptions     = "ehmpv"
 566     validLongOptions = ['domain=', 'moTarget=']             
 567     option = {}
 568     option['forceEnglish'] = 0
 569     option['mo'] = 0
 570     option['po'] = 0        
 571     option['verbose'] = 0
 572     option['domain'] = None
 573     option['moTarget'] = None
 574     try:
 575         optionList,pargs = getopt.getopt(sys.argv[1:],validOptions,validLongOptions)
 576     except getopt.GetoptError, e:
 577         printUsage(e[0])   
 578         sys.exit(1)       
 579     for (opt,val) in optionList:
 580         if  (opt == '-h'):    
 581             printUsage()
 582             sys.exit(0) 
 583         elif (opt == '-e'):         option['forceEnglish'] = 1
 584         elif (opt == '-m'):         option['mo'] = 1
 585         elif (opt == '-p'):         option['po'] = 1
 586         elif (opt == '-v'):         option['verbose'] = 1
 587         elif (opt == '--domain'):   option['domain'] = val
 588         elif (opt == '--moTarget'): option['moTarget'] = val
 589     if len(pargs) == 0:         
 590         appDirPath = os.getcwd()                     
 591         if option['verbose']:
 592             print "No project directory given. Using current one:  %s" % appDirPath
 593     elif len(pargs) == 1:
 594         appDirPath = pargs[0]
 595     else:
 596         printUsage('Too many arguments (%u).  Use double quotes if you have space in directory name' % len(pargs))
 597         sys.exit(1)
 598     if option['domain'] is None:
 599         # If no domain specified, use the name of the target directory
 600         option['domain'] = fileBaseOf(appDirPath)
 601     if option['verbose']:
 602         print "Application domain used is: '%s'" % option['domain']        
 603     if option['po']:
 604         try:
 605             makePO(appDirPath,option['domain'],option['verbose'])
 606         except IOError, e:
 607             printUsage(e[1] + '\n   You must write a file app.fil that contains the list of all files to parse.')
 608     if option['mo']:
 609         makeMO(appDirPath,option['moTarget'],option['domain'],option['verbose'],option['forceEnglish'])
 610     sys.exit(1)            
 611             
 612 
 613 # -----------------------------------------------------------------------------

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2009-10-04 09:16:03, 27.9 KB) [[attachment:mki18n.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.