Merge pull request #7825 from s0undt3ch/features/i18n-documentation

i18n documentation updates
This commit is contained in:
David Boucha 2013-10-14 14:49:28 -07:00
commit e4c85c61be
8 changed files with 3336 additions and 2855 deletions

View File

@ -0,0 +1,81 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
:copyright: © 2013 by the SaltStack Team, see AUTHORS for more details.
:license: Apache 2.0, see LICENSE for more details.
compile-translation-catalogs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compile the existing translation catalogs.
'''
# Import python libs
import os
import sys
import fnmatch
# Import 3rd-party libs
HAS_BABEL = False
try:
from babel.messages import mofile, pofile
HAS_BABEL = True
except ImportError:
try:
import polib
except ImportError:
print(
'You need to install either babel or pofile in order to compile '
'the message catalogs. One of:\n'
' pip install babel\n'
' pip install polib'
)
sys.exit(1)
DOC_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
LOCALES_DIR = os.path.join(DOC_DIR, 'locale')
def main():
'''
Run the compile code
'''
print('Gathering the translation catalogs to compile...'),
sys.stdout.flush()
entries = {}
for locale in os.listdir(os.path.join(LOCALES_DIR)):
if locale == 'pot':
continue
locale_path = os.path.join(LOCALES_DIR, locale)
entries[locale] = []
for dirpath, _, filenames in os.walk(locale_path):
for filename in fnmatch.filter(filenames, '*.po'):
entries[locale].append(os.path.join(dirpath, filename))
print('DONE')
for locale, po_files in sorted(entries.items()):
lc_messages_path = os.path.join(LOCALES_DIR, locale, 'LC_MESSAGES')
print('\nCompiling the {0!r} locale:'.format(locale))
for po_file in sorted(po_files):
relpath = os.path.relpath(po_file, lc_messages_path)
print ' {0}.po -> {0}.mo'.format(relpath.split('.po', 1)[0])
if HAS_BABEL:
catalog = pofile.read_po(open(po_file))
mofile.write_mo(
open(po_file.replace('.po', '.mo'), 'wb'), catalog
)
continue
catalog = polib.pofile(po_file)
catalog.save_as_mofile(fpath=po_file.replace('.po', '.mo'))
print('Done')
if __name__ == '__main__':
main()

View File

@ -0,0 +1,55 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
:copyright: © 2013 by the SaltStack Team, see AUTHORS for more details.
:license: Apache 2.0, see LICENSE for more details.
download-translation-catalog
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Download a translation catalog from Transifex.
'''
# Import python libs
import os
import sys
# Import 3rd-party libs
try:
import txclib.utils
except ImportError:
print(
'The \'transifex-client\' library needs to be installed. '
'Please execute one of \'pip install transifex-client\' or '
'\'easy_install transifex-client\''
)
sys.exit(1)
DOC_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
LOCALES_DIR = os.path.join(DOC_DIR, 'locale')
def main():
'''
Run the compile code
'''
os.chdir(DOC_DIR)
tx_root = txclib.utils.find_dot_tx()
if len(sys.argv) < 2:
print('You need to pass a locale to this script. For example: '
'pt_PT, zh_CN, ru, etc...')
sys.exit(1)
for locale in sys.argv[1:]:
print('Download {0!r} translations catalog...'.format(locale))
txclib.utils.exec_command('pull', ['-l', locale], tx_root)
print('Done')
if __name__ == '__main__':
main()

View File

