====== 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 ;)
{{:p2p:rtorrent:pyroscope-rtorrent-ps:rtmanager_janv2017.png?400&direct|C'est beau}}
===== Formats =====
# 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
* ESC est un échappement qui précède les codes couleurs.
* [99m sont les codes couleurs de bash
* le format peut se définir de la même façon qu'un template, on peut utiliser des structures conditionelles, etc.
===== Script =====
Date: 24 janvier 2017
#!/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