servyass-dotfiles/.config/servyass/banner.zsh

90 lines
5 KiB
Bash

# banner.zsh : écran d'accueil de servyass (style du portfolio : noir, accent lime, mono, labels espacés)
# Appelé depuis ~/.zshrc à l'ouverture d'une session ; relançable avec la commande `motd`.
servyass_banner() {
emulate -L zsh
setopt extendedglob
local L=$'\e[38;2;211;253;80m' W=$'\e[38;2;245;245;240m' M=$'\e[38;2;138;138;133m' D=$'\e[38;2;70;70;66m'
local A=$'\e[38;2;255;207;74m' R=$'\e[38;2;255;95;95m' B=$'\e[1m' X=$'\e[0m'
# Logo « ANSI Shadow » : blocs pleins + ombre portée. SERV en blanc, YASS en lime (dégradé du haut vers le bas),
# comme YASSER / BOULAYOUNE sur le portfolio. Les ombres (╗║╔═╝╚) sont en gris foncé.
local -a S=('███████╗' '██╔════╝' '███████╗' '╚════██║' '███████║' '╚══════╝')
local -a E=('███████╗' '██╔════╝' '█████╗ ' '██╔══╝ ' '███████╗' '╚══════╝')
local -a Rr=('██████╗ ' '██╔══██╗' '██████╔╝' '██╔══██╗' '██║ ██║' '╚═╝ ╚═╝')
local -a V=('██╗ ██╗' '██║ ██║' '██║ ██║' '╚██╗ ██╔╝' ' ╚████╔╝ ' ' ╚═══╝ ')
local -a Y=('██╗ ██╗' '╚██╗ ██╔╝' ' ╚████╔╝ ' ' ╚██╔╝ ' ' ██║ ' ' ╚═╝ ')
local -a Aa=(' █████╗ ' '██╔══██╗' '███████║' '██╔══██║' '██║ ██║' '╚═╝ ╚═╝')
local -a grad=('211;253;80' '196;242;70' '178;228;60' '158;212;52' '138;194;44' '118;176;38')
local -a ink=('245;245;240' '238;238;232' '228;228;222' '216;216;210' '204;204;198' '192;192;186')
local sh=$'\e[38;2;58;58;54m' i c ch out left right
print
for i in {1..6}; do
left="${S[i]}${E[i]}${Rr[i]}${V[i]}" right="${Y[i]}${Aa[i]}${S[i]}${S[i]}"
out=" "
for ch in ${(s::)left}; do [[ $ch == '█' ]] && out+=$'\e[38;2;'${ink[i]}'m█' || { [[ $ch == ' ' ]] && out+=' ' || out+="${sh}${ch}"; }; done
for ch in ${(s::)right}; do [[ $ch == '█' ]] && out+=$'\e[38;2;'${grad[i]}'m█' || { [[ $ch == ' ' ]] && out+=' ' || out+="${sh}${ch}"; }; done
(( i == 6 )) && out+=" ${M}©$(date +%Y)"
print -r -- "${out}${X}"
done
print -r -- " ${L}▌${X} ${M}SERVEUR PERSO · DEBIAN $(cut -d. -f1 /etc/debian_version) · RÉGION LYONNAISE${X}"
print
# Jauge : 16 traits, lime sous 75 %, ambre jusqu'à 90 %, rouge au-delà
bar() {
local p=$1 n=$(( ($1 * 16 + 50) / 100 )) c=$L
(( p >= 75 )) && c=$A; (( p >= 90 )) && c=$R
print -rn -- "${c}${(l:n::━:)}${D}${(l:16-n::─:)}${X}"
}
row() { print -r -- " ${M}${(r:9:)1}${X}$2"; }
# Uptime
local up=${$(</proc/uptime)[1]%.*} upt
if (( up >= 86400 )); then upt="$(( up / 86400 )) j $(( up % 86400 / 3600 )) h"
elif (( up >= 3600 )); then upt="$(( up / 3600 )) h $(( up % 3600 / 60 )) min"
else upt="$(( up / 60 )) min"; fi
# Charge + température CPU
local -a la=(${=$(</proc/loadavg)})
local t=0 z
for z in /sys/class/thermal/thermal_zone*(N); do [[ $(<$z/type) == x86_pkg_temp ]] && t=$(( $(<$z/temp) / 1000 )); done
local tc=$W; (( t >= 70 )) && tc=$A; (( t >= 85 )) && tc=$R
# Mémoire
local mt ma
mt=${${(M)${(f)"$(</proc/meminfo)"}:#MemTotal:*}//[^0-9]/}
ma=${${(M)${(f)"$(</proc/meminfo)"}:#MemAvailable:*}//[^0-9]/}
local mu=$(( mt - ma )) mp=$(( (mt - ma) * 100 / mt ))
# Disque
local -a df=(${=${(f)"$(df -P / 2>/dev/null)"}[2]})
local dp=${df[5]%\%}
row UPTIME "${W}${upt}${X}"
row CPU "${tc}${t}°C${X} ${M}charge${X} ${W}${la[1]} ${la[2]} ${la[3]}${X} ${D}($(nproc) cœurs)${X}"
row MÉMOIRE "$(bar $mp) ${W}$(printf '%.1f' $(( mu / 1048576.0 )))${M} / $(printf '%.1f' $(( mt / 1048576.0 ))) Go${X}"
row DISQUE "$(bar $dp) ${W}${dp} %${M} · $(( df[3] / 1048576 )) / $(( df[2] / 1048576 )) Go${X}"
# Docker : actifs / arrêtés
if (( $+commands[docker] )); then
local -a st=(${(f)"$(docker ps -a --format '{{.State}}' 2>/dev/null)"})
local on=${#${(M)st:#running}} off=$(( ${#st} - ${#${(M)st:#running}} ))
local -a unh=(${(f)"$(docker ps --filter health=unhealthy --format '{{.Names}}' 2>/dev/null)"})
local line="${L}●${X} ${W}${on} actifs${X}"
(( off )) && line+=" ${D}○ ${off} arrêtés${X}"
(( ${#unh} )) && [[ -z $YB_BANNER_PUBLIC ]] && line+=" ${R}▲ ${(j:, :)unh}${X} ${M}en mauvaise santé${X}"
row DOCKER "$line"
fi
# Réseau : LAN, Tailscale (100.*)
local -a ips=(${=$(hostname -I 2>/dev/null)})
local lan=${${(M)ips:#192.168.1.*}[1]} ts=${${(M)ips:#100.*}[1]}
local net="${W}${lan:-?}${X}"
[[ -n $ts ]] && net+=" ${M}tailscale${X} ${W}${ts}${X}"
[[ -z $YB_BANNER_PUBLIC ]] && row RÉSEAU "$net" # YB_BANNER_PUBLIC=1 : captures publiques sans adresses internes
print
print -r -- " ${D}──${X} ${M}$(LC_TIME=fr_FR.UTF-8 date '+%A %-d %B · %H:%M')${X}"
print
unfunction bar row
}