Commits

David Keegan committed b44eeec

*adding a header to Localize.py so it can be moved to other projects
*adding --utf8 flag to Localize.py which, if present, will convert the resulting .strings files to utf-8
*converted .strings files to utf-8
*updated 'Translate' script to specify utf-8

Comments (0)

Files changed (11)

English.lproj/MainMenu.strings

File contents unchanged.

English.lproj/Projects.strings

File contents unchanged.

English.lproj/Repo.strings

File contents unchanged.

French.lproj/MainMenu.strings

File contents unchanged.

French.lproj/Projects.strings

File contents unchanged.

French.lproj/Repo.strings

File contents unchanged.

German.lproj/MainMenu.strings

File contents unchanged.

German.lproj/Projects.strings

File contents unchanged.

German.lproj/Repo.strings

File contents unchanged.
 #!/usr/bin/python
+
+'''
+Wraps the ibtool commandline to generate nibs from .strings files.
+An md5 checksum of the base nibs is stored in a Localize.json file,
+if a checksum for the file does not exist or the check does not match
+a new localized nib is created.
+
+Based on Philippe Casgrain's technique for localizing nibs at build
+    http://developer.casgrain.com/?p=94
+
+Written by David Keegan for Murky
+    http://bitbucket.org/snej/murky
+
+Usage: 
+    Localize.py [options]
+
+    Options:
+      -h, --help            show this help message and exit
+      -f LANG, --from=LANG  the language to localize from
+      -t LANGS, --to=LANGS  an array of languages to localize to, separated by '|'
+      -n NIBS, --nibs=NIBS  an array of nibs to localize, separated by '|', .xib
+                            can be left off
+      -u, --utf8            if this flag is present the .strings files will be re-
+                            encoded as utf-8
+      -i, --ignore          if this flag is present the md5 checksums will be
+                            ignored
+                            
+The MIT License
+
+Copyright David Keegan 2009-1010
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+'''
+
 import time
+import codecs
 import os, sys
 import subprocess
 from optparse import OptionParser
     #python2.5
     import simplejson as json
 
+def detectEncoding(filepath):
+    '''
+    Try to detect the file's encoding.
+    If its not utf-16 assume it's utf-8, this should work for ascii
+    files becuase the first 128 characters are the same...
+    '''
+    
+    f = open(filepath, 'r')
+    firstBytes = f.read(2)
+    f.close()
+    
+    if firstBytes == codecs.BOM_UTF16_BE:
+        return 'utf_16_be'
+    elif firstBytes == codecs.BOM_UTF16_LE:
+        return 'utf_16_le'
+    #use sig just encase there is a BOM in the file
+    return 'utf_8_sig'
+
+def fileToUtf8(stringFile):
+    '''
+    Convert the .strings file from utf-16 to utf-8
+    This will allow files diffs
+    '''
+    tempStrings = stringFile+'temp'
+    stringsEncoding = detectEncoding(stringFile)
+    #if the file is not already utf-8 re-encode it
+    if stringsEncoding != 'utf_8_sig':
+        fromFile = codecs.open(stringFile, 'r', stringsEncoding)
+        toFile = codecs.open(tempStrings, 'w', 'utf_8')
+        for eachLine in fromFile:
+            toFile.write(eachLine)
+        
+        toFile.close()            
+        fromFile.close()
+        
+        os.remove(stringFile)
+        os.rename(tempStrings, stringFile)
+        
 def runCommand(command, args):
