This commit is contained in:
pika 2025-04-14 09:22:15 +02:00
commit cc8ffcfcc2
38 changed files with 6046 additions and 0 deletions

2
bash/README.md Normal file
View file

@ -0,0 +1,2 @@
# bash

190
bash/arch-hyprland.sh Normal file
View file

@ -0,0 +1,190 @@
#!/bin/bash -e
# ╭───────────────╮
# │ env functions │
# ╰───────────────╯
# ───────────────────────────────────< ANSI color codes >───────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
# ERROR: -- Message
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
# INFO: -- Message
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
# WARNING: -- Message
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
# NOTE: -- Message
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ──────────────────────< Check if the given command exists silently >──────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─────────────< Check if the user is root and set sudo variable if necessary >─────────────
check_root() {
if [[ "$(id -u)" -ne 0 ]]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
# ─< Distribution detection and installation >────────────────────────────────────────
get_packager() {
$_sudo pacman -Sy
if command_exists paru; then
_install() { paru -S --noconfirm "$@"; }
elif command_exists yay; then
_install() { yay -S --noconfirm "$@"; }
elif command_exists pacman; then
_install() { "$_sudo" pacman -S --noconfirm "$@"; }
fi
}
check_deps() {
deps=(
"hyprland"
"hyprpicker"
"hyprlang"
"hyprutils"
"hyprwayland-scanner"
"xdg-desktop-portal-hyprland"
"$BarOfChoise"
"${MenuOfChoise[@]}"
"swww"
"wlogout"
"libnotify"
)
for dependency in "${deps[@]}"; do
if ! command_exists "$dependency"; then
echo_note "Installing $dependency.."
_install "$dependency" || echo_error "Error installing $dependency!"
else
echo_info "$dependency is already installed"
fi
done
}
ask_bar() {
echo_note "Which bar do you want to use?"
echo_note "[g]Bar, [H]yprpanel, [W]aybar"
read -r ask_bar </dev/tty
case "$ask_bar" in
g | G | gbar | gBar)
BarOfChoise="gBar"
;;
h | H | Hyprpanel | hyprpanel | hypr | Hypr)
BarOfChoise="ags-hyprpanel-git"
;;
w | W | waybar | Waybar)
BarOfChoise="waybar"
;;
*)
echo_error "You did not select something useful! Try again!"
ask_bar
;;
esac
}
ask_menu() {
echo_note "Which menu do you want to install?"
echo_note "[r]ofi, [t]tofi, [b]oth"
read -r askMenu </dev/tty
case "$askMenu" in
[rR] | rofi)
MenuOfChoise="rofi"
;;
[tT] | tofi)
MenuOfChoise="tofi"
;;
[bB] | both)
MenuOfChoise=("tofi" "rofi")
;;
*)
echo_error "You did not select something useful! Try again!"
ask_bar
;;
esac
}
ask_dotfiles() {
if [ ! -d "$HOME/.config/hypr" ]; then
echo_note "Do you want to install the custom pika hyprdots?"
echo_note "[Y/n]"
read -r ask_dotfiles </dev/tty
case "$ask_dotfiles" in
n | N)
echo_info "Finishing config now"
;;
*)
if ! command_exists git; then
_install git
fi
local gitDir=""
echo_note "What is your preferred git directory?"
read -r gitDir </dev/tty
if [ ! -d "$gitDir" ]; then
mkdir -p "$gitDir"
fi
if [[ ! -d "$gitDir/dotfiles" ]]; then
git clone --recursive --depth=1 https://git.k4li.de/dotfiles/hyprdots.git "$gitDir/dotfiles"
cd "$gitDir/dotfiles" || echo_error "Directory of choise doesnt work.."
make
else
git clone --recursive --depth=1 https://git.k4li.de/dotfiles/hyprdots.git "$gitDir/dotfiles/hyprdots" || echo_error "this directory is not empty.."
cd "$gitDir/dotfiles/hyprdots" || echo_error "Directory of choise doesnt work.."
make
fi
;;
esac
fi
}
# ───────────────────────────────< main function to execute >───────────────────────────────
main() {
if check_root; then
if check_aur; then
get_packager
fi
else
echo_error "Something went terribly wrong!"
exit 1
fi
ask_bar
ask_menu
check_deps
ask_dotfiles
}
if ! command_exists hyprland; then
main
else
echo_warning "Hyprland is already installed!"
fi

106
bash/bash_tui.sh Executable file
View file

@ -0,0 +1,106 @@
#!/bin/bash
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Menu options
declare -a options=(
"Dotfiles"
"CLI Tool Installation"
"Sudo-Options"
"Optimizations"
"Exit"
)
# declare -a options="Dotfiles CLI_Tool_Installation Sudo-Options Optimizations Exit"
# Function to print colored text
print_color() {
printf "%b%s%b\n" "$1" "$2" "$NC"
}
# Function to display the menu
display_menu() {
clear
print_color "$BLUE" "=== Environment Setup Menu ==="
for i in "${!options[@]}"; do
if [[ $i -eq $selected ]]; then
print_color "$GREEN" "> ${options[$i]}"
else
echo " ${options[$i]}"
fi
done
}
# Function to handle dotfiles setup
dotfiles_setup() {
print_color "$YELLOW" "Setting up dotfiles..."
# Add your dotfiles setup logic here
sleep 2
}
# Function to handle CLI tool installation
cli_tool_installation() {
print_color "$YELLOW" "Installing CLI tools..."
# Add your CLI tool installation logic here
sleep 2
}
# Function to handle optimizations
optimizations() {
print_color "$YELLOW" "Performing optimizations..."
# Add your optimization logic here
sleep 2
}
sudo_options() {
if [[ -e /etc/sudoers ]]; then
echo "Defaults pwfeedback" | tee -a /etc/sudoers
echo "Defaults insults" | tee -a /etc/sudoers
else
echo_error "There is no /etc/sudoers file."
fi
}
# Main menu loop
main_menu() {
local selected=0
local key=""
while true; do
display_menu
# Read a single character
read -rsn1 key
case $key in
A | k) # Up arrow or k
((selected--))
if [[ $selected -lt 0 ]]; then
selected=$((${#options[@]} - 1))
fi
;;
B | j) # Down arrow or j
((selected++))
if [[ $selected -ge ${#options[@]} ]]; then
selected=0
fi
;;
"") # Enter key
case $selected in
0) dotfiles_setup ;;
1) cli_tool_installation ;;
2) sudo_options ;;
3) optimizations ;;
4) exit 0 ;;
esac
;;
esac
done
}
# Start the main menu
main_menu </dev/tty

157
bash/debian-major.sh Normal file
View file

