#!/bin/sh
# Copyright (c) 2003-2005 Nuxeo SARL <http://nuxeo.com>
# Authors:
# M.-A. Darche <madarche@nuxeo.com>
# Julien Anguenot <ja@nuxeo.com>
# Encolpe Degoute <edegoute@nuxeo.com>
#
# $Id: update_pos 33162 2006-02-20 11:12:25Z div $

prog_name=update_pos
usage="Usage:
$prog_name [options]

  -h, --help
     print help message and exit.

  -v, --verbose
     print messages and debug information during po file processing.
"

help() {
echo "
$usage
This script scans the skins directory for ZPT files (*.zpt and *.pt) to find
strings to translate. It updates the pot/pos files inside the i18n directory of
the product in which the script is run. Afterward one can then safely and very
easily update the *.po files for untranslated messages.

This script relies on the GNU Internationalization utilities, so be sure that
you have the gettext package (or equivalent) on your system.

This script relies on the PRODUCTS_DIR variable to find the CPSI18n product.
So for this script to work, you need to set this variable.

Example:
$ cd /var/lib/zope2.7/instance/instance1/Products/CPSDefault/i18n/
$ export PRODUCTS_DIR=/var/lib/zope2.7/instance/instance1/Products/
$ update_pos --verbose
"
}

if [ ! $Z_NAME ]; then
    ECHO=echo
    PWD=pwd
    RM=rm
    GREP=grep
else
    # Include the Nuxeo specific script inc.sh if it exists
    . inc.sh || exit -1
fi

# If the first argument is "-h" or "--help" display help.
if [[ $1 == "-h" ]] || [[ $1 == "--help" ]]; then
    help; exit 0
fi

# If the first argument is "-v" or "--verbose" display help.
if [[ $1 == "-v" ]] || [[ $1 == "--verbose" ]]; then
    verbose='True'
else
    verbose=''
fi

# Check a po or pot file well-formedness
checkPoFile() {
    po_file=$1
    # We are interested in the conversion here, we are just interested by the
    # possible error messages and the return status of the command.
    # 0 => the file is correct, otherwise there are errors.
    msgconv $po_file >> /dev/null
    if [ $? -ne 0 ] ; then
        $ECHO "##############################################"
        $ECHO "The file $po_file has problems!"
        $ECHO "Correct the errors and re-run $prog_name"
        $ECHO "##############################################"
        $ECHO
        exit 1
    fi
}

# Take the .config.pot from the make_pot
# to get the name of the pot file choosen by
# the user.
getPotName() {
    POT_FILE_NAME=`$GREP pot ./.config.pot`
}

# This optional file may be used to eliminate duplicate translations with
# CPSDefault or other products such as CPSSchemas, etc. when a product overide
# some templates. To activate this functionality, you just need to have a
# .blacklist_pot file in your i18n directory.
#
# This file may have multiple lines. Each line of this file must be the path to
# the xxx.pot file of a product.
BLACKLIST_POT_FILE_NAME='.blacklist_pot'


###############
#    MAIN
###############

if [[ -n $verbose ]]; then
    $ECHO "################################################"
    $ECHO "### Environment variables"
    $ECHO "################################################"
    $ECHO "ZHOME/Z_NAME = $ZHOME/$Z_NAME"
    $ECHO "PRODUCTS_DIR = $PRODUCTS_DIR"
fi

if [ -x $ZHOME/$Z_NAME/bin/python ]; then
    PYTHON_BIN=$ZHOME/$Z_NAME/bin/python
else
    PYTHON_BIN=`which python`
fi

# PRODUCTS_DIR is the only necessary variable that this script needs to get
if [ -z $PRODUCTS_DIR ]; then
    if [ -d $ZHOME/$Z_NAME/Products ]; then
        PRODUCTS_DIR=$ZHOME/$Z_NAME/Products
    else
        PRODUCTS_DIR=`$PWD`/../..
    fi
    if [ -n $verbose ]; then
        $ECHO "Computed PRODUCTS_DIR = $PRODUCTS_DIR"
    fi
fi

if [ -n $verbose ]; then
        $ECHO
fi

if [ ! -d $PRODUCTS_DIR/CPSI18n ]; then
    $ECHO "You must install CPSI18n in your Products directory"
    exit 1
fi

PARSER_SCRIPT=$PRODUCTS_DIR/CPSI18n/i18n_xgettext.py
# Checking if we are in the i18n directory
$PWD | grep "i18n" >> /dev/null
if [ $? -eq 1 ] ; then
    $ECHO "update_pos **needs** to be executed within the i18n directory"
    exit 1
fi
$PWD | grep "i18n/" >> /dev/null
if [ $? -eq 0 ] ; then
    $ECHO "update_pos **needs** to be executed within the i18n directory"
    exit 1
fi

# Where to look for the .z?pt files
ZPT_PATH=".."