@ -0,0 +1,96 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
:copyright: © 2013 by the SaltStack Team, see AUTHORS for more details.
:license: Apache 2.0, see LICENSE for more details.
setup-transifex-config
~~~~~~~~~~~~~~~~~~~~~~
Setup the Transifex client configuration file
'''
# Import python libs
import os
import sys
import getpass
import ConfigParser
HOST = 'https://www.transifex.com'
RCFILE = os.path.abspath(os.path.expanduser('~/.transifexrc'))
def main():
'''
Run the setup code
'''
print(
'This script will setup a Transifex client configuration file, or, '
'if it already exists, make some minimal checks to see if it\'s '
'properly configured\n'
)
if not os.path.exists(RCFILE):
while True:
try:
username = raw_input(
'What is your username on Transifex.com? '
)
if username:
break
except KeyboardInterrupt:
print
sys.exit(1)
while True:
try:
password = getpass.getpass(
'What is your password on Transifex.com? '
)
if password:
break
except KeyboardInterrupt:
print
sys.exit(1)
config = ConfigParser.SafeConfigParser()
config.add_section(HOST)
config.set(HOST, 'token', '')
config.set(HOST, 'hostname', HOST)
config.set(HOST, 'username', username)
config.set(HOST, 'password', password)
config.write(open(RCFILE, 'w'))
print('username and password stored in {0!r}'.format(RCFILE))
os.chmod(RCFILE, 0600)
print('Secured the permissions on {0!r} to 0600'.format(RCFILE))
sys.exit(0)
# The file exists, let's see if it's properly configured
config = ConfigParser.SafeConfigParser()
config.read([RCFILE])
if not config.has_section(HOST):
print('\'~/.transifexrc\' is not properly configured, it\'s missing '
'the {0} section'.format(HOST))
for setting in ('username', 'password', 'hostname', 'token'):
if not config.has_option(HOST, setting):
print('\'~/.transifexrc\' is not properly configured, it\'s '
'missing the {0} option'.format(setting))
sys.exit(1)
if setting == 'token':
# Token should be left empty
continue
if not config.get(HOST, setting):
print('\'~/.transifexrc\' is not properly configured, it\'s '
'missing a value for the {0} option'.format(setting))
sys.exit(1)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,208 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
:copyright: © 2013 by the SaltStack Team, see AUTHORS for more details.
:license: Apache 2.0, see LICENSE for more details.
update-transifex-source-translations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Update the transifex sources configuration file and push the source
'''
# Import python libs
import os
import sys
import logging
import subprocess
import ConfigParser
try:
import txclib.utils
except ImportError:
print(
'The \'transifex-client\' library needs to be installed. '
'Please execute one of \'pip install transifex-client\' or '
'\'easy_install transifex-client\''
)
sys.exit(1)
DOC_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
def main():
'''
Run the update code
'''
os.chdir(DOC_DIR)
print('Extracting translatable strings....')
try:
subprocess.check_call(['make', 'gettext'])
except subprocess.CalledProcessError as exc:
print('An error occurred while extracting the translation '
'strings: {0}'.format(exc))
sys.exit(1)
locale_dir = os.path.join(DOC_DIR, 'locale')
pot_dir = os.path.join(DOC_DIR, '_build', 'locale')
tx_root = txclib.utils.find_dot_tx()
tx_config = os.path.join(tx_root, '.tx', 'config')
if not tx_root:
print('Unable to find the \'.tx/\' directory. Unable to continue')
sys.exit(1)
# We do not want the txclib INFO or WARNING logging
logging.getLogger('txclib').setLevel(logging.ERROR)
print('Gathering the translation template files...'),
sys.stdout.flush()
entries = []
for dirpath, dirnames, filenames in os.walk(pot_dir):
for filename in filenames:
pot_file = os.path.join(dirpath, filename)
base, ext = os.path.splitext(pot_file)
if ext != ".pot":
continue
resource_path = os.path.relpath(base, pot_dir)
try:
import babel.messages.pofile
if not len(babel.messages.pofile.read_po(open(pot_file))):
# Empty pot file, continue
continue
except ImportError:
# No babel package, let's keep on going
pass
resource_name = resource_path.replace(
'\\', '/').replace('/', '--').replace('.', '_')
entries.append((resource_path, resource_name))
print('Done')
# Let's load the resources already present in the configuration file
cfg = ConfigParser.SafeConfigParser()
cfg.read([tx_config])
handled_resources = set(
section for section in
cfg.sections() if section.startswith('salt.')
)
print('Updating the entries in \'.tx/config\'...')
sys.stdout.flush()
total_entries = len(entries)
for idx, (resource_path, resource_name) in enumerate(sorted(entries)):
print(
'[{0:>{pad}}/{1}] Updating resource for '
'{resource_path}.pot ({resource_name})'.format(
idx + 1,
total_entries,
pad=len(str(total_entries)),
locale_dir=locale_dir,
resource_name=resource_name,
resource_path=resource_path
)
),
sys.stdout.flush()
try:
txclib.utils.exec_command(
'set',
'--auto-local -r salt.{resource_name} '
'{locale_dir}/<lang>/LC_MESSAGES/{resource_path}.po '
'--source-lang en '
'--source-file {pot_dir}/{resource_path}.pot '
'--source-name {resource_path}.rst '
'--execute'.format(
resource_name=resource_name,
resource_path=resource_path,
locale_dir=locale_dir,
pot_dir=pot_dir.rstrip('/')
).split(),
tx_root
)
print
if 'salt.{0}'.format(resource_name) in handled_resources:
handled_resources.remove('salt.{0}'.format(resource_name))
except KeyboardInterrupt:
print
sys.exit(1)
if handled_resources:
non_handled_resources = len(handled_resources)
print('Removing old resources from configuration and upstream'
'(if possible)')
for idx, resource_name in enumerate(sorted(handled_resources)):
print(
'[{0:>{pad}}/{1}] Removing resource {resource_name!r}'.format(
idx + 1,
non_handled_resources,
pad=len(str(non_handled_resources)),
resource_name=resource_name,
)
),
sys.stdout.flush()
try:
txclib.utils.exec_command(
'delete',
['-r', resource_name],
tx_root
)
except Exception, err:
print err
finally:
if cfg.has_section(resource_name):
cfg.remove_section(resource_name)
print
cfg.write(open(tx_config, 'w'))
print
# Set the translations file type we're using
txclib.utils.exec_command('set', ['-t', 'PO'], tx_root)
print
print('Pushing translation template files...')
for idx, (resource_path, resource_name) in enumerate(sorted(entries)):
print(
'[{0:>{pad}}/{1}] Pushing resource for '
'{resource_path}.pot ({resource_name})'.format(
idx + 1,
total_entries,
pad=len(str(total_entries)),
locale_dir=locale_dir,
resource_name=resource_name,
resource_path=resource_path
)
),
sys.stdout.flush()
try:
txclib.utils.exec_command(
'push',
'--resource salt.{resource_name} '
'--source '
'--skip '
'--no-interactive'.format(
resource_name=resource_name,
resource_path=resource_path,
locale_dir=locale_dir
).split(),
tx_root
)
print
except KeyboardInterrupt:
print
sys.exit(1)
if handled_resources:
print('=' * 80)
print('Don\'t forget to delete the following remote resources:')
for resource_name in sorted(handled_resources):
print(' {0}'.format(resource_name))
print('=' * 80)
print 'DONE'
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@ ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(TRANSLATIONOPTS
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext translations
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext translations download-translations
help:
@echo "Please use \`make <target>' where <target> is one of"
@ -66,24 +66,6 @@ clean:
rm -rf $(BUILDDIR)/*
find locale/ -name *.mo -exec rm {} \;
translations:
@if [ "$(SPHINXLANG)" = "en" ] || [ "x$(SPHINXLANG)" = "x" ]; then \
echo "No need to update translations. Skipping..."; \
elif [ ! -d locale/$(SPHINXLANG) ]; then \
echo "The locale directory for $(SPHINXLANG) does not exist"; \
exit 1; \
else \
echo "Extracting translatable strings"; \
make gettext; \
\
echo "Updating existing translation catalog for '$(SPHINXLANG)'"; \
sphinx-intl update -p _build/locale -l $(SPHINXLANG); \
\
echo "Compiling exising message catalog for '$(SPHINXLANG)'"; \
sphinx-intl build -l $(SPHINXLANG); \
fi
html: translations
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@ -181,9 +163,9 @@ info: translations
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) locale/pot
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in locale/pot."
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale"
changes: translations
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@ -210,3 +192,20 @@ pseudoxml: translations
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
translations:
@if [ "$(SPHINXLANG)" = "en" ] || [ "x$(SPHINXLANG)" = "x" ]; then \
echo "No need to update translations. Skipping..."; \
elif [ ! -d locale/$(SPHINXLANG) ]; then \
echo "The locale directory for $(SPHINXLANG) does not exist"; \
exit 1; \
else \
echo "Compiling exising message catalog for '$(SPHINXLANG)'"; \
.scripts/compile-translation-catalogs; \
fi
download-translations:
@echo "Downloading $(SPHINXLANG) translations"
.scripts/download-translation-catalog $(SPHINXLANG)

View File

@ -32,6 +32,7 @@ Full Table of Contents
topics/conventions/*
topics/git/*
topics/development/index
topics/translating
ref/configuration/logging/*
ref/configuration/logging/handlers/*

View File

@ -2,18 +2,59 @@ Translating Documentation
=========================
If you wish to help translate the Salt documentation to your language, please
head over to the `Transifex`_ website and `signup`_ for an account.
head over to the `Transifex`_ website and `signup`__ for an account.
Once registered, head over to the `Salt Translation Project`_, and either click
on **Request Language** if you can't find yours, or, select the language for
which you wish to contribute and click **Join Team**.
Once registered, head over to the `Salt Translation Project`__, and either
click on **Request Language** if you can't find yours, or, select the language
for which you wish to contribute and click **Join Team**.
`Transifex`_ provides some useful reading resources on their `support domain`_,
namely, some useful articles `directed to translators`_.
`Transifex`_ provides some useful reading resources on their `support
domain`__, namely, some useful articles `directed to translators`__.
.. __: https://www.transifex.com/signup/
.. __: https://www.transifex.com/projects/p/salt/
.. __: http://support.transifex.com/
.. __: http://support.transifex.com/customer/portal/topics/414107-translators/articles
Building A Localized Version of the Documentation
-------------------------------------------------
While you're working on your translation on `Transifex`_, you might want to
have a look at how it's rendering.
There's a little script which simplifies the download process of the
translations(which isn't that complicated in the first place).
So, let's assume you're translating ``pt_PT``, Portuguese(Portugal). To
download the translations, execute from the ``doc/`` directory of your Salt
checkout:
.. code-block:: bash
make download-translations SPHINXLANG=pt_PT
To download ``pt_PT``, Portuguese(Portugal) and ``nl``, Dutch, you can use the
helper script directly:
.. code-block:: bash
.scripts/download-translation-catalog pt_PT nl
After the download process finishes, which might take a while, the next step is
to build a localized version of the documentation.
Following the ``pt_PT`` example above:
.. code-block:: bash
make html SPHINXLANG=pt_PT
Open your browser, point it to the local documentation path and check the
localized output you've just build.
.. _`signup`: https://www.transifex.com/signup/
.. _`Transifex`: https://www.transifex.com
.. _`Salt Translation Project`: https://www.transifex.com/projects/p/salt/
.. _`support domain`: http://support.transifex.com/
.. _`directed to translators`: http://support.transifex.com/customer/portal/topics/414107-translators/articles