summaryrefslogtreecommitdiff
path: root/tools/po
diff options
context:
space:
mode:
authorLorry <lorry@roadtrain.codethink.co.uk>2012-08-22 14:29:52 +0100
committerLorry <lorry@roadtrain.codethink.co.uk>2012-08-22 14:29:52 +0100
commitf1bdf13786f0752c0846cf36f0d91e4fc6747929 (patch)
tree4223b2035bf2240d681a53822808b3c7f687b905 /tools/po
downloadsubversion-tarball-f1bdf13786f0752c0846cf36f0d91e4fc6747929.tar.gz
Tarball conversion
Diffstat (limited to 'tools/po')
-rwxr-xr-xtools/po/l10n-report.py246
-rwxr-xr-xtools/po/po-update.sh123
2 files changed, 369 insertions, 0 deletions
diff --git a/tools/po/l10n-report.py b/tools/po/l10n-report.py
new file mode 100755
index 0000000..1aadd58
--- /dev/null
+++ b/tools/po/l10n-report.py
@@ -0,0 +1,246 @@
+#!/usr/bin/env python
+#
+# $Id: l10n-report.py 1132657 2011-06-06 14:23:36Z julianfoad $
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#
+
+"""Usage: l10n-report.py [OPTION...]
+
+Send the l10n translation status report to an email address. If the
+email address is not specified, print in stdout.
+
+Options:
+
+ -h, --help Show this help message.
+
+ -m, --to-email-id Send the l10n translation status report to this
+ email address.
+"""
+
+import sys
+import getopt
+import os
+import re
+import subprocess
+
+FROM_ADDRESS = "Subversion Translation Status <noreply@subversion.apache.org>"
+LIST_ADDRESS = "dev@subversion.apache.org"
+SUBJECT_TEMPLATE = "[l10n] Translation status report for %s r%s"
+MAIL_THREAD_ID = '<translation_status_report_for_%s@subversion.apache.org>'
+
+def _rev():
+ dollar = "$Revision: 1132657 $"
+ return int(re.findall('[0-9]+', dollar)[0]);
+
+def usage_and_exit(errmsg=None):
+ """Print a usage message, plus an ERRMSG (if provided), then exit.
+ If ERRMSG is provided, the usage message is printed to stderr and
+ the script exits with a non-zero error code. Otherwise, the usage
+ message goes to stdout, and the script exits with a zero
+ errorcode."""
+ if errmsg is None:
+ stream = sys.stdout
+ else:
+ stream = sys.stderr
+ stream.write("%s\n" % __doc__)
+ stream.flush()
+ if errmsg:
+ stream.write("\nError: %s\n" % errmsg)
+ stream.flush()
+ sys.exit(2)
+ sys.exit(0)
+
+
+class l10nReport:
+ def __init__(self, to_email_id=""):
+ self.to_email_id = to_email_id
+ self.from_email_id = "<%s>" % LIST_ADDRESS
+
+ def safe_command(self, cmd_and_args, cmd_in=""):
+ [stdout, stderr] = subprocess.Popen(cmd_and_args, \
+ stdin=subprocess.PIPE, \
+ stdout=subprocess.PIPE, \
+ stderr=subprocess.PIPE).communicate(input=cmd_in)
+ return stdout, stderr
+
+ def match(self, pattern, string):
+ if isinstance(pattern, basestring):
+ pattern = re.compile(pattern)
+ match = re.compile(pattern).search(string)
+ if match and match.groups():
+ return match.group(1)
+ else:
+ return None
+
+ def get_msgattribs(self, file):
+ msgout = self.safe_command(['msgattrib', '--translated', file])[0]
+ grepout = self.safe_command(['grep', '-E', '^msgid *"'], msgout)[0]
+ sedout = self.safe_command(['sed', '1d'], grepout)[0]
+ trans = self.safe_command(['wc', '-l'], sedout)[0]
+
+ msgout = self.safe_command(['msgattrib', '--untranslated', file])[0]
+ grepout = self.safe_command(['grep', '-E', '^msgid *"'], msgout)[0]
+ sedout = self.safe_command(['sed', '1d'], grepout)[0]
+ untrans = self.safe_command(['wc', '-l'], sedout)[0]
+
+ msgout = self.safe_command(['msgattrib', '--only-fuzzy', file])[0]
+ grepout = self.safe_command(['grep', '-E', '^msgid *"'], msgout)[0]
+ sedout = self.safe_command(['sed', '1d'], grepout)[0]
+ fuzzy = self.safe_command(['wc', '-l'], sedout)[0]
+
+ msgout = self.safe_command(['msgattrib', '--only-obsolete', file])[0]
+ grepout = self.safe_command(['grep', '-E', '^#~ msgid *"'], msgout)[0]
+ obsolete = self.safe_command(['wc', '-l'], grepout)[0]
+
+ return int(trans), int(untrans), int(fuzzy), int(obsolete)
+
+ def pre_l10n_report(self):
+ # svn revert --recursive subversion/po
+ cmd = ['svn', 'revert', '--recursive', 'subversion/po']
+ stderr = self.safe_command(cmd)[1]
+ if stderr:
+ sys.stderr.write("\nError: %s\n" % stderr)
+ sys.stderr.flush()
+ sys.exit(0)
+
+ # svn update
+ cmd = ['svn', 'update']
+ stderr = self.safe_command(cmd)[1]
+ if stderr:
+ sys.stderr.write("\nError: %s\n" % stderr)
+ sys.stderr.flush()
+ sys.exit(0)
+
+ # tools/po/po-update.sh
+ cmd = ['sh', 'tools/po/po-update.sh']
+ self.safe_command(cmd)
+
+
+def bar_graph(nominal_length, trans, untrans, fuzzy, obsolete):
+ """Format the given four counts into a bar graph string in which the
+ total length of the bars representing the TRANS, UNTRANS and FUZZY
+ counts is NOMINAL_LENGTH characters, and the bar representing the
+ OBSOLETE count extends beyond that."""
+
+ total_count = trans + untrans + fuzzy # don't include 'obsolete'
+ accum_bar = 0
+ accum_count = 0
+ s = ''
+ for count, letter in [(trans, '+'), (untrans, 'U'), (fuzzy, '~'),
+ (obsolete, 'o')]:
+ accum_count += count
+ new_bar_end = nominal_length * accum_count / total_count
+ s += letter * (new_bar_end - accum_bar)
+ accum_bar = new_bar_end
+ return s
+
+
+def main():
+ # Parse the command-line options and arguments.
+ try:
+ opts, args = getopt.gnu_getopt(sys.argv[1:], "hm:",
+ ["help",
+ "to-email-id=",
+ ])
+ except getopt.GetoptError, msg:
+ usage_and_exit(msg)
+
+ to_email_id = None
+ for opt, arg in opts:
+ if opt in ("-h", "--help"):
+ usage_and_exit()
+ elif opt in ("-m", "--to-email-id"):
+ to_email_id = arg
+
+ l10n = l10nReport()
+ os.chdir("%s/../.." % os.path.dirname(os.path.abspath(sys.argv[0])))
+ l10n.pre_l10n_report()
+ [info_out, info_err] = l10n.safe_command(['svn', 'info'])
+ if info_err:
+ sys.stderr.write("\nError: %s\n" % info_err)
+ sys.stderr.flush()
+ sys.exit(0)
+
+ po_dir = 'subversion/po'
+ branch_name = l10n.match('URL:.*/asf/subversion/(\S+)', info_out)
+ [info_out, info_err] = l10n.safe_command(['svnversion', po_dir])
+ if info_err:
+ sys.stderr.write("\nError: %s\n" % info_err)
+ sys.stderr.flush()
+ sys.exit(0)
+
+ wc_version = re.sub('[MS]', '', info_out.strip())
+ title = "Translation status report for %s@r%s" % \
+ (branch_name, wc_version)
+
+ os.chdir(po_dir)
+ files = sorted(os.listdir('.'))
+ format_head = "\n%6s %7s %7s %7s %7s" % ("lang", "trans", "untrans",
+ "fuzzy", "obs")
+ format_line = "--------------------------------------"
+ print("\n%s\n%s\n%s" % (title, format_head, format_line))
+
+ body = ""
+ po_pattern = re.compile('(.*).po$')
+ for file in files:
+ lang = l10n.match(po_pattern, file)
+ if not lang:
+ continue
+ [trans, untrans, fuzzy, obsolete] = l10n.get_msgattribs(file)
+ po_format = "%6s %7d %7d %7d %7d" %\
+ (lang, trans, untrans, fuzzy, obsolete)
+ po_format += " " + bar_graph(30, trans, untrans, fuzzy, obsolete)
+ body += "%s\n" % po_format
+ print(po_format)
+
+ if to_email_id:
+ import smtplib
+ # Ensure compatibility of the email module all the way to Python 2.3
+ try:
+ from email.message import Message
+ except ImportError:
+ from email.Message import Message
+
+ msg = Message()
+ msg["From"] = FROM_ADDRESS
+ msg["To"] = to_email_id
+ msg["Subject"] = SUBJECT_TEMPLATE % (branch_name, wc_version)
+ msg["X-Mailer"] = "l10n-report.py r%s" % _rev()
+ msg["Reply-To"] = LIST_ADDRESS
+ msg["Mail-Followup-To"] = LIST_ADDRESS
+ msg["In-Reply-To"] = MAIL_THREAD_ID % (branch_name.replace('/', '_'))
+ msg["References"] = msg["In-Reply-To"]
+
+ # http://www.iana.org/assignments/auto-submitted-keywords/auto-submitted-keywords.xhtml
+ msg["Auto-Submitted"] = 'auto-generated'
+
+ msg.set_type("text/plain")
+ msg.set_payload("\n".join((title, format_head, format_line, body)))
+
+ server = smtplib.SMTP('localhost')
+ server.sendmail("From: " + FROM_ADDRESS,
+ "To: " + to_email_id,
+ msg.as_string())
+ print("The report is sent to '%s' email id." % to_email_id)
+ else:
+ print("\nYou have not passed '-m' option, so email is not sent.")
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/po/po-update.sh b/tools/po/po-update.sh
new file mode 100755
index 0000000..9891531
--- /dev/null
+++ b/tools/po/po-update.sh
@@ -0,0 +1,123 @@
+#!/bin/sh
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#
+#
+# Usage:
+# ./po-update.sh pot
+# - to generate just the pot file
+# ./po-update.sh
+# - to update all locales
+# ./po-update.sh LL
+# - to update one the LL locale
+
+set -e
+
+XGETTEXT=${XGETTEXT:-xgettext}
+MSGMERGE=${MSGMERGE:-msgmerge}
+
+svn_base=
+for i in . .. ../..; do
+ if [ -d "$i/subversion/po" ]; then
+ svn_base="$i"
+ break
+ fi
+done
+if [ -z "$svn_base" ]; then
+ echo "E: You must run po-update.sh from within a Subversion source tree." >&2
+ exit 1
+fi
+
+pot_done=
+
+make_pot()
+{
+ if [ -z "$pot_done" ]; then
+ echo "Building subversion.pot..."
+ (cd $svn_base/subversion/po && \
+ find .. \
+ -name .svn -prune -or \
+ -name tests -prune -or \
+ -name bindings -prune -or \
+ -name "*.c" -print -or \
+ -name "svn_error_codes.h" -print -or \
+ -name "svn_fs_util.h" -print | \
+ $XGETTEXT --sort-by-file -k_ -kN_ -kQ_:1,2 -kSVN_ERRDEF:3 \
+ --flag=_:1:pass-c-format \
+ --flag=N_:1:pass-c-format \
+ --flag=Q_:1:pass-c-format \
+ --flag=Q_:2:pass-c-format \
+ --flag=svn_cmdline_printf:2:c-format \
+ --flag=svn_cmdline_fprintf:3:c-format \
+ --flag=svn_error_createf:3:c-format \
+ --flag=svn_error_wrap_apr:2:c-format \
+ --flag=svn_stream_printf:3:c-format \
+ --flag=svn_stream_printf_from_utf8:4:c-format \
+ --flag=svn_string_createf:2:c-format \
+ --flag=svn_string_createv:2:c-format \
+ --flag=svn_stringbuf_createf:2:c-format \
+ --flag=svn_stringbuf_createv:2:c-format \
+ --flag=svn_fs_bdb__dberrf:3:c-format \
+ --flag=file_printf_from_utf8:3:c-format \
+ --flag=do_io_file_wrapper_cleanup:3:c-format \
+ --flag=do_io_file_wrapper_cleanup:4:c-format \
+ --msgid-bugs-address=dev@subversion.apache.org \
+ --add-comments --files-from=- -o subversion.pot )
+ pot_done=1
+ fi
+}
+
+update_po()
+{
+ (cd $svn_base/subversion/po &&
+ for i in $1.po; do
+ echo "Updating $i..."
+ # In a display of truly bizarre behaviour, msgmerge (at least, the
+ # GNU gettext-tools 0.14.6 implementation) inverts the order of obsolete
+ # messages every time it is run. Therefore, run it twice, to invert and
+ # then re-invert, to minimize spurious diffs.
+ $MSGMERGE --sort-by-file --no-wrap --update $i subversion.pot
+ $MSGMERGE --sort-by-file --no-wrap --update $i subversion.pot
+ done )
+}
+
+if [ $# -eq 0 ]; then
+ make_pot
+ update_po \*
+else
+ langs=
+ while [ $# -ge 1 ]; do
+ case $1 in
+ pot) ;;
+ *)
+ if [ -e $svn_base/subversion/po/$1.po ]; then
+ langs="$langs $1"
+ else
+ echo "E: No such .po file '$1.po'" >&2
+ exit 1
+ fi
+ esac
+ shift
+ done
+ make_pot
+ for lang in $langs; do
+ update_po $lang
+ done
+fi