├── .std.h.sh ├── LICENSE ├── README.md ├── baker ├── bdl ├── catservice ├── ccat ├── dogservice ├── hpwd ├── og++4.8 ├── pelf ├── pelf_extract ├── pelf_linker ├── prev ├── randexec ├── ttts ├── unnappear ├── voices_ttts.md ├── whoch └── xpointerkeys /.std.h.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #### "Standard" POSIX SH library. #### 3 | #############################Provides: 4 | 5 | # spinner() require() palette255 6 | 7 | # Display a spinner loader with the colors declared(or not!) in the COOLSPINNERCOLOR variable 8 | spinner() { 9 | if [ -z "$COOLSPINNER" ]; then 10 | COOLSPINNER='|/-\\' 11 | fi 12 | 13 | if [ -z "$COOLSPINNER_COLOR" ]; then 14 | COOLSPINNER_COLOR='\033[0m' 15 | fi 16 | 17 | if [ -z "$COOLSPINNER_DELAY" ]; then 18 | COOLSPINNER_DELAY=0.1 19 | fi 20 | 21 | len=$(printf "%s" "$COOLSPINNER" | wc -c | awk '{print $1}') 22 | trap 'printf "\033[?25h"; exit' INT 23 | 24 | while true; do 25 | i=1 26 | while [ "$i" -le "$len" ]; do 27 | char=$(printf "%s" "$COOLSPINNER" | cut -c "$i") 28 | if [ -n "$COOLSPINNER_COLOR" ]; then 29 | printf "%b%s%b" "$COOLSPINNER_COLOR" "$char" "\033[0m" 30 | else 31 | printf "%s" "$char" 32 | fi 33 | sleep "$COOLSPINNER_DELAY" 34 | printf "\r" 35 | i=$((i + 1)) 36 | done 37 | done 38 | } 39 | 40 | # Check if a dependency is installed. 41 | require() { 42 | command -v "$1" >/dev/null 2>&1 || { printf "Error: %s is not installed\n" "$1" >&2; exit 1; } 43 | } 44 | 45 | # Display a color palette of N colors with(out) text. 46 | palette() { 47 | [ -z "$COOLPALETTE" ] && COOLPALETTE=16 48 | p_display() { 49 | for c in $(seq 0 "$((COOLPALETTE - 1))"); do 50 | [ "$COOLPALETTE_TEXT" = "0" ] && printf '\033[48;5;%dm ' "$c" || printf '\033[48;5;%dm%3d' "$c" "$c" 51 | done 52 | printf '\033[0m\n' 53 | } 54 | p_display 55 | } 56 | 57 | unnappear() { 58 | "$@" >/dev/null 2>&1 59 | } 60 | s() { 61 | export "$1"="$2" 62 | } 63 | 64 | set_colors() { 65 | color00="#272822" # Base 00 - Black 66 | color01="#f92672" # Base 08 - Red 67 | color02="#a6e22e" # Base 0B - Green 68 | color03="#f4bf75" # Base 0A - Yellow 69 | color04="#66d9ef" # Base 0D - Blue 70 | color05="#ae81ff" # Base 0E - Magenta 71 | color06="#a1efe4" # Base 0C - Cyan 72 | color07="#f8f8f2" # Base 05 - White 73 | color08="#75715e" # Base 03 - Bright Black 74 | color09="#f92672" # Base 08 - Bright Red 75 | color10="#a6e22e" # Base 0B - Bright Green 76 | color11="#f4bf75" # Base 0A - Bright Yellow 77 | color12="#66d9ef" # Base 0D - Bright Blue 78 | color13="#ae81ff" # Base 0E - Bright Magenta 79 | color14="#a1efe4" # Base 0C - Bright Cyan 80 | color15="#f9f8f5" # Base 07 - Bright White 81 | color16="#fd971f" # Base 09 82 | color17="#cc6633" # Base 0F 83 | color18="#383830" # Base 01 84 | color19="#49483e" # Base 02 85 | color20="#a59f85" # Base 04 86 | color21="#f5f4f1" # Base 06 87 | color_foreground="#f8f8f2" # Base 05 88 | color_background="#272822" # Base 00 89 | 90 | # Variables to set 91 | s GUM_FILE_CURSOR_FOREGROUND "$color00" 92 | s GUM_FILE_SYMLINK_FOREGROUND "$color19" 93 | s GUM_FILE_DIRECTORY_FOREGROUND "$color02" 94 | s GUM_FILE_FILE_FOREGROUND "$color_foreground" 95 | s GUM_FILE_PERMISSIONS_FOREGROUND "$color20" 96 | s GUM_FILE_SELECTED_FOREGROUND "$color00" 97 | s GUM_FILE_FILE_SIZE_FOREGROUND "$color21" 98 | # s GUM_CONFIRM_PROMPT_FOREGROUND "$color_foreground" 99 | # s GUM_CONFIRM_SELECTED_FOREGROUND "$color09" # Set to a color similar to Base 09 100 | # s GUM_CONFIRM_UNSELECTED_FOREGROUND "$color07" # Set to a color similar to Base 07 101 | s GUM_FILTER_INDICATOR_FOREGROUND "$color00" 102 | s GUM_FILTER_SELECTED_PREFIX_FOREGROUND "$color00" 103 | s GUM_FILTER_UNSELECTED_PREFIX_FOREGROUND "$color21" 104 | s GUM_FILTER_HEADER_FOREGROUND "$color21" 105 | s GUM_FILTER_TEXT_FOREGROUND "$color_foreground" 106 | s GUM_FILTER_CURSOR_TEXT_FOREGROUND "$color_foreground" 107 | s GUM_FILTER_MATCH_FOREGROUND "$color00" 108 | s GUM_FILTER_PROMPT_FOREGROUND "$color21" 109 | s GUM_FILTER_PLACEHOLDER_FOREGROUND "$color21" 110 | s GUM_INPUT_PROMPT_FOREGROUND "$color_foreground" 111 | s GUM_INPUT_PLACEHOLDER_FOREGROUND "$color02" # Set to a color similar to Base 0B 112 | s GUM_INPUT_CURSOR_FOREGROUND "$color07" 113 | s GUM_INPUT_HEADER_FOREGROUND "$color21" 114 | s GUM_WRITE_BASE_FOREGROUND "" 115 | s GUM_WRITE_CURSOR_LINE_NUMBER_FOREGROUND "$color05" 116 | s GUM_WRITE_CURSOR_LINE_FOREGROUND "$color_foreground" 117 | s GUM_WRITE_CURSOR_FOREGROUND "$color07" # Set to a color similar to Base 0E 118 | s GUM_WRITE_END_OF_BUFFER_FOREGROUND "$color00" 119 | s GUM_WRITE_LINE_NUMBER_FOREGROUND "$color07" # Set to a color similar to Base 05 120 | s GUM_WRITE_HEADER_FOREGROUND "$color21" 121 | s GUM_WRITE_PLACEHOLDER_FOREGROUND "$color21" 122 | s GUM_WRITE_PROMPT_FOREGROUND "$color07" # Set to a color similar to Base 05 123 | s GUM_CHOOSE_CURSOR_FOREGROUND "$color05" # Set to a color similar to Base 0E 124 | s GUM_CHOOSE_HEADER_FOREGROUND "$color21" 125 | s GUM_CHOOSE_ITEM_FOREGROUND "$color_foreground" 126 | s GUM_CHOOSE_SELECTED_FOREGROUND "$color05" # Set to a color similar to Base 0E 127 | } 128 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright <2024> . “New BSD License” or “Modified BSD License”. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | Handyscripts 4 |
5 | 6 |

