################################################### # Convert bytes to human readable form # Required Arguments: 1 # ${1} = Positive integer ( bytes ) # Result: Print human readable form. # Reference: # https://unix.stackexchange.com/a/259254 ################################################### _bytes_to_human() { b_bytes_to_human="$(printf "%.0f\n" "${1:-0}")" s_bytes_to_human=0 d_bytes_to_human='' type_bytes_to_human='' while [ "${b_bytes_to_human}" -gt 1024 ]; do d_bytes_to_human="$(printf ".%02d" $((b_bytes_to_human % 1024 * 100 / 1024)))" b_bytes_to_human=$((b_bytes_to_human / 1024)) && s_bytes_to_human=$((s_bytes_to_human += 1)) done j=0 && for i in B KB MB GB TB PB EB YB ZB; do j="$((j += 1))" && [ "$((j - 1))" = "${s_bytes_to_human}" ] && type_bytes_to_human="${i}" && break continue done printf "%s\n" "${b_bytes_to_human}${d_bytes_to_human} ${type_bytes_to_human}" } ################################################### # Convert given time in seconds to readable form # 110 to 1 minute(s) and 50 seconds # Arguments: 1 # ${1} = Positive Integer ( time in seconds ) # Result: read description # Reference: # https://stackoverflow.com/a/32164707 ################################################### _display_time() { t_display_time="${1}" day_display_time="$((t_display_time / 60 / 60 / 24))" hr_display_time="$((t_display_time / 60 / 60 % 24))" min_display_time="$((t_display_time / 60 % 60))" sec_display_time="$((t_display_time % 60))" [ "${day_display_time}" -gt 0 ] && printf '%d days ' "${day_display_time}" [ "${hr_display_time}" -gt 0 ] && printf '%d hrs ' "${hr_display_time}" [ "${min_display_time}" -gt 0 ] && printf '%d minute(s) ' "${min_display_time}" [ "${day_display_time}" -gt 0 ] || [ "${hr_display_time}" -gt 0 ] || [ "${min_display_time}" -gt 0 ] && printf 'and ' printf '%d seconds\n' "${sec_display_time}" } ################################################### # Fetch latest commit sha of release or branch # Do not use github rest api because rate limit error occurs # Arguments: 3 # ${1} = "branch" or "release" # ${2} = branch name or release name # ${3} = repo name e.g Akianonymus/gdrive-downloader # Result: print fetched sha ################################################### _get_latest_sha() { unset latest_sha_get_latest_sha raw_get_latest_sha case "${1:-${TYPE}}" in branch) latest_sha_get_latest_sha="$( raw_get_latest_sha="$(curl --compressed -s https://github.com/"${3:-${REPO}}"/commits/"${2:-${TYPE_VALUE}}".atom -r 0-2000)" _tmp="$(printf "%s\n" "${raw_get_latest_sha}" | grep -o "Commit\\/.*<" -m1 || :)" && _tmp="${_tmp##*\/}" && printf "%s\n" "${_tmp%%<*}" )" ;; release) latest_sha_get_latest_sha="$( raw_get_latest_sha="$(curl -L --compressed -s https://github.com/"${3:-${REPO}}"/releases/"${2:-${TYPE_VALUE}}")" _tmp="$(printf "%s\n" "${raw_get_latest_sha}" | grep "=\"/""${3:-${REPO}}""/commit" -m1 || :)" && _tmp="${_tmp##*commit\/}" && printf "%s\n" "${_tmp%%\"*}" )" ;; *) : ;; esac printf "%b" "${latest_sha_get_latest_sha:+${latest_sha_get_latest_sha}\n}" } ################################################### # Method to extract specified field data from json # Arguments: 2 # ${1} - value of field to fetch from json # ${2} - Optional, no of lines to parse for the given field in 1st arg # ${3} - Optional, nth number of value from extracted values, default it 1. # Input: file | pipe # _json_value "Arguments" < file # echo something | _json_value "Arguments" # Result: print extracted value ################################################### _json_value() { { [ "${2}" -gt 0 ] 2>| /dev/null && no_of_lines_json_value="${2}"; } || : { [ "${3}" -gt 0 ] 2>| /dev/null && num_json_value="${3}"; } || { ! [ "${3}" = all ] && num_json_value=1; } # shellcheck disable=SC2086 _tmp="$(grep -o "\"${1}\"\:.*" ${no_of_lines_json_value:+-m} ${no_of_lines_json_value})" || return 1 printf "%s\n" "${_tmp}" | sed -e "s/.*\"""${1}""\"://" -e 's/[",]*$//' -e 's/["]*$//' -e 's/[,]*$//' -e "s/^ //" -e 's/^"//' -n -e "${num_json_value}"p || : return 0 } ################################################### # Move cursor to nth no. of line ( above ) # Arguments: 1 # ${1} = Positive integer ( line number ) # Result: Read description ################################################### _move_cursor() { printf "\033[%sA" "${1:?Error: Num of line}" } ################################################### # Print a text to center interactively and fill the rest of the line with text specified. # This function is fine-tuned to this script functionality, so may appear unusual. # Arguments: 4 # If ${1} = normal # ${2} = text to print # ${3} = symbol # If ${1} = justify # If remaining arguments = 2 # ${2} = text to print # ${3} = symbol # If remaining arguments = 3 # ${2}, ${3} = text to print # ${4} = symbol # Result: read description # Reference: # https://gist.github.com/TrinityCoder/911059c83e5f7a351b785921cf7ecda ################################################### _print_center() { [ $# -lt 3 ] && printf "Missing arguments\n" && return 1 term_cols_print_center="${COLUMNS:?}" type_print_center="${1}" filler_print_center="" case "${type_print_center}" in normal) out_print_center="${2}" && symbol_print_center="${3}" ;; justify) if [ $# = 3 ]; then input1_print_center="${2}" symbol_print_center="${3}" to_print_print_center="" out_print_center="" to_print_print_center="$((term_cols_print_center - 5))" { [ "${#input1_print_center}" -gt "${to_print_print_center}" ] && out_print_center="[ $(printf "%.${to_print_print_center}s\n" "${input1_print_center}")..]"; } || { out_print_center="[ ${input1_print_center} ]"; } else input1_print_center="${2}" input2_print_center="${3}" symbol_print_center="${4}" to_print_print_center="" temp_print_center="" out_print_center="" to_print_print_center="$((term_cols_print_center * 47 / 100))" { [ "${#input1_print_center}" -gt "${to_print_print_center}" ] && temp_print_center=" $(printf "%.${to_print_print_center}s\n" "${input1_print_center}").."; } || { temp_print_center=" ${input1_print_center}"; } to_print_print_center="$((term_cols_print_center * 46 / 100))" { [ "${#input2_print_center}" -gt "${to_print_print_center}" ] && temp_print_center="${temp_print_center}$(printf "%.${to_print_print_center}s\n" "${input2_print_center}").. "; } || { temp_print_center="${temp_print_center}${input2_print_center} "; } out_print_center="[${temp_print_center}]" fi ;; *) return 1 ;; esac str_len_print_center="${#out_print_center}" [ "${str_len_print_center}" -ge "$((term_cols_print_center - 1))" ] && { printf "%s\n" "${out_print_center}" && return 0 } filler_print_center_len="$(((term_cols_print_center - str_len_print_center) / 2))" i_print_center=1 && while [ "${i_print_center}" -le "${filler_print_center_len}" ]; do filler_print_center="${filler_print_center}${symbol_print_center}" && i_print_center="$((i_print_center + 1))" done printf "%s%s%s" "${filler_print_center}" "${out_print_center}" "${filler_print_center}" [ "$(((term_cols_print_center - str_len_print_center) % 2))" -ne 0 ] && printf "%s" "${symbol_print_center}" printf "\n" return 0 } ################################################### # Check if script terminal supports ansi escapes # Result: return 1 or 0 ################################################### _support_ansi_escapes() { unset ansi_escapes case "${TERM:-}" in xterm* | rxvt* | urxvt* | linux* | vt* | screen*) ansi_escapes="true" ;; *) : ;; esac { [ -t 2 ] && [ -n "${ansi_escapes}" ] && return 0; } || return 1 } ################################################### # Alternative to timeout command # Arguments: 1 and rest # ${1} = amount of time to sleep # rest = command to execute # Result: Read description # Reference: # https://stackoverflow.com/a/24416732 ################################################### _timeout() { timeout_timeout="${1:?Error: Specify Timeout}" && shift { "${@}" & child="${!}" trap -- "" TERM { sleep "${timeout_timeout}" kill -9 "${child}" } & wait "${child}" } 2>| /dev/null 1>&2 }n