qtalk_opensource/contrib/extract_translations/prepare-translation.sh
#!/bin/bash

# Frontend for ejabberd's extract_translations.erl
# by Badlop

# How to create template files for a new language:
# NEWLANG=zh
# cp msgs/ejabberd.pot msgs/$NEWLANG.po
# echo \{\"\",\"\"\}. > msgs/$NEWLANG.msg
# ../../extract_translations/prepare-translation.sh -updateall

prepare_dirs ()
{
	# Where is Erlang binary
	ERL=`which erl`

	EJA_SRC_DIR=$EJA_DIR/src/
	EJA_MSGS_DIR=$EJA_DIR/priv/msgs/
	EXTRACT_DIR=$EJA_DIR/contrib/extract_translations/
	EXTRACT_ERL=$EXTRACT_DIR/extract_translations.erl
	EXTRACT_BEAM=$EXTRACT_DIR/extract_translations.beam

	SRC_DIR=$RUN_DIR/src
	EBIN_DIR=$RUN_DIR/ebin
	MSGS_DIR=$EJA_DIR/priv/msgs

	if !([[ -n $EJA_DIR ]])
	then 
	echo "ejabberd dir does not exist: $EJA_DIR"
	fi

	if !([[ -x $EXTRACT_BEAM ]])
	then 
	sh -c "cd $EXTRACT_DIR; $ERL -compile $EXTRACT_ERL"
	fi
}

extract_lang ()
{
	MSGS_FILE=$1
	MSGS_FILE2=$MSGS_FILE.translate
	MSGS_PATH=$MSGS_DIR/$MSGS_FILE
	MSGS_PATH2=$MSGS_DIR/$MSGS_FILE2

	echo -n "Extracting language strings for '$MSGS_FILE':"

	echo -n " new..."
	cd $SRC_DIR
	$ERL -pa $EXTRACT_DIR -noinput -noshell -s extract_translations -s init stop -extra . $MSGS_PATH >$MSGS_PATH.new
	sed -e 's/^% \.\//% /g;' $MSGS_PATH.new > $MSGS_PATH.new2
	mv $MSGS_PATH.new2 $MSGS_PATH.new 

	echo -n " old..."
	$ERL -pa $EXTRACT_DIR -noinput -noshell -s extract_translations -s init stop -extra -unused . $MSGS_PATH >$MSGS_PATH.unused
	find_unused_full $MSGS_FILE $MSGS_FILE.unused

	echo "" >$MSGS_PATH2
	echo "    ***** Translation file for ejabberd ***** " >>$MSGS_PATH2
	echo "" >>$MSGS_PATH2

	echo "" >>$MSGS_PATH2
	echo "    *** New strings: Can you please translate them? *** " >>$MSGS_PATH2
	cat $MSGS_PATH.new >>$MSGS_PATH2

	echo "" >>$MSGS_PATH2
	echo "" >>$MSGS_PATH2
	echo "    *** Unused strings: They will be removed automatically *** " >>$MSGS_PATH2
	cat $MSGS_PATH.unused.full >>$MSGS_PATH2

	echo "" >>$MSGS_PATH2
	echo "" >>$MSGS_PATH2
	echo "    *** Already translated strings: you can also modify any of them if you want *** " >>$MSGS_PATH2
	echo "" >>$MSGS_PATH2
	cat $MSGS_PATH.old_cleaned >>$MSGS_PATH2

	echo " ok"

	rm $MSGS_PATH.new
	rm $MSGS_PATH.old_cleaned
	rm $MSGS_PATH.unused.full
}

extract_lang_all ()
{
	cd $MSGS_DIR
	for i in $( ls *.msg ) ; do
		extract_lang $i;
	done

	echo -e "File\tMissing\tLanguage\t\tLast translator"
	echo -e "----\t-------\t--------\t\t---------------"
	cd $MSGS_DIR
	for i in $( ls *.msg ) ; do
		MISSING=`cat $i.translate | grep "\", \"\"}." | wc -l`
		LANGUAGE=`grep "X-Language:" $i.translate | sed 's/% Language: //g'`
		LASTAUTH=`grep "Author:" $i.translate | head -n 1 | sed 's/% Author: //g'`
		echo -e "$i\t$MISSING\t$LANGUAGE\t$LASTAUTH"
	done

	cd $MSGS_DIR
	REVISION=`git describe --always`
	zip $HOME/ejabberd-langs-$REVISION.zip *.translate;

	rm *.translate
}

