[gnome-keysign: 4/18] setup.py: Generate translated desktop file



commit 206bc94c0073addd73f48222b76c5681bf55ca1c
Author: Tobias Mueller <muelli cryptobitch de>
Date:   Mon Oct 9 16:26:29 2017 +0200

    setup.py: Generate translated desktop file
    
    This seems to work reasonably well for having a translated desktop file
    generated.  I don't like so much having all of this in setup.py so maybe
    someone gets around to extract it into a babel-desktop package or so.
    But it's the first step towards having a useful babel setup for desktop
    apps.

 ...e-keysign.desktop => gnome-keysign.raw.desktop} |  0
 setup.py                                           | 78 +++++++++++++++++++++-
 2 files changed, 77 insertions(+), 1 deletion(-)
---
diff --git a/data/gnome-keysign.desktop b/data/gnome-keysign.raw.desktop
similarity index 100%
rename from data/gnome-keysign.desktop
rename to data/gnome-keysign.raw.desktop
diff --git a/setup.py b/setup.py
index 13be66d..0dd52a1 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,14 @@
 #!/usr/bin/env python
 #
 from __future__ import print_function
+# We can't use unicode_literals because there seems to be
+# a bug in setuptools:
+# https://stackoverflow.com/a/23175194/2015768
+# from __future__ import unicode_literals
+
+import codecs
+import glob
+import logging
 
 from setuptools import setup
 from setuptools.command.install import install
@@ -10,6 +18,8 @@ from distutils.command.build import build
 import os
 import sys
 
+logging.basicConfig(level=logging.WARN)
+
 # Just in case we're attempting to execute this setup.py
 # when cwd != thisdir...
 os.chdir(os.path.dirname(os.path.realpath(__file__)))
@@ -18,9 +28,75 @@ with open(os.path.join('keysign', '_version.py')) as f:
     exec(f.read())
 
 
+
+def translate_desktop_file(infile, outfile, localedir):
+    # We import it here rather than globally because
+    # we don't have a guarantee for babel to be available
+    # globally. The setup_requires can only be evaluated after
+    # this file has been loaded. And it can't load if the import
+    # cannot be resolved.
+    from babel.messages.pofile import read_po
+    infp = codecs.open(infile, 'rb', encoding='utf-8')
+    outfp = codecs.open(outfile, 'wb', encoding='utf-8')
+    # glob in Python 3.5 takes ** syntax
+    # pofiles = glob.glob(os.path.join(localedir, '**.po', recursive=True))
+    pofiles = [os.path.join(dirpath, f)
+        for dirpath, dirnames, files in os.walk(localedir)
+        for f in files if f.endswith('.po')]
+
+    logging.debug('Loading %r', pofiles)
+    catalogs = {}
+
+    for pofile in pofiles:
+        catalog = read_po(open(pofile, 'r'))
+        catalogs[catalog.locale] = catalog
+        logging.info("Found %d strings for %s", len(catalog), catalog.locale)
+        # logging.debug("Strings for %r", catalog, catalog.values())
+    if not catalogs:
+        logging.warning("Could not find pofiles in %r: %r", localedir, pofiles)
+
+    for line in (x.strip() for x in infp):
+        logging.debug('Found in original (%s): %r', type(line), line)
+        # We intend to ignore the first line
+        if line.startswith('[Desktop'):
+            additional_lines = []
+        else:
+            additional_lines = []
+            # This is a rather primitive approach to generating the translated
+            # desktop file.  For example we don't really care about all the
+            # keys in the file.  But its simplicity is a feature and we
+            # ignore the runtime overhead, because it should only run centrally
+            # once.
+            key, value = line.split('=', 1)
+            logging.debug("Found key: %r", key)
+            for locale, catalog in catalogs.items():
+                translated = catalog.get(value)
+                logging.debug("Translated %r[%r]=%r: %r (%r)",
+                    key, locale, value, translated,
+                    translated.string if translated else '')
+                if translated and translated.string \
+                              and translated.string != value:
+                    additional_line = u'{keyword}[{locale}]={translated}'.format(
+                                        keyword=key,
+                                        locale=locale,
+                                        translated=translated.string,
+                                    )
+                    additional_lines.append(additional_line)
+                logging.debug("Writing more lines: %s", additional_lines)
+
+        # Write the new file.
+        # First the original line found it in the file, then the translations.
+        outfp.writelines((outline+'\n' for outline in ([line] + additional_lines)))
+
+
 class BuildWithCompile(build):
     sub_commands = [('compile_catalog', None)] + build.sub_commands
 
+    def run(self):
+        translate_desktop_file('data/gnome-keysign.raw.desktop', 'data/gnome-keysign.desktop', 
'keysign/locale')
+        build.run(self)
+
+
 # Pretty much from http://stackoverflow.com/a/41120180/2015768
 class InstallWithCompile(install):
     def run(self):
@@ -176,7 +252,7 @@ setup(
         ],
         message_extractors = {
             '': [
-               ('**.desktop', 'babelglade:extract_desktop', None),
+               ('**.raw.desktop', 'babelglade:extract_desktop', None),
             ],
             'keysign': [
                 ('**.py', 'python', None),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]