[Checkins] SVN: z3c.recipe.i18n/ Added initial implementation
Roger Ineichen
roger at projekt01.ch
Wed Apr 30 18:11:58 EDT 2008
Log message for revision 85935:
Added initial implementation
Changed:
A z3c.recipe.i18n/branches/
A z3c.recipe.i18n/tags/
A z3c.recipe.i18n/trunk/
A z3c.recipe.i18n/trunk/CHANGES.txt
A z3c.recipe.i18n/trunk/README.txt
A z3c.recipe.i18n/trunk/bootstrap.py
A z3c.recipe.i18n/trunk/buildout.cfg
A z3c.recipe.i18n/trunk/setup.py
A z3c.recipe.i18n/trunk/src/
A z3c.recipe.i18n/trunk/src/z3c/
A z3c.recipe.i18n/trunk/src/z3c/__init__.py
A z3c.recipe.i18n/trunk/src/z3c/recipe/
A z3c.recipe.i18n/trunk/src/z3c/recipe/__init__.py
A z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/
A z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/README.txt
A z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/__init__.py
A z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18n.py
A z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nextract.py
A z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nmergeall.py
A z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nstats.py
A z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/testing.zcml
A z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/tests.py
-=-
Added: z3c.recipe.i18n/trunk/CHANGES.txt
===================================================================
--- z3c.recipe.i18n/trunk/CHANGES.txt (rev 0)
+++ z3c.recipe.i18n/trunk/CHANGES.txt 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,8 @@
+=======
+CHANGES
+=======
+
+Version 0.5.0 (unreleased)
+--------------------------
+
+- Initial Release
Property changes on: z3c.recipe.i18n/trunk/CHANGES.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/README.txt
===================================================================
--- z3c.recipe.i18n/trunk/README.txt (rev 0)
+++ z3c.recipe.i18n/trunk/README.txt 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,2 @@
+This Zope 3 recipes offers different tools which allows to extract i18n
+translation messages from egg based packages.
Property changes on: z3c.recipe.i18n/trunk/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/bootstrap.py
===================================================================
--- z3c.recipe.i18n/trunk/bootstrap.py (rev 0)
+++ z3c.recipe.i18n/trunk/bootstrap.py 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2008 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.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id:$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+try:
+ import pkg_resources
+except ImportError:
+ ez = {}
+ exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+ import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
+
Property changes on: z3c.recipe.i18n/trunk/bootstrap.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/buildout.cfg
===================================================================
--- z3c.recipe.i18n/trunk/buildout.cfg (rev 0)
+++ z3c.recipe.i18n/trunk/buildout.cfg 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,7 @@
+[buildout]
+parts = test
+develop = .
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3c.recipe.i18n [test]
Added: z3c.recipe.i18n/trunk/setup.py
===================================================================
--- z3c.recipe.i18n/trunk/setup.py (rev 0)
+++ z3c.recipe.i18n/trunk/setup.py 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,79 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation 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.
+#
+##############################################################################
+"""Setup
+
+$Id:$
+"""
+import os
+import xml.sax.saxutils
+from setuptools import setup, find_packages
+
+
+def read(*rnames):
+ text = open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+ return xml.sax.saxutils.escape(text)
+
+setup(
+ name = 'z3c.recipe.i18n',
+ version = '0.5.0dev',
+ author = 'Roger Ineichen and the Zope Community',
+ author_email = 'zope-dev at zope.org',
+ description = 'Zope3 development server setup recipes',
+ long_description=(
+ read('README.txt')
+ + '\n\n' +
+ 'Detailed Documentation\n'
+ '**********************'
+ + '\n\n' +
+ read('src', 'z3c', 'recipe', 'i18n', 'README.txt')
+ + '\n\n' +
+ read('CHANGES.txt')
+ ),
+ license = 'ZPL 2.1',
+ keywords = 'zope3 z3c i18n locales extraction recipe',
+ classifiers = [
+ 'Development Status :: 3 - Alpha',
+ 'Environment :: Web Environment',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Programming Language :: Python',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Framework :: Zope3'],
+ url = 'http://pypi.python.org/pypi/z3c.recipe.i18n',
+ packages = find_packages('src'),
+ include_package_data = True,
+ package_dir = {'':'src'},
+ namespace_packages = ['z3c', 'z3c.recipe'],
+ extras_require = dict(
+ test = [
+ 'zope.testing',
+ 'zope.app.locales',
+ ],
+ ),
+ install_requires = [
+ 'ZConfig >=2.4a5',
+ 'setuptools',
+ 'zc.buildout',
+ 'zc.recipe.egg',
+ 'zope.testing',
+ 'zope.configuration',
+ ],
+ entry_points = {
+ 'zc.buildout': [
+ 'i18n = z3c.recipe.i18n.i18n:I18nSetup',
+ ]
+ },
+)
Property changes on: z3c.recipe.i18n/trunk/setup.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/src/z3c/__init__.py
===================================================================
--- z3c.recipe.i18n/trunk/src/z3c/__init__.py (rev 0)
+++ z3c.recipe.i18n/trunk/src/z3c/__init__.py 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,7 @@
+# this is a namespace package
+try:
+ import pkg_resources
+ pkg_resources.declare_namespace(__name__)
+except ImportError:
+ import pkgutil
+ __path__ = pkgutil.extend_path(__path__, __name__)
Property changes on: z3c.recipe.i18n/trunk/src/z3c/__init__.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/src/z3c/recipe/__init__.py
===================================================================
--- z3c.recipe.i18n/trunk/src/z3c/recipe/__init__.py (rev 0)
+++ z3c.recipe.i18n/trunk/src/z3c/recipe/__init__.py 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,6 @@
+# namespace package boilerplate
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError, e:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
Property changes on: z3c.recipe.i18n/trunk/src/z3c/recipe/__init__.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/README.txt
===================================================================
--- z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/README.txt (rev 0)
+++ z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/README.txt 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,280 @@
+=============================
+Translation domain extraction
+=============================
+
+z3c.recipe.start
+----------------
+
+This Zope 3 recipes offers different tools which allows to extract i18n
+translation messages from egg based packages.
+
+The 'i18n' recipe can be used to generate the required scripts for extract
+message ids from egg based packages. The i18nmerge allows to merge them into
+a *.po file. And the i18nstats script gives you an overview about the state
+of the translated files.
+
+Note
+----
+
+This i18nextract.py file uses different semantic for the arguments. The script
+offers to define egg packages instead of one package path. This makes it easy
+to define eggs as source where we extract the messages from.
+
+
+Options
+*******
+
+The 'app' recipe accepts the following options:
+
+eggs
+ The names of one or more eggs, with their dependencies that should
+ be included in the Python path of the generated scripts.
+
+packages
+ The names of one or more eggs which the messages should get extracted from.
+ Note, this is different to the original zope.app.locales implementation.
+ The original implementation uses one path as -d argument which assumes a
+ specific zope.* package structure with a lod style trunk setup.
+
+domain
+ The translation domain.
+
+output
+ The path of the output file relative to the package root.
+
+maker
+ One or more module name which can get used as additional maker. This module
+ must be located in the python path because it get resolved by
+ zope.configuration.name.resolve. For a sample maker see
+ z3c.csvvocabulary.csvStrings.
+
+zcml (required)
+ The contents of configuration used for extraction. Normaly used for load
+ meta configuration.
+
+excludeDefaultDomain (optional, default=False)
+ 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. (False if not used)
+
+pythonOnly (optional, default=False)
+ Only extract message ids from Python (False if not used)
+
+exludeDirectoryName (optional, default=[])
+ Allows to specify one or more directory name, relative to the package, to
+ exclude. (None if not used)
+
+Test
+****
+
+Lets define some (bogus) eggs that we can use in our application:
+
+ >>> mkdir('outputDir')
+ >>> mkdir('demo1')
+ >>> write('demo1', 'setup.py',
+ ... '''
+ ... from setuptools import setup
+ ... setup(name = 'demo1')
+ ... ''')
+
+ >>> mkdir('demo2')
+ >>> write('demo2', 'setup.py',
+ ... '''
+ ... from setuptools import setup
+ ... setup(name = 'demo2', install_requires='demo1')
+ ... ''')
+
+Lets create a minimal `buildout.cfg` file:
+
+ >>> write('buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... parts = i18n
+ ... offline = true
+ ...
+ ... [i18n]
+ ... recipe = z3c.recipe.i18n:i18n
+ ... eggs = z3c.recipe.i18n
+ ... packages = demo1
+ ... domain = recipe
+ ... output = outputDir
+ ... zcml = <include package="z3c.recipe.tests" file="extract.zcml" />"
+ ... ''' % globals())
+
+Now, Let's run the buildout and see what we get:
+
+ >>> print system(join('bin', 'buildout')),
+ Installing i18n.
+ i18n: setting up i18n tools
+ Generated script 'bin\\i18nextract'.
+ Generated script 'bin\\i18nmergeall'.
+ Generated script 'bin\\i18nstats'.
+
+After running buildout, the bin folder contains the different i18n script:
+
+ >>> ls('bin')
+ - buildout-script.py
+ - buildout.exe
+ - i18nextract-script.py
+ - i18nextract.exe
+ - i18nmergeall-script.py
+ - i18nmergeall.exe
+ - i18nstats-script.py
+ - i18nstats.exe
+
+
+i18nextract
+-----------
+
+The i18nextract.py contains the following code:
+
+ >>> cat('bin', 'i18nextract-script.py')
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ ...
+ ]
+ <BLANKLINE>
+ import z3c.recipe.i18n.i18nextract
+ <BLANKLINE>
+ if __name__ == '__main__':
+ z3c.recipe.i18n.i18nextract.main(['i18nextract', '-d', 'recipe', '-s', '/sample-buildout/parts/i18n/configure.zcml', '-o', '/sample-buildout/outputDir', '-p', 'demo1'])
+
+i18nmergeall
+------------
+
+The i18nmergeall.py contains the following code:
+
+ >>> cat('bin', 'i18nmergeall-script.py')
+ #!C:\Python24\python.exe
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ ...
+ ]
+ <BLANKLINE>
+ import z3c.recipe.i18n.i18nmergeall
+ <BLANKLINE>
+ if __name__ == '__main__':
+ z3c.recipe.i18n.i18nmergeall.main(['i18nmergeall', '-l', '...outputDir'])
+
+i18nstats
+---------
+
+The i18nstats.py contains the following code:
+
+ >>> cat('bin', 'i18nstats-script.py')
+ #!C:\Python24\python.exe
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ ...
+ ]
+ <BLANKLINE>
+ import z3c.recipe.i18n.i18nstats
+ <BLANKLINE>
+ if __name__ == '__main__':
+ z3c.recipe.i18n.i18nstats.main(['i18nstats', '-l', '...outputDir'])
+
+
+Full Sample
+-----------
+
+Lets create a `buildout.cfg` file using all available arguments:
+
+ >>> write('buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... parts = i18n
+ ... offline = true
+ ...
+ ... [i18n]
+ ... recipe = z3c.recipe.i18n:i18n
+ ... eggs = z3c.recipe.i18n
+ ... packages = demo1
+ ... domain = recipe
+ ... output = outputDir
+ ... zcml = <include package="z3c.recipe.tests" file="extract.zcml" />"
+ ... maker = z3c.csvvocabulary.csvStrings
+ ... excludeDefaultDomain = true
+ ... pythonOnly = true
+ ... exludeDirectoryName = foo
+ ... bar
+ ... ''' % globals())
+
+Now, Let's run the buildout and see what we get:
+
+ >>> print system(join('bin', 'buildout')),
+ Uninstalling i18n.
+ Installing i18n.
+ i18n: setting up i18n tools
+ Generated script 'bin\\i18nextract'.
+ Generated script 'bin\\i18nmergeall'.
+ Generated script 'bin\\i18nstats'.
+
+After running buildout, the bin folder contains the different i18n script:
+
+ >>> ls('bin')
+ - buildout-script.py
+ - buildout.exe
+ - i18nextract-script.py
+ - i18nextract.exe
+ - i18nmergeall-script.py
+ - i18nmergeall.exe
+ - i18nstats-script.py
+ - i18nstats.exe
+
+
+i18nextract
+-----------
+
+The i18nextract.py contains the following code:
+
+ >>> cat('bin', 'i18nextract-script.py')
+ #!C:\Python24\python.exe
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ ...
+ ]
+ <BLANKLINE>
+ import z3c.recipe.i18n.i18nextract
+ <BLANKLINE>
+ if __name__ == '__main__':
+ z3c.recipe.i18n.i18nextract.main(['i18nextract', '-d', 'recipe', '-s', '/sample-buildout/parts/i18n/configure.zcml', '-o', '/sample-buildout/outputDir', '--exclude-default-domain', '--python-only', '-m', 'z3c.csvvocabulary.csvStrings', '-p', 'demo1', '-x', 'foo', '-x', 'bar'])
+
+i18nmergeall
+------------
+
+The i18nmergeall.py contains the following code:
+
+ >>> cat('bin', 'i18nmergeall-script.py')
+ #!C:\Python24\python.exe
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ ...
+ ]
+ <BLANKLINE>
+ import z3c.recipe.i18n.i18nmergeall
+ <BLANKLINE>
+ if __name__ == '__main__':
+ z3c.recipe.i18n.i18nmergeall.main(['i18nmergeall', '-l', '...outputDir'])
+
+i18nstats
+---------
+
+The i18nstats.py contains the following code:
+
+ >>> cat('bin', 'i18nstats-script.py')
+ #!C:\Python24\python.exe
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ ...
+ ]
+ <BLANKLINE>
+ import z3c.recipe.i18n.i18nstats
+ <BLANKLINE>
+ if __name__ == '__main__':
+ z3c.recipe.i18n.i18nstats.main(['i18nstats', '-l', '...outputDir'])
Property changes on: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/__init__.py
===================================================================
--- z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/__init__.py (rev 0)
+++ z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/__init__.py 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1 @@
+# make a package
Property changes on: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/__init__.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18n.py
===================================================================
--- z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18n.py (rev 0)
+++ z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18n.py 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,150 @@
+##############################################################################
+#
+# Copyright (c) 2008 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.
+#
+##############################################################################
+"""
+$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('z3c.recipe.i18n')).location
+
+
+zcmlTemplate = """<configure xmlns='http://namespaces.zope.org/zope'
+ xmlns:meta="http://namespaces.zope.org/meta"
+ >
+
+ %s
+
+</configure>
+"""
+
+
+class I18nSetup(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'
+ 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()
+
+ excludeDefaultDomain = self.options.get('excludeDefaultDomain',
+ False)
+
+ pythonOnly = self.options.get('pythonOnly', False)
+
+ # setup configuration file
+ zcml = self.options.get('zcml', None)
+ if zcml is None:
+ raise zc.buildout.UserError('No zcml configuration defined.')
+ zcml = zcmlTemplate % zcml
+
+ # get domain
+ domain = self.options.get('domain', None)
+ if domain is None:
+ raise zc.buildout.UserError('No domain given.')
+
+ # get output path
+ output = self.options.get('output', None)
+ if output is None:
+ raise zc.buildout.UserError('No output path given.')
+ output = os.path.abspath(output)
+
+ partsDir = os.path.join(
+ self.buildout['buildout']['parts-directory'],
+ self.name,
+ )
+ if not os.path.exists(partsDir):
+ os.mkdir(partsDir)
+ zcmlFilename = os.path.join(partsDir, 'configure.zcml')
+ file(zcmlFilename, 'w').write(zcml)
+
+ # Generate i18nextract
+ arguments = ['%sextract'% self.name,
+ '-d', domain,
+ '-s', zcmlFilename,
+ '-o', output,
+ ]
+
+ if excludeDefaultDomain:
+ arguments.extend(['--exclude-default-domain'])
+
+ if pythonOnly:
+ arguments.extend(['--python-only'])
+
+ makers = [m for m in self.options.get('maker', '').split() if m!='']
+ for m in makers:
+ arguments.extend(['-m', m])
+
+ # add package names as -p multi option
+ packages = [p for p in self.options.get('packages', '').split()
+ if p!='']
+ for p in packages:
+ arguments.extend(['-p', p])
+
+ exludeDirNames = [x for x
+ in self.options.get('exludeDirectoryName', '').split()
+ if x!='']
+ for x in exludeDirNames:
+ arguments.extend(['-x', x])
+
+ generated = zc.buildout.easy_install.scripts(
+ [('%sextract'% self.name, 'z3c.recipe.i18n.i18nextract', 'main')],
+ ws, self.options['executable'], 'bin',
+ extra_paths = [this_loc],
+ arguments = arguments,
+ )
+
+ # Generate i18nmergeall
+ arguments = ['%smergeall'% self.name, '-l', output]
+ generated.extend(
+ zc.buildout.easy_install.scripts(
+ [('%smergeall'% self.name,
+ 'z3c.recipe.i18n.i18nmergeall',
+ 'main')],
+ ws, self.options['executable'], 'bin',
+ extra_paths = [this_loc],
+ arguments = arguments,
+ ))
+
+ # Generate i18nstats
+
+ arguments = ['%sstats'% self.name, '-l', output]
+ generated.extend(
+ zc.buildout.easy_install.scripts(
+ [('%sstats'% self.name,
+ 'z3c.recipe.i18n.i18nstats',
+ 'main')],
+ ws, self.options['executable'], 'bin',
+ extra_paths = [this_loc],
+ arguments = arguments,
+ ))
+
+ return generated
Property changes on: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18n.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nextract.py
===================================================================
--- z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nextract.py (rev 0)
+++ z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nextract.py 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,164 @@
+#!/usr/bin/env python2.4
+##############################################################################
+#
+# Copyright (c) 2008 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 located in egg packages.
+
+This tool will extract all findable message strings from all
+internationalizable files in your defined eggs product. It only extracts
+message ids of the specified domain. It defaults to the 'z3c' domain and the
+z3c package whihc use the shared 'z3c' i18n namespace.
+
+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 as a buildout installed script.
+
+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. 'z3c')
+ -p / --package <egg>
+ Specifies the egg package that is supposed to be searched
+ (i.e. 'z3c.form')
+ -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 the directory path in which to put the output translation
+ template.
+ -x dir
+ Specifies a directory, relative to the package, to exclude. Note this
+ is only a directory name an not a path
+ 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 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 = 'z3c'
+ include_default_domain = True
+ output_dir = None
+ exclude_dirs = []
+ python_only = False
+ site_zcml = None
+ makers = []
+ paths = []
+ 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', '--package'):
+ package = resolve(arg)
+ path = os.path.dirname(package.__file__)
+ if not os.path.exists(path):
+ usage(1, 'The specified path does not exist.')
+ paths.append(path)
+
+ # 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]
+
+ # setup output file
+ output_file = domain+'.pot'
+ if output_dir:
+ if not os.path.exists(output_dir):
+ os.mkdir(output_dir)
+ output_file = os.path.join(output_dir, output_file)
+
+ print "domain: %r\n" \
+ "configuration: %s\n" \
+ "exclude dirs: %r\n" \
+ "include default domain: %r\n" \
+ "python only: %r\n" \
+ % (domain, site_zcml, exclude_dirs, include_default_domain,
+ python_only)
+
+ from zope.app.locales.extract import POTMaker
+ from zope.app.locales.extract import py_strings
+ from zope.app.locales.extract import tal_strings
+ from zope.app.locales.extract import zcml_strings
+
+ # setup pot maker
+ maker = POTMaker(output_file, '')
+
+ # add maker for each given path
+ for path in paths:
+ src_start = path.rfind('src')
+ base_dir = path[:src_start]
+ packagePath = path[len(base_dir):]
+
+ print "package: %r\n" \
+ "base: %r\n" \
+ "path: %r\n" \
+ % (packagePath, base_dir, 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()
+ print "output: %r\n" % output_file
+
+
+if __name__ == '__main__':
+ main()
Property changes on: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nextract.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nmergeall.py
===================================================================
--- z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nmergeall.py (rev 0)
+++ z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nmergeall.py 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,91 @@
+#!/usr/bin/env python2.4
+##############################################################################
+#
+# Copyright (c) 2008 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: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nmergeall.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nstats.py
===================================================================
--- z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nstats.py (rev 0)
+++ z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nstats.py 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,171 @@
+#!/usr/bin/env python2.4
+##############################################################################
+#
+# Copyright (c) 2008 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.
+#
+##############################################################################
+"""Translation Statistics Utility
+
+Utility to determine the status of the translations.
+
+Usage: i18nstats.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
+
+SEARCHING = 0
+COMMENT = 1
+MSGID = 2
+MSGSTR = 3
+MSGDONE = 4
+
+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 getMessageDictionary(file):
+ """Simple state machine."""
+
+ msgs = []
+ comment = []
+ msgid = []
+ msgstr = []
+ fuzzy = False
+ line_counter = 0
+ status = SEARCHING
+
+ for line in file.readlines():
+ line = line.strip('\n')
+ line_counter += 1
+
+ # Handle Events
+ if line.startswith('#'):
+ status = COMMENT
+
+ elif line.startswith('msgid'):
+ line = line[6:]
+ line_number = line_counter
+ status = MSGID
+
+ elif line.startswith('msgstr'):
+ line = line[7:]
+ status = MSGSTR
+
+ elif line == '':
+ status = MSGDONE
+
+ # Actions based on status
+ if status == MSGID:
+ msgid.append(line.strip('"'))
+
+ elif status == MSGSTR:
+ msgstr.append(line.strip('"'))
+
+ elif status == COMMENT:
+ if line.startswith('#, fuzzy'):
+ fuzzy = True
+ comment.append(line[1:].strip())
+
+ elif status == MSGDONE:
+ status = SEARCHING
+ # Avoid getting the meta-data message string
+ if ''.join(msgid):
+ msgs.append( (''.join(msgid), ''.join(msgstr),
+ line_number, '\n'.join(comment), fuzzy) )
+ comment = []
+ msgid = []
+ msgstr = []
+ fuzzy = False
+
+ return msgs
+
+
+def stats(path):
+ print 'Language Total Done Not Done Fuzzy Done %'
+ print '=========================================================='
+ languages = os.listdir(path)
+ languages.sort()
+ for language in languages:
+ lc_messages_path = os.path.join(path, language, 'LC_MESSAGES')
+
+ # 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)
+ file = open(domain_path, mode='r')
+ msgs += getMessageDictionary(file)
+
+ # We are dealing with the default language, which always has just one
+ # message string for the meta data (which is not recorded).
+ if len(msgs) == 0:
+ continue
+
+ total = len(msgs)
+ not_done = len([msg for msg in msgs if msg[1] == ''])
+ fuzzy = len([msg for msg in msgs if msg[4] is True])
+ done = total - not_done - fuzzy
+ percent_done = 100.0 * done/total
+
+ line = language + ' '*(8-len(language))
+ line += ' '*(9-len(str(total))) + str(total)
+ line += ' '*(8-len(str(done))) + str(done)
+ line += ' '*(12-len(str(not_done))) + str(not_done)
+ line += ' '*(9-len(str(fuzzy))) + str(fuzzy)
+ pd_str = '%0.2f %%' %percent_done
+ line += ' '*(12-len(pd_str)) + pd_str
+ print line
+
+
+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.')
+ stats(path)
+
+if __name__ == '__main__':
+ main()
+
Property changes on: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/i18nstats.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/testing.zcml
===================================================================
--- z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/testing.zcml (rev 0)
+++ z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/testing.zcml 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1 @@
+<!-- just for testing -->
\ No newline at end of file
Property changes on: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/testing.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/tests.py
===================================================================
--- z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/tests.py (rev 0)
+++ z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/tests.py 2008-04-30 22:11:58 UTC (rev 85935)
@@ -0,0 +1,133 @@
+##############################################################################
+#
+# Copyright (c) 2008 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.
+#
+##############################################################################
+
+import os, re
+import pkg_resources
+
+import zc.buildout.testing
+
+import unittest
+import zope.testing
+from zope.testing import doctest, renormalizing
+
+
+def setUp(test):
+ zc.buildout.testing.buildoutSetUp(test)
+ zc.buildout.testing.install_develop('RestrictedPython', test)
+ zc.buildout.testing.install_develop('ZConfig', test)
+ zc.buildout.testing.install_develop('ZODB3', test)
+ zc.buildout.testing.install_develop('pytz', test)
+ zc.buildout.testing.install_develop('z3c.recipe.i18n', test)
+ zc.buildout.testing.install_develop('zc.recipe.egg', test)
+ zc.buildout.testing.install_develop('zdaemon', test)
+ zc.buildout.testing.install_develop('zodbcode', test)
+ zc.buildout.testing.install_develop('zope.annotation', test)
+ zc.buildout.testing.install_develop('zope.app.applicationcontrol', test)
+ zc.buildout.testing.install_develop('zope.app.appsetup', test)
+ zc.buildout.testing.install_develop('zope.app.authentication', test)
+ zc.buildout.testing.install_develop('zope.app.basicskin', test)
+ zc.buildout.testing.install_develop('zope.app.broken', test)
+ zc.buildout.testing.install_develop('zope.app.component', test)
+ zc.buildout.testing.install_develop('zope.app.container', test)
+ zc.buildout.testing.install_develop('zope.app.content', test)
+ zc.buildout.testing.install_develop('zope.app.debug', test)
+ zc.buildout.testing.install_develop('zope.app.dependable', test)
+ zc.buildout.testing.install_develop('zope.app.error', test)
+ zc.buildout.testing.install_develop('zope.app.exception', test)
+ zc.buildout.testing.install_develop('zope.app.folder', test)
+ zc.buildout.testing.install_develop('zope.app.form', test)
+ zc.buildout.testing.install_develop('zope.app.generations', test)
+ zc.buildout.testing.install_develop('zope.app.http', test)
+ zc.buildout.testing.install_develop('zope.app.i18n', test)
+ zc.buildout.testing.install_develop('zope.app.interface', test)
+ zc.buildout.testing.install_develop('zope.app.locales', test)
+ zc.buildout.testing.install_develop('zope.app.pagetemplate', test)
+ zc.buildout.testing.install_develop('zope.app.principalannotation', test)
+ zc.buildout.testing.install_develop('zope.app.publication', test)
+ zc.buildout.testing.install_develop('zope.app.publisher', test)
+ zc.buildout.testing.install_develop('zope.app.renderer', test)
+ zc.buildout.testing.install_develop('zope.app.rotterdam', test)
+ zc.buildout.testing.install_develop('zope.app.schema', test)
+ zc.buildout.testing.install_develop('zope.app.security', test)
+ zc.buildout.testing.install_develop('zope.app.session', test)
+ zc.buildout.testing.install_develop('zope.app.testing', test)
+ zc.buildout.testing.install_develop('zope.app.wsgi', test)
+ zc.buildout.testing.install_develop('zope.app.zapi', test)
+ zc.buildout.testing.install_develop('zope.app.zcmlfiles', test)
+ zc.buildout.testing.install_develop('zope.app.zopeappgenerations', test)
+ zc.buildout.testing.install_develop('zope.cachedescriptors', test)
+ zc.buildout.testing.install_develop('zope.component', test)
+ zc.buildout.testing.install_develop('zope.configuration', test)
+ zc.buildout.testing.install_develop('zope.contenttype', test)
+ zc.buildout.testing.install_develop('zope.copypastemove', test)
+ zc.buildout.testing.install_develop('zope.datetime', test)
+ zc.buildout.testing.install_develop('zope.deferredimport', test)
+ zc.buildout.testing.install_develop('zope.deprecation', test)
+ zc.buildout.testing.install_develop('zope.dottedname', test)
+ zc.buildout.testing.install_develop('zope.dublincore', test)
+ zc.buildout.testing.install_develop('zope.error', test)
+ zc.buildout.testing.install_develop('zope.event', test)
+ zc.buildout.testing.install_develop('zope.exceptions', test)
+ zc.buildout.testing.install_develop('zope.filerepresentation', test)
+ zc.buildout.testing.install_develop('zope.formlib', test)
+ zc.buildout.testing.install_develop('zope.hookable', test)
+ zc.buildout.testing.install_develop('zope.i18n', test)
+ zc.buildout.testing.install_develop('zope.i18nmessageid', test)
+ zc.buildout.testing.install_develop('zope.interface', test)
+ zc.buildout.testing.install_develop('zope.lifecycleevent', test)
+ zc.buildout.testing.install_develop('zope.location', test)
+ zc.buildout.testing.install_develop('zope.minmax', test)
+ zc.buildout.testing.install_develop('zope.modulealias', test)
+ zc.buildout.testing.install_develop('zope.pagetemplate', test)
+ zc.buildout.testing.install_develop('zope.proxy', test)
+ zc.buildout.testing.install_develop('zope.publisher', test)
+ zc.buildout.testing.install_develop('zope.schema', test)
+ zc.buildout.testing.install_develop('zope.security', test)
+ zc.buildout.testing.install_develop('zope.session', test)
+ zc.buildout.testing.install_develop('zope.size', test)
+ zc.buildout.testing.install_develop('zope.structuredtext', test)
+ zc.buildout.testing.install_develop('zope.tal', test)
+ zc.buildout.testing.install_develop('zope.tales', test)
+ zc.buildout.testing.install_develop('zope.testing', test)
+ zc.buildout.testing.install_develop('zope.testing', test)
+ zc.buildout.testing.install_develop('zope.thread', test)
+ zc.buildout.testing.install_develop('zope.traversing', test)
+
+
+checker = renormalizing.RENormalizing([
+ zc.buildout.testing.normalize_path,
+ (re.compile(
+ "Couldn't find index page for '[a-zA-Z0-9.]+' "
+ "\(maybe misspelled\?\)"
+ "\n"
+ ), ''),
+ (re.compile("""['"][^\n"']+z3c.recipe.i18n[^\n"']*['"],"""),
+ "'/z3c.recipe.i18n',"),
+ (re.compile('#![^\n]+\n'), ''),
+ (re.compile('-\S+-py\d[.]\d(-\S+)?.egg'),
+ '-pyN.N.egg',
+ ),
+ ])
+
+
+def test_suite():
+ return unittest.TestSuite(
+ doctest.DocFileSuite('README.txt',
+ setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
+ optionflags=doctest.ELLIPSIS, checker=checker),
+ )
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Property changes on: z3c.recipe.i18n/trunk/src/z3c/recipe/i18n/tests.py
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the Checkins
mailing list