@ -0,0 +1,157 @@
#!/bin/sh
# ╭───────────────╮
# │ env functions │
# ╰───────────────╯
# ───────────────────────────────────< ANSI color codes >───────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─────────────< Check if the user is root and set sudo variable if necessary >─────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
# ──────────────────────< Check if the given command exists silently >──────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ╭────────────────────────────────────╮
# │ insert your scripts/functions here │
# ╰────────────────────────────────────╯
full_update_and_upgrade() {
if command_exists apt-get; then
echo_info "Updating sources.."
$_sudo apt-get update || echo_error "Something went wrong, please check your connection and permissions!"
$_sudo apt-get upgrade --assume-yes || echo_error "Something went wrong, please check your connection and permissions!"
$_sudo apt-get full-upgrade --assume-yes || echo_error "Something went wrong, please check your connection and permissions!"
else
echo_error "The OS is not suitable for this script!"
fi
}
clean_and_full_upgrade() {
if command_exists apt-get; then
echo_info "Cleaning the environment.."
$_sudo apt-get clean --assume-yes
full_update_and_upgrade
else
echo_error "The OS is not suitable for this script!"
fi
}
post_clean() {
if command_exists apt-get; then
$_sudo apt-get autoremove --assume-yes
else
echo_error "The OS is not suitable for this script!"
fi
}
detect_version() {
. /etc/os-release
case "$VERSION_CODENAME" in
bookworm)
cur_os="bookworm"
tar_os="trixie"
;;
buster)
cur_os="buster"
tar_os="bullseye"
;;
bullseye)
cur_os="bullseye"
tar_os="bookworm"
;;
*)
echo_error "$VERSION_CODENAME is either not a debian version, or just simply not defined"
return 1
;;
esac
}
update_sources() {
# Create backup directory if it doesn't exist
BACKUP_DIR="/var/backups/apt-sources"
echo_info "Creating backup directory at $BACKUP_DIR..."
$_sudo mkdir -p "$BACKUP_DIR"
echo_info "Backing up current sources lists..."
$_sudo cp /etc/apt/sources.list "$BACKUP_DIR/sources.list.backup.$(date +%Y%m%d)"
echo_info "Updating sources from Bookworm to Trixie..."
# Replace bookworm with trixie in main sources.list
$_sudo sed -i "s/$cur_os/$tar_os/g" /etc/apt/sources.list
# Check and update any additional source files in sources.list.d
if [ -d "/etc/apt/sources.list.d" ]; then
for sourcefile in /etc/apt/sources.list.d/*.list; do
if [ -f "$sourcefile" ]; then
filename=$(basename "$sourcefile")
echo_info "Backing up and updating $sourcefile..."
$_sudo cp "$sourcefile" "$BACKUP_DIR/${filename}.backup.$(date +%Y%m%d)"
$_sudo sed -i "s/$cur_os/$tar_os/g" "$sourcefile"
fi
done
fi
echo_note "Sources have been updated to Trixie. Please run a full system update."
echo_warning "Make sure to review the changes and ensure all repositories are compatible with Trixie!"
echo_info "Backups stored in $BACKUP_DIR"
echo ""
__lsb_release__="$(lsb_release -a)"
echo_info "$__lsb_release__"
}
# ───────────────────────────────< main function to execute >───────────────────────────────
main() {
if check_root; then
full_update_and_upgrade
if detect_version; then
update_sources
fi
clean_and_full_upgrade
post_clean
else
echo_error "Something went terribly wrong!"
fi
}
main

110
bash/docker-network.sh Normal file
View file

@ -0,0 +1,110 @@
#!/bin/sh
# ╭───────────────╮
# │ env functions │
# ╰───────────────╯
# ───────────────────────────────────< ANSI color codes >───────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─────────────< Check if the user is root and set sudo variable if necessary >─────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
# ──────────────────────< Check if the given command exists silently >──────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ╭────────────────────────────────────╮
# │ insert your scripts/functions here │
# ╰────────────────────────────────────╯
# Function to initialize or update the Docker daemon configuration
dnetwork_init() {
if ! command_exists docker; then
echo_error "No docker was found! Cannot continue!"
return 1
fi
CONFIG_FILE="/etc/docker/daemon.json"
echo_info "Checking Docker daemon configuration..."
# Check if the configuration file exists
if [ ! -f "$CONFIG_FILE" ]; then
echo_warning "Docker daemon configuration file not found. Creating it."
${_sudo} mkdir -p /etc/docker
${_sudo} tee "$CONFIG_FILE" >/dev/null <<EOF
{
"default-address-pools": [
{
"base": "10.0.0.0/8",
"size": 24
}
]
}
EOF
echo_note "Configuration file created with default network."
else
# Check if the "default-address-pools" entry exists
if grep -q '"default-address-pools"' "$CONFIG_FILE"; then
echo_note "Docker daemon configuration already contains 'default-address-pools'. No changes made."
else
echo_warning "Adding 'default-address-pools' to existing configuration."
${_sudo} jq '. + {"default-address-pools": [{"base": "10.0.0.0/8", "size": 24}]}' "$CONFIG_FILE" | ${_sudo} tee "$CONFIG_FILE.tmp" >/dev/null
${_sudo} mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
echo_note "Default address pool added to configuration."
fi
fi
echo_info "Restarting Docker to apply changes..."
${_sudo} systemctl restart docker && echo_note "Docker restarted successfully." || echo_error "Failed to restart Docker."
}
# ───────────────────────────────< main function to execute >───────────────────────────────
main() {
if check_root; then
dnetwork_init
else
echo_error "Something went terribly wrong!"
fi
}
main

3
bash/fix.sh Normal file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
sudo reflector --verbose --latest 10 --sort rate --save /etc/pacman.d/mirrorlist

378
bash/games/2048.sh Executable file
View file

@ -0,0 +1,378 @@
#!/usr/bin/env bash
#important variables
declare -ia board # array that keeps track of game status
declare -i pieces # number of pieces present on board
declare -i score=0 # score variable
declare -i flag_skip # flag that prevents doing more than one operation on
# single field in one step
declare -i moves # stores number of possible moves to determine if player lost
# the game
declare ESC=$'\e' # escape byte
declare header="Bash 2048 v1.1 (https://github.com/mydzor/bash2048)"
declare -i start_time=$(date +%s)
#default config
declare -i board_size=4
declare -i target=2048
declare -i reload_flag=0
declare config_dir="$HOME/.bash2048"
#for colorizing numbers
declare -a colors
colors[2]=33 # yellow text
colors[4]=32 # green text
colors[8]=34 # blue text
colors[16]=36 # cyan text
colors[32]=35 # purple text
colors[64]="33m\033[7" # yellow background
colors[128]="32m\033[7" # green background
colors[256]="34m\033[7" # blue background
colors[512]="36m\033[7" # cyan background
colors[1024]="35m\033[7" # purple background
colors[2048]="31m\033[7" # red background (won with default target)
exec 3>/dev/null # no logging by default
trap "end_game 0 1" INT #handle INT signal
#simplified replacement of seq command
function _seq {
local cur=1
local max
local inc=1
case $# in
1) let max=$1 ;;
2)
let cur=$1
let max=$2
;;
3)
let cur=$1
let inc=$2
let max=$3
;;
esac
while test $max -ge $cur; do
printf "$cur "
let cur+=inc
done
}
# print currect status of the game, last added pieces are marked red
function print_board {
clear
printf "$header pieces=$pieces target=$target score=$score\n"
printf "Board status:\n" >&3
printf "\n"
printf '/------'
for l in $(_seq 1 $index_max); do
printf '+------'
done
printf '\\\n'
for l in $(_seq 0 $index_max); do
printf '|'
for m in $(_seq 0 $index_max); do
if let ${board[l * $board_size + m]}; then
if let '(last_added==(l*board_size+m))|(first_round==(l*board_size+m))'; then
printf '\033[1m\033[31m %4d \033[0m|' ${board[l * $board_size + m]}
else
printf "\033[1m\033[${colors[${board[l * $board_size + m]}]}m %4d\033[0m |" ${board[l * $board_size + m]}
fi
printf " %4d |" ${board[l * $board_size + m]} >&3
else
printf ' |'
printf ' |' >&3
fi
done
let l==$index_max || {
printf '\n|------'
for l in $(_seq 1 $index_max); do
printf '+------'
done
printf '|\n'
printf '\n' >&3
}
done
printf '\n\\------'
for l in $(_seq 1 $index_max); do
printf '+------'
done
printf '/\n'
}
# Generate new piece on the board
# inputs:
# $board - original state of the game board
# $pieces - original number of pieces
# outputs:
# $board - new state of the game board
# $pieces - new number of pieces
function generate_piece {
while true; do
let pos=RANDOM%fields_total
let board[$pos] || {
let value=RANDOM%10?2:4
board[$pos]=$value
last_added=$pos
printf "Generated new piece with value $value at position [$pos]\n" >&3
break
}
done
let pieces++
}
# perform push operation between two pieces
# inputs:
# $1 - push position, for horizontal push this is row, for vertical column
# $2 - recipient piece, this will hold result if moving or joining
# $3 - originator piece, after moving or joining this will be left empty
# $4 - direction of push, can be either "up", "down", "left" or "right"
# $5 - if anything is passed, do not perform the push, only update number
# of valid moves
# $board - original state of the game board
# outputs:
# $change - indicates if the board was changed this round
# $flag_skip - indicates that recipient piece cannot be modified further
# $board - new state of the game board
function push_pieces {
case $4 in
"up")
let "first=$2*$board_size+$1"
let "second=($2+$3)*$board_size+$1"
;;
"down")
let "first=(index_max-$2)*$board_size+$1"
let "second=(index_max-$2-$3)*$board_size+$1"
;;
"left")
let "first=$1*$board_size+$2"
let "second=$1*$board_size+($2+$3)"
;;
"right")
let "first=$1*$board_size+(index_max-$2)"
let "second=$1*$board_size+(index_max-$2-$3)"
;;
esac
let ${board[$first]} || {
let ${board[$second]} && {
if test -z $5; then
board[$first]=${board[$second]}
let board[$second]=0
let change=1
printf "move piece with value ${board[$first]} from [$second] to [$first]\n" >&3
else
let moves++
fi
return
}
return
}
let ${board[$second]} && let flag_skip=1
let "${board[$first]}==${board[second]}" && {
if test -z $5; then
let board[$first]*=2
let "board[$first]==$target" && end_game 1
let board[$second]=0
let pieces-=1
let change=1
let score+=${board[$first]}
printf "joined piece from [$second] with [$first], new value=${board[$first]}\n" >&3
else
let moves++
fi
}
}
function apply_push {
printf "\n\ninput: $1 key\n" >&3
for i in $(_seq 0 $index_max); do
for j in $(_seq 0 $index_max); do
flag_skip=0
let increment_max=index_max-j
for k in $(_seq 1 $increment_max); do
let flag_skip && break
push_pieces $i $j $k $1 $2
done
done
done
}
function check_moves {
let moves=0
apply_push up fake
apply_push down fake
apply_push left fake
apply_push right fake
}
function key_react {
let change=0
read -d '' -sn 1
test "$REPLY" = "$ESC" && {
read -d '' -sn 1 -t1
test "$REPLY" = "[" && {
read -d '' -sn 1 -t1
case $REPLY in
A) apply_push up ;;
B) apply_push down ;;
C) apply_push right ;;
D) apply_push left ;;
esac
}
} || {
case $REPLY in
k) apply_push up ;;
j) apply_push down ;;
l) apply_push right ;;
h) apply_push left ;;
w) apply_push up ;;
s) apply_push down ;;
d) apply_push right ;;
a) apply_push left ;;
esac
}
}
function save_game {
rm -rf "$config_dir"
mkdir "$config_dir"
echo "${board[@]}" >"$config_dir/board"
echo "$board_size" >"$config_dir/board_size"
echo "$pieces" >"$config_dir/pieces"
echo "$target" >"$config_dir/target"
# echo "$log_file" > "$config_dir/log_file"
echo "$score" >"$config_dir/score"
echo "$first_round" >"$config_dir/first_round"
}
function reload_game {
printf "Loading saved game...\n" >&3
if test ! -d "$config_dir"; then
return
fi
board=($(cat "$config_dir/board"))
board_size=($(cat "$config_dir/board_size"))
board=($(cat "$config_dir/board"))
pieces=($(cat "$config_dir/pieces"))
first_round=($(cat "$config_dir/first_round"))
target=($(cat "$config_dir/target"))
score=($(cat "$config_dir/score"))
fields_total=board_size*board_size
index_max=board_size-1
}
function end_game {
# count game duration
end_time=$(date +%s)
let total_time=end_time-start_time
print_board
printf "Your score: $score\n"
printf "This game lasted "
$(date --version >/dev/null 2>&1)
if [[ "$?" -eq 0 ]]; then
date -u -d @${total_time} +%T
else
date -u -r ${total_time} +%T
fi
stty echo
let $1 && {
printf "Congratulations you have achieved $target\n"
exit 0
}
let test -z $2 && {
read -n1 -p "Do you want to overwrite saved game? [y|N]: "
test "$REPLY" = "Y" || test "$REPLY" = "y" && {
save_game
printf "\nGame saved. Use -r option next to load this game.\n"
exit 0
}
test "$REPLY" = "" && {
printf "\nGame not saved.\n"
exit 0
}
}
printf "\nYou have lost, better luck next time.\033[0m\n"
exit 0
}
function help {
cat <<END_HELP
Usage: $1 [-b INTEGER] [-t INTEGER] [-l FILE] [-r] [-h]
-b specify game board size (sizes 3-9 allowed)
-t specify target score to win (needs to be power of 2)
-l log debug info into specified file
-r reload the previous game
-h this help
END_HELP
}
#parse commandline options
while getopts "b:t:l:rh" opt; do
case $opt in
b)
board_size="$OPTARG"
let '(board_size>=3)&(board_size<=9)' || {
printf "Invalid board size, please choose size between 3 and 9\n"
exit -1
}
;;
t)
target="$OPTARG"
printf "obase=2;$target\n" | bc | grep -e '^1[^1]*$'
let $? && {
printf "Invalid target, has to be power of two\n"
exit -1
}
;;
r) reload_flag="1" ;;
h)
help $0
exit 0
;;
l) exec 3>$OPTARG ;;
\?)
printf "Invalid option: -"$opt", try $0 -h\n" >&2
exit 1
;;
:)
printf "Option -"$opt" requires an argument, try $0 -h\n" >&2
exit 1
;;
esac
done
#init board
let fields_total=board_size*board_size
let index_max=board_size-1
for i in $(_seq 0 $fields_total); do board[$i]="0"; done
let pieces=0
generate_piece
first_round=$last_added
generate_piece
#load saved game if flag is set
if test $reload_flag = "1"; then
reload_game
fi
while true; do
print_board
key_react
let change && generate_piece
first_round=-1
let pieces==fields_total && {
check_moves
let moves==0 && end_game 0 #lose the game
}
done

50
bash/games/wordle.sh Executable file
View file

@ -0,0 +1,50 @@
words=($(grep '^\w\w\w\w\w$' /usr/share/dict/words | tr '[a-z]' '[A-Z]'))
actual=${words[$(($RANDOM % ${#words[@]}))]} end=false guess_count=0 max_guess=6
if [[ $1 == "unlimit" ]]; then
max_guess=999999
fi
while [[ $end != true ]]; do
guess_count=$(($guess_count + 1))
if [[ $guess_count -le $max_guess ]]; then
echo "Enter your guess ($guess_count / $max_guess):"
read guess
guess=$(echo $guess | tr '[a-z]' '[A-Z]')
if [[ " ${words[*]} " =~ " $guess " ]]; then
output="" remaining=""
if [[ $actual == $guess ]]; then
echo "You guessed right!"
for ((i = 0; i < ${#actual}; i++)); do
output+="\033[30;102m ${guess:$i:1} \033[0m"
done
printf "$output\n"
end=true
else
for ((i = 0; i < ${#actual}; i++)); do
if [[ "${actual:$i:1}" != "${guess:$i:1}" ]]; then
remaining+=${actual:$i:1}
fi
done
for ((i = 0; i < ${#actual}; i++)); do
if [[ "${actual:$i:1}" != "${guess:$i:1}" ]]; then
if [[ "$remaining" == *"${guess:$i:1}"* ]]; then
output+="\033[30;103m ${guess:$i:1} \033[0m"
remaining=${remaining/"${guess:$i:1}"/}
else
output+="\033[30;107m ${guess:$i:1} \033[0m"
fi
else
output+="\033[30;102m ${guess:$i:1} \033[0m"
fi
done
printf "$output\n"
fi
else
echo "Please enter a valid word with 5 letters!"
guess_count=$(($guess_count - 1))
fi
else
echo "You lose! The word is:"
echo $actual
end=true
fi
done

246
bash/gitsetup.sh Executable file
View file

@ -0,0 +1,246 @@
#!/bin/bash
# Get the current git config list
gc_ls="$(git config --list)"
# ANSI color codes
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_gls() {
printf "${BOLD}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# Function to print colored text
print_color() {
printf "%b%s%b\n" "$1" "$2" "$NC"
}
# Check if the given command exists silently
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# Function to install a package if `curl` is available
if command_exists curl; then
install_pkg() {
sh -c "$(curl -sSL https://git.k4li.de/pika/scripts/raw/branch/main/bash/snippets/install_pkg.sh)" -- "$@"
}
else
echo_error "curl is not installed, universal install disabled!"
fi
# Function for barebones Git setup
gitBareBonesSetup() {
echo_gls "Please enter your username: "
read -r g_username
echo_gls "Please enter your email: "
read -r g_mail
echo_gls "Please enter your default branch name <e.g. main>"
read -r g_branch
git config --global user.name "$g_username"
git config --global user.email "$g_mail"
git config --global init.defaultBranch "$g_branch"
echo_note "Barebones Git setup complete!"
read </dev/tty
}
# Function for extended Git configuration
gitExtendedSetup() {
echo_gls "Please enter the default branch name (e.g., main): "
read -r g_branch
echo_gls "Please enter your preferred text editor (e.g., vim, nano, code): "
read -r g_editor
# Set default branch name
git config --global init.defaultBranch "$g_branch"
# Set preferred text editor
git config --global core.editor "$g_editor"
# Set some common aliases
git config --global alias.co "checkout"
git config --global alias.br "branch"
git config --global alias.ci "commit"
git config --global alias.st "status"
# Set default push behavior to simple (to avoid issues with push)
git config --global push.default simple
# Enable credential caching for 15 minutes (900 seconds)
git config --global credential.helper "cache --timeout=900"
# Add a global .gitignore file (optional)
echo_gls "Do you have a global .gitignore file? If so, please provide the path (or leave blank to skip): "
read -r g_gitignore
if [ -n "$g_gitignore" ] && [ -f "$g_gitignore" ]; then
git config --global core.excludesfile "$g_gitignore"
echo_note "Global .gitignore file set to $g_gitignore"
else
echo_warning "Skipping global .gitignore configuration!"
fi
echo_note "Extended Git setup complete!"
read </dev/tty
}
gitChangeMail() {
echo_gls "Please enter the new e-Mail: "
read -e -r new_mail
git config --global user.email "$new_mail"
echo_note "Email updated to $new_mail"
read </dev/tty
}
gitChangeUsername() {
currentName="$(git config --get user.name)"
echo_warning "Do you really want to change your username? (current username is $currentName) (y/N): "
read -e -r confirm
if [[ "$currentName" -eq ^"yY" ]]; then
echo_gls "Please enter the new Username: "
read -r new_username
git config --global user.name "$new_username"
echo_note "Username updated to $new_username"
read </dev/tty
fi
}
gitCredentialsAddAuthToken() {
local CREDENTIALS_FILE="$HOME/.git-credentials"
echo_gls "Enter the domain/server (e.g. git.k4li.de):"
read -r g_domain
echo_gls "Enter your username:"
read -r g_user
echo_gls "Enter your authentication token:"
read -r g_token # The '-s' flag hides input for privacy
# Append the new credentials to the file
echo "https://$g_user:$g_token@$g_domain" >>"$CREDENTIALS_FILE"
echo "Credentials added for $g_domain in $CREDENTIALS_FILE"
git config --global credential.helper store
chmod 600 "$HOME/.git-credentials"
read </dev/tty
}
# Display the current Git configuration
showGitConfig() {
echo_gls "This is your current git-config:"
echo_gls "─────────────────────────────────────────────────"
# Loop through each line of the git config list and format it nicely
printf "%s\n" "$gc_ls" | while IFS='=' read -r key value; do
# Extract section/category name (before the first period)
category="${key%%.*}"
# Extract setting name (after the first period)
setting="${key#*.}"
# Use different colors and styles for category and setting names
printf "${BOLD}${CYAN}%-20s${NC}: ${LIGHT_GREEN}%-30s${NC} ${YELLOW}%s${NC}\n" "$category" "$setting" "$value"
done
echo_gls "─────────────────────────────────────────────────"
read </dev/tty
}
# Main menu loop
main_menu() {
local selected=0
local key=""
while true; do
display_menu
# Read a single character
read -rsn1 key
case $key in
A | k) # Up arrow or k
((selected--))
if [[ $selected -lt 0 ]]; then
selected=$((${#options[@]} - 1))
fi
;;
B | j) # Down arrow or j
((selected++))
if [[ $selected -ge ${#options[@]} ]]; then
selected=0
fi
;;
q) # q for quit
exit 0
;;
"") # Enter key
case $selected in
0) gitBareBonesSetup ;;
1) gitExtendedSetup ;;
2) gitChangeMail ;;
3) gitChangeUsername ;;
4) gitCredentialsAddAuthToken ;;
5) showGitConfig ;;
6) exit 0 ;;
esac
;;
esac
done
}
# Menu options
declare -a options=(
"BareBones setup"
"Extended setup"
"Change e-Mail"
"Change username"
"Activate git-credentials and add Authentication token for any git server"
"Show the current git config"
"Exit"
)
# Function to display the menu
display_menu() {
clear
print_color "$BLUE" "=== Git setup tui ==="
echo_note "(navigate with j/k or up/down arrows - q to quit)"
for i in "${!options[@]}"; do
if [[ $i -eq $selected ]]; then
print_color "$GREEN" "> ${options[$i]}"
else
echo " ${options[$i]}"
fi
done
}
# Main function
main() {
if command_exists git; then
main_menu </dev/tty
else
install_pkg git && main
fi
}
main

160
bash/installs/forgejo-runner.sh Executable file
View file

@ -0,0 +1,160 @@
#!/usr/bin/env bash
# ─< ANSI color codes >───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m'
# ─< Initialize storage variables >───────────────────────────────────────────────────────
_STORED_ERRORS=""
_STORED_WARNINGS=""
_STORED_INFOS=""
_STORED_NOTES=""
# ─< echo functions that store and display messages >────────────────────────────
echo_error() {
local message="${RED}$1${NC}\n"
printf "$message" >&2
_STORED_ERRORS="${_STORED_ERRORS}${message}"
}
echo_warning() {
local message="${YELLOW}$1${NC}\n"
printf "$message"
_STORED_WARNINGS="${_STORED_WARNINGS}${message}"
}
echo_info() {
local message="${CYAN}$1${NC}\n"
printf "$message"
_STORED_INFOS="${_STORED_INFOS}${message}"
}
echo_note() {
local message="${LIGHT_GREEN}$1${NC}\n"
printf "$message"
_STORED_NOTES="${_STORED_NOTES}${message}"
}
# ─< Improved display function that only shows categories with content >──────────────────
display_stored_messages() {
local has_messages=0
# ─< First check if we have any messages at all >─────────────────────────────────────────
if [ -z "$_STORED_ERRORS" ] && [ -z "$_STORED_WARNINGS" ] && [ -z "$_STORED_INFOS" ] && [ -z "$_STORED_NOTES" ]; then
return 0
fi
# ─< Now display each non-empty category with proper spacing >────────────────────────────
if [ -n "$_STORED_ERRORS" ]; then
printf "\n${BOLD}${RED}=== Errors ===${NC}\n"
printf "$_STORED_ERRORS"
has_messages=1
fi
if [ -n "$_STORED_WARNINGS" ]; then
[ "$has_messages" -eq 1 ] && printf "\n"
printf "${BOLD}${YELLOW}=== Warnings ===${NC}\n"
printf "$_STORED_WARNINGS"
has_messages=1
fi
if [ -n "$_STORED_INFOS" ]; then
[ "$has_messages" -eq 1 ] && printf "\n"
printf "${BOLD}${CYAN}=== Info ===${NC}\n"
printf "$_STORED_INFOS"
has_messages=1
fi
if [ -n "$_STORED_NOTES" ]; then
[ "$has_messages" -eq 1 ] && printf "\n"
printf "${BOLD}${LIGHT_GREEN}=== Notes ===${NC}\n"
printf "$_STORED_NOTES"
fi
}
_exit() {
display_stored_messages
exit 1
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─< Check if the user is root and set sudo variable if necessary >───────────────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
getRunner() {
# ╭─────────────────────────────────────────────────────────╮
# │ should output something like this │
# │ ╭─────────────────────────────────────────────────────╮ │
# │ │ Good signature from "Forgejo <contact@forgejo.org>" │ │
# │ │ aka "Forgejo Releases <release@forgejo.org>" │ │
# │ ╰─────────────────────────────────────────────────────╯ │
# ╰─────────────────────────────────────────────────────────╯
#
# ─< get the runner version >─────────────────────────────────────────────────────────────
export RUNNER_VERSION=$(curl -X 'GET' https://data.forgejo.org/api/v1/repos/forgejo/runner/releases/latest | jq .name -r | cut -c 2-)
# ─< get the runner binary >──────────────────────────────────────────────────────────────
wget -O forgejo-runner https://code.forgejo.org/forgejo/runner/releases/download/v${RUNNER_VERSION}/forgejo-runner-${RUNNER_VERSION}-linux-amd64
# ─< make it executable >─────────────────────────────────────────────────────────────────
chmod +x forgejo-runner
# ─< get the verification hashes >────────────────────────────────────────────────────────
wget -O forgejo-runner.asc https://code.forgejo.org/forgejo/runner/releases/download/v${RUNNER_VERSION}/forgejo-runner-${RUNNER_VERSION}-linux-amd64.asc
gpg --keyserver keys.openpgp.org --recv EB114F5E6C0DC2BCDD183550A4B61A2DC5923710
gpg --verify forgejo-runner.asc forgejo-runner
}
userCreation() {
$_sudo useradd --create-home runner
$_sudo usermod -aG docker runner
}
envCheck() {
if ! command_exists curl; then
echo_error "You have no curl installed"
_exit
fi
if ! command_exists wget; then
echo_error "You have no wget installed"
_exit
fi
if ! command_exists docker; then
echo_warning "Sorry, you have no docker installed.."
_exit
fi
if command_exists forgejo-runner; then
echo_warning "forgejo-runner binary is already callable.."
_exit
fi
}
if envCheck; then
getRunner
if ! grep -iq "runner" /etc/passwd; then
userCreation
fi
forgejo-runner generate-config >config.yml && $_sudo rsync -avP config.yml /home/runner/config.yml
fi

357
bash/postinstall.sh Executable file
View file

@ -0,0 +1,357 @@
{
#!/bin/sh
# ╭──────────────╮
# │ dependencies │
# ╰──────────────╯
deps="7zip bc btop exa fzf gawk gdu git make pv ripgrep rsync stow tmux trash-cli unzip zoxide zsh"
# ╭─────────────╮
# │ ENVIRONMENT │
# ╰─────────────╯
# ANSI color codes
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m'
# Initialize storage variables
_STORED_ERRORS=""
_STORED_WARNINGS=""
_STORED_INFOS=""
_STORED_NOTES=""
# Modified echo functions that store and display messages
echo_error() {
message="${RED}$1${NC}\n"
printf "$message" >&2
_STORED_ERRORS="${_STORED_ERRORS}${message}"
}
echo_warning() {
message="${YELLOW}$1${NC}\n"
printf "$message"
_STORED_WARNINGS="${_STORED_WARNINGS}${message}"
}
echo_info() {
message="${CYAN}$1${NC}\n"
printf "$message"
_STORED_INFOS="${_STORED_INFOS}${message}"
}
echo_note() {
message="${LIGHT_GREEN}$1${NC}\n"
printf "$message"
_STORED_NOTES="${_STORED_NOTES}${message}"
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─────────────────────────────────────< get packager >─────────────────────────────────────
checkPkg() {
pkger=""
for pkg in apt-get dnf pacman apk zypper; do
if command_exists $pkg; then
printf "Using ${RED}${pkg}${NC} method.."
pkger="$pkg"
# break
return 0
fi
done
}
# ─────────────────────────────────< check for root/sudo >───────────────────────────────
# checkRoot() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo -E"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
# }
# ╭─────╮
# │ apt │
# ╰─────╯
aptCommentCDinSources() {
# Path to sources.list
sources_file="/etc/apt/sources.list"
# Check if file exists
if [ ! -f "$sources_file" ]; then
echo_error "Error: $sources_file not found"
return 1
fi
# Comment out CD-ROM entries using sudo
$_sudo sed -i 's/^[[:space:]]*deb[[:space:]]\+cdrom:/#&/' "$sources_file"
echo_info "CD-ROM entries have been commented out in $sources_file"
}
aptBase() {
aptCommentCDinSources
echo_info "Updating sources.."
$_sudo apt update
if ! command_exists sudo; then
echo_note "Installing sudo"
apt install sudo --assume-yes
fi
echo_note "Installing base packages: $deps"
for _deps in $deps; do
if ! command_exists "$_deps"; then
echo_info "Installing $_deps.."
if ! $_sudo apt install "$_deps" --assume-yes; then
echo_error "$_deps - failed to install!"
fi
else
echo_note "$_deps - was already installed!"
fi
done
}
aptOptimize() {
if command_exists nala; then
echo_info "Nala is already present, fetching mirros now! (This might take a minute or two, depending on your internet speed)"
$_sudo nala fetch --auto --assume-yes --https-only
else
echo_note "Nala is not installed on the system, do you want to install it now? (Y/n): "
read -r inst_nala </dev/tty
case "$inst_nala" in
N | n)
echo_warning "All right, continue without nala!"
;;
*)
echo_note "Installing nala.."
$_sudo apt install nala --assume-yes &&
echo_info "Fetching best mirrors"
$_sudo nala fetch --auto --assume-yes --https-only
;;
esac
fi
}
# ╭────────╮
# │ pacman │
# ╰────────╯
pacmanBase() {
if command_exists nano; then
if command_exists vim; then
echo_note "Removing nano, vim is backup"
$_sudo pacman -R nano --noconfirm
else
echo_note "Removing nano and installing vim as a backup"
$_sudo pacman -S vim --noconfirm
fi
fi
$_sudo pacman -S base-devel --noconfirm
echo_note "Installing base packages: $deps"
for _deps in $deps; do
if ! command_exists "$_deps"; then
if ! $_sudo pacman -S "$_deps" --noconfirm; then
echo_error "$_deps - failed to install"
fi
else
echo_note "$_deps - was already installed"
fi
done
}
# ╭─────╮
# │ dnf │
# ╰─────╯
dnfBase() {
echo_info "Updating sources.."
if ! $_sudo dnf update; then
echo_error "Maybe you need a proxy?"
exit 1
fi
echo_note "Installing base packages: $deps"
for _deps in $deps; do
if ! command_exists "$_deps"; then
echo_info "Installing $_deps.."
if ! $_sudo dnf install "$_deps"; then
echo_error "$_deps - failed to install!"
fi
else
echo_note "$_deps - was already installed!"
fi
done
}
# ╭────────╮
# │ zypper │
# ╰────────╯
zypperBase() {
echo_info "Updating sources.."
if ! $_sudo zypper ref; then
echo_error "Maybe you need a proxy?"
exit 1
fi
echo_note "Installing base packages: $deps"
for _deps in $deps; do
if ! command_exists "$_deps"; then
echo_info "Installing $_deps.."
if ! $_sudo zypper in "$_deps"; then
echo_error "$_deps - failed to install!"
fi
else
echo_note "$_deps - was already installed!"
fi
done
}
# ╭───────────╮
# │ FUNCTIONS │
# ╰───────────╯
# envCheck() {
# checkRoot
# checkPkg
# }
install_base() {
if ! checkPkg; then
return 1
fi
echo_info "Installing base packages..."
case "$pkger" in
apt-get)
echo_info "apt-get"
aptBase
;;
dnf)
echo_info "dnf"
dnfBase
;;
pacman)
echo_info "pacman"
pacmanBase
;;
zypper)
echo_info "zypper"
zypperBase
;;
apk) ;;
esac
}
optimize_os() {
if ! checkPkg; then
return 1
fi
echo_info "Running OS optimizations..."
# debug
echo_error "PCK=$pkg PKGER=$pkger"
case "$pkg" in
apt-get)
aptOptimize
;;
dnf)
echo_warning "Currently, there are no optimizations for the fedora distribution."
;;
pacman)
echo_warning "Currently, there are no optimizations for the arch distribution."
;;
zypper)
echo_warning "Currently, there are no optimizations for the openSUSE distribution."
;;
apk)
echo_warning "Currently, there are no optimizations for the Alpine distribution."
;;
esac
}
# setup_vpn() {
# echo_info "Setting up VPN..."
# # Add VPN setup logic here
# }
# ╭──────────╮
# │ ARGUMENTS │
# ╰──────────╯
show_help() {
echo "Usage: $0 [OPTIONS]"
echo " --install-base Install base packages"
echo " --optimize-os Optimize the OS"
echo " --all Uses all flags together"
# echo " --setup-vpn Setup VPN"
echo " --help Show this help message"
echo ""
echo "If you 'curl | sh' this script, then replace 'sh' with 'sh -s -- [OPTIONS]'"
printf "So for example ${CYAN} curl https://path/to/postinstall.sh | sh -s -- --all ${NC}"
}
# Default to no options
INSTALL_BASE=false
OPTIMIZE_OS=false
# SETUP_VPN=false
# Parse command-line arguments
while [ "$#" -gt 0 ]; do
case "$1" in
--install-base)
INSTALL_BASE=true
;;
--optimize-os)
OPTIMIZE_OS=true
;;
--all)
OPTIMIZE_OS=true
INSTALL_BASE=true
;;
# --setup-vpn)
# SETUP_VPN=true
# ;;
--help)
show_help
exit 0
;;
*)
echo_error "Unknown option: $1"
show_help
exit 1
;;
esac
shift
done
# Execute selected options
$OPTIMIZE_OS && optimize_os
$INSTALL_BASE && install_base
# $SETUP_VPN && setup_vpn
# If no options were provided, show help
if [ "$INSTALL_BASE" = false ] && [ "$OPTIMIZE_OS" = false ]; then # && [ "$SETUP_VPN" = false ]; then
show_help
exit 1
fi
}

143
bash/realmjoin.sh Normal file
View file

@ -0,0 +1,143 @@
#!/bin/sh -e
# ╭───────────────╮
# │ env functions │
# ╰───────────────╯
# ───────────────────────────────────< ANSI color codes >───────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ────────────────< function to check if the given command exists silently >────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─────────────< Check if the user is root and set sudo variable if necessary >─────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
# ─< Distribution detection and installation >────────────────────────────────────────
get_packager() {
if [ -e /etc/os-release ]; then
echo_info "Detecting distribution..."
. /etc/os-release
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
case "$ID" in
ubuntu | pop) _install() { $_sudo apt-get install --assume-yes "$@"; } ;;
debian) _install() { $_sudo apt-get install --assume-yes "$@"; } ;;
fedora) _install() { $_sudo dnf install -y "$@"; } ;;
alpine) _install() { $_sudo apk add "$@"; } ;;
arch | manjaro | garuda | endeavour) _install() { $_sudo pacman -S --noconfirm "$@"; } ;;
opensuse*) _install() { $_sudo zypper in -y "$@"; } ;;
*)
if echo "$ID_LIKE" | grep -q "debian"; then
_install() { $_sudo apt-get install --assume-yes "$@"; }
elif echo "$ID_LIKE" | grep -q "ubuntu"; then
_install() { $_sudo apt-get install --assume-yes "$@"; }
elif echo "$ID_LIKE" | grep -q "arch"; then
_install() { $_sudo pacman -S --noconfirm "$@"; }
elif echo "$ID_LIKE" | grep -q "fedora"; then
_install() { $_sudo dnf install -y "$@"; }
elif echo "$ID_LIKE" | grep -q "suse"; then
_install() { $_sudo zypper in -y "$@"; }
else
echo_error "Unsupported distribution: $ID"
return 1
fi
;;
esac
else
echo_error "Unable to detect distribution. /etc/os-release not found."
return 1
fi
}
# ──────────────────────────< define your functions/script here >────────────────────────
dependencies() {
_deps="krb5-user realmd sssd-tools sssd libnss-sss libpam-sss adcli"
for dependency in $_deps; do
if ! command_exists "$dependency"; then
echo_info "Installing $dependency.."
sleep 0.3
if ! _install "$dependency"; then
echo_error "$dependency - could not be installed!"
else
echo_note "$dependency - was installed successfully!"
fi
else
echo_note "$dependency is already installed."
fi
done
}
_join() {
domain="swu.dom"
echo_note "You are trying to connect to $domain.."
sleep 1
echo_note "Please enter an administrator user like this: [example-user]"
printf "Admin User: " >&2
read -r _admin </dev/tty
if [ -n "$_admin" ]; then
if realm join -v -U "$_admin@$domain" "$domain"; then
echo_note "Successfully joined domain $domain."
else
echo_error "Failed to join domain $domain."
return 1
fi
else
echo_error "Administrator username cannot be empty."
return 1
fi
}
# ───────────────────────────────< define the main function >───────────────────────────────
main() {
if check_root; then
get_packager &&
dependencies &&
_join
else
echo_error "Root privileges are required. Exiting."
return 1
fi
}
# ──────────────────────────────< execute the main function >────────────────────────────
main

38
bash/setup/hlpush.sh Executable file
View file

@ -0,0 +1,38 @@
#!/usr/bin/env bash
# ─< ANSI color codes >───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
main() {
local dir="/opt/docker"
cd $dir || echo_error "Can't navigate to $dir"
git add .
git commit -m "Automatic push on $(date)"
git push
}
main

152
bash/setup/homelapGitSetup.sh Executable file
View file

@ -0,0 +1,152 @@
#!/usr/bin/env bash
# ─< ANSI color codes >───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─< Check if the user is root and set sudo variable if necessary >───────────────────────
check_root() {
if [[ "$(id -u)" -ne 0 ]]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
check_root
gitUserSetup() {
local g_username="server-agent"
local g_mail="info@team-pieck.de"
local g_branch="main"
local g_domain="git.k4li.de"
local CREDENTIALS_FILE="$HOME/.git-credentials"
git config --global user.name "$g_username"
git config --global user.email "$g_mail"
git config --global init.defaultBranch "$g_branch"
if [[ ! -e "$CREDENTIALS_FILE" ]]; then
echo_note "Enter your authentication token:"
read -r -s g_token </dev/tty # The '-s' flag hides input for privacy
# Append the new credentials to the file
echo "https://$g_username:$g_token@$g_domain" >>"$CREDENTIALS_FILE"
echo "Credentials added for $g_domain in $CREDENTIALS_FILE"
git config --global credential.helper store
chmod 600 "$HOME/.git-credentials"
fi
}
gitDirSetup() {
cd /opt/docker || echo_error "could not cd /opt/docker"
if $_sudo ping -w2 10.255.255.1; then
local location="hl"
elif $_sudo ping -w2 10.69.69.2; then
location="vps"
fi
git init .
git branch -m main
if git remote add origin "https://git.k4li.de/homelab/${location}-$(hostname)"; then
git add .
git commit -m "Initial script commit"
git push -u origin main
else
echo_error 'Failed setting the git repo up with git remote add "$(hostname)" "https://git.k4li.de/homelab/${location}-$(hostname).git"'
fi
}
set_cronjob() {
# Configuration
CRON_COMMAND="/opt/scripts/hlpush.sh"
CRON_SCHEDULE="0 3,15 * * *"
CRON_LOG="./cronjobs.log"
CRON_ENTRY="$CRON_SCHEDULE $CRON_COMMAND >> $CRON_LOG 2>&1"
# Check for existing entry
EXISTING_ENTRIES=$(crontab -l 2>/dev/null)
# Add entry if not exists
if ! echo "$EXISTING_ENTRIES" | grep -qF "$CRON_ENTRY"; then
# Create temporary cron file
TMPFILE=$(mktemp)
# Preserve existing entries
[ -n "$EXISTING_ENTRIES" ] && echo "$EXISTING_ENTRIES" >"$TMPFILE"
# Add header and new entry
echo -e "\n# Daily 3AM/3PM job added $(date)" >>"$TMPFILE"
echo "$CRON_ENTRY" >>"$TMPFILE"
# Install new cron file
crontab "$TMPFILE"
rm -f "$TMPFILE"
echo_info "Success: Cronjob installed"
echo_note "Verify with: crontab -l"
else
echo_warning "Notice: Cronjob already exists"
exit 0
fi
}
if ! command_exists git; then
return 1
echo_error "You don't have git installed!"
fi
gitUserSetup
if [[ -d /opt/docker/ ]]; then
gitDirSetup
fi
if [[ -d /opt/scripts/bash ]]; then
set_cronjob
else
if command_exists curl; then
curl -o /opt/scripts/hlpush.sh https://git.k4li.de/scripts/bash/raw/branch/main/setup/hlpush.sh
fi
fi

207
bash/setup/tuiDots.sh Executable file
View file

@ -0,0 +1,207 @@
#!/bin/bash
# ─< ANSI color codes >───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─< Check if the user is root and set sudo variable if necessary >───────────────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
# Function to print colored text
print_color() {
printf "%b%s%b\n" "$1" "$2" "$NC"
}
# Function to return to the main menu
return_to_menu() {
echo_info "Returning to the main menu in 3 seconds..."
sleep 3
}
gitDir="$HOME/git/dotfiles"
dotRemote="https://git.k4li.de/dotfiles"
instRemote="https://git.k4li.de/scripts/sh/raw/branch/main/installs"
if [ ! -d "$gitDir" ]; then
print_color "$RED" "=== git dir created - $gitDir ==="
mkdir -p "$gitDir"
fi
d_="git curl"
for dependency in $d_; do
if ! command_exists "$dependency"; then
print_color "$RED" "You're missing some dependencies!"
print_color "$RED" "Install $dependency and start the script again"
exit 1
fi
done
# Function to display the menu
display_menu() {
clear
print_color "$BLUE" "=== Environment Setup Menu ==="
for i in "${!options[@]}"; do
if [[ $i -eq $selected ]]; then
print_color "$GREEN" "> ${options[$i]}"
else
echo " ${options[$i]}"
fi
done
}
# Function to handle dotfiles setup
nvimSetup() {
print_color "$YELLOW" "Setting up neovim..."
if [ ! -d "$HOME/.config/nvim" ]; then
echo_note "Installing into .config directly"
git clone --branch minimal --recurse-submodule --depth=1 "${dotRemote}/nvim.git" "$HOME/.config/nvim"
else
if [ -d "$gitDir/nvim" ]; then
cd "$gitDir/nvim" || {
echo_error "The given path - $gitDir/nvim - was not found!"
return 1
}
git pull --recurse-submodule
else
echo_note "Installing into $gitDir/nvim"
git clone --branch minimal --recurse-submodule --depth=1 "${dotRemote}/nvim.git" "$gitDir/nvim"
fi
fi
return_to_menu
}
# Function to handle CLI tool installation
nvimMinimalSetup() {
print_color "$YELLOW" "Setting up neovim minimal branch..."
if [ ! -d "$HOME/.config/nvim" ]; then
echo_note "Installing into .config directly"
git clone --branch minimal --recurse-submodule --depth=1 "${dotRemote}/nvim.git" "$HOME/.config/nvim"
else
if [ -d "$gitDir/nvim-minimal" ]; then
cd "$gitDir/nvim-minimal" || {
echo_error "The given path - $gitDir/nvim-minimal - was not found!"
return 1
}
git pull --recurse-submodule
else
echo_note "Installing into $gitDir/nvim-minimal"
git clone --branch minimal --recurse-submodule --depth=1 "${dotRemote}/nvim.git" "$gitDir/nvim-minimal"
fi
fi
return_to_menu
}
installStuff() {
echo_info "I want to install.."
read -r gitPackage </dev/tty
echo_note "Installing from $instRemote/$gitPackage"
curl -fsSL "${instRemote}/${gitPackage}.sh" | sh
return_to_menu
}
sudoOptions() {
if [[ -e /etc/sudoers ]]; then
echo "Defaults pwfeedback" | $_sudo tee -a /etc/sudoers
echo "Defaults insults" | $_sudo tee -a /etc/sudoers
else
echo_error "There is no /etc/sudoers file."
fi
return_to_menu
}
# Menu options
declare -a options=(
"Sudo-Options"
"neovim"
"neovim-minimal"
"Install.."
"Exit"
)
# Main menu loop
main_menu() {
local selected=0
local key=""
while true; do
display_menu
# Read a single character
read -rsn1 key
case $key in
q | Q)
exit 0
;;
A | k) # Up arrow or k
((selected--))
if [[ $selected -lt 0 ]]; then
selected=$((${#options[@]} - 1))
fi
;;
B | j) # Down arrow or j
((selected++))
if [[ $selected -ge ${#options[@]} ]]; then
selected=0
fi
;;
"" | l) # Enter key
case $selected in
0) sudoOptions ;;
1) nvimSetup ;;
2) nvimMinimalSetup ;;
3) installStuff ;;
4) exit 0 ;;
esac
;;
esac
done
}
# Start the main menu
check_root
main_menu </dev/tty

View file

@ -0,0 +1,86 @@
#!/bin/sh -e
LOG_FILE="/var/log/unattended-upgrades-check.log"
# Colors
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
run_checks() {
echo_info "Checking if unattended-upgrades is active..."
if command_exists unattended-upgrades; then
# if dpkg-query -W -f='${Status}' unattended-upgrades 2>/dev/null | grep -q "install ok installed"; then
echo_note "unattended-upgrades is already installed."
else
echo_warning "unattended-upgrades is not installed. Attempting to install..."
if command_exists apt-get; then
if apt-get update && apt-get install --assume-yes unattended-upgrades; then
echo_note "unattended-upgrades successfully installed."
else
echo_error "Failed to install unattended-upgrades. Exiting."
exit 1
fi
else
echo_error "apt is not available on this system. Exiting."
exit 1
fi
fi
# Enable unattended-upgrades
UNATTENDED_UPGRADES_FILE="/etc/apt/apt.conf.d/50unattended-upgrades"
if [ -f "$UNATTENDED_UPGRADES_FILE" ]; then
echo_info "Configuring unattended upgrades in $UNATTENDED_UPGRADES_FILE"
# Add or modify configurations as needed
# Example: $_sudo sed -i 's/old_value/new_value/' "$UNATTENDED_UPGRADES_FILE"
else
echo_error "Unattended upgrades file not found!"
fi
}
run_setup() {
if command_exists unattended-upgrades; then
systemctl enable --now unattended-upgrades || echo_error "Something went wrong! Could not setup the service/autostart"
fi
}
# Main script
main() {
echo_info "Starting unattended-upgrades check script..."
if [ "$(id -u)" -ne 0 ]; then
echo_error "This script must be run as root. Please run with sudo."
exit 1
fi
run_checks
run_setup && echo_note "Script completed successfully!"
}
main

157
bash/updates.sh Executable file
View file

@ -0,0 +1,157 @@
#!/bin/sh
# ─< ANSI color codes >───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─< Check if the user is root and set sudo variable if necessary >───────────────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
# ─< Distribution detection and installation >────────────────────────────────────────
get_packager() {
if [ -e /etc/os-release ]; then
echo_info "Detecting distribution..."
. /etc/os-release
# ─< Convert $ID and $ID_LIKE to lowercase >──────────────────────────────────────────────
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
case "$ID" in
ubuntu | pop) packager="apt" ;;
debian) packager="apt" ;;
fedora) packager="dnf" ;;
alpine) packager="apk" ;;
arch | manjaro | garuda | endeavour) packager="pacman" ;;
opensuse*) packager="zypper" ;;
*)
if [ "${ID_LIKE#*debian}" != "$ID_LIKE" ]; then
packager="apt"
elif [ "${ID_LIKE#*ubuntu}" != "$ID_LIKE" ]; then
packager="apt"
elif [ "${ID_LIKE#*arch}" != "$ID_LIKE" ]; then
packager="pacman"
elif [ "${ID_LIKE#*fedora}" != "$ID_LIKE" ]; then
packager="dnf"
elif [ "${ID_LIKE#*suse}" != "$ID_LIKE" ]; then
packager="zypper"
else
echo_error "Unsupported distribution: $ID"
exit 1
fi
;;
esac
else
echo_error "Unable to detect distribution. /etc/os-release not found."
exit 1
fi
}
_update() {
case "$packager" in
apt)
if command_exists nala; then
echo_note "Using nala to update packages.. Please be patient.."
sleep 1
$_sudo nala update
$_sudo nala upgrade -y
$_sudo nala autoremove -y
$_sudo apt-get autoclean -y
else
echo_note "Using nala to update packages.. Please be patient.."
sleep 1
$_sudo apt-get update
$_sudo apt-get upgrade -y
$_sudo apt-get autoremove -y
$_sudo apt-get autoclean -y
fi
;;
dnf)
echo_note "Using dnf to update packages.. Please be patient.."
sleep 1
$_sudo dnf update
;;
pacman)
echo_note "Using pacman to update packages.. Please be patient.."
sleep 1
$_sudo pacman -Syu --noconfirm
;;
apk)
echo_note "Using apk to update packages.. Please be patient.."
sleep 1
$_sudo apk update
$_sudo apk upgrade
;;
zypper)
echo_note "Using zypper to update packages.. Please be patient.."
sleep 1
$_sudo zypper dup
;;
*)
if [ -z "$packager" ]; then
echo_error "The packager variable is not declared.."
else
echo_error "$packager is not a known packager.."
fi
;;
esac
}
_flatpak() {
if command_exists flatpak; then
echo_info "Trying to update flatpaks.."
sleep 1
flatpak update
else
echo_note "No flatpaks found"
fi
}
main() {
check_root
sleep 1
if get_packager; then
_update
_flatpak
fi
}
main

105
installs/README.md Normal file
View file

@ -0,0 +1,105 @@
## sh
# 🛠️ **Script Collection**
> [!TIP]
> Feel free to use and modify these scripts to suit your needs!
---
## 🚀 **Quick Start**
Clone the repository and start using the scripts:
```bash
git clone https://git.k4li.de/scripts/sh.git scripts && cd scripts
```
Or run individual scripts directly:
```bash
curl -fsSL <URL> | sh
```
---
## 📁 **Utility Scripts**
- **🔑 `ssh-keyperm.sh`**
Fixes permissions for `.ssh/` keys.
```bash
curl -fsSL https://git.k4li.de/pika/scripts/raw/branch/main/bash/snippets/ssh-keyperm.sh | sh
```
- **👽️ `updates.sh`**
Updates system packages + flatpaks.
```bash
curl -sSL https://git.k4li.de/pika/scripts/raw/branch/main/bash/setups/updates.sh | sh
```
- **🚀 `postinstall.sh`**
Sets up basic post-install tasks.
```bash
curl -sSL https://git.k4li.de/pika/scripts/raw/branch/main/bash/setup/postinstall.sh | sh -s -- -- <flag>
```
| **Available Flag** | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --install-base | Installs base packages like zsh and tmux, zoxide and trash etc. |
| --optimize-os | Currently only supported by apt based systems. Installs nala and fetches best mirrors. Equivalent options might be made in the future for other packagemanagers. |
> [!TIP]
> You can run all options together, with the `all` flag.
>
> ```bash
> curl -sSL https://git.k4li.de/scripts/sh/raw/branch/main/setup/postinstall.sh | sh -s -- --all
> ```
---
## 📦 **Install Scripts**
- **🐋 `docker.sh`**
Installs Docker (Debian, Ubuntu, Fedora).
```bash
curl -sSL https://git.k4li.de/scripts/sh/raw/branch/main/installs/docker.sh | sh
```
- **`neovim.sh`**
Installs Neovim 10.0+ (Debian, Ubuntu, Fedora).
```bash
curl -sSL https://git.k4li.de/scripts/sh/raw/branch/main/installs/neovim.sh | sh
```
- **🎨 `neovide.sh`**
Installs Neovide with Cargo (includes Cargo setup).
```bash
curl -sSL https://git.k4li.de/scripts/sh/raw/branch/main/installs/neovide.sh | sh
```
- **⚡️`xmrig.sh`**
Installs xmrig in `$HOME/.bin/xmrig/`.
```bash
curl -sSL https://git.k4li.de/scripts/sh/raw/branch/main/installs/xmrig.sh | sh
```
- **🗃️ `yazi.sh`**
Installs [yazi](https://github.com/sxyazi/yazi) with Cargo.
```bash
curl -fsSL https://git.k4li.de/scripts/sh/raw/branch/main/installs/yazi.sh | sh
```
---
## 📚 **Browse More**
Explore additional scripts in the repository. Modify them or use them as-is to streamline your workflow!
---

180
installs/docker.sh Executable file
View file

@ -0,0 +1,180 @@
#!/bin/sh -e
# ─< ANSI color codes >───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
check_sudo() {
# check for $su
if [ "$USER" != "root" ]; then
if command -v sudo >/dev/null 2>&1; then
su="sudo"
else
echo "Are you sure you can handle this? You're not root and sudo cannot be found.. [y/n]"
read -r sud </dev/tty
case $sud in
[Yy]) echo "All right, if anything breaks, it's on you" ;;
[Nn])
echo "All right, you're good. Try to install 'sudo'"
exit 1
;;
*)
echo "Invalid choice. Exiting."
exit 1
;;
esac
su=""
fi
else
su=""
fi
echo "--- check_sudo done --- echo '$su' |"
}
# ─< Distribution detection and installation >────────────────────────────────────────
check_dist() {
if [ -e /etc/os-release ]; then
echo_info "Detecting distribution..."
. /etc/os-release
# ─< Convert $ID and $ID_LIKE to lowercase >──────────────────────────────────────────────
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
case "$ID" in
ubuntu | pop) _ubuntu ;;
debian) _debian ;;
fedora) _fedora ;;
# alpine) _alpine ;;
arch | manjaro | garuda | endeavour) _arch ;;
opensuse*) inst_opensuse ;;
*)
if [ "${ID_LIKE#*debian}" != "$ID_LIKE" ]; then
_debian
elif [ "${ID_LIKE#*ubuntu}" != "$ID_LIKE" ]; then
_ubuntu
elif [ "${ID_LIKE#*arch}" != "$ID_LIKE" ]; then
_arch
elif [ "${ID_LIKE#*fedora}" != "$ID_LIKE" ]; then
_fedora
# elif [ "${ID_LIKE#*suse}" != "$ID_LIKE" ]; then
# _opensuse
else
echo_error "Unsupported distribution: $ID"
exit 1
fi
;;
esac
else
echo_error "Unable to detect distribution. /etc/os-release not found."
exit 1
fi
}
_debian() {
clear
echo_info "executing debian"
sleep 2
$su apt-get update &&
$su apt-get install -y ca-certificates curl &&
$su install -m 0755 -d /etc/apt/keyrings &&
$su curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc &&
$su chmod a+r /etc/apt/keyrings/docker.asc &&
sleep 0.5
if [ "$VERSION_CODENAME" == "trixie" ]; then
VERSION_CODENAME="bookworm"
fi
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | $su tee /etc/apt/sources.list.d/docker.list >/dev/null
clear &&
echo_info "Addet repository. Updating and installing now.."
sleep 1
$su apt-get update
$su apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
}
_ubuntu() {
clear
echo_info "executing ubuntu"
sleep 2
$su apt-get update &&
$su apt-get install -y ca-certificates curl &&
$su install -m 0755 -d /etc/apt/keyrings &&
$su curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc &&
$su chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | $su tee /etc/apt/sources.list.d/docker.list >/dev/null
clear &&
echo_info "Addet repository. Updating and installing now.."
sleep 0.5
$su apt-get update
$su apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
}
_fedora() {
clear
echo_info "executing fedora"
sleep 2
$su dnf -y install dnf-plugins-core
$su dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
$su dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
}
_arch() {
clear
echo_info "executing arch"
sleep 2
$su pacman -S docker docker-compose --noconfirm
}
init_docker() {
if command -v docker >/dev/null 2>&1; then
echo_info "Docker was installed correctly. Do you want to add $(whoami) to the docker group? (y/n)"
read -r dgroup </dev/tty
case "$dgroup" in
[Yy])
$su usermod -aG docker "$(whoami)"
;;
esac
sleep 1
$su systemctl enable --now docker
echo_info "$(whoami) is now part of the docker group. Restart your session to enable the changes. Also docker was addet as a service. Should autostart from now on."
else
echo_error "Something went wrong!"
fi
}
main() {
if check_sudo; then
# if check_dist; then
# init_docker
# else
# echo_error "No distro found.. At least thats what the error says.."
# fi
check_dist && init_docker
else
echo_error "Sudo check was failing hard..!"
fi
}
main </dev/tty

152
installs/flatpak.sh Executable file
View file

@ -0,0 +1,152 @@
#!/bin/sh -e
# ANSI color codes
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ─< Silent execution >─────────────────────────────────────────────────────────────────
silentexec() {
"$@" >/dev/null 2>&1
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# Check if the user is root and set sudo variable if necessary
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_note "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_note "Root access confirmed."
_sudo=""
fi
}
flatpak_init() {
if command_exists flatpak; then
echo_info "Flatpak exists, initializing flathub repository!"
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
else
echo_error "Flatpak was not found!"
fi
}
inst_arch() {
echo_note "Using Arch script, btw!"
if command_exists yay; then
i_arch="yay"
elif command_exists paru; then
i_arch="paru"
elif command_exists pacman; then
i_arch="$_sudo pacman"
fi
if [ -n "$i_arch" ]; then
i_arch -S flatpak
else
echo_error "No packager for installation found.. (not even pacman...)"
fi
}
inst_debian() {
echo_note "Using Debian script!"
if command_exists nala; then
$_sudo nala update
$_sudo nala install flatpak -y
elif command_exists apt-get; then
echo_info "Couldn't find nala, falling back to apt-get"
$_sudo apt-get update
$_sudo apt-get install flatpak -y
fi
}
inst_ubuntu() {
echo_note "Using Ubuntu script!"
if command_exists nala; then
$_sudo nala update
$_sudo nala install flatpak -y
elif command_exists apt-get; then
echo_info "Couldn't find nala, falling back to apt-get"
$_sudo apt-get update
$_sudo apt-get install flatpak -y
fi
}
# ─< Distribution detection and installation >────────────────────────────────────────
get_packager() {
if [ -e /etc/os-release ]; then
echo_info "Detecting distribution..."
. /etc/os-release
# Convert $ID and $ID_LIKE to lowercase
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
case "$ID" in
ubuntu | pop) inst_ubuntu ;;
debian) inst_debian ;;
fedora) inst_fedora ;;
alpine) inst_alpine ;;
arch | manjaro | garuda | endeavour) inst_arch ;;
opensuse*) inst_opensuse ;;
*)
# Use standard [ ] syntax for string matching
if [ "${ID_LIKE#*debian}" != "$ID_LIKE" ]; then
inst_debian
elif [ "${ID_LIKE#*ubuntu}" != "$ID_LIKE" ]; then
inst_ubuntu
elif [ "${ID_LIKE#*arch}" != "$ID_LIKE" ]; then
inst_arch
elif [ "${ID_LIKE#*fedora}" != "$ID_LIKE" ]; then
inst_fedora
elif [ "${ID_LIKE#*suse}" != "$ID_LIKE" ]; then
inst_opensuse
else
echo_error "Unsupported distribution: $ID"
exit 1
fi
;;
esac
else
echo_error "Unable to detect distribution. /etc/os-release not found."
exit 1
fi
}
install_flatpak() {
check_root &&
get_packager &&
flatpak_init
}
install_flatpak

310
installs/ghostty.sh Normal file
View file

@ -0,0 +1,310 @@
#!/bin/sh
# ╭───────────────╮
# │ env functions │
# ╰───────────────╯
# ───────────────────────────────────< ANSI color codes >───────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─────────────< Check if the user is root and set sudo variable if necessary >─────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
# ──────────────────────< Check if the given command exists silently >──────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
_cd() {
cd "$1" || echo_error "Could not cd into $1!"
}
# ─< Distribution detection and installation >────────────────────────────────────────
# checks for variable dist={debian,ubuntu,fedora,arch,suse}
get_packager() {
if [ -e /etc/os-release ]; then
echo_info "Detecting distribution..."
. /etc/os-release
# ─< Convert $ID and $ID_LIKE to lowercase >──────────────────────────────────────────────
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
case "$ID" in
ubuntu | pop | linuxmint | elementary) dist="ubuntu" ;;
debian | kali | zorin | parrot | deepin | raspbian | devuan) dist="debian" ;;
fedora | nobara | rhel | centos) dist="fedora" ;;
arch | manjaro | garuda | endeavour | artix) dist="arch" ;;
opensuse*) dist="suse" ;;
*)
if [ "${ID_LIKE#*debian}" != "$ID_LIKE" ]; then
dist="debian"
echo_note "Detected Debian-based distribution"
elif [ "${ID_LIKE#*ubuntu}" != "$ID_LIKE" ]; then
dist="ubuntu"
echo_note "Detected Ubuntu-based distribution"
elif [ "${ID_LIKE#*arch}" != "$ID_LIKE" ]; then
dist="arch"
echo_note "Detected Arch-based distribution"
elif [ "${ID_LIKE#*fedora}" != "$ID_LIKE" ]; then
dist="fedora"
echo_note "Detected Fedora-based distribution"
elif [ "${ID_LIKE#*suse}" != "$ID_LIKE" ]; then
dist="suse"
echo_note "Detected SUSE-based distribution"
else
echo_error "Unsupported distribution: $ID"
echo_note "Please report this issue with your distribution details"
exit 1
fi
;;
esac
else
echo_error "Unable to detect distribution. /etc/os-release not found."
exit 1
fi
}
# ╭────────────────────────────────────╮
# │ insert your scripts/functions here │
# ╰────────────────────────────────────╯
# ─────────────────────────────────────< dependencies >─────────────────────────────────────
deps_common="git curl tar"
deps_arch="$deps_common gtk4 libadwaita"
deps_deb="$deps_common libgtk-4-dev libadwaita-1-dev"
deps_fedora="$deps_common gtk4-devel zig libadwaita-devel"
deps_suse="$deps_common gtk4-tools libadwaita-devel pkgconf-pkg-config zig"
checkDeps=""
checkDeps() {
get_packager
case "$dist" in
debian | ubuntu)
pkg="apt-get"
echo "Detected packagemanager ${RED}${pkg}"
echo_info "Updating sources.."
$_sudo apt-get update
echo_info "Checking dependencies now.."
sleep 3
for dep in $deps_deb; do
if ! command_exists $dep; then
echo_info "Installing $dep.."
$_sudo apt-get install "$dep" --assume-yes </dev/tty
fi
done
checkDeps="done"
;;
fedora)
pkg="dnf"
echo "Detected packagemanager ${RED}${pkg}"
echo_info "Updating sources.."
$_sudo dnf update
echo_info "Checking dependencies now.."
sleep 3
for dep in $deps_fedora; do
if ! command_exists $dep; then
echo_info "Installing $dep.."
$_sudo dnf install "$dep" </dev/tty
fi
done
checkDeps="done"
;;
suse)
pkg="zypper"
echo "Detected packagemanager ${RED}${pkg}"
echo_info "Updating sources.."
$_sudo zypper refresh
echo_info "Checking dependencies now.."
sleep 3
for dep in $deps_suse; do
if ! command_exists $dep; then
echo_info "Installing $dep.."
$_sudo zypper install "$dep" -y </dev/tty
fi
done
checkDeps="done"
;;
arch)
pkg="pacman"
echo "Detected packagemanager ${RED}${pkg}"
echo_info "Updating sources.."
$_sudo pacman -Syy
echo_info "Checking dependencies now.."
sleep 3
for dep in $deps_arch; do
if ! command_exists $dep; then
echo_info "Installing $dep.."
$_sudo pacman -S "$dep" --noconfirm </dev/tty
fi
done
checkDeps="done"
;;
*)
echo "Something went wrong with your Distribution ${RED}${dist}"
;;
esac
echo_note "Distributional dependence check complete"
}
checkZig() {
if ! command_exists zig; then
echo_warning "Zig was not found, trying to install it now.."
sleep 3
case "$dist" in
arch)
$_sudo pacman -S zig --noconfirm
;;
suse)
$_sudo zypper install zig
;;
*)
installZig
;;
esac
else
echo_note "Zig was already found on the system.."
fi
}
installZig() {
if ! command_exists curl; then
echo_error "Most basic things (like curl) are not there!"
echo_error "Aborting now!"
exit 1
fi
if [ -h /bin/zig ] && [ ! -x /bin/zig ]; then
echo_warning "Found zig at /bin/zig, removing it now.."
$_sudo rm -rf /bin/zig
fi
# zigDir=$(mktemp -d)
zigDir="$HOME/.local/zig"
if [ ! -d $zigDir ]; then
echo_note "Zig build directory getting setup.."
mkdir $zigDir
fi
cd "$zigDir" || echo_error "$zigDir is not a valid directory!"
echo_info "Downloading zig 13.0.. This could take a while.."
curl -fsSL https://ziglang.org/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz -o zig.tar.xz || echo_error "Could not download zig 13.0.."
echo_info "Uncompressing archive.."
sleep 1
tar -xf ./zig.tar.xz
echo_info "Linking zig for the installation.."
mv zig-* zig >/dev/null 2>&1
$_sudo ln -rs ./zig/zig /bin/zig
}
cloneGhostty() {
if [ ! "$checkDeps" = "done" ]; then
echo_error "Dependencies are not installed, aborting now!"
exit 1
fi
# buildDir=$(mktemp -d)
buildDir="$HOME/.local/ghostty-build"
if [ -d "$buildDir" ] && [ -n "$(ls -A "$buildDir")" ]; then
echo_warning "Ghostty build directory already exists at ${buildDir}, do you want to remove it? (y/n)"
read -r removeBuildDir </dev/tty
case "$removeBuildDir" in
[yY]) $_sudo rm -rf "$buildDir" ;;
*)
echo_error "Aborting now!"
exit 1
;;
esac
else
mkdir -p "$buildDir"
fi
echo_info "Cloning ghostty repository now.."
git clone https://github.com/ghostty-org/ghostty.git "$buildDir" || echo_error "Could not clone ghostty repository!"
_cd "$buildDir"
echo_info "Preparations are done!"
buildGhostty
}
buildGhostty() {
echo_info "Building ghostty now.."
zig build -p /usr -Doptimize=ReleaseFast
}
ErrorExit() {
echo_error "Fatal error!"
echo_error "${1}"
echo_error "Exiting now!"
exit 1
}
# ───────────────────────────────< main function to execute >───────────────────────────────
main() {
if check_root; then
checkDeps || ErrorExit "Step 1/3"
checkZig || ErrorExit "Step 2/3"
cloneGhostty || ErrorExit "Step 3/3"
else
echo_error "Something went terribly wrong!"
fi
}
main </dev/tty

632
installs/hyprland.sh Normal file
View file

@ -0,0 +1,632 @@
#!/bin/sh -e
# ╭───────────────╮
# │ env functions │
# ╰───────────────╯
# ───────────────────────────────────< ANSI color codes >───────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ─────────────< Check if the user is root and set sudo variable if necessary >─────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
# ──────────────────────< Check if the given command exists silently >──────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ╭────────────────────────────────────╮
# │ insert your scripts/functions here │
# ╰────────────────────────────────────╯
hyprSlim="hyprland hyprland-protocols hyprwayland-scanner libhyprcursor-dev wayland-utils wayland-protocols wl-clipboard nwg-look xdg-desktop-portal-hyprland liblz4"
hyprAdvanced="$menu pavucontrol pamixer btop bluez wlogout wob"
OPTIONAL_SCREENSHOT="grimshot slurp swappy"
OPTIONAL_SCREENRECORD="wf-recorder"
OPTIONAL_AUDIO="pulseaudio pavucontrol"
OPTIONAL_NOTIFY="sway-notification-center libnotify"
OPTIONAL_UTILS="brightnessctl network-manager-gnome gnome-keyring swayidle playerctl"
OPTIONAL_FILES="xdg-user-dirs nautilus gvfs"
OPTIONAL_SDDM_DEPS="qml6-module-qtquick-controls qml6-module-qtquick-effects sddm"
BUILD_DEPS="git gcc make cmake meson ninja-build pkg-config"
RUST_DEPS="cargo rustc" # Separate rust dependencies
askThings() {
echo_note "Do you want to install hyprland? (y/N)"
read -r askHyprland </dev/tty
case "$askHyprland" in
[yY]) askHyprland="true" ;;
*)
echo_error "Aborting now!"
exit 1
;;
esac
echo_note "What bar do you want to install? (available: [w]aybar, [h]yprpanel, [g]Bar)"
read -r askBar </dev/tty
case "$askBar" in
[Ww] | waybar)
bar="waybar"
;;
[Hh] | hyprpanel)
bar="hyprpanel"
;;
[Gg] | gBar | gbar)
bar="gBar"
;;
esac
echo_info "Set bar to $bar"
echo_note "Do you want to install [r]ofi or [t]ofi?: "
read -r askRofi </dev/tty
case "$askRofi" in
[tT] | tofi)
menu="tofi"
;;
[rR] | rofi)
menu="rofi"
;;
*)
menu="rofi"
;;
esac
echo_info "Set menu to $menu"
echo_note "Doy you want to install sddm with minimal dependency theme? [catppucchin-mocha] (Y/n) :"
read -r askSddm </dev/tty
case "$askSddm" in
[nN]) ;;
*)
hyprAdvanced="$hyprAdvanced $OPTIONAL_SDDM_DEPS"
sddm_minimal="true"
;;
esac
echo_info "Installing - $OPTIONAL_SDDM_DEPS - for sddm"
# Optional packages section
echo_note "Would you like to install screenshot tools ($OPTIONAL_SCREENSHOT)? (Y/n)"
read -r askScreenshot </dev/tty
case "$askScreenshot" in
[nN]) ;;
*) hyprAdvanced="$hyprAdvanced $OPTIONAL_SCREENSHOT" ;;
esac
echo_note "Would you like to install screen recording tools ($OPTIONAL_SCREENRECORD)? (Y/n)"
read -r askRecord </dev/tty
case "$askRecord" in
[nN]) ;;
*) hyprAdvanced="$hyprAdvanced $OPTIONAL_SCREENRECORD" ;;
esac
echo_note "Would you like to install audio tools ($OPTIONAL_AUDIO)? (Y/n)"
read -r askAudio </dev/tty
case "$askAudio" in
[nN]) ;;
*) hyprAdvanced="$hyprAdvanced $OPTIONAL_AUDIO" ;;
esac
echo_note "Would you like to install notification daemon ($OPTIONAL_NOTIFY)? (Y/n)"
read -r askNotify </dev/tty
case "$askNotify" in
[nN]) ;;
*) hyprAdvanced="$hyprAdvanced $OPTIONAL_NOTIFY" ;;
esac
echo_note "Would you like to install utility tools ($OPTIONAL_UTILS)? (Y/n)"
read -r askUtils </dev/tty
case "$askUtils" in
[nN]) ;;
*) hyprAdvanced="$hyprAdvanced $OPTIONAL_UTILS" ;;
esac
echo_note "Would you like to install additional file management tools ($OPTIONAL_FILES)? (Y/n)"
read -r askFiles </dev/tty
case "$askFiles" in
[nN]) ;;
*) hyprAdvanced="$hyprAdvanced $OPTIONAL_FILES" ;;
esac
}
buildBar() {
echo "..installing ${RED}${bar}${NC}"
case "$bar" in
waybar)
$_sudo $pkg install -y $bar </dev/tty
;;
gBar) ;;
hyprpanel) ;;
esac
}
instTools() {
case "$pkg" in
pacman)
aur="yay paru"
for i in $aur; do
if command_exists $i; then
echo "..using ${RED}$i${NC}"
pkgAur=$i
fi
done
if [ -z $pkgAur ]; then
echo_error "No aur helper present! You first have to install either yay or paru!"
exit 1
fi
if [ "$bar" = "hyprpanel" ]; then
if command_exists $pkgAur; then
echo_info "Installing hyprpanel..."
$pkgAur -S ags-hyprpanel-git --noconfirm </dev/tty
fi
elif [ "$bar" = "gBar" ]; then
if command_exists $pkgAur; then
echo_info "Installing gBar..."
$pkgAur -S gbar-git --noconfirm </dev/tty
fi
fi
;;
*)
buildBar
;;
esac
}
get_package_name() {
_package="$1"
case "$pkg" in
pacman)
echo_info "Getting package names..."
case "$_package" in
# Core/Slim
libhyprcursor-dev) echo "hyprcursor-git" ;;
xdg-desktop-portal-hyprland) echo "xdg-desktop-portal-hyprland" ;;
wayland-utils) echo "wayland-utils" ;;
nwg-look) echo "nwg-look-bin" ;;
# Advanced
btop) echo "btop" ;;
pamixer) echo "pamixer" ;;
wlogout) echo "wlogout" ;;
wob) echo "wob" ;;
# sddm
qml6-module-qtquick-*) echo "kirigami" ;;
# Screenshot
grim) echo "grim" ;;
slurp) echo "slurp" ;;
swappy) echo "swappy" ;;
# Screen recording
wf-recorder) echo "wf-recorder" ;;
# Audio
pipewire) echo "pipewire" ;;
wireplumber) echo "wireplumber" ;;
pipewire-alsa) echo "pipewire-alsa" ;;
pipewire-pulse) echo "pipewire-pulse" ;;
# Notification
sway-notification-center) echo "sway-notification-center" ;;
libnotify) echo "libnotify" ;;
# Utils
brightnessctl) echo "brightnessctl" ;;
network-manager-gnome) echo "network-manager-applet" ;;
gnome-keyring) echo "gnome-keyring" ;;
swayidle) echo "swayidle" ;;
playerctl) echo "playerctl" ;;
# Files
xdg-user-dirs) echo "xdg-user-dirs" ;;
gvfs) echo "gvfs" ;;
liblz4) echo "lz4" ;;
*) echo "$_package" ;;
esac
;;
apt-get)
case "$_package" in
# Core/Slim
hyprland) echo "hyprland" ;;
libhyprcursor-dev) echo "libhyprcursor-dev" ;;
nwg-look) echo "nwg-look" ;;
# Advanced
pamixer) echo "pamixer" ;;
wob) echo "wob" ;;
# sddm
qml6-module-qtquick-controls) echo "qml6-module-qtquick-controls" ;;
qml6-module-qtquick-effects) echo "qml6-module-qtquick-effects" ;;
# Screenshot
grim) echo "grim" ;;
slurp) echo "slurp" ;;
swappy) echo "swappy" ;;
# Screen recording
wf-recorder) echo "wf-recorder" ;;
# Audio
pipewire) echo "pipewire" ;;
wireplumber) echo "wireplumber" ;;
pipewire-alsa) echo "pipewire-alsa" ;;
pipewire-pulse) echo "pipewire-pulse" ;;
# Notification
sway-notification-center) echo "sway-notification-center" ;;
libnotify) echo "libnotify-bin" ;;
# Utils
brightnessctl) echo "brightnessctl" ;;
network-manager-gnome) echo "network-manager-gnome" ;;
gnome-keyring) echo "gnome-keyring" ;;
swayidle) echo "swayidle" ;;
playerctl) echo "playerctl" ;;
# Files
xdg-user-dirs) echo "xdg-user-dirs" ;;
gvfs) echo "gvfs" ;;
liblz4) echo "liblz4-dev" ;;
*) echo "$_package" ;;
esac
;;
dnf)
case "$_package" in
# Core/Slim
libhyprcursor-dev) echo "hyprcursor-devel" ;;
xdg-desktop-portal-hyprland) echo "xdg-desktop-portal-hyprland" ;;
nwg-look) echo "nwg-look" ;;
# Advanced
wlogout) echo "wlogout" ;;
# sddm
qml6-module-qtquick-controls) echo "qml6-module-qtquick-controls" ;;
qml6-module-qtquick-effects) echo "qml6-module-qtquick-effects" ;;
# Screenshot
grim) echo "grim" ;;
slurp) echo "slurp" ;;
swappy) echo "swappy" ;;
# Screen recording
wf-recorder) echo "wf-recorder" ;;
# Audio
pipewire) echo "pipewire" ;;
wireplumber) echo "wireplumber" ;;
pipewire-alsa) echo "pipewire-alsa" ;;
pipewire-pulse) echo "pipewire-pulseaudio" ;;
# Notification
sway-notification-center) echo "sway-notification-center" ;;
libnotify) echo "libnotify" ;;
# Utils
brightnessctl) echo "brightnessctl" ;;
network-manager-gnome) echo "nm-connection-editor" ;;
gnome-keyring) echo "gnome-keyring" ;;
swayidle) echo "swayidle" ;;
playerctl) echo "playerctl" ;;
# Files
xdg-user-dirs) echo "xdg-user-dirs" ;;
gvfs) echo "gvfs" ;;
liblz4) echo "lz4-devel" ;;
*) echo "$_package" ;;
esac
;;
zypper)
case "$_package" in
# Core/Slim
libhyprcursor-dev) echo "hyprcursor-devel" ;;
# Advanced
pamixer) echo "pamixer" ;;
wob) echo "wob" ;;
# sddm
qml6-module-qtquick-controls) echo "qml6-module-qtquick-control" ;;
qml6-module-qtquick-effects) echo "qml6-module-qtquick-effects" ;;
# Screenshot
grim) echo "grim" ;;
slurp) echo "slurp" ;;
swappy) echo "swappy" ;;
# Screen recording
wf-recorder) echo "wf-recorder" ;;
# Audio
pipewire) echo "pipewire" ;;
wireplumber) echo "wireplumber" ;;
pipewire-alsa) echo "pipewire-alsa" ;;
pipewire-pulse) echo "pipewire-pulseaudio" ;;
# Notification
sway-notification-center) echo "sway-notification-center" ;;
libnotify) echo "libnotify" ;;
# Utils
brightnessctl) echo "brightnessctl" ;;
network-manager-gnome) echo "NetworkManager-gnome" ;;
gnome-keyring) echo "gnome-keyring" ;;
swayidle) echo "swayidle" ;;
playerctl) echo "playerctl" ;;
# Files
xdg-user-dirs) echo "xdg-user-dirs" ;;
gvfs) echo "gvfs" ;;
liblz4) echo "liblz4-devel" ;;
*) echo "$_package" ;;
esac
;;
esac
}
# Add this function to check for Rust toolchain
check_rust() {
for tool in $RUST_DEPS; do
if ! command_exists "$tool"; then
case $pkg in
pacman)
echo_info "Updating package database..."
$_sudo pacman -Sy
echo_info "Installing Rust toolchain..."
$_sudo pacman -S rust cargo --noconfirm </dev/tty
;;
apt-get)
echo_info "Updating package database..."
$_sudo apt-get update
echo_info "Installing Rust toolchain..."
$_sudo apt-get install rustc cargo -y </dev/tty
;;
dnf)
echo_info "Updating package database..."
$_sudo dnf install rust cargo -y </dev/tty
;;
zypper)
echo_info "Updating package database..."
$_sudo zypper install rust cargo -y </dev/tty
;;
esac
return $?
fi
done
return 0
}
# Modify build_swww to check for Rust first
build_swww() {
echo_info "Building swww from source..."
# Check for Rust toolchain
if ! check_rust; then
echo_error "Failed to install Rust toolchain"
failed_builds="$failed_builds swww"
return 1
fi
# Store current directory
current_dir=$(pwd)
# Create temporary build directory
build_dir=$(mktemp -d)
trap "$_sudo rm -rf $build_dir" EXIT
cd "$build_dir" || exit 1
# Clone and build swww
if git clone https://github.com/Horus645/swww.git; then
cd swww || exit 1
if cargo build --release; then
echo_info "Installing swww..."
$_sudo cp target/release/swww /usr/local/bin/
$_sudo cp target/release/swww-daemon /usr/local/bin/
echo_note "swww installed successfully!"
else
echo_error "Failed to build swww"
failed_builds="$failed_builds swww"
fi
else
echo_error "Failed to clone swww repository"
failed_builds="$failed_builds swww"
fi
# Cleanup and return to original directory
cd "$current_dir" || exit 1
rm -rf "$build_dir"
}
# Modify instDeps() to use the new check_rust function
instDeps() {
pkgManager="apt-get pacman dnf zypper"
for i in $pkgManager; do
if command_exists $i; then
echo "..using ${RED}$i${NC}"
pkg=$i
fi
done
# First install build dependencies if we need to build swww
if ! command_exists swww; then
echo_info "Installing build dependencies for swww..."
case $pkg in
pacman)
echo_info "Updating package database..."
$_sudo pacman -Sy
echo_info "Installing build dependencies..."
$_sudo pacman -S $BUILD_DEPS --noconfirm </dev/tty
echo_info "Installing swww..."
$_sudo pacman -S swww -y </dev/tty
;;
apt-get | dnf)
echo_info "Updating package database..."
$_sudo $pkg update
echo_info "Installing build dependencies..."
$_sudo $pkg install $BUILD_DEPS -y </dev/tty
build_swww
;;
zypper)
echo_info "Updating package database..."
$_sudo zypper install $BUILD_DEPS -y </dev/tty
echo_info "Installing swww..."
$_sudo zypper install swww -y </dev/tty
;;
esac
fi
# Continue with normal package installation
transformed_deps=""
for dep in $deps; do
transformed_deps="$transformed_deps $(get_package_name "$dep")"
done
deps="$transformed_deps"
echo_info "Installing dependencies..."
case $pkg in
pacman)
if [ "$sddm_minimal" = "true" ]; then
$_sudo pacman -S sddm --noconfirm </dev/tty
fi
for d in $deps; do
if ! command_exists "$d"; then
$_sudo pacman -S "$d" --noconfirm </dev/tty
fi
done
# $_sudo pacman -S $deps --noconfirm </dev/tty
;;
apt-get)
if [ "$sddm_minimal" = "true" ]; then
$_sudo "$pkg" install sddm --no-install-recommends </dev/tty
fi
for d in $deps; do
if ! command_exists "$d"; then
$_sudo $pkg install "$d" --assume-yes </dev/tty
fi
done
;;
*)
for d in $deps; do
if ! command_exists "$d"; then
$_sudo $pkg install "$d" -y </dev/tty
fi
done
;;
esac
}
checkDependencies() {
deps=""
cd="$hyprSlim $hyprAdvanced"
for f in $cd; do
if ! command_exists $f; then
deps="$deps $f"
fi
done
}
cloneDotfiles() {
echo_info "Which dotfiles do you want to clone? ([p]ika's config, or just type the link to your own repo)"
read -r askDotfiles2 </dev/tty
case "$askDotfiles2" in
[pP])
echo_info "Cloning pika's config..."
git clone --recursive --depth=1 https://git.k4li.de/dotfiles/hyprdots.git $HOME/git/hyprdots || echo_error "Failed to clone dotfiles!" && exit 1
cd $HOME/git/hyprdots || echo_error "Failed to clone dotfiles!" && exit 1
echo_info "Installing dotfiles..."
make </dev/tty || echo_error "Failed to install dotfiles!" && exit 1
echo_info "Dotfiles installed successfully!"
;;
*)
echo_info "Cloning dotfiles from $askDotfiles2..."
git clone --recursive --depth=1 $askDotfiles2 $HOME/git/hyprdots
cd $HOME/git/hyprdots || echo_error "Failed to clone dotfiles!" && exit 1
echo_info "Your dotfiles have been saved to $HOME/git/hyprdots"
echo_info "You can now install your dotfiles how you want to!"
;;
esac
}
checkConfig() {
dirs="hypr $menu $bar"
for i in $dirs; do
if [ ! -d "$HOME/.config/$i" ]; then
echo_warning "Config directory $i not found!"
echo_note "Do you want to clone some dotfiles? (y/N)"
read -r askDotfiles </dev/tty
case "$askDotfiles" in
[yY])
echo_info "Cloning dotfiles..."
cloneDotfiles
;;
[nN])
echo_note "Skipping dotfiles installation..."
;;
esac
fi
done
}
# ───────────────────────────────< main function to execute >───────────────────────────────
main() {
if check_root; then
askThings
if [ "$askHyprland" = "true" ]; then
checkDependencies
instDeps
instTools
checkConfig
fi
else
echo_error "Something went terribly wrong!"
fi
}
main

97
installs/hyprpanel.sh Normal file
View file

@ -0,0 +1,97 @@
#!/bin/sh -c
# ─< ANSI color codes >───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─< Check if the user is root and set sudo variable if necessary >───────────────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
inst_arch() {
dependencies="aylurs-gtk-shell grimblast hyprpicker"
if command_exists curl; then
if [ ! -d "$HOME/.bun" ]; then
echo_info "Downloading bun and linking it.."
curl -fsSL https://bun.sh/install | bash && $_sudo ln -s $HOME/.bun/bin/bun /usr/local/bin/bun
else
echo_note "Bun is already installed"
fi
$_sudo pacman -S pipewire libgtop bluez bluez-utils btop networkmanager dart-sass wl-clipboard brightnessctl swww python gnome-bluetooth-3.0 pacman-contrib power-profiles-daemon gvfs --noconfirm
if command_exists yay; then
echo_info "Using yay to install $dependencies"
yay -S --noconfirm $dependencies
elif command_exists paru; then
echo_info "Using paru to install $dependencies"
paru -S --noconfirm $dependencies
else
echo_error "No aur helper found.. Cannot continue!"
exit 1
fi
else
echo_warning "No curl was found, cannot continue!"
exit 1
fi
}
clone_to_ags() {
if [ ! -d "$HOME/.config/ags" ]; then
if command_exists git; then
git clone --depth=1 https://github.com/Jas-SinghFSU/HyprPanel "$HOME/.config/ags"
else
echo_error "There was no git found, cannot continue!"
exit 1
fi
else
echo_note "ags is already present, try running 'ags' in your terminal"
fi
}
main() {
if check_root; then
inst_arch
clone_to_ags
fi
}
main

71
installs/install-blesh.sh Executable file
View file

@ -0,0 +1,71 @@
{
#!/bin/bash
# ─< Helper functions >─────────────────────────────────────────────────────────────────
echo_error() { echo -e "\033[0;1;31mError: \033[0;31m\t${*}\033[0m"; }
echo_binfo() { echo -e "\033[0;1;34mINFO:\033[0;34m\t${*}\033[0m"; }
echo_info() { echo -e "\033[0;1;35mInfo: \033[0;35m${*}\033[0m"; }
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─< Check root and set sudo variable if necessary >───────────────────────────────────────────────
check_root() {
if [[ "${EUID}" -ne 0 ]]; then
if command_exists sudo; then
echo_binfo "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_binfo "Root access confirmed."
_sudo=""
fi
}
install_pkg() {
bash -c "$(curl -sSL https://git.k4li.de/pika/scripts/raw/branch/main/bash/snippets/install_pkg.sh)" -- "$@"
}
i_blesh() {
dir="$(mktemp -d)"
local deps=("bash" "git" "make" "gawk")
for pkg in "${deps[@]}"; do
if ! command_exists "$pkg"; then
install_pkg "$pkg"
fi
done &&
git clone --recursive --depth 1 --shallow-submodules https://github.com/akinomyoga/ble.sh.git "$dir" &&
make -C "$dir" install PREFIX=$HOME/.local
}
cleanup() {
echo_info "Do you want to clear the temp dir ($dir/) which was created for installation? [Y|n]" && read -r ask_dir
case "$ask_dir" in
[Nn])
echo_info "All right, didn't clean anything!"
;;
[Yy] | *)
$_sudo command rm -rf "$dir/"
;;
esac
}
main() {
# Check root access and set _sudo
if ! check_root; then
return 1
fi
if [[ ! -f $HOME/.local/share/blesh/ble.sh ]]; then
i_blesh
cleanup
else
echo_info "Blesh is already installed"
fi
}
main
}

131
installs/neovide.sh Executable file
View file

@ -0,0 +1,131 @@
#!/bin/sh
# ─< ANSI color codes >───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ─< check if command exists silently >───────────────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─< Silent execution >─────────────────────────────────────────────────────────────────
silentexec() {
"$@" >/dev/null 2>&1
}
# ─< Check if the user is root and set _sudo variable if necessary >───────────────────────
checkRoot() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
installNeovide() {
if ! command_exists cargo; then
curl --proto '=https' --tlsv1.2 -sSf "https://sh.rustup.rs" | sh
"$HOME/.cargo/bin/cargo" install --git https://github.com/neovide/neovide
else
cargo install --git https://github.com/neovide/neovide
fi
if [ -e "$HOME/.cargo/bin/neovide" ]; then
$_sudo ln -rs "$HOME/.cargo/bin/neovide" /bin/neovide
fi
}
i_arch() {
deps="base-devel fontconfig freetype2 libglvnd sndio cmake git gtk3 python sdl2 vulkan-intel libxkbcommon-x11"
$_sudo pacman -Sy
for dep in $deps; do
if ! command_exists $dep; then
silentexec $_sudo pacman --noconfirm -S "$dep" || echo_error "Couldn't install $dep"
fi
done
}
i_debian() {
$_sudo apt-get update
deps="curl gnupg ca-certificates git gcc-multilib g++-multilib cmake libssl-dev pkg-config libfreetype6-dev libasound2-dev libexpat1-dev libxcb-composite0-dev libbz2-dev libsndio-dev freeglut3-dev libxmu-dev libxi-dev libfontconfig1-dev libxcursor-dev"
for dep in $deps; do
if ! command_exists $dep; then
silentexec $_sudo apt-get install --assume-yes "$dep" || echo_error "Couldn't install $dep"
fi
done
}
i_fedora() {
deps="fontconfig-devel freetype-devel libX11-xcb libX11-devel libstdc++-static libstdc++-devel"
$_sudo dnf update
for dep in $deps; do
if ! command_exists $dep; then
silentexec $_sudo dnf install "$dep" || echo_error "Couldn't install $dep"
fi
done
$_sudo dnf groupinstall "Development Tools" "Development Libraries"
$_sudo dnf install dnf-plugins-core
}
checkDistrosAndDependencies() {
if [ -f /etc/os-release ]; then
echo_info "Sourcing /etc/os-release to determine the distribution..."
. /etc/os-release
case "$ID" in
debian | ubuntu | kali | linuxmint | pop | elementary | zorin | kubuntu | neon | kdeneon | deepin | linuxlite | linuxmintdebian | linuxmintubuntu | linuxmintkali | linuxmintpop | linuxmintelementary | linuxmintzorin | linuxmintkubuntu | linuxmintneon | linuxmintkdeneon | linuxmintdeepin | linuxmintlinuxlite) i_debian ;;
arch | manjaro | endeavouros) i_arch ;;
fedora | centos | rhel | rocky | almalinux) i_fedora ;;
*)
case "$ID_LIKE" in
*debian*) i_debian ;;
*arch*) i_arch ;;
*fedora*) i_fedora ;;
*)
echo_error "Unsupported distribution: $ID"
exit 1
;;
esac
;;
esac
else
echo_error "No os-release file found under /etc/. Exiting now!"
exit 1
fi
}
main() {
if checkRoot; then
checkDistrosAndDependencies && installNeovide
fi
}
main

223
installs/neovim.sh Executable file
View file

@ -0,0 +1,223 @@
{
#!/bin/sh -e
# ANSI color codes
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# Check if the user is root and set sudo variable if necessary
check_root() {
if [ "$(id -u)" -ne 0 ]; then
echo_note "checked $(id -u)"
if command_exists sudo; then
echo_note "Checking sudo"
echo_warning "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
if [ -n "$_sudo" ]; then
echo_info "--- check_root done --- echo '$_sudo' |"
else
echo_warning "sudo variable is empty: $_sudo"
fi
}
# ─< Dependencies >─────────────────────────────────────────────────────────────────────
deps="git cargo meson luarocks pipx curl ripgrep make composer npm gcc g++ unzip zip"
# ─< Distribution-specific installation functions >─────────────────────────────────────
inst_ubuntu() {
$_sudo apt-get update
for _deps in $deps; do
$_sudo apt-get install -y "$_deps" </dev/tty
done
inst_generic
}
inst_debian() {
$_sudo apt-get update
for _deps in $deps; do
$_sudo apt-get install -y "$_deps" </dev/tty
done
inst_generic
}
inst_fedora() {
$_sudo dnf update </dev/tty
for _deps in $deps; do
$_sudo dnf install -y "$_deps" </dev/tty
done
$_sudo dnf install -y neovim
}
inst_arch() {
$_sudo pacman -Syu --noconfirm
for _deps in $deps; do
$_sudo pacman -S --noconfirm "$_deps"
done
$_sudo pacman -S --noconfirm --needet neovim
}
inst_opensuse() {
$_sudo zypper refresh
for _deps in $deps; do
$_sudo zypper in "$_deps"
done
$_sudo zypper in neovim
}
inst_alpine() {
$_sudo apk update
for _deps in $deps; do
$_sudo apk add "$_deps"
done
$_sudo apk add neovim
}
echo_info "Fetching latest stable Neovim version..."
latest_version=$(curl -s https://api.github.com/repos/neovim/neovim/releases/latest | grep 'tag_name' | cut -d\" -f4)
inst_generic() {
tempdir="$(mktemp -d)"
if [ ! -d "$HOME/.bin" ]; then
mkdir -p "$HOME/.bin"
fi
echo_info "Downloading Neovim version $latest_version..."
# Determine architecture
arch=$(uname -m)
if [ "$arch" = "aarch64" ] || [ "$arch" = "armv7l" ]; then
nvim_tarball="nvim-linux-arm64.tar.gz"
else
nvim_tarball="nvim-linux-x86_64.tar.gz"
fi
# Download the tarball
curl -fsSL -o "$tempdir/nvim.tar.gz" "https://github.com/neovim/neovim/releases/download/${latest_version}/${nvim_tarball}"
# Change to the temporary directory and extract
cd "$tempdir"
tar -xzf nvim.tar.gz
# Remove old installation if it exists
rm -rf "$HOME/.bin/nvim-linux-x86_64" "$HOME/.bin/nvim-linux-arm64"
# Copy to destination
cp -r ./nvim-linux-* "$HOME/.bin/"
# Create symlinks with absolute paths
inst_paths="/usr/bin /usr/share/bin $HOME/.local/bin"
for in_path in $inst_paths; do
if [ -d "$in_path" ]; then
echo_info "Installing into $in_path"
$_sudo ln -sf "$HOME/.bin/nvim-linux-*/bin/nvim" "$in_path/nvim"
fi
done
# Clean up
rm -rf "$tempdir"
echo_info "Neovim $latest_version installed successfully"
}
checkVersion() {
currentVersion="$(nvim --version | head -n1 | awk '{print $2}')"
}
# ─< Distribution detection and installation >────────────────────────────────────────
get_packager() {
if [ -e /etc/os-release ]; then
echo_info "Detecting distribution..."
. /etc/os-release
# Convert $ID and $ID_LIKE to lowercase
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
case "$ID" in
ubuntu | pop) inst_ubuntu ;;
debian) inst_debian ;;
fedora) inst_fedora ;;
alpine) inst_alpine ;;
arch | manjaro | garuda | endeavour) inst_arch ;;
opensuse*) inst_opensuse ;;
*)
if [ "${ID_LIKE#*debian}" != "$ID_LIKE" ]; then
inst_debian
elif [ "${ID_LIKE#*ubuntu}" != "$ID_LIKE" ]; then
inst_ubuntu
elif [ "${ID_LIKE#*arch}" != "$ID_LIKE" ]; then
inst_arch
elif [ "${ID_LIKE#*fedora}" != "$ID_LIKE" ]; then
inst_fedora
elif [ "${ID_LIKE#*suse}" != "$ID_LIKE" ]; then
inst_opensuse
else
echo_error "Unsupported distribution: $ID"
exit 1
fi
;;
esac
else
echo_error "Unable to detect distribution. /etc/os-release not found."
exit 1
fi
}
# ─< Main function >─────────────────────────────────────────────────────────────────
main() {
if command_exists nvim; then
checkVersion
if [ "$(printf '%s\n' "$latest_version" "$currentVersion" | sort -V | head -n1)" = "$latest_version" ]; then
echo_warning "Neovim is already installed in version: $currentVersion"
echo_error "Exiting now!"
exit 0
fi
fi
echo_info "Starting Neovim installation script..."
get_packager
if command -v nvim >/dev/null 2>&1; then
echo_note "Neovim has been successfully installed!"
echo_info "Neovim version: $(nvim --version | head -n1)"
else
echo_error "Neovim installation failed."
exit 1
fi
}
# ─< Script execution >─────────────────────────────────────────────────────────────
check_root && main
}

