i18n: fixed mistage in message generator which lead to some messages disappeared.
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 30 Sep 2011 09:25:53 +0000 (09:25 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 30 Sep 2011 09:25:53 +0000 (09:25 +0000)
Also, cleaned up po files from unused messages.

po/README.txt
po/check_po.py [new file with mode: 0755]
po/clean_po.py [new file with mode: 0755]
po/merge_po.py [new file with mode: 0755]
po/update_msg.py
po/update_pot.py

index 79b0bf7c062ab270a6a006025dc7681a3108f137..76dce7b414c48e3a02d24082f081e7b446bb2af1 100644 (file)
@@ -71,3 +71,11 @@ For example in update_pot.py:
 -GETTEXT_XGETTEXT_EXECUTABLE = "xgettext"
 +GETTEXT_XGETTEXT_EXECUTABLE = "C:\\Blender\\lib\\\windows\\\binaries\\\gettext\\xgettext.exe"
 
+4. Other scripts
+----------------
+
+- check_po.py: this script checks if all messages declared in blender.pot exists in.po files
+               and that no extra messages are declared in .po files
+- clean_po.py: this script removes all commented messages which aren't required by .pot file anymore.
+- merge_po.py: this scripts accepts two files as arguments and copies translations from second file
+               into first file.
diff --git a/po/check_po.py b/po/check_po.py
new file mode 100755 (executable)
index 0000000..a402c2b
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+
+# $Id$
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# <pep8 compliant>
+
+# update the pot file according the POTFILES.in
+
+import os
+import sys
+from codecs import open
+
+CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
+
+FILE_NAME_POT = os.path.join(CURRENT_DIR, "blender.pot")
+
+
+def read_messages(fname):
+    def stripeol(s):
+        return s.rstrip("\n\r")
+
+    messages = {}
+    reading_message = False
+    message = ""
+    with open(fname, 'r', "utf-8") as handle:
+        while True:
+            line = handle.readline()
+
+            if not line:
+                break
+
+            line = stripeol(line)
+            if line.startswith("msgid"):
+                reading_message = True
+                message = line[7:-1]
+            elif line.startswith("msgstr"):
+                reading_message = False
+                messages[message] = True
+            elif reading_message:
+                message += line[1:-1]
+    return messages
+
+
+def main():
+    pot_messages = read_messages(FILE_NAME_POT)
+
+    if len(sys.argv) > 1:
+        for lang in sys.argv[1:]:
+            po = os.path.join(CURRENT_DIR, lang + '.po')
+
+            if os.path.exists(po):
+                po_messages = read_messages(po)
+                for msgid in po_messages:
+                    if not pot_messages.get(msgid):
+                        print('Unneeded message id \'%s\'' % (msgid))
+
+                for msgid in pot_messages:
+                    if not po_messages.get(msgid):
+                        print('Missed message id \'%s\'' % (msgid))
+    else:
+        for po in os.listdir(CURRENT_DIR):
+            if po.endswith('.po'):
+                print('Processing %s...' % (po))
+                po_messages = read_messages(po)
+                for msgid in po_messages:
+                    if not pot_messages.get(msgid):
+                        print('    Unneeded message id \'%s\'' % (msgid))
+
+                for msgid in pot_messages:
+                    if not po_messages.get(msgid):
+                        print('    Missed message id \'%s\'' % (msgid))
+
+
+if __name__ == "__main__":
+    print("\n\n *** Running %r *** \n" % __file__)
+    main()
diff --git a/po/clean_po.py b/po/clean_po.py
new file mode 100755 (executable)
index 0000000..2cbd2cb
--- /dev/null
@@ -0,0 +1,190 @@
+#!/usr/bin/env python
+
+# $Id$
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# <pep8 compliant>
+
+# update the pot file according the POTFILES.in
+
+import os
+import sys
+import collections
+
+from codecs import open
+
+CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
+
+FILE_NAME_POT = os.path.join(CURRENT_DIR, "blender.pot")
+
+
+def read_messages(fname):
+    def stripeol(s):
+        return s.rstrip("\n\r")
+
+    last_message = None
+
+    if hasattr(collections, 'OrderedDict'):
+        messages = collections.OrderedDict()
+        commented_messages = collections.OrderedDict()
+    else:
+        messages = {}
+        commented_messages = {}
+
+    reading_message = False
+    reading_translation = False
+    commented = False
+    message = ""
+    translation = ""
+    message_lines = []
+    translation_lines = []
+    comment_lines = []
+    with open(fname, 'r', "utf-8") as handle:
+        while True:
+            line = handle.readline()
+
+            if not line:
+                break
+
+            line = stripeol(line)
+            if line.startswith("msgid") or line.startswith("#~ msgid"):
+                if reading_translation:
+                    last_message['translation'] = translation
+                    translation_lines = []
+
+                reading_message = True
+                reading_translation = False
+
+                if line.startswith('#~'):
+                    message = line[10:-1]
+                    commented = True
+                else:
+                    message = line[7:-1]
+                    commented = False
+
+                message_lines.append(message)
+            elif line.startswith("msgstr") or line.startswith("#~ msgstr"):
+                reading_message = False
+                reading_translation = True
+                last_message = {'comment_lines': comment_lines,
+                                'message_lines': message_lines,
+                                'translation_lines': translation_lines}
+
+                if commented:
+                    translation = line[11:-1]
+                    commented_messages[message] = last_message
+                else:
+                    translation = line[8:-1]
+                    messages[message] = last_message
+
+                message_lines = []
+                comment_lines = []
+                translation_lines.append(translation)
+            elif not line.startswith('"') and not line.startswith('#~ "'):
+                if reading_translation:
+                    last_message['translation'] = translation
+                else:
+                    comment_lines.append(line)
+
+                reading_message = False
+                reading_translation = False
+                message_lines = []
+                translation_lines = []
+            elif reading_message:
+                if line.startswith('#~ "'):
+                    m = line[4:-1]
+                else:
+                    m = line[1:-1]
+
+                message += m
+                message_lines.append(m)
+            elif reading_translation:
+                if line.startswith('#~ "'):
+                    t = line[4:-1]
+                else:
+                    t = line[1:-1]
+
+                translation += t
+                translation_lines.append(t)
+
+    return (messages, commented_messages)
+
+
+def do_clean(po, pot_messages):
+    po_messages, commented_messages = read_messages(po)
+
+    for msgid in commented_messages:
+        if pot_messages.get(msgid):
+            t = po_messages.get(msgid)
+            if not t:
+                print(('Reusing full item from commented ' + \
+                       'lines for msgid \'%s\'') % (msgid))
+                po_messages[msgid] = commented_messages[msgid]
+            elif not t['translation']:
+                print(('Reusing translation from commented ' + \
+                       'lines for msgid \'%s\'') % (msgid))
+                m = commented_messages[msgid]
+                t['translation'] = m['translation']
+                t['translation_lines'] = m['translation_lines']
+
+    with open(po, 'w', 'utf-8') as handle:
+        for msgid in po_messages:
+            item = po_messages[msgid]
+
+            for x in item['comment_lines']:
+                handle.write(x + "\n")
+
+            first = True
+            for x in item['message_lines']:
+                if first:
+                    handle.write("msgid \"%s\"\n" % (x))
+                else:
+                    handle.write("\"%s\"\n" % (x))
+                first = False
+
+            first = True
+            for x in item['translation_lines']:
+                if first:
+                    handle.write("msgstr \"%s\"\n" % (x))
+                else:
+                    handle.write("\"%s\"\n" % (x))
+                first = False
+
+            handle.write("\n")
+
+
+def main():
+    pot_messages, commented_messages = read_messages(FILE_NAME_POT)
+
+    if len(sys.argv) > 1:
+        for lang in sys.argv[1:]:
+            po = os.path.join(CURRENT_DIR, lang + '.po')
+
+            if os.path.exists(po):
+                do_clean(po, pot_messages)
+    else:
+        for po in os.listdir(CURRENT_DIR):
+            if po.endswith('.po'):
+                print('Processing %s...' % (po))
+                do_clean(po, pot_messages)
+
+
+if __name__ == "__main__":
+    print("\n\n *** Running %r *** \n" % __file__)
+    main()
diff --git a/po/merge_po.py b/po/merge_po.py
new file mode 100755 (executable)
index 0000000..b4a1ffa
--- /dev/null
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+
+# $Id$
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# <pep8 compliant>
+
+# update the pot file according the POTFILES.in
+
+import os
+import sys
+import collections
+
+from codecs import open
+
+
+def read_messages(fname):
+    def stripeol(s):
+        return s.rstrip("\n\r")
+
+    last_message = None
+
+    if hasattr(collections, 'OrderedDict'):
+        messages = collections.OrderedDict()
+        commented_messages = collections.OrderedDict()
+    else:
+        messages = {}
+        commented_messages = {}
+
+    reading_message = False
+    reading_translation = False
+    commented = False
+    message = ""
+    translation = ""
+    message_lines = []
+    translation_lines = []
+    comment_lines = []
+    with open(fname, 'r', "utf-8") as handle:
+        while True:
+            line = handle.readline()
+
+            if not line:
+                break
+
+            line = stripeol(line)
+            if line.startswith("msgid") or line.startswith("#~ msgid"):
+                if reading_translation:
+                    last_message['translation'] = translation
+                    translation_lines = []
+
+                reading_message = True
+                reading_translation = False
+
+                if line.startswith('#~'):
+                    message = line[10:-1]
+                    commented = True
+                else:
+                    message = line[7:-1]
+                    commented = False
+
+                message_lines.append(message)
+            elif line.startswith("msgstr") or line.startswith("#~ msgstr"):
+                reading_message = False
+                reading_translation = True
+                last_message = {'comment_lines': comment_lines,
+                                'message_lines': message_lines,
+                                'translation_lines': translation_lines}
+
+                if commented:
+                    translation = line[11:-1]
+                    commented_messages[message] = last_message
+                else:
+                    translation = line[8:-1]
+                    messages[message] = last_message
+
+                message_lines = []
+                comment_lines = []
+                translation_lines.append(translation)
+            elif not line.startswith('"') and not line.startswith('#~ "'):
+                if reading_translation:
+                    last_message['translation'] = translation
+                else:
+                    comment_lines.append(line)
+
+                reading_message = False
+                reading_translation = False
+                message_lines = []
+                translation_lines = []
+            elif reading_message:
+                if line.startswith('#~ "'):
+                    m = line[4:-1]
+                else:
+                    m = line[1:-1]
+
+                message += m
+                message_lines.append(m)
+            elif reading_translation:
+                if line.startswith('#~ "'):
+                    t = line[4:-1]
+                else:
+                    t = line[1:-1]
+
+                translation += t
+                translation_lines.append(t)
+
+    return (messages, commented_messages)
+
+
+def main():
+    if len(sys.argv) == 3:
+        dst_messages, tmp = read_messages(sys.argv[1])
+        from_messages, tmp = read_messages(sys.argv[2])
+
+        for msgid in dst_messages:
+            msg = dst_messages.get(msgid)
+            from_msg = from_messages.get(msgid)
+
+            if from_msg and from_msg['translation']:
+                msg['translation'] = from_msg['translation']
+                msg['translation_lines'] = from_msg['translation_lines']
+
+        with open(sys.argv[1], 'w', 'utf-8') as handle:
+            for msgid in dst_messages:
+                item = dst_messages[msgid]
+
+                for x in item['comment_lines']:
+                    handle.write(x + "\n")
+
+                first = True
+                for x in item['message_lines']:
+                    if first:
+                        handle.write("msgid \"%s\"\n" % (x))
+                    else:
+                        handle.write("\"%s\"\n" % (x))
+                    first = False
+
+                first = True
+                for x in item['translation_lines']:
+                    if first:
+                        handle.write("msgstr \"%s\"\n" % (x))
+                    else:
+                        handle.write("\"%s\"\n" % (x))
+                    first = False
+
+                handle.write("\n")
+    else:
+        print('Usage: %s <destination-po> <source-po>' % (sys.argv[0]))
+
+
+if __name__ == "__main__":
+    print("\n\n *** Running %r *** \n" % __file__)
+    main()
index aede99651b1d0d03c4320e6e808fab5311208230..9fc9967146d70c1fdaf6f6fbde9ba272f2534ffd 100644 (file)
@@ -78,6 +78,9 @@ def dump_messages_rna(messages):
         if bl_rna.description:
             messages.setdefault(bl_rna.description, []).append(msgsrc)
 
+        if hasattr(bl_rna, 'bl_label') and  bl_rna.bl_label:
+            messages.setdefault(bl_rna.bl_label, []).append(msgsrc)
+
         walkProperties(bl_rna)
 
     def walkClass(cls):
@@ -119,13 +122,19 @@ def dump_messages_rna(messages):
     for cls in cls_list:
         walkClass(cls)
 
-    from bpy_extras.keyconfig_utils import KM_HIERARCHY
+    cls_list = bpy.types.OperatorProperties.__subclasses__()
+    cls_list.sort(key=full_class_id)
+    for cls in cls_list:
+        walkClass(cls)
 
-    walk_keymap_hierarchy(KM_HIERARCHY, "KM_HIERARCHY")
+    cls_list = bpy.types.Menu.__subclasses__()
+    cls_list.sort(key=full_class_id)
+    for cls in cls_list:
+        walkClass(cls)
 
+    from bpy_extras.keyconfig_utils import KM_HIERARCHY
 
-    ## XXX. what is this supposed to do, we wrote the file already???
-    #_walkClass(bpy.types.SpaceDopeSheetEditor)
+    walk_keymap_hierarchy(KM_HIERARCHY, "KM_HIERARCHY")
 
 
 def dump_messages_pytext(messages):
index 22e1e7a1c1f75a0a33c67ce647df1ed9739f4a5b..4e2020264445d183aa4059c984c25dd345daf704 100755 (executable)
@@ -92,6 +92,7 @@ def main():
                 else:
                     line = line.replace("\\", "\\\\")
                     line = line.replace("\"", "\\\"")
+                    line = line.replace("\t", "\\t")
 
                     if not pot_messages.get(line):
                         for msgsrc in msgsrc_ls: