Revert "replace gettext and intltool with Babel"

This commit is contained in:
Markus Frosch 2020-05-19 21:07:52 +02:00 committed by GitHub
parent 4719eefa4d
commit 6718ab1095
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1495 additions and 1520 deletions

5
.gitignore vendored
View File

@ -19,3 +19,8 @@ remotinatorc
terminatorlib/meliae terminatorlib/meliae
/dist /dist
/MANIFEST /MANIFEST
## language / intltool related files
.intltool*
data/terminator.appdata.xml
data/terminator.desktop

View File

@ -1,27 +0,0 @@
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`.

View File

@ -1,7 +0,0 @@
[ignore: build/**]
[python: **.py]
[python: terminator]
[python: remotinator]
[glade: **.glade]
[glade: data/terminator.metainfo.xml]
[desktop: **.desktop]

View File

@ -2,47 +2,47 @@
<!-- Copyright 2013 Stephen Boddy <stephen.j.boddy@gmail.com> --> <!-- Copyright 2013 Stephen Boddy <stephen.j.boddy@gmail.com> -->
<component type="desktop"> <component type="desktop">
<id>terminator.desktop</id> <id>terminator.desktop</id>
<metadata_license>CC0-1.0</metadata_license> <metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0 only</project_license> <project_license>GPL-2.0 only</project_license>
<name translatable="yes">Terminator</name> <_name>Terminator</_name>
<summary translatable="yes">Multiple terminals in one window</summary> <_summary>Multiple terminals in one window</_summary>
<description> <description>
<p translatable="yes"> <_p>
The robot future of terminals The robot future of terminals
</p> </_p>
<p translatable="yes"> <_p>
A power-user tool for arranging terminals. It is inspired by programs such as 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 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). in grids (tabs is the most common default method, which Terminator also supports).
</p> </_p>
<p translatable="yes"> <_p>
Much of the behavior of Terminator is based on GNOME Terminal, and we are adding 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 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. directions with useful features for sysadmins and other users.
</p> </_p>
<p translatable="yes">Some highlights:</p> <_p>Some highlights:</_p>
<ul> <ul>
<li translatable="yes">Arrange terminals in a grid</li> <_li>Arrange terminals in a grid</_li>
<li translatable="yes">Tabs</li> <_li>Tabs</_li>
<li translatable="yes">Drag and drop re-ordering of terminals</li> <_li>Drag and drop re-ordering of terminals</_li>
<li translatable="yes">Lots of keyboard shortcuts</li> <_li>Lots of keyboard shortcuts</_li>
<li translatable="yes">Save multiple layouts and profiles via GUI preferences editor</li> <_li>Save multiple layouts and profiles via GUI preferences editor</_li>
<li translatable="yes">Simultaneous typing to arbitrary groups of terminals</li> <_li>Simultaneous typing to arbitrary groups of terminals</_li>
</ul> </ul>
<p translatable="yes">And lots more...</p> <_p>And lots more...</_p>
</description> </description>
<screenshots> <screenshots>
<screenshot type="default"> <screenshot type="default">
<image>http://4.bp.blogspot.com/-xt4Tja1TMQ0/Vdemmf8wYSI/AAAAAAAAA9A/uROTre0PMls/s1600/terminator_main_basic.png</image> <image>http://4.bp.blogspot.com/-xt4Tja1TMQ0/Vdemmf8wYSI/AAAAAAAAA9A/uROTre0PMls/s1600/terminator_main_basic.png</image>
<caption translatable="yes">The main window showing the application in action</caption> <_caption>The main window showing the application in action</_caption>
</screenshot> </screenshot>
<screenshot> <screenshot>
<image>http://4.bp.blogspot.com/-rRxALSpEEZw/Vdeu58JgpnI/AAAAAAAAA9o/XewWKJ5HNo4/s1600/terminator_main_complex.png</image> <image>http://4.bp.blogspot.com/-rRxALSpEEZw/Vdeu58JgpnI/AAAAAAAAA9o/XewWKJ5HNo4/s1600/terminator_main_complex.png</image>
<caption translatable="yes">Getting a little crazy with the terminals</caption> <_caption>Getting a little crazy with the terminals</_caption>
</screenshot> </screenshot>
<screenshot> <screenshot>
<image>http://2.bp.blogspot.com/-t_8oRyMXUls/VdemmRVnZnI/AAAAAAAAA88/rHIr8L1X7Ho/s1600/terminatorprefs_global.png</image> <image>http://2.bp.blogspot.com/-t_8oRyMXUls/VdemmRVnZnI/AAAAAAAAA88/rHIr8L1X7Ho/s1600/terminator_prefs_global.png</image>
<caption translatable="yes">The preferences window where you can change the defaults</caption> <_caption>The preferences window where you can change the defaults</_caption>
</screenshot> </screenshot>
</screenshots> </screenshots>
<url type="homepage">https://github.com/gnome-terminator/terminator</url> <url type="homepage">https://github.com/gnome-terminator/terminator</url>

11
po/genpot.sh Executable file
View File

@ -0,0 +1,11 @@
#!/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

File diff suppressed because it is too large Load Diff

5
po/update_all_po.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh
# Update translation files
for po_file in `ls *.po`; do
msgmerge -N -U ${po_file} terminator.pot
done

View File

@ -1,7 +1,2 @@
[aliases] [aliases]
test=pytest test=pytest
[extract_messages]
mapping_file = babel.cfg
output_file = po/terminator.pot
input_dirs = .

119
setup.py
View File

@ -16,61 +16,76 @@ import platform
from terminatorlib.version import APP_NAME, APP_VERSION from terminatorlib.version import APP_NAME, APP_VERSION
GETTEXT_SOURCE = 'po' PO_DIR = 'po'
GETTEXT_DOMAIN = 'terminator' MO_DIR = os.path.join('build', 'mo')
GETTEXT_TARGET = os.path.join('share', 'locale')
CSS_DIR = os.path.join('terminatorlib', 'themes') CSS_DIR = os.path.join('terminatorlib', 'themes')
if sys.version_info < (3, 0): if sys.version_info < (3, 0):
PYTEST_VERSION = '<5' PYTEST_VERSION = '<5'
BABELGLADE_VERSION = '< 0.7'
else: else:
PYTEST_VERSION = '>0' PYTEST_VERSION = '>0'
BABELGLADE_VERSION = '> 0'
class TerminatorDist(Distribution): class TerminatorDist(Distribution):
global_options = Distribution.global_options + [ global_options = Distribution.global_options + [
("build-documentation", None, "Build the documentation"), ("build-documentation", None, "Build the documentation"),
("install-documentation", None, "Install 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")] ("without-icon-cache", None, "Don't attempt to run gtk-update-icon-cache")]
def __init__ (self, *args): def __init__ (self, *args):
self.without_gettext = False
self.without_icon_cache = False self.without_icon_cache = False
Distribution.__init__(self, *args) Distribution.__init__(self, *args)
class CustomBuild(build): class BuildData(build):
""" def run (self):
Custom build extensions to build build.run (self)
"""
def run(self): if not self.distribution.without_gettext:
build.run(self) # Build the translations
self.build_i18n() for po in glob.glob (os.path.join (PO_DIR, '*.po')):
lang = os.path.basename(po[:-3])
mo = os.path.join(MO_DIR, lang, 'terminator.mo')
def build_i18n(self): directory = os.path.dirname(mo)
""" if not os.path.exists(directory):
Compiling files for gettext from *.po to *.mo with the proper target path info('creating %s' % directory)
""" os.makedirs(directory)
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')): if newer(po, mo):
lang = os.path.basename(po[:-3]) info('compiling %s -> %s' % (po, mo))
mo = os.path.join(self.build_base, GETTEXT_TARGET, lang, 'LC_MESSAGES', 'terminator.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)
directory = os.path.dirname(mo) TOP_BUILDDIR='.'
if not os.path.exists(directory): INTLTOOL_MERGE='intltool-merge'
os.makedirs(directory) desktop_in='data/terminator.desktop.in'
desktop_data='data/terminator.desktop'
if newer(po, mo): rc = os.system ("C_ALL=C " + INTLTOOL_MERGE + " -d -u -c " + TOP_BUILDDIR +
compiler.input_file = po "/po/.intltool-merge-cache " + TOP_BUILDDIR + "/po " +
compiler.output_file = mo desktop_in + " " + desktop_data)
compiler.run() 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): class Uninstall(Command):
description = "Attempt an uninstall from an install --record file" description = "Attempt an uninstall from an install --record file"
@ -133,7 +148,7 @@ class Uninstall(Command):
class InstallData(install_data): class InstallData(install_data):
def run (self): def run (self):
self.data_files.extend (self._find_css_files ()) 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) install_data.run (self)
if not self.distribution.without_icon_cache: if not self.distribution.without_icon_cache:
self._update_icon_cache () self._update_icon_cache ()
@ -146,16 +161,14 @@ class InstallData(install_data):
except Exception as e: except Exception as e:
warn("updating the GTK icon cache failed: %s" % str(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 = [] data_files = []
build_base = self.distribution.command_obj['build'].build_base if not self.distribution.without_gettext:
for mo in glob.glob(os.path.join(build_base, GETTEXT_TARGET, '*', 'LC_MESSAGES', '*.mo')): for mo in glob.glob (os.path.join (MO_DIR, '*', 'terminator.mo')):
dest = mo.lstrip(build_base + os.sep) lang = os.path.basename(os.path.dirname(mo))
data_files.append((dest, [mo])) dest = os.path.join('share', 'locale', lang, 'LC_MESSAGES')
data_files.append((dest, [mo]))
return data_files return data_files
@ -170,27 +183,6 @@ class InstallData(install_data):
return data_files 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']: if platform.system() in ['FreeBSD', 'OpenBSD']:
man_dir = 'man' man_dir = 'man'
else: else:
@ -237,8 +229,6 @@ setup(name=APP_NAME,
], ],
setup_requires=[ setup_requires=[
'pytest-runner', 'pytest-runner',
'babel',
'BabelGladeExtractor ' + BABELGLADE_VERSION,
], ],
install_requires=[ install_requires=[
'pycairo', 'pycairo',
@ -250,7 +240,6 @@ setup(name=APP_NAME,
tests_require=test_deps, tests_require=test_deps,
extras_require={'test': test_deps}, extras_require={'test': test_deps},
package_data={'terminatorlib': ['preferences.glade', 'layoutlauncher.glade']}, package_data={'terminatorlib': ['preferences.glade', 'layoutlauncher.glade']},
cmdclass={'build': CustomBuild, 'install_data': InstallData, 'uninstall': Uninstall, cmdclass={'build': BuildData, 'install_data': InstallData, 'uninstall': Uninstall},
'update_catalogs': UpdateCatalogs},
distclass=TerminatorDist) distclass=TerminatorDist)