Add a quick Dojo resource bundle <-> POT roundtripping script
authordbs <dbs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 16 Oct 2008 03:54:49 +0000 (03:54 +0000)
committerdbs <dbs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 16 Oct 2008 03:54:49 +0000 (03:54 +0000)
Ensure Dojo resource bundles adhere to JSON formatting specs

git-svn-id: svn://svn.open-ils.org/ILS/trunk@10838 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/web/js/dojo/openils/conify/nls/aou.js
Open-ILS/web/js/dojo/openils/conify/nls/aout.js
build/i18n/scripts/dojo_resource.py [new file with mode: 0755]

index 1a387a0..039ba00 100644 (file)
@@ -1,31 +1,31 @@
 {
-       CONFIRM_DELETE: "Are you sure you want to delete ${0}?",
-       CONFIRM_EXIT: "There are unsaved changes to one or more organizational units. Click OK to save these changes, or Cancel to abandon them.",
-       ERROR_CREATING_CHILD: "Problem creating child Organizational Unit",
-       ERROR_DELETING: "Problem deleting ${0}",
-       ERROR_DELETING_LAST: "Cannot delete ${0}, you need at least one.",
-       ERROR_FETCHING_HOLDS: "Problem fetching Holds Address for ${0}",
-       ERROR_FETCHING_HOURS: "Problem fetching hours of operation for ${0}",
-       ERROR_FETCHING_ILL: "Problem fetching ILL Address for ${0}", 
-       ERROR_FETCHING_MAILING: "Problem fetching Mailing Address for ${0}", 
-       ERROR_FETCHING_ORGS: "Problem fetching organizational unit data",
-       ERROR_FETCHING_PHYSICAL: "Problem fetching Physical Address for ${0}", 
-       ERROR_FETCHING_TYPES: "Problem fetching organizational unit type data",
-       ERROR_ORPHANS: "Cannot delete ${0}, ${1} subordinates still exist.",
-       ERROR_SAVING_HOO: "Problem saving Hours of Operation data for ${0}",
-       ERROR_SAVING_DATA: "Problem saving data for ${0}",
-       ERROR_SAVING_HOLDS: "Problem saving Holds Address data for ${0}", 
-       ERROR_SAVING_ILL: "Problem saving ILL Address data for ${0}", 
-       ERROR_SAVING_MAILING: "Problem saving Mailing Address data for ${0}", 
-       ERROR_SAVING_PHYSICAL: "Problem saving Physical Address data for ${0}", 
-       LABEL_NEW_BRANCH: "New Branch",
-       STATUS_DELETED: "${0} deleted", 
-       STATUS_EDITING: "Now editing ${0}",
-       SUCCESS_CREATING_CHILD: "New child Organizational Unit created for ${0}",
-       SUCCESS_SAVE: "Saved changes to ${0}",
-       SUCCESS_SAVING_HOO: "Hours of Operation updated for ${0}",
-       SUCCESS_SAVING_HOLDS: "Saved changes to the Holds Address of ${0}",
-       SUCCESS_SAVING_ILL: "Saved changes to the ILL Address of ${0}",
-       SUCCESS_SAVING_MAILING: "Saved changes to the Mailing Address of ${0}",
-       SUCCESS_SAVING_PHYSICAL: "Saved changes to the Physical Address of ${0}"
+       "CONFIRM_DELETE": "Are you sure you want to delete ${0}?",
+       "CONFIRM_EXIT": "There are unsaved changes to one or more organizational units. Click OK to save these changes, or Cancel to abandon them.",
+       "ERROR_CREATING_CHILD": "Problem creating child Organizational Unit",
+       "ERROR_DELETING": "Problem deleting ${0}",
+       "ERROR_DELETING_LAST": "Cannot delete ${0}, you need at least one.",
+       "ERROR_FETCHING_HOLDS": "Problem fetching Holds Address for ${0}",
+       "ERROR_FETCHING_HOURS": "Problem fetching hours of operation for ${0}",
+       "ERROR_FETCHING_ILL": "Problem fetching ILL Address for ${0}", 
+       "ERROR_FETCHING_MAILING": "Problem fetching Mailing Address for ${0}", 
+       "ERROR_FETCHING_ORGS": "Problem fetching organizational unit data",
+       "ERROR_FETCHING_PHYSICAL": "Problem fetching Physical Address for ${0}", 
+       "ERROR_FETCHING_TYPES": "Problem fetching organizational unit type data",
+       "ERROR_ORPHANS": "Cannot delete ${0}, ${1} subordinates still exist.",
+       "ERROR_SAVING_HOO": "Problem saving Hours of Operation data for ${0}",
+       "ERROR_SAVING_DATA": "Problem saving data for ${0}",
+       "ERROR_SAVING_HOLDS": "Problem saving Holds Address data for ${0}", 
+       "ERROR_SAVING_ILL": "Problem saving ILL Address data for ${0}", 
+       "ERROR_SAVING_MAILING": "Problem saving Mailing Address data for ${0}", 
+       "ERROR_SAVING_PHYSICAL": "Problem saving Physical Address data for ${0}", 
+       "LABEL_NEW_BRANCH": "New Branch",
+       "STATUS_DELETED": "${0} deleted", 
+       "STATUS_EDITING": "Now editing ${0}",
+       "SUCCESS_CREATING_CHILD": "New child Organizational Unit created for ${0}",
+       "SUCCESS_SAVE": "Saved changes to ${0}",
+       "SUCCESS_SAVING_HOO": "Hours of Operation updated for ${0}",
+       "SUCCESS_SAVING_HOLDS": "Saved changes to the Holds Address of ${0}",
+       "SUCCESS_SAVING_ILL": "Saved changes to the ILL Address of ${0}",
+       "SUCCESS_SAVING_MAILING": "Saved changes to the Mailing Address of ${0}",
+       "SUCCESS_SAVING_PHYSICAL": "Saved changes to the Physical Address of ${0}"
 }
