#!/bin/bash
#
# Inspiré du travail de:
# Sebastien de Boissieu (c) 2006
# $Id: convertEnc.sh,v 1.5 2006/10/22 14:18:50 sebastien Exp $
# Licence : GPL 2
#-------------------------------------------------------------------------------------
# Conversion de toute une arborescence d'un encodage dans un autre.
# Exemple d'utilisation :
#  mise à  jour de sa distribution Linux d'encodage xxxx vers UTF-8
#
# Nécessite : convmv et iconv
#
# Utilisation :
# $ ./convert_encod.sh /Documents/Divers
#
# IMPORTANT : faites une copie de vos données et travaillez sur cette copie !!
# (Je ne peux être tenu responsable si vous corrompez vos données, soyez prudents)
#
# Script modifié par zebulon-2 (Zeb_66)
# FROM et TO en Majuscule! Pour la liste complète des encodages supportés et le format d'écriture,faire: $ iconv --list
# l'utilisation est très simple, il suffit de suivre les indications.
# Se reporter à  la notice jointe pour les détails du fonctionnement.

FROM="ISO-8859-1"					# encodage source des noms de fichiers/rÃÂÃÂ©pertoires.
TO="UTF-8"						# encodage cible
TP=~/tmp							# emplacement des fichiers de travail
LST=converti-REP.txt				# Fichier renfermant tout les rÃÂÃÂ©pertoires traitÃÂÃÂ©s.
LST1=converti-NON.txt				# Fichier renfermant les fichiers non traitÃÂÃÂ©s.
STAMP="##ÃÂÃÂ§$TOÃÂÃÂ§##"					# marquage des fichiers sans charset (scripts par exemple)

# Conversion récursive des noms de fichiers et répertoires
convert_names()
{
echo "                            ***  Conversion des NOMS de fichiers et rÃÂÃÂ©pertoires  ***"
echo
convmv -r -f $FROM -t $TO --qfrom --notest --replace $reponse 
echo "                    ***  Conversion des Noms de fichiers et rÃÂÃÂ©pertoires effectuÃÂÃÂ©e... *** "
echo;sleep 3
}

marque()		# recherche du marquage en fin de document (Stamp)
{
grep -q $STAMP $fic;A=$?
	if [ "$A" = "0" ]; then
	Stamp="1"
	else
	Stamp="0"
fi
}

# Procédure de visu du fichier à  corriger
voir()
{
kwrite --encoding="$encForm2" $fic
F2=""
while [ "$F2" = "" ]; do
echo "                         *** La conversion ÃÂÃÂ  partir de: $encForm2 convient-elle? ***"
echo "        === 0 pour \"changer l'encodage source\" - 1 pour \"OUI, c'est bon\" - 2 pour \"dÃÂÃÂ¨jÃÂÃÂ  converti\" ==="
echo;echo  -n  "   Votre dÃÂÃÂ©cision? : "
read  -n 1 reponse
case	$reponse in
0)
echo;echo "                         **  Si pas trouvÃÂÃÂ© un encodage compatible, rÃÂÃÂ©pondre : 0  **"
echo;echo -n "   Quel encodage(en minuscule)? : "
read  reponse1
	echo
	case $reponse1 in
	0)
	echo $HEAD/$fic 1>>$TP/$LST1
	F2="0";;
	*)
	F3=""
	while [ "$F3" = "" ]; do
	CODE=`echo $reponse1 | tr $MIN $MAJ`
	grep -qox "$CODE" $TP/iconv_list.txt;A=$?
		if [ "$A" = "0" ]; then
		encForm2="$CODE"
		F2="1";F3="1"
		else
		echo;echo "             **  Mauvais ÃÂÃÂ©noncÃÂÃÂ© du code, vérifier la syntaxe dans $TP/iconv_list.txt  **"
		echo "                           **  Taper le bon code ou 0 pour abandonner... **"
		echo;echo -en "   Ancien code:$reponse1\tTapez votre nouveau code: "
		read  reponse2		
		echo
		case $reponse2 in
		0)
		echo $HEAD/$fic 1>>$TP/$LST1
		F2="0";F3="1";;
		*)
		F2="1";F3="";reponse1="$reponse2";;
		esac
	fi
	done;;
	esac
;;

1)
F2="1";;
2)
F2="2";;
*)
echo "                        !!!! Mauvaise réponse... !!!!"
echo
F2=""
sleep 1;;
esac
done
}

# Routine de conversion du contenu d'un fichier
do_convert()
{
fic="$1";F1="0";Stamp="0";F2="1"
encForm2=`file -bi "$fic" | awk -F "charset=" '{ print $2 }' | tr $MIN $MAJ`	# Lecture du charset
case $encForm2 in		# redéfinition du charset  partir du mime

UNKNOWN)
encForm1=`file -bi "$fic" | awk -F "charset=" '{ print $1 }' |  sed "s/; //"`	# Lecture du mime
	case "$encForm1" in
	"text/x-c")
	encForm2="ISO-8859.1";;
	"text/plain")
	encForm2="ISO-8859-15";;
	*)
	encForm2=""
	echo $HEAD/$fic 1>>$TP/$LST1;;
	esac
;;

US-ASCII)
encForm2="";;

"")
encForm1=`file -bi "$fic" | awk -F "charset=" '{ print $1 }' |  sed "s/; //"`
	case "$encForm1" in
	"application/x-shellscript")
	encForm2="ISO-8859-1"
	marque
		if [ "$Stamp" = "0" ]; then
		voir
		F1="1"
		else
		encForm2=""
	fi;;	
	esac