208
installs/virt-manager.sh Executable file
View file

@ -0,0 +1,208 @@
#!/bin/sh
# ─< ANSI color codes >───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m'
# ─< Initialize storage variables >───────────────────────────────────────────────────────
_STORED_ERRORS=""
_STORED_WARNINGS=""
_STORED_INFOS=""
_STORED_NOTES=""
# ─< echo functions that store and display messages >────────────────────────────
echo_error() {
message="${RED}$1${NC}\n"
printf "$message" >&2
_STORED_ERRORS="${_STORED_ERRORS}${message}"
}
echo_warning() {
message="${YELLOW}$1${NC}\n"
printf "$message"
_STORED_WARNINGS="${_STORED_WARNINGS}${message}"
}
echo_info() {
message="${CYAN}$1${NC}\n"
printf "$message"
_STORED_INFOS="${_STORED_INFOS}${message}"
}
echo_note() {
message="${LIGHT_GREEN}$1${NC}\n"
printf "$message"
_STORED_NOTES="${_STORED_NOTES}${message}"
}
# ─< Improved display function that only shows categories with content >──────────────────
display_stored_messages() {
has_messages=0
# ─< First check if we have any messages at all >─────────────────────────────────────────
if [ -z "$_STORED_ERRORS" ] && [ -z "$_STORED_WARNINGS" ] && [ -z "$_STORED_INFOS" ] && [ -z "$_STORED_NOTES" ]; then
return 0
fi
# ─< Now display each non-empty category with proper spacing >────────────────────────────
if [ -n "$_STORED_ERRORS" ]; then
printf "\n${BOLD}${RED}=== Errors ===${NC}\n"
printf "$_STORED_ERRORS"
has_messages=1
fi
if [ -n "$_STORED_WARNINGS" ]; then
[ "$has_messages" -eq 1 ] && printf "\n"
printf "${BOLD}${YELLOW}=== Warnings ===${NC}\n"
printf "$_STORED_WARNINGS"
has_messages=1
fi
if [ -n "$_STORED_INFOS" ]; then
[ "$has_messages" -eq 1 ] && printf "\n"
printf "${BOLD}${CYAN}=== Info ===${NC}\n"
printf "$_STORED_INFOS"
has_messages=1
fi
if [ -n "$_STORED_NOTES" ]; then
[ "$has_messages" -eq 1 ] && printf "\n"
printf "${BOLD}${LIGHT_GREEN}=== Notes ===${NC}\n"
printf "$_STORED_NOTES"
fi
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─< Check if the user is root and set $_sudo variable if necessary >───────────────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_binfo "User is not root. Using $_sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_binfo "Root access confirmed."
_sudo=""
fi
}
# ─< Distribution detection and installation >────────────────────────────────────────
get_packager() {
if [ -e /etc/os-release ]; then
echo_info "Detecting distribution..."
. /etc/os-release
# ─< Convert $ID and $ID_LIKE to lowercase >──────────────────────────────────────────────
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
case "$ID" in
ubuntu | pop) install_debian ;;
debian) install_debian ;;
fedora) install_fedora ;;
# alpine) inst_alpine ;;
arch | manjaro | garuda | endeavour) install_arch ;;
# opensuse*) inst_opensuse ;;
*)
if [ "${ID_LIKE#*debian}" != "$ID_LIKE" ]; then
install_debian
elif [ "${ID_LIKE#*ubuntu}" != "$ID_LIKE" ]; then
install_debian
elif [ "${ID_LIKE#*arch}" != "$ID_LIKE" ]; then
inst_arch
elif [ "${ID_LIKE#*fedora}" != "$ID_LIKE" ]; then
install_fedora
# elif [ "${ID_LIKE#*suse}" != "$ID_LIKE" ]; then
# inst_opensuse
else
echo_error "Unsupported distribution: $ID"
exit 1
fi
;;
esac
else
echo_error "Unable to detect distribution. /etc/os-release not found."
exit 1
fi
}
# Function to add user to the 'libvirt' group and start services
configure_libvirt() {
echo_note "Adding user to 'libvirt' group..."
$_sudo usermod -aG libvirt "$(whoami)"
echo_note "Starting and enabling libvirt service..."
if command -v systemctl &>/dev/null; then
$_sudo systemctl start libvirtd
$_sudo systemctl enable libvirtd
else
echo_warning "systemctl command not found, skipping service management."
fi
echo_note "Configuration complete. You might need to log out and log back in for group changes to take effect."
}
# Install packages for Debian/Ubuntu/Pop!_OS
install_debian() {
echo_info "Updating package list..."
$_sudo apt update -y
echo_info "Installing virt-manager, qemu-full, and related packages..."
$_sudo apt install -y virt-manager qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils
echo_note "Installation complete on Debian/Ubuntu/Pop!_OS!"
}
# Install packages for Fedora
install_fedora() {
echo_info "Updating package list..."
$_sudo dnf check-update -y
echo_info "Installing virt-manager, qemu-full, and related packages..."
$_sudo dnf install -y virt-manager qemu-kvm libvirt libvirt-client bridge-utils
echo_note "Installation complete on Fedora!"
}
# Install packages for Arch Linux/Manjaro/EndeavourOS
install_arch() {
echo_info "Updating package list..."
$_sudo pacman -Syu --noconfirm
echo_info "Installing virt-manager, qemu-full, and related packages..."
$_sudo pacman -S --noconfirm virt-manager qemu-full libvirt dnsmasq bridge-utils
echo_note "Installation complete on Arch Linux/Manjaro/EndeavourOS!"
}
# Install packages for openSUSE
install_opensuse() {
echo_info "Updating package list..."
$_sudo zypper refresh
echo_info "Installing virt-manager, qemu-full, and related packages..."
$_sudo zypper install -y virt-manager qemu-kvm libvirt libvirt-client bridge-utils
echo_note "Installation complete on openSUSE!"
}
main() {
check_root &&
get_packager &&
configure_libvirt
display_stored_messages
}
main

