diff --git a/install.sh b/install.sh index 14edc4c..fd4e5c8 100644 --- a/install.sh +++ b/install.sh @@ -1,412 +1,361 @@ -#!/bin/bash -# Couleurs de texte -NOIR='\e[30m' -ROUGE='\e[31m' -VERT='\e[32m' -JAUNE='\e[33m' -BLEU='\e[34m' -ROSE='\e[35m' -CYAN='\e[36m' -BLANC='\e[37m' +#!/usr/bin/env bash +set -Eeuo pipefail -# Couleurs de fond -FOND_NOIR='\e[40m' -FOND_ROUGE='\e[41m' -FOND_VERT='\e[42m' -FOND_JAUNE='\e[43m' -FOND_BLEU='\e[44m' -FOND_ROSE='\e[45m' -FOND_CYAN='\e[46m' -FOND_BLANC='\e[47m' - -# Effets -GRAS='\e[1m' -SOULIGNE='\e[4m' -CLIGNOTANT='\e[5m' -INVERSE='\e[7m' -NORMAL='\e[0m' - - -# Initialisation -sudook=false - -if sudo -n true 2>/dev/null; then - # On peut faire sudo sans mot de passe - sudook=true +# ========= Colors (safe if no TTY) ========= +if [ -t 1 ]; then + NOIR='\e[30m'; ROUGE='\e[31m'; VERT='\e[32m'; JAUNE='\e[33m'; BLEU='\e[34m'; ROSE='\e[35m'; CYAN='\e[36m'; BLANC='\e[37m' + GRAS='\e[1m'; SOULIGNE='\e[4m'; NORMAL='\e[0m' else - # Ni root ni sudo dispo - sudook=false + NOIR=''; ROUGE=''; VERT=''; JAUNE=''; BLEU=''; ROSE=''; CYAN=''; BLANC='' + GRAS=''; SOULIGNE=''; NORMAL='' fi -#Vérification des prérequis -echo -e "$BLEU""Vérification si les prérequis sont disponibles""$NORMAL" +# ========= Paths ========= BIN_DIR="$HOME/bin" AUTOPOST_DIR="$HOME/autopost" +BASHRC_FILE="$HOME/.bashrc" +BASH_COMPLETION_DIR="$HOME/.bash_completion.d" +TMP_DIR="$(mktemp -d)" +cleanup() { rm -rf "$TMP_DIR"; } +trap cleanup EXIT -# Vérifier si le dossier bin existe, sinon le créer -echo -e "$BLEU""Vérification de la présence du dossier bin""$NORMAL" -if [ ! -d "$BIN_DIR" ]; then - mkdir -p "$BIN_DIR" -fi +# ========= Helpers ========= +log() { printf "${BLEU}%s${NORMAL}\n" "$*"; } +ok() { printf "${VERT}%s${NORMAL}\n" "$*"; } +warn() { printf "${JAUNE}%s${NORMAL}\n" "$*"; } +err() { printf "${ROUGE}%s${NORMAL}\n" "$*"; } +die() { err "$*"; exit 1; } -LISTE_APPLIS=() -LISTE_APPLIS+=("curl basename php screen") +is_root() { [ "${EUID:-$(id -u)}" -eq 0 ]; } +has_cmd() { command -v "$1" >/dev/null 2>&1; } -# Vérifier et installer mediainfo si manquant -if command -v mediainfo > /dev/null 2>&1; then - LISTE_APPLIS+=("mediainfo") -else - echo -e "${ROUGE}mediainfo est manquant. Installation en cours...${NORMAL}" - if $sudook; then - sudo apt install libmms0 - # URLs dans l’ordre souhaité - urls=( - "https://mediaarea.net/download/binary/libzen0/0.4.41/libzen0v5_0.4.41-1_amd64.Debian_12.deb" - "https://mediaarea.net/download/binary/libmediainfo0/25.04/libmediainfo0v5_25.04-1_amd64.Debian_12.deb" - "https://mediaarea.net/download/binary/mediainfo/25.04/mediainfo_25.04-1_amd64.Debian_12.deb" - ) - - # Télécharger - for url in "${urls[@]}"; do - wget -q "$url" - done - - # Extraire les noms de fichiers, dans le même ordre - files=("${urls[@]##*/}") - - # Installer dans l’ordre défini - for pkg in "${files[@]}"; do - sudo dpkg -i "$pkg" - done - - # Nettoyer - rm -f "${files[@]}" - LISTE_APPLIS+=("mediainfo") - echo -e "${VERT}mediainfo installé${NORMAL}" +# sudo wrapper: use sudo if available and needed +run_root() { + if is_root; then + "$@" + elif has_cmd sudo; then + sudo "$@" else - echo -e "${ROUGE}mediainfo est manquant. Installation en cours...${NORMAL}" - curl -L -o "$BIN_DIR/mediainfo" "https://mediaarea.net/download/binary/mediainfo/20.09/mediainfo-20.09.glibc2.3-x86_64.AppImage" - chmod 777 "$BIN_DIR/mediainfo" - LISTE_APPLIS+=("$BIN_DIR/mediainfo") - echo -e "${VERT}mediainfo installé dans $BIN_DIR${NORMAL}" + die "Cette action nécessite les privilèges root (sudo non disponible)." + fi +} + +ensure_dir() { mkdir -p "$1"; } + +# safer install than chmod 777 +install_bin() { # install_bin + install -m 755 "$1" "$2" +} + +# ========= Start ========= +log "Initialisation des dossiers" +ensure_dir "$BIN_DIR" +ensure_dir "$AUTOPOST_DIR" +ensure_dir "$BASH_COMPLETION_DIR" + +# Ensure PATH contains $HOME/bin for this session & future shells +if ! printf '%s' "$PATH" | grep -q "$HOME/bin"; then + export PATH="$HOME/bin:$PATH" + if ! grep -q 'export PATH="$HOME/bin:$PATH"' "$BASHRC_FILE" 2>/dev/null; then + echo 'export PATH="$HOME/bin:$PATH"' >> "$BASHRC_FILE" + ok "Ajout de \$HOME/bin au PATH dans $BASHRC_FILE" fi fi -# Demande à l'utilisateur +# ========= Pre-reqs used by the script itself ========= +log "Vérification des prérequis (wget, curl, tar, xz, unzip, jq éventuellement)…" +MISSING=() +for c in wget curl tar xz; do + has_cmd "$c" || MISSING+=("$c") +done +# unzip est requis plus bas +has_cmd unzip || MISSING+=("unzip") +if [ "${#MISSING[@]}" -gt 0 ]; then + warn "Installation des prérequis manquants: ${MISSING[*]}" + if has_cmd apt-get; then + run_root apt-get update -y + run_root apt-get install -y "${MISSING[@]}" + else + die "Gestionnaire de paquets non géré (apt-get). Installe manuellement: ${MISSING[*]}" + fi +fi + +# ========= Packages list check (array usage) ========= +REQUIRED_CMDS=(curl basename php screen) + +# ========= mediainfo ========= +if has_cmd mediainfo; then + ok "mediainfo déjà présent" +else + warn "mediainfo manquant → tentative via apt (puis fallback)" + if has_cmd apt-get; then + if run_root apt-get install -y mediainfo; then + ok "mediainfo installé par apt" + else + warn "apt mediainfo indisponible, tentative via .deb officiels" + DEBS=( + "https://mediaarea.net/download/binary/libzen0/0.4.41/libzen0v5_0.4.41-1_amd64.Debian_12.deb" + "https://mediaarea.net/download/binary/libmediainfo0/25.04/libmediainfo0v5_25.04-1_amd64.Debian_12.deb" + "https://mediaarea.net/download/binary/mediainfo/25.04/mediainfo_25.04-1_amd64.Debian_12.deb" + ) + pushd "$TMP_DIR" >/dev/null + for u in "${DEBS[@]}"; do wget -q "$u"; done + run_root dpkg -i ./*.deb || run_root apt-get -f -y install + popd >/dev/null + fi + else + # AppImage fallback + APP="$BIN_DIR/mediainfo" + curl -fsSL -o "$APP" "https://mediaarea.net/download/binary/mediainfo/20.09/mediainfo-20.09.glibc2.3-x86_64.AppImage" + install -m 755 "$APP" "$APP" + ok "mediainfo AppImage installé dans $BIN_DIR" + fi +fi +REQUIRED_CMDS+=(mediainfo) + +# ========= Choix BDD (SQLite / MySQL) ========= echo "Quel système de base de données voulez-vous utiliser ?" select BDD in "SQLite" "MySQL"; do case $BDD in "SQLite") - echo "Vous avez choisi SQLite." - # Bloc vérification/install sqlite3 - if command -v sqlite3 > /dev/null 2>&1; then - LISTE_APPLIS+=("sqlite3") + log "SQLite sélectionné" + if has_cmd sqlite3; then + ok "sqlite3 déjà présent" else - echo -e "${ROUGE}sqlite3 est manquant. Installation en cours...${NORMAL}" - if $sudook; then - sudo apt install -y sqlite3 - LISTE_APPLIS+=("sqlite3") - echo -e "${VERT}sqlite3 installé${NORMAL}" + if has_cmd apt-get; then + run_root apt-get install -y sqlite3 else - curl -L -o sqlite-tools.zip "https://www.sqlite.org/2024/sqlite-tools-linux-x64-3470000.zip" - unzip sqlite-tools.zip -d "$BIN_DIR" - chmod 777 "$BIN_DIR/sqlite3" - # Nettoyage - rm -rf sqlite-tools.zip "$BIN_DIR/sqlite-tools-linux-x64-3480000" "$BIN_DIR/sqldiff" "$BIN_DIR/sqlite3_analyzer" "$BIN_DIR/sqlite3_rsync" - LISTE_APPLIS+=("$BIN_DIR/sqlite3") - echo -e "${VERT}sqlite3 installé dans $BIN_DIR${NORMAL}" + warn "apt absent → installation binaire sqlite3" + pushd "$TMP_DIR" >/dev/null + curl -fsSL -o sqlite-tools.zip "https://www.sqlite.org/2024/sqlite-tools-linux-x64-3470000.zip" + unzip -q sqlite-tools.zip + # trouve sqlite3 + SQLITE_BIN="$(find . -type f -name sqlite3 -perm -u+x | head -n1)" + [ -n "$SQLITE_BIN" ] || die "sqlite3 introuvable dans l’archive" + install_bin "$SQLITE_BIN" "$BIN_DIR/sqlite3" + popd >/dev/null + ok "sqlite3 installé dans $BIN_DIR" fi fi + REQUIRED_CMDS+=(sqlite3) break ;; "MySQL") - echo "Vous avez choisi MySQL." - if command -v mysql > /dev/null 2>&1; then - LISTE_APPLIS+=("mysql") - echo -e "${VERT}MySQL est disponible${NORMAL}" - # Place ici le code MySQL à exécuter + log "MySQL sélectionné" + if has_cmd mysql; then + ok "mysql client disponible" + REQUIRED_CMDS+=(mysql) else - echo -e "${ROUGE}MySQL n'est pas installé. Bascule automatique sur SQLite.${NORMAL}" - # Bloc vérification/install sqlite3 (copié plus haut) - if command -v sqlite3 > /dev/null 2>&1; then - LISTE_APPLIS+=("sqlite3") + warn "mysql client indisponible → bascule automatique sur SQLite" + if has_cmd apt-get; then + run_root apt-get install -y sqlite3 else - echo -e "${ROUGE}sqlite3 est manquant. Installation en cours...${NORMAL}" - if $sudook; then - sudo apt install -y sqlite3 - LISTE_APPLIS+=("sqlite3") - echo -e "${VERT}sqlite3 installé${NORMAL}" - else - curl -L -o sqlite-tools.zip "https://www.sqlite.org/2024/sqlite-tools-linux-x64-3470000.zip" - unzip sqlite-tools.zip -d "$BIN_DIR" - chmod 777 "$BIN_DIR/sqlite3" - rm -rf sqlite-tools.zip "$BIN_DIR/sqlite-tools-linux-x64-3480000" "$BIN_DIR/sqldiff" "$BIN_DIR/sqlite3_analyzer" "$BIN_DIR/sqlite3_rsync" - LISTE_APPLIS+=("$BIN_DIR/sqlite3") - echo -e "${VERT}sqlite3 installé dans $BIN_DIR${NORMAL}" - fi + pushd "$TMP_DIR" >/dev/null + curl -fsSL -o sqlite-tools.zip "https://www.sqlite.org/2024/sqlite-tools-linux-x64-3470000.zip" + unzip -q sqlite-tools.zip + SQLITE_BIN="$(find . -type f -name sqlite3 -perm -u+x | head -n1)" + [ -n "$SQLITE_BIN" ] || die "sqlite3 introuvable dans l’archive" + install_bin "$SQLITE_BIN" "$BIN_DIR/sqlite3" + popd >/dev/null fi + REQUIRED_CMDS+=(sqlite3) fi break ;; - *) - echo "Choix invalide." - ;; + *) echo "Choix invalide.";; esac done -# Vérifier et installer jq si manquant -if command -v jq > /dev/null 2>&1; then - LISTE_APPLIS+=("jq") +# ========= jq ========= +if has_cmd jq; then + ok "jq déjà présent" else - echo -e "${ROUGE}jq est manquant. Installation en cours...${NORMAL}" - curl -L -o "$BIN_DIR/jq" "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64" - chmod 777 "$BIN_DIR/jq" - LISTE_APPLIS+=("$BIN_DIR/jq") - echo -e "${VERT}jq installé dans $BIN_DIR${NORMAL}" + log "Installation de jq" + if has_cmd apt-get; then + run_root apt-get install -y jq + else + curl -fsSL -o "$TMP_DIR/jq" "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64" + install_bin "$TMP_DIR/jq" "$BIN_DIR/jq" + fi fi +REQUIRED_CMDS+=(jq) -# Vérifier et installer 7z si manquant -if command -v 7z > /dev/null 2>&1; then - LISTE_APPLIS+=("7z") +# ========= 7z ========= +if has_cmd 7z; then + ok "7z déjà présent" else - echo -e "${ROUGE}7z est manquant. Installation en cours...${NORMAL}" + log "Installation de 7z (binaire standalone)" + pushd "$TMP_DIR" >/dev/null Z_URL="https://7-zip.org/a/7z2409-linux-x64.tar.xz" - Z_TAR="7z2409-linux-x64.tar.xz" - Z_DIR="7z2409-linux-x64" - Z_EXE="7zzs" - wget -q -O "$Z_TAR" "$Z_URL" - tar -xJf "$Z_TAR" > /dev/null 2>&1 - mv "$Z_EXE" "$BIN_DIR/7z" - rm "$Z_TAR" 7zz - chmod 777 "$BIN_DIR/7z" - LISTE_APPLIS+=("$BIN_DIR/7z") + wget -q -O 7z.tar.xz "$Z_URL" + tar -xJf 7z.tar.xz + # Cherche 7zz* exécutable + Z_BIN="$(find . -maxdepth 1 -type f -name '7zz*' -perm -u+x | head -n1)" + [ -n "$Z_BIN" ] || die "binaire 7z introuvable" + install_bin "$Z_BIN" "$BIN_DIR/7z" + popd >/dev/null fi +REQUIRED_CMDS+=(7z) -#Téléchargement et installation de bdinfo -echo -e "$BLEU""Téléchargement et installation de BDInfo""$NORMAL" -curl -L -o bdinfo_linux_v2.0.6.zip "https://github.com/dotnetcorecorner/BDInfo/releases/download/linux-2.0.6/bdinfo_linux_v2.0.6.zip" -unzip bdinfo_linux_v2.0.6.zip -d "$BIN_DIR" -chmod 777 "$BIN_DIR/BDInfo" -curl -L -o bdinfodatasubstractor_linux_v2.0.6.zip "https://github.com/dotnetcorecorner/BDInfo/releases/download/linux-2.0.6/bdinfodatasubstractor_linux_v2.0.6.zip" -unzip bdinfodatasubstractor_linux_v2.0.6.zip -d "$BIN_DIR" -chmod 777 "$BIN_DIR/BDInfoDataSubstractor" +# ========= BDInfo & Substractor ========= +log "Installation BDInfo" +pushd "$TMP_DIR" >/dev/null +curl -fsSL -o bdinfo.zip "https://github.com/dotnetcorecorner/BDInfo/releases/download/linux-2.0.6/bdinfo_linux_v2.0.6.zip" +unzip -q bdinfo.zip +BDINFO_BIN="$(find . -type f -name BDInfo -perm -u+x | head -n1)" +[ -n "$BDINFO_BIN" ] || die "BDInfo introuvable" +install_bin "$BDINFO_BIN" "$BIN_DIR/BDInfo" +curl -fsSL -o substractor.zip "https://github.com/dotnetcorecorner/BDInfo/releases/download/linux-2.0.6/bdinfodatasubstractor_linux_v2.0.6.zip" +unzip -q substractor.zip +SUB_BIN="$(find . -type f -name BDInfoDataSubstractor -perm -u+x | head -n1)" +[ -n "$SUB_BIN" ] || die "BDInfoDataSubstractor introuvable" +install_bin "$SUB_BIN" "$BIN_DIR/BDInfoDataSubstractor" +popd >/dev/null +REQUIRED_CMDS+=(BDInfo BDInfoDataSubstractor) -# Télécharger et extraire Nyuu -echo -e "$BLEU""Téléchargement et installation de nyuu""$NORMAL" +# ========= Nyuu ========= +log "Installation Nyuu" +pushd "$TMP_DIR" >/dev/null NYUU_URL="https://github.com/Antidote2151/Nyuu-Obfuscation/releases/download/v0.4.2-Obfuscate1.3/nyuu-v0.4.2-Obfuscate1.3-linux-amd64.tar.xz" -NYUU_TAR="nyuu.tar.xz" -NYUU_EXE="nyuu" +wget -q -O nyuu.tar.xz "$NYUU_URL" +tar -xJf nyuu.tar.xz +NYUU_BIN="$(find . -type f -name nyuu -perm -u+x | head -n1)" +[ -n "$NYUU_BIN" ] || die "nyuu introuvable dans l’archive" +install_bin "$NYUU_BIN" "$BIN_DIR/nyuu" +popd >/dev/null +REQUIRED_CMDS+=(nyuu) -wget -q -O "$NYUU_TAR" "$NYUU_URL" -tar -xJf "$NYUU_TAR" > /dev/null 2>&1 -mv "$NYUU_EXE" "$BIN_DIR/nyuu" -rm config-sample.json -rm "$NYUU_TAR" -chmod 777 "$BIN_DIR/nyuu" -LISTE_APPLIS+=("$BIN_DIR/nyuu") - -# Télécharger et extraire ParPar -echo -e "$BLEU""Téléchargement et installation de parpar""$NORMAL" +# ========= ParPar ========= +log "Installation ParPar" +pushd "$TMP_DIR" >/dev/null PARPAR_URL="https://github.com/animetosho/ParPar/releases/download/v0.4.5/parpar-v0.4.5-linux-static-amd64.xz" -PARPAR_XZ="parpar-v0.4.5-linux-static-amd64.xz" +wget -q -O parpar.xz "$PARPAR_URL" +xz -d parpar.xz +PARPAR_BIN="$(find . -maxdepth 1 -type f -name 'parpar-*' -perm -u+x | head -n1)" +[ -n "$PARPAR_BIN" ] || die "parpar introuvable" +install_bin "$PARPAR_BIN" "$BIN_DIR/parpar" +popd >/devnull +REQUIRED_CMDS+=(parpar) -wget -q -O "$PARPAR_XZ" "$PARPAR_URL" -xz -d "$PARPAR_XZ" > /dev/null 2>&1 -chmod 777 "parpar-v0.4.5-linux-static-amd64" -mv "parpar-v0.4.5-linux-static-amd64" "$BIN_DIR/parpar" -LISTE_APPLIS+=("$BIN_DIR/parpar") - -# Téléchargement et installation du script de post -echo -e "$BLEU""Téléchargement de autopost""$NORMAL" - -# Création des répertoires si inexistants -mkdir -p "$AUTOPOST_DIR" - -# Télécharger les fichiers dans autopost +# ========= Téléchargement scripts autopost ========= +log "Téléchargement des scripts autopost" wget -q -O "$AUTOPOST_DIR/analyzer.sh" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/analyzer.sh" -wget -q -O "$AUTOPOST_DIR/common.sh" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/common.sh" -wget -q -O "$AUTOPOST_DIR/posteur.sh" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/posteur.sh" +wget -q -O "$AUTOPOST_DIR/common.sh" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/common.sh" +wget -q -O "$AUTOPOST_DIR/posteur.sh" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/posteur.sh" +wget -q -O "$BIN_DIR/postauto" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/bin/postauto" +[ -f "$AUTOPOST_DIR/conf.sh" ] || wget -q -O "$AUTOPOST_DIR/conf.sh" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/conf.sh" -# Télécharger le fichier dans bin -wget -q -O "$BIN_DIR/postauto" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/bin/postauto" - -if [ ! -f "$AUTOPOST_DIR/conf.sh" ]; then - wget -q -O "$AUTOPOST_DIR/conf.sh" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/conf.sh" -fi - -# Donner les permissions d'exécution si nécessaire -chmod 777 "$BIN_DIR/postauto" +chmod 755 "$BIN_DIR/postauto" chmod -R 755 "$AUTOPOST_DIR" -LISTE_APPLIS+=("$BIN_DIR/postauto") - -# Définir le chemin du fichier bashrc -BASHRC_FILE="$HOME/.bashrc" - -source $BASHRC_FILE - -manquants=() - -for i in $LISTE_APPLIS; do - if ! command -v "$i" > /dev/null 2>&1; then - manquants+=("$i") - fi -done - -if [ ${#manquants[@]} -gt 0 ]; then - echo -e "${ROUGE}Programme(s) manquant(s) : ${manquants[*]}${NORMAL}" - exit 1 -else - echo -e "${VERT}Toutes les dépendances sont disponibles.${NORMAL}" -fi - -# Marqueurs pour identifier la section ajoutée -DEBUT_MARKER="# DEBUT COMPLETION POSTAUTO" -FIN_MARKER="# FIN COMPLETION POSTAUTO" - -# Le code de complétion à ajouter, encadré par les marqueurs -read -r -d '' COMPLETION_CODE << 'EOF' -# DEBUT COMPLETION POSTAUTO -# Fonction de complétion pour ton script +# ========= Bash completion (fichier dédié) ========= +COMP_FILE="$BASH_COMPLETION_DIR/postauto" +if [ ! -s "$COMP_FILE" ]; then + cat > "$COMP_FILE" <<'EOF' +# completion postauto _autopost_completion() { local cur prev opts cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - - # Liste des commandes disponibles opts="start stop restart show status createdb add log check update" - - # Si l'utilisateur est en train de taper le premier argument, proposer les commandes + if [ $COMP_CWORD -eq 1 ]; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi - - # (Optionnel) Pour la sous-commande "add", proposer des fichiers en complétion if [ $COMP_CWORD -eq 2 ] && [ "${COMP_WORDS[1]}" = "add" ]; then COMPREPLY=( $(compgen -f -- "${cur}") ) return 0 fi } - -# Associer la fonction de complétion à ton script (ici, 'postauto' est le nom de la commande) complete -F _autopost_completion postauto -# FIN COMPLETION POSTAUTO EOF - -# Vérifier si le code est déjà présent dans le fichier bashrc -if grep -q "$DEBUT_MARKER" "$BASHRC_FILE"; then - echo "La configuration de complétion pour 'postauto' est déjà présente dans $BASHRC_FILE." + ok "Completion bash installée dans $COMP_FILE" + # source automatique depuis .bashrc si pas déjà présent + if ! grep -q 'bash_completion.d' "$BASHRC_FILE" 2>/dev/null; then + echo '[ -f "$HOME/.bash_completion.d/postauto" ] && . "$HOME/.bash_completion.d/postauto"' >> "$BASHRC_FILE" + fi else - echo "Ajout de la configuration de complétion dans $BASHRC_FILE..." - # Ajouter une ligne vide pour séparer (optionnel) - echo "" >> "$BASHRC_FILE" - # Ajouter le code de complétion - echo "$COMPLETION_CODE" >> "$BASHRC_FILE" - echo "Mise à jour effectuée." + ok "Completion déjà présente" fi - -echo "Vérification de l'environnement pour la page de suivi..." - -# Fonction pour afficher les messages en vert -log() { - echo -e "\033[1;32m$1\033[0m" -} - -# Définir le répertoire NVM +# ========= Environnement page de suivi (Node/NPM) ========= +log "Vérification environnement Node.js" export NVM_DIR="$HOME/.nvm" - -# Vérifier si nvm est déjà chargé dans la session actuelle if [ -s "$NVM_DIR/nvm.sh" ]; then - log "nvm est déjà installé. Chargement de nvm..." - \. "$NVM_DIR/nvm.sh" + . "$NVM_DIR/nvm.sh" else - log "nvm non trouvé, installation de nvm..." - # Installer nvm - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash - - # Après l'installation, sourcer nvm pour la session courante - export NVM_DIR="$HOME/.nvm" - if [ -s "$NVM_DIR/nvm.sh" ]; then - \. "$NVM_DIR/nvm.sh" - log "NVM installé et chargé." - else - log "Erreur : nvm n'a pas pu être chargé." - exit 1 - fi + log "Installation de nvm" + curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash + . "$NVM_DIR/nvm.sh" fi -# Vérification de Node.js -if command -v node &> /dev/null; then - current_version=$(node -v | sed 's/^v//') - major_version=$(echo "$current_version" | cut -d. -f1) - if [ "$major_version" -lt 22 ]; then - log "Node.js version $current_version détectée (inférieure à 22). Mise à jour en cours..." - nvm install 22 - nvm use 22 - else - log "Node.js version $current_version détectée, compatible." - fi +REQ_NODE_MAJOR=22 +if has_cmd node; then + cur="$(node -v | sed 's/^v//; s/\..*//')" + if [ "$cur" -lt "$REQ_NODE_MAJOR" ]; then + log "Node < $REQ_NODE_MAJOR → installation" + nvm install "$REQ_NODE_MAJOR" + nvm use "$REQ_NODE_MAJOR" + else + ok "Node $(node -v) OK" + fi else - log "Node.js non trouvé, installation de Node.js 22..." - nvm install 22 - nvm use 22 - updated="1" + log "Installation Node $REQ_NODE_MAJOR" + nvm install "$REQ_NODE_MAJOR" + nvm use "$REQ_NODE_MAJOR" fi -# Charger nvm après installation -export NVM_DIR="$HOME/.nvm" -[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" +# Modules npm locaux dans $AUTOPOST_DIR +log "Vérification modules npm" +pushd "$AUTOPOST_DIR" >/dev/null +[ -f package.json ] || npm init -y >/dev/null 2>&1 || true +modules=(express express-session sqlite3 ansi-to-html @tailwindcss/browser autoprefixer jquery mysql2 session-file-store chokidar) +missing=() +for m in "${modules[@]}"; do + npm list "$m" --depth=0 >/dev/null 2>&1 || missing+=("$m") +done +if [ "${#missing[@]}" -gt 0 ]; then + log "Installation modules: ${missing[*]}" + npm install "${missing[@]}" +else + ok "Tous les modules npm sont présents" +fi +popd >/dev/null -# Vérification des modules npm nécessaires -log "Vérification des modules npm requis..." +# ========= Fichiers Node (server.js, db.js, config.js) ========= +log "Vérification fichiers Node" +[ -f "$AUTOPOST_DIR/server.js" ] || wget -q -O "$AUTOPOST_DIR/server.js" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/server.js" +[ -f "$AUTOPOST_DIR/db.js" ] || wget -q -O "$AUTOPOST_DIR/db.js" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/db.js" +if [ ! -f "$AUTOPOST_DIR/config.js" ]; then + wget -q -O "$AUTOPOST_DIR/config.js" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/config.js" + ok "Installation terminée. Configurez $AUTOPOST_DIR/config.js." +fi -modules=("express" "express-session" "sqlite3" "ansi-to-html" "@tailwindcss/browser" "autoprefixer" "jquery" "mysql2" "session-file-store" "chokidar") -missing_modules=() - -for module in "${modules[@]}"; do - if ! npm list "$module" &> /dev/null; then - missing_modules+=("$module") - fi +# ========= Vérification finale des commandes ========= +log "Vérification finale des binaires requis" +missing_final=() +for cmd in "${REQUIRED_CMDS[@]}"; do + if ! command -v "$cmd" >/dev/null 2>&1; then + # autoriser chemin absolu + if [[ "$cmd" == */* ]]; then + [ -x "$cmd" ] || missing_final+=("$cmd") + else + missing_final+=("$cmd") + fi + fi done -if [ ${#missing_modules[@]} -gt 0 ]; then - log "Modules manquants détectés : ${missing_modules[*]}" - npm install "${missing_modules[@]}" +if [ "${#missing_final[@]}" -gt 0 ]; then + die "Programmes manquants: ${missing_final[*]}" else - log "Tous les modules requis sont déjà installés." + ok "Toutes les dépendances sont disponibles." fi -# Vérification et téléchargement des fichiers de configuration -log "Vérification des fichiers de configuration..." - -if [ ! -f "$AUTOPOST_DIR/server.js" ]; then - log "Téléchargement de server.js..." - wget -q -O "$AUTOPOST_DIR/server.js" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/server.js" - updated="1" +# ========= Chown ciblé (si sudo utilisé) ========= +if ! is_root && [ -n "${SUDO_USER:-}" ]; then + run_root chown -R "$SUDO_USER":"$SUDO_USER" "$BIN_DIR" "$AUTOPOST_DIR" "$BASH_COMPLETION_DIR" || true fi -if [ ! -f "$AUTOPOST_DIR/db.js" ]; then - log "Téléchargement de db.js..." - wget -q -O "$AUTOPOST_DIR/db.js" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/db.js" - updated="1" -fi - -if [ ! -f "$AUTOPOST_DIR/config.js" ]; then - log "Téléchargement de config.js..." - wget -q -O "$AUTOPOST_DIR/config.js" "https://tig.unfr.pw/UNFR/postauto/raw/branch/main/autopost/config.js" - echo -e "${BLEU}Installation terminée. Vous pouvez maintenant configurer $AUTOPOST_DIR/config.js.${NORMAL}" -fi - -echo "Suppression du script après exécution..." -rm -- "$0" - -if $sudook; then - # change propriétaire/group récursivement - USER_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6) - sudo chown -R "$SUDO_USER":"$SUDO_USER" "$USER_HOME" -fi - - +ok "Installation terminée."