diff options
author | Lorry <lorry@roadtrain.codethink.co.uk> | 2012-08-22 14:29:52 +0100 |
---|---|---|
committer | Lorry <lorry@roadtrain.codethink.co.uk> | 2012-08-22 14:29:52 +0100 |
commit | f1bdf13786f0752c0846cf36f0d91e4fc6747929 (patch) | |
tree | 4223b2035bf2240d681a53822808b3c7f687b905 /tools/po | |
download | subversion-tarball-f1bdf13786f0752c0846cf36f0d91e4fc6747929.tar.gz |
Tarball conversion
Diffstat (limited to 'tools/po')
-rwxr-xr-x | tools/po/l10n-report.py | 246 | ||||
-rwxr-xr-x | tools/po/po-update.sh | 123 |
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 |