[Checkins] SVN: lovely.recipe/trunk/ - Recipe for i18nextract and i18nmerge

Jürgen Kartnaller juergen at kartnaller.at
Mon Jun 11 13:55:38 EDT 2007


Log message for revision 76616:
  - Recipe for i18nextract and i18nmerge
  - no tests right now because of the complex setup (will come soon)
  

Changed:
  U   lovely.recipe/trunk/CHANGES.txt
  U   lovely.recipe/trunk/buildout.cfg
  U   lovely.recipe/trunk/setup.py
  U   lovely.recipe/trunk/src/lovely/recipe/fs/tests.py
  A   lovely.recipe/trunk/src/lovely/recipe/i18n/
  A   lovely.recipe/trunk/src/lovely/recipe/i18n/README.txt
  A   lovely.recipe/trunk/src/lovely/recipe/i18n/__init__.py
  A   lovely.recipe/trunk/src/lovely/recipe/i18n/i18n.py
  A   lovely.recipe/trunk/src/lovely/recipe/i18n/i18nextract.py
  A   lovely.recipe/trunk/src/lovely/recipe/i18n/i18nmergeall.py

-=-
Modified: lovely.recipe/trunk/CHANGES.txt
===================================================================
--- lovely.recipe/trunk/CHANGES.txt	2007-06-11 16:22:13 UTC (rev 76615)
+++ lovely.recipe/trunk/CHANGES.txt	2007-06-11 17:55:37 UTC (rev 76616)
@@ -2,6 +2,14 @@
 Changes for lovely.recipe
 =========================
 
+
+2007/06/04 0.2.0a1:
+===================
+
+- Recipe for i18nextract and i18nmerge
+- no tests right now because of the complex setup (will come soon)
+
+
 2007/06/04 0.1a1:
 =================
 

Modified: lovely.recipe/trunk/buildout.cfg
===================================================================
--- lovely.recipe/trunk/buildout.cfg	2007-06-11 16:22:13 UTC (rev 76615)
+++ lovely.recipe/trunk/buildout.cfg	2007-06-11 17:55:37 UTC (rev 76616)
@@ -2,9 +2,9 @@
 develop = .
 parts = test
 
+find-links = http://download.zope.org/distribution
+
 [test]
 recipe = zc.recipe.testrunner
 eggs = lovely.recipe
 
-
-

Modified: lovely.recipe/trunk/setup.py
===================================================================
--- lovely.recipe/trunk/setup.py	2007-06-11 16:22:13 UTC (rev 76615)
+++ lovely.recipe/trunk/setup.py	2007-06-11 17:55:37 UTC (rev 76616)
@@ -4,11 +4,12 @@
 [zc.buildout]
 mkdir = lovely.recipe.fs.mkdir:Mkdir
 mkfile = lovely.recipe.fs.mkfile:Mkfile