find_unused_full ()
{
	DATFILE=$1
	DATFILEI=$1.old_cleaned
	DELFILE=$2
	cd msgs

	DATFILE1=$DATFILE.t1
	DATFILE2=$DATFILE.t2

	DELFILE1=$DELFILE.t1
	DELFILE2=$DELFILE.t2
	DELFILEF=$DATFILE.unused.full
	echo "" >$DELFILEF

	grep -v "\\\\" $DELFILE >$DELFILE2
	echo ENDFILEMARK >>$DELFILE2
	cp $DATFILE $DATFILEI
	cp $DATFILE $DATFILE2

	cp $DELFILE2 $DELFILE1
	STRING=`head -1 $DELFILE1`
	until [[ $STRING == ENDFILEMARK ]]; do 
		cp $DELFILE2 $DELFILE1
		cp $DATFILE2 $DATFILE1

		STRING=`head -1 $DELFILE1`

		cat $DATFILE1 | grep "$STRING" >>$DELFILEF
		cat $DATFILE1 | grep -v "$STRING" >$DATFILE2
		cat $DELFILE1 | grep -v "$STRING" >$DELFILE2
	done

	mv $DATFILE2 $DATFILEI

	rm -f $MSGS_PATH.t1
	rm $MSGS_PATH.unused
	rm -f $MSGS_PATH.unused.t1
	rm $MSGS_PATH.unused.t2

	cd ..
}

extract_lang_srcmsg2po ()
{
	LANG=$1
	LANG_CODE=$LANG.$PROJECT
	MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg
	PO_PATH=$MSGS_DIR/$LANG_CODE.po

	echo $MSGS_PATH

	cd $SRC_DIR
	$ERL -pa $EXTRACT_DIR -pa $EBIN_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$PO_PATH.1
	sed -e 's/ \[\]$/ \"\"/g;' $PO_PATH.1 > $PO_PATH.2
	msguniq --sort-by-file $PO_PATH.2 --output-file=$PO_PATH
	
	rm $PO_PATH.*
}

extract_lang_src2pot ()
{
	LANG_CODE=$PROJECT
	MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg
	POT_PATH=$MSGS_DIR/$LANG_CODE.pot

	echo -n "" >$MSGS_PATH
	echo "% Language: Language Name" >>$MSGS_PATH
	echo "% Author: Translator name and contact method" >>$MSGS_PATH
	echo "" >>$MSGS_PATH

	cd $SRC_DIR
	$ERL -pa $EXTRACT_DIR -pa $EBIN_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$POT_PATH.1
	sed -e 's/ \[\]$/ \"\"/g;' $POT_PATH.1 > $POT_PATH.2

	#msguniq --sort-by-file $POT_PATH.2 $EJA_MSGS_DIR --output-file=$POT_PATH
	msguniq --sort-by-file $POT_PATH.2 --output-file=$POT_PATH

	rm $POT_PATH.*
	rm $MSGS_PATH

	# If the project is a specific module, not the main ejabberd
	if [[ $PROJECT != ejabberd ]] ; then
	    # Remove from project.pot the strings that are already present in the general ejabberd
	    EJABBERD_MSG_FILE=$EJA_MSGS_DIR/es.po # This is just some file with translated strings
	    POT_PATH_TEMP=$POT_PATH.temp
	    msgattrib --set-obsolete --only-file=$EJABBERD_MSG_FILE -o $POT_PATH_TEMP $POT_PATH
	    mv $POT_PATH_TEMP $POT_PATH
	fi
}

extract_lang_popot2po ()
{
	LANG_CODE=$1
	PO_PATH=$MSGS_DIR/$LANG_CODE.po
	POT_PATH=$MSGS_DIR/$PROJECT.pot

	msgmerge $PO_PATH $POT_PATH >$PO_PATH.translate 2>/dev/null
	mv $PO_PATH.translate $PO_PATH 
}

extract_lang_po2msg ()
{
	LANG_CODE=$1
	PO_PATH=$LANG_CODE.po
	MS_PATH=$PO_PATH.ms
	MSGID_PATH=$PO_PATH.msgid
	MSGSTR_PATH=$PO_PATH.msgstr
	MSGS_PATH=$LANG_CODE.msg

	cd $MSGS_DIR

	# Check PO has correct ~
	# Let's convert to C format so we can use msgfmt
	PO_TEMP=$LANG_CODE.po.temp
	cat $PO_PATH | sed 's/%/perc/g' | sed 's/~/%/g' | sed 's/#:.*/#, c-format/g' >$PO_TEMP
	msgfmt $PO_TEMP --check-format
	result=$?
	rm $PO_TEMP
	if [ $result -ne 0 ] ; then
		exit 1
	fi

	msgattrib $PO_PATH --translated --no-fuzzy --no-obsolete --no-location --no-wrap | grep "^msg" | tail --lines=+3 >$MS_PATH
	grep "^msgid" $PO_PATH.ms | sed 's/^msgid //g' >$MSGID_PATH
	grep "^msgstr" $PO_PATH.ms | sed 's/^msgstr //g' >$MSGSTR_PATH
	echo "%% -*- coding: latin-1 -*-" >$MSGS_PATH
	paste $MSGID_PATH $MSGSTR_PATH --delimiter=, | awk '{print "{" $0 "}."}' | sort -g >>$MSGS_PATH

	rm $MS_PATH
	rm $MSGID_PATH
	rm $MSGSTR_PATH
}

