├── .gitattributes ├── nvidia-check.sh ├── .gitignore ├── astop.sh ├── astart.sh ├── astatus.sh ├── areload.sh ├── arestart.sh ├── _cf_key.sh ├── clear_journal.sh ├── rm-linux-5.15.sh ├── rm-nvidia.sh ├── _rebase ├── .editorconfig ├── prompt_update.sh ├── connect-redis.sh ├── docker-limits.sh ├── ffmpeg.sh ├── docker-remove-dangling.sh ├── docker-update.sh ├── install-insight.sh ├── install-redis.sh ├── normalize.sh ├── volumeup.sh ├── twicevolume.sh ├── _includes.sh ├── redis-status.sh ├── check_redis.sh ├── ufsmount.sh ├── addsubtitles.sh ├── cf-listdomains.sh ├── editdeb.sh ├── mp32wav.sh ├── wav2mp3.sh ├── ogg2mp3.sh ├── wma2mp3.sh ├── opus2mp3.sh ├── mp42mp3.sh ├── LICENSE ├── ogg2wav.sh ├── flac2mp3.sh ├── fsmount.sh ├── README.md ├── makedslibrary.sh ├── cf-add-a_record_proxied.sh ├── cf-add-a_record_nonproxied.sh ├── cf-add-txt_record.sh ├── cf-purgecache.sh ├── cf-add-subdomain.sh ├── cf-delete-record.sh ├── concat_mp3.sh ├── checkdslibrary.sh └── fix_filenames.php /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sh eol=lf -------------------------------------------------------------------------------- /nvidia-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | nvidia-smi 4 | lsmod | grep nvidia 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | .DS_Store 3 | *.bak 4 | *.*~ 5 | .Trash-1000 6 | .editorconfig 7 | -------------------------------------------------------------------------------- /astop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | sudo service apache2 stop 5 | -------------------------------------------------------------------------------- /astart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | sudo service apache2 start 5 | -------------------------------------------------------------------------------- /astatus.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | sudo service apache2 status 5 | -------------------------------------------------------------------------------- /areload.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | sudo service apache2 force-reload 5 | -------------------------------------------------------------------------------- /arestart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | sudo service apache2 restart 5 | -------------------------------------------------------------------------------- /_cf_key.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #@author Filip Oščádal 3 | 4 | export CF_TOKEN="=== your token ===" 5 | -------------------------------------------------------------------------------- /clear_journal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | sudo journalctl --vacuum-size=500M 5 | -------------------------------------------------------------------------------- /rm-linux-5.15.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo apt purge --no-install-recommends linux-image-5.15.0-* linux-headers-5.15.0-* 4 | -------------------------------------------------------------------------------- /rm-nvidia.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo apt purge nvidia-* 4 | sudo apt autoremove --purge 5 | sudo apt autoclean 6 | 7 | sudo add-apt-repository ppa:graphics-drivers/ppa 8 | sudo apt update 9 | sudo ubuntu-drivers list 10 | -------------------------------------------------------------------------------- /_rebase: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #@author Fred Brooker 3 | 4 | git checkout --orphan latest_branch 5 | git add -A 6 | git commit -am "rebased" 7 | git branch -D master 8 | git branch -m master 9 | git push -f origin master 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /prompt_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | wget -O ~/.git-prompt.sh https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh 5 | wget -O ~/.git-completion.bash https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash 6 | -------------------------------------------------------------------------------- /connect-redis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | cd "$(dirname "$0")" 5 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 6 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 7 | 8 | sudo docker exec -it redis redis-cli 9 | -------------------------------------------------------------------------------- /docker-limits.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | TOKEN=$(curl --silent "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token) 5 | curl --silent --head -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest 6 | -------------------------------------------------------------------------------- /ffmpeg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | # Trap Ctrl+C (SIGINT) to perform a graceful exit 5 | trap 'echo -e "\n\e[31mScript terminated by user (Ctrl+C).\e[0m"; exit 1' SIGINT 6 | 7 | set -x 8 | docker run --rm --cpus "8.0" -v "$(pwd):/config" -w /config lscr.io/linuxserver/ffmpeg:latest "$@" 9 | exit $? 10 | -------------------------------------------------------------------------------- /docker-remove-dangling.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | ABSPATH=$(readlink -f $0) 5 | ABSDIR=$(dirname $ABSPATH) 6 | cd $ABSDIR 7 | 8 | export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin 9 | 10 | docker images -f 'dangling=true' -q | xargs docker rmi 11 | -------------------------------------------------------------------------------- /docker-update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | ABSPATH=$(readlink -f $0) 5 | ABSDIR=$(dirname $ABSPATH) 6 | cd $ABSDIR 7 | 8 | export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin 9 | 10 | docker images | grep -v REPOSITORY | awk '{print $1}' | xargs -L1 docker pull 11 | -------------------------------------------------------------------------------- /install-insight.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | cd "$(dirname "$0")" 5 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 6 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 7 | 8 | docker rm redisinsight --force 9 | docker run -v redisinsight:/db -p 7777:8001 --name redisinsight -d redislabs/redisinsight 10 | -------------------------------------------------------------------------------- /install-redis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | cd "$(dirname "$0")" 5 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 6 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 7 | 8 | docker rm redis --force 9 | docker run -dit --restart unless-stopped -p 6377:6379 --ulimit nofile=50000:50000 --name redis redis:latest 10 | 11 | docker rm redisearch --force 12 | docker run -dit --restart unless-stopped -p 6378:6379 --ulimit nofile=50000:50000 --name redisearch redislabs/redisearch:latest 13 | -------------------------------------------------------------------------------- /normalize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nNormalizes video volume\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which ffmpeg >/dev/null 2>&1 || (echo "Installing ffmpeg" && sudo apt-get install -yqq ffmpeg) 10 | which ffmpeg >/dev/null 2>&1 || (echo "ERROR: ffmpeg is not installed" && exit 1) 11 | 12 | if [ -n "$1" ]; then 13 | if [ -f "$1" ]; then 14 | ffmpeg -i "$1" -c:v copy -af "loudnorm" "normalized_$1" 15 | else 16 | echo "Invalid filename: $1" 17 | exit 1 18 | fi 19 | fi 20 | 21 | echo -e "Done.\n" 22 | -------------------------------------------------------------------------------- /volumeup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nUppends video volume by +3 dB\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which ffmpeg >/dev/null 2>&1 || (echo "Installing ffmpeg" && sudo apt-get install -yqq ffmpeg) 10 | which ffmpeg >/dev/null 2>&1 || (echo "ERROR: ffmpeg is not installed" && exit 1) 11 | 12 | if [ -n "$1" ]; then 13 | if [ -f "$1" ]; then 14 | ffmpeg -i "$1" -c:v copy -af "volume=3dB" "volup_$1" 15 | else 16 | echo "Invalid filename: $1" 17 | exit 1 18 | fi 19 | fi 20 | 21 | echo -e "Done.\n" 22 | -------------------------------------------------------------------------------- /twicevolume.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nUppends video volume by +6 dB\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which ffmpeg >/dev/null 2>&1 || (echo "Installing ffmpeg" && sudo apt-get install -yqq ffmpeg) 10 | which ffmpeg >/dev/null 2>&1 || (echo "ERROR: ffmpeg is not installed" && exit 1) 11 | 12 | if [ -n "$1" ]; then 13 | if [ -f "$1" ]; then 14 | ffmpeg -i "$1" -c:v copy -af "volume=3dB" "volup2x_$1" 15 | else 16 | echo "Invalid filename: $1" 17 | exit 1 18 | fi 19 | fi 20 | 21 | echo -e "Done.\n" 22 | -------------------------------------------------------------------------------- /_includes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #@author Fred Brooker 3 | 4 | info() { 5 | echo -e "\e[0;1m${*}\e[0m" 1>&2 6 | } 7 | 8 | infogreen() { 9 | echo -e "\e[1;32m${*}\e[0m" 1>&2 10 | } 11 | 12 | infored() { 13 | echo -e "\e[1;31m${*}\e[0m" 1>&2 14 | } 15 | 16 | warn() { 17 | echo -e "\e[1;33m***\e[0;1m ${*}\e[0m" 1>&2 18 | sleep 3 19 | } 20 | 21 | fail() { 22 | echo -e "\e[1;31m***\e[0;1m ${*}\e[0m" 1>&2 23 | exit 1 24 | } 25 | 26 | function yes_or_no () { 27 | while true 28 | do 29 | read -p "$* [y/N]: " yn 30 | case $yn in 31 | [Yy]*) return 0 ;; 32 | [Nn]*) return 1 ;; 33 | *) 34 | return 1 ;; 35 | esac 36 | done 37 | } 38 | -------------------------------------------------------------------------------- /redis-status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #@author Filip Oščádal 3 | 4 | ABSPATH=$(readlink -f $0) 5 | ABSDIR=$(dirname $ABSPATH) 6 | cd $ABSDIR 7 | 8 | export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin 9 | export PATH=$PATH:/root/bin:/root/go/bin:/root/.cargo/bin:/root/scripts 10 | 11 | function rcli1 { 12 | docker exec redisearch redis-cli $1 13 | } 14 | 15 | function rcli2 { 16 | docker exec redis redis-cli $1 17 | } 18 | 19 | #echo -ne "\n\n\e[32mRediSearch\e[0m\n" 20 | #rcli1 info | grep redis 21 | #echo -ne "\n" 22 | #rcli1 info | grep keys 23 | 24 | echo -ne "\n\n\e[32mRedis\e[0m\n" 25 | rcli2 info | grep redis 26 | echo -ne "\n" 27 | rcli2 info | grep keys 28 | -------------------------------------------------------------------------------- /check_redis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | ABSPATH=$(readlink -f $0) 5 | ABSDIR=$(dirname $ABSPATH) 6 | cd $ABSDIR 7 | 8 | export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin 9 | export PATH=$PATH:/root/bin:/root/go/bin:/root/.cargo/bin:/root/scripts 10 | 11 | function rcli1 { 12 | docker exec -it redisearch redis-cli $1 13 | } 14 | 15 | function rcli2 { 16 | docker exec -it redis redis-cli $1 17 | } 18 | 19 | echo -ne "\n\n\e[32mRediSearch\e[0m\n" 20 | rcli1 info | grep redis 21 | echo -ne "\n" 22 | rcli1 info | grep keys 23 | 24 | 25 | echo -ne "\n\n\e[32mRedis\e[0m\n" 26 | rcli2 info | grep redis 27 | echo -ne "\n" 28 | rcli2 info | grep keys 29 | -------------------------------------------------------------------------------- /ufsmount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | cd "$(dirname "$0")" 5 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 6 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 7 | 8 | function disconnect { 9 | cd ~/ 10 | echo $1 11 | fusermount -u $1 12 | } 13 | 14 | disconnect DS1 15 | disconnect DS2 16 | disconnect DS3 17 | 18 | disconnect GSC 19 | 20 | #disconnect HMCSFX 21 | #disconnect INGAME 22 | #disconnect SFX 23 | 24 | #disconnect KONTAKT1 25 | #disconnect KONTAKT2 26 | #disconnect KONTAKT3 27 | 28 | #disconnect SAMPLES1 29 | #disconnect SAMPLES2 30 | #disconnect SAMPLES3 31 | 32 | disconnect STORAGEBOX storagebox: 33 | disconnect VIETCONG vietcong: 34 | -------------------------------------------------------------------------------- /addsubtitles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nAdd SRT subtitles to the video.\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which ffmpeg >/dev/null 2>&1 || (echo "Installing ffmpeg" && sudo apt-get install -yqq ffmpeg) 10 | which ffmpeg >/dev/null 2>&1 || (echo "ERROR: ffmpeg is not installed" && exit 1) 11 | 12 | if [ -n "$1" ]; then 13 | if [ -f "$1" ]; then 14 | fn=$(basename -- "$1") 15 | fn="${fn%.*}" 16 | if [ -f "$fn.srt" ]; then 17 | echo "Processing: $1 $fn.srt" 18 | ffmpeg -i "$1" -vf subtitles="$fn.srt" "subtit_$1" 19 | else 20 | echo "Missing SRT file!" 21 | exit 1 22 | fi 23 | else 24 | echo "Invalid filename: $1" 25 | exit 1 26 | fi 27 | fi 28 | 29 | echo -e "Done.\n" 30 | -------------------------------------------------------------------------------- /cf-listdomains.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | CF_API="https://api.cloudflare.com/client/v4" 5 | PAGE=1 6 | PER_PAGE=50 7 | 8 | cd "$(dirname "$0")" 9 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 10 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 11 | 12 | . ./_includes.sh 13 | if [ -f "./_cf_key.sh" ]; then . ./_cf_key.sh; fi 14 | if [ -z "$CF_TOKEN" ]; then fail "Missing CF_TOKEN token value!"; fi; 15 | 16 | # list all zones (max. 50) 17 | if [ -f "/tmp/cf-zones.txt" ]; then r=$(cat "/tmp/cf-zones.txt"); else 18 | r=$(curl -s -X GET "${CF_API}/zones?status=active&page=${PAGE}&per_page=${PER_PAGE}&match=all" \ 19 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 20 | echo $r > "/tmp/cf-zones.txt" 21 | fi 22 | 23 | echo $r|jq ".result[].name"|sort|sed 's/"//g' 24 | -------------------------------------------------------------------------------- /editdeb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # from: http://ubuntuforums.org/showthread.php?t=636724 3 | 4 | if [[ -z "$1" ]]; then 5 | echo "Syntax: $0 debfile" 6 | exit 1 7 | fi 8 | 9 | DEBFILE="$1" 10 | TMPDIR=`mktemp -d /tmp/deb.XXXXXXXXXX` || exit 1 11 | OUTPUT=`basename "$DEBFILE" .deb`.modfied.deb 12 | 13 | if [[ -e "$OUTPUT" ]]; then 14 | echo "$OUTPUT exists." 15 | rm -r "$TMPDIR" 16 | exit 1 17 | fi 18 | 19 | dpkg-deb -x "$DEBFILE" "$TMPDIR" 20 | dpkg-deb --control "$DEBFILE" "$TMPDIR"/DEBIAN 21 | 22 | if [[ ! -e "$TMPDIR"/DEBIAN/control ]]; then 23 | echo DEBIAN/control not found. 24 | 25 | rm -r "$TMPDIR" 26 | exit 1 27 | fi 28 | 29 | CONTROL="$TMPDIR"/DEBIAN/control 30 | 31 | MOD=`stat -c "%y" "$CONTROL"` 32 | vi "$CONTROL" 33 | 34 | if [[ "$MOD" == `stat -c "%y" "$CONTROL"` ]]; then 35 | echo Not modfied. 36 | else 37 | echo Building new deb... 38 | dpkg -b "$TMPDIR" "$OUTPUT" 39 | fi 40 | 41 | rm -r "$TMPDIR" 42 | -------------------------------------------------------------------------------- /mp32wav.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nConvert MP3 files to WAV recursively.\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which ffmpeg >/dev/null 2>&1 || (echo "Installing ffmpeg" && sudo apt-get install -yqq ffmpeg) 10 | which ffmpeg >/dev/null 2>&1 || (echo "ERROR: ffmpeg is not installed" && exit 1) 11 | 12 | if [ -n "$1" ]; then 13 | if [ -d "$1" ]; then 14 | cd "$1" 15 | else 16 | echo "Invalid folder: $1" 17 | exit 1 18 | fi 19 | fi 20 | 21 | for i in *; do 22 | if [ -d "$i" ]; then 23 | echo "Recursing into directory: $i" 24 | $0 "$i" 25 | fi 26 | done 27 | 28 | for i in *.mp3; do 29 | if [ -f "$i" ]; then 30 | echo "Converting: $i" 31 | ffmpeg -i "$i" "${i%.mp3}.wav" 32 | if [ $? -eq 0 ]; then 33 | echo "Successfully converted: $i" 34 | rm -f "$i" 35 | else 36 | echo "Failed to convert: $i" 37 | fi 38 | fi 39 | done 40 | 41 | echo -e "Done.\n" 42 | -------------------------------------------------------------------------------- /wav2mp3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nConvert WAV files to MP3 recursively.\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which lame >/dev/null 2>&1 || (echo "Installing lame" && sudo apt-get install -yqq lame) 10 | which lame >/dev/null 2>&1 || (echo "ERROR: lame is not installed" && exit 1) 11 | 12 | if [ -n "$1" ]; then 13 | if [ -d "$1" ]; then 14 | cd "$1" 15 | else 16 | echo "Invalid folder: $1" 17 | exit 1 18 | fi 19 | fi 20 | 21 | for i in * 22 | do 23 | if [ -d "$i" ]; then 24 | echo "Recursing into directory: $i" 25 | $0 "$i" 26 | fi 27 | done 28 | 29 | for i in *.wav 30 | do 31 | if [ -f "$i" ]; then 32 | echo "Converting: $i" 33 | lame -h --preset extreme "$i" "${i%.wav}.mp3" 34 | if [ $? -eq 0 ]; then 35 | echo "Successfully converted: $i" 36 | rm -f "$i" 37 | else 38 | echo "Failed to convert: $i" 39 | fi 40 | fi 41 | done 42 | 43 | echo -e "Done.\n" 44 | -------------------------------------------------------------------------------- /ogg2mp3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nConvert OGG files to MP3 recursively.\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which ffmpeg >/dev/null 2>&1 || (echo "Installing ffmpeg" && sudo apt-get install -yqq ffmpeg) 10 | which ffmpeg >/dev/null 2>&1 || (echo "ERROR: ffmpeg is not installed" && exit 1) 11 | 12 | if [ -n "$1" ]; then 13 | if [ -d "$1" ]; then 14 | cd "$1" 15 | else 16 | echo "Invalid folder: $1" 17 | exit 1 18 | fi 19 | fi 20 | 21 | for i in * 22 | do 23 | if [ -d "$i" ]; then 24 | echo "Recursing into directory: $i" 25 | $0 "$i" 26 | fi 27 | done 28 | 29 | for i in *.ogg 30 | do 31 | if [ -f "$i" ]; then 32 | echo "Converting: $i" 33 | j="${i%.ogg}" 34 | ffmpeg -i "$i" -b:a 320k "$j.mp3" 35 | if [ $? -eq 0 ]; then 36 | echo "Successfully converted: $i" 37 | rm -f "$i" 38 | else 39 | echo "Failed to convert: $i" 40 | fi 41 | fi 42 | done 43 | 44 | echo -e "Done.\n" 45 | -------------------------------------------------------------------------------- /wma2mp3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nConvert WMA files to MP3 recursively.\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which ffmpeg >/dev/null 2>&1 || (echo "Installing ffmpeg" && sudo apt-get install -yqq ffmpeg) 10 | which ffmpeg >/dev/null 2>&1 || (echo "ERROR: ffmpeg is not installed" && exit 1) 11 | 12 | if [ -n "$1" ]; then 13 | if [ -d "$1" ]; then 14 | cd "$1" 15 | else 16 | echo "Invalid folder: $1" 17 | exit 1 18 | fi 19 | fi 20 | 21 | for i in * 22 | do 23 | if [ -d "$i" ]; then 24 | echo "Recursing into directory: $i" 25 | $0 "$i" 26 | fi 27 | done 28 | 29 | for i in *.wma 30 | do 31 | if [ -f "$i" ]; then 32 | echo "Converting: $i" 33 | j="${i%.wma}" 34 | ffmpeg -i "$i" -b:a 320k "$j.mp3" 35 | if [ $? -eq 0 ]; then 36 | echo "Successfully converted: $i" 37 | rm -f "$i" 38 | else 39 | echo "Failed to convert: $i" 40 | fi 41 | fi 42 | done 43 | 44 | echo -e "Done.\n" 45 | -------------------------------------------------------------------------------- /opus2mp3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nConvert OPUS files to MP3 recursively.\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which ffmpeg >/dev/null 2>&1 || (echo "Installing ffmpeg" && sudo apt-get install -yqq ffmpeg) 10 | which ffmpeg >/dev/null 2>&1 || (echo "ERROR: ffmpeg is not installed" && exit 1) 11 | 12 | if [ -n "$1" ]; then 13 | if [ -d "$1" ]; then 14 | cd "$1" 15 | else 16 | echo "Invalid folder: $1" 17 | exit 1 18 | fi 19 | fi 20 | 21 | for i in * 22 | do 23 | if [ -d "$i" ]; then 24 | echo "Recursing into directory: $i" 25 | $0 "$i" 26 | fi 27 | done 28 | 29 | for i in *.opus 30 | do 31 | if [ -f "$i" ]; then 32 | echo "Converting: $i" 33 | j="${i%.opus}" 34 | ffmpeg -i "$i" -b:a 320k "$j.mp3" 35 | if [ $? -eq 0 ]; then 36 | echo "Successfully converted: $i" 37 | rm -f "$i" 38 | else 39 | echo "Failed to convert: $i" 40 | fi 41 | fi 42 | done 43 | 44 | echo -e "Done.\n" 45 | -------------------------------------------------------------------------------- /mp42mp3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nConvert M4A files to MP3 recursively.\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which ffmpeg >/dev/null 2>&1 || (echo "Installing ffmpeg" && sudo apt-get install -yqq ffmpeg) 10 | which ffmpeg >/dev/null 2>&1 || (echo "ERROR: ffmpeg is not installed" && exit 1) 11 | 12 | if [ -n "$1" ]; then 13 | if [ -d "$1" ]; then 14 | cd "$1" 15 | else 16 | echo "Invalid folder: $1" 17 | exit 1 18 | fi 19 | fi 20 | 21 | for i in *; do 22 | if [ -d "$i" ]; then 23 | echo "Recursing into directory: $i" 24 | $0 "$i" 25 | fi 26 | done 27 | 28 | for i in *.m4a; do 29 | if [ -f "$i" ]; then 30 | echo "Converting: $i" 31 | ffmpeg -i "$i" -codec:v copy -codec:a libmp3lame -b:a 320k "${i%.m4a}.mp3" 32 | if [ $? -eq 0 ]; then 33 | echo "Successfully converted: $i" 34 | rm -f "$i" 35 | else 36 | echo "Failed to convert: $i" 37 | fi 38 | fi 39 | done 40 | 41 | echo -e "Done.\n" 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 GS Cloud Ltd. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ogg2wav.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nConvert OGG files to WAV recursively.\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which ffmpeg >/dev/null 2>&1 || (echo "Installing ffmpeg" && sudo apt-get install -yqq ffmpeg) 10 | which ffmpeg >/dev/null 2>&1 || (echo "ERROR: ffmpeg is not installed" && exit 1) 11 | which lame >/dev/null 2>&1 || (echo "Installing lame" && sudo apt-get install -yqq lame) 12 | which lame >/dev/null 2>&1 || (echo "ERROR: lame is not installed" && exit 1) 13 | 14 | if [ -n "$1" ]; then 15 | if [ -d "$1" ]; then 16 | cd "$1" 17 | else 18 | echo "Invalid folder: $1" 19 | exit 1 20 | fi 21 | fi 22 | 23 | for i in * 24 | do 25 | if [ -d "$i" ]; then 26 | echo "Recursing into directory: $i" 27 | $0 "$i" 28 | fi 29 | done 30 | 31 | for i in *.ogg 32 | do 33 | if [ -f "$i" ]; then 34 | echo "Converting: $i" 35 | j="${i%.ogg}" 36 | ffmpeg -i "$i" -vn "$j.wav" 37 | if [ $? -eq 0 ]; then 38 | echo "Successfully converted: $i" 39 | rm -f "$i" 40 | else 41 | echo "Failed to convert: $i" 42 | fi 43 | fi 44 | done 45 | 46 | echo -e "Done.\n" 47 | -------------------------------------------------------------------------------- /flac2mp3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | if [ $# -eq 0 ]; then 5 | echo -e "\nConvert FLAC files to MP3 recursively.\n\nSyntax: $(basename $0) \n" 6 | exit 1 7 | fi 8 | 9 | which flac >/dev/null 2>&1 || (echo "Installing flac" && sudo apt-get install -yqq flac) 10 | which flac >/dev/null 2>&1 || (echo "ERROR: flac is not installed" && exit 1) 11 | which lame >/dev/null 2>&1 || (echo "Installing lame" && sudo apt-get install -yqq lame) 12 | which lame >/dev/null 2>&1 || (echo "ERROR: lame is not installed" && exit 1) 13 | 14 | if [ -n "$1" ]; then 15 | if [ -d "$1" ]; then 16 | cd "$1" 17 | else 18 | echo "Invalid folder: $1" 19 | exit 1 20 | fi 21 | fi 22 | 23 | for i in * 24 | do 25 | if [ -d "$i" ]; then 26 | echo "Recursing into directory: $i" 27 | $0 "$i" 28 | fi 29 | done 30 | 31 | for i in *.flac 32 | do 33 | if [ -f "$i" ]; then 34 | echo "Converting: $i" 35 | j="${i%.flac}" 36 | flac -d "$i" 37 | lame -h --preset extreme "$j.wav" "$j.mp3" 38 | if [ $? -eq 0 ]; then 39 | echo "Successfully converted: $i" 40 | rm -f "$i" "$j.wav" 41 | else 42 | echo "ERROR: Failed to convert: $i" 43 | fi 44 | fi 45 | done 46 | 47 | echo -e "Done.\n" 48 | -------------------------------------------------------------------------------- /fsmount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | cd "$(dirname "$0")" 5 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 6 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 7 | 8 | mkdir -p /1TB/rclone 9 | 10 | options="--vfs-cache-mode full --vfs-cache-max-age 12h --dir-cache-time 30m --buffer-size 512M --vfs-read-ahead 2048M --drive-chunk-size 256M --cache-dir /1TB/rclone --attr-timeout 3s --daemon" 11 | 12 | function connect { 13 | cd ~/ 14 | if [ ! -d "${1}" ]; then 15 | echo "Missing folder ${1} !!!" 16 | exit 1 17 | fi 18 | if [ -z "$(ls -A ${1})" ]; then 19 | TEST=$(rclone listremotes | grep "$2") 20 | if [ ! -z "$TEST" ]; then 21 | echo mounting $2 to $1 22 | rclone mount $options $2 $1 --daemon-wait 90s 23 | else 24 | echo -en "\n! rclone profile $2 does not exist !\n" 25 | fi 26 | fi 27 | } 28 | 29 | connect DS1 ds1: 30 | connect DS2 ds2: 31 | connect DS3 ds3: 32 | 33 | connect GSC gsc: 34 | 35 | #connect HMCSFX hmcsfx: 36 | #connect INGAME ingame: 37 | #connect SFX sfx: 38 | 39 | #connect KONTAKT1 kontakt1: 40 | #connect KONTAKT2 kontakt2: 41 | #connect KONTAKT3 kontakt3: 42 | 43 | #connect SAMPLES1 samples1: 44 | #connect SAMPLES2 samples2: 45 | #connect SAMPLES3 samples3: 46 | 47 | connect STORAGEBOX storagebox: 48 | connect VIETCONG vietcong: 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Linux Shell Scripts Collection 2 | 3 | Author: Fred Brooker 💌 ⛅️ GS Cloud Ltd. [https://gscloud.cz](https://gscloud.cz) 4 | 5 | ## Apache 6 | 7 | * areload.sh 8 | * arestart.sh 9 | * astart.sh 10 | * astatus.sh 11 | * astop.sh 12 | 13 | ## Audio Manipulation 14 | 15 | * concat_mp3.sh 16 | * flac2mp3.sh 17 | * mp32wav.sh 18 | * mp42mp3.sh 19 | * ogg2mp3.sh 20 | * ogg2wav.sh 21 | * opus2mp3.sh 22 | * wav2mp3.sh 23 | * wma2mp3.sh 24 | 25 | ## Cloudflare 26 | 27 | * _cf_key.sh *(configuration - put in your Cloudflare token)* 28 | * cf-add-a_record_nonproxied.sh 29 | * cf-add-a_record_proxied.sh 30 | * cf-add-subdomain.sh 31 | * cf-add-txt_record.sh 32 | * cf-delete-record.sh 33 | * cf-listdomains.sh 34 | * cf-purgecache.sh 35 | 36 | ## Decent Sampler Tools 37 | 38 | * checkdslibrary.sh 39 | * makedslibrary.sh 40 | 41 | ## Docker 42 | 43 | * docker-limits.sh 44 | * docker-remove-dangling.sh 45 | * docker-update.sh 46 | * ffmpeg.sh *(ffmpeg replacement, set CPU load to your own)* 47 | * install-insight.sh 48 | * install-redis.sh 49 | 50 | ## Movie Manipulation 51 | 52 | * addsubtitles.sh 53 | * normalize.sh 54 | * twicevolume.sh 55 | * volumeup.sh 56 | 57 | ## Redis 58 | 59 | * check_redis.sh 60 | * connect-redis.sh 61 | * redis-status.sh 62 | 63 | ## System 64 | 65 | * clear_journal.sh 66 | * editdeb.sh 67 | * fix_filenames.php 68 | * nvidia-check.sh 69 | * prompt_update.sh 70 | * rm-linux-5.15.sh 71 | * rm-nvidia.sh 72 | -------------------------------------------------------------------------------- /makedslibrary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | # Google Gemini 2.5 Flash - 2025-07-13 4 | 5 | # Enable nullglob: If no files match the pattern, the glob expands to nothing, 6 | # preventing the script from trying to process a literal "*.dsbundle". 7 | shopt -s nullglob 8 | 9 | # Set Internal Field Separator to newline only to handle filenames with spaces correctly. 10 | IFS=$'\n' 11 | 12 | # Flag to check if any .dsbundle directories were found and processed. 13 | found_bundles=false 14 | 15 | # Loop through all directories ending with .dsbundle in the current directory. 16 | for bundle_dir in *.dsbundle; do 17 | 18 | # Check if the current item is actually a directory. 19 | if [[ -d "$bundle_dir" ]]; then 20 | found_bundles=true 21 | 22 | # Construct the output .dslibrary filename. 23 | # We remove the '.dsbundle' extension and append '.dslibrary'. 24 | library_name="${bundle_dir%.dsbundle}.dslibrary" 25 | if [[ -f "$library_name" ]]; then 26 | echo "> '$library_name' already exists" 27 | continue 28 | fi 29 | 30 | echo "Archiving '$bundle_dir'..." 31 | 32 | # Use the 'zip' command: 33 | # -0 : Store files only, do not compress. This is key for "faster to load". 34 | # -r : Recurse into directories (necessary to archive the entire bundle_dir). 35 | zip -0 -q -r "$library_name" "$bundle_dir" 36 | 37 | # Check the exit status 38 | if [[ $? -eq 0 ]]; then 39 | echo "Successfully created '$library_name'." 40 | else 41 | echo "Error creating '$library_name'. Please check the error messages above." 42 | fi 43 | fi 44 | done 45 | 46 | if ! $found_bundles; then 47 | echo "No *.dsbundle directories found in the current directory." 48 | fi 49 | 50 | echo "Done." 51 | 52 | # Restore IFS 53 | unset IFS 54 | -------------------------------------------------------------------------------- /cf-add-a_record_proxied.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | CF_API="https://api.cloudflare.com/client/v4" 5 | PAGE=1 6 | PER_PAGE=50 7 | 8 | cd "$(dirname "$0")" 9 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 10 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 11 | 12 | . ./_includes.sh 13 | if [ -f "./_cf_key.sh" ]; then . ./_cf_key.sh; fi 14 | if [ -z "$CF_TOKEN" ]; then fail "Missing CF_TOKEN token value!"; fi; 15 | 16 | # parameters 17 | if [ $# -lt 3 ]; then info "\nUsage: \t$0 \n\n"; exit; fi 18 | if [ $# -eq 3 ]; then dom=$1; sub=$2; content=$3; fi 19 | if [ $# -gt 3 ]; then info "\nUsage: \t$0 \n\n"; exit; fi 20 | 21 | # list all zones (max. 50) 22 | r=$(curl -s -X GET "${CF_API}/zones?status=active&page=${PAGE}&per_page=${PER_PAGE}&match=all" \ 23 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json"); 24 | names=$(echo $r|jq ".result[].name"|sed 's/"//g') 25 | count=$(echo $names|sed 's/ /\n/g'|wc -l) 26 | 27 | # multiple domains or single one 28 | if [ "$dom" == "all" ] 29 | then 30 | yes_or_no "Process $count zone(s) and add \"$sub\" subdomain to all of them?" || exit 1 31 | else 32 | echo "Searching for \"$dom\" zone ..." 33 | fi 34 | 35 | j=0 36 | for i in $names 37 | do 38 | ((j++)) 39 | if [ "$dom" != "all" ]; then if [ "$dom" != "$i" ]; then continue; fi; fi 40 | 41 | # get current zone 42 | r=$(curl -s -X GET "${CF_API}/zones?name=${i}&status=active&match=all" \ 43 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 44 | id=$(echo $r|jq ".result[].id"|sed 's/"//g') 45 | name=$(echo $r|jq ".result[].name"|sed 's/"//g') 46 | 47 | # add A record 48 | r=$(curl -s -X POST "${CF_API}/zones/${id}/dns_records" \ 49 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json" \ 50 | --data '{"type":"A","name":"'${sub}'","content":"'${content}'","ttl":1,"proxied":true}') 51 | result=$(echo $r|jq ".success") 52 | 53 | # check result 54 | if [ "$result" == "true" ]; then 55 | infogreen "$j/$count ${name}" 56 | else 57 | infored "$j/$count ${name}" 58 | echo $r|jq ".errors[].message" 59 | fi 60 | 61 | done 62 | -------------------------------------------------------------------------------- /cf-add-a_record_nonproxied.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | CF_API="https://api.cloudflare.com/client/v4" 5 | PAGE=1 6 | PER_PAGE=50 7 | 8 | cd "$(dirname "$0")" 9 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 10 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 11 | 12 | . ./_includes.sh 13 | if [ -f "./_cf_key.sh" ]; then . ./_cf_key.sh; fi 14 | if [ -z "$CF_TOKEN" ]; then fail "Missing CF_TOKEN token value!"; fi; 15 | 16 | # parameters 17 | if [ $# -lt 3 ]; then info "\nUsage: \t$0 \n\n"; exit; fi 18 | if [ $# -eq 3 ]; then dom=$1; sub=$2; content=$3; fi 19 | if [ $# -gt 3 ]; then info "\nUsage: \t$0 \n\n"; exit; fi 20 | 21 | # list all zones (max. 50) 22 | r=$(curl -s -X GET "${CF_API}/zones?status=active&page=${PAGE}&per_page=${PER_PAGE}&match=all" \ 23 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json"); 24 | names=$(echo $r|jq ".result[].name"|sed 's/"//g') 25 | count=$(echo $names|sed 's/ /\n/g'|wc -l) 26 | 27 | # multiple domains or single one 28 | if [ "$dom" == "all" ] 29 | then 30 | yes_or_no "Process $count zone(s) and add \"$sub\" subdomain to all of them?" || exit 1 31 | else 32 | echo "Searching for \"$dom\" zone ..." 33 | fi 34 | 35 | j=0 36 | for i in $names 37 | do 38 | ((j++)) 39 | if [ "$dom" != "all" ]; then if [ "$dom" != "$i" ]; then continue; fi; fi 40 | 41 | # get current zone 42 | r=$(curl -s -X GET "${CF_API}/zones?name=${i}&status=active&match=all" \ 43 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 44 | id=$(echo $r|jq ".result[].id"|sed 's/"//g') 45 | name=$(echo $r|jq ".result[].name"|sed 's/"//g') 46 | 47 | # add A record 48 | r=$(curl -s -X POST "${CF_API}/zones/${id}/dns_records" \ 49 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json" \ 50 | --data '{"type":"A","name":"'${sub}'","content":"'${content}'","ttl":1,"proxied":false}') 51 | result=$(echo $r|jq ".success") 52 | 53 | # check result 54 | if [ "$result" == "true" ]; then 55 | infogreen "$j/$count ${name}" 56 | info "+ A record: ${sub} ${content}" 57 | else 58 | infored "$j/$count ${name}" 59 | echo $r|jq ".errors[].message" 60 | fi 61 | 62 | done 63 | -------------------------------------------------------------------------------- /cf-add-txt_record.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | CF_API="https://api.cloudflare.com/client/v4" 5 | PAGE=1 6 | PER_PAGE=50 7 | 8 | cd "$(dirname "$0")" 9 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 10 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 11 | 12 | . ./_includes.sh 13 | if [ -f "./_cf_key.sh" ]; then . ./_cf_key.sh; fi 14 | if [ -z "$CF_TOKEN" ]; then fail "Missing CF_TOKEN token value!"; fi; 15 | 16 | # parameters 17 | if [ $# -lt 3 ]; then info "\nUsage: \t$0 \n\n"; exit; fi 18 | if [ $# -eq 3 ]; then dom=$1; key=$2; content=$3; fi 19 | if [ $# -gt 3 ]; then info "\nUsage: \t$0 \n\n"; exit; fi 20 | 21 | # list all zones (max. 50) 22 | r=$(curl -s -X GET "${CF_API}/zones?status=active&page=${PAGE}&per_page=${PER_PAGE}&match=all" \ 23 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 24 | names=$(echo $r|jq ".result[].name"|sed 's/"//g') 25 | count=$(echo $names|sed 's/ /\n/g'|wc -l) 26 | 27 | # multiple domains or single one 28 | if [ "$dom" == "all" ] 29 | then 30 | yes_or_no "Process $count zone(s) and add \"$key\" key to all of them?" || exit 1 31 | else 32 | echo "Searching for \"$dom\" zone ..." 33 | fi 34 | 35 | j=0 36 | for i in $names 37 | do 38 | ((j++)) 39 | if [ "$dom" != "all" ]; then if [ "$dom" != "$i" ]; then continue; fi; fi 40 | 41 | # get current zone 42 | r=$(curl -s -X GET "${CF_API}/zones?name=${i}&status=active&match=all" \ 43 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 44 | id=$(echo $r|jq ".result[].id"|sed 's/"//g') 45 | name=$(echo $r|jq ".result[].name"|sed 's/"//g') 46 | 47 | # add TXT record 48 | r=$(curl -s -X POST "${CF_API}/zones/${id}/dns_records" \ 49 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json" \ 50 | --data '{"type":"TXT","name":"'${key}'","content":"'${content}'","ttl":1}') 51 | result=$(echo $r|jq ".success") 52 | 53 | # check result 54 | if [ "$result" == "true" ]; then 55 | echo -en "$j/$count " 56 | infogreen "${name}" 57 | info "+ TXT record: ${key} ${content}" 58 | else 59 | echo -en "$j/$count " 60 | infored "${name}" 61 | echo $r|jq ".errors[].message" 62 | fi 63 | 64 | done 65 | -------------------------------------------------------------------------------- /cf-purgecache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | CF_API="https://api.cloudflare.com/client/v4" 5 | PAGE=1 6 | PER_PAGE=50 7 | 8 | cd "$(dirname "$0")" 9 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 10 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 11 | 12 | . ./_includes.sh 13 | if [ -f "./_cf_key.sh" ]; then . ./_cf_key.sh; fi 14 | if [ -z "$CF_TOKEN" ]; then fail "Missing CF_TOKEN token value!"; fi; 15 | 16 | # parameters 17 | if [ $# -eq 0 ]; then dom="all"; fi 18 | if [ $# -eq 1 ]; then dom=$1; fi 19 | if [ $# -gt 1 ]; then info "\nUsage: \t$0 []\n\n"; exit; fi 20 | 21 | # list all zones (max. 50) 22 | if [ -f "/tmp/cf-zones.txt" ]; then r=$(cat "/tmp/cf-zones.txt"); else 23 | r=$(curl -s -X GET "${CF_API}/zones?status=active&page=${PAGE}&per_page=${PER_PAGE}&match=all" \ 24 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 25 | echo $r > "/tmp/cf-zones.txt" 26 | fi 27 | names=$(echo $r|jq ".result[].name"|sed 's/"//g') 28 | count=$(echo $names|sed 's/ /\n/g'|wc -l) 29 | 30 | # multiple domains or single one 31 | if [ "$dom" == "all" ] 32 | then 33 | yes_or_no "Process $count zone(s) and purge edge cache for all of them?" || exit 1 34 | else 35 | echo "Searching for \"$dom\" zone ..." 36 | fi 37 | 38 | j=0 39 | for i in $names 40 | do 41 | ((j++)) 42 | if [ "$dom" != "all" ]; then if [ "$dom" != "$i" ]; then continue; fi; fi 43 | 44 | # get current zone 45 | r=$(curl -s -X GET "${CF_API}/zones?name=${i}&status=active&page=1&per_page=1&match=all" \ 46 | -H "Authorization: Bearer ${CF_TOKEN}" \ 47 | -H "Content-Type: application/json") 48 | id=$(echo $r|jq ".result[].id"|sed 's/"//g') 49 | name=$(echo $r|jq ".result[].name"|sed 's/"//g') 50 | 51 | # purge cache 52 | r=$(curl -s -X POST "${CF_API}/zones/${id}/purge_cache" \ 53 | -H "Authorization: Bearer ${CF_TOKEN}" \ 54 | -H "Content-Type: application/json" \ 55 | --data '{"purge_everything":true}') 56 | result=$(echo $r|jq ".success") 57 | 58 | # check result 59 | if [ "$result" == "true" ]; then 60 | echo -en "$j/$count " 61 | infogreen "${name}" 62 | if [ "$dom" != "all" ]; then exit 0; fi 63 | else 64 | echo -en "$j/$count " 65 | infored "${name}" 66 | fi 67 | 68 | done 69 | 70 | if [ "$dom" != "all" ]; then echo "Not found!"; exit 1; fi 71 | -------------------------------------------------------------------------------- /cf-add-subdomain.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | CF_API="https://api.cloudflare.com/client/v4" 5 | PAGE=1 6 | PER_PAGE=50 7 | 8 | cd "$(dirname "$0")" 9 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 10 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 11 | 12 | . ./_includes.sh 13 | if [ -f "./_cf_key.sh" ]; then . ./_cf_key.sh; fi 14 | if [ -z "$CF_TOKEN" ]; then fail "Missing CF_TOKEN token value!"; fi; 15 | 16 | # parameters 17 | if [ $# -lt 2 ]; then info "\nUsage: \t$0 []\n\n"; exit; fi 18 | if [ $# -eq 2 ]; then dom=$1; sub=$2; val=""; fi 19 | if [ $# -eq 3 ]; then dom=$1; sub=$2; val=$3; fi 20 | if [ $# -gt 3 ]; then info "\nUsage: \t$0 []\n\n"; exit; fi 21 | 22 | # list all zones (max. 50) 23 | r=$(curl -s -X GET "${CF_API}/zones?status=active&page=${PAGE}&per_page=${PER_PAGE}&match=all" \ 24 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 25 | names=$(echo $r|jq ".result[].name"|sed 's/"//g') 26 | count=$(echo $names|sed 's/ /\n/g'|wc -l) 27 | 28 | # multiple domains or single one 29 | if [ "$dom" == "all" ] 30 | then 31 | yes_or_no "Process $count zone(s) and add \"$sub\" subdomain to all of them?" || exit 1 32 | else 33 | echo "Searching for \"$dom\" zone ..." 34 | fi 35 | 36 | j=0 37 | for i in $names 38 | do 39 | ((j++)) 40 | if [ "$dom" != "all" ]; then if [ "$dom" != "$i" ]; then continue; fi; fi 41 | 42 | # get current zone 43 | r=$(curl -s -X GET "${CF_API}/zones?name=${i}&status=active&match=all" \ 44 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 45 | id=$(echo $r|jq ".result[].id"|sed 's/"//g') 46 | name=$(echo $r|jq ".result[].name"|sed 's/"//g') 47 | 48 | # add CNAME record 49 | if [ "$val" == "" ]; then content=${name}; else content=${val}; fi 50 | r=$(curl -s -X POST "${CF_API}/zones/${id}/dns_records" \ 51 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json" \ 52 | --data '{"type":"CNAME","name":"'${sub}'","content":"'${content}'","ttl":1,"proxied":true}') 53 | result=$(echo $r|jq ".success") 54 | 55 | # check result 56 | if [ "$result" == "true" ]; then 57 | echo -en "$j/$count " 58 | infogreen "${name}" 59 | info "+ CNAME record: ${sub} > ${content}" 60 | else 61 | echo -en "$j/$count " 62 | infored "${name}" 63 | echo $r|jq ".errors[].message" 64 | fi 65 | 66 | done 67 | -------------------------------------------------------------------------------- /cf-delete-record.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | CF_API="https://api.cloudflare.com/client/v4" 5 | PAGE=1 6 | PER_PAGE=50 7 | 8 | cd "$(dirname "$0")" 9 | export PATH=$PATH:/snap/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 10 | export PATH=$PATH:$HOME/go/bin:$HOME/.cargo/bin:$HOME/bin:$HOME/scripts 11 | 12 | . ./_includes.sh 13 | if [ -f "./_cf_key.sh" ]; then . ./_cf_key.sh; fi 14 | if [ -z "$CF_TOKEN" ]; then fail "Missing CF_TOKEN token value!"; fi; 15 | 16 | # parameters 17 | if [ $# -lt 2 ]; then info "\nUsage: \t$0 \n\n"; exit; fi 18 | if [ $# -eq 2 ]; then dom=$1; sub=$2; fi 19 | if [ $# -gt 2 ]; then info "\nUsage: \t$0 \n\n"; exit; fi 20 | 21 | # list all zones (max. 50) 22 | r=$(curl -s -X GET "${CF_API}/zones?status=active&page=${PAGE}&per_page=${PER_PAGE}&match=all" \ 23 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 24 | names=$(echo $r|jq ".result[].name"|sed 's/"//g') 25 | count=$(echo $names|sed 's/ /\n/g'|wc -l) 26 | 27 | # multiple domains or single one 28 | if [ "$dom" == "all" ] 29 | then 30 | yes_or_no "Process $count zone(s) and add \"$sub\" subdomain to all of them?" || exit 1 31 | else 32 | echo "Searching for \"$dom\" zone ..." 33 | fi 34 | 35 | j=0 36 | for i in $names 37 | do 38 | ((j++)) 39 | if [ "$dom" != "all" ]; then if [ "$dom" != "$i" ]; then continue; fi; fi 40 | 41 | # get current zone 42 | r=$(curl -s -X GET "${CF_API}/zones?name=${i}&status=active&match=all" \ 43 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 44 | id=$(echo $r|jq ".result[].id"|sed 's/"//g') 45 | name=$(echo $r|jq ".result[].name"|sed 's/"//g') 46 | 47 | # get record ID for deletion 48 | r=$(curl -s -X GET "${CF_API}/zones/${id}/dns_records?name=${sub}.${name}&match=all" \ 49 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 50 | rec=$(echo $r|jq ".result[].id"|sed 's/"//g') 51 | if [ "$rec" == "" ]; then infored "${name} * record ${sub}.${name} not found"; continue; fi 52 | 53 | # delete record 54 | r=$(curl -s -X DELETE "${CF_API}/zones/${id}/dns_records/${rec}" \ 55 | -H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json") 56 | result=$(echo $r|jq ".success") 57 | 58 | # check result 59 | if [ "$result" == "true" ]; then 60 | echo -en "$j/$count " 61 | infogreen "${name}" 62 | info "- record: ${sub}" 63 | else 64 | echo -en "$j/$count " 65 | infored "${name}" 66 | echo $r|jq ".errors[].message" 67 | fi 68 | 69 | done 70 | -------------------------------------------------------------------------------- /concat_mp3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | 4 | which ffmpeg >/dev/null 2>&1 5 | if [ $? -eq 1 ]; then 6 | echo "Installing ffmpeg" 7 | sudo apt-get install -yqq ffmpeg 8 | fi 9 | 10 | which ffmpeg >/dev/null 2>&1 11 | if [ $? -eq 1 ]; then 12 | echo -e "ERROR: ffmpeg is not installed!\n" 13 | exit 1 14 | fi 15 | 16 | which lame >/dev/null 2>&1 17 | if [ $? -eq 1 ]; then 18 | echo "Installing lame" 19 | sudo apt-get install -yqq lame 20 | fi 21 | 22 | which lame >/dev/null 2>&1 23 | if [ $? -eq 1 ]; then 24 | echo -e "ERROR: lame is not installed!\n" 25 | exit 1 26 | fi 27 | 28 | if [ ! -e ".concat" ]; then 29 | find . -maxdepth 1 -type f -size 0 -delete 30 | 31 | for i in * 32 | do 33 | # skip if not a directory 34 | if [ ! -d "$i" ]; then continue; fi 35 | echo -en "> $i\n" 36 | 37 | # check if file exists 38 | if [ -e "$i.mp3" ]; then 39 | A=`du -sb "$i" | awk '{print $1}' | awk '{print int($1)}'` # folder size, integer 40 | B=`du -sb "$i.mp3" | awk '{print $1}' | awk '{print int($1)+10485760}'` # file size, integer + 10 MB 41 | if [ "$B" -gt "$A" ]; then 42 | echo "🆗 $i" 43 | continue 44 | else 45 | echo "🤯 $i failure" 46 | rm -f "$i.mp3" >/dev/null 2>&1 47 | rm -f "$i/.concat" >/dev/null 2>&1 48 | sleep 2 49 | fi 50 | fi 51 | 52 | # check if already processed 53 | if [ -e "$i/.concat" ]; then continue; fi 54 | 55 | # dive into the album 56 | cd "$i" 57 | find . -maxdepth 1 -type f -size 0 -delete 58 | 59 | # check for subfolders 60 | D=0 61 | for x in * 62 | do 63 | if [ -d "$x" ]; then D=1; continue; fi 64 | done 65 | 66 | # run recursively 67 | if [ "$D" -eq "1" ]; then echo "📁 subfolders ..."; . $0; cd ..; continue; fi 68 | 69 | # check for MP3s 70 | FILES=`ls *.mp3 2>/dev/null` 71 | if [ -z "$FILES" ]; then echo "😵 missing MP3 in $i"; cd ..; continue; fi 72 | 73 | # create MP3 74 | echo -en "\n\nProcessing: $i\n\n" 75 | ls *.mp3 | perl -ne 'print "file $_"' > .files 76 | ffmpeg -y -f concat -i .files -c copy "../$i.mp3" 77 | if [ $? -eq 0 ]; then 78 | touch .concat 79 | fi 80 | rm -f .files 81 | cd .. 82 | 83 | # check filesizes 84 | if [ -e "$i.mp3" ]; then 85 | A=`du -sb "$i" | awk '{print $1}' | awk '{print int($1)}'` # folder size, integer 86 | B=`du -sb "$i.mp3" | awk '{print $1}' | awk '{print int($1)+10485760}'` # file size, integer + 10 MB 87 | if [ "$B" -gt "$A" ]; then 88 | echo "🆗 $i" 89 | continue 90 | else 91 | echo "🤯 $i failure" 92 | rm -f "$i.mp3" >/dev/null 2>&1 93 | rm -f "$i/.concat" >/dev/null 2>&1 94 | sleep 2 95 | fi 96 | fi 97 | done 98 | 99 | find . -maxdepth 1 -type f -size 0 -delete 100 | touch .concat 101 | fi 102 | -------------------------------------------------------------------------------- /checkdslibrary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # @author Fred Brooker 3 | # Google Gemini 2.5 Flash - 2025-07-15 4 | 5 | # Function to count zero-length files in a .dslibrary archive 6 | count_zero_length_files_in_archive() { 7 | local dslibrary_file="$1" 8 | local zero_count=0 9 | 10 | # Check if the file is actually a zip file and list its contents 11 | # Filter for lines that start with 0 (padded with spaces) in the 'Length' column 12 | # The output of unzip -l typically looks like: 13 | # Length Date Time Name 14 | # -------- -------- -------- ---- 15 | # 0 07-15-25 08:00 empty_file.txt 16 | # 123 07-15-25 08:01 data.txt 17 | # -------- ------- 18 | # So we're looking for lines starting with whitespace followed by 0, 19 | # and then ignoring the summary lines. 20 | 21 | # Use awk to filter and count: 22 | # NR > 3: Start processing after the header lines. 23 | # $1 ~ /^[ ]*0$/: Check if the first field (Length) is exactly 0. 24 | # $NF !~ /\/$/: Ensure the last field (Name) does not end with '/' (i.e., is not a directory). 25 | zero_count=$(unzip -l "$dslibrary_file" 2>/dev/null | awk ' 26 | NR > 3 && $1 ~ /^[ ]*0$/ && $NF !~ /\/$/ { 27 | print " - Found zero-length file: " $NF; 28 | count++; 29 | } 30 | END { print "TOTAL_COUNT:" count } 31 | ' | grep -oP 'TOTAL_COUNT:\K[0-9]+$') 32 | 33 | echo "$zero_count" 34 | } 35 | 36 | # Main script logic 37 | main() { 38 | # Trap Ctrl+C (SIGINT) to perform a graceful exit 39 | trap 'echo -e "\n\e[31mScript terminated by user (Ctrl+C).\e[0m"; exit 1' SIGINT 40 | 41 | local root_dir=$(pwd) 42 | local total_zero_length_files=0 43 | declare -A zero_length_counts # Associative array to store counts per file 44 | 45 | echo -en "Scan: $(realpath "$root_dir")\n\n" 46 | 47 | # Find all .dslibrary files recursively 48 | # -type f: ensures it's a file 49 | # -name "*.dslibrary": matches the file extension 50 | while IFS= read -r filepath; do 51 | echo -en "Checking: $filepath" 52 | 53 | # Verify if it's a ZIP file (a basic check, 'unzip' will fail if not) 54 | if ! unzip -t "$filepath" &>/dev/null; then 55 | echo -e " \e[31mWarning: '$filepath' is not a valid ZIP file and cannot be processed.\e[0m" 56 | continue 57 | fi 58 | 59 | local current_zero_count=$(count_zero_length_files_in_archive "$filepath") 60 | 61 | if [[ "$current_zero_count" -gt 0 ]]; then 62 | zero_length_counts["$filepath"]="$current_zero_count" 63 | total_zero_length_files=$((total_zero_length_files + current_zero_count)) 64 | echo -en " \e[31m$current_zero_count\e[0m" 65 | fi 66 | echo "" 67 | 68 | done < <(find "$root_dir" -type f -name "*.dslibrary") 69 | 70 | echo "--- Scan Complete ---" 71 | echo "Total empty files found across all .dslibrary files: $total_zero_length_files" 72 | 73 | if [[ ${#zero_length_counts[@]} -gt 0 ]]; then 74 | echo "" 75 | echo "Summary of empty files:" 76 | for dslib_path in "${!zero_length_counts[@]}"; do 77 | echo -en "- '$dslib_path' \e[31m${zero_length_counts[$dslib_path]}\e[0m\n" 78 | done 79 | else 80 | echo "" 81 | echo "No .dslibrary files with zero-length internal files were found." 82 | fi 83 | } 84 | 85 | # Execute the main function 86 | main 87 | -------------------------------------------------------------------------------- /fix_filenames.php: -------------------------------------------------------------------------------- 1 | 9 | * @license MIT https://gscloud.cz/LICENSE 10 | * @link None 11 | */ 12 | 13 | if (file_exists('.bashrc') || file_exists('.profile')) { 14 | // stop if running from $HOME directory 15 | die("EMERGENCY STOP!!!"); 16 | } 17 | 18 | define("DS", DIRECTORY_SEPARATOR); 19 | 20 | $map = [ 21 | 'á' => 'a', 22 | 'č' => 'c', 23 | 'à' => 'a', 24 | 'á' => 'a', 25 | 'ä' => 'a', 26 | 27 | 'č' => 'c', 28 | 'ć' => 'c', 29 | 30 | 'ď' => 'd', 31 | 32 | 'ě' => 'e', 33 | 'è' => 'e', 34 | 'é' => 'e', 35 | 'ë' => 'e', 36 | 'é' => 'e', 37 | 'ě' => 'e', 38 | 39 | 'í' => 'i', 40 | 'í' => 'i', 41 | 42 | 'ĺ' => 'l', 43 | 'ľ' => 'l', 44 | 45 | 'ň' => 'n', 46 | 'ń' => 'n', 47 | 48 | 'ó' => 'o', 49 | 'ô' => 'o', 50 | 'ö' => 'o', 51 | 'ö' => 'o', 52 | 'ø' => 'o', 53 | 54 | 'ř' => 'r', 55 | 'ŕ' => 'r', 56 | 'ř' => 'r', 57 | 58 | 'š' => 's', 59 | 'š' => 's', 60 | 61 | 'ť' => 't', 62 | 63 | 'ú' => 'u', 64 | 'ú' => 'u', 65 | 'û' => 'u', 66 | 'ü' => 'u', 67 | 'ü' => 'u', 68 | 'ü' => 'u', 69 | 'ů' => 'u', 70 | 71 | 'ý' => 'y', 72 | 'ý' => 'y', 73 | 74 | 'ž' => 'z', 75 | 'ž' => 'z', 76 | 77 | 'Á' => 'A', 78 | 'Ä' => 'A', 79 | 80 | 'Ć' => 'C', 81 | 'Č' => 'C', 82 | 83 | 'Ď' => 'D', 84 | 85 | 'É' => 'E', 86 | 'Ě' => 'E', 87 | 88 | 'Í' => 'I', 89 | 90 | 'Ĺ' => 'L', 91 | 'Ľ' => 'l', 92 | 93 | 'Ň' => 'N', 94 | 'Ń' => 'N', 95 | 96 | 'Ó' => 'O', 97 | 'Ô' => 'o', 98 | 'Ö' => 'O', 99 | 100 | 'Ŕ' => 'R', 101 | 'Ř' => 'R', 102 | 103 | 'Š' => 'S', 104 | 105 | 'Ť' => 'T', 106 | 107 | 'Ü' => 'U', 108 | 'Ü' => 'U', 109 | 'Ú' => 'U', 110 | 'Û' => 'U', 111 | 'Ů' => 'U', 112 | 113 | 'Ý' => 'Y', 114 | 115 | 'Ž' => 'Z', 116 | 117 | ' ' => '_', 118 | '(' => '_', 119 | ')' => '_', 120 | '+' => '-', 121 | ';' => '-', 122 | '[' => '_', 123 | ']' => '_', 124 | '~' => '-', 125 | '–' => '-', 126 | '—' => '-', 127 | '•' => '-', 128 | '⧸' => '-', 129 | '⧹' => '-', 130 | '"' => '', 131 | ':' => '-', 132 | '?' => '', 133 | '|' => '-', 134 | '..' => '.', 135 | '--' => '-', 136 | '__' => '_', 137 | ]; 138 | 139 | $work = true; 140 | do { 141 | $i = 0; 142 | $dirs = []; 143 | $paths = []; 144 | $names1 = []; 145 | $names2 = []; 146 | clearstatcache(); 147 | echo "Reading folders\n"; 148 | 149 | foreach ($iterator = new RecursiveIteratorIterator( 150 | new RecursiveDirectoryIterator( 151 | "./", 152 | RecursiveDirectoryIterator::SKIP_DOTS 153 | ), RecursiveIteratorIterator::SELF_FIRST 154 | ) as $item) { 155 | $path = $iterator->getSubPath(); 156 | $sub = $iterator->getSubPathName(); 157 | $name = $iterator->getFileName(); 158 | $fix = strtolower(strtr($name, $map)); 159 | $fix = preg_replace('!_+!', '_', $fix); 160 | 161 | $fix = str_replace('-_', '-', $fix); 162 | $fix = str_replace('.-', '.', $fix); 163 | $fix = str_replace('-.', '.', $fix); 164 | $fix = str_replace('._', '.', $fix); 165 | $fix = str_replace('_-', '-', $fix); 166 | $fix = str_replace('_.', '.', $fix); 167 | $fix = str_replace('_-_', '-', $fix); 168 | 169 | $fix = trim($fix, ' _-.'); 170 | $fix = preg_replace('!_+!', '_', $fix); 171 | $fix = preg_replace('/[^a-z0-9_\-.]/', '', $fix); 172 | 173 | if ($item->isDir()) { 174 | if ($name != $fix) { 175 | $dirs[$sub] = substr_count($sub, "/"); 176 | $names1[$sub] = $name; 177 | $names2[$sub] = $fix; 178 | $paths[$sub] = $path; 179 | echo "+"; 180 | $i++; 181 | } else { 182 | echo "."; 183 | } 184 | } 185 | } 186 | arsort($dirs); 187 | 188 | if (count($dirs)) { 189 | $fixes = count($dirs); 190 | echo "\nFixing folders: {$fixes}x\n\n"; 191 | 192 | $fails = 0; 193 | foreach ($dirs??=[] as $k => $v) { 194 | if ($paths[$k] == "") { 195 | $paths[$k] = "."; 196 | } 197 | echo "> $paths[$k]/$names2[$k]\n"; 198 | if (!@rename("$paths[$k]/$names1[$k]", "$paths[$k]/$names2[$k]")) { 199 | $fails++; 200 | echo "\n! {$fails}. FAIL: " 201 | . "{$paths[$k]}/{$names1[$k]}" 202 | . " -> {$paths[$k]}/{$names2[$k]}\n"; 203 | } 204 | } 205 | } else { 206 | $work = false; 207 | } 208 | } while ($work); 209 | 210 | echo "\nFixing files\n"; 211 | foreach ($iterator = new RecursiveIteratorIterator( 212 | new RecursiveDirectoryIterator( 213 | "./", 214 | RecursiveDirectoryIterator::SKIP_DOTS 215 | ), RecursiveIteratorIterator::SELF_FIRST 216 | ) as $item) { 217 | $path = $iterator->getSubPath(); 218 | $sub = $iterator->getSubPathName(); 219 | $name = $iterator->getFileName(); 220 | $fix = strtolower(strtr($name, $map)); 221 | $fix = preg_replace('!_+!', '_', $fix); 222 | 223 | $fix = str_replace('-_', '-', $fix); 224 | $fix = str_replace('.-', '.', $fix); 225 | $fix = str_replace('-.', '.', $fix); 226 | $fix = str_replace('._', '.', $fix); 227 | $fix = str_replace('_-', '-', $fix); 228 | $fix = str_replace('_.', '.', $fix); 229 | $fix = str_replace('_-_', '-', $fix); 230 | $fix = trim($fix, ' _-.'); 231 | 232 | $fix = preg_replace('!_+!', '_', $fix); 233 | $fix = preg_replace('!-+!', '-', $fix); 234 | $fix = str_replace('..', '.', $fix); 235 | $fix = preg_replace('/[^a-z0-9_\-.]/', '', $fix); 236 | 237 | // special case 238 | if ($fix === 'concat') { 239 | $fix = '.concat'; 240 | } 241 | 242 | if ($item->isDir()) { 243 | continue; 244 | } else { 245 | if (strlen($path) == 0 && $name != $fix) { 246 | echo " * $fix\n"; 247 | @rename($name, $fix); 248 | } 249 | if (strlen($path) && $name != $fix) { 250 | echo " * $fix\n"; 251 | @rename($path . DS . $name, $path . DS . $fix); 252 | } 253 | } 254 | } 255 | --------------------------------------------------------------------------------