#!/bin/bash # shellcheck source=/dev/null # Constants HYPERTERM_DIR="${HYPERTERM_DIR:-$HOME/.hyperterm}" URL_1="${URL_1:-https://git.fridu.us/heckyel/hyperterm}" URL_2="${URL_2:-https://c.fridu.us/software/hyperterm.git}" REPO_ERROR_MSG_ES="${REPO_ERROR_MSG_ES:-El repositorio no está disponible o no hay conexión a Internet.}" REPO_ERROR_MSG_EN="${REPO_ERROR_MSG_EN:-The repository is unavailable or there\'s no internet connection.}" #---------------------------- # Check if a command exists #---------------------------- function _which() { command -v "$1" &> /dev/null } #---------------------------- # Check if a URL is reachable #---------------------------- function _url_exists() { curl --output /dev/null --silent --head --write-out "%{http_code}" "$1" } #------------------ # Get working URLs #------------------ function _get_repo_urls() { if [ "$(_url_exists "$URL_1")" -eq 200 ]; then echo "$URL_1|$URL_1/raw/branch/master" elif [ "$(_url_exists "$URL_2")" -eq 200 ]; then echo "$URL_2|$URL_2/plain" else msg_err "$REPO_ERROR_MSG_ES" "$REPO_ERROR_MSG_EN" return 1 fi } #---------------------------- # Download file with curl #---------------------------- function download_file() { local remote_path=$1 local local_path=$2 local repo_info local raw_url repo_info=$(_get_repo_urls) || return 1 raw_url="${repo_info#*|}" install -d "$(dirname "$local_path")" curl -Ls "$raw_url/$remote_path" -o "$local_path" } #-------------------------------- # Download _custom.sh if missing #-------------------------------- function ifexists_custom() { local custom_path="$HYPERTERM_DIR/_custom.sh" if [ ! -e "$custom_path" ]; then download_file "hyperterm/_custom.sh" "$custom_path" fi } #------------------- # Show progress bar #------------------- function show_progress() { local current=$1 local total=$2 local message=${3:-"Procesando"} if [[ $total -eq 0 ]]; then printf '\r%s... ' "$message" return fi local percentage=$((current * 100 / total)) local filled=$((percentage / 5)) # 20 chars max local empty=$((20 - filled)) # Truncate long filenames for better display local display_message="$message" if [[ ${#message} -gt 30 ]]; then display_message="...${message: -27}" fi # Clear the line first, then show progress printf '\r\033[K[%*s%*s] %d%% (%d/%d) %s' \ "$filled" "$(printf '#%.0s' $(seq 1 $filled))" \ "$empty" "" \ "$percentage" "$current" "$total" "$display_message" [[ $current -eq $total ]] && printf '\n' } #------------------------------ # Update HyperTerm environment #------------------------------ function updbashrc() { local repo_info repo_info=$(_get_repo_urls) || return 1 # Step 1: Download checksum and _custom.sh download_file "hyperterm/hyperterm.sha512" "$HYPERTERM_DIR/hyperterm.sha512" ifexists_custom # Step 2: Verify checksum (cd "$HYPERTERM_DIR" && sha512sum -c hyperterm.sha512 &> /dev/null) local _integer=$? if [[ "$_integer" -eq 0 ]]; then _colors_bash "$@" printf '%b' "${BOLD}${CYAN}" printf '%s\n' ' __ __ ______ ' printf '%s\n' ' / / / /_ ______ ___ ____/_ __/__ _________ ___ ' printf '%s\n' ' / /_/ / / / / __ \/ _ \/ ___// / / _ \/ ___/ __ `__ \ ' printf '%s\n' ' / __ / /_/ / /_/ / __/ / / / / __/ / / / / / / / ' printf '%s\n' ' /_/ /_/\__, / .___/\___/_/ /_/ \___/_/ /_/ /_/ /_/ ' printf '%s\n' ' /____/_/ ' printf '%s\n' ' ' printf '%b' "${BOLD}${GREY}" msg "✔️ HyperTerm se ha actualizado y/o está en la versión actual." \ "✔️ HyperTerm has been updated and/or is at the current version." msg "Puede reportar errores en https://todo.sr.ht/~heckyel/hyperterm" \ "You can report issues at https://todo.sr.ht/~heckyel/hyperterm" msg "Obtén tu copia en: https://c.fridu.us/software/hyperterm.git" \ "Get your copy at: https://c.fridu.us/software/hyperterm.git" printf '%b\n' "$RESET" else msg "Verificando archivos modificados..." \ "Checking for modified files..." # Step 3: Check each file individually and download only if needed local files_to_update=() local current_file=0 # First pass: identify files that need updating while IFS= read -r line; do local expected_hash file_path expected_hash=$(echo "$line" | cut -d' ' -f1) file_path=$(echo "$line" | cut -d' ' -f2) file_path=${file_path#./} local full_path="$HYPERTERM_DIR/$file_path" # Check if file exists and has correct hash if [[ ! -f "$full_path" ]] || ! echo "$expected_hash ./$file_path" | (cd "$HYPERTERM_DIR" && sha512sum -c --quiet >/dev/null 2>&1); then files_to_update+=("$file_path") fi done < "$HYPERTERM_DIR/hyperterm.sha512" local total_updates=${#files_to_update[@]} if [[ $total_updates -eq 0 ]]; then msg "✔️ Todos los archivos están actualizados" \ "✔️ All files are up to date" else msg "Descargando $total_updates archivo(s) modificado(s)..." \ "Downloading $total_updates modified file(s)..." # Second pass: download only the files that need updating for file_path in "${files_to_update[@]}"; do ((current_file++)) if [[ "${LANG:-}" =~ ^es ]]; then show_progress "$current_file" "$total_updates" "Actualizando $file_path" else show_progress "$current_file" "$total_updates" "Updating $file_path" fi download_file "hyperterm/$file_path" "$HYPERTERM_DIR/$file_path" done fi _colors_bash "$@" source "$HOME/.bashrc" fi } #------------------------------------ # Overwrite _custom.sh interactively #------------------------------------ function updbashrc_custom() { _get_repo_urls > /dev/null || return 1 while true; do question=$(msg "¿Estás seguro de sobre-escribir _custom.sh? [s/N]: " \ "Are you sure to overwrite _custom.sh? [y/N]: ") read -r -p "$question" input case "$input" in [yY]|[sS]) download_file "hyperterm/_custom.sh" "$HYPERTERM_DIR/_custom.sh" source "$HOME/.bashrc" break ;; [nN]|"") break ;; *) msg "Por favor responde sí o no." \ "Please answer yes or no." ;; esac done }