Merge pull request #70 from mattrose/13-gettext
This commit is contained in:
commit
ec2d50cdfc
|
@ -19,8 +19,3 @@ remotinatorc
|
|||
terminatorlib/meliae
|
||||
/dist
|
||||
/MANIFEST
|
||||
|
||||
## language / intltool related files
|
||||
.intltool*
|
||||
data/terminator.appdata.xml
|
||||
data/terminator.desktop
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
Development Notes
|
||||
=================
|
||||
|
||||
Here we connect notes and howtos for development around Terminator. Feel free to extend or submit suggestions.
|
||||
|
||||
## Translation i18n
|
||||
|
||||
Tooling is based on [Babel](https://babel.pocoo.org), the configuration is stored in `babel.cfg`, `setup.cfg` and
|
||||
some code in `setup.py`.
|
||||
|
||||
The POT file [po/terminator.pot](po/terminator.pot) contains the template for all translations and should be updated
|
||||
regularly, especially when messages changed inside the source code.
|
||||
|
||||
```
|
||||
$ python setup.py extract_messages
|
||||
```
|
||||
|
||||
Usually catalogs are updated with external translation tools, e.g. when new translations are merged. But we can update
|
||||
the catalogs here, so translators will have it more easy to pick up their work.
|
||||
This is a custom extension in `setup.py`.
|
||||
|
||||
```
|
||||
$ python setup.py update_catalogs
|
||||
```
|
||||
|
||||
Compilation of catalogs into the binary form, from `*.po` to `*.mo` is done during `setup.py build`, and the files are
|
||||
installed during `setup.py install`.
|
|
@ -0,0 +1,7 @@
|
|||
[ignore: build/**]
|
||||
[python: **.py]
|
||||
[python: terminator]
|
||||
[python: remotinator]
|
||||
[glade: **.glade]
|
||||
[glade: data/terminator.metainfo.xml]
|
||||
[desktop: **.desktop]
|
|
@ -4,45 +4,45 @@
|
|||
<id>terminator.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-2.0 only</project_license>
|
||||
<_name>Terminator</_name>
|
||||
<_summary>Multiple terminals in one window</_summary>
|
||||
<name translatable="yes">Terminator</name>
|
||||
<summary translatable="yes">Multiple terminals in one window</summary>
|
||||
<description>
|
||||
<_p>
|
||||
<p translatable="yes">
|
||||
The robot future of terminals
|
||||
</_p>
|
||||
<_p>
|
||||
</p>
|
||||
<p translatable="yes">
|
||||
A power-user tool for arranging terminals. It is inspired by programs such as
|
||||
gnome-multi-term, quadkonsole, etc. in that the main focus is arranging terminals
|
||||
in grids (tabs is the most common default method, which Terminator also supports).
|
||||
</_p>
|
||||
<_p>
|
||||
</p>
|
||||
<p translatable="yes">
|
||||
Much of the behavior of Terminator is based on GNOME Terminal, and we are adding
|
||||
more features from that as time goes by, but we also want to extend out in different
|
||||
directions with useful features for sysadmins and other users.
|
||||
</_p>
|
||||
<_p>Some highlights:</_p>
|
||||
</p>
|
||||
<p translatable="yes">Some highlights:</p>
|
||||
<ul>
|
||||
<_li>Arrange terminals in a grid</_li>
|
||||
<_li>Tabs</_li>
|
||||
<_li>Drag and drop re-ordering of terminals</_li>
|
||||
<_li>Lots of keyboard shortcuts</_li>
|
||||
<_li>Save multiple layouts and profiles via GUI preferences editor</_li>
|
||||
<_li>Simultaneous typing to arbitrary groups of terminals</_li>
|
||||
<li translatable="yes">Arrange terminals in a grid</li>
|
||||
<li translatable="yes">Tabs</li>
|
||||
<li translatable="yes">Drag and drop re-ordering of terminals</li>
|
||||
<li translatable="yes">Lots of keyboard shortcuts</li>
|
||||
<li translatable="yes">Save multiple layouts and profiles via GUI preferences editor</li>
|
||||
<li translatable="yes">Simultaneous typing to arbitrary groups of terminals</li>
|
||||
</ul>
|
||||
<_p>And lots more...</_p>
|
||||
<p translatable="yes">And lots more...</p>
|
||||
</description>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>http://4.bp.blogspot.com/-xt4Tja1TMQ0/Vdemmf8wYSI/AAAAAAAAA9A/uROTre0PMls/s1600/terminator_main_basic.png</image>
|
||||
<_caption>The main window showing the application in action</_caption>
|
||||
<caption translatable="yes">The main window showing the application in action</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>http://4.bp.blogspot.com/-rRxALSpEEZw/Vdeu58JgpnI/AAAAAAAAA9o/XewWKJ5HNo4/s1600/terminator_main_complex.png</image>
|
||||
<_caption>Getting a little crazy with the terminals</_caption>
|
||||
<caption translatable="yes">Getting a little crazy with the terminals</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>http://2.bp.blogspot.com/-t_8oRyMXUls/VdemmRVnZnI/AAAAAAAAA88/rHIr8L1X7Ho/s1600/terminator_prefs_global.png</image>
|
||||
<_caption>The preferences window where you can change the defaults</_caption>
|
||||
<image>http://2.bp.blogspot.com/-t_8oRyMXUls/VdemmRVnZnI/AAAAAAAAA88/rHIr8L1X7Ho/s1600/terminatorprefs_global.png</image>
|
||||
<caption translatable="yes">The preferences window where you can change the defaults</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<url type="homepage">https://github.com/gnome-terminator/terminator</url>
|
11
po/genpot.sh
11
po/genpot.sh
|
@ -1,11 +0,0 @@
|
|||
#!/bin/sh
|
||||
# Stupid workaround for intltools not handling extensionless files
|
||||
ln -s terminator ../terminator.py
|
||||
ln -s remotinator ../remotinator.py
|
||||
|
||||
# Make translation files
|
||||
intltool-update -g terminator -o terminator.pot -p
|
||||
|
||||
# Cleanup after stupid workaround
|
||||
rm ../terminator.py
|
||||
rm ../remotinator.py
|
1358
po/terminator.pot
1358
po/terminator.pot
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
# Update translation files
|
||||
for po_file in `ls *.po`; do
|
||||
msgmerge -N -U ${po_file} terminator.pot
|
||||
done
|
|
@ -1,2 +1,7 @@
|
|||
[aliases]
|
||||
test=pytest
|
||||
|
||||
[extract_messages]
|
||||
mapping_file = babel.cfg
|
||||
output_file = po/terminator.pot
|
||||
input_dirs = .
|
||||
|
|
109
setup.py
109
setup.py
|
@ -16,76 +16,61 @@ import platform
|
|||
|
||||
from terminatorlib.version import APP_NAME, APP_VERSION
|
||||
|
||||
PO_DIR = 'po'
|
||||
MO_DIR = os.path.join('build', 'mo')
|
||||
GETTEXT_SOURCE = 'po'
|
||||
GETTEXT_DOMAIN = 'terminator'
|
||||
GETTEXT_TARGET = os.path.join('share', 'locale')
|
||||
CSS_DIR = os.path.join('terminatorlib', 'themes')
|
||||
|
||||
if sys.version_info < (3, 0):
|
||||
PYTEST_VERSION = '<5'
|
||||
BABELGLADE_VERSION = '< 0.7'
|
||||
else:
|
||||
PYTEST_VERSION = '>0'
|
||||
BABELGLADE_VERSION = '> 0'
|
||||
|
||||
|
||||
class TerminatorDist(Distribution):
|
||||
global_options = Distribution.global_options + [
|
||||
("build-documentation", None, "Build the documentation"),
|
||||
("install-documentation", None, "Install the documentation"),
|
||||
("without-gettext", None, "Don't build/install gettext .mo files"),
|
||||
("without-icon-cache", None, "Don't attempt to run gtk-update-icon-cache")]
|
||||
|
||||
def __init__ (self, *args):
|
||||
self.without_gettext = False
|
||||
self.without_icon_cache = False
|
||||
Distribution.__init__(self, *args)
|
||||
|
||||
|
||||
class BuildData(build):
|
||||
def run (self):
|
||||
build.run (self)
|
||||
class CustomBuild(build):
|
||||
"""
|
||||
Custom build extensions to build
|
||||
"""
|
||||
|
||||
if not self.distribution.without_gettext:
|
||||
# Build the translations
|
||||
for po in glob.glob (os.path.join (PO_DIR, '*.po')):
|
||||
def run(self):
|
||||
build.run(self)
|
||||
self.build_i18n()
|
||||
|
||||
def build_i18n(self):
|
||||
"""
|
||||
Compiling files for gettext from *.po to *.mo with the proper target path
|
||||
"""
|
||||
info('compiling i18n files')
|
||||
from babel.messages.frontend import compile_catalog
|
||||
compiler = compile_catalog(self.distribution)
|
||||
compiler.domain = [GETTEXT_DOMAIN]
|
||||
|
||||
for po in glob.glob(os.path.join(GETTEXT_SOURCE, '*.po')):
|
||||
lang = os.path.basename(po[:-3])
|
||||
mo = os.path.join(MO_DIR, lang, 'terminator.mo')
|
||||
mo = os.path.join(self.build_base, GETTEXT_TARGET, lang, 'LC_MESSAGES', 'terminator.mo')
|
||||
|
||||
directory = os.path.dirname(mo)
|
||||
if not os.path.exists(directory):
|
||||
info('creating %s' % directory)
|
||||
os.makedirs(directory)
|
||||
|
||||
if newer(po, mo):
|
||||
info('compiling %s -> %s' % (po, mo))
|
||||
try:
|
||||
rc = subprocess.call(['msgfmt', '-o', mo, po])
|
||||
if rc != 0:
|
||||
raise Warning("msgfmt returned %d" % rc)
|
||||
except Exception as e:
|
||||
error("Building gettext files failed. Ensure you have gettext installed. Alternatively, try setup.py --without-gettext [build|install]")
|
||||
error("Error: %s" % str(e))
|
||||
sys.exit(1)
|
||||
compiler.input_file = po
|
||||
compiler.output_file = mo
|
||||
compiler.run()
|
||||
|
||||
TOP_BUILDDIR='.'
|
||||
INTLTOOL_MERGE='intltool-merge'
|
||||
desktop_in='data/terminator.desktop.in'
|
||||
desktop_data='data/terminator.desktop'
|
||||
rc = os.system ("C_ALL=C " + INTLTOOL_MERGE + " -d -u -c " + TOP_BUILDDIR +
|
||||
"/po/.intltool-merge-cache " + TOP_BUILDDIR + "/po " +
|
||||
desktop_in + " " + desktop_data)
|
||||
if rc != 0:
|
||||
# run the desktop_in through a command to strip the "_" characters
|
||||
with open(desktop_in) as file_in, open(desktop_data, 'w') as file_data:
|
||||
[file_data.write(line.lstrip('_')) for line in file_in]
|
||||
|
||||
appdata_in='data/terminator.appdata.xml.in'
|
||||
appdata_data='data/terminator.metainfo.xml'
|
||||
rc = os.system ("C_ALL=C " + INTLTOOL_MERGE + " -x -u -c " + TOP_BUILDDIR +
|
||||
"/po/.intltool-merge-cache " + TOP_BUILDDIR + "/po " +
|
||||
appdata_in + " " + appdata_data)
|
||||
if rc != 0:
|
||||
# run the appdata_in through a command to strip the "_" characters
|
||||
with open(appdata_in) as file_in, open(appdata_data, 'w') as file_data:
|
||||
[file_data.write(line.replace('<_','<').replace('</_','</')) for line in file_in]
|
||||
|
||||
class Uninstall(Command):
|
||||
description = "Attempt an uninstall from an install --record file"
|
||||
|
@ -148,7 +133,7 @@ class Uninstall(Command):
|
|||
class InstallData(install_data):
|
||||
def run (self):
|
||||
self.data_files.extend (self._find_css_files ())
|
||||
self.data_files.extend (self._find_mo_files ())
|
||||
self.data_files.extend(self._find_mo_files())
|
||||
install_data.run (self)
|
||||
if not self.distribution.without_icon_cache:
|
||||
self._update_icon_cache ()
|
||||
|
@ -161,13 +146,15 @@ class InstallData(install_data):
|
|||
except Exception as e:
|
||||
warn("updating the GTK icon cache failed: %s" % str(e))
|
||||
|
||||
def _find_mo_files (self):
|
||||
def _find_mo_files(self):
|
||||
"""
|
||||
search for gettext files built during build step
|
||||
"""
|
||||
data_files = []
|
||||
|
||||
if not self.distribution.without_gettext:
|
||||
for mo in glob.glob (os.path.join (MO_DIR, '*', 'terminator.mo')):
|
||||
lang = os.path.basename(os.path.dirname(mo))
|
||||
dest = os.path.join('share', 'locale', lang, 'LC_MESSAGES')
|
||||
build_base = self.distribution.command_obj['build'].build_base
|
||||
for mo in glob.glob(os.path.join(build_base, GETTEXT_TARGET, '*', 'LC_MESSAGES', '*.mo')):
|
||||
dest = mo.lstrip(build_base + os.sep)
|
||||
data_files.append((dest, [mo]))
|
||||
|
||||
return data_files
|
||||
|
@ -183,6 +170,27 @@ class InstallData(install_data):
|
|||
return data_files
|
||||
|
||||
|
||||
class UpdateCatalogs(Command):
|
||||
"""Update all gettext catalogs """
|
||||
description = __doc__
|
||||
user_options = []
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
from babel.messages.frontend import update_catalog
|
||||
updater = update_catalog(self.distribution)
|
||||
updater.input_file = os.path.join(GETTEXT_SOURCE, 'terminator.pot')
|
||||
|
||||
for po in glob.glob(os.path.join(GETTEXT_SOURCE, '*.po')):
|
||||
updater.output_file = po
|
||||
updater.run()
|
||||
|
||||
|
||||
if platform.system() in ['FreeBSD', 'OpenBSD']:
|
||||
man_dir = 'man'
|
||||
else:
|
||||
|
@ -229,6 +237,8 @@ setup(name=APP_NAME,
|
|||
],
|
||||
setup_requires=[
|
||||
'pytest-runner',
|
||||
'babel',
|
||||
'BabelGladeExtractor ' + BABELGLADE_VERSION,
|
||||
],
|
||||
install_requires=[
|
||||
'pycairo',
|
||||
|
@ -240,6 +250,7 @@ setup(name=APP_NAME,
|
|||
tests_require=test_deps,
|
||||
extras_require={'test': test_deps},
|
||||
package_data={'terminatorlib': ['preferences.glade', 'layoutlauncher.glade']},
|
||||
cmdclass={'build': BuildData, 'install_data': InstallData, 'uninstall': Uninstall},
|
||||
cmdclass={'build': CustomBuild, 'install_data': InstallData, 'uninstall': Uninstall,
|
||||
'update_catalogs': UpdateCatalogs},
|
||||
distclass=TerminatorDist)
|
||||
|
||||
|
|
Loading…
Reference in New Issue