Table des matières

rtmanager.sh

Un script fait maison pour accueillir les utilisateurs d'une session SSH sur la seedbox.

Le script est encore en développement, pas de dépot git sous la main.

Le script ne se suffit pas à lui-même, il se complète avec les formats et les templates de sortie de rtcontrol. Vous devrez aussi ajuster les permissions des répertoires.

Screenshot

Bon ok, c'est du terminal hein… mais y'a un peu de couleur ;)

C'est beau

Formats

config.ini
# Affiche nom, pourcentage de completion, taille, débit descendant et montant.
f1      = {{default ESC= '\x1B'}}{{d.name}}{{ESC}}[0m | {{ESC}}{{if d.is_complete}}[32m{{else}}[33m{{endif}}{{d.done|int}}%{{ESC}}[0m | {{ESC}}[35m{{d.size|sz|strip}}{{ESC}}[0m | {{if not d.is_complete}} {{ESC}}[36m{{d.down|sz|strip}}{{ESC}}[0m{{endif}} {{ESC}}[31m{{d.up|sz|strip}}{{ESC}}[0m
 
# Affiche uniquement le ratio et le nom.
f2      = {{default ESC= '\x1B'}}{{d.name}} | {{ESC}}{{if d.ratio < 0.75}}[31m{{elif d.ratio < 1.0}}[33m{{else}}[32m{{endif}}{{d.ratio}}{{ESC}}[0m

Script

Date: 24 janvier 2017

rtmanager.sh
#!/bin/bash
 
 
### ENV + AUTH
 
 
RTBIN="/home/rtorrentuser/bin"
RTCFGOPTS='--config-dir /home/rtorrentuser/.pyroscope -D rtorrent_rc=/home/rtorrentuser/.rtorrent.rc'
RTCMD="$RTBIN/rtcontrol $RTCFGOPTS"
RTPATHCOMPLETE="/mnt/local/1/downloads/rtorrent/complete"
RTPATHWORK="/mnt/local/1/downloads/rtorrent/work"
RTPATHWATCH="/mnt/local/1/downloads/rtorrent/watch"
RTPATHWATCHHANDLED="/mnt/local/1/downloads/rtorrent/watch_archives"
 
function rt_is_admin() {
 
	if [ "$USER" = "rtorrentuser" ]; then
		return 0
	else
		return 1
	fi
}
 
if [ "$USER" = "rtorrentuser" ]; then
	if [ "$#" -eq 0  ]; then
		RTUSER="flexget"
	else
		RTUSER="$1"
	fi
else
		RTUSER="$USER"
		# à vérif: si je mets le / final, il ne match pas
		RTCMD="$RTCMD custom_targetdir=!$RTPATHCOMPLETE/flexget*"
fi
 
 
 
### COULEURS
 
function test_colors() {
	echo -en "$C0$1$C0\t"
	echo -en "$C1$1$C0\t"
	echo -en "$C2$1$C0\t"
	echo -en "$C3$1$C0\n"
	echo -en "$C4$1$C0\t"
	echo -en "$C5$1$C0\t"
	echo -en "$C6$1$C0\t"
	echo -en "$C7$1$C0\n"
	echo -en "$C8$1$C0\t"
	echo -en "$C9$1$C0\t"
	echo -en "$CA$1$C0\t"
	echo -en "$CB$1$C0\n"
	echo -en "$CC$1$C0\t"
	echo -en "$CD$1$C0\t"
	echo -en "$CE$1$C0\t"
	echo -en "$CF$1$C0\n"
	echo -en "$CG$1$C0\t"
}
 
C0="\033[0m" # No color
C1="\033[0;30m" # Black
C2="\033[0;31m" # Red
C3="\033[0;32m" # Green
C4="\033[0;33m" # Brown
C5="\033[0;34m" # Blue
C6="\033[0;35m" # Purple
C7="\033[0;36m" # Cyan
C8="\033[0;37m" # Light Gray
C9="\033[1;30m" # Dark Gray
CA="\033[1;31m" # Light Red
CB="\033[1;32m" # Light Green
CC="\033[1;33m" # Yellow
CD="\033[1;34m" # Light Blue
CE="\033[1;35m" # Light Purple
CF="\033[1;36m" # Light Cyan
CG="\033[1;37m" # White
 
 
### RTCONTROL
 
 
RTF1="custom_targetdir=$RTPATHCOMPLETE/$RTUSER*"
 
function rt_print_user_torrents() {
	$RTCMD -qo f1 "$RTF1"
}
 
function rt_print_users_torrents() {
	$RTCMD -qo f1 "*"
}
 
function rt_print_user_incomplete() {
	$RTCMD -qo f1 "$RTF1" "is_complete=no"
}
 
function rt_print_user_complete() {
	$RTCMD -qo f1 "$RTF1" "is_complete=yes"
}
 
function rt_print_user_ratio() {
	$RTCMD -qo f2 "$RTF1"
}
 
function rt_print_user_trackers() {
	$RTCMD -q "*" -o alias -s alias \* | uniq -c
}
 
function rt_print_recent_complete() {
 
	echo -e "Téléchargements complétés récemment (< 7 jours) :\n"
 
	$RTCMD -qo f1 "*" "is_complete=yes" "completed=-1w"
 
	echo ""
}
 
function rt_print_download_details() {
	$RTCMD -q ""
}
 
function rt_print_orphans() {
	$RTCMD -qO orphans.txt \*
}
 
function rt_user_search() {
 
	if [ $# -gt 1 ]; then
		return_value=true
		__ret1="$1"
		__ret2="$2"
		shift 2
	fi
 
 
	echo "Rechercher des téléchargements selon quel motif ?"
	echo "Exemple: bisounours"
	echo "Exemple: cité*peur"
 
	echo -ne $CD"rechercher>$C0 "
	read critere
 
	if [ "$critere" != "" ]; then
 
		critere="*$critere*" # on jokerise, pas pratique sinon
 
		resultats=$(mktemp)
		$RTCMD -qo f1 "$RTF1" "$critere" | tee $resultats
		let nbresu=$(cat $resultats | wc -l)
	fi
 
	if [ "$nbresu" = "0" ]; then
		echo "Aucun résultat trouvé."
	else
		echo "Il y a $nbresu résultat(s)."
	fi
 
 
	[ $return_value ] && eval $__ret1="'$critere'" && eval $__ret2="'$nbresu'"
}
 
function rt_del_user_torrents() {
 
	action="purge"
 
	if [ "$1" = "cull" ]; then
		action="cull"
	fi
 
 
	rt_user_search critere nbresu
 
	if [ "$nbresu" -gt "0" ]; then
 
		let cptsuppr=0
 
		echo "Êtes-vous sûr de vouloir supprimer ces téléchargements ? (o/O/y/Y/n/N)"
		if [ "$action" = "cull" ]; then
			echo -ne "$CA!$C0"
		fi
 
		echo -ne $CD"supprimer>$C0 "
		read confirmation
 
		case $confirmation in
			o|O|y|Y)
				$RTCMD -q "custom_targetdir=*$RTPATHCOMPLETE/$RTUSER/*" "$critere" --"$action" --yes && let cptsuppr="$cptsuppr+1" # > /dev/null
											# --cull ou --purge)
				;;
			n|N|*)
				echo "Rien." > /dev/null	
				;;
		esac
 
		if [ "$cptsuppr" -eq "0" ]; then
				echo "Aucun téléchargement supprimé."
		else
				echo "$cptsuppr téléchargement(s) supprimé(s)"
		fi
 
	fi
}
 
# idem que _event.download.finished, sauf qu'on fait le choix de virer les symlinks de /work/
function rt_move_then_restart() {
 
	# vérifier si ce qu'on souhaite déplacer est en fait un lien symbolique
	origin=$($RTCMD "hash=$1" -qo path.strip)
 
	is_sym=0
 
	if [ -L "$origin" ]; then
		is_sym=1
	fi
 
 
        $RTCMD "hash=$1" -q --stop
        $RTCMD "hash=$1" -q --exec "directory.set={{item.custom_targetdir}}" -o custom_targetdir --yes
 
	if [ "$is_sym" -eq "1" ]; then
		rm "$origin"
	else
        	$RTCMD "hash=$1" -q --spawn "mv {{item.path}} {{item.custom_targetdir}}" -o custom_targetdir
	fi
 
        sleep 1
 
        $RTCMD "hash=$1" -q --start
}
 
function rt_test_permissions() {
 
        dir1="$($RTCMD "hash=$1" -qo custom_targetdir)"
 
	if [ ! -w "$dir1" ]; then
		echo "$dir1 n'est pas accessible en écriture."
		return 1
	fi
 
	return 0
}
 
# Si _event.download.finished n'a pas fait son boulot, on peut le faire a posteriori avec cette fonction
# Inconvénient : se lance avec les permissions de $USER
function rt_move_work_torrents() {
	hashlist=$($RTCMD -q "path=*$RTPATHWORK/*" -o hash)
 
	echo "$hashlist"
 
	let cpt=0
	let igncpt=0
 
	if [ "$hashlist" != "" ]; then
 
		for h in "$hashlist"
		do
			if rt_test_permissions "$h"; then
				rt_move_then_restart "$h" && let cpt="$cpt+1"
			else 
				let ign="$ign+1"
			fi
		done
 
		echo "$cpt téléchargement(s) déplacé(s)."
	else
		echo "Aucun téléchargement déplacé."
	fi
 
	if [ $igncpt -gt 0 ]; then
		echo "$igncpt téléchargements ont été ignorés : pas les permissions requises"
	fi
 
}
 
# Il y a un problème avec cette fonction : si t'as pas les permissions en lecture, il va penser que le lien symbolique est cassé et doit être viré.
function rt_del_broken_symlinks() {
	cpt=0
 
	for f in $RTPATHWORK/*
	do
		if [ -h "$f" ]; then
			echo "est symb: $f"
		fi
 
		if [ -r "$f" ]; then
			echo "je peux lire: $f"
		fi
 
		if [ -w "$f" ]; then
			echo "je peux écrire dans: $f"
		fi
 
		if [ -e "$f" ]; then
			echo "il existe ! $f"
		fi
 
 
		# lien sym, lisible, n'existe pas
		if [ -h "$f" -a -r "$f" -a ! -e "$f" ]; then
			echo "bwana: $f"
#			rm "$f" && let cpt=$cpt+1
		fi
	done
 
	echo "$cpt liens cassé(s) supprimé(s)."
}
 
 
### BASHERIES
 
function list_users_complete() {
 
	find "$RTPATHCOMPLETE" -mindepth 2 -maxdepth 3 -path "$RTPATHCOMPLETE/$u*" ! -empty 2>/dev/null | cut -d '/' -f 8-
	# -printf "%H : %f\n"
 
}
 
function list_user_watch() {
 
	echo -e $C4"Fichiers .torrent dans $RTUSER/watch :"$C0
 
	find "$RTPATHWATCH/$RTUSER" -iname '*.torrent'	| cut -d '/' -f 9-
 
}
 
function list_user_watch_handled() {
 
	echo -e $C4"Fichiers .torrent archivés de $RTUSER :"$C0
 
	find "$RTPATHWATCHHANDLED/$RTUSER" -iname '*.torrent'	| cut -d '/' -f 9-
 
}
 
 
### MENU
 
 
function menu_welcome() {
 
clear
 
echo -e "Salut $CB$RTUSER$C0,\n"
echo -e "Voici quelques options pour gérer tes téléchargements :\n"
 
}
 
function menu_actions() {
 
echo -e "$CA[ACTIONS]$C0"
cat << EOF
 
  [$RTUSER] L : Lister tes téléchargements
  [$RTUSER] I : Lister tes téléchargements incomplets
  [$RTUSER] C : Lister tes téléchargements terminés
  [$RTUSER] S : Rechercher des téléchargements selon leur nom
  [all]	A : Lister tous les téléchargements
  [$RTUSER] D : Supprimer des téléchargements sans supprimer les fichiers terminés
  [$RTUSER] DD : /!\ Supprimer des téléchargements, y compris les fichiers terminés
  [all] O : Lister les fichiers complets de tous les utilisateurs
  [$RTUSER] W : Lister les fichiers .torrent dans watch
  [$RTUSER] R : Afficher le ratio des téléchargements
 
EOF
 
rt_is_admin && menu_actions_admin
 
echo -e "$CA[MENU]$C0"
cat << EOF
 
  Q : Pour quitter ce menu (accès au shell)
  M : Pour réafficher ce menu
  Z : Pour afficher un dinosaure
 
EOF
 
}
 
function menu_actions_admin() {
 
echo -e "$CA[ADMIN]$C0"
cat << EOF
 
  or : Lister les fichiers orphelins (non chargés dans rtorrent)
  mv : Déplacer les fichiers qui pour une raison X sont restés dans /work/
  sy : Retirer les liens symboliques cassés de /work/
 
EOF
 
}
 
function menu_dinosaur() {
	num=$(( ( RANDOM % 8 ) + 1 ))
 
#	cola=$(( ( RANDOM % 2 ) ))
	colb=$(( ( RANDOM % 8 ) ))
	cola=1
 
	echo -ne "\033[$cola;3$colb"m
	cat $RTBIN/dinosaur.$num
	echo -ne "\033[0m"
 
}
 
function menu_unknown_option() {
	echo "Option inconnue."
	sleep 1
	clear
	menu_actions
}
 
function menu_ask() {
 
	echo -ne "$CD>$C0 "
 
	read choice
 
	case $choice in
		l|L)
			rt_print_user_torrents
			;;
		i|I)
			rt_print_user_incomplete
			;;
		c|C)
			rt_print_user_complete
			;;
		s|S)
			rt_user_search
			;;
		a|A)
			rt_print_users_torrents
			;;
		d|D)
			rt_del_user_torrents purge
			;;
		dd|DD)
			rt_del_user_torrents cull
			;;
		o|O)
			list_users_complete
			;;
		w|W)
			list_user_watch
			list_user_watch_handled
			;;
		r|R)
			rt_print_user_ratio
			;;
		or)
			rt_is_admin && rt_print_orphans || menu_unknown_option
			;;
		mv)
			rt_is_admin && rt_move_work_torrents || menu_unknown_option
			;;
		sy)
			rt_is_admin && rt_del_broken_symlinks || menu_unknown_option
			;;
		q|Q)
			echo -e "Entrez$CB rtmanager.sh$C0 pour relancer le script de gestion rtorrent."
			exit 0
			;;
		m|M)
			clear
			menu_actions
			menu_ask
			;;
		z|Z)
			menu_dinosaur
			;;
		"")
			menu_ask
			;;
		*)
			menu_unknown_option
			;;
	esac
}
 
menu_welcome
menu_actions
 
rt_print_recent_complete
 
#test_colors "Youpi!"
 
while :
do
	menu_ask
done