+i18n = lovely.recipe.i18n.i18n:I18n
 """
 
 setup (
     name='lovely.recipe',
-    version='0.1a1',
+    version='0.2.0a1',
     author = "Lovely Systems",
     author_email = "office at lovelysystems.com",
     license = "ZPL 2.1",
@@ -20,6 +21,7 @@
     namespace_packages = ['lovely', 'lovely.recipe'],
     install_requires = ['setuptools',
                         'zc.buildout',
+                        'zc.recipe.egg',
                         ],
     entry_points = entry_points,
     zip_safe = True,

Modified: lovely.recipe/trunk/src/lovely/recipe/fs/tests.py
===================================================================
--- lovely.recipe/trunk/src/lovely/recipe/fs/tests.py	2007-06-11 16:22:13 UTC (rev 76615)
+++ lovely.recipe/trunk/src/lovely/recipe/fs/tests.py	2007-06-11 17:55:37 UTC (rev 76616)
@@ -4,6 +4,7 @@
 
 def setUp(test):
     testing.buildoutSetUp(test)
+    testing.install_develop('zc.recipe.egg', test)
     testing.install_develop('lovely.recipe', test)
 
 def test_suite():

Added: lovely.recipe/trunk/src/lovely/recipe/i18n/README.txt
===================================================================
--- lovely.recipe/trunk/src/lovely/recipe/i18n/README.txt	                        (rev 0)
+++ lovely.recipe/trunk/src/lovely/recipe/i18n/README.txt	2007-06-11 17:55:37 UTC (rev 76616)
@@ -0,0 +1,52 @@
+=================
+i18n Tools Recipe
+=================
+
+This recipe allows to create i18n tools to extract and merge po files.
+
+
+Creating The Tools
+==================
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... """
+    ... [buildout]
+    ... parts = i18n
+    ...
+    ... find-links = http://download.zope.org/distribution
+    ... offline = true
+    ...
+    ... [i18n]
+    ... recipe = lovely.recipe:i18n
+    ... package = lovely.recipe
+    ... domain = recipe
+    ... location = src/somewhere
+    ... output = locales
+    ... zcml = src/somewhere/configure.zcml
+    ... maker = z3c.csvvocabulary.csvStrings
+    ... """)
+    >>> print system(buildout),
+    Installing i18n.
+    i18n: setting up i18n tools
+    Generated script 'bin/i18nextract'.
+    Generated script 'bin/i18nmergeall'.
+
+    >>> import os
+    >>> ls(os.path.join(sample_buildout, 'bin'))
+    -  buildout
+    -  i18nextract
+    -  i18nmergeall
+
+    >>> cat('bin', 'i18nextract')
+    #!/opt/local/bin/python
+    <BLANKLINE>
+    import sys
+    sys.path[0:0] = [
+      ,
+      ]
+    <BLANKLINE>
+    import lovely.recipe.i18n.i18nextract
+    <BLANKLINE>
+    if __name__ == '__main__':
+        lovely.recipe.i18n.i18nextract.main()
+


Property changes on: lovely.recipe/trunk/src/lovely/recipe/i18n/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: lovely.recipe/trunk/src/lovely/recipe/i18n/__init__.py
===================================================================
--- lovely.recipe/trunk/src/lovely/recipe/i18n/__init__.py	                        (rev 0)
+++ lovely.recipe/trunk/src/lovely/recipe/i18n/__init__.py	2007-06-11 17:55:37 UTC (rev 76616)
@@ -0,0 +1 @@
+# make this a python package


Property changes on: lovely.recipe/trunk/src/lovely/recipe/i18n/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: lovely.recipe/trunk/src/lovely/recipe/i18n/i18n.py
===================================================================
--- lovely.recipe/trunk/src/lovely/recipe/i18n/i18n.py	                        (rev 0)
+++ lovely.recipe/trunk/src/lovely/recipe/i18n/i18n.py	2007-06-11 17:55:37 UTC (rev 76616)
@@ -0,0 +1,80 @@
+##############################################################################
+#
+# Copyright (c) 2007 Lovely Systems and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import os
+import logging
+
+import zc.buildout
+import zc.recipe.egg
+
+import pkg_resources
+
+this_loc = pkg_resources.working_set.find(
+    pkg_resources.Requirement.parse('lovely.recipe')).location
+
+
+class I18n(object):
+
+    def __init__(self, buildout, name, options):
+        self.buildout = buildout
+        self.name = name
+        self.options = options
+        if 'eggs' not in self.options:
+            self.options['eggs'] = ''
+        self.options['eggs'] =   self.options['eggs'] + '\n' \
+                               + 'zope.app.locales' + '\n' \
+                               + self.options['package']
+        self.egg = zc.recipe.egg.Egg(buildout, name, options)
+
+    def install(self):
+        logging.getLogger(self.name).info('setting up i18n tools')
+
+        requirements, ws = self.egg.working_set()
+
+        arguments = ['i18nextract',
+                     '-d', self.options.get('domain',
+                                            self.options['package']),
+                     '-p', self.options['location'],
+                     '-s', self.options['zcml'],
+                     '-o', self.options.get('output', 'locales'),
+                    ]
+        makers = [m for m in self.options.get('maker', '').split() if m!='']
+        for m in makers:
+            arguments.extend(['-m', m])
+        zc.buildout.easy_install.scripts(
+            [('i18nextract', 'lovely.recipe.i18n.i18nextract', 'main')],
+            ws, self.options['executable'], 'bin',
+            extra_paths = [this_loc],
+            arguments = arguments,
+            )
+
+        arguments = ['i18nmergeall',
+                     '-l', os.path.join(self.options['location'],
+                                        self.options.get('output', 'locales'),
+                                       ),
+                    ]
+        zc.buildout.easy_install.scripts(
+            [('i18nmergeall', 'lovely.recipe.i18n.i18nmergeall', 'main')],
+            ws, self.options['executable'], 'bin',
+            extra_paths = [this_loc],
+            arguments = arguments,
+            )
+
+        return ()
+
+


Property changes on: lovely.recipe/trunk/src/lovely/recipe/i18n/i18n.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: lovely.recipe/trunk/src/lovely/recipe/i18n/i18nextract.py
===================================================================
--- lovely.recipe/trunk/src/lovely/recipe/i18n/i18nextract.py	                        (rev 0)
+++ lovely.recipe/trunk/src/lovely/recipe/i18n/i18nextract.py	2007-06-11 17:55:37 UTC (rev 76616)
@@ -0,0 +1,179 @@
+#!/usr/bin/env python2.4
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Program to extract internationalization markup from Python Code,
+Page Templates and ZCML.
+
+This tool will extract all findable message strings from all
+internationalizable files in your Zope 3 product. It only extracts message ids
+of the specified domain. It defaults to the 'zope' domain and the zope
+package.
+
+Note: The Python Code extraction tool does not support domain
+      registration, so that all message strings are returned for
+      Python code.
+
+Note: The script expects to be executed either from inside the Zope 3 source
+      tree or with the Zope 3 source tree on the Python path.  Execution from
+      a symlinked directory inside the Zope 3 source tree will not work.
+
+Usage: i18nextract.py [options]
+Options:
+    -h / --help
+        Print this message and exit.
+    -d / --domain <domain>
+        Specifies the domain that is supposed to be extracted (i.e. 'zope')
+    -p / --path <path>
+        Specifies the package that is supposed to be searched
+        (i.e. 'zope/app')
+    -s / --site_zcml <path>
+        Specify the location of the 'site.zcml' file. By default the regular
+        Zope 3 one is used.
+    -e / --exclude-default-domain
+        Exclude all messages found as part of the default domain. Messages are
+        in this domain, if their domain could not be determined. This usually
+        happens in page template snippets.
+    -m python-function
+        Specify a python function which is added as a maker to the POTMaker.
+    -o dir
+        Specifies a directory, relative to the package in which to put the
+        output translation template.
+    -x dir
+        Specifies a directory, relative to the package, to exclude.
+        May be used more than once.
+    --python-only
+        Only extract message ids from Python
+
+$Id$
+"""
+
+from zope.configuration.name import resolve
+
+import os, sys, getopt
+def usage(code, msg=''):
+    # Python 2.1 required
+    print >> sys.stderr, __doc__
+    if msg:
+        print >> sys.stderr, msg
+    sys.exit(code)
+
+def app_dir():
+    try:
+        import zope
+    except ImportError:
+        # Couldn't import zope, need to add something to the Python path
+
+        # Get the path of the src
+        path = os.path.abspath(os.getcwd())
+        while not path.endswith('src'):
+            parentdir = os.path.dirname(path)
+            if path == parentdir:
+                # root directory reached
+                break
+            path = parentdir
+        sys.path.insert(0, path)
+
+        try:
+            import zope
+        except ImportError:
+            usage(1, "Make sure the script has been executed "
+                     "inside Zope 3 source tree.")
+
+    return os.path.dirname(zope.__file__)
+
+def main(argv=sys.argv):
+    try:
+        opts, args = getopt.getopt(
+            argv[1:],
+            'hed:s:i:m:p:o:x:',
+            ['help', 'domain=', 'site_zcml=', 'path=', 'python-only'])
+    except getopt.error, msg:
+        usage(1, msg)
+
+    domain = 'zope'
+    path = app_dir()
+    include_default_domain = True
+    output_dir = None
+    exclude_dirs = []
+    python_only = False
+    site_zcml = None
+    makers = []
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            usage(0)
+        elif opt in ('-d', '--domain'):
+            domain = arg
+        elif opt in ('-s', '--site_zcml'):
+            site_zcml = arg
+        elif opt in ('-e', '--exclude-default-domain'):
+            include_default_domain = False
+        elif opt in ('-m', ):
+            makers.append(arg)
+        elif opt in ('-o', ):
+            output_dir = arg
+        elif opt in ('-x', ):
+            exclude_dirs.append(arg)
+        elif opt in ('--python-only',):
+            python_only = True
+        elif opt in ('-p', '--path'):
+            if not os.path.exists(arg):
+                usage(1, 'The specified path does not exist.')
+            path = arg
+            # We might not have an absolute path passed in.
+            if not path == os.path.abspath(path):
+                cwd = os.getcwd()
+                # This is for symlinks. Thanks to Fred for this trick.
+                if os.environ.has_key('PWD'):
+                    cwd = os.environ['PWD']
+                path = os.path.normpath(os.path.join(cwd, arg))
+
+    # When generating the comments, we will not need the base directory info,
+    # since it is specific to everyone's installation
+    src_start = path.rfind('src')
+    base_dir = path[:src_start]
+
+    output_file = domain+'.pot'
+    if output_dir:
+        output_dir = os.path.join(path, output_dir)
+        if not os.path.exists(output_dir):
+            os.mkdir(output_dir)
+        output_file = os.path.join(output_dir, output_file)
+
+    print "base path: %r\n" \
+          "search path: %s\n" \
+          "'site.zcml' location: %s\n" \
+          "exclude dirs: %r\n" \
+          "domain: %r\n" \
+          "include default domain: %r\n" \
+          "output file: %r\n" \
+          "Python only: %r" \
+          % (base_dir, path, site_zcml, exclude_dirs, domain,
+             include_default_domain, output_file, python_only)
+
+    from zope.app.locales.extract import POTMaker, \
+         py_strings, tal_strings, zcml_strings
+
+    maker = POTMaker(output_file, path)
+    maker.add(py_strings(path, domain, exclude=exclude_dirs), base_dir)
+    if not python_only:
+        maker.add(zcml_strings(path, domain, site_zcml), base_dir)
+        maker.add(tal_strings(path, domain, include_default_domain,
+                              exclude=exclude_dirs), base_dir)
+    for m in makers:
+        poMaker = resolve(m)
+        maker.add(poMaker(path, base_dir, exclude_dirs))
+    maker.write()
+
+if __name__ == '__main__':
+    main()