if [[ -n $verbose ]]; then
  $ECHO "################################################"
  $ECHO "### Checking .pot and .po files well-formedness"
  $ECHO "################################################"
  $ECHO
fi

# Generating the .pot file from the ZPTs.
# Getting the file name to use from the product's configuration
# file. This file name is $POT_FILE_NAME
getPotName
chmod a+w $POT_FILE_NAME
$PYTHON_BIN $PARSER_SCRIPT \
--output $POT_FILE_NAME --output-encoding='ISO-8859-15' $ZPT_PATH

# Checking the ZPT's po file well-formedness
checkPoFile $POT_FILE_NAME

# Reading each line of the file with name
# BLACKLIST_POT_FILE_NAME to find all the files which we want
# to purge duplicates from.
#
# The BLACKLIST_POT_FILE_NAME is an optional file, so we must
# test that the file exists and is readable before trying to use it.
if [[ -r $BLACKLIST_POT_FILE_NAME ]]; then
  PURGED_POT_FILE_NAME="$POT_FILE_NAME.purged"
  while read line; do
    EXISTING_POT_FILE_NAME=$line
    if [[ -n $EXISTING_POT_FILE_NAME ]]; then
        if [[ -n $verbose ]]; then
            $ECHO "##################################################################"
            $ECHO "Purging duplicates from file $EXISTING_POT_FILE_NAME"
            $ECHO "##################################################################"
            $ECHO
        fi
        msgattrib --only-file=$EXISTING_POT_FILE_NAME \
        --set-obsolete --no-obsolete -o $PURGED_POT_FILE_NAME $POT_FILE_NAME
        if [[ -r $PURGED_POT_FILE_NAME ]]; then
            mv $PURGED_POT_FILE_NAME $POT_FILE_NAME
        fi
    fi
  done < $BLACKLIST_POT_FILE_NAME
fi

if [[ -r custom.pot ]]; then
    # Checking the user custom.pot file well-formedness
    checkPoFile custom.pot
    # Concatenate the custom pot file and the pot file coming from the ZPTs
    msgcat --use-first $POT_FILE_NAME custom.pot -o $POT_FILE_NAME
fi

chmod a-w $POT_FILE_NAME

# Merging the po files with the new pot template
if [[ -n $verbose ]]; then
    $ECHO "##################################################################"
    $ECHO "Updating the final *.po files that will be used by the application"
    $ECHO "##################################################################"
    $ECHO
fi
ls *.po | while read po_file ; do
    # Checking the final po file because someone might have corrupted
    # it for example by inserting duplicate translations.
    checkPoFile $po_file
    if [[ -n $verbose ]]; then
        $ECHO "Merging $po_file with $POT_FILE_NAME"
        msgmerge $po_file $POT_FILE_NAME -o $po_file
    else
        msgmerge $po_file $POT_FILE_NAME -o $po_file 2>/dev/null
    fi
    # Replacing possible fuzzy translations from final .po file with
    # translations from the reference translations (which are en and
    # fr translations at the moment) so that we only end up with
    # meaningfull translations.
    case $po_file in
        fr.po | mg.po | it.po) po_reference_file=fr.po;;
        eu.po) po_reference_file=es.po;;
        *) po_reference_file=en.po;;
    esac
    if [[ -r $po_reference_file ]] \
       && [ $po_file != $po_reference_file ]; then
        if [[ -n $verbose ]]; then
            $ECHO "Replacing fuzzy translations in $po_file by the translations from the $po_reference_file file"
        fi
        # Keeping track of which messages have fuzzy translations by
        # storing them in a dedicated file.
        fuzzy_po="fuzzy_$po_file"
        msgattrib --only-fuzzy -o $fuzzy_po $po_file
        if [[ -r $fuzzy_po ]]; then
            # Generating a file purged from fuzzy translations
            purged_po="purged_$po_file"
            msgattrib --no-fuzzy -o $purged_po $po_file
            # Augmenting the purged file with all the translations
            # from the po_reference_file.
            with_reference_trans_po="with_ref_trans_$po_file"
            msgmerge --no-fuzzy-matching -o $with_reference_trans_po $purged_po $po_reference_file 2>/dev/null
            # Marking back all the translations that are fuzzy for
            # this particular language so that the translators know
            # that they should provide translations in their own
            # language instead.
            msgattrib --only-file=$fuzzy_po --set-fuzzy --clear-obsolete -o $po_file $with_reference_trans_po
            # Un-fuzzy-ing the header entry. There isn't any simpler way of
            # doing this. This step is not mandatory, but it is better that way.
            msgattrib --only-file=$purged_po --clear-fuzzy -o $po_file $po_file
            # Removing the temporary files
            $RM -f $fuzzy_po $purged_po $with_reference_trans_po
        fi
    fi
done

exit 0
