#!/bin/sh -e # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE # Version 2, December 2004 # Copyright (C) 2010-2013 Zakhar @ ubuntu.fr # Everyone is permitted to copy and distribute verbatim or modified # copies of this license document, and changing it is allowed as long # as the name is changed. # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE # TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION # 0. You just DO WHAT THE FUCK YOU WANT TO. # This program is free software. It comes without any warranty, to # the extent permitted by applicable law. You can redistribute it # and/or modify it under the terms of the Do What The Fuck You Want # To Public License, Version 2, as published by Sam Hocevar. See # http://www.wtfpl.net/ for more details. #=========================================================== # Fonction : # ---------- # - Télécharge automatiquement un lien ou une liste de liens free spécifiés dans # un fichier passé en paramètre 1. # NOTE: la liste de lien peut être une page web, le script extrait les liens # qui ont un pattern correct correspondant à un lien dl.free # Il ne s'agit cependant pas d'un "parsing", par ex. si les liens sont # raccourcis par une balise le script ne # trouvera pas. Cependant pour des liens postés dans des forums, ce genre # de "truc" n'existe pas, et les liens sont en général trouvés. # En cas de difficulté, la solution consiste alors à extraire les liens # 'manuellement' avec un éditeur de texte. # - Réessaye en cas d'erreurs du serveur (infini, CTRL+C pour stopper) # - Le téléchargement peut être interrompu à tout moment. Il reprendra # exactement où il avait été interrompu. # - Lorsqu'on a passé un fichier contenant des liens et qu'on reprend le # téléchargement, celui-ci saute les fichiers déjà téléchargés. # - Les fichiers résultants possèdent le nom donnés par l'uploader. # Si ce nom n'est pas récupérable, le nom du lien à la place. # - On peut lancer plusieurs scripts de téléchargement en parallèle à # condition qu'ils ne portent pas sur les mêmes liens à télécharger. # # Usage : # ------- # Voir description dans la fonction usage() # # Remarque : ce script fonctionne que vous soyez chez Free ou pas # ========== (sinon c'est juste BEAUCOUP plus long quand on n'est pas chez Free !) # Rectificatif : Depuis la fin de Megaupload, pour lutter contre la surcharge et que # =========== les freenautes puissent avoir un service décent, Free a mis en place # un captcha pour les non Freenautes. Le script ne fonctionne donc plus # si l'on n'est pas chez Free, et il n'y a rien qu'on puisse faire. # # Tested : Ubuntu Lucid, Precise # ------ # # Version : 2.2 # ------- # # Date : 2013-01-05 # ----- # # Author : Zakhar # ------ # # History : # ------- # 2.2 # - Licence changée en WTFPL V2 # - Signalement d'un bug par netbja lors d'une utilisation avec screen # (http://forum.ubuntu-fr.org/viewtopic.php?pid=12093101#p12093101) # Désormais, lancé avec screen ou byobu, le script fonctionne correctement # les ecritures à l'écran se font en monochrome. # 2.1.1 # Les scripts lancés en parallèle tiennent désormais compte du marquage # correctement. Le fichier de lien est marqué avec un lock, et relu à chaque # item pour vérifier si un téléchargement parallèle a eu lieu et s'est terminé. # 2.1.0 # - Le post de Lapogne71 (http://forum.ubuntu-fr.org/viewtopic.php?id=896681) # m'a donné l'idée de rendre le script "parallèle". En réalité, pour ne pas # rentrer dans cette complexité et aussi pour garder un affichage clair, # vous pouvez désormais lancer le script sur une même liste dans plusieurs # terminaux, si le fichier est déjà en cours de téléchargement (dans un # autre terminal), cela vous sera indiqué, et on passe au fichier suivant. # Et en réalité c'était très facile à faire... puisque Free nous dit lorsque # on tente de charger 2 fois le même fichier (c'est une des limites posées # par Free pour éviter les "accélérateurs de téléchargement). # Donc si vous avez un liste de 15 fichiers et que vous voulez paralléliser # il suffit de lancer le script avec le nom de la liste en paramètre sur # plusieurs terminaux. Le maximum est 6, puisque au delà Free bloque au delà. # 2.0.0 # - Version curl / dash + extraction intelligente de liens # # Contributor : // Ajouter votre nom si vous contribuez et redistribuez // # ----------- # ====================================================================================== # Notes à l'attention des futurs contributeurs (et pour mémoire pour moi-même)! # ----- # # Particularités (bug ?) Free. # - Pour obtenir le nom du fichier, il suffit d'avoir le header --content-disposition # En principe on pourrait faire juste un HEAD mais cela échoue et dl.free.fr retourne # une erreur 404 sur ce HEAD # On utilise donc une "ruse", on fait un GET normal en demandant un "range" # impossible. La réponse normale est alors 416 (Range impossible) si on est chez Free # et sinon on obtient une page avec le lien vers le fichier à télécharger. # # Différences Freenautes/Non Freenautes. # - Pour un Freenaute, l'activation du lien télécharge directement le fichier # - Un non Freenaute va récupérer une page de formulaire dans laquelle figure # le nom du fichier spécifié par l'uploader et un lien de téléchargment. # # - Les status header HTTP qui nous intéressent sont : # 404 : là on arrête le script vu qu'un fichier est irrécupérable. # 200 : OK # 206 : dans le cas d'une reprise (contenu partiel) après un CTRL+C # 416 : dans le cas du contournement expliqué plus haut. Cela peut aussi arriver si # on a détruit réinitialisé le fichier des liens et que certains fichiers sont # déjà complètement téléchargés. Dans ce cas on ira voir au serveur, et on # constate que la longueur du fichier est la même que le fichier local, et le # serveur rendra donc 416. Ce n'est donc pas une erreur à proprement parler # pour ce qui nous concerne. # 500 : cela signale une surcharge du serveur. Dans ce cas on temporise et # on refait un essai. # # - Si curl rencontre une erreur, c'est de toute façon irrécupérable. Dans ce cas le # script s'arrêtera car il est lancé avec l'option '-e' # # ====================================================================================== # -------------------------------------------------------------------------------------- # Variables et fonctions utilitaires (usage et trap) | # -------------------------------------------------------------------------------------- SLEEP=30 fCHECK='n' fFORCE='n' fMARK='n' fFBX='n' fCPY='n' fREN='n' fMOVE='n' fVERB='n' FILTRE='' LINKS='' LIST='' DEST='' PATTERN='http://dl.free.fr/' LOCK_FILE='/tmp/dlfree.lock' LIST_FILE='/tmp/dlfree.list' FBX_CONFIG_FILE="${HOME}/.config/mafreebox.conf" FBX_IP_PORT='mafreebox.freebox.fr' JSONRPC='{"jsonrpc":"2.0","method":' # -------------------------------------------------------------------------------------- # Fonction de nettoyage final et trap en cas d'arrêt forcé du script | # -------------------------------------------------------------------------------------- clean() { rm "${TMPLOG}" "${TMPLOG}".?; } trap clean HUP INT QUIT ABRT TERM # -------------------------------------------------------------------------------------- # Contournement permettant par exemple d'utiliser le script via phpshell qui lance | # un terminal "basique" ne supportant pas tput. | # -------------------------------------------------------------------------------------- if tput sgr0 2>/dev/null && tput setf 9 2>/dev/null; then TPUT="tput" else TPUT="nop" fi nop() { : } # -------------------------------------------------------------------------------------- # Diverses fonctions utilitaires | # -------------------------------------------------------------------------------------- usage() { if [ -n "$1" ]; then ${TPUT} bold; printf "\n%s\n\n" "${1}"; ${TPUT} sgr0; fi cat <, --sleep= Spécifie le temps d'attente en cas de problème serveur. -v, --verbose Mode verbeux. -V, --version Affiche la version du script. EOF if [ -n "${TMPLOG}" ]; then clean; fi exit $# } vecho() { if [ "${fVERB}" = 'y' ]; then printf '⬕ %s\n' "${1}" fi } cyan() { ${TPUT} setf 3; ${TPUT} bold; } red() { ${TPUT} setf 4; ${TPUT} bold; } yellow() { ${TPUT} setf 6; ${TPUT} bold; } normal() { ${TPUT} setf 9; ${TPUT} sgr0; } abort() { ERR=${1} if [ ${1} -ne 0 ]; then red; fi until shift && [ -z "${1}" ]; do printf '%s\n' "${1}" done if [ -n "${TMPLOG}" ]; then clean; fi normal exit 1 } jsoncatch() { if [ "${HTTP_CODE}" -ne 200 ] || grep ',"error":' "${TMPLOG}" >/dev/null; then echo "\n** Erreur JSON avec la Freebox." cat "${TMPLOG}" clean exit fi } freebox_start_dl() { HTTP_CODE=$( curl "http://${FBX_IP_PORT}/download.cgi" \ -o "${TMPLOG}" \ -b "${TMPLOG}.f" \ -d "url=${IDENT}&user=freebox&method=download.http_add" \ -H 'X-Requested-With: XMLHttpRequest' \ -w "%{http_code}" \ -s) jsoncatch } marklink() { if [ ${fMARK} = 'y' ]; then ( flock 9 sed -i -e "s|${IDENT}|# &\|${NAME}|" "${LINKS}" ) 9>"/tmp/${LINKS}.lock" rm -f "/tmp/${LINKS}.lock" fi } checkform() { if [ "${fMARK}" = 'y' ]; then vecho "-k ignoré dans cette forme" fMARK='n' fi } # Priorité : move / rename / copy / freebox ignorefbx() { if [ "${fFBX}" = 'y' ]; then vecho "-b est ignoré lorsque ${1} est spécifié" fFBX='n' fi } ignorecpy() { if [ "${fCPY}" = 'y' ]; then vecho "-p est ignoré lorsque ${1} est spécifié" fCPY='n' fi ignorefbx "${1}" } checkprio() { if [ "${fMOVE}" = 'y' ]; then if [ "${fREN}" = 'y' ]; then vecho "-r est ignoré lorsque -m est spécifié" fREN='n' fi ignorecpy '-m' else if [ "${fREN}" = 'y' ]; then ignorecpy '-r' else if [ "${fCPY}" = 'y' ]; then ignorefbx '-p' fi fi fi } checkmark() { if [ "${fCHECK}" = 'y' -a "${fMARK}" = 'y' ]; then vecho "-k est ignoré lorsque -c est spécifié" fMARK='n' fi } checkforce() { if [ "${fCHECK}" = 'y' -a "${fFORCE}" = 'y' ]; then vecho "-f est ignoré lorsque -c est spécifié" fFORCE='n' fi } param2() { printf '%s' "${1}" | cut -c "${2}"- | sed 's/[=|:]\?//' } # -------------------------------------------------------------------------------------- # Lecture et vérification des paramètres | # -------------------------------------------------------------------------------------- echo until [ -z "${1}" ]; do case "${1}" in --freebox ) fFBX='y'; checkprio ;; --check ) fCHECK='y'; checkforce; checkmark ;; --filtre ) FILTRE=$2; shift ;; --filtre* ) FILTRE=$( param2 "${1}" 9 ) ;; --force ) fFORCE='y'; checkforce ;; --help ) usage ;; --mark ) fMARK='y'; checkmark ;; --move ) fMOVE='y'; checkprio ;; --copy ) fCPY='y'; checkprio ;; --rename ) fREN='y' ; checkprio ;; --sleep ) SLEEP=$2; shift ;; --sleep* ) SLEEP=$( param2 "${1}" 8 ) ;; --verbose ) fVERB='y' ;; --version ) printf "%s\n" "$( basename ${0} ): Version 2.1.1"; exit 0 ;; - ) usage "Paramètre non spécifié : '-'" ;; -* ) i=2 while [ ${i} -le ${#1} ] do case $( printf '%s' "${1}" | cut -c ${i} ) in b ) fFBX='y'; checkprio ;; c ) fCHECK='y'; checkforce; checkmark ;; e ) if [ ${i} -eq ${#1} ]; then FILTRE=$2; shift else FILTRE=$( param2 "${1}" ${i} ) fi break ;; f ) fFORCE='y'; checkforce ;; h ) usage ;; k ) fMARK='y'; checkmark ;; m ) fMOVE='y'; checkprio ;; p ) fCPY='y'; checkprio ;; r ) fREN='y' ; checkprio ;; s ) if [ ${i} -eq ${#1} ]; then SLEEP=$2; shift else SLEEP=$( param2 "${1}" ${i} ) fi break ;; v ) fVERB='y' ;; V ) printf "%s\n" "$( basename ${0} ): Version 2.2"; exit 0 ;; * ) usage "Paramètre incorrect : '-$(printf '%s' ${1} | cut -c ${i})'" ;; esac i=$(( ${i} + 1 )) done ;; *) if [ -n "${LINKS}" ]; then if [ -n "${DEST}" ]; then usage "Argument en trop : '${1}'." else DEST="${LINKS}" LINKS="${1}" fi else LINKS="${1}" fi ;; esac shift done vecho "Lecture des paramètres OK" # -------------------------------------------------------------------------------------- # Si on est en 'copie/move' de la Freebox, le premier paramètre est la destination. | # Si 2 paramètres avaient été donnés, c'est déjà OK, mais sinon il faut inverser. | # Si aucun paramètre, on fixe DEST au répertoire courant : '.' | # Sinon, on vérifie juste si on n'a pas donné trop de paramètres ou aucun ! | # Dans le cas du rename, 0 param est OK, 1 est rename sur liste de filtrage | # -------------------------------------------------------------------------------------- vecho "Détermination de la forme utilisée" if [ "${fREN}" = 'y' ]; then if [ -n "${DEST}" ]; then usage "Argument en trop : '${DEST}'." fi if [ "${fFORCE}" = 'y' ]; then vecho "-f sera ignoré dans cette forme" fFORCE='n' fi if [ -z "${LINKS}" ]; then vecho "Forme 4 : renommage total sur la Freebox" if [ "${fMARK}" = 'y' ]; then vecho "-k sera ignoré dans cette forme" fMARK='n' fi else vecho "Forme 4 : renommage sur la Freebox filtré par liste" fi else if [ "${fCPY}" = 'y' -o "${fMOVE}" = 'y' ]; then if [ -z "${DEST}" ]; then vecho "Forme 4 : copie/déplacement total de la Freebox" DEST="${LINKS}" LINKS='' if [ -z "${DEST}" ]; then DEST='.' fi if [ "${fMARK}" = 'y' ]; then vecho "-k sera ignoré dans cette forme" fMARK='n' fi else vecho "Forme 4 : copie/déplacement de la Freebox filtré par liste" fi if [ ! -d "${DEST}" ]; then abort 1 "Erreur, le chemin spécifié n'est pas un répertoire : '${DEST}'" fi else if [ -n "${DEST}" ]; then usage "Argument en trop : '${DEST}'." fi if [ -z "${LINKS}" ]; then usage "Pas de lien ni de fichier spécifié." fi fi fi # -------------------------------------------------------------------------------------- # Récupération des liens selon la forme utilisée | # 1ère forme: un lien unique de type http://dl.free.fr/123456789 | # 2ème forme: une page web contenant des liens de la forme ci-dessus | # 3ème forme: un fichier contenant des liens de la forme ci-dessus | # 4ème forme: idem aux 3 autres, mais facultatif | # -------------------------------------------------------------------------------------- if [ -z ${TMPLOG} ]; then TMPLOG=$( mktemp ); fi touch "${TMPLOG}.f" if [ -n "${LINKS}" ]; then SVG_LINKS="${LINKS}" if printf '%s' "${LINKS}" | egrep "^http://|^https://|^ftp://" >/dev/null; then if printf '%s' "${LINKS}" | grep "^${PATTERN}" >/dev/null; then if [ ${#LINKS} -eq 27 ]; then LIST="${LINKS}" vecho "Forme 1 : lien unique dl.free.fr complet." checkform else usage "Lien unique incorrect : '${LINKS}'" fi else vecho "Forme 2 : lien vers une page web." HTTP_CODE=$( curl "${LINKS}" -s -o "${TMPLOG}.f" -w '%{http_code}' ) if [ "${HTTP_CODE}" = "200" ]; then vecho "Récupération de la page web réussie" LINKS="${TMPLOG}.f" checkform else abort "** Erreur récupération de la page contenant des liens : '${LINKS}'" fi fi fi if [ -z "${LIST}" ]; then if [ -f "${LINKS}" ]; then if [ "${LINKS}" = "${SVG_LINKS}" ]; then vecho "Forme 3 : fichier contenant des liens" fi vecho "Extraction des liens dl.free.fr" ENCODE=$( file "${LINKS}" --mime-encoding | sed 's/.*: //' ) if [ "${ENCODE}" = 'binary' ]; then abort 1 "** Erreur, le fichier fourni est un fichier binaire : '${SVG_LINKS}'" fi LIST=$( sed "s|\(#\?[ |\t]*\)\?\(${PATTERN}.........\)|\2\1 \n|g" "${LINKS}" \ | { LANG="en_GB.${ENCODE}" && \ sed -n "s|.*\(${PATTERN}..........\)|\1|p" ; \ } | uniq -w 27 | sed '/#/d;s/ //' ) else if [ ${#LINKS} -gt 27 -o ${#LINKS} -lt 9 ]; then abort 1 "Erreur, fichier inexistant ou lien unique incorrect : '${LINKS}'" fi LIST="$( printf '%s' ${PATTERN} | cut -c -$(( 27 - ${#LINKS})) )${LINKS}" if printf '%s' "${LIST}" | grep -v "^${PATTERN}" >/dev/null; then abort 1 "Erreur, fichier inexistant ou lien unique incorrect : '${LINKS}'" else vecho "Forme 1 : lien unique dl.free.fr partiel." checkform fi fi fi if [ -z "${LIST}" ]; then abort 0 "Arrêt, aucun fichier dl.free.fr trouvé dans '${SVG_LINKS}'" fi vecho "Détermination de la forme d'usage réussie" fi # -------------------------------------------------------------------------------------- # Récupération du mot de passe de la Freebox (fichier config ou clavier) | # -------------------------------------------------------------------------------------- if [ "${fCPY}" = 'y' -o "${fMOVE}" = 'y' -o "${fFBX}" = 'y' -o "${fREN}" = 'y' ]; then vecho "Initialisation de la communication avec la Freebox" if [ -f "${FBX_CONFIG_FILE}" ]; then vecho "Fichier mot de passe trouvé" . "${FBX_CONFIG_FILE}" fi if [ -z "${PASSWORD}" ]; then stty_orig=`stty -g` stty -echo read -p "Mot de passe de votre FreeBox: " PASSWORD stty $stty_orig echo fi HTTP_CODE=$( curl "http://${FBX_IP_PORT}/login.php"\ -c "${TMPLOG}.f"\ -d "login=freebox&passwd=$PASSWORD"\ -o /dev/null\ -w "%{http_code}"\ -s ) # Quand le mot de passe est correct, on a 302, mais on veut juste le cookie # donc on ne met pas d'option -L pour récupérer la page après login # Sinon, un mot de passe incorrect rend une page qui l'indique + un HTTP_CODE à 200 if [ "${HTTP_CODE}" -ne 302 ]; then abort 1 "** Mot de passe incorrect." fi vecho "Initialisation communication Freebox réussie" fi # -------------------------------------------------------------------------------------- # 4ème forme, on veut récupérer des fichiers présents sur la Freebox | # -1) Lecture du répertoire où sont téléchargés les fichiers | # -2) Lecture de la liste des fichiers téléchargés depuis dl.free.fr | # -------------------------------------------------------------------------------------- if [ "${fCPY}" = 'y' -o "${fMOVE}" = 'y' -o "${fREN}" = 'y' ]; then vecho "Initialisations pour la Forme 4" vecho "Récupération de répertoire de téléchargement" HTTP_CODE=$(curl "http://${FBX_IP_PORT}/download.cgi"\ -o "${TMPLOG}" \ -b "${TMPLOG}.f" \ --data "${JSONRPC}\"download.config_get\"}" \ -H 'Content-Type: application/json; charset=utf-8' \ -w '%{http_code}'\ -s ) jsoncatch DL_DIR=$( sed 's/.*,"download_dir":"//;s/","max_dl":.*//;s|\\/|/|g' "${TMPLOG}" ) vecho "Récupération de la liste des fichiers dans ce répertoire" HTTP_CODE=$(curl "http://${FBX_IP_PORT}/fs.cgi"\ -o "${TMPLOG}" \ -b "${TMPLOG}.f" \ --data "${JSONRPC}\"fs.list\",\"id\":0.$(od -An -N8 -t fD /dev/urandom| sed 's/.*,//;s/e.*//'),\"params\":[\"${DL_DIR}\",{\"with_attr\":true}]}" \ -H 'Content-Type: application/json; charset=utf-8' \ -w '%{http_code}'\ -s ) jsoncatch DL_DIR_LIST=$( sed -e 's|.*"jsonrpc":"2.0","result":\[\?||;s|\]\?}$||' -e 's/},/}\n/g' "${TMPLOG}" ) vecho "Récupération de la liste des téléchargements" HTTP_CODE=$(curl "http://${FBX_IP_PORT}/download.cgi"\ -o "${TMPLOG}" \ -b "${TMPLOG}.f" \ --data "${JSONRPC}\"download.list\"}" \ -H 'Content-Type: application/json; charset=utf-8' \ -w '%{http_code}'\ -s ) jsoncatch FBX_LIST=$( sed -e 's/^{"jsonrpc":"2.0","result":\[\?//;s/\]\?}$//' -e 's/},/}\n/g'\ <"${TMPLOG}" | sed -n '/"url":"http:\\\/\\\/dl.free.fr\\\//p') if [ -z "${FBX_LIST}" ]; then abort 0 "Pas de fichiers à traiter sur la Freebox." fi if [ -z "${LIST}" ]; then LIST=$( printf '%s' "${FBX_LIST}" | sed 's/.*,"url":"//;s/","rx_rate.*//;s|\\/|/|g') fi fi if [ "${fCHECK}" = 'y' ]; then vecho "Mode vérification d'existence seulement (pas de téléchargement)" if [ "${fCPY}" = 'y' ]; then vecho "Fichiers seulement vérifiés sur la Freebox" fi if [ "${fMOVE}" = 'y' -o "${fREN}" = 'y' ]; then vecho "Fichiers vérifiés et éventuellement réparés sur la Freebox" fi else if [ "${fFORCE}" = 'y' ]; then if [ "${fCPY}" = 'y' -o "${fMOVE}" = 'y' ]; then vecho "Copie/déplacement avec écrasement si les fichiers existent déjà" else if [ "${fFBX}" = 'y' ]; then vecho "-f est ignoré lorsque -b est spécifié" fFORCE='n' else vecho "Téléchargement avec reprise si les fichiers existent déjà" fi fi fi fi # -------------------------------------------------------------------------------------- # Boucle principale de téléchargement des fichiers | # -------------------------------------------------------------------------------------- for IDENT in ${LIST} do printf "\n\n─────────────────────────────────────\nFichier : %s\n" ${IDENT} BASE_IDENT=$( basename "${IDENT}" ) if grep -qs "# ${IDENT}" "${LINKS}"; then echo "Déjà téléchargé en parallèle." continue fi # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Vérifie l'existence du fichier et trouve le nom de la destination | while : do HTTP_CODE=$( curl "${IDENT}" -s -L --cookie-jar "${TMPLOG}.c" -D "${TMPLOG}.h"\ --header 'Range: bytes=-0' -o "${TMPLOG}" -w "%{http_code}" ) case ${HTTP_CODE} in 404) abort 1 "*!* Ficher inexistant : ${IDENT}"\ "Téléchargement impossible." ;; 200) echo "\n** Ce script ne fonctionne ainsi que si vous êtes chez Free !\n" exit ;; 416) NAME=$( tr -d '\r' <"${TMPLOG}.h" |\ sed -n '/Content-disposition/s/.*filename=//p;s/^M//g' ) if [ -z "${NAME}" ]; then NAME="${BASE_IDENT}"; fi break ;; *) echo "\n** Erreur serveur (${HTTP_CODE}) : attente ${SLEEP}s\n" sleep ${SLEEP} 2>/dev/null || sleep 30 ;; esac done # # Dans le header, il n'y a rien qui indique l'encoding du nom de fichier. | # On teste donc si le nom est valide en utf-8, et sinon on suppose que c'est de | # l'iso-8859-1 # if [ $( printf '%s' "${NAME}" | iconv -f utf-8 -t utf-8 -c -s ) != "${NAME}" ]; then NAME=$( printf '%s' "${NAME}" | iconv -f iso-8859-1 -t utf-8 -s ) fi if [ "${NAME}" = "${BASE_IDENT}" ]; then echo "Fichier déjà en cours de téléchargement" else printf "Cible : "; yellow; printf '%s\n' "${NAME}"; normal fi # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Filtrage si l'option --filtre a été spécifiée (et la chaine non nulle !) | if [ -n "${FILTRE}" ]; then if printf '%s' "${NAME}" | grep -vE "${FILTRE}"; then printf "Fichier non traité (filtrage par option --filtre)" continue fi fi # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Vérification d'existence si on n'a pas mis l'option --force | if [ "${fFORCE}" = 'n' -a "${fCHECK}" = 'n' ]; then if [ "${fCPY}" = 'y' -o "${fMOVE}" = 'y' ]; then TARGET="${DEST}/${NAME}" else TARGET="${NAME}" fi if [ "${fFBX}" = 'n' -o "${fCPY}" = 'y' -o "${fMOVE}" = 'y' ]; then if [ -f "${TARGET}" ]; then abort 1 "*!* Fichier cible existe déjà : ${TARGET}" \ "Vous pouvez :" \ "- Supprimer le fichier au préalable ou" \ "- Utiliser l'option -f pour forcer la réécriture/reprise." fi fi fi # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Télécharge le fichier si pas en mode vérification | while [ "${fCHECK}" = 'n' -a "${fCPY}" = 'n' -a "${fMOVE}" = 'n' -a \ "${fREN}" = 'n' -a "${NAME}" != "${BASE_IDENT}" ] do if [ "${fFBX}" = 'y' ]; then freebox_start_dl else HTTP_CODE=$( curl "$IDENT" -C - -o "$NAME" -w "%{http_code}" ) fi case ${HTTP_CODE} in 200 |\ 206 |\ 416) # Marque le lien comme OK if [ "${fFBX}" = 'y' ]; then printf "Téléchargement soumis à la Freebox avec succès\n" else printf "Téléchargement terminé avec succès\n" fi marklink break ;; *) echo "** Erreur serveur (${HTTP_CODE}) : attente ${SLEEP}\n" sleep $SLEEP 2>/dev/null ;; esac done fFILE_OK='y' if [ "${fCPY}" = 'y' -o "${fMOVE}" = 'y' -o "${fREN}" = 'y' ]; then THIS=$( printf '%s' "${FBX_LIST}" | sed -n "/${BASE_IDENT}\",\"rx_rate/p" ) if [ -z "${THIS}" ]; then abort 1 "Fichier absent sur la freebox ou a déjà été supprimé : '${IDENT}'" fi if ! echo "${DL_DIR_LIST}" |\ grep "\"type\":\"file\",\"name\":\"${BASE_IDENT}\"" >/dev/null; then L1="Fichier '${BASE_IDENT}' présent dans la liste mais pas dans le répertoire" fFILE_OK='n' fi FBX_FILE="${DL_DIR}/${BASE_IDENT}" status=$( printf '%s' "${THIS}" | sed 's/.*"status":"//;s/","url":.*//' ) case ${status} in 'done' ) if [ ${fCHECK} = 'n' ]; then if [ "${fFILE_OK}" = 'n' ]; then abort 1 "${L1}" fi if [ "${fREN}" = 'y' ]; then HTTP_CODE=$(curl "http://${FBX_IP_PORT}/fs.cgi"\ -o "${TMPLOG}" \ -b "${TMPLOG}.f" \ --data "${JSONRPC}\"fs.move\",\"params\":[\"${FBX_FILE}\",\"${DL_DIR}/${NAME}\"]}" \ -H 'Content-Type: application/json; charset=utf-8' \ -w '%{http_code}'\ -s ) jsoncatch printf "Fichier renommé sur la Freebox avec succès\n" marklink else HTTP_CODE=$( curl "http://${FBX_IP_PORT}/get.php" \ -o "${DEST}/${NAME}" \ -w "%{http_code}" \ -b "${TMPLOG}.f"\ -d "filename=${FBX_FILE}" ) if [ "${HTTP_CODE}" -eq 200 ]; then printf "Copie du fichier depuis la Freebox terminée avec succès\n" marklink else abort 1 "Erreur téléchargement depuis la Freebox de '${FBX_FILE}'" fi fi else if [ "${fFILE_OK}" = 'n' ]; then red; echo "${L1}"; normal fi fi ;; 'running') size=$( printf '%s' "${THIS}" | sed 's/.*,"size"://;s/}//' ) trnf=$( printf '%s' "${THIS}" | sed 's/.*,"transferred"://;s/,"name":.*//' ) if [ ${trnf} -eq 0 ]; then pourcent=0 else pourcent=$(( ${trnf} * 100 / ${size} )) fi cyan; printf "Téléchargement en cours : %2u%%\n" ${pourcent}; normal ;; *) errmsg=$(printf '%s' "${THIS}"|sed 's/.*"errmsg":"//;s/","status":.*//') red printf "Etat inattendu ou erreur :\n" printf " status=%s\n" "${status}"; printf " errmsg=%s\n" "${errmsg}"; normal esac if [ \( "${fMOVE}" = 'y' -o "${fREN}" = 'y' \) -a "${status}" != 'running' ]; then if [ "${status}" = 'done' -a \( ${fCHECK} = 'n' -o "${fFILE_OK}" = 'n' \) -o \ "${status}" != 'done' -a ${fCHECK} = 'y' ]; then # Suppression dans la liste des téléchargements ID=$( printf '%s' "${THIS}" | sed 's/.*,"id"://;s/,"transferred":.*//' ) HTTP_CODE=$(curl "http://${FBX_IP_PORT}/download.cgi"\ -o "${TMPLOG}" \ -b "${TMPLOG}.f" \ --data "${JSONRPC}\"download.remove\",\"params\":[\"http\",${ID}]}" \ -H 'Content-Type: application/json; charset=utf-8' \ -w '%{http_code}'\ -s ) jsoncatch if [ "${fMOVE}" = 'y' ]; then # Suppression des fichiers if echo "${DL_DIR_LIST}" |\ grep "\"type\":\"file\",\"name\":\"${BASE_IDENT}\"" >/dev/null; then HTTP_CODE=$(curl "http://${FBX_IP_PORT}/fs.cgi"\ -o "${TMPLOG}" \ -b "${TMPLOG}.f" \ --data "${JSONRPC}\"fs.remove\",\"params\":[[\"${FBX_FILE}\"]]}" \ -H 'Content-Type: application/json; charset=utf-8' \ -w '%{http_code}'\ -s ) jsoncatch fi printf "Suppression du fichier sur la Freebox réussie\n" else printf "Suppression du fichier de la liste des téléchargements réussie\n" fi fi if [ "${status}" != 'done' -a ${fCHECK} = 'y' ]; then freebox_start_dl printf "Réparation OK : téléchargement re-soumis à la Freebox\n" fi fi fi if [ "${fCHECK}" = 'y' -a "${fFILE_OK}" = 'y' ]; then printf "Vérification OK" fi # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ done # -------------------------------------------------------------------------------------- # Fin correcte du traitement | # -------------------------------------------------------------------------------------- echo "\n\n\n╔═══════════════════════════════════════════╗" echo "║ Les traitements sont terminés avec succès ║" echo "╚═══════════════════════════════════════════╝" clean