Property changes on: lovely.recipe/trunk/src/lovely/recipe/i18n/i18nextract.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: lovely.recipe/trunk/src/lovely/recipe/i18n/i18nmergeall.py
===================================================================
--- lovely.recipe/trunk/src/lovely/recipe/i18n/i18nmergeall.py	                        (rev 0)
+++ lovely.recipe/trunk/src/lovely/recipe/i18n/i18nmergeall.py	2007-06-11 17:55:37 UTC (rev 76616)
@@ -0,0 +1,91 @@
+#!/usr/bin/env python2.4
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Merge a POT file with all languages
+
+This utility requires the GNU gettext package to be installed. The command
+'msgmerge' will be executed for each language.
+
+Usage: i18mergeall.py [options]
+Options:
+
+    -h / --help
+        Print this message and exit.
+
+    -l / --locales-dir
+        Specify the 'locales' directory for which to generate the statistics.
+
+$Id$
+"""
+import sys
+import os
+import getopt
+
+def usage(code, msg=''):
+    """Display help."""
+    print >> sys.stderr, '\n'.join(__doc__.split('\n')[:-2])
+    if msg:
+        print >> sys.stderr, '** Error: ' + str(msg) + ' **'
+    sys.exit(code)
+
+
+def merge(path):
+    for language in os.listdir(path):
+        lc_messages_path = os.path.join(path, language, 'LC_MESSAGES')
+
+        # English is the default for Zope, so ignore it
+        #if language == 'en':
+        #    continue
+
+        # Make sure we got a language directory
+        if not os.path.isdir(lc_messages_path):
+            continue
+
+        msgs = []
+        for domain_file in os.listdir(lc_messages_path):
+            if domain_file.endswith('.po'):
+                domain_path = os.path.join(lc_messages_path, domain_file)
+                pot_path = os.path.join(path, domain_file+'t')
+                domain = domain_file.split('.')[0]
+                print 'Merging language "%s", domain "%s"' %(language, domain)
+                os.system('msgmerge -U %s %s' %(domain_path, pot_path))
+
+
+def main(argv=sys.argv):
+    try:
+        opts, args = getopt.getopt(
+            argv[1:],
+            'l:h',
+            ['help', 'locals-dir='])
+    except getopt.error, msg:
+        usage(1, msg)
+
+    path = None
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            usage(0)
+        elif opt in ('-l', '--locales-dir'):
+            cwd = os.getcwd()
+            # This is for symlinks. Thanks to Fred for this trick.
+            if os.environ.has_key('PWD'):
+                cwd = os.environ['PWD']
+            path = os.path.normpath(os.path.join(cwd, arg))
+
+    if path is None:
+        usage(1, 'You must specify the path to the locales directory.')
+    merge(path)
+
+if __name__ == '__main__':
+    main()
+


Property changes on: lovely.recipe/trunk/src/lovely/recipe/i18n/i18nmergeall.py
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native



More information about the Checkins mailing list