====== 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