summaryrefslogtreecommitdiff
path: root/miscripts
diff options
context:
space:
mode:
Diffstat (limited to 'miscripts')
-rw-r--r--miscripts/DICTIONARY9
-rw-r--r--miscripts/Export Chrome Bookmarks as HTML 54
-rw-r--r--miscripts/check_ssh.sh10
-rw-r--r--miscripts/choice.sh23
-rw-r--r--miscripts/delfi_rss.py3
-rw-r--r--miscripts/hypothetical_cliparmyknife_mod.txt9
-rw-r--r--miscripts/hypothetical_picarmyknife.txt11
-rw-r--r--miscripts/imnotgivingup.sh15
-rw-r--r--miscripts/inotifytest.sh9
-rw-r--r--miscripts/minivac_pulse.sh134
-rw-r--r--miscripts/postman.sh117
-rw-r--r--miscripts/qemu_helper.sh0
-rw-r--r--miscripts/rshred.txt65
-rw-r--r--miscripts/shigoto_kfxx.sh114
-rw-r--r--miscripts/shigoto_trivy_sorting_hat.sh66
-rw-r--r--miscripts/snap.sh20
-rw-r--r--miscripts/wide_play_cmus.sh101
-rw-r--r--miscripts/wide_play_dmenu.sh106
-rw-r--r--miscripts/wireguard-install.sh474
19 files changed, 1340 insertions, 0 deletions
diff --git a/miscripts/DICTIONARY b/miscripts/DICTIONARY
new file mode 100644
index 0000000..d7765b5
--- /dev/null
+++ b/miscripts/DICTIONARY
@@ -0,0 +1,9 @@
+$ rsync ftp.edrdg.org::nihongo/JMdict_e ~/Downloads/JMdict_e
+
+NUKLEAR FLASHCARDS
+
+DEAR IMGUI IMMEDIATE MODE
+DYNAMICALLY GENERATES A CHAIN OF FLASHCARDS BASED ON CURSOR SELECTION (xclip -selection primary -o, -selection clipboard if you want it triggered by ctrl+C instead)
+
+EACH FLASHCARD HAS A LINK TO A LOOKUP WEBSITE OF THE USER'S CHOICE (%s = search string)
+ABILITY TO READ INPUT OVER A NETWORK IN CASE SOMEONE WANTS TO USE A DIFFERENT DEVICE FOR THE TRANSLATION WINDOW \ No newline at end of file
diff --git a/miscripts/Export Chrome Bookmarks as HTML b/miscripts/Export Chrome Bookmarks as HTML
new file mode 100644
index 0000000..7bc5c51
--- /dev/null
+++ b/miscripts/Export Chrome Bookmarks as HTML
@@ -0,0 +1,54 @@
+#credits: Mostly to tobibeer and Snak3d0c @ https://stackoverflow.com/questions/47345612/export-chrome-bookmarks-to-csv-file-using-powershell
+#Path to chrome bookmarks
+$pathToJsonFile = "$env:localappdata\Google\Chrome\User Data\Default\Bookmarks"
+
+$htmlOut = 'C:\temp\ChromeBookmarks.html'
+$htmlHeader = @'
+<!DOCTYPE NETSCAPE-Bookmark-file-1>
+<!--This is an automatically generated file.
+ It will be read and overwritten.
+ Do Not Edit! -->
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
+<Title>Bookmarks</Title>
+<H1>Bookmarks</H1>
+<DL><p>
+'@
+
+$htmlHeader | Out-File -FilePath $htmlOut -Force -Encoding utf8 #line59
+
+#A nested function to enumerate bookmark folders
+Function Get-BookmarkFolder {
+[cmdletbinding()]
+Param(
+[Parameter(Position=0,ValueFromPipeline=$True)]
+$Node
+)
+
+Process
+{
+
+ foreach ($child in $node.children)
+ {
+ $da = [math]::Round([double]$child.date_added / 1000000) #date_added - from microseconds (Google Chrome {dates}) to seconds 'standard' epoch.
+ $dm = [math]::Round([double]$child.date_modified / 1000000) #date_modified - from microseconds (Google Chrome {dates}) to seconds 'standard' epoch.
+ if ($child.type -eq 'Folder')
+ {
+ " <DT><H3 FOLDED ADD_DATE=`"$($da)`">$($child.name)</H3>" | Out-File -FilePath $htmlOut -Append -Force -Encoding utf8
+ " <DL><p>" | Out-File -FilePath $htmlOut -Append -Force -Encoding utf8
+ Get-BookmarkFolder $child
+ " </DL><p>" | Out-File -FilePath $htmlOut -Append -Force -Encoding utf8
+ }
+ else
+ {
+ " <DT><a href=`"$($child.url)`" ADD_DATE=`"$($da)`">$($child.name)</a>" | Out-File -FilePath $htmlOut -Append -Encoding utf8
+ } #else url
+ } #foreach
+ } #process
+} #end function
+
+$data = Get-content $pathToJsonFile -Encoding UTF8 | out-string | ConvertFrom-Json
+$sections = $data.roots.PSObject.Properties | select -ExpandProperty name
+ForEach ($entry in $sections) {
+ $data.roots.$entry | Get-BookmarkFolder
+}
+'</DL>' | Out-File -FilePath $htmlOut -Append -Force -Encoding utf8
diff --git a/miscripts/check_ssh.sh b/miscripts/check_ssh.sh
new file mode 100644
index 0000000..c423845
--- /dev/null
+++ b/miscripts/check_ssh.sh
@@ -0,0 +1,10 @@
+function check_ssh() {
+ ssh -o PasswordAuthentication=no "$@" true 2>&1 > /dev/null
+ [ $? == 0 ] && {
+ echo Connection successful
+ } || {
+ echo Connection failure
+ }
+}
+
+#check_ssh -i ~/.ssh/id_rsa tori_kago@torikago.com \ No newline at end of file
diff --git a/miscripts/choice.sh b/miscripts/choice.sh
new file mode 100644
index 0000000..c2f4e16
--- /dev/null
+++ b/miscripts/choice.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# Bash Menu Script Example
+
+PS3='Please enter your choice: '
+options=("Option 1" "Option 2" "Option 3" "Quit")
+select opt in "${options[@]}"
+do
+ case $opt in
+ "Option 1")
+ echo "you chose choice 1"
+ ;;
+ "Option 2")
+ echo "you chose choice 2"
+ ;;
+ "Option 3")
+ echo "you chose choice $REPLY which is $opt"
+ ;;
+ "Quit")
+ break
+ ;;
+ *) echo "invalid option $REPLY";;
+ esac
+done \ No newline at end of file
diff --git a/miscripts/delfi_rss.py b/miscripts/delfi_rss.py
new file mode 100644
index 0000000..80fe24d
--- /dev/null
+++ b/miscripts/delfi_rss.py
@@ -0,0 +1,3 @@
+https://www.delfi.rs/pretraga?q=&c=5&per_page=20&s=najnovije&cena_od=0&cena_do=0&izdavaci=%5B%5D&pismo=%5B%5D&povez=%5B%5D&uzrast=%5B%5D&autor=%5B%5D&datum_unosa=%5B%5D&platforma=%5B%5D&zanr=%5B10078%5D&podzanr=%5B%5D&boks=%5B%5D&kategorija=%5B%5D&stanje=1
+
+https://www.delfi.rs/pretraga?q=&c=5&per_page=50&s=najnovije&cena_od=0&cena_do=0&izdavaci=%5B%5D&pismo=%5B%5D&povez=%5B%5D&uzrast=%5B%5D&autor=%5B%5D&datum_unosa=%5B%5D&platforma=%5B%5D&zanr=%5B40127%5D&podzanr=%5B%5D&boks=%5B%5D&kategorija=%5B%5D&stanje=1 \ No newline at end of file
diff --git a/miscripts/hypothetical_cliparmyknife_mod.txt b/miscripts/hypothetical_cliparmyknife_mod.txt
new file mode 100644
index 0000000..e5f6b4d
--- /dev/null
+++ b/miscripts/hypothetical_cliparmyknife_mod.txt
@@ -0,0 +1,9 @@
+
+printf 'file.mp4\n%.0s' {1..118} > files.txt
+cat inputs.txt | tr -d "\n" | sed -r "s|file |\ -i |g" > input.txt
+
+
+for i in {0..119}; do echo "[$i:v:0][$i:a:0]"; done > filters.txt
+cat filters.txt | tr -d "\n" > filter.txt
+
+ffmpeg $(cat input.txt) -filter_complex "$(cat filter.txt)" -map "[outv]" -map "[outa]" out.mkv \ No newline at end of file
diff --git a/miscripts/hypothetical_picarmyknife.txt b/miscripts/hypothetical_picarmyknife.txt
new file mode 100644
index 0000000..bb33890
--- /dev/null
+++ b/miscripts/hypothetical_picarmyknife.txt
@@ -0,0 +1,11 @@
+# STACK MULTIPLE IMAGES SIDE BY SIDE / TOP TO BOTTOM
+# INTERACTIVE CROP, SHOW PREVIEW IN SEPARATE WINDOW
+# BREAK DOWN GIF INTO FRAMES AND VICE VERSA
+# REMOVE BLACK BORDERS
+# ADD WATERMARK
+# APPLY BASIC BITCH IMAGE FILTERS
+# LOOK UP WHAT ELSE IT CAN DO ON THE WEBSITE, AND MAYBE ASK SOMEONE FOR IDEAS
+# COLOR PICKER
+
+
+# Automatically adding transparency and removing whitespace from images.mp4
diff --git a/miscripts/imnotgivingup.sh b/miscripts/imnotgivingup.sh
new file mode 100644
index 0000000..0634e20
--- /dev/null
+++ b/miscripts/imnotgivingup.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+
+# USE THIS WHEN IT'S TIME TO COMPILE A LIST OF NAMES FOR YOUR *ACTUAL* ART SORTING PROGRAM, YOU BITCH
+
+ART_DIR="$HOME/art"
+
+IMAGE_EXT_FIND="\(png\|jpe?g\|gif\|bmp\|webp\)"
+IMAGE_EXT="$(echo "$IMAGE_EXT_FIND" | sed -r "s|\\\\\)|)|g; s|\\\\\(|(|g")"
+
+find "$ART_DIR" -type f -iregex ".*\.${IMAGE_EXT_FIND}$" | sed -r "s|$ART_DIR\/||g; s|\/[0-9]+\_p[0-9]+\.${IMAGE_EXT}$|\/PIXIV_TAG|g; s|\/danbooru(\_[a-z0-9]+){2}\.${IMAGE_EXT}$|\/DANBOORU_TAG|g; s|[0-9]*[^0-9]*?\.${IMAGE_EXT}$||g" | sort | uniq | sed '/^$/d'
+
+
+
+
diff --git a/miscripts/inotifytest.sh b/miscripts/inotifytest.sh
new file mode 100644
index 0000000..860c7ad
--- /dev/null
+++ b/miscripts/inotifytest.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+# requires notify-tools
+
+inotifywait -m ~/Tempsktop -e create -e moved_to |
+ while read dir action file; do
+ echo "The file '$file' appeared in directory '$dir' via '$action'"
+ [[ -n $(echo "$file" | grep "png") ]] && feh "${dir}${file}"
+ done
diff --git a/miscripts/minivac_pulse.sh b/miscripts/minivac_pulse.sh
new file mode 100644
index 0000000..c6f2cbc
--- /dev/null
+++ b/miscripts/minivac_pulse.sh
@@ -0,0 +1,134 @@
+#!/bin/bash
+
+
+#MPV WINDOW / SOME OTHER OUTPUT
+#pactl list sink-inputs | grep -E "^\s*Sink\ Input\ \#|^\s*media\.name\ \=\ " | tac | grep -A 1 -E "^\s*media\.name\ \=\ .*Onii.*" | grep -oP "Sink\ Input\ \#\K[0-9]+"
+
+#SINK
+#pacmd list-sinks | grep -E "^\s*name:|^\s*module:" | grep -A 1 -E "^\s*name: <CombinedDiscordSink>" | grep -oP "module: \K[0-9]+"
+
+######################### VARIABLES #########################
+
+MICROPHONE="alsa_input.pci-0000_00_1b.0.analog-stereo"
+SPEAKERS="alsa_output.pci-0000_00_1b.0.analog-stereo"
+
+SHORTCUTS=(
+ 'FUNCTION | TERMINAL EQUIVALENT | RECOMMENDED KEYBIND'
+ '------------------------------------------------------------------------------------------'
+ 'Change Sink | minivac.sh | Ctrl+Shift+F7'
+ 'Load Sinks | minivac.sh -l | -'
+ 'Unload Sinks | minivac.sh -u | -'
+ 'Notify-send Sinks | minivac.sh -n | F7'
+ 'Reset Sinks | minivac.sh -r | Shift+F7'
+)
+
+DMENU_APPEARANCE="mononoki;11;#191919;#AAAAAA;#890089;#FFFFFF;Select Input:"
+
+for i in {1..7}
+do
+ declare "dm$i=$(echo $DMENU_APPEARANCE | cut -f$i -d';')" # CONVERT DMENU APPEARANCE STRIP INTO SEPARATE PARAMETERS
+done
+
+mapfile -t INPUTS < <( pactl list sink-inputs | grep -B 30 -A 10 "application.process.binary" | grep "Sink Input\|application\.name\|media\.name" | grep -B 2 "application\.name" | sed -r "/--/d; s|Sink\ Input\ ||g; s|[[:space:]]*application\.name\ \=|\~|g; s|[[:space:]]*media\.name\ \=\ |\~\ |g" | paste -sd ' \n' )
+
+mapfile -t SINKS < <( pactl list sinks | grep -A 3 "Sink #" | grep "Sink #\|Name:\|Description:" | sed -r "s|[[:space:]]*Name:\ |\~ |g; s|[[:space:]]*Description:\ |\~\ |g" | paste -sd ' \n' )
+
+######################### HELPER FUNCTIONS #########################
+
+treat_inputs () {
+ i=0
+ for INPUT in "${INPUTS[@]}"
+ do
+ SINK=$( pactl list sink-inputs | grep -A 5 "$( echo $INPUT | sed -r "s| .*||g" )" | grep "Sink:")
+ SINK_TRANSLATED=$( pactl list sinks | grep -A 3 "$( echo $SINK | sed -r 's|: | #|g')" | grep "Description" | sed -r "s|.*Description: ||g" )
+ INPUTS[i]=$( echo "$INPUT -> $SINK_TRANSLATED" )
+ ((i++))
+ done
+}
+
+load_sinks () {
+ if [[ -z "$(pactl list short modules | grep "DiscordSink")" ]]; then
+ pactl load-module module-null-sink sink_name=VirtualDiscordSink
+ pactl load-module module-loopback source="$MICROPHONE" sink=VirtualDiscordSink
+ pactl load-module module-combine-sink slaves=VirtualDiscordSink,$SPEAKERS sink_name=CombinedDiscordSink
+ else
+ echo -e "\nSinks already loaded."
+ fi
+}
+
+unload_sinks () {
+ read -r -p "Are you sure? [y/N] " response
+ response=${response,,} # tolower
+ if [[ "$response" =~ ^(yes|y)$ ]]; then
+ pactl list short modules | grep "DiscordSink" | cut -f1 | xargs -L1 pactl unload-module
+ echo -e "\nSinks unloaded."
+ else
+ echo -e "\nSink unloading aborted."
+ fi
+}
+
+configure_mic () {
+ MIC_NAME=$( pactl list source-outputs | grep -B 18 "WEBRTC VoiceEngine" | grep "Source Output #" | sed -r "s|^.*#||g" )
+ MIC_SOURCE=$( pactl list source-outputs | grep -B 18 "WEBRTC VoiceEngine" | grep "Source:" | sed -r "s|^.*:\ ||g" )
+ SINK_SOURCE=$( pactl list sources | grep -B 3 "VirtualDiscordSink.monitor" | grep "Source #" | sed -r "s|^.*#||g" )
+ [[ "$MIC_SOURCE" -ne "$SINK_SOURCE" ]] && pactl move-source-output "$MIC_NAME" "VirtualDiscordSink.monitor" && $HOME/stuf/scripts/notification_wrapper.sh "\nMICROPHONE\nHAS BEEN MOVED TO SINK\n$SINK_SOURCE" "MINIVAC"
+}
+
+reset_sinks () {
+ echo -e "Yes\nNo" \
+ | dmenu -fn "$([[ $(fc-match "$dm1" | grep "$dm1") ]] && fc-match -f %{family} "$dm1" || fc-match -f %{family} mono)-$dm2" -l 10 -i -nb "$dm3" -nf "$dm4" -sb "#900D09" -sf "$dm6" -p "Reset all sinks?" \
+ | grep "Yes" &> /dev/null && for INPUT in "${INPUTS[@]}"; do pactl move-sink-input "$(echo $INPUT | awk -F' ~ ' '{print $1}' | sed "s|#||")" "alsa_output.pci-0000_00_1b.0.analog-stereo"; done \
+ && $HOME/stuf/scripts/notification_wrapper.sh "\nALL SINKS HAVE BEEN RESET" "MINIVAC"
+}
+
+notify_sinks () {
+ treat_inputs
+ $HOME/stuf/scripts/notification_wrapper.sh "\nLIST OF CURRENT MAPPINGS\n$(for INPUT in "${INPUTS[@]}"; do echo "\n$INPUT"; done)" "MINIVAC"
+}
+
+change_sink () {
+ treat_inputs
+ CHOICE_INPUT=$( echo "$(for INPUT in "${INPUTS[@]}"; do echo $INPUT; done)" | uniq | dmenu -fn "$([[ $(fc-match "$dm1" | grep "$dm1") ]] && fc-match -f %{family} "$dm1" || fc-match -f %{family} mono)-$dm2" -l 10 -i -nb "$dm3" -nf "$dm4" -sb "$dm5" -sf "$dm6" -p "$dm7" )
+ CHI_COMMAND=$(echo $CHOICE_INPUT | awk -F' ~ ' '{print $1}' | sed "s|#||")
+ CHI_NOTIFY=$(echo $CHOICE_INPUT | awk -F' ~ ' '{print $2}' )
+
+ [[ -n $CHI_COMMAND ]] && CHOICE_SINK=$( echo "$(for SINK in "${SINKS[@]}"; do echo $SINK; done)" | uniq | dmenu -fn "$([[ $(fc-match "$dm1" | grep "$dm1") ]] && fc-match -f %{family} "$dm1" || fc-match -f %{family} mono)-$dm2" -l 10 -i -nb "$dm3" -nf "$dm4" -sb "$dm5" -sf "$dm6" -p "Select Sink:" )
+ CHS_COMMAND=$(echo $CHOICE_SINK | awk -F' ~ ' '{print $2}' )
+ CHS_NOTIFY=$(echo $CHOICE_SINK | awk -F' ~ ' '{print $3}' )
+
+ [[ -n $CHI_COMMAND && -n $CHS_COMMAND ]] && pactl move-sink-input "$CHI_COMMAND" "$CHS_COMMAND" && $HOME/stuf/scripts/notification_wrapper.sh "\nSOURCE\n$CHI_NOTIFY\nHAS BEEN MOVED TO SINK\n$CHS_NOTIFY" "MINIVAC"
+}
+
+######################### EXECUTION #########################
+
+# [[ -z $( grep -E "^alsa_output.pci-0000_03_04.0.analog-stereo$" $HOME/.config/pulse/* ) || -z $( grep -E "^alsa_input.pci-0000_03_04.0.iec958-stereo$" $HOME/.config/pulse/* ) ]] \
+# && $HOME/stuf/scripts/notification_wrapper.sh "\nSYSTEM CHANGE DETECTED, TERMINATING PROGRAM" "MINIVAC" && exit
+
+load_sinks
+configure_mic
+
+while getopts "hlunr" opt; do
+ case $opt in
+ h) echo -e "usage: $0 [-h help] [-n notify-send sinks] [-l load sinks] [-u unload sinks] [-r reset sinks]\n\nSuggested Keyboard Shortcuts:\n"; printf '%s\n' "${SHORTCUTS[@]}"; exit ;; # PRINT HELP IN TERMINAL
+ l) load_sinks; exit ;; # LOAD ALL SINKS
+ u) unload_sinks; exit ;; # UNLOAD ALL SINKS
+ n) notify_sinks; exit ;; # LIST ALL SINKS VIA WRAPPER
+ r) reset_sinks; exit ;; # RESET ALL SINKS
+ ?) echo "error: option -$OPTARG is not implemented"; exit ;;
+ esac
+done
+
+change_sink
+
+# pacmd load-module module-loopback source=MICROPHONE_SOURCE sink=Virtual
+# alsa_input.usb-C-Media_Electronics_Inc._YMC_1040-00.mono-fallback
+# pacmd load-module module-combine-sink slaves=Virtual,SOUNDCARD_SINK
+# alsa_output.pci-0000_03_04.0.analog-stereo
+# set mpv playback to simultaneous output to null output, CMI...
+# set recording to monitor of null output
+
+
+
+
+# pactl list sinks -> Sink #1
+# pactl list sink-inputs -> Sink: 1
diff --git a/miscripts/postman.sh b/miscripts/postman.sh
new file mode 100644
index 0000000..3b62240
--- /dev/null
+++ b/miscripts/postman.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+URL="http://172.26.16.1:8080/klk"
+
+FILE="$HOME/csv.csv"
+
+function loadPredmeti () {
+ echo -e "\n\n\n---------- LOADING PREDMETI ----------"
+ while read line; do
+ curl --location "${URL}/predmeti" \
+ --header 'Content-Type: application/json' \
+ --data ' {
+ "naziv": "'"$line"'"
+ }'
+ done < <( tail -n +2 $FILE | iconv -c -f utf-8 -t ascii | sed -r "s|\",\"|~|g; s|~ET~|~CET~|g; s|\"||g" | cut -d"~" -f 1 | sort | uniq | tr -d '\r' )
+}
+
+function loadProfesori () {
+ echo -e "\n\n\n---------- LOADING PROFESORI ----------"
+ while read line; do
+ ime="${line##* }"
+ prezime="${line%% *}"
+
+ curl --location "${URL}/profesori" \
+ --header 'Content-Type: application/json' \
+ --data ' {
+ "ime": "'"$ime"'",
+ "prezime": "'"$prezime"'"
+ }'
+ done < <( tail -n +2 $FILE | iconv -c -f utf-8 -t ascii | sed -r "s|\",\"|~|g; s|~ET~|~CET~|g; s|\"||g" | cut -d"~" -f 3 | sort | uniq | tr -d '\r' )
+}
+
+function loadGrupe () {
+ echo -e "\n\n\n---------- LOADING GRUPE ----------"
+ while read line; do
+ curl --location "${URL}/grupe" \
+ --header 'Content-Type: application/json' \
+ --data ' {
+ "oznaka": "'"$line"'"
+ }'
+ done < <( tail -n +2 $FILE | iconv -c -f utf-8 -t ascii | sed -r "s|\",\"|~|g; s|~ET~|~CET~|g; s|\"||g" | cut -d"~" -f 4 | sort | uniq | tr ',' '\n' | sed -s "s| ||g" | sort | uniq | tr -d '\r' )
+}
+
+
+function loadUcionice () {
+ echo -e "\n\n\n---------- LOADING UCIONICE ----------"
+ while read line; do
+ curl --location "${URL}/ucionice" \
+ --header 'Content-Type: application/json' \
+ --data ' {
+ "oznaka": "'"$line"'"
+ }'
+ done < <( tail -n +2 $FILE | iconv -c -f utf-8 -t ascii | sed -r "s|\",\"|~|g; s|~ET~|~CET~|g; s|\"||g" | cut -d"~" -f 7 | sort | uniq | tr -d '\r' )
+}
+
+LINENUM=0
+
+function loadTermini () {
+ echo -e "\n\n\n---------- LOADING TERMINI ----------"
+ while read line; do
+
+ pocetni_termin="$( echo "$line" | cut -d"~" -f 6 | cut -d"-" -f 1 | tr -d '\r' )"
+ krajnji_termin="$( echo "$line" | cut -d"~" -f 6 | cut -d"-" -f 2 | tr -d '\r' )"
+ dan_u_nedelji="$( echo "$line" | cut -d"~" -f 5 | tr -d '\r' )"
+
+ tip_nastave="$( echo "$line" | cut -d"~" -f 2 | tr -d '\r' )"
+
+ ucionica_oznaka="$( echo "$line" | cut -d"~" -f 7 | tr -d '\r' )"
+
+ profesor_ime="$( echo "$line" | cut -d"~" -f 3 | cut -d" " -f 2- | tr -d '\r' )"
+ profesor_prezime="$( echo "$line" | cut -d"~" -f 3 | cut -d" " -f 1 | tr -d '\r' )"
+
+ predmet_naziv="$( echo "$line" | cut -d"~" -f 1 | tr -d '\r' )"
+
+ jank=""
+
+ IFS=", " read -ra GRPS <<< $( echo -e "$line" | cut -d"~" -f 4 | tr -d '\r' )
+ for grp in "${GRPS[@]}"; do
+ jank="${jank}{ \"oznaka\": \"${grp}\" }, "
+ done
+
+ jank="${jank::-2}"
+
+ curl --location "${URL}/termini" \
+ --header 'Content-Type: application/json' \
+ --data ' {
+ "pocetniTermin": "'"$pocetni_termin"'",
+ "krajnjiTermin": "'"$krajnji_termin"'",
+ "danUNedelji": "'"$dan_u_nedelji"'",
+ "tipNastave": "'"$tip_nastave"'",
+ "ucionica": {
+ "oznaka": "'"$ucionica_oznaka"'"
+ },
+ "profesor": {
+ "ime": "'"$profesor_ime"'",
+ "prezime": "'"$profesor_prezime"'"
+ },
+ "predmet": {
+ "naziv": "'"$predmet_naziv"'"
+ },
+ "grupe": [ '"$jank"' ]
+ }'
+
+ done < <( tail -n +2 $FILE | iconv -c -f utf-8 -t ascii | sed -r "s|\",\"|~|g; s|~ET~|~CET~|g; s|\"||g" | sort | uniq )
+}
+
+
+
+loadPredmeti
+loadProfesori
+loadGrupe
+loadUcionice
+
+sleep 1
+loadTermini
+
+echo -e "\n\n\nDone"
diff --git a/miscripts/qemu_helper.sh b/miscripts/qemu_helper.sh
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/miscripts/qemu_helper.sh
diff --git a/miscripts/rshred.txt b/miscripts/rshred.txt
new file mode 100644
index 0000000..99d6708
--- /dev/null
+++ b/miscripts/rshred.txt
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+NOTIFY="console"
+DELETE=""
+SHRED_OPTIONS=""
+FILES=()
+
+while [ -n "${1}" ]; do
+ case "${1}" in
+
+ "--zenity" )
+ NOTIFY="zenity"
+ ;;
+
+ "-q" | "--quiet" )
+ NOTIFY=""
+ ;;
+
+ "-u" | "--remove" )
+ SHRED_OPTIONS="${SHRED_OPTIONS} ${1}"
+ DELETE="true"
+ ;;
+
+ "-n" | "-s" )
+ SHRED_OPTIONS="${SHRED_OPTIONS} ${1} ${2}"
+ shift
+ ;;
+
+ "--")
+ shift
+ while [[ -n "${1}" ]]; do
+ [[ -e "${1}" ]] && FILES=( "${FILES[@]}" "${1}" )
+ shift
+ done
+ break
+ ;;
+
+ -* )
+ SHRED_OPTIONS="${SHRED_OPTIONS} ${1}"
+ ;;
+
+ * )
+ #FILES[${#FILES[*]}]="${1}"
+ if [ -e "${1}" ]; then
+ FILES=( "${FILES[@]}" "${1}" )
+ fi
+ ;;
+
+ esac
+
+ shift
+
+done
+
+for F in "${FILES[@]}"; do
+ [[ -e "${F}" ]] || continue
+ if [ -d "${F}" ]; then
+ find "${F}" -type f -exec shred ${SHRED_OPTIONS} {} +
+ [[ "${DELETE}" = "true" ]] && rm -r "${F}"
+ else
+ shred ${SHRED_OPTIONS} "${F}"
+ fi
+done
+
+exit 0
diff --git a/miscripts/shigoto_kfxx.sh b/miscripts/shigoto_kfxx.sh
new file mode 100644
index 0000000..29526ce
--- /dev/null
+++ b/miscripts/shigoto_kfxx.sh
@@ -0,0 +1,114 @@
+#!/bin/bash
+
+FIVEXX_ONLY=true
+CONTAINER_SELECT=false
+WRITE_TO_FILE=false
+FLAGS=""
+HELP_TEXT="script usage: $(basename $0) [-h (prints this message)] [-a (print all logs, not just 5xx errors)] [-c (view logs of a certain container)] [-C (view logs of all containers)] [-p (previous pod state)] [-s TIMEDELTA (print logs since TIMEDELTA)] pod_name"
+
+while getopts 'hacCwps:' OPTION; do
+ case "$OPTION" in
+ h)
+ echo "$HELP_TEXT" >&2 ; exit 0
+ ;;
+ a)
+ FIVEXX_ONLY=false
+ ;;
+ c)
+ CONTAINER_SELECT=true
+ ;;
+ C)
+ [[ $CONTAINER_SELECT == true ]] && echo "ERROR: -C AND -c CAN'T BE USED AS PART OF THE SAME COMMAND" && exit -2
+ FLAGS="$FLAGS --all-containers"
+ echo "VIEWING LOGS OF ALL CONTAINERS IN POD"
+ ;;
+ p)
+ FLAGS="$FLAGS -p"
+ echo "VIEWING LOGS OF POD'S PREVIOUS STATE"
+ ;;
+ w)
+ WRITE_TO_FILE=true
+ echo "WRITE TO FILE: TRUE"
+ ;;
+ s)
+ TIMEDELTA="$OPTARG"
+ echo "TIME DELTA SPECIFIED: $TIMEDELTA"
+ FLAGS="$FLAGS --since=$TIMEDELTA"
+ ;;
+ ?)
+ echo "$HELP_TEXT" >&2 ; exit 0
+ exit 0
+ ;;
+ esac
+done
+shift "$(($OPTIND -1))"
+
+POD_ARG="$1"
+ENV="$( kubectx -c | cut -d "-" -f3 )"
+POD_LIST="$( kubectl get pods --all-namespaces | grep "$POD_ARG" | awk '$0!=""{print NR, $0}' )"
+POD_NUM="$( echo "$POD_LIST" | wc -l )"
+POD=""
+CONTAINER=""
+
+get_containers () {
+ CONTAINER_LIST="$( kubectl get pods "$POD" -o jsonpath="{.spec['containers','initContainers'][*].name}" | tr ' ' '\n' | awk '$0!=""{print NR, $0}' )"
+ CONTAINER_NUM="$( echo "$CONTAINER_LIST" | wc -l )"
+ if [[ "$CONTAINER_NUM" -gt 1 ]]; then
+ echo -e "\nLIST OF CONTAINERS IN POD ${POD}:\n${CONTAINER_LIST}\n"
+ read -p 'PLEASE SELECT POD NUMBER: ' containerindex
+ [[ "$containerindex" =~ [0-9]+ ]] || echo "FUNKY INPUT, DEFAULTING TO 1" && containerindex=1
+ if [[ "$containerindex" -le "$CONTAINER_NUM" ]]; then
+ CONTAINER="$( echo "$CONTAINER_LIST" | sed -n "${containerindex}p" | sed -r "s|^[^ ]* *||g" )"
+ else
+ echo "ERROR: INDEX OF CONTAINER EXCEEDS NUMBER OF CONTAINERS FOUND INSIDE POD"
+ exit 1
+ fi
+ elif [[ "$CONTAINER_NUM" -eq 1 ]]; then
+ CONTAINER="$( echo "$CONTAINER_LIST" | sed -r "s|^[^ ]* *||g" )"
+ else
+ echo "NO CONTAINERS FOUND IN $POD"
+ exit -1
+ fi
+ FLAGS="$FLAGS --container="$CONTAINER""
+}
+
+get_logs () {
+ grepstr=""
+ echostr="ALL LOGS FOR POD ${POD}:\n"
+ tmp_file="$( mktemp -p "/tmp" "${POD}_logs_tmp_XXXXX" )"
+ file="${POD}_logs.txt"
+ NS="$( echo "$POD_LIST" | grep "$POD" | sed -r "s|^[^ ]* *([^ ]*) *(.*?)|\1|g" )"
+ [[ ! $( kubens -c | grep "$NS" ) ]] && kubens "$NS"
+ [[ $( kubens -c | grep "$NS" ) ]] || exit -1
+ [[ $CONTAINER_SELECT == true ]] && get_containers && echostr="$( echo "$echostr" | sed -r "s|:| (container $CONTAINER):|g" )"
+ [[ ! $FIVEXX_ONLY ]] && echostr="$( echo "$echostr" | sed -r "s|^ALL|5XX|" )" && grepstr="[^\.0-9a-zA-Z\-]5[0-9]{2}[^\.0-9a-zA-Z\-]"
+ echo -e "$echostr"
+ kubectl logs "$POD" $FLAGS --timestamps=true --prefix=true | grep --color=always -E "$grepstr" | tee "$tmp_file"
+
+ [[ "$WRITE_TO_FILE" = "true" ]] && cat "$tmp_file" | sed -e 's/\x1b\[[0-9;]*m//g' > "$file" && echo "Logs saved to '$file'."
+
+ rm -f "$tmp_file"
+}
+
+[[ -z "$POD_ARG" ]] && echo "ERROR: MUST SPECIFY POD" && exit -1
+
+echo -e "CURRENT ENV: $ENV\n"
+
+if [[ "$POD_NUM" -gt 1 ]]; then
+ echo -e "FOUND MORE THAN ONE POD THAT MATCHES STRING:\n${POD_LIST}\n"
+ read -p 'PLEASE SELECT POD NUMBER: ' podindex
+ [[ "$podindex" =~ [0-9]+ ]] || echo "FUNKY INPUT, DEFAULTING TO 1" && podindex=1
+ if [[ "$podindex" -le "$POD_NUM" ]]; then
+ POD="$( echo "$POD_LIST" | sed -n "${podindex}p" | sed -r "s|^([^ ]* *){2}||g" | grep -o -E "^[^ ]*" )"
+ get_logs
+ else
+ echo "ERROR: INDEX OF POD EXCEEDS NUMBER OF PODS FOUND"
+ exit 1
+ fi
+elif [[ "$POD_NUM" -eq 1 ]]; then
+ POD="$( echo "$POD_LIST" | sed -r "s|^([^ ]* *){2}||g" | grep -o -E "^[^ ]*" )"
+ get_logs
+else
+ echo "POD NOT FOUND ON $ENV"
+ exit -1
+fi
diff --git a/miscripts/shigoto_trivy_sorting_hat.sh b/miscripts/shigoto_trivy_sorting_hat.sh
new file mode 100644
index 0000000..2f7e1ae
--- /dev/null
+++ b/miscripts/shigoto_trivy_sorting_hat.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+# version: 4.0
+
+VULN_REPORT_PREV=""
+VULN_REPORT_FULL="vulnerable_images_full_$( date +'%Y-%m-%d_%s' ).txt"
+VULN_REPORT_NEW="vulnerable_images_to_report.txt"
+
+[ "$#" -lt 1 ] && echo "script usage: $(basename $0) [-h (prints this message)] [-p previous_report.txt] prometheus_dump.txt" >&2 && exit 0
+
+while getopts 'hp:' OPTION; do
+ case "$OPTION" in
+ h)
+ echo "script usage: $(basename $0) [-h (prints this message)] [-p previous_report.txt] prometheus_dump.txt" >&2 ; exit 0
+ ;;
+ p)
+ VULN_REPORT_PREV="$OPTARG"
+ echo "Previous trivy report: $VULN_REPORT_PREV"
+[[ -z "$VULN_REPORT_PREV" || ! $(file "$VULN_REPORT_PREV" | grep "txt: ASCII text") ]] && echo "ERROR: Option -p requires .txt file of previous report" && exit -1
+ ;;
+ ?)
+ echo "script usage: $(basename $0) [-h (prints this message)] [-p previous_report.txt] prometheus_dump.txt" >&2
+ exit 0
+ ;;
+ esac
+done
+shift "$(($OPTIND -1))"
+
+TRIVY_DUMP="$1"
+[[ -z "$TRIVY_DUMP" || ! $(file "$TRIVY_DUMP" | grep "txt: ASCII text") ]] && echo "ERROR: Script requires .txt file of raw alert data from Prometheus" && exit -1
+
+ENV="$( grep -o -E "cluster=([A-Z0-9]+-?)+" "$TRIVY_DUMP" | head -n 1 | cut -d "-" -f 3 )"
+
+[[ -z $( echo "$ENV" | grep -E "PROD|QSS|OAE|FAE" ) ]] && echo "ERROR: ENVIRONMENT NOT FOUND" && exit -1
+
+VULN_REPORT_FULL="${ENV}_${VULN_REPORT_FULL}"
+VULN_REPORT_NEW="${ENV}_${VULN_REPORT_NEW}"
+
+{ echo "REPORT TIMESTAMP: $(date +'%Y-%m-%d %H:%M')" ; cat "$TRIVY_DUMP" | sed -r "s/active=truealertname=ATTENTION>>>ImageVulnerabilitiesFound<<<WARNINGcluster=WE-POS-(DEV|FAE|OAE|QSS|PROD)-AKS-(SUPPORT|SVC)(-1|-2)?cluster_short_name=.*?cluster_type=.*?image_repository=/Image /g; s/image_tag=/:/g; s/namespace=/ in namespace /g; s/pos_alert=.*$//g" | sed '/Image/! d' | sort -V ; } > "$VULN_REPORT_FULL"
+
+VULN_REPORT_TMP="$( mktemp -p "/tmp" "vuln_report_tmp_XXXXX" )"
+if [[ -n "$VULN_REPORT_PREV" ]]; then
+ tail -n +2 "$VULN_REPORT_FULL" | grep -vf "$VULN_REPORT_PREV" > "$VULN_REPORT_TMP"
+else
+ tail -n +2 "$VULN_REPORT_FULL" > "$VULN_REPORT_TMP"
+fi
+
+NAMESPACE="<NONE>"
+
+head -n 1 "$VULN_REPORT_FULL" | sed -r "s/REPORT\ TIMESTAMP:/CURRENT\ REPORT\ TIMESTAMP: /g" > "$VULN_REPORT_NEW"
+head -n 1 "$VULN_REPORT_PREV" | sed -r "s/REPORT\ TIMESTAMP:/PREVIOUS\ REPORT\ TIMESTAMP:/g" >> "$VULN_REPORT_NEW"
+date1=$( sed -n '1p' "$VULN_REPORT_NEW" | sed -r "s/^.*?:\ +[0-9]{2}([0-9]{2})\-([0-9]+)\-([0-9]+)\ .*?$/\1\2\3/g")
+date2=$( sed -n '2p' "$VULN_REPORT_NEW" | sed -r "s/^.*?:\ +[0-9]{2}([0-9]{2})\-([0-9]+)\-([0-9]+)\ .*?$/\1\2\3/g")
+echo -e "DAYS SINCE LAST REPORT: $(( ($(date --date="$date1" +%s) - $(date --date="$date2" +%s) )/(60*60*24) ))" >> "$VULN_REPORT_NEW"
+
+while IFS= read -r line
+do
+ echo "$line"
+ CURR_NAMESPACE="$( echo "$line" | sed -r "s/^.* in namespace //g")"
+ CURR_IMAGE="$( echo "$line" | sed -r "s/^Image //g ; s/ in namespace.*$//g")"
+ [[ "$CURR_NAMESPACE" != "$NAMESPACE" ]] && echo -e "\n\nNAMESPACE: ${CURR_NAMESPACE}\n" >> "$VULN_REPORT_NEW"
+ echo "$CURR_IMAGE" >> "$VULN_REPORT_NEW"
+ NAMESPACE="$CURR_NAMESPACE"
+done < "$VULN_REPORT_TMP"
+
+rm -f "$VULN_REPORT_TMP"
diff --git a/miscripts/snap.sh b/miscripts/snap.sh
new file mode 100644
index 0000000..0a5b887
--- /dev/null
+++ b/miscripts/snap.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# Basic snapshot-style rsync backup script
+
+# Config
+OPT="-aPh"
+LINK="--link-dest=$HOME/Downloads/Snapshots/username/last"
+SRC="/home/jay/TXTFILES/"
+SNAP="$HOME/Downloads/Snapshots/"
+LAST="$HOME/Downloads/Snapshots/last"
+date=`date "+%Y-%b-%d:_%T"`
+
+# Run rsync to create snapshot
+rsync $OPT $LINK $SRC ${SNAP}$date
+
+# Remove symlink to previous snapshot
+rm -f $LAST
+
+# Create new symlink to latest snapshot for the next backup to hardlink
+ln -s ${SNAP}$date $LAST
diff --git a/miscripts/wide_play_cmus.sh b/miscripts/wide_play_cmus.sh
new file mode 100644
index 0000000..eeb6e55
--- /dev/null
+++ b/miscripts/wide_play_cmus.sh
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+
+# THE FINAL SOLUTION
+# DEPENDENCIES: sox, cmus
+# ANOTHER OPTION WOULD BE TO DMENU ALL THE OPTIONS, SO IT CAN BE RUN WITH ONLY ONE KEYBOARD SHORTCUT
+# AND I CAN'T HELP BUT THINK THAT THERE'S SOME WAY TO UNIFY THE PLAYLIST TYPES AND THE SINGLE-SONG BRANCH AND USE ONLY FLAGS INSTEAD OF IF
+# ALSO IT WOULD PROBABLY RUN FASTER IF I REPLACED EVERY FIND WITH LOCATE
+# OH WELL
+
+# look into types of parentheses, $(( )) is math for example
+# shuf is a thing
+# also xargs -r is a thing
+
+# [ "$(printf "Yes\\nNo" | dmenu -l 2 -i -p "Send $file to the trash?")" = "Yes" ]
+
+
+[[ ! $(pgrep -x cmus) ]] && xfce4-terminal -e cmus && exit
+
+
+SHORTCUTS=(
+ 'FUNCTION | TERMINAL EQUIVALENT | RECOMMENDED KEYBIND'
+ '------------------------------------------------------------------------------------------'
+ 'Play Song | play.sh | F8'
+ 'Queue Song | play.sh -q | F9'
+ 'Notify-send Queue | play.sh -n | F10'
+ 'Play/Pause Song | cmus-remote -u | Shift+F8'
+ 'Skip to Next Song | cmus-remote --next | Shift+F9'
+ 'Toggle Autoplay | cmus-remote -C "toggle continue" | Ctrl+F9'
+ 'Play Playlist | play.sh -l | Ctrl+Shift+F8'
+ 'Queue Playlist | play.sh -lq | Ctrl+Shift+F9'
+ 'Clear Playlist | play.sh -c | Ctrl+Shift+F10'
+ 'Increase Volume | cmus-remote -v +5% | Shift+Upper side mouse button'
+ 'Decrease Volume | cmus-remote -v -5% | Shift+Lower side mouse button'
+)
+
+playlist_flag=false
+queue_flag=false
+clear_flag=false
+current_song=$(cmus-remote -Q | grep file | sed "s|file ||g")
+
+MUSIC="$HOME/music"
+SONG=""
+SED_STRING="s|^|player-play |"
+ROFI_THEME="BernBlue"
+
+#E0E04B
+#AAAA00
+
+while getopts "hnlqc" opt; do
+ case $opt in
+ h) echo -e "usage: $0 [-h help] [-n notify-send queue] [-l list] [-q queue] [-c clear]\n\nSuggested Keyboard Shortcuts:\n"; printf '%s\n' "${SHORTCUTS[@]}"; exit ;; # PRINT HELP IN TERMINAL
+# n) notify-send -u low -t 15000 -i $HOME/stuf/rikanom.png "Songs currently in queue:" "$(cmus-remote -C 'save -q -' | sed -r 's|^\/([^\/]+\/)+||g' )"; exit ;; # NOTIFY-SEND QUEUE
+ n) "$HOME/stuf/scripts/notification_wrapper.sh" "\n> $( echo $current_song | sed -r 's|^\/([^\/]+\/)+||g' ) \n$( cmus-remote -C 'save -q -' | sed -r 's|^\/([^\/]+\/)+||g' | head -n 50 )" "UNIVPLAY" ; exit ;; # NOTIFY-SEND QUEUE VIA OWN WRAPPER
+ l) playlist_flag=true; ROFI_THEME="BernViolet" ;; # SET PLAYLIST FLAG, CHANGE DMENU COLOR
+ q) queue_flag=true; SED_STRING="s|^|add -q |"; ROFI_THEME="${ROFI_THEME}Queue" ;; # SET QUEUE FLAG, CHANGE DMENU TEXT
+ c) clear_flag=true; ROFI_THEME="BernRed" ;; # SET CLEAR FLAG, CHANGE DMENU COLOR/TEXT
+ ?) echo "error: option -$OPTARG is not implemented"; exit ;;
+ esac
+done
+
+if $clear_flag ; then
+
+ CHOICE=$(echo -e "1. Keep only the currently playing song\n2. Clear everything\n3. Abort" \
+ | rofi -dmenu -i -no-custom -p "" -theme "$ROFI_THEME" -async-pre-read 3 -no-click-to-exit )
+ echo "$CHOICE" | grep "1" &> /dev/null && cmus-remote -q -c
+ # fuck you cmus
+ echo "$CHOICE" | grep "2" &> /dev/null && cmus-remote -q -c && sox -n -r 44100 -c 2 /tmp/silence.wav trim 0.0 0.5 && cmus-remote -C "player-play /tmp/silence.wav" && rm /tmp/silence.wav && cmus-remote -C "set continue=false"
+ exit
+fi
+
+
+
+
+if $playlist_flag ; then
+
+ # FIND EVERY DIRECTORY WITH AN AUDIO FILE IN IT AND PIPE IT INTO DMENU
+ PL_DIR=$(find $MUSIC -type f -iregex ".*\.\(mp3\|flac\|m4a\|ogg\)$" -printf '%h/\n' | uniq \
+ | rofi -dmenu -i -no-custom -p "" -theme "$ROFI_THEME" -async-pre-read 15 -no-click-to-exit )
+
+ if [[ -n $PL_DIR ]]; then
+
+ $queue_flag || cmus-remote -q -c # || OPERATOR; IF QUEUE FLAG IS FALSE, THEN CLEAR THE QUEUE
+ find "$PL_DIR" -maxdepth 1 -type f | sort | sed "s|^|add -q |" | sed -r "s|'|\\\'|g" | xargs -I{} cmus-remote -C "{}" # FIND EVERY SONG IN THE DIRECTORY (IGNORING ANY NESTED DIRECTORIES) AND PIPE THEM INTO CMUS-REMOTE
+ $queue_flag || cmus-remote -q --next # || OPERATOR; IF QUEUE FLAG IS FALSE, PUSH THE FIRST-QUEUED SONG
+ $queue_flag || cmus-remote -p # || OPERATOR; IF QUEUE FLAG IS FALSE, PLAY THE PUSHED SONG
+ cmus-remote -C "set continue=true" # ENABLE AUTOPLAY
+ cmus-remote -C "set play_library=false" # DISABLE ORDINARY PLAYLIST PLAYBACK JUST IN CASE
+ fi
+
+else
+
+ # FIND EVERY AUDIO FILE AND PIPE IT INTO ROFI, IN TWO LINES
+ SONG=$( find $MUSIC -type f -iregex ".*\.\(mp3\|flac\|m4a\|ogg\)$" -printf '/%P\n' | sort --version-sort | sed -r "s|(^\/([^\/]+\/)+)(([^\/])+$)|\1\n\3\x0f|g; $ s|.{1}$||" | paste -sd '\n\0' \
+ | rofi -dmenu -sep '\x0f' -eh 2 -i -no-custom -p "" -theme "$ROFI_THEME" -async-pre-read 15 -no-click-to-exit | paste -sd '' )
+
+ [[ -n $SONG ]] && [[ -n "$current_song" ]] && ! $queue_flag && cmus-remote -C "add -Q $current_song" # IF QUEUE FLAG IS FALSE, PLACE CURRENTLY PLAYING SONG AT THE END OF THE QUEUE
+ [[ -n $SONG ]] && echo "${MUSIC}${SONG}" | sed "$SED_STRING" | cmus-remote # MUCH CLEANER THAN DMENU
+ [[ -n $SONG ]] && cmus-remote -C "set continue=$queue_flag" # TOGGLE AUTOPLAY BASED ON CIRCUMSTANCES
+
+fi
diff --git a/miscripts/wide_play_dmenu.sh b/miscripts/wide_play_dmenu.sh
new file mode 100644
index 0000000..96a9705
--- /dev/null
+++ b/miscripts/wide_play_dmenu.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+
+
+# THE FINAL SOLUTION
+# DEPENDENCIES: sox, cmus
+# ANOTHER OPTION WOULD BE TO DMENU ALL THE OPTIONS, SO IT CAN BE RUN WITH ONLY ONE KEYBOARD SHORTCUT
+# AND I CAN'T HELP BUT THINK THAT THERE'S SOME WAY TO UNIFY THE PLAYLIST TYPES AND THE SINGLE-SONG BRANCH AND USE ONLY FLAGS INSTEAD OF IF
+# ALSO IT WOULD PROBABLY RUN FASTER IF I REPLACED EVERY FIND WITH LOCATE
+# OH WELL
+
+# look into types of parentheses, $(( )) is math for example
+# shuf is a thing
+# also xargs -r is a thing
+
+
+[[ ! $(pgrep -x cmus) ]] && xfce4-terminal -e cmus && exit
+
+
+SHORTCUTS=(
+ 'FUNCTION | TERMINAL EQUIVALENT | RECOMMENDED KEYBIND'
+ '------------------------------------------------------------------------------------------'
+ 'Play Song | play.sh | F8'
+ 'Queue Song | play.sh -q | F9'
+ 'Notify-send Queue | play.sh -n | F10'
+ 'Play/Pause Song | cmus-remote -u | Shift+F8'
+ 'Skip to Next Song | cmus-remote --next | Shift+F9'
+ 'Toggle Autoplay | cmus-remote -C "toggle continue" | Ctrl+F9'
+ 'Play Playlist | play.sh -l | Ctrl+Shift+F8'
+ 'Queue Playlist | play.sh -lq | Ctrl+Shift+F9'
+ 'Clear Playlist | play.sh -c | Ctrl+Shift+F10'
+ 'Increase Volume | cmus-remote -v +5% | Shift+Upper side mouse button'
+ 'Decrease Volume | cmus-remote -v -5% | Shift+Lower side mouse button'
+)
+
+playlist_flag=false
+queue_flag=false
+clear_flag=false
+current_song=$(cmus-remote -Q | grep file | sed "s|file ||g")
+
+MUSIC="$HOME/music"
+SONG=""
+SED_STRING="s|^|player-play |"
+DMENU_APPEARANCE="mononoki;11;#191919;#AAAAAA;#0000AA;#FFFFFF;Choose your jam:"
+
+#E0E04B
+#AAAA00
+
+while getopts "hnlqc" opt; do
+ case $opt in
+ h) echo -e "usage: $0 [-h help] [-n notify-send queue] [-l list] [-q queue] [-c clear]\n\nSuggested Keyboard Shortcuts:\n"; printf '%s\n' "${SHORTCUTS[@]}"; exit ;; # PRINT HELP IN TERMINAL
+# n) notify-send -u low -t 15000 -i $HOME/stuf/rikanom.png "Songs currently in queue:" "$(cmus-remote -C 'save -q -' | sed -r 's|^\/([^\/]+\/)+||g' )"; exit ;; # NOTIFY-SEND QUEUE
+ n) $HOME/stuf/scripts/notification_wrapper.sh "\n> $( echo $current_song | sed -r 's|^\/([^\/]+\/)+||g' ) \n$( cmus-remote -C 'save -q -' | sed -r 's|^\/([^\/]+\/)+||g' | head -n 50 )" "UNIVPLAY" ; exit ;; # NOTIFY-SEND QUEUE VIA OWN WRAPPER
+ l) playlist_flag=true; DMENU_APPEARANCE="mononoki;11;#191919;#AAAAAA;#005000;#FFFFFF;Choose your playlist:" ;; # SET PLAYLIST FLAG, CHANGE DMENU COLOR
+ q) queue_flag=true; SED_STRING="s|^|add -q |"; DMENU_APPEARANCE="mononoki;11;#191919;#AAAA00;#0000AA;#FFFF00;Queue your jam:" ;; # SET QUEUE FLAG, CHANGE DMENU TEXT
+ c) clear_flag=true; DMENU_APPEARANCE="mononoki;11;#191919;#AAAAAA;#900D09;#FFFFFF;Choose queue clear method:" ;; # SET CLEAR FLAG, CHANGE DMENU COLOR/TEXT
+ ?) echo "error: option -$OPTARG is not implemented"; exit ;;
+ esac
+done
+
+
+for i in {1..7}
+do
+ declare "dm$i=$(echo $DMENU_APPEARANCE | cut -f$i -d';')" # CONVERT DMENU APPEARANCE STRIP INTO SEPARATE PARAMETERS
+done
+
+
+if $clear_flag ; then
+
+ CHOICE=$(echo -e "1. Keep only the currently playing song\n2. Clear everything\n3. Abort" \
+ | dmenu -fn "$([[ $(fc-match "$dm1" | grep "$dm1") ]] && fc-match -f %{family} "$dm1" || fc-match -f %{family} mono)-$dm2" -l 10 -i -nb "$dm3" -nf "$dm4" -sb "$dm5" -sf "$dm6" -p "$dm7" )
+ echo "$CHOICE" | grep "1" &> /dev/null && cmus-remote -q -c
+ # fuck you cmus
+ echo "$CHOICE" | grep "2" &> /dev/null && cmus-remote -q -c && sox -n -r 44100 -c 2 /tmp/silence.wav trim 0.0 0.5 && cmus-remote -C "player-play /tmp/silence.wav" && rm /tmp/silence.wav && cmus-remote -C "set continue=false"
+ exit
+fi
+
+
+
+
+if $playlist_flag ; then
+
+ # FIND EVERY DIRECTORY WITH AN AUDIO FILE IN IT AND PIPE IT INTO DMENU
+ PL_DIR=$(find $MUSIC -type f -iregex ".*\.\(mp3\|flac\|m4a\|ogg\)$" | sed -r "s|([^\/])+$||g" | sort --version-sort | uniq \
+ | dmenu -fn "$([[ $(fc-match "$dm1" | grep "$dm1") ]] && fc-match -f %{family} "$dm1" || fc-match -f %{family} mono)-$dm2" -l 10 -i -nb "$dm3" -nf "$dm4" -sb "$dm5" -sf "$dm6" -p "$dm7" )
+
+ if [[ -n $PL_DIR ]]; then
+
+ $queue_flag || cmus-remote -q -c # || OPERATOR; IF QUEUE FLAG IS FALSE, THEN CLEAR THE QUEUE
+ find "$PL_DIR" -maxdepth 1 -type f | sort | sed "s|^|add -q |" | sed -r "s|'|\\\'|g" | xargs -I{} cmus-remote -C "{}" # FIND EVERY SONG IN THE DIRECTORY (IGNORING ANY NESTED DIRECTORIES) AND PIPE THEM INTO CMUS-REMOTE
+ $queue_flag || cmus-remote -q --next # || OPERATOR; IF QUEUE FLAG IS FALSE, PUSH THE FIRST-QUEUED SONG
+ $queue_flag || cmus-remote -p # || OPERATOR; IF QUEUE FLAG IS FALSE, PLAY THE PUSHED SONG
+ cmus-remote -C "set continue=true" # ENABLE AUTOPLAY
+ cmus-remote -C "set play_library=false" # DISABLE ORDINARY PLAYLIST PLAYBACK JUST IN CASE
+ fi
+
+else
+
+ # FIND EVERY AUDIO FILE AND PIPE IT INTO DMENU
+ SONG=$(find $MUSIC -type f -iregex ".*\.\(mp3\|flac\|m4a\|ogg\)$" | sed -r "s|^\/([^\/]+\/)+||g" | sort --version-sort \
+ | dmenu -fn "$([[ $(fc-match "$dm1" | grep "$dm1") ]] && fc-match -f %{family} "$dm1" || fc-match -f %{family} mono)-$dm2" -l 10 -i -nb "$dm3" -nf "$dm4" -sb "$dm5" -sf "$dm6" -p "$dm7" )
+
+ [[ -n $SONG ]] && [[ -n "$current_song" ]] && ! $queue_flag && cmus-remote -C "add -Q $current_song" # IF QUEUE FLAG IS FALSE, PLACE CURRENTLY PLAYING SONG AT THE END OF THE QUEUE
+ [[ -n $SONG ]] && echo $SONG | sed -r "s|'|\\\'|g" | xargs -I{} find $MUSIC -type f -iname "{}" | head -n 1 | sed "$SED_STRING" | cmus-remote # FIND THE CLEANED-UP SONG'S FULL PATH AND PIPE IT INTO CMUS-REMOTE
+ [[ -n $SONG ]] && cmus-remote -C "set continue=$queue_flag" # TOGGLE AUTOPLAY BASED ON CIRCUMSTANCES
+
+fi \ No newline at end of file
diff --git a/miscripts/wireguard-install.sh b/miscripts/wireguard-install.sh
new file mode 100644
index 0000000..22ca7cc
--- /dev/null
+++ b/miscripts/wireguard-install.sh
@@ -0,0 +1,474 @@
+#!/bin/bash
+
+# Secure WireGuard server installer
+# https://github.com/angristan/wireguard-install
+
+RED='\033[0;31m'
+ORANGE='\033[0;33m'
+NC='\033[0m'
+
+function isRoot() {
+ if [ "${EUID}" -ne 0 ]; then
+ echo "You need to run this script as root"
+ exit 1
+ fi
+}
+
+function checkVirt() {
+ if [ "$(systemd-detect-virt)" == "openvz" ]; then
+ echo "OpenVZ is not supported"
+ exit 1
+ fi
+
+ if [ "$(systemd-detect-virt)" == "lxc" ]; then
+ echo "LXC is not supported (yet)."
+ echo "WireGuard can technically run in an LXC container,"
+ echo "but the kernel module has to be installed on the host,"
+ echo "the container has to be run with some specific parameters"
+ echo "and only the tools need to be installed in the container."
+ exit 1
+ fi
+}
+
+function checkOS() {
+ # Check OS version
+ if [[ -e /etc/debian_version ]]; then
+ source /etc/os-release
+ OS="${ID}" # debian or ubuntu
+ if [[ ${ID} == "debian" || ${ID} == "raspbian" ]]; then
+ if [[ ${VERSION_ID} -lt 10 ]]; then
+ echo "Your version of Debian (${VERSION_ID}) is not supported. Please use Debian 10 Buster or later"
+ exit 1
+ fi
+ OS=debian # overwrite if raspbian
+ fi
+ elif [[ -e /etc/rocky-release ]]; then
+ source /etc/os-release
+ OS=almalinux
+ elif [[ -e /etc/almalinux-release ]]; then
+ source /etc/os-release
+ os=almalinux
+ elif [[ -e /etc/fedora-release ]]; then
+ source /etc/os-release
+ OS="${ID}"
+ elif [[ -e /etc/centos-release ]]; then
+ source /etc/os-release
+ OS=centos
+ elif [[ -e /etc/oracle-release ]]; then
+ source /etc/os-release
+ OS=oracle
+ elif [[ -e /etc/arch-release ]]; then
+ OS=arch
+ else
+ echo "Looks like you aren't running this installer on a Debian, Ubuntu, Fedora, CentOS, AlmaLinux, Oracle or Arch Linux system"
+ exit 1
+ fi
+}
+
+function initialCheck() {
+ isRoot
+ checkVirt
+ checkOS
+}
+
+function installQuestions() {
+ echo "Welcome to the WireGuard installer!"
+ echo "The git repository is available at: https://github.com/angristan/wireguard-install"
+ echo ""
+ echo "I need to ask you a few questions before starting the setup."
+ echo "You can leave the default options and just press enter if you are ok with them."
+ echo ""
+
+ # Detect public IPv4 or IPv6 address and pre-fill for the user
+ SERVER_PUB_IP=$(ip -4 addr | sed -ne 's|^.* inet \([^/]*\)/.* scope global.*$|\1|p' | awk '{print $1}' | head -1)
+ if [[ -z ${SERVER_PUB_IP} ]]; then
+ # Detect public IPv6 address
+ SERVER_PUB_IP=$(ip -6 addr | sed -ne 's|^.* inet6 \([^/]*\)/.* scope global.*$|\1|p' | head -1)
+ fi
+ read -rp "IPv4 or IPv6 public address: " -e -i "${SERVER_PUB_IP}" SERVER_PUB_IP
+
+ # Detect public interface and pre-fill for the user
+ SERVER_NIC="$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1)"
+ until [[ ${SERVER_PUB_NIC} =~ ^[a-zA-Z0-9_]+$ ]]; do
+ read -rp "Public interface: " -e -i "${SERVER_NIC}" SERVER_PUB_NIC
+ done
+
+ until [[ ${SERVER_WG_NIC} =~ ^[a-zA-Z0-9_]+$ && ${#SERVER_WG_NIC} -lt 16 ]]; do
+ read -rp "WireGuard interface name: " -e -i wg0 SERVER_WG_NIC
+ done
+
+ until [[ ${SERVER_WG_IPV4} =~ ^([0-9]{1,3}\.){3} ]]; do
+ read -rp "Server's WireGuard IPv4: " -e -i 10.66.66.1 SERVER_WG_IPV4
+ done
+
+ until [[ ${SERVER_WG_IPV6} =~ ^([a-f0-9]{1,4}:){3,4}: ]]; do
+ read -rp "Server's WireGuard IPv6: " -e -i fd42:42:42::1 SERVER_WG_IPV6
+ done
+
+ # Generate random number within private ports range
+ RANDOM_PORT=$(shuf -i49152-65535 -n1)
+ until [[ ${SERVER_PORT} =~ ^[0-9]+$ ]] && [ "${SERVER_PORT}" -ge 1 ] && [ "${SERVER_PORT}" -le 65535 ]; do
+ read -rp "Server's WireGuard port [1-65535]: " -e -i "${RANDOM_PORT}" SERVER_PORT
+ done
+
+ # Adguard DNS by default
+ until [[ ${CLIENT_DNS_1} =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; do
+ read -rp "First DNS resolver to use for the clients: " -e -i 94.140.14.14 CLIENT_DNS_1
+ done
+ until [[ ${CLIENT_DNS_2} =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; do
+ read -rp "Second DNS resolver to use for the clients (optional): " -e -i 94.140.15.15 CLIENT_DNS_2
+ if [[ ${CLIENT_DNS_2} == "" ]]; then
+ CLIENT_DNS_2="${CLIENT_DNS_1}"
+ fi
+ done
+
+ echo ""
+ echo "Okay, that was all I needed. We are ready to setup your WireGuard server now."
+ echo "You will be able to generate a client at the end of the installation."
+ read -n1 -r -p "Press any key to continue..."
+}
+
+function installWireGuard() {
+ # Run setup questions first
+ installQuestions
+
+ # Install WireGuard tools and module
+ if [[ ${OS} == 'ubuntu' ]] || [[ ${OS} == 'debian' && ${VERSION_ID} -gt 10 ]]; then
+ apt-get update
+ apt-get install -y wireguard iptables resolvconf qrencode
+ elif [[ ${OS} == 'debian' ]]; then
+ if ! grep -rqs "^deb .* buster-backports" /etc/apt/; then
+ echo "deb http://deb.debian.org/debian buster-backports main" >/etc/apt/sources.list.d/backports.list
+ apt-get update
+ fi
+ apt update
+ apt-get install -y iptables resolvconf qrencode
+ apt-get install -y -t buster-backports wireguard
+ elif [[ ${OS} == 'fedora' ]]; then
+ if [[ ${VERSION_ID} -lt 32 ]]; then
+ dnf install -y dnf-plugins-core
+ dnf copr enable -y jdoss/wireguard
+ dnf install -y wireguard-dkms
+ fi
+ dnf install -y wireguard-tools iptables qrencode
+ elif [[ ${OS} == 'almalinux' ]]; then
+ dnf -y install epel-release elrepo-release
+ dnf -y install wireguard-tools iptables qrencode
+ if [[ ${VERSION_ID} == 8* ]]; then
+ dnf -y install kmod-wireguard
+ fi
+ elif [[ ${OS} == 'centos' ]]; then
+ yum -y install epel-release elrepo-release
+ if [[ ${VERSION_ID} -eq 7 ]]; then
+ yum -y install yum-plugin-elrepo
+ fi
+ yum -y install kmod-wireguard wireguard-tools iptables qrencode
+ elif [[ ${OS} == 'oracle' ]]; then
+ dnf install -y oraclelinux-developer-release-el8
+ dnf config-manager --disable -y ol8_developer
+ dnf config-manager --enable -y ol8_developer_UEKR6
+ dnf config-manager --save -y --setopt=ol8_developer_UEKR6.includepkgs='wireguard-tools*'
+ dnf install -y wireguard-tools qrencode iptables
+ elif [[ ${OS} == 'arch' ]]; then
+ pacman -S --needed --noconfirm wireguard-tools qrencode
+ fi
+
+ # Make sure the directory exists (this does not seem the be the case on fedora)
+ mkdir /etc/wireguard >/dev/null 2>&1
+
+ chmod 600 -R /etc/wireguard/
+
+ SERVER_PRIV_KEY=$(wg genkey)
+ SERVER_PUB_KEY=$(echo "${SERVER_PRIV_KEY}" | wg pubkey)
+
+ # Save WireGuard settings
+ echo "SERVER_PUB_IP=${SERVER_PUB_IP}
+SERVER_PUB_NIC=${SERVER_PUB_NIC}
+SERVER_WG_NIC=${SERVER_WG_NIC}
+SERVER_WG_IPV4=${SERVER_WG_IPV4}
+SERVER_WG_IPV6=${SERVER_WG_IPV6}
+SERVER_PORT=${SERVER_PORT}
+SERVER_PRIV_KEY=${SERVER_PRIV_KEY}
+SERVER_PUB_KEY=${SERVER_PUB_KEY}
+CLIENT_DNS_1=${CLIENT_DNS_1}
+CLIENT_DNS_2=${CLIENT_DNS_2}" >/etc/wireguard/params
+
+ # Add server interface
+ echo "[Interface]
+Address = ${SERVER_WG_IPV4}/24,${SERVER_WG_IPV6}/64
+ListenPort = ${SERVER_PORT}
+PrivateKey = ${SERVER_PRIV_KEY}" >"/etc/wireguard/${SERVER_WG_NIC}.conf"
+
+ if pgrep firewalld; then
+ FIREWALLD_IPV4_ADDRESS=$(echo "${SERVER_WG_IPV4}" | cut -d"." -f1-3)".0"
+ FIREWALLD_IPV6_ADDRESS=$(echo "${SERVER_WG_IPV6}" | sed 's/:[^:]*$/:0/')
+ echo "PostUp = firewall-cmd --add-port ${SERVER_PORT}/udp && firewall-cmd --add-rich-rule='rule family=ipv4 source address=${FIREWALLD_IPV4_ADDRESS}/24 masquerade' && firewall-cmd --add-rich-rule='rule family=ipv6 source address=${FIREWALLD_IPV6_ADDRESS}/24 masquerade'
+PostDown = firewall-cmd --remove-port ${SERVER_PORT}/udp && firewall-cmd --remove-rich-rule='rule family=ipv4 source address=${FIREWALLD_IPV4_ADDRESS}/24 masquerade' && firewall-cmd --remove-rich-rule='rule family=ipv6 source address=${FIREWALLD_IPV6_ADDRESS}/24 masquerade'" >>"/etc/wireguard/${SERVER_WG_NIC}.conf"
+ else
+ echo "PostUp = iptables -A FORWARD -i ${SERVER_PUB_NIC} -o ${SERVER_WG_NIC} -j ACCEPT; iptables -A FORWARD -i ${SERVER_WG_NIC} -j ACCEPT; iptables -t nat -A POSTROUTING -o ${SERVER_PUB_NIC} -j MASQUERADE; ip6tables -A FORWARD -i ${SERVER_WG_NIC} -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ${SERVER_PUB_NIC} -j MASQUERADE
+PostDown = iptables -D FORWARD -i ${SERVER_PUB_NIC} -o ${SERVER_WG_NIC} -j ACCEPT; iptables -D FORWARD -i ${SERVER_WG_NIC} -j ACCEPT; iptables -t nat -D POSTROUTING -o ${SERVER_PUB_NIC} -j MASQUERADE; ip6tables -D FORWARD -i ${SERVER_WG_NIC} -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ${SERVER_PUB_NIC} -j MASQUERADE" >>"/etc/wireguard/${SERVER_WG_NIC}.conf"
+ fi
+
+ # Enable routing on the server
+ echo "net.ipv4.ip_forward = 1
+net.ipv6.conf.all.forwarding = 1" >/etc/sysctl.d/wg.conf
+
+ sysctl --system
+
+ systemctl start "wg-quick@${SERVER_WG_NIC}"
+ systemctl enable "wg-quick@${SERVER_WG_NIC}"
+
+ newClient
+ echo "If you want to add more clients, you simply need to run this script another time!"
+
+ # Check if WireGuard is running
+ systemctl is-active --quiet "wg-quick@${SERVER_WG_NIC}"
+ WG_RUNNING=$?
+
+ # WireGuard might not work if we updated the kernel. Tell the user to reboot
+ if [[ ${WG_RUNNING} -ne 0 ]]; then
+ echo -e "\n${RED}WARNING: WireGuard does not seem to be running.${NC}"
+ echo -e "${ORANGE}You can check if WireGuard is running with: systemctl status wg-quick@${SERVER_WG_NIC}${NC}"
+ echo -e "${ORANGE}If you get something like \"Cannot find device ${SERVER_WG_NIC}\", please reboot!${NC}"
+ fi
+}
+
+function newClient() {
+ ENDPOINT="${SERVER_PUB_IP}:${SERVER_PORT}"
+
+ echo ""
+ echo "Tell me a name for the client."
+ echo "The name must consist of alphanumeric character. It may also include an underscore or a dash and can't exceed 15 chars."
+
+ until [[ ${CLIENT_NAME} =~ ^[a-zA-Z0-9_-]+$ && ${CLIENT_EXISTS} == '0' && ${#CLIENT_NAME} -lt 16 ]]; do
+ read -rp "Client name: " -e CLIENT_NAME
+ CLIENT_EXISTS=$(grep -c -E "^### Client ${CLIENT_NAME}\$" "/etc/wireguard/${SERVER_WG_NIC}.conf")
+
+ if [[ ${CLIENT_EXISTS} == '1' ]]; then
+ echo ""
+ echo "A client with the specified name was already created, please choose another name."
+ echo ""
+ fi
+ done
+
+ for DOT_IP in {2..254}; do
+ DOT_EXISTS=$(grep -c "${SERVER_WG_IPV4::-1}${DOT_IP}" "/etc/wireguard/${SERVER_WG_NIC}.conf")
+ if [[ ${DOT_EXISTS} == '0' ]]; then
+ break
+ fi
+ done
+
+ if [[ ${DOT_EXISTS} == '1' ]]; then
+ echo ""
+ echo "The subnet configured supports only 253 clients."
+ exit 1
+ fi
+
+ BASE_IP=$(echo "$SERVER_WG_IPV4" | awk -F '.' '{ print $1"."$2"."$3 }')
+ until [[ ${IPV4_EXISTS} == '0' ]]; do
+ read -rp "Client's WireGuard IPv4: ${BASE_IP}." -e -i "${DOT_IP}" DOT_IP
+ CLIENT_WG_IPV4="${BASE_IP}.${DOT_IP}"
+ IPV4_EXISTS=$(grep -c "$CLIENT_WG_IPV4/24" "/etc/wireguard/${SERVER_WG_NIC}.conf")
+
+ if [[ ${IPV4_EXISTS} == '1' ]]; then
+ echo ""
+ echo "A client with the specified IPv4 was already created, please choose another IPv4."
+ echo ""
+ fi
+ done
+
+ BASE_IP=$(echo "$SERVER_WG_IPV6" | awk -F '::' '{ print $1 }')
+ until [[ ${IPV6_EXISTS} == '0' ]]; do
+ read -rp "Client's WireGuard IPv6: ${BASE_IP}::" -e -i "${DOT_IP}" DOT_IP
+ CLIENT_WG_IPV6="${BASE_IP}::${DOT_IP}"
+ IPV6_EXISTS=$(grep -c "${CLIENT_WG_IPV6}/64" "/etc/wireguard/${SERVER_WG_NIC}.conf")
+
+ if [[ ${IPV6_EXISTS} == '1' ]]; then
+ echo ""
+ echo "A client with the specified IPv6 was already created, please choose another IPv6."
+ echo ""
+ fi
+ done
+
+ # Generate key pair for the client
+ CLIENT_PRIV_KEY=$(wg genkey)
+ CLIENT_PUB_KEY=$(echo "${CLIENT_PRIV_KEY}" | wg pubkey)
+ CLIENT_PRE_SHARED_KEY=$(wg genpsk)
+
+ # Home directory of the user, where the client configuration will be written
+ if [ -e "/home/${CLIENT_NAME}" ]; then
+ # if $1 is a user name
+ HOME_DIR="/home/${CLIENT_NAME}"
+ elif [ "${SUDO_USER}" ]; then
+ # if not, use SUDO_USER
+ if [ "${SUDO_USER}" == "root" ]; then
+ # If running sudo as root
+ HOME_DIR="/root"
+ else
+ HOME_DIR="/home/${SUDO_USER}"
+ fi
+ else
+ # if not SUDO_USER, use /root
+ HOME_DIR="/root"
+ fi
+
+ # Create client file and add the server as a peer
+ echo "[Interface]
+PrivateKey = ${CLIENT_PRIV_KEY}
+Address = ${CLIENT_WG_IPV4}/32,${CLIENT_WG_IPV6}/128
+DNS = ${CLIENT_DNS_1},${CLIENT_DNS_2}
+
+[Peer]
+PublicKey = ${SERVER_PUB_KEY}
+PresharedKey = ${CLIENT_PRE_SHARED_KEY}
+Endpoint = ${ENDPOINT}
+AllowedIPs = 0.0.0.0/0,::/0" >>"${HOME_DIR}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.conf"
+
+ # Add the client as a peer to the server
+ echo -e "\n### Client ${CLIENT_NAME}
+[Peer]
+PublicKey = ${CLIENT_PUB_KEY}
+PresharedKey = ${CLIENT_PRE_SHARED_KEY}
+AllowedIPs = ${CLIENT_WG_IPV4}/32,${CLIENT_WG_IPV6}/128" >>"/etc/wireguard/${SERVER_WG_NIC}.conf"
+
+ wg syncconf "${SERVER_WG_NIC}" <(wg-quick strip "${SERVER_WG_NIC}")
+
+ echo -e "\nHere is your client config file as a QR Code:"
+
+ qrencode -t ansiutf8 -l L <"${HOME_DIR}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.conf"
+
+ echo "It is also available in ${HOME_DIR}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.conf"
+}
+
+function revokeClient() {
+ NUMBER_OF_CLIENTS=$(grep -c -E "^### Client" "/etc/wireguard/${SERVER_WG_NIC}.conf")
+ if [[ ${NUMBER_OF_CLIENTS} == '0' ]]; then
+ echo ""
+ echo "You have no existing clients!"
+ exit 1
+ fi
+
+ echo ""
+ echo "Select the existing client you want to revoke"
+ grep -E "^### Client" "/etc/wireguard/${SERVER_WG_NIC}.conf" | cut -d ' ' -f 3 | nl -s ') '
+ until [[ ${CLIENT_NUMBER} -ge 1 && ${CLIENT_NUMBER} -le ${NUMBER_OF_CLIENTS} ]]; do
+ if [[ ${CLIENT_NUMBER} == '1' ]]; then
+ read -rp "Select one client [1]: " CLIENT_NUMBER
+ else
+ read -rp "Select one client [1-${NUMBER_OF_CLIENTS}]: " CLIENT_NUMBER
+ fi
+ done
+
+ # match the selected number to a client name
+ CLIENT_NAME=$(grep -E "^### Client" "/etc/wireguard/${SERVER_WG_NIC}.conf" | cut -d ' ' -f 3 | sed -n "${CLIENT_NUMBER}"p)
+
+ # remove [Peer] block matching $CLIENT_NAME
+ sed -i "/^### Client ${CLIENT_NAME}\$/,/^$/d" "/etc/wireguard/${SERVER_WG_NIC}.conf"
+
+ # remove generated client file
+ rm -f "${HOME}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.conf"
+
+ # restart wireguard to apply changes
+ wg syncconf "${SERVER_WG_NIC}" <(wg-quick strip "${SERVER_WG_NIC}")
+}
+
+function uninstallWg() {
+ echo ""
+ read -rp "Do you really want to remove WireGuard? [y/n]: " -e REMOVE
+ REMOVE=${REMOVE:-n}
+ if [[ $REMOVE == 'y' ]]; then
+ checkOS
+
+ systemctl stop "wg-quick@${SERVER_WG_NIC}"
+ systemctl disable "wg-quick@${SERVER_WG_NIC}"
+
+ if [[ ${OS} == 'ubuntu' ]]; then
+ apt-get autoremove --purge -y wireguard qrencode
+ elif [[ ${OS} == 'debian' ]]; then
+ apt-get autoremove --purge -y wireguard qrencode
+ elif [[ ${OS} == 'fedora' ]]; then
+ dnf remove -y wireguard-tools qrencode
+ if [[ ${VERSION_ID} -lt 32 ]]; then
+ dnf remove -y wireguard-dkms
+ dnf copr disable -y jdoss/wireguard
+ fi
+ dnf autoremove -y
+ elif [[ ${OS} == 'almalinux' ]]; then
+ dnf -y remove wireguard-tools qrencode
+ if [[ ${VERSION_ID} == 8* ]]; then
+ dnf -y remove kmod-wireguard
+ fi
+ dnf -y autoremove
+ elif [[ ${OS} == 'centos' ]]; then
+ yum -y remove kmod-wireguard wireguard-tools qrencode
+ yum -y autoremove
+ elif [[ ${OS} == 'oracle' ]]; then
+ yum -y remove wireguard-tools qrencode
+ yum -y autoremove
+ elif [[ ${OS} == 'arch' ]]; then
+ pacman -Rs --noconfirm wireguard-tools qrencode
+ fi
+
+ rm -rf /etc/wireguard
+ rm -f /etc/sysctl.d/wg.conf
+
+ # Reload sysctl
+ sysctl --system
+
+ # Check if WireGuard is running
+ systemctl is-active --quiet "wg-quick@${SERVER_WG_NIC}"
+ WG_RUNNING=$?
+
+ if [[ ${WG_RUNNING} -eq 0 ]]; then
+ echo "WireGuard failed to uninstall properly."
+ exit 1
+ else
+ echo "WireGuard uninstalled successfully."
+ exit 0
+ fi
+ else
+ echo ""
+ echo "Removal aborted!"
+ fi
+}
+
+function manageMenu() {
+ echo "Welcome to WireGuard-install!"
+ echo "The git repository is available at: https://github.com/angristan/wireguard-install"
+ echo ""
+ echo "It looks like WireGuard is already installed."
+ echo ""
+ echo "What do you want to do?"
+ echo " 1) Add a new user"
+ echo " 2) Revoke existing user"
+ echo " 3) Uninstall WireGuard"
+ echo " 4) Exit"
+ until [[ ${MENU_OPTION} =~ ^[1-4]$ ]]; do
+ read -rp "Select an option [1-4]: " MENU_OPTION
+ done
+ case "${MENU_OPTION}" in
+ 1)
+ newClient
+ ;;
+ 2)
+ revokeClient
+ ;;
+ 3)
+ uninstallWg
+ ;;
+ 4)
+ exit 0
+ ;;
+ esac
+}
+
+# Check for root, virt, OS...
+initialCheck
+
+# Check if WireGuard is already installed and load params
+if [[ -e /etc/wireguard/params ]]; then
+ source /etc/wireguard/params
+ manageMenu
+else
+ installWireGuard
+fi