index 1b2813e..cb486de 100644 (file)
@@ -1,17 +1,16 @@
 {
-
-       CONFIRM_UNSAVED_CHANGES: "There are unsaved changes to one or more organization types. Click OK to save these changes, or Cancel to abandon them.",
-       CONFIRM_DELETE: "Are you sure you want to delete ${0}?",
-       ERROR_CREATING_CHILD: "Problem creating child Organization Type",
-       ERROR_CREATING_CHILD_METHOD: "Problem calling method to create child Organization Type",
-       ERROR_DELETING: "Problem deleting ${0}",
-       ERROR_DELETING_LAST: "Cannot delete ${0}. You need at least one organization type.",
-       ERROR_ORPHANS: "Cannot delete ${0}; ${1} subordinates still exist.",
-       ERROR_SAVING_DATA: "Problem saving data for ${0}",
-       ERROR_FETCHING_TYPES: "Problem fetching organization types",
-       LABEL_NEW_TYPE: "New Type",
-       STATUS_DELETED: "${0} deleted", 
-       STATUS_EDITING: "Now editing ${0}", 
-       SUCCESS_CREATING_CHILD: "New child Organization Type created for ${0}",
-       SUCCESS_SAVING_DATA: "Saved changes to ${0}"
+       "CONFIRM_UNSAVED_CHANGES": "There are unsaved changes to one or more organization types. Click OK to save these changes, or Cancel to abandon them.",
+       "CONFIRM_DELETE": "Are you sure you want to delete ${0}?",
+       "ERROR_CREATING_CHILD": "Problem creating child Organization Type",
+       "ERROR_CREATING_CHILD_METHOD": "Problem calling method to create child Organization Type",
+       "ERROR_DELETING": "Problem deleting ${0}",
+       "ERROR_DELETING_LAST": "Cannot delete ${0}. You need at least one organization type.",
+       "ERROR_ORPHANS": "Cannot delete ${0}; ${1} subordinates still exist.",
+       "ERROR_SAVING_DATA": "Problem saving data for ${0}",
+       "ERROR_FETCHING_TYPES": "Problem fetching organization types",
+       "LABEL_NEW_TYPE": "New Type",
+       "STATUS_DELETED": "${0} deleted", 
+       "STATUS_EDITING": "Now editing ${0}", 
+       "SUCCESS_CREATING_CHILD": "New child Organization Type created for ${0}",
+       "SUCCESS_SAVING_DATA": "Saved changes to ${0}"
 }