187
installs/xmrig.sh Executable file
View file

@ -0,0 +1,187 @@
{
#!/bin/sh
# ANSI color codes
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# Check if the user is root and set sudo variable if necessary
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
# < Distribution detection and installation >
get_packager() {
if [ -e /etc/os-release ]; then
echo_info "Detecting distribution..."
. /etc/os-release
# < Convert $ID and $ID_LIKE to lowercase >
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
case "$ID" in
ubuntu | pop) _install() {
$_sudo apt-get install "$@" --assume-yes
} ;;
debian) _install() {
$_sudo apt-get install "$@" --assume-yes
} ;;
fedora) _install() {
$_sudo dnf install "$@" -y
} ;;
alpine) _install() {
$_sudo apk add "$@"
} ;;
arch | manjaro | garuda | endeavour) _install() {
$_sudo pacman -S "$@" --noconfirm
} ;;
opensuse*) _install() { $_sudo zypper in "$@" -y; } ;;
*)
if [ "${ID_LIKE#*debian}" != "$ID_LIKE" ]; then
_install() { $_sudo apt-get install "$@" --assume-yes; }
elif [ "${ID_LIKE#*ubuntu}" != "$ID_LIKE" ]; then
_install() { $_sudo apt-get install "$@" --assume-yes; }
elif [ "${ID_LIKE#*arch}" != "$ID_LIKE" ]; then
_install() { $_sudo pacman -S "$@" --noconfirm; }
elif [ "${ID_LIKE#*fedora}" != "$ID_LIKE" ]; then
_install() { $_sudo dnf install "$@" -y; }
elif [ "${ID_LIKE#*suse}" != "$ID_LIKE" ]; then
_install() { $_sudo zypper in "$@" -y; }
else
echo_error "Unsupported distribution: $ID"
exit 1
fi
;;
esac
else
echo_error "Unable to detect distribution. /etc/os-release not found."
exit 1
fi
}
# Check if a command exists
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# Install dependencies
_dependencies() {
tools="git cmake make"
packages="libuv1-dev libssl-dev libhwloc-dev argon2"
for tool in $tools; do
if command_exists "$tool"; then
echo_note "$tool is already installed"
else
echo_info "Installing $tool.."
_install "$tool" || echo_error "Failed to install $tool"
fi
done
for package in $packages; do
echo_info "Installing $package"
_install "$package" || echo_error "Failed to install $package"
done
echo_note "Dependency check completed!"
}
# Clone the repository and prepare build directory
_git() {
xmrig_dir="$HOME/.bin/xmrig"
if [ -d "$xmrig_dir" ]; then
echo_warning "$xmrig_dir already exists. Skipping clone."
else
echo_info "Cloning xmrig repository to $xmrig_dir"
mkdir -p "$HOME/.bin"
if ! git clone --depth=1 https://github.com/xmrig/xmrig.git "$xmrig_dir"; then
echo_error "Failed to clone xmrig repository."
return 1
fi
fi
build_dir="$xmrig_dir/build"
mkdir -p "$build_dir" || {
echo_error "Failed to create build directory: $build_dir"
return 1
}
cd "$build_dir" || {
echo_error "Failed to navigate to build directory: $build_dir"
return 1
}
}
# Initialize and build the application
_appinit() {
echo_info "Running cmake .."
if ! cmake ..; then
echo_error "CMake failed."
return 1
fi
echo_info "Running make (this could take a while)"
if ! make; then
echo_error "Make failed."
return 1
fi
$_sudo ln -s ./xmrig /usr/bin/xmrig || "Link of application failed hard! Is not accessible at /usr/bin/xmrig"
}
# Main function
main() {
if ! check_root; then
echo_error "Root check failed. Exiting."
return 1
fi
if ! get_packager; then
echo_error "Failed to detect distribution or set packager."
return 1
fi
_dependencies || return 1
if _git; then
_appinit || echo_error "Build initialization failed."
else
echo_error "Failed during Git operations."
fi
}
main
}

