Skip to content

Commit

Permalink
Changes to setup.py:
Browse files Browse the repository at this point in the history
	- New translation process, handled by the babel module.
	- Translations moved to a subfolder of the pipobot module so they are automatically installed with the module in all cases
	- Added documentation on the internationalisation/translation process
	- Better version handling (setup.py should not import any pipobot modules)
  • Loading branch information
VinDuv authored and sleduc committed Aug 11, 2012
1 parent 2fb88a1 commit f09c6a2
Show file tree
Hide file tree
Showing 17 changed files with 196 additions and 466 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ syntax:glob
*.pyo
*.orig
*.swp
*.mo
*.log
.DS_Store
bdd/*
Expand Down
16 changes: 16 additions & 0 deletions bin/pipobot
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env python -W ignore::DeprecationWarning

import imp

try:
imp.find_module('pipobot')
except ImportError:
import sys
sys.stderr.write("The pipobot module was not found. Check your "
"PipoBot installation and the PYTHONPATH variable.\n")
sys.exit(-1)

from pipobot import PipoBotManager

if __name__ == "__main__":
PipoBotManager().run()
8 changes: 8 additions & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ Some "High-level" modules

high_level

Internationalisation and Localisation
-------------------------------------
.. toctree::
:maxdepth: 3
:numbered:

internat_loc

Indices and tables
==================

Expand Down
96 changes: 96 additions & 0 deletions doc/source/internat_loc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
Internationalisation
--------------------

Pipobot uses the `gettext` module for internationalisation purposes. You can
use the following functions to render your module translatable.

.. function:: gettext(string)
_(string)

These functions take a string in argument and return the translated string.
Sample usage::
self.bot.say(_("Hello, World!"))
When one of these two functions are used, the string passed in parameter
will be automatically proposed for translation.

If you want to translate a string format, pass only the format to the
function::
self.bot.say(_("Hello, %s") % name)
If you have more than one format parameter, it is better to name them
explicitely because the translator may want to reverse the order::
self.bot.say(_("Today is %(month)s, %(day)d") % {'month': month,
'day': day})
.. function:: ngettext(singular, plural, n)

``ngettext`` is used to translate expressions which can be pluralised.
Sample usage::
self.bot.say(ngettext("You have %d message", "You have %d messages",
message_count) % message_count)
Always use ``ngettext`` instead of ``if message_count == 1: …`` because
some languages have pluralization rules different from English (for
instance, in French, `0` is singular, not plural, and in Polish, there are
5 different plural forms depending on the item count)

.. function:: N_(string)

``N_`` is a no-op. It just returns the string passed in parameter. It is
used to mark strings which should be translatable but cannot be directly
translated because the translation system is not already active (so ``_``,
``gettext`` and ``ngettext`` are unavailable). That may be the case for
strings defined as constants in a Python module or as a class attribute.

For instance::

HELLO_MESSAGE = N_("Hello, World!")
[…]
def say_hello():
print _(HELLO_MESSAGE)

You do not need to ``import`` anything to use these functions: they are always
defined at the global level.

Translation handling
--------------------

Pipobot uses the ``babel`` module to handle translations. If you intend to add
new translations or update existing ones, you will need to install this module.

New language
^^^^^^^^^^^^

To translate Pipobot to a new language (for instance `zz_ZZ`, use the
following commands (from the directory containing the ``setup.py`` script)::
python setup.py extract_messages # Extract the messages from Pipobot’s sources
python setup.py init_catalog -l zz_ZZ # Create a translation catalog for the specified language

You can now edit ``pipobot/i18n/zz_ZZ/LC_MESSAGES/pipobot.po`` (with a standard
text editor or POEdit, for instance) and translate every message. When done,
run::
python setup.py compile_catalog # Compile the translation catalog

The translation can now be used by Pipobot.


Update an existing language
^^^^^^^^^^^^^^^^^^^^^^^^^^^

To update an existing translation catalog in order to take into account the
changes in Pipobot’s source code, run the following commands (replace `zz_ZZ`
with the name of the catalog you want to update)::
python setup.py extract_messages # Extract the messages from Pipobot’s sources
python setup.py update_catalog -l zz_ZZ # Update the translation catalog for the specified language

You can now edit ``pipobot/i18n/zz_ZZ/LC_MESSAGES/pipobot.po`` (with a standard
text editor or POEdit, for instance) and translate every message. When done,
run::
python setup.py compile_catalog # Compile the translation catalog

The translation can now be used by Pipobot.




1 change: 0 additions & 1 deletion pipobot/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
__version__ = "1.0"
1 change: 1 addition & 0 deletions pipobot/_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "1.0"
File renamed without changes.
2 changes: 2 additions & 0 deletions pipobot/i18n/mapping.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Mappings for message extraction
[python: **.py]
23 changes: 23 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Babel configuration
[compile_catalog]
domain = pipobot
directory = pipobot/i18n
statistics = true

[extract_messages]
copyright_holder = Pipoteam
msgid_bugs_address = pipoteam@xouillet.info
mapping_file = pipobot/i18n/mapping.cfg
output_file = pipobot/i18n/pipobot.pot
width = 80

[init_catalog]
domain = pipobot
input_file = pipobot/i18n/pipobot.pot
output_dir = pipobot/i18n

[update_catalog]
domain = pipobot
input_file = pipobot/i18n/pipobot.pot
output_dir = pipobot/i18n
previous = true
142 changes: 50 additions & 92 deletions setup.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,95 +1,53 @@
from setuptools import setup, find_packages
from distutils import cmd
from distutils.command.install_data import install_data as _install_data
from distutils.command.build import build as _build
#!/usr/bin/env python

import os
from distutils.core import setup
from os.path import dirname, join
import sys

sys.path.insert(0, 'translation')
import msgfmt

from pipobot import __version__

def list_all_data_files(dst_path, src_path):
f = []
for (dirpath, dirname, filenames) in os.walk(src_path):
f.append((os.path.join(dst_path, dirpath),
[os.path.join(dirpath, filename) for filename in filenames]))
return f

# Class for compiling .po files
class build_trans(cmd.Command):
description = 'Compile .po files into .mo files'
def initialize_options(self):
pass

def finalize_options(self):
pass

def run(self):
po_dir = os.path.join(os.path.dirname(os.curdir), 'translation', 'po')
for path, names, filenames in os.walk(po_dir):
for f in filenames:
if f.endswith('.po'):
lang = f[:len(f) - 3]
src = os.path.join(path, f)
dest_path = os.path.join('build', 'locale', lang, 'LC_MESSAGES')
dest = os.path.join(dest_path, 'pipobot.mo')
if not os.path.exists(dest_path):
os.makedirs(dest_path)
if not os.path.exists(dest):
print 'Compiling %s' % src
msgfmt.make(src, dest)
else:
src_mtime = os.stat(src)[8]
dest_mtime = os.stat(dest)[8]
if src_mtime > dest_mtime:
print 'Compiling %s' % src
msgfmt.make(src, dest)

# Add the translation build to the default build
class build(_build):
sub_commands = _build.sub_commands + [('build_trans', None)]
def run(self):
_build.run(self)

# Idem for install commands
class install_data(_install_data):

def run(self):
for lang in os.listdir('build/locale/'):
lang_dir = os.path.join('share', 'locale', lang, 'LC_MESSAGES')
lang_file = os.path.join('build', 'locale', lang, 'LC_MESSAGES', 'pipobot.mo')
self.data_files.append( (lang_dir, [lang_file]) )
_install_data.run(self)

# Put them in a nice dic
cmdclass = {
'build': build,
'build_trans': build_trans,
'install_data': install_data,
}

setup(
name = 'pipobot',
version = __version__,
description = 'A modular bot for Jabber MUCs',
author = 'Pipoteam',
author_email = 'pipoteam@xouillet.info',
# url = '',

packages = find_packages(exclude=["modules*"]),
data_files = list_all_data_files('/usr/share/pipobot', 'modules'),
# scripts = [],
cmdclass = cmdclass,

entry_points = {
'console_scripts' : [
'pipobot = pipobot.bot:main',
]
},

install_requires=['distribute'],
requires=['BeautifulSoup'],
)
try:
from babel.messages import frontend as babel
except ImportError:
sys.stderr.write("The babel module is not installed. Translation tools "
"will not be available.")
babel = None

if sys.hexversion < 0x02060000 or sys.hexversion >= 0x03000000:
sys.stderr.write(
"This program require Python 2.6 or newer, but is not yet compatible "
"with Python 3.\n"
)
sys.exit(1)

if __name__ == '__main__':
# We cannot import pipobot._version directly since we could get an already
# installed version.

execfile(join(dirname(__file__), 'pipobot', '_version.py'))
# __version__ is now defined.


kwargs = {}
if babel:
kwargs['cmdclass'] = {
'compile_catalog': babel.compile_catalog,
'extract_messages': babel.extract_messages,
'init_catalog': babel.init_catalog,
'update_catalog': babel.update_catalog,
}
else:
cmdclass = {}

setup(
name="PipoBot",
version=__version__,
description="A modular bot for Jabber MUCs.",
author="Pipoteam",
author_email="pipoteam@xouillet.info",
url="http://github.com/pipoteam/pipobot",
packages=['pipobot'],
package_data={'pipobot': ['i18n/*/LC_MESSAGES/pipobot.mo']},
data_files=[('/etc', ['pipobot.conf.yml'])],
requires=['yaml'],
scripts=['bin/pipobot'],
**kwargs
)
11 changes: 0 additions & 11 deletions translation/README

This file was deleted.

9 changes: 0 additions & 9 deletions translation/compile.sh

This file was deleted.

Loading

0 comments on commit f09c6a2

Please sign in to comment.