;;

esac
	if [ "$encForm2" != "" ]; then
	if [ "$F2" = "2" ];then echo -e "\r$STAMP" >> $fic;fi
		if [ "$encForm2" != "$TO" ]; then 		# ce charset est-il diffÃÂÃÂ©rent de celui visÃÂÃÂ©?
			if [ "$F2" = "1" ]; then 
			echo "     Conversion de: "$fic"  -> "$encForm1"     "$encForm2
			nouv_fic=($fic"_"$TO)
			iconv -f "$encForm2" -t "$TO" $fic -o $nouv_fic		# la conversion
				if [ "$F1" = "1" ]; then
				echo -e "\r$STAMP" >> $nouv_fic
			fi 
			touch -r $fic $nouv_fic				# Pour conserver la/les date(s) :
			chown --reference $fic $nouv_fic		# Pour conserver le proprietaire
			chmod --reference $fic $nouv_fic		# pour conserver les droits :
			mv -f $nouv_fic $fic				# on ÃÂÃÂ©crase l'ancien fichier par le nouveau
			F="1"
		fi
	fi
fi
}

# Conversion rÃÂÃÂ©cursive du contenu des fichiers texte
convert_content()
{
	if [ -d "$HEAD" ]; then 			# c'est un rÃÂÃÂ©pertoire
		if [ -x "$HEAD" ]; then 		# On peut entrer dans le rÃÂÃÂ©pertoire
		echo "EntrÃÂÃÂ©e dans : $HEAD"
		chemin_orig=`pwd`
		cd -- "$HEAD"
		F="0"
		for fic in * ; do
		base_fic=$(basename -- "$fic")
               if [ -f "$base_fic" ]; then 	     # Si fichier, on exÃÂÃÂ©cute la procÃÂÃÂ©dure
			tilde=`echo "$base_fic" | cut --delimiter=~ --fields=2`
				if [ "$tilde" != "" ]; then
				do_convert "$base_fic"
			fi
		fi
		done
			if [ "$F" = "0" ]; then
			echo "==Rien ÃÂÃÂ  faire!=="
		fi
		echo "Sortie de   : "$HEAD
		cd $chemin_orig
		else
		echo "*** EntrÃÂÃÂ©e INTERDITE dans : $HEAD ***"
	fi
fi
}

#=======================================
# DÃÂÃÂ©but exÃÂÃÂ©cution

MIN="abcdefghijklmnopqrstuvwxyz.-_:"
MAJ="ABCDEFGHIJKLMNOPQRSTUVWXYZ.-_:"
F=""


lst=`echo "$LST1" | cut -sd . --fields=1`
LST1=($lst"_"`date +%d%m%g`".txt")

LST2="convert_"`date +%d%m%g`".txt"
LST3="convert0_"`date +%d%m%g`".txt"

rep="0"
until [ "$rep" = "1" ]; do
clear
echo "                       *** Conversion des rÃÂÃÂ©pertoires/fichiers et contenu en $TO ***"
echo "                      === Indiquez le chemin (Path) absolu de la zone ÃÂÃÂ  convertir ==="
echo "                                            suivi d' entrÃÂÃÂ©e <--| "
echo "                                    Exemple:  /home/mon-home/Documents  "
echo "                              Pour quitter sans rien faire --> rÃÂÃÂ©pondre: q"
echo;echo  -n  "   Votre Path? : "
read reponse
	if [ "$reponse" = "q" ]; then
	clear;exit 1
fi
	if [ "$reponse" != "" ]; then
	test -d $reponse ;A=$?
		if [ "$A" = "0" ]; then
		echo
		rep="1"
		else
		clear
		echo
		echo "                           !!!! Erreur dans le path...$reponse !!!!"
		echo "                  === Indiquez le chemin (Path) absolu de la zone ÃÂÃÂ  convertir ==="
		sleep 4
	fi
fi
done

reponse=$(echo $reponse | sed "s/\/$//")
echo;echo "                              == OpÃÂÃÂ©ration lancÃÂÃÂ©e sur: $reponse =="
echo
convert_names $reponse
echo "                      ============================================================"
echo
# Remarque : si $reponse est un rÃÂÃÂ©pertoire dont le nom a ÃÂÃÂ©tÃÂÃÂ© converti, le contenu de $reponse est obsolÃÂÃÂ¨te.
# on le convertit :
path=$(echo $reponse | iconv -f $FROM -t $TO)
echo "                                    Path actuel="$path
echo;echo "                             ***  Conversion du contenu des fichiers  ***"
echo

ls -AR1 $path | sed -n "/:$/p"  >$TP/$LST3;cat $TP/$LST3 | sed "s/:$//" >$TP/$LST2
rm -f $TP/$LST3

	if [ ! -f $TP/iconv_list.txt ]; then
	iconv --list | sed "s/\/\/*$//g" > $TP/iconv_list.txt
fi

NL=0;HEAD="1"
TAIL=$(tail -n 1 $TP/$LST2)
until [ "$HEAD" = "$TAIL" ]; do
NL=$(($NL + 1))
HEAD=$(head -n $NL $TP/$LST2 | tail -n 1)
convert_content
done

cat $TP/$LST2 >> $TP/$LST
rm -f $TP/$LST2
echo;echo "                                          *** TERMINE ***"
echo
##ÃÂ§UTF-8ÃÂ§##
##ÃÂ§UTF-8ÃÂ§##
##ÃÂ§UTF-8ÃÂ§##

