Smarter error handling in Dojo i18n script
[working/Evergreen.git] / build / i18n / scripts / dojo_resource.py
index 604b402..d33f655 100755 (executable)
@@ -7,8 +7,8 @@ Requires polib from http://polib.googlecode.com
 
 Source event definitions are structured as follows:
 {
-    MSG_ID1: "This is a message with 1 variable - ${0}.",
-    MSG_ID2: "This is a message with two variables: ${0} and ${1}."
+    "MSG_ID1": "This is a message with 1 variable - ${0}.",
+    "MSG_ID2": "This is a message with two variables: ${0} and ${1}."
 }
 
 Note that this is a deliberately limited subset of the variable substitution
@@ -28,12 +28,14 @@ allowed by http://api.dojotoolkit.org/jsdoc/dojo/1.2/dojo.string.substitute
 # GNU General Public License for more details.
 
 import basel10n
+import codecs
 import optparse
 import polib
 import re
 import sys
 import simplejson
 import os.path
+import os
 
 class DojoResource (basel10n.BaseL10N):
     """
@@ -53,14 +55,27 @@ class DojoResource (basel10n.BaseL10N):
         Extracts translatable strings from Evergreen's Dojo resource bundles.
         """
         self.pothead()
-        
-        bundle = simplejson.load(open(source, 'r'))
+
+        # Avoid generating duplicate entries by keeping track of msgids
+        msgids = dict()
+
+       try:
+            bundle = simplejson.load(codecs.open(source, encoding='utf-8', mode='r'))
+       except ValueError:
+           print("Reading Dojo resource file %s" % (source))
+            raise
 
         for key, value in bundle.iteritems():
-            poe = polib.POEntry()
-            poe.occurrences = [(os.path.basename(source), key)]
-            poe.msgid = value
-            poe.msgstr = value
+            if value in msgids:
+                msgids[str(value)].occurrences.append((os.path.basename(source), str(key)))
+            else:
+                poe = polib.POEntry()
+                poe.occurrences = [(os.path.basename(source), str(key))]
+                poe.msgid = str(value)
+                msgids[str(value)] = poe
+
+        # Now add the POEntries to our POFile
+        for poe in msgids.values():
             self.pot.append(poe)
 
     def create_bundle(self):
@@ -68,10 +83,11 @@ class DojoResource (basel10n.BaseL10N):
         Creates a Dojo resource bundle file based on a translated PO file.
         """
 
-        msg = "\t\"%s\": \"%s\""
-
         for entry in self.pot:
-            for filename, msgkey in entry.occurrences:
+            for occurrence in entry.occurrences:
+                # Ack. Horrible hack because polib started insisting
+                # that occurrences use integers for line numbers. The nerve!
+                filename, msgkey = occurrence[0].split('.js');
                 if entry.msgstr == '':
                     # No translation available; use the en-US definition
                     self.msgs[msgkey] = entry.msgid
@@ -99,6 +115,8 @@ def main():
     if options.pot:
         pot.get_strings(options.pot)
         if options.outfile:
+            if not os.path.exists(options.outfile):
+                os.makedirs(os.path.dirname(options.outfile))
             pot.savepot(options.outfile)
         else:
             sys.stdout.write(pot.pot.__str__())
@@ -108,7 +126,9 @@ def main():
         pot.loadpo(options.create)
         pot.create_bundle()
         if options.outfile:
-            outfile = open(options.outfile, 'w')
+            if not os.path.exists(options.outfile):
+                os.makedirs(os.path.dirname(options.outfile))
+            outfile = codecs.open(options.outfile, encoding='utf-8', mode='w')
             simplejson.dump(pot.msgs, outfile, indent=4)
         else:
             print(simplejson.dumps(pot.msgs, indent=4))