diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-11-05 16:16:40 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-11-05 16:16:40 +0400 |
commit | fd6138a26d1efdf46be3d8dff85d63eaad5f0d21 (patch) | |
tree | 29c75a98dff7a67512cfcab0ab51a26c45198050 | |
parent | 33accdb725bb7e5bb133b17faa2cc6191eca73ef (diff) |
remove dirs to make them external's
-rw-r--r-- | po/POTFILES.in | 201 | ||||
-rw-r--r-- | po/README.txt | 81 | ||||
-rwxr-xr-x | po/check_po.py | 92 | ||||
-rwxr-xr-x | po/clean_po.py | 189 | ||||
-rwxr-xr-x | po/merge_po.py | 166 | ||||
-rwxr-xr-x | po/update_mo.py | 67 | ||||
-rw-r--r-- | po/update_msg.py | 380 | ||||
-rwxr-xr-x | po/update_po.py | 66 | ||||
-rwxr-xr-x | po/update_pot.py | 106 |
9 files changed, 0 insertions, 1348 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in deleted file mode 100644 index 5a4ba6a9cb2..00000000000 --- a/po/POTFILES.in +++ /dev/null @@ -1,201 +0,0 @@ -release/scripts/modules/rna_prop_ui.py - -release/scripts/startup/bl_operators/object.py -release/scripts/startup/bl_operators/object_align.py -release/scripts/startup/bl_operators/object_quick_effects.py -release/scripts/startup/bl_operators/object_randomize_transform.py -release/scripts/startup/bl_operators/presets.py -release/scripts/startup/bl_operators/screen_play_rendered_anim.py -release/scripts/startup/bl_operators/sequencer.py -release/scripts/startup/bl_operators/wm.py - -release/scripts/startup/bl_ui/properties_animviz.py -release/scripts/startup/bl_ui/properties_data_armature.py -release/scripts/startup/bl_ui/properties_data_bone.py -release/scripts/startup/bl_ui/properties_data_camera.py -release/scripts/startup/bl_ui/properties_data_curve.py -release/scripts/startup/bl_ui/properties_data_empty.py -release/scripts/startup/bl_ui/properties_data_lamp.py -release/scripts/startup/bl_ui/properties_data_lattice.py -release/scripts/startup/bl_ui/properties_data_mesh.py -release/scripts/startup/bl_ui/properties_data_metaball.py -release/scripts/startup/bl_ui/properties_data_modifier.py -release/scripts/startup/bl_ui/properties_game.py -release/scripts/startup/bl_ui/properties_material.py -release/scripts/startup/bl_ui/properties_object_constraint.py -release/scripts/startup/bl_ui/properties_object.py -release/scripts/startup/bl_ui/properties_particle.py -release/scripts/startup/bl_ui/properties_physics_cloth.py -release/scripts/startup/bl_ui/properties_physics_common.py -release/scripts/startup/bl_ui/properties_physics_field.py -release/scripts/startup/bl_ui/properties_physics_fluid.py -release/scripts/startup/bl_ui/properties_physics_smoke.py -release/scripts/startup/bl_ui/properties_physics_softbody.py -release/scripts/startup/bl_ui/properties_render.py -release/scripts/startup/bl_ui/properties_scene.py -release/scripts/startup/bl_ui/properties_texture.py -release/scripts/startup/bl_ui/properties_world.py - -release/scripts/startup/bl_ui/space_console.py -release/scripts/startup/bl_ui/space_dopesheet.py -release/scripts/startup/bl_ui/space_graph.py -release/scripts/startup/bl_ui/space_image.py -release/scripts/startup/bl_ui/space_info.py -release/scripts/startup/bl_ui/space_logic.py -release/scripts/startup/bl_ui/space_nla.py -release/scripts/startup/bl_ui/space_node.py -release/scripts/startup/bl_ui/space_outliner.py -release/scripts/startup/bl_ui/space_sequencer.py -release/scripts/startup/bl_ui/space_text.py -release/scripts/startup/bl_ui/space_time.py -release/scripts/startup/bl_ui/space_userpref.py -release/scripts/startup/bl_ui/space_userpref_keymap.py -release/scripts/startup/bl_ui/space_view3d.py -release/scripts/startup/bl_ui/space_view3d_toolbar.py - -source/blender/editors/animation/anim_channels_edit.c -source/blender/editors/animation/anim_markers.c -source/blender/editors/animation/anim_ops.c -source/blender/editors/animation/drivers.c -source/blender/editors/animation/keyframing.c -source/blender/editors/animation/keyingsets.c - -source/blender/editors/armature/armature_ops.c -source/blender/editors/armature/editarmature.c -source/blender/editors/armature/editarmature_sketch.c -source/blender/editors/armature/poselib.c -source/blender/editors/armature/poseobject.c -source/blender/editors/armature/poseSlide.c - -source/blender/editors/curve/editcurve.c -source/blender/editors/curve/editfont.c - -source/blender/editors/gpencil/gpencil_paint.c - -source/blender/editors/interface/interface_layout.c -source/blender/editors/interface/interface_ops.c -source/blender/editors/interface/interface_regions.c -source/blender/editors/interface/interface_templates.c -source/blender/editors/interface/interface_utils.c -source/blender/editors/interface/view2d_ops.c - -source/blender/editors/mesh/editmesh.c -source/blender/editors/mesh/editmesh_add.c -source/blender/editors/mesh/editmesh_loop.c -source/blender/editors/mesh/editmesh_mods.c -source/blender/editors/mesh/editmesh_tools.c -source/blender/editors/mesh/loopcut.c -source/blender/editors/mesh/mesh_data.c -source/blender/editors/mesh/mesh_ops.c - -source/blender/editors/metaball/mball_edit.c - -source/blender/editors/object/object_add.c -source/blender/editors/object/object_constraint.c -source/blender/editors/object/object_edit.c -source/blender/editors/object/object_group.c -source/blender/editors/object/object_lattice.c -source/blender/editors/object/object_modifier.c -source/blender/editors/object/object_ops.c -source/blender/editors/object/object_relations.c -source/blender/editors/object/object_select.c -source/blender/editors/object/object_shapekey.c -source/blender/editors/object/object_transform.c -source/blender/editors/object/object_vgroup.c - -source/blender/editors/physics/particle_edit.c -source/blender/editors/physics/particle_object.c -source/blender/editors/physics/physics_pointcache.c - -source/blender/editors/render/render_internal.c -source/blender/editors/render/render_opengl.c -source/blender/editors/render/render_shading.c -source/blender/editors/render/render_view.c - -source/blender/editors/screen/area.c -source/blender/editors/screen/screendump.c -source/blender/editors/screen/screen_ops.c - -source/blender/editors/sculpt_paint/paint_ops.c -source/blender/editors/sculpt_paint/paint_image.c -source/blender/editors/sculpt_paint/paint_utils.c -source/blender/editors/sculpt_paint/paint_vertex.c -source/blender/editors/sculpt_paint/sculpt.c - -source/blender/editors/sound/sound_ops.c - -source/blender/editors/space_action/action_edit.c -source/blender/editors/space_action/action_ops.c -source/blender/editors/space_action/action_select.c - -source/blender/editors/space_buttons/buttons_header.c -source/blender/editors/space_buttons/buttons_ops.c - -source/blender/editors/space_console/console_ops.c - -source/blender/editors/space_file/file_draw.c -source/blender/editors/space_file/file_ops.c -source/blender/editors/space_file/file_panels.c - -source/blender/editors/space_graph/graph_buttons.c -source/blender/editors/space_graph/graph_edit.c -source/blender/editors/space_graph/graph_ops.c -source/blender/editors/space_graph/graph_select.c - -source/blender/editors/space_image/image_buttons.c -source/blender/editors/space_image/image_ops.c - -source/blender/editors/space_info/info_ops.c -source/blender/editors/space_info/info_report.c -source/blender/editors/space_info/space_info.c - -source/blender/editors/space_logic/logic_buttons.c - -source/blender/editors/space_nla/nla_buttons.c -source/blender/editors/space_nla/nla_channels.c -source/blender/editors/space_nla/nla_edit.c -source/blender/editors/space_nla/nla_select.c - -source/blender/editors/space_node/node_buttons.c -source/blender/editors/space_node/node_edit.c -source/blender/editors/space_node/node_header.c -source/blender/editors/space_node/node_ops.c -source/blender/editors/space_node/node_select.c -source/blender/editors/space_node/node_state.c - -source/blender/editors/space_script/script_edit.c - -source/blender/editors/space_sequencer/sequencer_add.c -source/blender/editors/space_sequencer/sequencer_buttons.c -source/blender/editors/space_sequencer/sequencer_edit.c -source/blender/editors/space_sequencer/sequencer_select.c - -source/blender/editors/space_text/text_header.c -source/blender/editors/space_text/text_ops.c -source/blender/editors/space_time/time_ops.c - -source/blender/editors/space_view3d/view3d_buttons.c -source/blender/editors/space_view3d/view3d_draw.c -source/blender/editors/space_view3d/view3d_edit.c -source/blender/editors/space_view3d/view3d_fly.c -source/blender/editors/space_view3d/view3d_header.c -source/blender/editors/space_view3d/view3d_select.c -source/blender/editors/space_view3d/view3d_view.c -source/blender/editors/space_view3d/view3d_toolbar.c - -source/blender/editors/transform/transform.c -source/blender/editors/transform/transform_ops.c -source/blender/editors/transform/transform_orientations.c - -source/blender/editors/util/undo.c - -source/blender/editors/uvedit/uvedit_ops.c -source/blender/editors/uvedit/uvedit_unwrap_ops.c - -source/blender/makesrna/intern/rna_userdef.c - -source/blender/windowmanager/intern/wm_files.c -source/blender/windowmanager/intern/wm_operators.c -source/blender/windowmanager/intern/wm_window.c - - diff --git a/po/README.txt b/po/README.txt deleted file mode 100644 index 6e634ae5ee3..00000000000 --- a/po/README.txt +++ /dev/null @@ -1,81 +0,0 @@ -Blender translation HOWTO -========================= - -I'll try briefly explain how translation works and how to update translation files. - -1. How it works ---------------- - -This folder contains source files for translation system. These source files have -got .po extension and they've got pretty simple syntax: - -msgid "some message id" -msgstr "translation for this message" - -This means when string "some message id" is used as operator name, tooltip, menu -and so it'll be displayed on the screen as "translation for this message". -Pretty simple. - -This source files are pre-compiled into ../release/datafiles/locale/<language>/LC_MESSAGES/blender.mo, -so they aren't getting compiled every time Blender is compiling to save some time and prevent -failure on systems which don't have needed tools for compiling .po files. - -2. How to update translations ------------------------------ - -It's also pretty simple. If you can find string you want to translate in <language>.po -file as msgid, just write correct msgstr string for it. If msgid is marked as fuzzy, -i.e. - -#, fuzzy -msgid "some message id" -msgstr "translation for this message" - -it means translation used to exist for this message, but message was changed, so translation -also have to be updated (it's easier to make new translation based on previous translation). -When translation was updated, remove line with '#, fuzzy' and it'll work. - -If there's no message in .po file you want to translate, probably .po file should be updated. -Use the following steps for this: -- With newly compiled blender run: - `blender --background --factory-startup --python update_msg.py` - to update messages.txt file (this file contains strings collected - automatically from RNA system and python UI scripts) -- Run update_pot.py script which will update blender.pot file. This file contains all - strings which should be transated. -- Run update_po.py script to merge all .po files with blender.pot (so all .po files - will contain all msgid-s declared in blender.pot) or update_po.py <language> to - update only needed .po file(s) to save time when you're busy with translation. - But before commit all .po files better be updated. - -When you've finished with translation, you should re-compile .po file into .mo file. -It's also pretty simple: just run update_mo.py script to recompile all languages or -just update_mo.py <language> to re-compile only needed language(s). - -NOTE: msgfmt, msgmerge and xgettext tools should be available in your PATH. - -These steps to update template, translation files and compile them can be made in "batch" mode -using GNUMakefile: - -make -f GNUMakefile translations - -NOTE: Blender has to be compiled using GNUMakefile first. - - -3. Note for Windows users -------------------------- -You can find compiled builds of gettext in the lib folder under "binaries\gettext\" for both windows and win64. -In order to run the scripts you will need to replace the location of the GETTEXT_..._EXECUTABLE. - -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 script 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 deleted file mode 100755 index a2b19d57428..00000000000 --- a/po/check_po.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 deleted file mode 100755 index 95bac39b42e..00000000000 --- a/po/clean_po.py +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 deleted file mode 100755 index dcbe9fc9890..00000000000 --- a/po/merge_po.py +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 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() diff --git a/po/update_mo.py b/po/update_mo.py deleted file mode 100755 index 50e99c7eeaa..00000000000 --- a/po/update_mo.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 all mo files in the LANGS - -import subprocess -import os -import sys - -GETTEXT_MSGFMT_EXECUTABLE = "msgfmt" -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) -SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(CURRENT_DIR, ".."))) -LOCALE_DIR = os.path.join(SOURCE_DIR, "release", "datafiles", "locale") - -DOMAIN = "blender" - - -def process_po(po): - lang = os.path.basename(po)[:-3] - - # show stats - cmd = (GETTEXT_MSGFMT_EXECUTABLE, - "--statistics", - os.path.join(CURRENT_DIR, "%s.po" % lang), - "-o", - os.path.join(LOCALE_DIR, lang, "LC_MESSAGES", "%s.mo" % DOMAIN), - ) - - print(" ".join(cmd)) - process = subprocess.Popen(cmd) - process.wait() - - -def main(): - if len(sys.argv) > 1: - for lang in sys.argv[1:]: - po = os.path.join(CURRENT_DIR, lang + '.po') - - if os.path.exists(po): - process_po(po) - else: - for po in os.listdir(CURRENT_DIR): - if po.endswith(".po"): - process_po(po) - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() diff --git a/po/update_msg.py b/po/update_msg.py deleted file mode 100644 index 21d727922d4..00000000000 --- a/po/update_msg.py +++ /dev/null @@ -1,380 +0,0 @@ -# ***** 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-80 compliant> - -# Write out messages.txt from blender - -# Execite: -# blender --background --python po/update_msg.py - -import os - -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) -SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(CURRENT_DIR, ".."))) - -FILE_NAME_MESSAGES = os.path.join(CURRENT_DIR, "messages.txt") -COMMENT_PREFIX = "#~ " - - -def dump_messages_rna(messages): - import bpy - - def classBlackList(): - blacklist_rna_class = [ - # core classes - "Context", "Event", "Function", "UILayout", - "BlendData", - # registerable classes - "Panel", "Menu", "Header", "RenderEngine", - "Operator", "OperatorMacro", "Macro", - "KeyingSetInfo", "UnknownType", - # window classes - "WindowManager", "Window" - ] - - # --------------------------------------------------------------------- - # Collect internal operators - - # extend with all internal operators - # note that this uses internal api introspection functions - # all possible operator names - op_names = list(sorted(set( - [cls.bl_rna.identifier for cls in - bpy.types.OperatorProperties.__subclasses__()] + - [cls.bl_rna.identifier for cls in - bpy.types.Operator.__subclasses__()] + - [cls.bl_rna.identifier for cls in - bpy.types.OperatorMacro.__subclasses__()] - ))) - - get_inatance = __import__("_bpy").ops.get_instance - path_resolve = type(bpy.context).__base__.path_resolve - for idname in op_names: - op = get_inatance(idname) - if 'INTERNAL' in path_resolve(op, "bl_options"): - blacklist_rna_class.append(idname) - - # --------------------------------------------------------------------- - # Collect builtin classes we dont need to doc - blacklist_rna_class.append("Property") - blacklist_rna_class.extend( - [cls.__name__ for cls in - bpy.types.Property.__subclasses__()]) - - # --------------------------------------------------------------------- - # Collect classes which are attached to collections, these are api - # access only. - collection_props = set() - for cls_id in dir(bpy.types): - cls = getattr(bpy.types, cls_id) - for prop in cls.bl_rna.properties: - if prop.type == 'COLLECTION': - prop_cls = prop.srna - if prop_cls is not None: - collection_props.add(prop_cls.identifier) - blacklist_rna_class.extend(sorted(collection_props)) - - return blacklist_rna_class - - blacklist_rna_class = classBlackList() - - def filterRNA(bl_rna): - id = bl_rna.identifier - if id in blacklist_rna_class: - print(" skipping", id) - return True - return False - - # ------------------------------------------------------------------------- - # Function definitions - - def walkProperties(bl_rna): - import bpy - - # get our parents properties not to export them multiple times - bl_rna_base = bl_rna.base - if bl_rna_base: - bl_rna_base_props = bl_rna_base.properties.values() - else: - bl_rna_base_props = () - - for prop in bl_rna.properties: - # only write this property is our parent hasn't got it. - if prop in bl_rna_base_props: - continue - if prop.identifier == "rna_type": - continue - - msgsrc = "bpy.types.%s.%s" % (bl_rna.identifier, prop.identifier) - if prop.name and prop.name != prop.identifier: - messages.setdefault(prop.name, []).append(msgsrc) - if prop.description: - messages.setdefault(prop.description, []).append(msgsrc) - - if isinstance(prop, bpy.types.EnumProperty): - for item in prop.enum_items: - msgsrc = "bpy.types.%s.%s, '%s'" % (bl_rna.identifier, - prop.identifier, - item.identifier, - ) - # Here identifier and name can be the same! - if item.name: # and item.name != item.identifier: - messages.setdefault(item.name, - []).append(msgsrc) - if item.description: - messages.setdefault(item.description, - []).append(msgsrc) - - def walkRNA(bl_rna): - - if filterRNA(bl_rna): - return - - msgsrc = "bpy.types.%s" % bl_rna.identifier - - if bl_rna.name and bl_rna.name != bl_rna.identifier: - messages.setdefault(bl_rna.name, []).append(msgsrc) - - 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): - walkRNA(cls.bl_rna) - - def walk_keymap_hierarchy(hier, msgsrc_prev): - for lvl in hier: - msgsrc = "%s.%s" % (msgsrc_prev, lvl[1]) - messages.setdefault(lvl[0], []).append(msgsrc) - - if lvl[3]: - walk_keymap_hierarchy(lvl[3], msgsrc) - - # ------------------------------------------------------------------------- - # Dump Messages - - def full_class_id(cls): - """ gives us 'ID.Lamp.AreaLamp' which is best for sorting. - """ - cls_id = "" - bl_rna = cls.bl_rna - while bl_rna: - cls_id = "%s.%s" % (bl_rna.identifier, cls_id) - bl_rna = bl_rna.base - return cls_id - - cls_list = type(bpy.context).__base__.__subclasses__() - cls_list.sort(key=full_class_id) - for cls in cls_list: - walkClass(cls) - - cls_list = bpy.types.Space.__subclasses__() - cls_list.sort(key=full_class_id) - for cls in cls_list: - walkClass(cls) - - cls_list = bpy.types.Operator.__subclasses__() - cls_list.sort(key=full_class_id) - for cls in cls_list: - walkClass(cls) - - cls_list = bpy.types.OperatorProperties.__subclasses__() - cls_list.sort(key=full_class_id) - for cls in cls_list: - walkClass(cls) - - 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 - - walk_keymap_hierarchy(KM_HIERARCHY, "KM_HIERARCHY") - - -def dump_messages_pytext(messages): - """ dumps text inlined in the python user interface: eg. - - layout.prop("someprop", text="My Name") - """ - import ast - - # ------------------------------------------------------------------------- - # Gather function names - - import bpy - # key: func_id - # val: [(arg_kw, arg_pos), (arg_kw, arg_pos), ...] - func_translate_args = {} - - # so far only 'text' keywords, but we may want others translated later - translate_kw = ("text", ) - - for func_id, func in bpy.types.UILayout.bl_rna.functions.items(): - # check it has a 'text' argument - for (arg_pos, (arg_kw, arg)) in enumerate(func.parameters.items()): - if ((arg_kw in translate_kw) and - (arg.is_output == False) and - (arg.type == 'STRING')): - - func_translate_args.setdefault(func_id, []).append((arg_kw, - arg_pos)) - # print(func_translate_args) - - # ------------------------------------------------------------------------- - # Function definitions - - def extract_strings(fp_rel, node_container): - """ Recursively get strings, needed incase we have "Blah" + "Blah", - passed as an argument in that case it wont evaluate to a string. - """ - - for node in ast.walk(node_container): - if type(node) == ast.Str: - eval_str = ast.literal_eval(node) - if eval_str: - # print("%s:%d: %s" % (fp, node.lineno, eval_str)) - msgsrc = "%s:%s" % (fp_rel, node.lineno) - messages.setdefault(eval_str, []).append(msgsrc) - - def extract_strings_from_file(fp): - filedata = open(fp, 'r', encoding="utf8") - root_node = ast.parse(filedata.read(), fp, 'exec') - filedata.close() - - fp_rel = os.path.relpath(fp, SOURCE_DIR) - - for node in ast.walk(root_node): - if type(node) == ast.Call: - # print("found function at") - # print("%s:%d" % (fp, node.lineno)) - - # lambda's - if type(node.func) == ast.Name: - continue - - # getattr(self, con.type)(context, box, con) - if not hasattr(node.func, "attr"): - continue - - translate_args = func_translate_args.get(node.func.attr, ()) - - # do nothing if not found - for arg_kw, arg_pos in translate_args: - if arg_pos < len(node.args): - extract_strings(fp_rel, node.args[arg_pos]) - else: - for kw in node.keywords: - if kw.arg == arg_kw: - extract_strings(fp_rel, kw.value) - - # ------------------------------------------------------------------------- - # Dump Messages - - mod_dir = os.path.join(SOURCE_DIR, - "release", - "scripts", - "startup", - "bl_ui") - - files = [os.path.join(mod_dir, fn) - for fn in sorted(os.listdir(mod_dir)) - if not fn.startswith("_") - if fn.endswith("py") - ] - - for fp in files: - extract_strings_from_file(fp) - - -def dump_messages(): - - def filter_message(msg): - - # check for strings like ": %d" - msg_test = msg - for ignore in ("%d", "%s", "%r", # string formatting - "*", ".", "(", ")", "-", "/", "\\", "+", ":", "#", "%" - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", - "x", # used on its own eg: 100x200 - "X", "Y", "Z", # used alone. no need to include - ): - msg_test = msg_test.replace(ignore, "") - msg_test = msg_test.strip() - if not msg_test: - # print("Skipping: '%s'" % msg) - return True - - # we could filter out different strings here - - return False - - if 1: - import collections - messages = collections.OrderedDict() - else: - messages = {} - - messages[""] = [] - - # get strings from RNA - dump_messages_rna(messages) - - # get strings from UI layout definitions text="..." args - dump_messages_pytext(messages) - - del messages[""] - - message_file = open(FILE_NAME_MESSAGES, 'w', encoding="utf8") - # message_file.writelines("\n".join(sorted(messages))) - - for key, value in messages.items(): - - # filter out junk values - if filter_message(key): - continue - - for msgsrc in value: - message_file.write("%s%s\n" % (COMMENT_PREFIX, msgsrc)) - message_file.write("%s\n" % key) - - message_file.close() - - print("Written %d messages to: %r" % (len(messages), FILE_NAME_MESSAGES)) - - -def main(): - - try: - import bpy - except ImportError: - print("This script must run from inside blender") - return - - dump_messages() - - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() diff --git a/po/update_po.py b/po/update_po.py deleted file mode 100755 index 0aab8c75646..00000000000 --- a/po/update_po.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 all po files in the LANGS - -import subprocess -import os -import sys - -GETTEXT_MSGMERGE_EXECUTABLE = "msgmerge" -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) -DOMAIN = "blender" - - -def process_po(po): - lang = os.path.basename(po)[:-3] - - # update po file - cmd = (GETTEXT_MSGMERGE_EXECUTABLE, - "--update", - "--backup=none", - "--lang=%s" % lang, - os.path.join(CURRENT_DIR, "%s.po" % lang), - os.path.join(CURRENT_DIR, "%s.pot" % DOMAIN), - ) - - print(" ".join(cmd)) - process = subprocess.Popen(cmd) - process.wait() - - -def main(): - if len(sys.argv) > 1: - for lang in sys.argv[1:]: - po = os.path.join(CURRENT_DIR, lang + '.po') - - if os.path.exists(po): - process_po(po) - else: - for po in os.listdir(CURRENT_DIR): - if po.endswith(".po"): - process_po(po) - - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() diff --git a/po/update_pot.py b/po/update_pot.py deleted file mode 100755 index c5f9acb9f42..00000000000 --- a/po/update_pot.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 subprocess -import os -from codecs import open - -GETTEXT_XGETTEXT_EXECUTABLE = "xgettext" -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) -SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(CURRENT_DIR, ".."))) -DOMAIN = "blender" -COMMENT_PREFIX = "#~ " # from update_msg.py - -FILE_NAME_POT = os.path.join(CURRENT_DIR, "blender.pot") -FILE_NAME_MESSAGES = os.path.join(CURRENT_DIR, "messages.txt") - - -def main(): - cmd = (GETTEXT_XGETTEXT_EXECUTABLE, - "--files-from=%s" % os.path.join(SOURCE_DIR, "po", "POTFILES.in"), - "--keyword=_", - "--keyword=N_", - "--directory=%s" % SOURCE_DIR, - "--output=%s" % os.path.join(SOURCE_DIR, "po", "%s.pot" % DOMAIN), - "--from-code=utf-8", - ) - - print(" ".join(cmd)) - process = subprocess.Popen(cmd) - process.wait() - - def stripeol(s): - return s.rstrip("\n\r") - - pot_messages = {} - reading_message = False - message = "" - with open(FILE_NAME_POT, '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 - pot_messages[message] = True - elif reading_message: - message += line[1:-1] - - # add messages collected automatically from RNA - with open(FILE_NAME_POT, "a", "utf-8") as pot_handle: - with open(FILE_NAME_MESSAGES, 'r', "utf-8") as handle: - msgsrc_ls = [] - while True: - line = handle.readline() - - if not line: - break - - line = stripeol(line) - - # COMMENT_PREFIX - if line.startswith(COMMENT_PREFIX): - msgsrc_ls.append(line[len(COMMENT_PREFIX):].strip()) - else: - line = line.replace("\\", "\\\\") - line = line.replace("\"", "\\\"") - line = line.replace("\t", "\\t") - - if not pot_messages.get(line): - for msgsrc in msgsrc_ls: - pot_handle.write("#: %s\n" % msgsrc) - pot_handle.write("msgid \"%s\"\n" % line) - pot_handle.write("msgstr \"\"\n\n") - msgsrc_ls[:] = [] - - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() |