149
installs/yazi.sh Normal file
View file

@ -0,0 +1,149 @@
{
#!/bin/sh -e
# ─< ANSI color codes >───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─< Check if the user is root and set sudo variable if necessary >───────────────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
evalCargo() {
if [ -e "$HOME/.cargo/env" ]; then
echo_note "Using $HOME/.cargo/env.."
. "$HOME/.cargo/env"
fi
}
i_cargo() {
# if ! command_exists make || ! command_exists gcc; then
# echo_error "The script might run into issues, because of make and gcc not being installed. Please install it, and run the script again, if it fails!"
# fi
evalCargo
if command_exists cargo; then
echo_info "Installing yazi through cargo"
elif command_exists curl; then
echo_note "no cargo found, using curl to install rustup"
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
evalCargo
rustup update
evalCargo
echo_info "Installing yazi through cargo"
else
echo_warning "neither cargo, nor curl were found. Cannot continue!"
fi
cargo install --locked yazi-fm yazi-cli
c_yazi
}
i_arch() {
$_sudo pacman -S yazi --noconfirm
c_yazi
}
i_opensuse() {
$_sudo zypper install yazi
c_yazi
}
c_yazi() {
if [ -e "$HOME/.config/yazi/package.toml" ]; then
if command_exists ya; then
ya pack -i
fi
else
echo_warning "There was no yazi config found.. "
fi
}
# ─< Distribution detection and installation >────────────────────────────────────────
get_packager() {
if [ -e /etc/os-release ]; then
echo_info "Detecting distribution..."
. /etc/os-release
# ─< Convert $ID and $ID_LIKE to lowercase >──────────────────────────────────────────────
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
case "$ID" in
ubuntu | pop) i_cargo ;;
debian) i_cargo ;;
fedora) i_cargo ;;
alpine) i_cargo ;;
arch | manjaro | garuda | endeavour) i_arch ;;
opensuse*) i_opensuse ;;
*)
if [ "${ID_LIKE#*debian}" != "$ID_LIKE" ]; then
i_cargo
elif [ "${ID_LIKE#*ubuntu}" != "$ID_LIKE" ]; then
i_cargo
elif [ "${ID_LIKE#*arch}" != "$ID_LIKE" ]; then
i_arch
elif [ "${ID_LIKE#*fedora}" != "$ID_LIKE" ]; then
i_cargo
elif [ "${ID_LIKE#*suse}" != "$ID_LIKE" ]; then
i_opensuse
else
echo_error "Unsupported distribution: $ID"
exit 1
fi
;;
esac
else
echo_error "Unable to detect distribution. /etc/os-release not found."
exit 1
fi
}
main() {
if check_root; then
get_packager
fi
}
main
}