-    '''run shell commands'''
+    '''Run shell commands'''
     commandAndArgs = '%s %s' % (command, args)
     proc = subprocess.Popen(commandAndArgs, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     stdout, stderr = proc.communicate()
     return stdout
  
 def md5(file):
-    '''get the md5 checksum of a file'''
+    '''Get the md5 checksum of a file'''
     md5Sum = runCommand('/usr/bin/openssl md5', file)
     return md5Sum.split('=')[1].strip()
     
-def generateStringsFile(nibFile):
-    '''generate a .strings file from a nib'''
+def generateStringsFile(nibFile, utf8=False):
+    '''
+    Generate a .strings file from a nib
+    If utf8 is True the .strings files will be re-encoded as utf-8
+    '''
     nibFileStrings = nibFile.rstrip('.xib')+'.strings'
+    runCommand('ibtool', '--generate-strings-file %s %s' % (nibFileStrings, nibFile))
+    
+    if utf8:
+        fileToUtf8(nibFileStrings)
+    
     print '  ', nibFileStrings, 'updated'
-    return runCommand('ibtool', '--generate-strings-file %s %s' % (nibFileStrings, nibFile))
     
-def writeNib(fromFile, toFile):
+def writeNib(fromFile, toFile, utf8=False):
     '''convert one localized nib from one language to another'''
     toStrings = toFile.rstrip('.xib')+'.strings'
+    runCommand('ibtool', '--strings-file %s --write %s %s' % (toStrings, toFile, fromFile))
+    
+    if utf8:
+        fileToUtf8(toStrings)
+    
     print '  ', toFile, 'updated'
-    return runCommand('ibtool', '--strings-file %s --write %s %s' % (toStrings, toFile, fromFile))
  
-def localizeNibs(fromLang, toLangs, nibs):
+def localizeNibs(fromLang, toLangs, nibs, utf8=False, ignore=False):
     '''Localize nibs from one language to others'''
     
     #get the data from the json file
     localizeJson = os.path.abspath('Localize.json')
-    if os.path.isfile(localizeJson):
+    if not(ignore) and os.path.isfile(localizeJson):
         localizeData = open(localizeJson, 'r')
         jsonData = json.load(localizeData)
         localizeData.close()
         
     fromLangLproj = fromLang+'.lproj'
     for eachNib in nibs:
-        fromNib = os.path.join(fromLangLproj, eachNib+'.xib')
+        eachNib = eachNib.strip()
+        if not(eachNib.endswith('.xib')):
+            eachNib += '.xib'
+        fromNib = os.path.join(fromLangLproj, eachNib)
         #if the fromFile is not in the jsonData or the md5 is different
         fromNibMd5 = md5(fromNib)
         if not(fromNib in jsonData) or jsonData[fromNib] != fromNibMd5:
             for eachToLang in toLangs:
-                toLangLproj = eachToLang+'.lproj'
+                toLangLproj = eachToLang.strip()+'.lproj'
                 toNib =  os.path.join(toLangLproj, eachNib+'.xib')
-                generateStringsFile(fromNib)
-                writeNib(fromNib, toNib)
+                generateStringsFile(fromNib, utf8)
+                writeNib(fromNib, toNib, utf8)
                 jsonData[fromNib] = fromNibMd5
             
     #update Localize.json
     
     opts = OptionParser()
     opts.add_option('--from', '-f', dest='fromLang', help='the language to localize from', metavar='LANG')
-    opts.add_option('--to', '-t', dest='toLangs', help='the languages to localize to', metavar='LANG')
-    opts.add_option('--nibs', '-n', dest='nibs', help='the nibs to localize', metavar='LANG')
+    opts.add_option('--to', '-t', dest='toLangs', help="an array of languages to localize to, separated by '|'", metavar='LANGS')
+    opts.add_option('--nibs', '-n', dest='nibs', help="an array of nibs to localize, separated by '|', .xib can be left off", metavar='NIBS')
+    opts.add_option('--utf8', '-u', dest='utf8', help='if this flag is present the .strings files will be re-encoded as utf-8', action="store_true", default=False)
+    opts.add_option('--ignore', '-i', dest='ignore', help='if this flag is present the md5 checksums will be ignored', action="store_true", default=False)
     options, arguments = opts.parse_args()
     
-    localizeNibs(options.fromLang, options.toLangs.split('|'), options.nibs.split('|'))
-    
+    localizeNibs(options.fromLang, options.toLangs.split('|'), options.nibs.split('|'), options.utf8, options.ignore)
     print 'Nibs updated in %.2f seconds' % (time.time()-startTime)

Murky.xcodeproj/project.pbxproj

 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "# Localize nibs\n${SRCROOT}/Localize.py --from English --to \"French|German\" --nibs \"MainMenu|Projects|Repo\"\n";
+			shellScript = "# Localize nibs\n${SRCROOT}/Localize.py --from English --to \"French|German\" --nibs \"MainMenu|Projects|Repo\" --utf8\n";
 		};
 /* End PBXShellScriptBuildPhase section */