7 | 8 | 9 | #### These should work on most POSIX systems. I try to minimize dependency on sucky software like that made by the FSF/GNU. If these script are not suckless, or do not work with any POSIX compatible system, please let me know, also, if you make changes, I'd be grateful if you made a PR. 10 | --- 11 | - #### Setup & Config 12 | > 1. **Clone** to `/usr/local/bin` and OR/AND any place in your `$PATH` 13 | > 2. Set executable bit with `chmod +x`. 14 | --- 15 | - [**Baker**](https://github.com/xplshn/Handyscripts/blob/main/baker) **➼** Rreceives a file as an argument and copies it to `.bak`, when invoked with `-R` it moves `.bak` to ``. 16 | > - When using -R do not suppply files ending in .bak, the script automatically detects them, if you want, you can do .bak.bak by using "baker .bak", though I do not recommend you do that, it quickly becomes confusing. Keep in mind that -R does not switch places with and .bak, it moves .bak to . 17 | --- 18 | - [**bdl (Binary Downloader)**](https://github.com/xplshn/Handyscripts/blob/main/ccat) **➼** Simple script that downloads `~ 1000` *statically linked*, *pre-built programs* to `.local/shared/bin` from : [Azathothas/Toolpacks](https://github.com/Azathothas/Toolpacks) `|` [Azathothas/Static-Binaries](https://github.com/Azathothas/Static-Binaries) `|` [Azathothas/static-toolbox](https://github.com/Azathothas/static-toolbox) 19 | > - It can Run(without installing), Install, Remove, List or give Info about programs or Search them (Fuzzy search that matches agains descriptions and package names). 20 | > > ```bash 21 | > > ❯ Usage: bdl {run|install|remove|search|info|list|tldr} 22 | > > 23 | > > curl -qfsSL "https://raw.githubusercontent.com/xplshn/Handyscripts/main/bdl" | bash -s -- {OPTIONS_HERE} 24 | > > #Example 25 | > > curl -qfsSL "https://raw.githubusercontent.com/xplshn/Handyscripts/main/bdl" | bash -s -- run neofetch 26 | > > ``` 27 | > - The Run option runs programs from /tmp, it caches them to a file, so if you run a program with the flag run more than one time, the second time it will not have to download the program anymore, if more than 40+ programs are cached, the cache deletes the first 40+ programs. It uses TMPFS for this behavior. Please edit the script to your likings, the first part of it contains variables you can change. 28 | > - It is not POSIX, but it works under BASH and shells which support extended POSIX. If you know how to fix that, how to make it suck less, I'd be grateful if you'd make an issue or a PR. For now, in the first run it will bootstrap bash by grabbing the binary from the Buildbase repo and then on subsequent runs it will use bash. The syntax is POSIX but MIGHT rely on undefined behaviour (When running under SH). 29 | > - Implemented in 363LOC! # Could be smaller but has many features. 30 | > - Rewritten in Golang: [bigDL](https://github.com/xplshn/bigdl) 31 | [![asciicast](https://asciinema.org/a/FzUYlDLumlbv3vYWjAa1BmYBx.svg)](https://asciinema.org/a/FzUYlDLumlbv3vYWjAa1BmYBx) 32 | --- 33 | - [**ccat (ColorCat)**](https://github.com/xplshn/Handyscripts/blob/main/ccat) **➼** Wrapper for cat that uses source-highlight to highlight text whenever a deffinition file matches the content of the text. Really handy! I recommend doing an alias, since it behaves exactly like cat. 34 | --- 35 | - [**catservice**](https://github.com/xplshn/Handyscripts/blob/main/catservice) `|` [**dogservice**](https://github.com/xplshn/Handyscripts/blob/main/dogservice) **➼** catservice and dogservice deliver fresh cat/dogs photos to your terminal (See the script and API documentation to change sizes, breeds, etc. Add to your shell's rc for maximum productivity) 36 | > ![image](https://github.com/xplshn/Handyscripts/assets/114888778/442b2ff0-ec1a-49eb-abf4-9eef15ecfcd0) 37 | --- 38 | - [**OG++4.8**](https://github.com/xplshn/Handyscripts/blob/main/og%2B%2B4.8) **➼** Wrapper for using an online compiler's API, currently, it does not support stdin or many libraries apart from those that come with g++. You can edit the og++4.8 script and change its version in the "compiler_cmd" variable. It is very OG. 39 | --- 40 | - [**TTTS(Tiktok Text-To-Speech)**](https://github.com/xplshn/Handyscripts/blob/main/ttts) **➼** is a script that abuses an API, that also abuses the Tiktok API 41 | > - The unnoficial API it uses to connect to tiktok's API can only parse 300 characters per request. In this script that is contemplated and so the text is cut into parts. You can also pass the voice you want to use, like this: ttts "Gangzta!" "en_us_009". Or use it along with TGPT and whisper.cpp's "command" tool to make an assistant that can even run commands(using tgpt -s you can ask tgpt to produce commands). 42 | > - See [voices_ttts.md](https://github.com/xplshn/Handyscripts/blob/main/voices_ttts.md) 43 | --- 44 | - [**whoch**](https://github.com/xplshn/Handyscripts/blob/main/whoch) **➼** REALLY HANDY when working with a big PATH variable, or with "replacing" commands, whoch receives a command as an argument and acts the same way as which, however, whoch prints out an ordered list of where that command is in your PATH. 45 | > - If you have `/usr/local/bin/cargo` and `/usr/bin/cargo`, if whoch were invoked with "cargo" as argument it'd print out this: 46 | > ```bash 47 | > $ whoch cargo 48 | > #output 49 | > /usr/local/bin/cargo 50 | > /usr/bin/cargo 51 | > ``` 52 | - [**pelf**](https://github.com/xplshn/Handyscripts/blob/main/pelf) **➼** PELF or rather, Pack an ELF is a utility that creates a bundle of a dynamic binary, it takes a binary and bundles its dependencies into a single, executable file. Along with optional directories, binaries and libraries, which are all accesible from the packed binary, as they are in its LD_LIBRARY_PATH and PATH. This allows for creating wrappers so that you can pack an entire C toolchain into a single executable, which is something I've done using Zig's static releases. 53 | > - It needs tar and base64. It is POSIX2008 compatible. It has proven to work on Alpine and .blobs generated across other systems work too (There might be some exceptions due to ABI differences.) of the same libc, one may use patchelf to change the interpreter prior to packing the binary. The compression can be changed by modifying the script, keep in mind that using base64 will expand the size of data by 37.6%, one can also use [`ascii85`](https://github.com/xplshn/m_ascii85) which only expands size by 13%. 54 | > ```sh 55 | > $ pelf $(which chocolate-doom) ./chocolate-doom.blob # The name can not be set arbitrarily. 56 | > $ ./chocolate-doom.blob 57 | > Chocolate Doom 3.0.1 58 | > Z_Init: Init zone memory allocation daemon. 59 | > zone memory: 0x7fd294494020, 1000000 allocated for zone 60 | > Using /tmp/.local/share/chocolate-doom/ for configuration and saves 61 | > V_Init: allocate screens. 62 | > M_LoadDefaults: Load system defaults. 63 | > saving config in /tmp/.local/share/chocolate-doom/default.cfg 64 | > Game mode indeterminate. No IWAD file was found. Try 65 | > specifying one with the '-iwad' command line parameter. 66 | > # as you can see, it works. Most programs can be packed this way, even graphical ones ; Some others may require you to create wrappers, to add extra binaries or libraries which do not appear in ldd's output. 67 | > # I've also managed to pack my window manager along with a few X utils into a single file (programs packed alongside each other can be accessed from the main program's PATH) 68 | > # An example you can try to see the capabilities of PELF is to pack the xfce4-terminal into a single binary, ofc PELF won't track python dependencies, or schemas or other misc files a program may need, but you can still use the --add-arbitrary functionality and create a wrapper for the main binary, then add the real binary with --add-binary. 69 | > # You can also create "development boxes", a binary which when executed launches a shell with a custom PATH and LD_LIBRARY_PRELOAD, the dev box can contain Golang, Make, Zig C as a portable C compiler, Rust's Cargo, etc, all by creating a wrappper that modifies some env variables (e,g for Go; GOROOT="$(dirname "$devbox_bindir")/go") and using --add-arbitrary to add the necessary folders which contain the programs' files 70 | > ``` 71 | - [**xpointerkeys**](https://github.com/xplshn/Handyscripts/blob/main/xpointerkeys) **➼** Enables X's pointerkeys feature "setxkbmap -option "keypad:pointerkeys". 72 | --- 73 | -------------------------------------------------------------------------------- /baker: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$#" -eq 1 ] && [ "$1" = "--help" ]; then 4 | printf 'Usage: %s [-R]\n' "$0" >&2 5 | printf 'baker will create a .bak file in the directory of .\n' >&2 6 | printf 'baker -R will move .bak to , efectively restoring .bak to its original place.\n' >&2 7 | printf 'Options:\n' >&2 8 | printf ' -R Recover the file from its .bak backup\n' >&2 9 | printf 'VERSION: 0.1 \n' 10 | exit 1 11 | fi 12 | 13 | if [ "$#" -ne 1 ] && [ "$#" -ne 2 ]; then 14 | printf 'Usage: %s [-R]\n' "$0" >&2 15 | exit 1 16 | fi 17 | 18 | file="$1" 19 | bak_file="${file}.bak" 20 | 21 | backup_file() { 22 | if [ -f "$file" ]; then 23 | if [ -f "$bak_file" ]; then 24 | printf 'baker: Backup file %s already exists\n' "$bak_file" >&2 25 | else 26 | cp "$file" "$bak_file" && 27 | printf 'baker: Backed up %s to %s\n' "$file" "$bak_file" 28 | fi 29 | else 30 | printf 'baker: %s does not exist or is not a regular file\n' "$file" >&2 31 | fi 32 | } 33 | 34 | recover_file() { 35 | if [ -f "$bak_file" ]; then 36 | mv "$bak_file" "$file" && 37 | printf 'baker: Recovered %s from %s\n' "$file" "$bak_file" 38 | else 39 | printf 'baker: %s does not exist or is not a regular file\n' "$bak_file" >&2 40 | fi 41 | } 42 | 43 | if [ "$#" -eq 2 ] && [ "$1" = "-R" ]; then 44 | file="$2" 45 | bak_file="${file}.bak" 46 | recover_file 47 | else 48 | backup_file 49 | fi 50 | -------------------------------------------------------------------------------- /bdl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # NOT POSIX, AT ALL. TODO: Make this not suck. Create a bash fork that does not have any of the BASH exclusive "features" and is 100% POSIX and ISO C. 3 | # UPDATE: POSIX syntax. Still relies on undefined behaviour/BASHisms/features the GNU might have accidentally implemented in their attempt to rework Thompson Shell. 4 | # If you install "Gum" (https://github.com/charmbracelet/gum) you will get some TUI fanciness. 5 | # UPDATE: Dismiss the TODO; Try: "https://github.com/xplshn/bigdl", which you can statically link, and no longer depend on anything but a Linux system. 6 | 7 | INAME="$0" 8 | GREEN='\033[0;32m' 9 | YELLOW='\033[1;33m' 10 | NC='\033[0m' # No Color 11 | 12 | # Directories, files, etc. NOTE: Not consistent. TODO: Enhance readability, simplify variables. 13 | INSTALL_DIR="${HOME}/.local/bin" # You may change this to whatever dir you want, make sure to add it to your PATH. 14 | TEMP_DIR="${TMPDIR:-/tmp}/bdl_cached" 15 | BOOTSTRAP_DIR="$HOME/.cache/bdl_bootstraped" 16 | CACHE_FILE="${TMPDIR:-${TEMP_DIR}}/bdl_install-less_bins_cached" 17 | METADATA_URL="https://raw.githubusercontent.com/metis-os/hysp-pkgs/main/data/metadata.json" 18 | SYSTEM_ARCH="$(uname -m)" 19 | if [ -z "$BASH_VERSION" ]; then 20 | xPATH="$PATH" 21 | PATH="$PATH:$BOOTSTRAP_DIR" 22 | if command -v bash >/dev/null 2>&1; then 23 | exec bash "$0" "$@" 24 | else 25 | echo "Running under SH, some features might not work(run), unless bash is installed or bootstrapped, there will be undefined behaviour. If the command you want to run fails try one more time. It might be related to this." 26 | fi 27 | PATH="$xPATH" 28 | fi 29 | 30 | spinner() { 31 | if [ -z "$COOLSPINNER" ]; then 32 | COOLSPINNER='|/-\\' 33 | fi 34 | if [ -z "$COOLSPINNER_COLOR" ]; then 35 | COOLSPINNER_COLOR='\033[0m' 36 | fi 37 | if [ -z "$COOLSPINNER_DELAY" ]; then 38 | COOLSPINNER_DELAY=0.1 39 | fi 40 | len=$(printf "%s" "$COOLSPINNER" | wc -c | awk '{print $1}') 41 | trap 'printf "\033[?25h"; exit' INT 42 | while true; do 43 | i=1 44 | while [ "$i" -le "$len" ]; do 45 | char=$(printf "%s" "$COOLSPINNER" | cut -c "$i") 46 | if [ -n "$COOLSPINNER_COLOR" ]; then 47 | printf "%b%s%b" "$COOLSPINNER_COLOR" "$char" "\033[0m" 48 | else 49 | printf "%s" "$char" 50 | fi 51 | sleep "$COOLSPINNER_DELAY" 52 | printf "\r" 53 | i=$((i + 1)) 54 | done 55 | done 56 | } 57 | 58 | # Function to display colored output 59 | print_color() { 60 | printf "%b%s%b\\n" "$1" "$2" "$NC" 61 | } 62 | 63 | # Define a helper function to determine which fetcher tool (curl or wget) should be used for bootstrapping 64 | determine_fetcher() { 65 | if command -v wget >/dev/null 2>&1; then 66 | FETCHER="wget" 67 | elif command -v curl >/dev/null 2>&1; then 68 | FETCHER="curl" 69 | else 70 | printf "Neither curl nor wget found. Cannot proceed with bootstrapping.\n" 71 | return 1 72 | fi 73 | } 74 | 75 | fetch_binary() { 76 | PACKAGE_NAME="$1" 77 | nINSTALL_DIR="$2" 78 | DESTINATION="${3:-$nINSTALL_DIR/$PACKAGE_NAME}" 79 | mkdir -p "$nINSTALL_DIR" 80 | determine_fetcher 81 | SOURCE_URL=$(find_url "$PACKAGE_NAME") 82 | if [ -z "$SOURCE_URL" ]; then 83 | print_color "$YELLOW" "Source URL not found for '$PACKAGE_NAME'." 84 | return 1 85 | fi 86 | COOLSPINNER_COLOR='\033[92m' 87 | spinner & spinner_pid=$! 88 | if [ "$FETCHER" = "curl" ]; then 89 | if ! "$FETCHER" -o "$DESTINATION" "$SOURCE_URL" >/dev/null 2>&1; then 90 | kill "$spinner_pid" >/dev/null 2>&1 # Stop the spinner 91 | printf "\033[2K\r" # Clear the spinner character 92 | print_color "$YELLOW" "Failed to fetch $PACKAGE_NAME." 93 | return 1 94 | fi 95 | chmod +x "$DESTINATION" && 96 | kill "$spinner_pid" >/dev/null 2>&1 # Stop the spinner 97 | printf "\033[2K\r" # Clear the spinner character 98 | print_color "$GREEN" "Fetched binary successfully." 99 | else 100 | if ! "$FETCHER" -O "$DESTINATION" "$SOURCE_URL" >/dev/null 2>&1; then 101 | kill "$spinner_pid" >/dev/null 2>&1 # Stop the spinner 102 | printf "\033[2K\r" # Clear the spinner character 103 | print_color "$YELLOW" "Failed to fetch $PACKAGE_NAME." 104 | return 1 105 | fi 106 | chmod +x "$DESTINATION" && 107 | kill "$spinner_pid" >/dev/null 2>&1 # Stop the spinner 108 | printf "\033[2K\r" # Clear the spinner character 109 | print_color "$GREEN" "Fetched binary successfully." 110 | fi 111 | } 112 | 113 | # Function to retrieve cached file location 114 | return_cached_file() { 115 | PACKAGE_NAME="$1" 116 | 117 | if [ -f "$CACHE_FILE" ] && grep -q "^$PACKAGE_NAME " "$CACHE_FILE"; then 118 | CACHED_LOCATION=$(grep -E "^$PACKAGE_NAME " "$CACHE_FILE" | awk '{ print $2 }') 119 | if [ -n "$CACHED_LOCATION" ]; then 120 | printf "%s\n" "$CACHED_LOCATION" 121 | return 0 122 | fi 123 | fi 124 | 125 | return 1 126 | } 127 | 128 | # Function to clean the cache (limit 40 programs) 129 | clean_cache() { 130 | if [ -f "$CACHE_FILE" ]; then 131 | # Remove duplicate entries in the cache 132 | awk '!seen[$0]++' "$CACHE_FILE" > temp.txt 133 | mv temp.txt "$CACHE_FILE" 134 | 135 | # Remove non-existent files from the cache 136 | while read -r line; do 137 | cached_package=$(echo "$line" | awk '{print $1}') 138 | cached_file=$(echo "$line" | awk '{print $2}') 139 | if [ ! -f "$TEMP_DIR/$cached_file" ] || [ "$cached_package" != "$(echo "$cached_file" | cut -d'-' -f 1 | cut -d'_' -f 2-)" ]; then 140 | sed -i "/$cached_file/d" "$CACHE_FILE" 141 | fi 142 | done < "$CACHE_FILE" 143 | fi 144 | } 145 | 146 | # Function to run from cache or fetch if not found 147 | run_from_cache() { 148 | PACKAGE_NAME="$1" 149 | CACHED_LOCATION=$(return_cached_file "$PACKAGE_NAME") 150 | 151 | if [ -n "$CACHED_LOCATION" ] && [ -x "$TEMP_DIR/$CACHED_LOCATION" ]; then 152 | printf "%bRunning '%s' from cache...%b\n" "$GREEN" "$PACKAGE_NAME" "$NC" 153 | clean_cache 154 | "$TEMP_DIR/$CACHED_LOCATION" "${@:2}" # Pass additional parameters as flags 155 | return 0 156 | else 157 | NEW_CACHED_LOCATION="bdl_$PACKAGE_NAME-$(date +'%s')" 158 | if fetch_binary "$PACKAGE_NAME" "$TEMP_DIR" "$TEMP_DIR/$NEW_CACHED_LOCATION"; then 159 | echo "$PACKAGE_NAME $NEW_CACHED_LOCATION" >> "$CACHE_FILE" # Update cache with the fetched binary 160 | clean_cache # Clean the cache 161 | "$TEMP_DIR/$NEW_CACHED_LOCATION" "${@:2}" # Execute the fetched binary 162 | return 0 163 | else 164 | return 1 165 | fi 166 | fi 167 | } 168 | 169 | install_binary() { 170 | PACKAGE_NAME="$1" 171 | 172 | # Check if the package name is empty 173 | if [ -z "$PACKAGE_NAME" ]; then 174 | print_color "$YELLOW" "No package name provided." 175 | return 176 | fi 177 | 178 | # Check if the binary is already installed in the INSTALL_DIR 179 | if [ -f "$INSTALL_DIR/$PACKAGE_NAME" ]; then 180 | print_color "$YELLOW" "The requested binary is already at: $INSTALL_DIR/$PACKAGE_NAME." 181 | if command -v gum >/dev/null 2>&1; then 182 | gum confirm "Do you want to continue?" || return 183 | else 184 | return 185 | fi 186 | fi 187 | 188 | # Get the cached location of the package 189 | CACHED_LOCATION=$(return_cached_file "$PACKAGE_NAME") 190 | 191 | if [ -n "$CACHED_LOCATION" ] && [ -x "$TEMP_DIR/$CACHED_LOCATION" ]; then 192 | print_color "$GREEN" "Installing '$PACKAGE_NAME' from cache..." 193 | mv "$TEMP_DIR/$CACHED_LOCATION" "$INSTALL_DIR/$PACKAGE_NAME" 194 | clean_cache # Remove duplicates and non-existent files from the cache 195 | return 1 196 | else 197 | # Fetch the binary if it's not found in the installation directory or cache 198 | fetch_binary "$PACKAGE_NAME" "$INSTALL_DIR" && print_color "$GREEN" "OK: $INSTALL_DIR/$PACKAGE_NAME" 199 | clean_cache # Remove duplicates and non-existent files from the cache 200 | fi 201 | } 202 | 203 | # Function to remove an installed package 204 | remove_package() { 205 | PACKAGE_NAME="$1" 206 | PACKAGE_LOCATION="$INSTALL_DIR/$PACKAGE_NAME" 207 | 208 | if [ -f "$PACKAGE_LOCATION" ]; then 209 | rm "$PACKAGE_LOCATION" && print_color "$GREEN" "Package '$PACKAGE_NAME' removed." 210 | else 211 | print_color "$YELLOW" "Package '$PACKAGE_NAME' is not installed." 212 | fi 213 | } 214 | 215 | # Function to retrieve package source URL 216 | find_url() { 217 | PACKAGE_NAME="$1" 218 | 219 | if [ -n "$NO_METADATA" ]; then 220 | if [ -n "$BASE" ]; then 221 | echo "https://bin.ajam.dev/$SYSTEM_ARCH/Baseutils/$PACKAGE_NAME" 222 | else 223 | echo "https://bin.ajam.dev/$SYSTEM_ARCH/$PACKAGE_NAME" 224 | fi 225 | return 226 | fi 227 | SOURCE_URL=$(curl -s "$METADATA_URL" | jq -r --arg pname "$PACKAGE_NAME" --arg sysarch "$SYSTEM_ARCH" \ 228 | '.packages[] | select(.name == $pname and .architecture == $sysarch) | .source') 229 | # Check if source URL is empty -> Find the URL manually if so. #NOTE:If the firt SOURCE_URL check works, it saves time, that's why we preffer extracting from metadata first and turning to "curl --fail" IFs/checks as a last resort 230 | if [ -z "$SOURCE_URL" ]; then 231 | SOURCE_URL="https://bin.ajam.dev/$SYSTEM_ARCH/$PACKAGE_NAME" 232 | if ! curl --location --output /dev/null --silent --fail "$SOURCE_URL"; then 233 | SOURCE_URL="https://bin.ajam.dev/$SYSTEM_ARCH/Baseutils/$PACKAGE_NAME" 234 | if ! curl --location --output /dev/null --silent --fail "$SOURCE_URL"; then 235 | SOURCE_URL="https://raw.githubusercontent.com/xplshn/Handyscripts/master/$PACKAGE_NAME" 236 | if ! curl --location --output /dev/null --silent --fail "$SOURCE_URL"; then 237 | print_color "$YELLOW" "Source URL not found for '$PACKAGE_NAME'." 238 | return 1 239 | fi 240 | fi 241 | fi 242 | fi 243 | printf '%s\n' "$SOURCE_URL" 244 | } 245 | 246 | # Function to show detailed package information with color 247 | show_package_info() { 248 | PACKAGE_NAME="$1" 249 | 250 | # Start spinner in the background & capture its PID. 251 | spinner & spinner_pid=$! 252 | PACKAGE_INFO=$(curl -s "$METADATA_URL" | jq --arg pname "$PACKAGE_NAME" --arg sysarch "$SYSTEM_ARCH" \ 253 | '.packages[] | select(.name == $pname and .architecture == $sysarch) | {description, name, version, updated, size, sha, source}') 254 | if [ -z "$PACKAGE_INFO" ]; then 255 | # Kill the spinner if download fails 256 | kill "$spinner_pid" >/dev/null 2>&1 257 | # Clear the line 258 | printf "\033[2K\r" 259 | # Print error. 260 | print_color "$YELLOW" "Info for package '$PACKAGE_NAME' not found in the metadata.json file. Please contribute to $METADATA_URL." 261 | else 262 | # Kill the spinner if download succeeds 263 | kill "$spinner_pid" >/dev/null 2>&1 264 | # Clear the line 265 | printf "\033[2K\r" 266 | # SUCCESS: Print info in JSON. 267 | print_color "$GREEN" "$PACKAGE_INFO" 268 | fi 269 | } 270 | 271 | fSearch() { 272 | SEARCH_TERM="$1" 273 | 274 | # Fetch metadata 275 | METADATA=$(curl -s "$METADATA_URL") 276 | 277 | # Check if metadata retrieval failed 278 | if [ -z "$METADATA" ]; then 279 | printf "Failed to fetch package information.\n" 280 | return 1 281 | fi 282 | 283 | # Filter packages based on the search term 284 | SEARCH_RESULTS=$(printf '%s\n' "$METADATA" | jq -r --arg sterm "$SEARCH_TERM" \ 285 | '.packages[] | select(.name + .description | test($sterm; "i")) | "\(.name) - \(.description)"' | sort -u) 286 | 287 | # Check if no matching packages found 288 | if [ -z "$SEARCH_RESULTS" ]; then 289 | printf "No matching packages found for '%s'.\n" "$SEARCH_TERM" 290 | return 1 291 | elif [ "$(echo "$SEARCH_RESULTS" | wc -l)" -gt 10 ]; then # Maximum results length 292 | printf "Too many matching packages found for '%s'.\n" "$SEARCH_TERM" 293 | return 1 294 | elif ! echo "$SEARCH_RESULTS" | grep -w "$SEARCH_TERM" > /dev/null; then 295 | printf "No matching packages found for '%s'.\n" "$SEARCH_TERM" 296 | return 1 297 | fi 298 | 299 | # Determine the truncation length 300 | TRUNC_LENGTH=$(( $(tput cols 2>/dev/null || echo "80") - 3 )) 301 | 302 | # Check if the package binary exists in the INSTALL_DIR and print results with installation state indicators 303 | printf '%s\n' "$SEARCH_RESULTS" | while IFS= read -r line; do # Take out the "grep -w" line if you want ACTUAL fuzzy search 304 | NAME=$(echo "$line" | awk -F ' - ' '{print $1}') 305 | DESCRIPTION=$(echo "$line" | awk -F ' - ' '{$1=""; print substr($0,2)}') 306 | CACHED_LOCATION=$(return_cached_file "$NAME") 307 | if [ -f "$INSTALL_DIR/$NAME" ]; then 308 | PREFIX="[i]" 309 | elif [ -n "$CACHED_LOCATION" ] && [ -x "$TEMP_DIR/$CACHED_LOCATION" ]; then 310 | PREFIX="[c]" 311 | else 312 | PREFIX="[-]" 313 | fi 314 | 315 | # Calculate available space for description 316 | AVAILABLE_SPACE=$((TRUNC_LENGTH - ${#PREFIX} - ${#NAME} - 4)) # 4 accounts for space around ' - ' 317 | 318 | # Truncate the description if it exceeds the available space 319 | if [ ${#DESCRIPTION} -gt "$AVAILABLE_SPACE" ]; then 320 | DESCRIPTION=$(printf '%s' "$DESCRIPTION" | cut -c 1-"$AVAILABLE_SPACE" | sed 's/[ ,]*$//;s/,$//') # Shrink to the maximum line size + Remove trailing spaces & commas. 321 | DESCRIPTION="${DESCRIPTION}..." 322 | fi 323 | 324 | printf "%s %s - %s\n" "$PREFIX" "$NAME" "$DESCRIPTION" 325 | done 326 | } 327 | 328 | # Function to list all possible packages 329 | list_packages() { 330 | spinner & spinner_pid=$! 331 | packages=$( 332 | { 333 | curl -qfsSL "https://bin.ajam.dev/$SYSTEM_ARCH/METADATA.json" && \ 334 | curl -qfsSL "https://bin.ajam.dev/$SYSTEM_ARCH/Baseutils/METADATA.json" && \ 335 | curl -qfsSL "https://api.github.com/repos/xplshn/Handyscripts/contents" 336 | } | jq -r '.[] | (.Name // .name)' | grep -v "\.7z$\|\.bz2$\|\.json$\|\.gz$\|\.md$\|\.txt$\|\.tar$\|\.zip$\|_dir$" | sort -u) 337 | 338 | kill "$spinner_pid" >/dev/null 2>&1 339 | printf "\033[2K\r%s\n" "$packages" 340 | } 341 | 342 | bootstrap() { 343 | mkdir -p "$BOOTSTRAP_DIR" 344 | PATH="$PATH:$BOOTSTRAP_DIR" 345 | if [ -n "$FETCHER" ]; then 346 | export NO_METADATA=1 347 | if ! command -v bash >/dev/null 2>&1; then 348 | print_color "${YELLOW}" "bash is not available. Bootstrapping..." 349 | BASE="true" fetch_binary "bash" "$BOOTSTRAP_DIR" 350 | fi 351 | if ! command -v curl >/dev/null 2>&1; then 352 | print_color "${YELLOW}" "curl is not installed. Bootstrapping..." 353 | fetch_binary curl "$BOOTSTRAP_DIR" 354 | fi 355 | if ! command -v jq >/dev/null 2>&1; then 356 | print_color "${YELLOW}" "jq is not installed. Bootstrapping..." 357 | fetch_binary "jq" "$BOOTSTRAP_DIR" 358 | fi 359 | if ! command -v awk >/dev/null 2>&1; then 360 | print_color "${YELLOW}" "awk is not installed. Bootstrapping..." 361 | BASE="true" fetch_binary "awk" "$BOOTSTRAP_DIR" 362 | fi 363 | if ! command -v tput >/dev/null 2>&1; then 364 | print_color "${YELLOW}" "tput is not available (from the netcurses package). Bootstrapping..." 365 | BASE="true" fetch_binary "tput" "$BOOTSTRAP_DIR" 366 | fi 367 | unset NO_METADATA 368 | fi 369 | } 370 | 371 | stubdl() { 372 | DEST="/tmp/._bdlstub_bigdl.bin" 373 | 374 | ARCH="$(uname -m)" 375 | if [ "$ARCH" = "x86_64" ]; then 376 | ARCH_SUFFIX="amd64" 377 | elif [ "$ARCH" = "aarch64" ]; then 378 | ARCH_SUFFIX="arm64" 379 | else 380 | echo "Unsupported architecture: $ARCH" 381 | exit 1 382 | fi 383 | 384 | BIGDL="https://github.com/xplshn/bigdl/releases/latest/download/bigdl_fast_${ARCH_SUFFIX}" 385 | 386 | if [ "$1" = "--install" ]; then 387 | DEST="$2" 388 | fi 389 | 390 | if [ -e "$DEST" ] && [ ! "$1" = "--install" ]; then 391 | "$DEST" "$@" 392 | else 393 | mkdir -p "$(dirname "$DEST")" 394 | if command -v wget >/dev/null 2>&1; then 395 | wget -q "$BIGDL" -O "$DEST" 396 | elif command -v curl >/dev/null 2>&1; then 397 | curl -qfsSL "$BIGDL" -o "$DEST" 398 | else 399 | echo "Neither wget nor curl is available." 400 | exit 1 401 | fi 402 | 403 | [ -e "$DEST" ] && [ "$1" = "--install" ] && echo "BIGDL IS NOW AVAILABLE. ($DEST)" 404 | chmod +x "$DEST" 405 | [ ! "$1" = "--install" ] && "$DEST" "$@" 406 | fi 407 | } 408 | 409 | determine_fetcher && bootstrap && \ 410 | case $1 in 411 | run) 412 | run_from_cache "$2" "${@:3}" 413 | ;; 414 | install) 415 | install_binary "$2" 416 | ;; 417 | remove) 418 | remove_package "$2" 419 | ;; 420 | search) 421 | fSearch "$2" 422 | ;; 423 | info) 424 | show_package_info "$2" 425 | ;; 426 | list) 427 | list_packages 428 | ;; 429 | find_url) 430 | find_url "$2" 431 | ;; 432 | tldr) 433 | run_from_cache tlrc "${@:2}" # Official TL;DR pages client written in Rust. 434 | ;; 435 | bigdl) 436 | shift 437 | stubdl "${@}" # Run bigdl (A total rewrite of bdl, which corrects all of its downfalls and implements a new `update` feature. bigdl is designed to be pretty. bigdl releases weight no more than 2 megs) 438 | ;; 439 | *) 440 | 441 | if [ "$1" = "what" ] && [ "$2" = "is" ] && [ "$3" = "bigdl?" -o "$3" = "bigdl" ]; then 442 | run_from_cache glow "https://raw.githubusercontent.com/xplshn/bigdl/master/README.md" 443 | exit 444 | fi 445 | 446 | if [ "$1" = "put" ] && [ "$2" = "bigdl" ] && [ "$3" = "at" ] && [ -n "$4" ]; then 447 | stubdl --install "$4" 448 | exit 449 | fi 450 | 451 | printf 'Usage: %s [list|install|remove|run|info|search|tldr|bigdl] [args...]\n' "$INAME" 452 | printf 'Usage: %s bdl is deprecated, please read about its rewrite/replacement in Go using the following command: ' "$INAME" 453 | print_color "$YELLOW" "$INAME what is bigdl?" 454 | printf 'Usage: %s You may also simply try it using the following command: ' "$INAME" 455 | print_color "$YELLOW" "$INAME bigdl" 456 | printf 'Usage: %s If you wish to install bigdl, use the following command: ' "$INAME" 457 | print_color "$YELLOW" "$INAME put bigdl at $HOME/.local/bin/bigdl" 458 | exit 1 459 | ;; 460 | esac 461 | 462 | exit 0 463 | -------------------------------------------------------------------------------- /catservice: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Download the image using curl with follow redirects 4 | curl -sS -L "https://api.thecatapi.com/v1/images/search?size=med&mime_types=jpg&format=src&has_breeds=true&order=RANDOM&page=0&limit=1" --output /tmp/cat_image.jpg 5 | 6 | # Check if download was successful 7 | if [ -f "/tmp/cat_image.jpg" ]; then 8 | # Display the downloaded image using viu if available 9 | if command -v viu >/dev/null 2>&1; then 10 | viu -w 15 -h 10 /tmp/cat_image.jpg 11 | rm /tmp/cat_image.jpg 12 | else 13 | echo "viu is not available to display the image." 14 | echo "You can view the downloaded image at: /tmp/cat_image.jpg" 15 | rm /tmp/cat_image.jpg 16 | fi 17 | else 18 | echo "Failed to download the image." 19 | fi 20 | -------------------------------------------------------------------------------- /ccat: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Use source-highlight with provided arguments and pass to cat 4 | source-highlight --out-format=esc -o STDOUT -i "$@" 2>/dev/null || cat "$@" 5 | -------------------------------------------------------------------------------- /dogservice: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Download the image using curl with follow redirects 4 | curl -sS -L "https://api.thedogapi.com/v1/images/search?size=med&mime_types=jpg&format=src&has_breeds=true&order=RANDOM&page=0&limit=1" --output /tmp/cat_image.jpg 5 | 6 | # Check if download was successful 7 | if [ -f "/tmp/cat_image.jpg" ]; then 8 | # Display the downloaded image using viu if available 9 | if command -v viu >/dev/null 2>&1; then 10 | viu -w 15 -h 10 /tmp/cat_image.jpg 11 | rm /tmp/cat_image.jpg 12 | else 13 | echo "viu is not available to display the image." 14 | echo "You can view the downloaded image at: /tmp/cat_image.jpg" 15 | rm /tmp/cat_image.jpg 16 | fi 17 | else 18 | echo "Failed to download the image." 19 | fi 20 | -------------------------------------------------------------------------------- /hpwd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Function to abbreviate directories under $HOME 4 | path() { 5 | if [ "$PWD" = "$HOME" ]; then 6 | [ "$PWD" = "$HOME" ] && [ -n "$COOLHOME" ] || COOLHOME="~" 7 | printf '%s' "$COOLHOME" 8 | 9 | elif [ "${PWD#"$HOME"/}" != "$PWD" ]; then 10 | [ -n "$COOLHOME_PREFIX" ] || COOLHOME_PREFIX="~" 11 | printf '%s' "$COOLHOME_PREFIX/${PWD#"$HOME"/} " # Display '~/...' for directories inside home 12 | 13 | else 14 | printf '%s' "$PWD " # Display the full path if outside home 15 | 16 | fi 17 | } 18 | 19 | # Print the abbreviated directory path 20 | path 21 | -------------------------------------------------------------------------------- /og++4.8: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Function to compile code using the online compiler 4 | compile_code() { 5 | source_content="$1" 6 | output_file="$2" 7 | execute_cmd="$3" 8 | 9 | # Construct the compiler command 10 | compiler_cmd="g++-4.8 main.cpp" 11 | 12 | # Construct the JSON string for the POST request 13 | json_data=$(jq -n --arg cmd "$compiler_cmd && $execute_cmd" --arg src "$source_content" '{"cmd": $cmd, "src": $src}') 14 | 15 | # Send the code to the online compiler using a POST request 16 | compiler_output=$(printf '%s' "$json_data" | curl -s -X POST -H "Content-Type: application/json" -d @- "http://coliru.stacked-crooked.com/compile") 17 | 18 | if [ -n "$output_file" ]; then 19 | printf '%s' "$compiler_output" > "$output_file" 20 | chmod +x "$output_file" 21 | else 22 | printf '%s' "$compiler_output" 23 | printf '\n' 24 | fi 25 | } 26 | 27 | # Check if file paths were provided as arguments 28 | if [ "$#" -eq 0 ]; then 29 | printf 'Usage: %s [-o output_file] ...\n' "$0" 30 | exit 1 31 | fi 32 | 33 | # Parse command-line options 34 | output_file="" 35 | execute_cmd="./a.out" 36 | 37 | while [ $# -gt 0 ]; do 38 | case $1 in 39 | -o) 40 | output_file="$2" 41 | execute_cmd="cat ./a.out" 42 | shift 2 43 | ;; 44 | *) 45 | break 46 | ;; 47 | esac 48 | done 49 | 50 | # Read the contents of the provided files 51 | source_content="" 52 | 53 | for file in "$@"; do 54 | if [ -f "$file" ]; then 55 | content=$(cat "$file") 56 | source_content="$source_content$content" 57 | else 58 | printf 'File not found: %s\n' "$file" 59 | exit 1 60 | fi 61 | done 62 | 63 | # Compile the provided C++ code 64 | compile_code "$source_content" "$output_file" "$execute_cmd" 65 | 66 | -------------------------------------------------------------------------------- /pelf: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # shellcheck disable=SC2034 4 | # shellcheck disable=SC3028 5 | 6 | # PELF. Pack an ELF. 7 | # PELF receives a binary as its first argument and an output as its second argument. It will pack all the necessary libraries that it needs to run, except the libC and LD. PELFs may include optional files inside, be it a library, binary, folder or file. 8 | 9 | LICENSE="BSD-3-Clause License\n 10 | Copyright <2024> \n 11 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n 12 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n 13 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n 14 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \“AS IS\” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n 16 | " 17 | 18 | # Check if the required arguments are provided 19 | if [ "$#" -lt 2 ]; then 20 | echo "Usage: $0 [ELF_SRC_PATH] [DST_PATH.blob] <--add-library [LIB_PATH]> <--add-binary [BIN_PATH]> <--add-metadata [icon128x128.xpm|icon128x128.png|app.desktop]> <--add-arbitrary [DIR|FILE]>" >&2 21 | exit 1 22 | fi 23 | 24 | # Create a temporary directory for bundling the files 25 | outer_tmp_dir="/tmp/pelf_$(date '+%s%M%S')_$RANDOM" 26 | tmp_dir="$outer_tmp_dir/pelf_$(date '+%s%M%S')_$RANDOM" 27 | mkdir -p "$tmp_dir/bin" "$tmp_dir/libs" || exit 1 28 | trap 'rm -rf "$outer_tmp_dir"' EXIT 29 | 30 | src="$1" 31 | dst="$2" 32 | 33 | # Function to figure out what libraries the binaries need/depend on. 34 | add_thelibs() { 35 | # Copy the libraries from the executable to the temporary directory 36 | ldd "$1" | awk ' 37 | # Store the first word of the first line 38 | NR == 1 { first_word = $1 } 39 | # For lines with =>, check if the third word is not the same as the first word of the first line 40 | /=>/ && $3 != first_word { print $3 } 41 | ' | while read -r lib; do 42 | # Copy the library to the temporary directory 43 | cp -L "$lib" "$tmp_dir/libs" || exit 1 44 | done 45 | } 46 | 47 | # Function to handle adding libraries 48 | add_library() { 49 | lib="$1" 50 | cp -L "$lib" "$tmp_dir/libs" || exit 1 51 | add_thelibs "$lib" || exit 1 52 | } 53 | 54 | # Function to handle adding binaries 55 | add_binary() { 56 | binary="$1" 57 | add_thelibs "$binary" 58 | cp -L "$binary" "$tmp_dir/bin/$(basename "$binary")" || exit 1 59 | } 60 | 61 | add_arbitrary() { 62 | cp -LR "$1" "$tmp_dir" || { echo "Failed to copy arbitrary files"; exit 1; } 63 | } 64 | 65 | add_metadata() { 66 | case "$1" in 67 | *.png | *.xpm | *.desktop) 68 | mkdir -p "$tmp_dir"/bundledMetadata || { echo "Failed to create directory"; exit 1; } 69 | cp -LR -- "$1" "$tmp_dir"/bundledMetadata/icon128x128."${1##*.}" || { echo "Failed to copy file"; exit 1; } 70 | ;; 71 | *) 72 | echo "File extension not supported. Must be .png, .xpm or .desktop. If you supply an icon, size must be 128x128" 73 | exit 1 74 | ;; 75 | esac 76 | } 77 | 78 | shift 2 # To access --(add)itional arguments 79 | 80 | # Process the optional arguments --add-library, --add-binary, and --add-arbitrary 81 | while [ "$#" -gt 0 ]; do 82 | case "$1" in 83 | --add-library) 84 | add_library "$2" 85 | shift 2 86 | ;; 87 | --add-binary) 88 | add_binary "$2" 89 | shift 2 90 | ;; 91 | --add-metadata) 92 | add_metadata "$2" 93 | shift 2 94 | ;; 95 | --add-arbitrary) 96 | add_arbitrary "$2" 97 | shift 2 98 | ;; 99 | 100 | *) 101 | echo "Invalid argument: $1" >&2 102 | exit 1 103 | ;; 104 | esac 105 | done 106 | 107 | # Copy the executable to the temporary directory 108 | add_binary "$src" || exit 1 109 | 110 | # Create a tar archive of the executable, libraries and additional files. 111 | if ! tar -C "$tmp_dir" -czf "$outer_tmp_dir/archive.tar.gz" .; then 112 | echo "Extraction failed" >&2 113 | exit 1 114 | fi 115 | 116 | # Create a self-extracting script 117 | cat > "$dst" << 'SCRIPT' 118 | #!/bin/sh 119 | # Get the binary's name 120 | rEXE_NAME="$(basename "$0" .blob)" 121 | [ -n "$EXE_NAME" ] || EXE_NAME="$rEXE_NAME" 122 | TMPDIR="/tmp/.pelfbundles/pbundle_$rEXE_NAME$(date '+%s%M%S')_$RANDOM" 123 | LIBS_BULKDIR="/tmp/pelfbundle_libs-bulkdir" 124 | cleanup() { 125 | if [ -z "$found_runningInstance" ] || [ "$found_runningInstance" != "1" ]; then 126 | # Delete individual files only if they are used exclusively by the current process 127 | for file in $REM_AFTERUSE; do 128 | if [ -z "$(fuser "$file" 2>/dev/null | grep "$EXE_NAME_PID")" ]; then 129 | rm "$file" 130 | fi 131 | done 132 | 133 | # Delete the directory 134 | rm -rf "$TMPDIR" 135 | fi 136 | } 137 | # Set up the trap 138 | trap cleanup EXIT 139 | ########################################################### 140 | 141 | # BASH version 142 | #set_tmpdir_from_env() { 143 | # # Construct the variable name by appending _bindir to $rEXENAME 144 | # var_name="${rEXE_NAME}_bindir" 145 | # 146 | # # Check if the constructed variable name exists and is not empty 147 | # if [ -n "${!var_name}" ]; then 148 | # # Set TMPDIR to the directory name of the constructed variable 149 | # TMPDIR="$(dirname "${!var_name}")" 150 | # found_runningInstance=1 151 | # return 152 | # fi 153 | #} 154 | 155 | set_tmpdir_from_env() { 156 | # Construct the variable name by appending _bindir to $rEXENAME 157 | var_name="${rEXE_NAME}_bindir" 158 | 159 | # Check if the constructed variable name exists and is not empty 160 | eval "var_value=\${$var_name}" 161 | if [ -d "$var_value" ]; then 162 | # Set TMPDIR to the directory name of the constructed variable 163 | TMPDIR="$(dirname "$var_value")" 164 | found_runningInstance=1 165 | return 166 | fi 167 | } 168 | 169 | set_tmpdir_from_env 170 | if [ -z "$found_runningInstance" ] || [ "$found_runningInstance" != "1" ]; then 171 | # Find the start position of the archive 172 | ARCHIVE_MARKER=$(awk '/^__ARCHIVE_MARKER__/ { print NR + 1; exit }' "$0") 173 | 174 | # Construct the variable name by appending _bindir to $rEXENAME 175 | var_name="${rEXE_NAME}_bindir" 176 | # Decode the base64-encoded archive and extract it 177 | mkdir -p "$TMPDIR" && tail -n +$ARCHIVE_MARKER "$0" | base64 -d | tar -xzf - -C "$TMPDIR" >/dev/null 2>&1 || { 178 | # Use eval to check if the constructed variable name exists and is not empty 179 | echo "Extraction failed" >&2 180 | eval "var_value=\"\${$var_name}\"" 181 | exit 1 182 | } 183 | fi 184 | 185 | # Function to check if a library is found in system paths 186 | is_library_in_system() { 187 | library=$1 188 | if [ -e "/usr/lib/$library" ] || [ -e "/lib/$library" ] || [ -e "/lib64/$library" ]; then 189 | return 0 # Library found in system 190 | else 191 | return 1 # Library not found in system 192 | fi 193 | } 194 | 195 | # Check if USE_SYSTEM_LIBRARIES is set to 1 or doesn't exist 196 | if [ "${USE_SYSTEM_LIBRARIES:-0}" -eq 1 ]; then 197 | for lib_file in "$TMPDIR/libs/"*; do 198 | lib_name=$(basename "$lib_file") 199 | 200 | if is_library_in_system "$lib_name"; then 201 | if [ "$SHOW_DISCARDPROCESS" -eq 1 ]; then 202 | echo "$lib_name found in system. Using the system's library." 203 | fi 204 | rm "$lib_file" 205 | else 206 | if [ "$SHOW_DISCARDPROCESS" -eq 1 ]; then 207 | echo "$lib_name not found in system. Using the bundl 208 | ed library." 209 | fi 210 | fi 211 | done 2>/dev/null 212 | fi 213 | 214 | mv_u() { 215 | SRC_DIR="$1" 216 | DEST_DIR="$2" 217 | 218 | # Loop through each file in the source directory 219 | for file in "$SRC_DIR"/*; do 220 | # Check if the file is a regular file 221 | [ -f "$file" ] || continue 222 | # Extract the filename from the path 223 | filename=$(basename "$file") 224 | # Check if the file does not exist in the destination directory or is newer 225 | if [ ! -e "$DEST_DIR/$file" ]; then 226 | REM_AFTERUSE="$REM_AFTERUSE $DEST_DIR/$filename " 227 | mv "$file" "$DEST_DIR/" 228 | elif [ "$(find "$file" -newer "$DEST_DIR/$filename" 2>/dev/null)" ]; then 229 | # Move the file to the destination directory 230 | mv "$file" "$DEST_DIR/" 231 | fi 232 | done 233 | } 234 | 235 | # Add extra binaries to the PATH, if they are there. 236 | if [ "$(ls -1 "$TMPDIR"/bin | wc -l)" -gt 1 ]; then 237 | if [ -z "$found_runningInstance" ] || [ "$found_runningInstance" != "1" ]; then 238 | export "$(echo "$rEXE_NAME" | sed -E 's/[-.]([a-zA-Z])/\U\1/g; s/[-.]//g')_bindir"="$TMPDIR/bin" 239 | export "$(echo "$rEXE_NAME" | sed -E 's/[-.]([a-zA-Z])/\U\1/g; s/[-.]//g')_libs"="$TMPDIR/libs" 240 | fi 241 | xPATH="$TMPDIR/bin:$PATH" 242 | USE_BULKLIBS=0 243 | fi 244 | 245 | # Figure out what we do 246 | binDest="$TMPDIR/bin/$EXE_NAME" 247 | case "$1" in 248 | --pbundle_help) 249 | printf "Description: Pack an ELF\n" 250 | printf "Usage:\n <--pbundle_link |--pbundle_help|--pbundle_xpmIcon|--pbundle_pngIcon|--pbundle_desktop> \n" 251 | printf "EnvVars:\n USE_BULKLIBS=[0,1]\n USE_SYSTEM_LIBRARIES=[1,0]\n SHOW_DISCARDPROCESS=[0,1]\n HELP_PAGE_LIST_PACKEDFILES=[0,1]\n" 252 | if [ "$HELP_PAGE_LIST_PACKEDFILES" = "1" ]; then 253 | ls "$TMPDIR"/* 254 | fi 255 | exit 1 256 | ;; 257 | --pbundle_link) 258 | binDest="$2" 259 | shift 2 260 | ;; 261 | --pbundle_xpmIcon) 262 | icon_path="$TMPDIR/bundledMetadata/icon128x128.xpm" 263 | if [ -f "$icon_path" ]; then 264 | base64 "$icon_path" 265 | exit 0 266 | else 267 | exit 1 268 | fi 269 | ;; 270 | --pbundle_pngIcon) 271 | icon_path="$TMPDIR/bundledMetadata/icon128x128.png" 272 | if [ -f "$icon_path" ]; then 273 | base64 "$icon_path" 274 | exit 0 275 | else 276 | exit 1 277 | fi 278 | ;; 279 | --pbundle_desktop) 280 | desktop_path="$TMPDIR/bundledMetadata/app.desktop" 281 | if [ -f "$desktop_path" ]; then 282 | base64 "$desktop_path" 283 | exit 0 284 | else 285 | exit 1 286 | fi 287 | ;; 288 | esac 289 | 290 | # Execute the binary with extracted libraries using LD_LIBRARY_PATH 291 | if [ "${USE_BULKLIBS:-0}" -eq 1 ]; then 292 | mkdir -p "$LIBS_BULKDIR" 293 | mv_u "$TMPDIR/libs" "$LIBS_BULKDIR" 294 | PATH="$PATH:$xPATH" LD_LIBRARY_PATH="$LIBS_BULKDIR" SELF_TEMPDIR="$TMPDIR" "$binDest" "$@" || exit 1 295 | EXE_NAME_PID="$!" 296 | else 297 | PATH="$PATH:$xPATH" LD_LIBRARY_PATH="$TMPDIR/libs" SELF_TEMPDIR="$TMPDIR" "$binDest" "$@" || exit 1 298 | EXE_NAME_PID="$!" 299 | fi 300 | 301 | exit $? 302 | __ARCHIVE_MARKER__ 303 | SCRIPT 304 | 305 | # Append the base64-encoded archive to the self-extracting script 306 | base64 <"$outer_tmp_dir/archive.tar.gz" >> "$dst" || exit 1 307 | 308 | # Make the self-extracting script executable 309 | chmod +x "$dst" || exit 1 310 | -------------------------------------------------------------------------------- /pelf_extract: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Check if the required arguments are provided 4 | if [ $# -lt 2 ]; then 5 | echo "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | INPUT_FILE="$1" 10 | TMPDIR="$2" 11 | 12 | # Find the line number where the archive starts 13 | ARCHIVE_MARKER=$(awk '/^__ARCHIVE_MARKER__/ { print NR + 1; exit }' "$INPUT_FILE") 14 | 15 | # Create the temporary directory if it doesn't exist 16 | mkdir -p "$TMPDIR" 17 | 18 | # Extract the base64-encoded archive and decode it 19 | tail -n +$ARCHIVE_MARKER "$INPUT_FILE" | base64 -d | tar -xzf - -C "$TMPDIR" || { 20 | echo "Extraction failed" >&2 21 | exit 1 22 | } 23 | 24 | echo "Files extracted successfully to $TMPDIR" 25 | -------------------------------------------------------------------------------- /pelf_linker: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Function to concatenate all *_bindir environment variables into PELF_BINDIRS 4 | 5 | vval="" 6 | PELF_BINDIRS="" 7 | PELF_LIBDIRS="" 8 | 9 | concatenate_bindirs() { 10 | # Target any variable ending with _bindir 11 | vars="$(env | grep ".*_bindir=" | cut -f 1 -d '=')" 12 | for v in $vars; do 13 | # Use eval to get the value of the variable 14 | eval "vval=\$$v" 15 | # Append the value to PELF_BINDIRS, ensuring to add a colon if it's not the first entry 16 | if [ -z "$PELF_BINDIRS" ]; then 17 | PELF_BINDIRS="$vval" 18 | else 19 | PELF_BINDIRS="$PELF_BINDIRS:$vval" 20 | fi 21 | done 22 | 23 | # Print the concatenated PELF_BINDIRS 24 | if [ -z "$1" ]; then 25 | echo "PELF_BINDIRS=\"$PELF_BINDIRS\"" 26 | fi 27 | } 28 | 29 | # Function to concatenate all *_bindir environment variables into PELF_LIBDIRS 30 | concatenate_libdirs() { 31 | # Target any variable ending with _bindir 32 | vars="$(env | grep ".*_libs=" | cut -f 1 -d '=')" 33 | for v in $vars; do 34 | # Use eval to get the value of the variable 35 | eval "vval=\$$v" 36 | # Append the value to PELF_LIBDIRS, ensuring to add a colon if it's not the first entry 37 | if [ -z "$PELF_LIBDIRS" ]; then 38 | PELF_LIBDIRS="$vval" 39 | else 40 | PELF_LIBDIRS="$PELF_LIBDIRS:$vval" 41 | fi 42 | done 43 | 44 | # Print the concatenated PELF_LIBDIRS 45 | if [ -z "$1" ]; then 46 | echo "PELF_LIBDIRS=\"$PELF_LIBDIRS\"" 47 | fi 48 | } 49 | 50 | # Call the functions 51 | concatenate_bindirs "$1" 52 | concatenate_libdirs "$1" 53 | 54 | if [ "$1" = "--export" ]; then 55 | export PELF_LIBDIRS="$PELF_LIBDIRS" 56 | export PELF_BINDIRS="$PELF_BINDIRS" 57 | else 58 | LD_LIBRARY_PATH="$PELF_LIBDIRS" PATH="$PATH:$PELF_BINDIRS" "$@" 59 | fi 60 | -------------------------------------------------------------------------------- /prev: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Function to display help page 4 | display_help() { 5 | printf "Usage: %s URL [Viewport: Width Height] [Width]\n" "$0" 6 | } 7 | 8 | # Function to check if a variable contains a number 9 | contains_number() { 10 | case $1 in 11 | *[!0-9]*) return 1 ;; # Variable does not contain only digits 12 | *) return 0 ;; # Variable contains only digits 13 | esac 14 | } 15 | 16 | # Function to display an image using viu 17 | display_image() { 18 | image_path="$1" 19 | viu "$image_path" 20 | } 21 | 22 | # Function to capture screenshot and display using viu 23 | capture_screenshot() { 24 | local url="$1" 25 | 26 | # Capture a screenshot using the API 27 | local api_endpoint="http://api.screenshotlayer.com/api/capture" 28 | local access_key="1c3d44a2fe16192e5b576d3ae4cd74f1" # Replace with your actual access key 29 | 30 | # Check if the URL ends with supported image extensions or if it's a direct link to an image 31 | if printf "%s\n" "$url" | grep -Eq "\.(jpg|jpeg|png|webp)$" || curl -sI "$url" | grep -iqE "Content-Type: image"; then 32 | # Direct link to an image file or supported image Content-Type 33 | local extension=$(printf "%s\n" "$url" | awk -F . '{print $NF}') 34 | if curl -s "$url" -o "/tmp/prev_web_screenshot.$extension"; then 35 | display_image "/tmp/prev_web_screenshot.$extension" 36 | rm -f "/tmp/prev_web_screenshot.$extension" 37 | else 38 | printf "Failed to download and display the image.\n" 39 | fi 40 | else 41 | # Fetch the screenshot using curl and identify the image type using file command 42 | local file_info=$(curl -sI "$url" | file -) 43 | if printf "%s\n" "$file_info" | grep -iq "image"; then 44 | local file_extension=$(printf "%s\n" "$file_info" | awk '{print $2}') 45 | if curl -s "${api_endpoint}?access_key=${access_key}&url=${url}&viewport=${SIZE1}x${SIZE2}&width=${SIZE3}" -o "/tmp/prev_web_screenshot.$file_extension"; then 46 | display_image "/tmp/prev_web_screenshot.$file_extension" 47 | rm -f "/tmp/prev_web_screenshot.$file_extension" 48 | else 49 | printf "Failed to capture a screenshot from the provided URL.\n" 50 | fi 51 | else 52 | printf "Unsupported image format.\n" 53 | fi 54 | fi 55 | } 56 | 57 | 58 | # Check if the script is called with an argument 59 | if [ $# -eq 0 ]; then 60 | display_help 61 | exit 1 62 | fi 63 | 64 | SIZE1="${2:-800}" 65 | SIZE2="${3:-800}" 66 | SIZE3="${4:-$SIZE1}" 67 | 68 | # Check if SIZEs contain numbers 69 | if ! contains_number "$SIZE1" || ! contains_number "$SIZE2" || ! contains_number "$SIZE3"; then 70 | SIZE1=800 71 | SIZE2=800 72 | SIZE3="$SIZE1" 73 | fi 74 | 75 | input="$1" 76 | capture_screenshot "$input" 77 | -------------------------------------------------------------------------------- /randexec: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Random execution... 4 | 5 | # Generate a random number between 1 and 100. 6 | random_number=$(awk 'BEGIN{srand(); print int(100*rand())}') 7 | 8 | # Check if the random number falls within the 2% range 9 | if [ "$random_number" -le 2 ]; then 10 | $@ 11 | fi 12 | -------------------------------------------------------------------------------- /ttts: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Make the output of a command dissappear 4 | unnappear() { 5 | "$@" >/dev/null 2>&1 6 | } 7 | 8 | # Display a spinner loader with the colors declared(or not!) in the COOLSPINNERCOLOR variable 9 | spinner() { 10 | if [ -z "$COOLSPINNER" ]; then 11 | COOLSPINNER='|/~\\' 12 | fi 13 | 14 | if [ -z "$COOLSPINNER_COLOR" ]; then 15 | COOLSPINNER_COLOR='\033[0m' 16 | fi 17 | 18 | if [ -z "$COOLSPINNER_DELAY" ]; then 19 | COOLSPINNER_DELAY=0.1 20 | fi 21 | 22 | len=$(printf "%s" "$COOLSPINNER" | wc -c | awk '{print $1}') 23 | trap 'printf "\033[?25h"; exit' INT 24 | 25 | while true; do 26 | i=1 27 | while [ "$i" -le "$len" ]; do 28 | char=$(printf "%s" "$COOLSPINNER" | cut -c "$i") 29 | if [ -n "$COOLSPINNER_COLOR" ]; then 30 | printf "%b%s%b" "$COOLSPINNER_COLOR" "$char" "\033[0m" 31 | else 32 | printf "%s" "$char" 33 | fi 34 | sleep "$COOLSPINNER_DELAY" 35 | printf "\b" 36 | i=$((i + 1)) 37 | done 38 | done 39 | } 40 | 41 | # Function to check and create cache file if it doesn't exist 42 | initialize_cache() { 43 | CACHE_DIR=${TMPDIR:-/tmp} 44 | CACHE_FILE="$CACHE_DIR/ttts_cache" 45 | if [ ! -f "$CACHE_FILE" ]; then 46 | touch "$CACHE_FILE" 47 | chmod 600 "$CACHE_FILE" 48 | fi 49 | } 50 | # Function to check if audio is cached 51 | check_cached_audio() { 52 | cached_audio=$(grep -E "^$TEXT;$VOICE;" "$CACHE_FILE" | awk -F';' '{print $3}') 53 | if [ -n "$cached_audio" ]; then 54 | printf "Audio for '%s' with voice '%s' found in cache.\n" "$TEXT" "$VOICE" 55 | # Decode and play cached audio data using available command 56 | temp_cached_audio="$CACHE_DIR/ttts_cached_audio_$$$$.mp3" 57 | echo "$cached_audio" | base64 -d > "$temp_cached_audio" 58 | play_cached_audio "$temp_cached_audio" 59 | rm -f "$temp_cached_audio" 60 | exit 0 61 | else 62 | fetch_and_cache_audio 63 | fi 64 | } 65 | # Function to play cached audio 66 | play_cached_audio() { 67 | # Show spinner while playing audio. 68 | spinner & spinner_pid=$! 69 | 70 | if command -v mpg123 >/dev/null 2>&1; then 71 | unnappear mpg123 "$1" 72 | elif command -v play >/dev/null 2>&1; then 73 | unnappear play -t mp3 "$1" 74 | elif command -v termux-media-player >/dev/null 2>&1; then 75 | unnappear termux-media-player play "$1" 76 | elif command -v audioplay >/dev/null 2>&1; then 77 | unnappear audioplay "$1" 78 | else 79 | printf "Please install 'mpg123' or 'sox' to play audio.\n" 80 | fi 81 | # Stop spinner once audio playback is finished. 82 | kill $spinner_pid > /dev/null 2>&1 83 | printf "\b \b\b\b" # Clear spinner output 84 | } 85 | # Function to fetch audio data from API and cache it 86 | fetch_and_cache_audio() { 87 | spinner $$ & 88 | response=$(curl -sSL -X POST \ 89 | -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0' \ 90 | -H 'Accept: */*' \ 91 | -H 'Accept-Language: en-US,en;q=0.5' \ 92 | -H 'Referer: https://www.text-to-speech.app/' \ 93 | -H 'Content-Type: application/json' \ 94 | -H 'Origin: https://www.text-to-speech.app' \ 95 | -H 'DNT: 1' \ 96 | -H 'Connection: keep-alive' \ 97 | -H 'TE: trailers' \ 98 | --data-raw "{\"text\":\"$TEXT\",\"voice\":\"$VOICE\"}" \ 99 | "$API_URL") 100 | audio_data=$(echo "$response" | awk -F'"data":"|",' '{print $2}') 101 | kill $! > /dev/null 2>&1 # Kill the spinner. 102 | printf "\b\b\b \b\b\b" # Clear spinner output. 103 | if [ -n "$audio_data" ] && [ "$audio_data" != "null" ]; then 104 | temp_audio_file="$CACHE_DIR/ttts_cached_audio_$$$$.mp3" 105 | printf "Audio data saved to: %s\n" "$temp_audio_file" 106 | echo "$audio_data" | base64 -d > "$temp_audio_file" 107 | play_cached_audio "$temp_audio_file" 108 | echo "$TEXT;$VOICE;$audio_data" >> "$CACHE_FILE" 109 | # Keep the latest 1000 entries in the cache 110 | cache_size=$(wc -l < "$CACHE_FILE") 111 | if [ "$cache_size" -gt 1000 ]; then 112 | tail -n 1000 "$CACHE_FILE" > "$CACHE_FILE.tmp" 113 | mv "$CACHE_FILE.tmp" "$CACHE_FILE" 114 | fi 115 | else 116 | RED='\033[1;31m' #| Color Red 117 | GREEN='\033[0;32m' #| Color Green 118 | PURPLE='\033[0;35m' #| Color Purple 119 | NC='\033[0m' #| No Color 120 | printf "${RED}Failed to retrieve audio content from the API.${NC}\n" 121 | printf "The value of VOICE${RED}($2)${NC} might not be correct\n" 122 | printf "See documentation at ${PURPLE}https://github.com/xplshn/Handyscripts/blob/main/voices_ttts.md${NC}\n" 123 | printf "You can also execute: ${GREEN}curl -SsL https://raw.githubusercontent.com/xplshn/Handyscripts/main/voices_ttts.md${NC}\n" 124 | fi 125 | } 126 | # Main script logic starts here 127 | # Define API URL and voice 128 | API_URL="https://tiktok-tts.weilnet.workers.dev/api/generation" 129 | TEXT="$1" 130 | VOICE="en_us_009" 131 | # Check number of arguments 132 | if [ $# -lt 1 ] || [ $# -gt 2 ]; then 133 | printf "Usage: %s \"your text here\" [voice]\n" "$0" 134 | exit 1 135 | fi 136 | # Assign second argument to VOICE if it exists 137 | if [ $# -eq 2 ]; then 138 | VOICE="$2" 139 | fi 140 | initialize_cache 141 | check_cached_audio 142 | #fetch_and_cache_audio 143 | -------------------------------------------------------------------------------- /unnappear: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # /bin/ksh 3 | 4 | # Check if a command is provided 5 | if [ -z "$1" ]; then 6 | echo "Usage: $0 " 7 | exit 1 8 | fi 9 | 10 | # Execute the provided command and redirect its output to /dev/null 11 | "$@" >/dev/null 2>&1 12 | -------------------------------------------------------------------------------- /voices_ttts.md: -------------------------------------------------------------------------------- 1 | ### English US 2 | - "en_us_001": "Female" 3 | - "en_us_006": "Male 1" 4 | - "en_us_007": "Male 2" 5 | - "en_us_009": "Male 3" 6 | - "en_us_010": "Male 4" 7 | 8 | ### English UK 9 | - "en_uk_001": "Male 1" 10 | - "en_uk_003": "Male 2" 11 | 12 | ### English AU 13 | - "en_au_001": "Female" 14 | - "en_au_002": "Male" 15 | 16 | ### French 17 | - "fr_001": "Male 1" 18 | - "fr_002": "Male 2" 19 | 20 | ### German 21 | - "de_001": "Female" 22 | - "de_002": "Male" 23 | 24 | ### Spanish 25 | - "es_002": "Male" 26 | 27 | ### Spanish MX 28 | - "es_mx_002": "Male 1" 29 | - "es_male_m3": "Male 2" 30 | - "es_female_f6": "Female 1" 31 | - "es_female_fp1": "Female 2" 32 | - "es_mx_female_supermom": "Female 3" 33 | - "es_mx_male_transformer": "Optimus Prime (Transformers)" 34 | 35 | ### Portuguese BR 36 | - "br_003": "Female 2" 37 | - "br_004": "Female 3" 38 | - "br_005": "Male" 39 | 40 | ### Indonesian 41 | - "id_001": "Female" 42 | 43 | ### Japanese 44 | - "jp_001": "Female 1" 45 | - "jp_003": "Female 2" 46 | - "jp_005": "Female 3" 47 | - "jp_006": "Male" 48 | 49 | ### Korean 50 | - "kr_002": "Male 1" 51 | - "kr_004": "Male 2" 52 | - "kr_003": "Female" 53 | 54 | ### Characters 55 | - "en_us_ghostface": "Ghostface (Scream)" 56 | - "en_us_chewbacca": "Chewbacca (Star Wars)" 57 | - "en_us_c3po": "C3PO (Star Wars)" 58 | - "en_us_stitch": "Stitch (Lilo & Stitch)" 59 | - "en_us_stormtrooper": "Stormtrooper (Star Wars)" 60 | - "en_us_rocket": "Rocket (Guardians of the Galaxy)" 61 | 62 | ### Singing 63 | - "en_female_f08_salut_damour": "Alto" 64 | - "en_male_m03_lobby": "Tenor" 65 | - "en_male_m03_sunshine_soon": "Sunshine Soon" 66 | - "en_female_f08_warmy_breeze": "Warmy Breeze" 67 | - "en_female_ht_f08_glorious": "Glorious" 68 | - "en_male_sing_funny_it_goes_up": "It Goes Up" 69 | - "en_male_m2_xhxs_m03_silly": "Chipmunk" 70 | - "en_female_ht_f08_wonderful_world": "Dramatic" 71 | -------------------------------------------------------------------------------- /whoch: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Function to validate the command 4 | validate_command() { 5 | case $1 in 6 | *[![:alnum:]_-]* | "") return 1 ;; # Rejects non-alphanumeric, underscores, and hyphens 7 | *) return 0 ;; # Allows only alphanumeric, underscores, and hyphens 8 | esac 9 | } 10 | 11 | # Function to search for the command in PATH 12 | search_command_in_path() { 13 | command_to_find="$1" 14 | found=false 15 | 16 | IFS=: 17 | for dir in $PATH; do 18 | if [ -x "$dir/$command_to_find" ]; then 19 | echo "$dir/$command_to_find" 20 | found=true 21 | fi 22 | done 23 | 24 | if [ "$found" = false ]; then 25 | echo "Command '$command_to_find' not found in PATH" >&2 26 | exit 1 27 | fi 28 | } 29 | 30 | # Main function 31 | main() { 32 | if ! validate_command "$1"; then 33 | echo "Invalid command format. Please provide an alphanumeric command name only." >&2 34 | exit 1 35 | fi 36 | 37 | search_command_in_path "$1" 38 | } 39 | 40 | # Execute main function with arguments 41 | case "$1" in 42 | "-a") 43 | main "$2" | awk '!seen[$0]++' 44 | ;; 45 | "--aa") 46 | main "$2" 47 | ;; 48 | *) 49 | main "$@" | head -n 1 50 | ;; 51 | esac 52 | -------------------------------------------------------------------------------- /xpointerkeys: -------------------------------------------------------------------------------- 1 | #!/bin/dash 2 | 3 | current_option=$(setxkbmap -query | grep "keypad:pointerkeys" | wc -l) 4 | 5 | if [ $current_option -eq 0 ]; then 6 | setxkbmap -option "keypad:pointerkeys" 7 | echo "pointerkeys are now enabled." 8 | else 9 | echo "pointerkeys are already enabled" 10 | fi 11 | --------------------------------------------------------------------------------