Konubinix' opinionated web of thoughts

Batch Downloader in Termux in Android

Fleeting

batch downloader in termux

android kivy application to multiple downloads using the storage access framework

clk android adb install com.termux com.termux.api

Open the termux api to enable the needed authorizations

pkg install termux-api
set -o errexit # -e
set -o errtrace # -E
set -o nounset # -u
set -o pipefail
shopt -s inherit_errexit

TMP="$(mktemp -d)"
trap "rm -rf '${TMP}'" 0

clk_popline ( ) {
    local file="$1"
    local variable="$2"
    if ! [ -s "${file}" ]
    then
        return 1
    fi
    local thehead="$(head -1 "${file}")"
    (
        # use a subshell to deal with a temp file
        TMPDIR="$(mktemp -d)"
        trap "rm -rf '${TMPDIR}'" 0
        tail +2 "${file}" > "${TMPDIR}/temp"
        mv "${TMPDIR}/temp" "${file}"
    )
    read "$2" < <(echo "${thehead}")
}

lock="${HOME}/multidownloader.lock"
indexfile="${TMP}/index.txt"
tempdldir="${TMP}/dl"

multidownloaderstate="${HOME}/multidownloader"
indexfilehash="${multidownloaderstate}/indexfilehash"
success="${multidownloaderstate}/success"
errors="${multidownloaderstate}/errors"

dest="${HOME}/storage/downloads"

log () {
    local msg="$1"
    echo "$(date): ${msg}"
    termux-notification --title 'Download status' --content "${msg}" --id downloader
}


(
    clean () {
        rm -f "${lock}"
        termux-wake-unlock
    }
    cleanerror () {
        clean
        log "Something went wrong, try running me again"
    }

    if test -e "${lock}"
    then
        log "Already an ongoing process"
        exit
    else
        touch "${lock}"
    fi

    trap "cleanerror" "0"
    termux-wake-lock

    curl --fail --silent --show-error --location "${index}" > "${indexfile}"

    hash="$(sha256sum < "${indexfile}")"
    if ! test -e "${indexfilehash}" || test "${hash}" != "$(cat "${indexfilehash}")"
    then
        rm -rf "${multidownloaderstate}"
        mkdir -p "${multidownloaderstate}"
        echo "${hash}" > "${indexfilehash}"
        touch "${success}"
        touch "${errors}"
    fi

    total="$(cat "${indexfile}"|wc -l)"
    i=0

    log "starting"

    dlit () {
        curl --fail --silent --show-error --location --remote-header-name --remote-name "${url}" --output-dir "${tempdldir}"
        filenames=($(ls "${tempdldir}/"))
        mv "${tempdldir}/"* "${dest}/"
        for filename in "${filenames[@]}"
        do
            termux-media-scan "${dest}/${filename}"
        done
    }

    mkdir -p "${tempdldir}"
    while clk_popline "${indexfile}" url
    do
        if ! grep -q "${url}" "${success}"
        then
            if dlit "${url}"
            then
                echo "${url}" >> "${success}"
            else
                echo "${url}" >> "${errors}"
            fi
        fi
        i=$((i+1))
        log "${i}/${total}"
    done

    log "done"
    trap "clean" "0"
)