157
installs/ytgo.sh Normal file
View file

@ -0,0 +1,157 @@
#!/bin/sh
# ╭───────────────╮
# │ env functions │
# ╰───────────────╯
# ───────────────────────────────────< ANSI color codes >───────────────────────────────────
RED='\033[0;31m'
CYAN='\033[0;36m'
YELLOW='\033[0;33m'
LIGHT_GREEN='\033[0;92m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo_error() {
printf "${BOLD}${RED}ERROR: ${NC}${RED}%s${NC}\n" "$1" >&2
}
echo_info() {
printf "${BOLD}${CYAN}INFO: ${NC}${CYAN}%s${NC}\n" "$1"
}
echo_warning() {
printf "${BOLD}${YELLOW}WARNING: ${NC}${YELLOW}%s${NC}\n" "$1"
}
echo_note() {
printf "${BOLD}${LIGHT_GREEN}NOTE: ${NC}${LIGHT_GREEN}%s${NC}\n" "$1"
}
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ─────────────< Check if the user is root and set sudo variable if necessary >─────────────
check_root() {
if [ "$(id -u)" -ne 0 ]; then
if command_exists sudo; then
echo_info "User is not root. Using sudo for privileged operations."
_sudo="sudo"
else
echo_error "No sudo found and you're not root! Can't install packages."
return 1
fi
else
echo_info "Root access confirmed."
_sudo=""
fi
}
# ──────────────────────< Check if the given command exists silently >──────────────────────
command_exists() {
command -v "$@" >/dev/null 2>&1
}
# ╭────────────────────────────────────╮
# │ insert your scripts/functions here │
# ╰────────────────────────────────────╯
# ─< Distribution detection and installation >────────────────────────────────────────
get_packager() {
if [ -e /etc/os-release ]; then
echo_info "Detecting distribution..."
. /etc/os-release
# ─< Convert $ID and $ID_LIKE to lowercase >──────────────────────────────────────────────
ID=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]')
ID_LIKE=$(printf "%s" "$ID_LIKE" | tr '[:upper:]' '[:lower:]')
case "$ID" in
ubuntu | pop) _install() {
$_sudo apt-get install --assume-yes "$@"
} ;;
debian) _install() {
$_sudo apt-get install --assume-yes "$@"
} ;;
fedora) _install() {
$_sudo dnf install -y "$@"
} ;;
alpine) inst_alpine ;;
arch | manjaro | garuda | endeavour) _install() {
$_sudo pacman -S --noconfirm "$@"
} ;;
opensuse*) inst_opensuse ;;
*)
if [ "${ID_LIKE#*debian}" != "$ID_LIKE" ]; then
_install() {
$_sudo apt-get install --assume-yes "$@"
}
elif [ "${ID_LIKE#*ubuntu}" != "$ID_LIKE" ]; then
_install() {
$_sudo apt-get install --assume-yes "$@"
}
elif [ "${ID_LIKE#*arch}" != "$ID_LIKE" ]; then
_install() {
$_sudo pacman -S --noconfirm "$@"
}
elif [ "${ID_LIKE#*fedora}" != "$ID_LIKE" ]; then
_install() {
$_sudo dnf install -y "$@"
}
elif [ "${ID_LIKE#*suse}" != "$ID_LIKE" ]; then
inst_opensuse
else
echo_error "Unsupported distribution: $ID"
exit 1
fi
;;
esac
else
echo_error "Unable to detect distribution. /etc/os-release not found."
exit 1
fi
}
_dependencies() {
get_packager
if [[ "$ID" == "arch" || "$ID_LIKE" == *"arch"* ]]; then
_deps="go git mpv yt-dlp"
else
_deps="golang git mpv yt-dlp"
fi
for dependency in $_deps; do
if ! command_exists "$dependency"; then
echo_info "Installing $dependency"
_install "$dependency" || echo_error "$dependency could not be installed!"
else
echo_note "$dependency - was already installed."
fi
done
}
_clone() {
tmpdir="$(mktemp --dir)"
repo="https://git.k4li.de/pika/ytgo.git"
cd "$tmpdir" || echo_error "$tmpdir is not a valid directory!"
git clone --depth=1 "$repo"
cd ytgo || echo_error "$tmpdir/ytgo is not a valid directory!"
}
_build() {
$_sudo make install
}
# ───────────────────────────────< main function to execute >───────────────────────────────
main() {
if check_root; then
_dependencies || echo_error "dependency function failed hard!"
_clone || echo_error "clone function failed hard!"
_build || echo_error "build function failed hard!"
else
echo_error "Something went terribly wrong!"
fi
}
main

