File indexing completed on 2024-03-24 17:21:40

0001 # -*- coding: UTF-8 -*-
0002 
0003 """
0004 Wrappers for commands from Gettext tools.
0005 
0006 @author: Chusslove Illich (Часлав Илић) <caslav.ilic@gmx.net>
0007 @license: GPLv3
0008 """
0009 
0010 import os
0011 import subprocess
0012 
0013 from pology import _, n_
0014 from pology.report import warning
0015 from pology.fsops import unicode_to_str
0016 
0017 
0018 def msgfilter (filtr, options=[]):
0019     """
0020     Pass PO file through C{msgfilter(1)} [hook factory].
0021 
0022     Wrappers modify PO files in place; the executed command is::
0023 
0024         msgfilter <options> -i <filepath> -o <filepath> <filtr>
0025 
0026     where C{options} parameter may be used to pass any
0027     extra options to C{msgfilter}.
0028     Both C{filtr} and C{options} are lists of command line arguments
0029     rather than monolithic strings, to avoid shell quoting problems.
0030     For example, to rewrap the PO file at 70 columns::
0031 
0032         msgfilter(["cat"], ["-w", "70"])
0033 
0034     or to replace every C{foo} with C{bar} in translation::
0035 
0036         msgfilter(["sed", "s/foo/bar/g"])
0037 
0038     @param filtr: filter to use
0039     @type filtr: [string*]
0040     @param options: additional options to pass to C{msgfilter}
0041     @type options: [string*]
0042 
0043     @return: type F6A hook
0044     @rtype: C{(filepath) -> numerr}
0045 
0046     @note: In case C{msgfilter} does not finish without errors,
0047         wrapper always reports number of errors as 1.
0048     """
0049 
0050     # FIXME: Check availability and version of msgfilter.
0051 
0052     base_cmdargs = ["msgfilter"] + options
0053 
0054     def wrapper (filepath):
0055         cmdargs = base_cmdargs + ["-i", filepath, "-o", filepath] + filtr
0056         cmdargs = list(map(unicode_to_str, cmdargs))
0057         ret = subprocess.call(cmdargs)
0058         if ret:
0059             warning(_("@info",
0060                       "%(file)s: %(cmd)s failed with exit code %(num)d "
0061                       "(filter: '%(filter)s', options: '%(options)s')",
0062                       file=filepath, cmd="msgfilter", num=ret, filter=filtr,
0063                       options=options))
0064             return 1
0065         return 0
0066 
0067     return wrapper
0068 
0069 
0070 def msgfmt (options=[]):
0071     """
0072     Pass PO file through C{msgfmt(1)} [hook factory].
0073 
0074     The file is not modified; the executed command is::
0075 
0076         msgfilter <options> -o /dev/null <filepath>
0077 
0078     where C{options} parameter may be used to pass any
0079     extra options to C{msgfmt}.
0080     C{options} is a list of command line arguments
0081     rather than a monolithic string, to avoid shell quoting problems.
0082 
0083     @param options: additional options to pass to C{msgfmt}
0084     @type options: [string*]
0085 
0086     @return: type S6A hook
0087     @rtype: C{(filepath) -> numerr}
0088 
0089     @note: In case C{msgfmt} does not finish without errors,
0090         wrapper always reports number of errors as 1.
0091     """
0092 
0093     # FIXME: Check availability and version of msgfmt.
0094 
0095     base_cmdargs = ["msgfmt"] + options + ["-o", "/dev/null"]
0096 
0097     def wrapper (filepath):
0098         cmdargs = base_cmdargs + [filepath]
0099         cmdargs = list(map(unicode_to_str, cmdargs))
0100         ret = subprocess.call(cmdargs)
0101         if ret:
0102             warning(_("@info",
0103                       "%(file)s: %(cmd)s failed with exit code %(num)d "
0104                       "(options: '%(options)s')",
0105                       file=filepath, cmd="msgfmt", num=ret, options=options))
0106             return 1
0107         return 0
0108 
0109     return wrapper
0110