1
0
postauto/install.sh
2025-08-13 08:08:34 +02:00

362 lines
12 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -Eeuo pipefail
# ========= 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
NOIR=''; ROUGE=''; VERT=''; JAUNE=''; BLEU=''; ROSE=''; CYAN=''; BLANC=''
GRAS=''; SOULIGNE=''; NORMAL=''
fi
# ========= 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
# ========= 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; }
is_root() { [ "${EUID:-$(id -u)}" -eq 0 ]; }
has_cmd() { command -v "$1" >/dev/null 2>&1; }
# sudo wrapper: use sudo if available and needed
run_root() {
if is_root; then
"$@"
elif has_cmd sudo; then
sudo "$@"
else
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 <src> <dst>
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
# ========= 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")
log "SQLite sélectionné"
if has_cmd sqlite3; then
ok "sqlite3 déjà présent"
else
if has_cmd apt-get; then
run_root apt-get install -y sqlite3
else
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 larchive"
install_bin "$SQLITE_BIN" "$BIN_DIR/sqlite3"
popd >/dev/null
ok "sqlite3 installé dans $BIN_DIR"
fi
fi
REQUIRED_CMDS+=(sqlite3)
break
;;
"MySQL")
log "MySQL sélectionné"
if has_cmd mysql; then
ok "mysql client disponible"
REQUIRED_CMDS+=(mysql)
else
warn "mysql client indisponible → bascule automatique sur SQLite"
if has_cmd apt-get; then
run_root apt-get install -y sqlite3
else
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 larchive"
install_bin "$SQLITE_BIN" "$BIN_DIR/sqlite3"
popd >/dev/null
fi
REQUIRED_CMDS+=(sqlite3)
fi
break
;;
*) echo "Choix invalide.";;
esac
done
# ========= jq =========
if has_cmd jq; then
ok "jq déjà présent"
else
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)
# ========= 7z =========
if has_cmd 7z; then
ok "7z déjà présent"
else
log "Installation de 7z (binaire standalone)"
pushd "$TMP_DIR" >/dev/null
Z_URL="https://7-zip.org/a/7z2409-linux-x64.tar.xz"
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)
# ========= 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)
# ========= 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"
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 larchive"
install_bin "$NYUU_BIN" "$BIN_DIR/nyuu"
popd >/dev/null
REQUIRED_CMDS+=(nyuu)
# ========= 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"
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)
# ========= 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 "$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"
chmod 755 "$BIN_DIR/postauto"
chmod -R 755 "$AUTOPOST_DIR"
# ========= 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]}"
opts="start stop restart show status createdb add log check update"
if [ $COMP_CWORD -eq 1 ]; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
if [ $COMP_CWORD -eq 2 ] && [ "${COMP_WORDS[1]}" = "add" ]; then
COMPREPLY=( $(compgen -f -- "${cur}") )
return 0
fi
}
complete -F _autopost_completion postauto
EOF
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
ok "Completion déjà présente"
fi
# ========= Environnement page de suivi (Node/NPM) =========
log "Vérification environnement Node.js"
export NVM_DIR="$HOME/.nvm"
if [ -s "$NVM_DIR/nvm.sh" ]; then
. "$NVM_DIR/nvm.sh"
else
log "Installation de nvm"
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
. "$NVM_DIR/nvm.sh"
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 "Installation Node $REQ_NODE_MAJOR"
nvm install "$REQ_NODE_MAJOR"
nvm use "$REQ_NODE_MAJOR"
fi
# 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
# ========= 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
# ========= 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_final[@]}" -gt 0 ]; then
die "Programmes manquants: ${missing_final[*]}"
else
ok "Toutes les dépendances sont disponibles."
fi
# ========= 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
ok "Installation terminée."