76
logging.sh Normal file
View file

@ -0,0 +1,76 @@
#!/bin/sh
# POSIX-compliant color codes
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Simple echo functions without any arrays or typeset
echo_error() {
printf "${RED}❌ %s${NC}\n" "$1" >&2
}
echo_warning() {
printf "${YELLOW}⚠️ %s${NC}\n" "$1"
}
echo_info() {
printf "${GREEN} %s${NC}\n" "$1"
}
echo_note() {
printf "${CYAN}📝 %s${NC}\n" "$1"
}
# ─< Check if the given command exists silently >─────────────────────────────────────────
command_exists() {
for i in which command; do
if command_exists $i; then
case $i in
command) command -v "$@" >/dev/null 2>&1 ;;
which) which "$@" >/dev/null 2>&1 ;;
esac
fi
done
}
_cd() {
cd "$1" || { echo_error "Cannot navigate to the directory: $1"; return 1; }
}
_exit() {
echo_error "There was an error, which caused the script to exit immediately"
echo_error "$1"
echo_error "Exiting now!"
exit 1
}
confirm_action() {
read -p "$1 - [y/n]: " confirm
case $confirm in
[yY] ) return 0 ;;
[nN] ) return 1 ;;
* ) echo_warning "Invalid input. Action cancelled." ; return 1 ;;
esac
}
create_dir() {
if [ ! -d "$1" ]; then
echo_info "Creating directory: $1"
mkdir -p "$1" || _exit "Failed to create directory $1"
else
echo_info "Directory $1 already exists"
fi
}
check_disk_space() {
threshold=1000000 # Minimum space in KB (e.g., 1GB)
available_space=$(df / | awk 'NR==2 {print $4}')
if [ "$available_space" -lt "$threshold" ]; then
echo_warning "Not enough disk space. Only $((available_space / 1024))MB remaining."
return 1
fi
echo_info "Sufficient disk space available."
}

331
python/Caddy/addEntry.py Executable file
View file

@ -0,0 +1,331 @@
#!/usr/bin/env python3
import os
import re
import socket
def get_host_ip():
"""Get the host IP address"""
try:
# Create a socket to determine the outgoing IP address
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80)) # Connect to Google DNS (doesn't send data)
host_ip = s.getsockname()[0]
s.close()
return host_ip
except Exception:
return "127.0.0.1" # Fallback to localhost
def get_user_input(prompt, default=None):
"""Interactive prompt with default values"""
value = input(f"{prompt} [{default}]: ") or default
return value
def find_caddyfile():
"""Check if the Caddyfile exists, otherwise ask for the path"""
default_path = "./conf/Caddyfile"
if os.path.exists(default_path):
return default_path
print("⚠ No Caddyfile found!")
while True:
custom_path = get_user_input("Enter the path to your Caddyfile")
if os.path.exists(custom_path):
return custom_path
print("❌ File not found, please try again.")
def parse_existing_entries(caddyfile_path):
"""Parse the existing Caddyfile to extract all configured domains"""
existing_entries = {}
try:
with open(caddyfile_path, "r") as file:
content = file.read()
# First, normalize the content to make parsing more reliable
# This removes comments and normalizes whitespace
lines = []
in_comment = False
for line in content.splitlines():
line = line.strip()
if not line or line.startswith('#'):
continue
# Handle inline comments
if '#' in line and not in_comment:
line = line[:line.index('#')].strip()
lines.append(line)
normalized_content = '\n'.join(lines)
# Use brace matching to properly extract domain blocks
blocks = []
current_position = 0
while current_position < len(normalized_content):
# Find the next domain block start
block_start = normalized_content.find('{', current_position)
if block_start == -1:
break
# Find corresponding domain definition
domain_start = normalized_content.rfind('\n', 0, block_start)
if domain_start == -1:
domain_start = 0
else:
domain_start += 1 # Skip the newline
domain_def = normalized_content[domain_start:block_start].strip()
# Find end of this block (accounting for nested braces)
brace_count = 1
block_end = block_start + 1
while brace_count > 0 and block_end < len(normalized_content):
if normalized_content[block_end] == '{':
brace_count += 1
elif normalized_content[block_end] == '}':
brace_count -= 1
block_end += 1
if brace_count == 0:
# We found a complete block
block_content = normalized_content[domain_start:block_end]
# Only process blocks with reverse_proxy directives
if 'reverse_proxy' in block_content:
blocks.append((domain_def, block_content))
current_position = block_end
# Process the extracted blocks
for domain_def, block_content in blocks:
# Extract target from reverse_proxy directive
proxy_match = re.search(r'reverse_proxy\s+(https?:\/\/[\d\.]+:\d+|[\d\.]+:\d+)', block_content)
if not proxy_match:
continue
target = proxy_match.group(1).strip()
# Process domains (handle comma-separated lists correctly)
domains = [d.strip() for d in domain_def.split(',')]
# Process each domain
for domain in domains:
# Skip if it looks like a directive rather than a domain
if '{' in domain or '}' in domain or not domain:
continue
# Skip literal "Host" that are likely from host header directives rather than domains
if domain == "Host" or domain == "{host}":
continue
# Verify domain format (basic check)
if not re.match(r'^[a-zA-Z0-9][-a-zA-Z0-9.]*[a-zA-Z0-9]$', domain) and not domain.startswith('*.'):
print(f"⚠️ Skipping invalid domain format: '{domain}'")
continue
# Determine proxy type
proxy_type = 'standard'
if "https://" in target and "tls_insecure_skip_verify" in block_content:
if "versions h1.1" in block_content:
proxy_type = 'opnsense'
else:
proxy_type = 'https_skip_verify'
# Store the entry
existing_entries[domain] = {
'target': target,
'content': block_content,
'proxy_type': proxy_type
}
# Debug output for special cases
if domain.lower() == "host":
print(f"⚠️ Warning: Found domain named 'host': {domain}")
except Exception as e:
print(f"❌ Error reading Caddyfile: {e}")
import traceback
print(traceback.format_exc())
return existing_entries
def format_caddy_entry(domains, target_ip, target_port, proxy_type):
"""Generate a properly formatted Caddy entry based on proxy type"""
domain_list = ", ".join(domains) # Multiple domains in a single line
if proxy_type == "standard":
return f"""
{domain_list} {{
tls {{
dns cloudflare {{env.CLOUDFLARE_API_TOKEN}}
}}
reverse_proxy {target_ip}:{target_port}
}}
"""
elif proxy_type == "https_skip_verify":
return f"""
{domain_list} {{
tls {{
dns cloudflare {{env.CLOUDFLARE_API_TOKEN}}
}}
reverse_proxy https://{target_ip}:{target_port} {{
transport http {{
tls
tls_insecure_skip_verify
}}
}}
}}
"""
elif proxy_type == "opnsense":
return f"""
{domain_list} {{
tls {{
dns cloudflare {{env.CLOUDFLARE_API_TOKEN}}
}}
reverse_proxy https://{target_ip}:{target_port} {{
transport http {{
tls
tls_insecure_skip_verify
versions h1.1 # Enforce HTTP/1.1
}}
header_up Host {{host}}
header_up X-Real-IP {{remote_host}}
header_up X-Forwarded-Proto {{scheme}}
header_up X-Forwarded-For {{remote}}
header_down Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# Remove problematic headers
header_up -Connection
header_up -Upgrade
}}
}}
"""
def update_existing_entry(caddyfile_path, domain, new_entry):
"""Replace an existing entry for the given domain"""
try:
with open(caddyfile_path, "r") as file:
content = file.read()
# New improved pattern to correctly match complete domain blocks
# This regex matches the domain block from start to finish, including all braces
domain_pattern = fr'(?m)^(?:(?:{re.escape(domain)}|[^{{,\s]+(?:,\s*{re.escape(domain)})(?:,\s*[^{{,\s]+)*|{re.escape(domain)}(?:,\s*[^{{,\s]+)+))\s*{{(?:[^{{}}]|{{(?:[^{{}}]|{{[^{{}}]*}})*}})*}}'
pattern = re.compile(domain_pattern, re.DOTALL)
match = pattern.search(content)
if match:
# Replace the block containing this domain with the new entry
new_content = content[:match.start()] + new_entry.strip() + content[match.end():]
with open(caddyfile_path, "w") as file:
file.write(new_content)
print(f"✅ Updated entry for {domain}")
else:
print(f"⚠ Could not find exact entry for {domain}. Adding as new entry.")
with open(caddyfile_path, "a") as file:
file.write(new_entry)
except Exception as e:
print(f"❌ Error updating Caddyfile: {e}")
print(f"Error details: {str(e)}")
def add_caddy_entry(caddyfile_path):
"""Add new Caddy reverse proxy entries, showing existing entries first"""
host_ip = get_host_ip()
existing_entries = parse_existing_entries(caddyfile_path)
print("\n📌 Existing Caddy Entries:")
if existing_entries:
for domain, data in existing_entries.items():
print(f" 🔹 {domain}{data['target']}")
else:
print(" ⚠ No entries found.")
while True:
domain = get_user_input("\nEnter the domain you want to configure", "")
if not domain:
print("❌ No domain provided. Skipping entry.")
continue
# If domain exists, extract its current values
existing_ip = host_ip
existing_port = "8080"
proxy_type = "standard"
if domain in existing_entries:
print(f"⚠ The domain {domain} already exists.")
edit_existing = get_user_input("Do you want to edit this entry? (y/n)", "y").lower() == "y"
if not edit_existing:
continue
existing_target = existing_entries[domain]['target']
proxy_type = existing_entries[domain]['proxy_type']
target_without_protocol = existing_target.replace("https://", "").replace("http://", "")
if ":" in target_without_protocol:
existing_ip, existing_port = target_without_protocol.split(":")
else:
existing_ip = target_without_protocol
existing_port = "80"
# Show host IP as an option
target_ip_prompt = f"Enter the target IP (type 'host' for {host_ip})"
target_ip = get_user_input(target_ip_prompt, existing_ip)
# Replace 'host' with actual host IP
if target_ip.lower() == 'host':
target_ip = host_ip
target_port = get_user_input("Enter the target port", existing_port)
print("\nChoose the proxy mode:")
print("1⃣ Standard (No HTTPS changes)")
print("2⃣ Internal HTTPS (skip verify)")
print("3⃣ OPNsense Mode (skip verify + enforce HTTP/1.1)")
# Pre-fill proxy type based on detected configuration
mode_choice_default = "1"
if proxy_type == "https_skip_verify":
mode_choice_default = "2"
elif proxy_type == "opnsense":
mode_choice_default = "3"
mode_choice = get_user_input("Enter option (1/2/3)", mode_choice_default)
proxy_type = "standard"
if mode_choice == "2":
proxy_type = "https_skip_verify"
elif mode_choice == "3":
proxy_type = "opnsense"
new_entry = format_caddy_entry([domain], target_ip, target_port, proxy_type)
if domain in existing_entries:
update_existing_entry(caddyfile_path, domain, new_entry)
else:
try:
with open(caddyfile_path, "a") as file:
file.write(new_entry)
print(f"\n✅ New entry added: {domain}{target_ip}:{target_port}")
except Exception as e:
print(f"\n❌ Error writing to Caddyfile: {e}")
return
# Ask if another entry should be added
more_entries = get_user_input("\nDo you want to add or edit another entry? (y/n)", "n").lower() == "y"
if not more_entries:
break
# Restart Caddy container
restart_caddy = get_user_input("\nDo you want to restart the Caddy container? (y/n)", "y").lower() == "y"
if restart_caddy:
os.system("docker compose restart caddy")
print("🔄 Caddy container restarted!")
if __name__ == "__main__":
caddyfile_path = find_caddyfile()
add_caddy_entry(caddyfile_path)

