ajout .local/bin/batlimit

This commit is contained in:
grayTerminal-sh 2026-06-05 13:01:27 +02:00
parent 109ca4f677
commit 5cdda1e86c
17 changed files with 671 additions and 0 deletions

3
bin/.local/bin/appid Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
sleep 3
mmsg -g -c | sed 's/^/title|appid: /'

124
bin/.local/bin/aurinstall Executable file
View file

@ -0,0 +1,124 @@
#!/bin/bash
set -euo pipefail
AUR_DIR="$HOME/Aur"
EDITOR_CMD="${EDITOR:-nvim}"
ASK_EDIT=0
FORCE_EDIT=0
DOWNLOAD_ONLY=0
while getopts ":eEd" opt; do
case "$opt" in
e) ASK_EDIT=1 ;;
E) FORCE_EDIT=1 ;;
d) DOWNLOAD_ONLY=1 ;;
*)
echo "Usage: aurinstall [-e|-E] [-d] <paquet1> [paquet2 ...]"
exit 1
;;
esac
done
shift $((OPTIND - 1))
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
info() { printf "${BLUE}==>${RESET} %s\n" "$1"; }
ok() { printf "${GREEN}==>${RESET} %s\n" "$1"; }
warn() { printf "${YELLOW}==>${RESET} %s\n" "$1"; }
error() { printf "${RED}==>${RESET} %s\n" "$1"; }
section() { printf "\n${CYAN}${BOLD}>>> %s${RESET}\n" "$1"; }
if [[ $# -lt 1 ]]; then
error "Usage: aurinstall [-e|-E] [-d] <paquet1> [paquet2 ...]"
exit 1
fi
mkdir -p "$AUR_DIR"
if [[ "$DOWNLOAD_ONLY" -eq 0 ]]; then
sudo -v || exit 1
while true; do
sudo -n true || exit
sleep 30
done 2>/dev/null &
SUDO_LOOP_PID=$!
trap 'kill "$SUDO_LOOP_PID" 2>/dev/null' EXIT INT TERM
fi
for pkg in "$@" ; do
section "$pkg"
cd "$AUR_DIR" || exit 1
if [[ "$DOWNLOAD_ONLY" -eq 0 ]] && pacman -Q "$pkg" >/dev/null 2>&1; then
warn "$pkg est déjà installé, on passe."
continue
fi
if [[ -d "$pkg/.git" ]]; then
warn "$pkg déjà cloné, utilisation du dossier existant"
cd "$pkg" || { error "Impossible d'entrer dans $pkg"; continue; }
pull_output=$(git pull --ff-only 2>&1) || {
error "git pull failed pour $pkg"
cd "$AUR_DIR" || exit 1
continue
}
printf "%s\n" "$pull_output"
else
info "Clonage de $pkg"
if ! git clone "https://aur.archlinux.org/${pkg}.git"; then
error "Impossible de cloner $pkg"
continue
fi
cd "$pkg" || { error "Impossible d'entrer dans $pkg"; continue; }
fi
if [[ "$FORCE_EDIT" -eq 1 ]]; then
info "Ouverture de PKGBUILD et .SRCINFO dans $EDITOR_CMD"
"$EDITOR_CMD" PKGBUILD .SRCINFO
elif [[ "$ASK_EDIT" -eq 1 || "$DOWNLOAD_ONLY" -eq 1 ]]; then
printf "${YELLOW}Éditer PKGBUILD/.SRCINFO pour %s ? [y/N] ${RESET}" "$pkg"
read -r ans
if [[ "$ans" == "y" || "$ans" == "Y" ]]; then
"$EDITOR_CMD" PKGBUILD .SRCINFO
fi
fi
if [[ "$DOWNLOAD_ONLY" -eq 1 ]]; then
ok "$pkg prêt pour audit dans $AUR_DIR/$pkg"
continue
fi
info "Vérifie au minimum source=(), checksums, prepare()/build()/package() et validpgpkeys si présents"
rm -f ./*.pkg.tar ./*.pkg.tar.*
if ! makepkg -sf; then
error "Build failed pour $pkg"
cd "$AUR_DIR" || exit 1
continue
fi
pkgfile=$(find . -maxdepth 1 -type f \( -name '*.pkg.tar' -o -name '*.pkg.tar.*' \) ! -name '*.sig' | head -n1 || true)
echo "DEBUG: pkgfile='$pkgfile'"
if [[ -z "$pkgfile" ]]; then
error "Aucun paquet généré pour $pkg"
cd "$AUR_DIR" || exit 1
continue
fi
info "Installation de $pkgfile"
if ! sudo pacman -U --noconfirm "$pkgfile"; then
error "Install failed pour $pkg"
cd "$AUR_DIR" || exit 1
continue
fi
ok "$pkg installé avec succès"
done

59
bin/.local/bin/aurremove Executable file
View file

@ -0,0 +1,59 @@
#!/bin/bash
set -euo pipefail
AUR_DIR="$HOME/Aur"
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
info() { printf "${BLUE}==>${RESET} %s\n" "$1"; }
ok() { printf "${GREEN}==>${RESET} %s\n" "$1"; }
warn() { printf "${YELLOW}==>${RESET} %s\n" "$1"; }
error() { printf "${RED}==>${RESET} %s\n" "$1"; }
section() { printf "\n${CYAN}${BOLD}>>> %s${RESET}\n" "$1"; }
if [[ $# -lt 1 ]]; then
error "Usage: aurremove <paquet1> [paquet2 ...]"
exit 1
fi
sudo -v || exit 1
while true; do
sudo -n true || exit
sleep 30
done 2>/dev/null &
SUDO_LOOP_PID=$!
trap 'kill "$SUDO_LOOP_PID" 2>/dev/null' EXIT INT TERM
for pkg in "$@" ; do
section "$pkg"
if ! pacman -Q "$pkg" >/dev/null 2>&1; then
warn "$pkg n'est pas installé"
continue
fi
info "Désinstallation de $pkg"
if ! sudo pacman -Rns "$pkg"; then
error "Échec de suppression pour $pkg"
continue
fi
ok "$pkg supprimé du système"
if [[ -d "$AUR_DIR/$pkg" ]]; then
printf "${YELLOW}Supprimer aussi le dossier %s ? [y/N] ${RESET}" "$AUR_DIR/$pkg"
read -r ans
if [[ "$ans" == "y" || "$ans" == "Y" ]]; then
rm -rf "$AUR_DIR/$pkg"
ok "Dossier $AUR_DIR/$pkg supprimé"
else
warn "Dossier conservé : $AUR_DIR/$pkg"
fi
fi
done

155
bin/.local/bin/aursearch Executable file
View file

@ -0,0 +1,155 @@
#!/bin/bash
set -euo pipefail
RPC_BASE="https://aur.archlinux.org/rpc/?v=5"
SEARCH_BY="name-desc"
DETAILS=0
QUIET=0
LIMIT=10
SORT_BY="popularity"
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
info() { printf "${BLUE}==>${RESET} %s\n" "$1"; }
ok() { printf "${GREEN}==>${RESET} %s\n" "$1"; }
warn() { printf "${YELLOW}==>${RESET} %s\n" "$1"; }
error() { printf "${RED}==>${RESET} %s\n" "$1" >&2; }
section() { printf "\n${CYAN}${BOLD}>>> %s${RESET}\n" "$1"; }
die() {
error "$1"
exit 1
}
usage() {
cat <<'USAGE'
Usage: aursearch [options] <recherche>
Options:
-n rechercher seulement dans le nom
-m rechercher par mainteneur
-d afficher les détails complets
-q afficher seulement les noms des paquets
-l N limiter le nombre de résultats (défaut : 10)
-s mode trier par : popularity | votes | name | modified | submitted
-h afficher cette aide
Exemples:
aursearch proton
aursearch -n sway
aursearch -m Eschwartz
aursearch -d rustdesk
aursearch -q -l 20 python
USAGE
}
require_cmd() {
command -v "$1" >/dev/null 2>&1 || die "Commande requise manquante : $1"
}
while getopts ":nmdql:s:h" opt; do
case "$opt" in
n) SEARCH_BY="name" ;;
m) SEARCH_BY="maintainer" ;;
d) DETAILS=1 ;;
q) QUIET=1 ;;
l)
[[ "$OPTARG" =~ ^[0-9]+$ ]] || die "-l attend un entier"
LIMIT="$OPTARG"
;;
s)
case "$OPTARG" in
popularity|votes|name|modified|submitted) SORT_BY="$OPTARG" ;;
*) die "Mode de tri invalide : $OPTARG" ;;
esac
;;
h)
usage
exit 0
;;
*)
usage
exit 1
;;
esac
done
shift $((OPTIND - 1))
[[ $# -ge 1 ]] || {
usage
exit 1
}
require_cmd curl
require_cmd jq
query="$*"
encoded_query=$(printf '%s' "$query" | jq -sRr @uri)
url="${RPC_BASE}&type=search&by=${SEARCH_BY}&arg=${encoded_query}"
json=$(curl -fsSL "$url") || die "Échec de requête vers l'AUR"
count=$(jq '.resultcount // 0' <<< "$json")
if (( count == 0 )); then
warn "Aucun résultat pour : $query"
exit 0
fi
sorted=$(jq --arg sort "$SORT_BY" '
.results
| if $sort == "name" then sort_by(.Name)
elif $sort == "votes" then sort_by(.NumVotes // 0) | reverse
elif $sort == "submitted" then sort_by(.FirstSubmitted // 0) | reverse
elif $sort == "modified" then sort_by(.LastModified // 0) | reverse
else sort_by(.Popularity // 0) | reverse
end
' <<< "$json")
limited=$(jq --argjson limit "$LIMIT" '.[0:$limit]' <<< "$sorted")
shown=$(jq 'length' <<< "$limited")
if (( QUIET == 1 )); then
jq -r '.[].Name' <<< "$limited"
exit 0
fi
info "$count résultat(s) trouvé(s), affichage de $shown entrée(s)"
if (( DETAILS == 1 )); then
jq -r '
.[] |
"\(.Name)\n" +
" Version : \(.Version // "?")\n" +
" Votes : \(.NumVotes // 0)\n" +
" Popularité : \(.Popularity // 0)\n" +
" Mainteneur : \(.Maintainer // "orphan")\n" +
" Soumis le : \(.FirstSubmitted // 0 | strftime("%Y-%m-%d %H:%M"))\n" +
" Modifié le : \(.LastModified // 0 | strftime("%Y-%m-%d %H:%M"))\n" +
" Hors date : \(if .OutOfDate then "yes" else "no" end)\n" +
" URL AUR : https://aur.archlinux.org/packages/\(.Name)\n" +
" Description : \(.Description // "")\n"
' <<< "$limited"
else
jq -r '
.[] |
[
.Name,
(.Version // "?"),
((.NumVotes // 0) | tostring),
((.Popularity // 0) | tostring),
(.Maintainer // "orphan")
] | @tsv
' <<< "$limited" | awk 'BEGIN {
printf "%-32s %-22s %-8s %-12s %-20s\n", "Nom", "Version", "Votes", "Popularité", "Mainteneur";
printf "%-32s %-22s %-8s %-12s %-20s\n", "--------------------------------", "----------------------", "--------", "------------", "--------------------";
}
{
printf "%-32s %-22s %-8s %-12s %-20s\n", $1, $2, $3, $4, $5;
}'
fi

194
bin/.local/bin/aurupdate Executable file
View file

@ -0,0 +1,194 @@
#!/bin/bash
set -euo pipefail
AUR_DIR="${AUR_DIR:-$HOME/Aur}"
END_UPDATE="Mis à jour avec succès ;p."
SYSTEM_NAME="$(cat /etc/hostname 2>/dev/null || echo "unknown")"
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
info() { printf "${BLUE}==>${RESET} %s\n" "$1"; }
ok() { printf "${GREEN}==>${RESET} %s\n" "$1"; }
warn() { printf "${YELLOW}==>${RESET} %s\n" "$1"; }
error() { printf "${RED}==>${RESET} %s\n" "$1"; }
section() { printf "\n${CYAN}${BOLD}>>> %s${RESET}\n" "$1"; }
[[ -d "$AUR_DIR" ]] || {
error "Répertoire AUR introuvable : $AUR_DIR"
exit 1
}
sudo -v || exit 1
while true; do
sudo -n true || exit
sleep 30
done 2>/dev/null &
SUDO_LOOP_PID=$!
trap 'kill "$SUDO_LOOP_PID" 2>/dev/null' EXIT INT TERM
cd "$AUR_DIR" || exit 1
shopt -s nullglob
repos=(*/)
shopt -u nullglob
if [[ ${#repos[@]} -eq 0 ]]; then
warn "Aucun dépôt AUR dans $AUR_DIR"
exit 0
fi
declare -a outdated_repos=()
audit_repo() {
local repo="$1"
local branch upstream local_rev remote_rev base_rev
cd "$AUR_DIR/$repo" || return 1
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
error "$repo n'est pas un dépôt git valide"
return 1
fi
branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null || true)
[[ -n "$branch" ]] || {
warn "$repo : HEAD détachée, ignoré"
return 1
}
if ! git remote update --prune >/dev/null 2>&1; then
error "Impossible de contacter le remote pour $repo"
return 1
fi
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || true)
[[ -n "$upstream" ]] || upstream="origin/$branch"
local_rev=$(git rev-parse HEAD 2>/dev/null || true)
remote_rev=$(git rev-parse "$upstream" 2>/dev/null || true)
base_rev=$(git merge-base HEAD "$upstream" 2>/dev/null || true)
if [[ -z "$remote_rev" || -z "$local_rev" || -z "$base_rev" ]]; then
error "Impossible de comparer $repo avec $upstream"
return 1
fi
if [[ "$local_rev" == "$remote_rev" ]]; then
return 1
fi
if [[ "$local_rev" != "$base_rev" ]]; then
warn "$repo a des commits locaux non poussés, ignoré"
return 1
fi
outdated_repos+=("$repo")
return 0
}
ask_update() {
local repo="$1"
while true; do
printf "${YELLOW}Mettre à jour %s ? [y/N/q] ${RESET}" "$repo"
read -r ans
case "$ans" in
y|Y) return 0 ;;
n|N|"") return 1 ;;
q|Q) return 2 ;;
*) warn "Réponse invalide, utilise y, n ou q" ;;
esac
done
}
info "Scan des dépôts AUR..."
for d in "${repos[@]}"; do
repo="${d%/}"
audit_repo "$repo" || true
done
if [[ ${#outdated_repos[@]} -eq 0 ]]; then
ok "Aucune mise à jour AUR détectée"
exit 0
fi
section "Mises à jour détectées"
for repo in "${outdated_repos[@]}"; do
cd "$AUR_DIR/$repo" || continue
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || echo "origin/HEAD")
printf "${YELLOW}- %s${RESET}\n" "$repo"
git --no-pager log --oneline --decorate HEAD.."$upstream" | sed 's/^/ /'
done
declare -a selected_repos=()
section "Sélection"
for repo in "${outdated_repos[@]}"; do
if ask_update "$repo"; then
selected_repos+=("$repo")
else
rc=$?
if [[ $rc -eq 2 ]]; then
warn "Sélection interrompue"
break
fi
fi
done
if [[ ${#selected_repos[@]} -eq 0 ]]; then
warn "Aucun paquet sélectionné"
exit 0
fi
section "Paquets sélectionnés"
for repo in "${selected_repos[@]}"; do
printf "${GREEN}- %s${RESET}\n" "$repo"
done
for repo in "${selected_repos[@]}"; do
cd "$AUR_DIR/$repo" || continue
section "$repo"
info "Récupération des changements"
if ! git pull --ff-only; then
error "git pull failed for $repo"
continue
fi
info "Vérifie au minimum PKGBUILD, sources, checksums et fonctions de build"
rm -f ./*.pkg.tar.*
if ! makepkg -sf; then
error "Build failed for $repo"
continue
fi
pkgfile=$(find . -maxdepth 1 -type f -name '*.pkg.tar.*' ! -name '*.sig' | head -n1 || true)
if [[ -z "$pkgfile" ]]; then
error "Aucun paquet trouvé pour $repo"
continue
fi
info "Installation de $pkgfile"
if ! sudo pacman -U --noconfirm "$pkgfile"; then
error "Install failed for $repo"
continue
fi
ok "$repo installé avec succès"
done
printf "\n"
if command -v figlet >/dev/null 2>&1; then
figlet -f slant "$SYSTEM_NAME" | while IFS= read -r line; do
printf "${GREEN}%s${RESET}\n" "$line"
done
printf "${GREEN}%s${RESET}\n" "$END_UPDATE"
else
printf "${GREEN}%s : %s${RESET}\n" "$SYSTEM_NAME" "$END_UPDATE"
fi

29
bin/.local/bin/batlimit Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -euo pipefail
BATTERY="${1:-BAT1}"
read -rp "Niveau max de charge voulu [%] : " STOP
if ! [[ "$STOP" =~ ^[0-9]+$ ]]; then
echo "Erreur: entre un nombre."
exit 1
fi
if (( STOP < 40 || STOP > 100 )); then
echo "Erreur: choisis une valeur entre 40 et 100."
exit 1
fi
START=$((STOP - 5))
echo "Batterie : $BATTERY"
echo "Seuil début charge : $START%"
echo "Seuil arrêt charge : $STOP%"
sudo tlp setcharge "$START" "$STOP" "$BATTERY"
echo
echo "État actuel :"
sudo tlp-stat -b | grep -E "Battery|threshold|charge|Plugin|Supported"

View file

@ -0,0 +1,20 @@
#!/bin/sh
BAT="BAT1"
THRESHOLD=20
STATE_FILE="${XDG_RUNTIME_DIR:-/tmp}/battery-low-notified"
capacity=$(cat /sys/class/power_supply/$BAT/capacity 2>/dev/null)
bat_status=$(cat /sys/class/power_supply/$BAT/status 2>/dev/null)
[ -z "$capacity" ] && exit 0
[ -z "$bat_status" ] && exit 0
if [ "$bat_status" = "Discharging" ] && [ "$capacity" -le "$THRESHOLD" ]; then
if [ ! -f "$STATE_FILE" ]; then
notify-send -u critical -t 10000 "Batterie faible" "Batterie à ${capacity}% — branche le chargeur."
touch "$STATE_FILE"
fi
else
rm -f "$STATE_FILE"
fi

View file

@ -0,0 +1,4 @@
#!/bin/sh
wl-paste --type text --watch cliphist store &
wl-paste --type image --watch cliphist store &
wait

21
bin/.local/bin/dcnvim Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -e
PROJECT_DIR="$(pwd)"
devcontainer up --workspace-folder "$PROJECT_DIR" >/dev/null
CONTAINER_ID="$(
docker ps -q \
--filter "label=devcontainer.local_folder=$PROJECT_DIR"
)"
if [ -z "$CONTAINER_ID" ]; then
echo "Aucun conteneur trouvé"
exit 1
fi
export DEVCONTAINER_ID="$CONTAINER_ID"
nvim "$@"

3
bin/.local/bin/i3s_restart Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
pkill i3status-rs
i3status-rs ~/.config/i3status-rust/config.toml &

10
bin/.local/bin/kitty-ssh-add.sh Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -e
cd "$HOME"
# lance ssh-add dans ce kitty
ssh-add "$HOME/.ssh/id_ed25519-admin"
# quand c'est fini, on lance un shell interactif normal
exec zsh

View file

@ -0,0 +1,2 @@
#!/bin/sh
grim -g "$(slurp)" - | wl-copy -t image/png

View file

@ -0,0 +1,3 @@
#!/bin/sh
systemctl --user start graphical-session.target || true
exec mango

View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -e
# Laisser le temps aux fenêtres de se lancer
sleep 5
# Aller sur le workspace 1
swaymsg "workspace 1"
# Regrouper les trois fenêtres sur le bon workspace (au cas où)
swaymsg '[app_id="kitty-1"] move to workspace 1'
swaymsg '[app_id="kitty-2"] move to workspace 1'
swaymsg '[title="Perplexity"] move to workspace 1'
# Layout horizontal global
swaymsg '[app_id="kitty-1"] focus'
swaymsg 'move left'
# Revenir sur la zone gauche (un des kitty)
swaymsg '[app_id="kitty-2"] focus'
swaymsg 'move down'
# Envoyer Perplexity à droite
swaymsg '[title="Perplexity"] focus'
swaymsg 'move right'
# Envoyer Perplexity à droite
swaymsg '[title="Perplexity"] focus'
swaymsg 'move right'

10
bin/.local/bin/tlp-profile.sh Executable file
View file

@ -0,0 +1,10 @@
#!/bin/sh
# Récupère la ligne "TLP profile = balanced/BAT" et isole "balanced/BAT"
profile=$(tlp-stat -s 2>/dev/null | awk -F'= ' '/TLP profile/ {print $2}')
# Optionnel : ne garder que le profil logique (performance/balanced/power-saver)
# profile=$(printf "%s" "$profile" | cut -d'/' -f1)
[ -z "$profile" ] && profile="unknown"
printf " %s\n" "$profile"

View file

@ -0,0 +1,4 @@
#!/bin/sh
pkill waybar
waybar &

View file

@ -0,0 +1 @@
success:suspend_resume:1780654450