#!/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 21917 2005-05-30 12:37:13Z madarche $

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 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 following software, so make sure they are installed on
your system and available for $prog_name:

  * the GNU Internationalization utilities,
    be sure to have the gettext package (or equivalent)

  * the OpenPTi18n Zope product

This script relies on the PRODUCTS_DIR variable to find the OpenPTi18n 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/OpenPTi18n ]; then
    $ECHO "You must install OpenPTi18n in your Products directory"
    exit 1
fi

PARSER_SCRIPT=$PRODUCTS_DIR/OpenPTi18n/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
SKINS_PATH="../skins/"

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 -o $POT_FILE_NAME $SKINS_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 | ro.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
