#!/bin/sh
#
# This script requires a Debian GNU system.
#
# Convert Moodle language packs to UTF-8, making all languages UTF-8 encoded.
# Where UTF-8 encoded language packs already exist, the original non-UTF-8 pack
# is moved out of the way and replaced with a softlink to the UTF-8 one.
# If this conversion is performed before any data is inserted, all data will be in one
# consistent encoding, meaning that multiple language packs can finally work
# together, and text will not be garbled when visitors have their GUI set to
# languages whose encodings don't match that of (parts of) the content.
#
# This script only converts the PHP files that generate the various HTML
# translations; documentation is left alone, and the database is not touched.
# It would be good practice always to set up databases with UTF-8 in the first
# place, sigh...
#
# Usage: moodle-utf ["languagedir" ["language" ...]]]
#
# "languagedir" is the directory where the language packs to be converted are
# kept.  Default is /usr/share/moodle/lang; language packs should be found
# there with names like "en" and "en_us" and so on.
#
# "language" is a name of a language pack to be converted, e.g. "en" or "en_us"
# and so on.  By default, all non-UTF-8 language packs found in languagedir are
# converted (insofar as possible).
#
# Easiest way to use this is when installing Moodle for the first time:
#
#	# apt-get install moodle
#	[...]
#	# moodle-utf
#	[...]
#
# Done!
#
# This script was written by Jeroen T. Vermeulen <jtv@thaiopensource.org>, and
# is in the public domain.
# Latest updates:
# 2005-11-02 (jtv) Major rework.  Does entire conversion now; better error
#	handling, less output, more comments.

# Base location of Moodle (defaults to /usr/share/moodle)
BASEDIR="$1"
shift

# Language packs to convert
LANGPACKS="$*"

# List files matching given pattern(s) in directory $1 (omit paths)
basefiles() {
	DIR="$1"
	shift
	PATS=$*
	pushd "$DIR" >/dev/null
	ls -d --quoting-style=shell -w 10000 -- $PATS
	popd >/dev/null
}

if test -z "$BASEDIR" ; then
	BASEDIR=/usr/share/moodle/lang
	if ! ls "$BASEDIR" >/dev/null ; then
		exit 1
	fi
fi

set -e

if test -z "$LANGPACKS" ; then
	LANGPACKS=`basefiles "$BASEDIR" '??' '??_??'`
	echo "No language packs specified.  Converting '??' and '??_??': "$LANGPACKS
fi

# File that defines encoding for a given language pack
ENCODINGFILE=moodle.php

# Regular expressions for encoding line
ENCODINGLEAD="^[[:space:]]*\$string\['thischarset'\][[:space:]]*=[[:space:]]*['\"]"
ENCODINGPAT="[^'\"]*"
ENCODINGTRAIL="['\"][[:space:]]*;[[:space:]]*$"

# Extract encoding used for language in directory $1
find_encoding () {
	grep "$ENCODINGLEAD$ENCODINGPAT$ENCODINGTRAIL" "$1/moodle.php" | sed -e "s/$ENCODINGLEAD//" -e "s/$ENCODINGTRAIL//"
}


convert () {
	PACKPATH="$1"
	UTFPATH="$2"
	OLDENCODING="$3"
	OK=true

	# First test if old encoding is supported by iconv
	if ! iconv -f "$OLDENCODING" -t utf-8 <<EOF ; then
EOF
		echo "Can't convert language pack $PACKPATH" >&2
		OK=false
	else
		echo "Converting $PACKPATH from $OLDENCODING to utf-8: $UTFPATH"

		# Create new language pack directory.
		if ! cp -r -- "$PACKPATH" "$UTFPATH" ; then
			# Failure here is likely to be fatal for all conversions...
			echo "Could not copy $PACKPATH to $UTFPATH" >&2
			exit 1
		fi

		# Convert PHP files to new encoding.  Never mind the help files
		# and documentation; touching those can only cause trouble and
		# we're really only concerned about pages that mix static with
		# dynamic content.
		# Replace old encoding string with the utf-8 one in the process.
		for i in `basefiles "$UTFPATH" '*.php'` ; do
			if ! test -s "$PACKPATH/$i" ; then
				# Avoid false errors because of files that are correctly empty
				echo "	$i: (empty file)"
				touch "$UTFPATH/$i"
			elif ! iconv -c -f "$OLDENCODING" -t utf-8 "$PACKPATH/$i" | sed -e "s/$OLDENCODING/utf-8/" >"$UTFPATH/$i" ; then
				OK=false
				echo "	$i: conversion error" >&1
			elif ! test -s "$UTFPATH/$i" ; then
				OK=false
			fi
		done
	fi
	$OK
}


# Create UTF-8 language pack based on existing language pack $1
make_utfpack () {
	INPACK=$1
	PACKPATH="$BASEDIR/$INPACK"
	UTFPATH="$PACKPATH"_utf8

	if ! test -d "$PACKPATH" ; then
		echo "Language pack $PACKPATH not found!" >&2
	else
		OLDENCODING=`find_encoding "$PACKPATH"`
		if test -z "$OLDENCODING" ; then
			echo "No encoding found in language pack $PACKPATH!" >&2
		elif test "$OLDENCODING" == "utf-8" ; then
			echo "Language pack $PACKPATH already in utf-8"
		elif ! convert "$PACKPATH" "$UTFPATH" "$OLDENCODING" ; then
			rm -rf "$UTFPATH"
		fi
	fi
}


# Move old language pack out of the way to make place for UTF-8 one
move_old() {
	OLDPACK="$1"
	BACKUP="$OLDPACK.bak"
	if test -h "$BACKUP" ; then
		rm -f -- "$BACKUP"
	else
		rm -rf -- "$BACKUP"
	fi
	mv -- "$OLDPACK" "$BACKUP"
}


for l in $LANGPACKS ; do
	OLDPACK="$BASEDIR/$l"
	NEWPACK="$OLDPACK"_utf8
	BACKUP="$OLDPACK.bak"

	if test -d "$NEWPACK" ; then
		echo "Language pack $NEWPACK already exists.  Linking $l to it."
		move_old "$OLDPACK"
		ln -s "$NEWPACK" "$OLDPACK"
	else
		make_utfpack $l
		if test -d "$NEWPACK" ; then
			move_old "$OLDPACK"
			mv -- "$NEWPACK" "$OLDPACK"
		fi
	fi
done