diff --git a/build/i18n/scripts/dojo_resource.py b/build/i18n/scripts/dojo_resource.py
new file mode 100755 (executable)
index 0000000..604b402
--- /dev/null
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+# dojo_resource.py
+"""
+This class enables translation of Dojo resource bundles using gettext format.
+
+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}."
+}
+
+Note that this is a deliberately limited subset of the variable substitution
+allowed by http://api.dojotoolkit.org/jsdoc/dojo/1.2/dojo.string.substitute
+
+"""
+# Copyright 2007 Dan Scott <dscott@laurentian.ca>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+import basel10n
+import optparse
+import polib
+import re
+import sys
+import simplejson
+import os.path
+
+class DojoResource (basel10n.BaseL10N):
+    """
+    This class provides methods for extracting translatable strings from
+    Evergreen's Dojo resource bundle files, generating translatable POT files,
+    reading translated PO files, and generating an updated Dojo resource bundle
+    files with additional or changed strings.
+    """
+
+    def __init__(self):
+        self.pot = None
+        basel10n.BaseL10N.__init__(self)
+        self.msgs = {}
+
+    def get_strings(self, source):
+        """
+        Extracts translatable strings from Evergreen's Dojo resource bundles.
+        """
+        self.pothead()
+        
+        bundle = simplejson.load(open(source, 'r'))
+
+        for key, value in bundle.iteritems():
+            poe = polib.POEntry()
+            poe.occurrences = [(os.path.basename(source), key)]
+            poe.msgid = value
+            poe.msgstr = value
+            self.pot.append(poe)
+
+    def create_bundle(self):
+        """
+        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:
+                if entry.msgstr == '':
+                    # No translation available; use the en-US definition
+                    self.msgs[msgkey] = entry.msgid
+                else:
+                    self.msgs[msgkey] = entry.msgstr
+
+def main():
+    """
+    Determine what action to take
+    """
+    opts = optparse.OptionParser()
+    opts.add_option('-p', '--pot', action='store', \
+        help='Create a POT file from the specified Dojo resource bundle file', \
+        metavar='FILE')
+    opts.add_option('-c', '--create', action='store', \
+        help='Create a Dojo resource bundle file from a translated PO FILE', \
+        metavar='FILE')
+    opts.add_option('-o', '--output', dest='outfile', \
+        help='Write output to FILE (defaults to STDOUT)', metavar='FILE')
+    (options, args) = opts.parse_args()
+
+    pot = DojoResource()
+
+    # Generate a new POT file from the Dojo resource bundle file
+    if options.pot:
+        pot.get_strings(options.pot)
+        if options.outfile:
+            pot.savepot(options.outfile)
+        else:
+            sys.stdout.write(pot.pot.__str__())
+
+    # Generate an Dojo resource bundle file from a PO file
+    elif options.create:
+        pot.loadpo(options.create)
+        pot.create_bundle()
+        if options.outfile:
+            outfile = open(options.outfile, 'w')
+            simplejson.dump(pot.msgs, outfile, indent=4)
+        else:
+            print(simplejson.dumps(pot.msgs, indent=4))
+
+    # No options were recognized - print help and bail
+    else:
+        opts.print_help()
+
+if __name__ == '__main__':
+    main()