2
python/README.md Normal file
View file

@ -0,0 +1,2 @@
# python

354
python/checkpkg.py Executable file
View file

@ -0,0 +1,354 @@
#!/usr/bin/env python3
import argparse
import urllib.request
import json
import signal
import re
import shutil
import textwrap
from concurrent.futures import ThreadPoolExecutor, as_completed
from urllib.error import HTTPError, URLError
# Color codes
COLORS = {
'reset': '\033[0m',
'bold': '\033[1m',
'red': '\033[91m',
'green': '\033[92m',
'yellow': '\033[93m',
'header': '\033[94m'
}
def colorize(text, color):
"""Add ANSI color codes if output is a terminal"""
if not hasattr(colorize, 'is_tty'):
colorize.is_tty = __import__('sys').stdout.isatty()
return f"{COLORS[color]}{text}{COLORS['reset']}" if colorize.is_tty else text
# def get_terminal_width(default=80):
# """Get terminal width with fallback"""
# try:
# return shutil.get_terminal_size().columns
# except:
# return default
signal.signal(signal.SIGINT, lambda s, f: exit(1))
REQUEST_HEADERS = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) checkpkg/1.0',
'Accept': 'application/json'
}
PM_MAPPINGS = {
'apt': ['debian_', 'ubuntu_'],
'dnf': ['fedora_'],
'pacman': ['arch'],
'aur': ['aur'],
'apk': ['alpine_'],
'zypper': ['opensuse_']
}
REPO_FORMATS = {
'debian_': "Debian {}",
'ubuntu_': "Ubuntu {}",
'fedora_': "Fedora {}",
'arch': "Arch",
'aur': "AUR",
'alpine_': "Alpine {}",
'opensuse_': "openSUSE {}"
}
def version_key(version):
"""Create a sorting key for version comparison"""
return [
(0, int(part)) if part.isdigit() else (1, part.lower())
for part in re.findall(r'(\d+|\D+)', version)
]
def get_package_manager(repo):
for pm, patterns in PM_MAPPINGS.items():
if any(repo.startswith(p) for p in patterns):
return pm
return None
def format_repository(repo):
for pattern, fmt in REPO_FORMATS.items():
if repo.startswith(pattern):
parts = repo.split('_')
return fmt.format(parts[1] if len(parts) > 1 else '')
return repo
def fetch_package_data(package):
try:
req = urllib.request.Request(
f'https://repology.org/api/v1/project/{package}',
headers=REQUEST_HEADERS
)
with urllib.request.urlopen(req, timeout=10) as response:
return json.load(response)
except HTTPError as e:
if e.code == 403:
print(colorize(f"Error: Repology blocked the request for {package} (try again later)", 'red'))
return None
except Exception:
return None
def print_table(output, headers, selected_pms, args):
"""Print formatted table with consistent alignment or list for small terminals"""
# Terminal dimensions
terminal_width = shutil.get_terminal_size().columns
# Calculate package availability for coloring
pkg_availability = {}
for pkg in args.packages:
versions = output.get(pkg, {})
available_count = sum(1 for pm in selected_pms if versions.get(pm, 'Not found') != 'Not found')
if available_count == 0:
pkg_availability[pkg] = 'red' # Not available anywhere
elif available_count == len(selected_pms):
pkg_availability[pkg] = 'green' # Available everywhere
else:
pkg_availability[pkg] = 'yellow' # Available in some places
# Determine minimum required widths
min_pkg_width = max(len(pkg) for pkg in args.packages) + 2
min_pm_width = 10
min_required_width = min_pkg_width + (min_pm_width * len(selected_pms)) + (3 * len(selected_pms))
# If terminal is too narrow for the table, use list format instead
if terminal_width < min_required_width and len(selected_pms) > 1:
print_list_format(output, headers, selected_pms, args, pkg_availability)
return
# Calculate column widths
padding = 1 # Space on each side of content
# Package column width
pkg_col_width = min(min_pkg_width + 4, max(min_pkg_width, terminal_width // (len(selected_pms) + 3)))
# PM column widths (divide remaining space equally)
remaining_width = terminal_width - pkg_col_width - (3 * len(selected_pms))
pm_col_width = max(min_pm_width, remaining_width // len(selected_pms))
col_widths = [pkg_col_width] + [pm_col_width] * len(selected_pms)
# Print header row
header_cells = []
for i, header in enumerate(headers):
text = header.center(col_widths[i] - (2 * padding))
cell = " " * padding + colorize(text, 'header') + " " * padding
header_cells.append(cell)
print(" | ".join(header_cells))
# Print separator line
total_width = sum(col_widths) + (3 * (len(col_widths) - 1))
print("-" * total_width)
# Print each package row
for pkg_idx, pkg in enumerate(args.packages):
versions = output.get(pkg, {})
# First collect all data for this package
package_data = []
# Package name (first column)
package_data.append([colorize(pkg, pkg_availability[pkg])])
# Version data for each package manager
for pm in selected_pms:
version = versions.get(pm, 'Not found')
if version == 'Not found':
package_data.append([colorize('-', 'red')])
continue
# Extract version number and repositories
version_parts = []
match = re.match(r'(.*?)\s+\((.*)\)$', version)
if match:
ver_num, repos = match.groups()
version_parts.append(colorize(ver_num, 'green'))
# Format repositories
repo_lines = []
repo_text = "(" + repos + ")"
# Wrap repository text if needed
avail_width = col_widths[len(package_data)] - (2 * padding)
if len(repo_text) <= avail_width:
repo_lines.append(colorize(repo_text, 'green'))
else:
# Handle wrapping for repositories
repo_parts = repos.split(', ')
current_line = "("
for repo in repo_parts:
if len(current_line) + len(repo) + 2 <= avail_width:
if current_line != "(":
current_line += ", "
current_line += repo
else:
if current_line != "(":
current_line += ")"
repo_lines.append(colorize(current_line, 'green'))
current_line = " " + repo
if current_line != "(":
current_line += ")" if not current_line.startswith(" ") else ""
repo_lines.append(colorize(current_line, 'green'))
# Combined version and repo lines
package_data.append([version_parts[0]] + repo_lines)
else:
# Simple version string
package_data.append([colorize(version, 'green')])
# Determine max number of lines needed
max_lines = max(len(column) for column in package_data)
# Print all lines for this package
for line_idx in range(max_lines):
row_cells = []
for col_idx, col_data in enumerate(package_data):
if line_idx < len(col_data):
# Actual content
content = col_data[line_idx]
content_plain = re.sub(r'\033\[\d+m', '', content)
# Calculate padding
left_pad = padding
right_pad = max(0, col_widths[col_idx] - len(content_plain) - left_pad)
cell = " " * left_pad + content + " " * right_pad
else:
# Empty cell
cell = " " * col_widths[col_idx]
row_cells.append(cell)
print(" | ".join(row_cells))
# Add separator between packages
if pkg_idx < len(args.packages) - 1:
print("·" * total_width)
def print_list_format(output, headers, selected_pms, args, pkg_availability):
"""Print packages in a vertical list format for narrow terminals"""
terminal_width = shutil.get_terminal_size().columns
for pkg_idx, pkg in enumerate(args.packages):
pkg_color = pkg_availability[pkg]
versions = output.get(pkg, {})
# Print package header with color based on availability
print(f"\n{colorize('Package:', 'bold')} {colorize(pkg, pkg_color)}")
print("-" * min(40, terminal_width - 2))
# Print versions for each package manager
for pm in selected_pms:
pm_name = headers[selected_pms.index(pm) + 1] # Get friendly display name
version = versions.get(pm, 'Not found')
if version == 'Not found':
print(f"{colorize(pm_name, 'header')}: {colorize('-', 'red')}")
else:
# Extract version and repo information
match = re.match(r'(.*?)\s+\((.*)\)$', version)
if match:
ver_num, repos = match.groups()
# Handle long repository lists with wrapping
if len(pm_name) + len(ver_num) + len(repos) + 5 > terminal_width:
print(f"{colorize(pm_name, 'header')}: {colorize(ver_num, 'green')}")
# Wrap repositories with proper indentation
wrapper = textwrap.TextWrapper(
width=terminal_width - 4,
initial_indent=" ",
subsequent_indent=" "
)
wrapped = wrapper.fill(f"({repos})")
print(colorize(wrapped, 'green'))
else:
print(f"{colorize(pm_name, 'header')}: {colorize(ver_num, 'green')} ({repos})")
else:
print(f"{colorize(pm_name, 'header')}: {colorize(version, 'green')}")
# Add separator between packages
if pkg_idx < len(args.packages) - 1:
print("\n" + "-" * min(40, terminal_width - 2))
def main():
parser = argparse.ArgumentParser(description='Package search tool')
parser.add_argument('--all', action='store_true')
parser.add_argument('--apt', action='store_true')
parser.add_argument('--dnf', action='store_true')
parser.add_argument('--pacman', action='store_true')
parser.add_argument('--apk', action='store_true')
parser.add_argument('--zypper', action='store_true')
parser.add_argument('--aur', action='store_true')
parser.add_argument('packages', nargs='+')
args = parser.parse_args()
selected_pms = [pm for pm, flag in [
('apt', args.apt or args.all),
('dnf', args.dnf or args.all),
('pacman', args.pacman or args.all),
('apk', args.apk or args.all),
('zypper', args.zypper or args.all),
('aur', args.aur or args.all)
] if flag]
if not selected_pms:
print(colorize("Error: No package managers selected", 'red'))
return
results = {}
with ThreadPoolExecutor(max_workers=5) as executor:
futures = {executor.submit(fetch_package_data, pkg): pkg for pkg in args.packages}
for future in as_completed(futures):
pkg = futures[future]
try:
data = future.result()
results[pkg] = data or []
except Exception as e:
print(colorize(f"Error processing {pkg}: {str(e)}", 'red'))
results[pkg] = []
output = {}
for pkg, entries in results.items():
pm_versions = {pm: {'version': '', 'repos': set(), 'key': []} for pm in selected_pms}
for entry in entries:
repo = entry.get('repo', '')
version = entry.get('version', 'N/A')
pm = get_package_manager(repo)
if pm in selected_pms and version != 'N/A':
repo_fmt = format_repository(repo)
current_key = version_key(version)
stored = pm_versions[pm]
if not stored['key'] or current_key > stored['key']:
stored['version'] = version
stored['repos'] = {repo_fmt}
stored['key'] = current_key
elif current_key == stored['key']:
stored['repos'].add(repo_fmt)
output[pkg] = {}
for pm in selected_pms:
data = pm_versions[pm]
if data['version']:
repos = ', '.join(sorted(data['repos']))
output[pkg][pm] = f"{data['version']} ({repos})"
else:
output[pkg][pm] = 'Not found'
print_table(output, ['Package'] + selected_pms, selected_pms, args)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,16 @@
print('BANK OF DEDEDEX')
pin1 = int(input("Enter your first PIN: "))
pin2 = int(input("Enter your PIN again, to confirm: "))
if pin1 == pin2:
password = pin1
pin = int(input('Enter your PIN: '))
while pin != password:
pin = int(input('Incorrect PIN. Enter your PIN again: '))
if pin == password:
print('PIN was entered successfully!')

76
python/dev/fonts.py Executable file
View file

@ -0,0 +1,76 @@
#!/usr/bin/env python3
import os
import subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed
from colorama import init, Fore, Style
import requests
# Initialize colorama
init(autoreset=True)
# List of font repositories
FONT_REPOS = {
"JetBrainsMono": "https://github.com/ryanoasis/nerd-fonts/releases/download/v3.3.0/JetBrainsMono.zip",
"CaskaydiaCove": "https://github.com/ryanoasis/nerd-fonts/releases/download/v3.3.0/CascadiaCode.zip",
# Add more repositories here
}
def display_menu(options, existing_fonts):
print(Fore.CYAN + "Select Font Repositories to Download:")
for i, option in enumerate(options, 1):
icon = Fore.GREEN + "" if option in existing_fonts else Fore.RED + " "
print(f"{i}. {option} {icon}")
print(Fore.YELLOW + "0. Exit")
def get_user_selection(options):
selected_indices = []
while True:
try:
choices = input(Fore.YELLOW + "Enter the numbers of your choices separated by spaces (q to quit): ")
if choices.strip().lower() == "q":
break
indices = [int(choice.strip()) - 1 for choice in choices.split() if choice.strip().isdigit()]
for index in indices:
if 0 <= index < len(options):
selected_indices.append(index)
else:
print(Fore.RED + f"Invalid choice: {index + 1}. Please try again.")
except ValueError:
print(Fore.RED + "Invalid input. Please enter numbers separated by spaces.")
return selected_indices
def download_font(url, download_path):
response = requests.get(url)
with open(download_path, 'wb') as file:
file.write(response.content)
def clone_repos(selected_repos, base_clone_directory):
with ThreadPoolExecutor(max_workers=4) as executor:
future_to_repo = {
executor.submit(download_font, FONT_REPOS[repo], os.path.join(base_clone_directory, f"{repo}.zip")): repo
for repo in selected_repos
}
for future in as_completed(future_to_repo):
repo = future_to_repo[future]
try:
future.result()
print(Fore.GREEN + f"Successfully downloaded {repo}")
except Exception as e:
print(Fore.RED + f"Failed to download {repo}: {e}")
def check_existing_fonts(clone_directory):
return {repo for repo in FONT_REPOS if os.path.exists(os.path.join(clone_directory, f"{repo}.zip"))}
def main():
base_clone_directory = os.path.expanduser("~/.local/share/fonts/")
os.makedirs(base_clone_directory, exist_ok=True)
existing_fonts = check_existing_fonts(base_clone_directory)
options = list(FONT_REPOS.keys())
display_menu(options, existing_fonts)
selected_indices = get_user_selection(options)
selected_repos = [options[i] for i in selected_indices if options[i] not in existing_fonts]
clone_repos(selected_repos, base_clone_directory)
if __name__ == "__main__":
main()

5
python/dev/test.py Normal file
View file

@ -0,0 +1,5 @@
from datetime import datetime
current_year = datetime.now().year
print(current_year)

42
python/mergefiles.py Normal file
View file

@ -0,0 +1,42 @@
import os
from datetime import datetime
def merge_files(file_paths):
# Dictionary to hold file contents by extension
files_by_extension = {}
# Read each file and group contents by extension
for file_path in file_paths:
_, ext = os.path.splitext(file_path)
if ext not in files_by_extension:
files_by_extension[ext] = []
with open(file_path, 'r') as file:
files_by_extension[ext].append(file.read())
# Ensure the .old directory exists
old_dir = '.old'
if not os.path.exists(old_dir):
os.makedirs(old_dir)
# Write merged contents to new files
for ext, contents in files_by_extension.items():
current_date = datetime.now().strftime("%Y-%m-%d")
merged_file_path = f'{current_date}{ext}'
# Move existing merged file to .old directory
if os.path.exists(merged_file_path):
os.rename(merged_file_path, os.path.join(old_dir, f'{current_date}{ext}'))
with open(merged_file_path, 'w') as merged_file:
for content in contents:
merged_file.write(content)
if __name__ == "__main__":
# Example usage: specify the file paths you want to merge
file_paths = [
'/test/first.csv',
'/test/second.csv',
'/test/third.csv'
]
merge_files(file_paths)