extract_lang_updateall ()
{
	echo "Generating POT"
	extract_lang_src2pot 

	cd $MSGS_DIR
	echo ""
	echo -e "File Missing Language     Last translator"
	echo -e "---- ------- --------     ---------------"
	for i in $( ls *.msg ) ; do
                LANG_CODE=${i%.msg}
		echo -n $LANG_CODE | awk '{printf "%-6s", $1 }'

		# Convert old MSG file to PO
		PO=$LANG_CODE.po
		[ -f $PO ] || extract_lang_srcmsg2po $LANG_CODE

		extract_lang_popot2po $LANG_CODE
		extract_lang_po2msg $LANG_CODE

		MISSING=`msgfmt --statistics $PO 2>&1 | awk '{printf "%5s", $4 }'`
		echo -n " $MISSING"

		LANGUAGE=`grep "X-Language:" $PO | sed 's/\"X-Language: //g' | sed 's/\\\\n\"//g' | awk '{printf "%-12s", $1}'`
		echo -n " $LANGUAGE"

		LASTAUTH=`grep "Last-Translator" $PO | sed 's/\"Last-Translator: //g' | sed 's/\\\\n\"//g'`
		echo " $LASTAUTH"
	done
	echo ""
	rm messages.mo

	cd ..
}

translation_instructions ()
{
	echo ""
	echo "  A new file has been created for you, with the current, the new and the deprecated strings:"
	echo "  $MSGS_PATH2"
	echo ""
	echo "  At the end of that file you will find the strings you must update:"
	echo "   - Untranslated strings are like this: {"March", ""}."
	echo "     To translate the string, add the text inside the commas. Example:"
	echo "     {"March", "Marzo"}."
	echo "   - Old strings that are not used: "Woowoa""
	echo "     Search the entire file for those strings and remove them"
	echo ""
	echo "  Once you have translated all the strings and removed all the old ones,"
	echo "  rename the file to overwrite the previous one:"
	echo "  $MSGS_PATH"
}

EJA_DIR=`pwd`
RUN_DIR=`pwd`
PROJECT=ejabberd

while [ $# -ne 0 ] ; do
    PARAM=$1
    shift
    case $PARAM in
        --) break ;;
	-project)
		PROJECT=$1
		shift
		;;
	-ejadir)
		EJA_DIR=$1
		shift
		;;
	-rundir)
		RUN_DIR=$1
		shift
		;;
	-lang)
		LANGU=$1
		prepare_dirs
		extract_lang $LANGU
		shift
		;;
	-langall)
		prepare_dirs
		extract_lang_all
		;;
	-srcmsg2po)
		LANG_CODE=$1
		prepare_dirs
		extract_lang_srcmsg2po $LANG_CODE
		shift
		;;
	-popot2po)
		LANG_CODE=$1
		prepare_dirs
		extract_lang_popot2po $LANG_CODE
		shift
		;;
	-src2pot)
		prepare_dirs
		extract_lang_src2pot 
		;;
	-po2msg)
		LANG_CODE=$1
		prepare_dirs
		extract_lang_po2msg $LANG_CODE
		shift
		;;
	-updateall)
		prepare_dirs
		extract_lang_updateall
		;;
	*)
		echo "Options:"
		echo "  -langall"
		echo "  -lang LANGUAGE_FILE"
		echo "  -srcmsg2po LANGUAGE   Construct .msg file using source code to PO file"
		echo "  -src2pot              Generate template POT file from source code"
		echo "  -popot2po LANGUAGE    Update PO file with template POT file"
		echo "  -po2msg LANGUAGE      Export PO file to MSG file"
		echo "  -updateall            Generate POT and update all PO"
		echo ""
		echo "Example:"
		echo "  ./prepare-translation.sh -lang es.msg"
		exit 0
		;;
    esac
done
