diff options
Diffstat (limited to 'pkgs/sources/scripts/source/apps')
-rwxr-xr-x | pkgs/sources/scripts/source/apps/aumo.sh | 28 | ||||
-rwxr-xr-x | pkgs/sources/scripts/source/apps/con2pdf.sh | 234 | ||||
-rw-r--r-- | pkgs/sources/scripts/source/apps/fupdate.1.md | 70 | ||||
-rwxr-xr-x | pkgs/sources/scripts/source/apps/fupdate.sh | 197 | ||||
-rwxr-xr-x | pkgs/sources/scripts/source/apps/git-edit-index.sh | 98 |
5 files changed, 627 insertions, 0 deletions
diff --git a/pkgs/sources/scripts/source/apps/aumo.sh b/pkgs/sources/scripts/source/apps/aumo.sh new file mode 100755 index 00000000..84d39deb --- /dev/null +++ b/pkgs/sources/scripts/source/apps/aumo.sh @@ -0,0 +1,28 @@ +#! /usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +unmounting() { + disk_name="$(find /dev/disk/by-label -type l -printf "%P|" | rofi -sep "|" -dmenu -p "Select disk to mount")" + + udisksctl unmount --block-device "/dev/disk/by-label/$disk_name" +} + +mounting() { + disk_name="$(find /dev/disk/by-label -type l -printf "%P|" | rofi -sep "|" -dmenu -p "Select disk to mount")" + + udisksctl mount --block-device "/dev/disk/by-label/$disk_name" +} + +case "$1" in +"mount") + mounting + ;; +"unmount" | "umount") + unmounting + ;; +*) + die "Usage: $NAME mount|unmount" + ;; +esac diff --git a/pkgs/sources/scripts/source/apps/con2pdf.sh b/pkgs/sources/scripts/source/apps/con2pdf.sh new file mode 100755 index 00000000..08bf8998 --- /dev/null +++ b/pkgs/sources/scripts/source/apps/con2pdf.sh @@ -0,0 +1,234 @@ +#! /usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# needed for help() and version +# shellcheck disable=2034 +AUTHORS="Soispha" +# shellcheck disable=2034 +YEARS="2023" +# shellcheck disable=2034 +VERSION="1.0.0" + +# NAME is from the wrapper +# shellcheck disable=SC2269 +NAME="$NAME" +help() { + cat <<EOF +Scan images and turn them into a pdf. + +Usage: + $NAME [OPTIONS] --name --device + +OPTIONS: + --out-dir | -o [FILE] + Path to place the generated pdf files (default: ./pdf). + + --name | -n NAME + Name for the pdf files (e.g. <NAME>_1.pdf). + + --num-pages | -p NUM + Number of pages to merge into one pdf (default: 1). + + --device | -d DEVICE + Device used for scanning. + + --method | -m METHOD + Method to use for scanning (default: ADF). + + --help | -h + Display this help and exit. + + --version | -v + Display version and copyright information and exit. +ARGUMENTS: + FILE := [[fd . --max-depth 3]] + A name of a file to store, default is: ./pdf + + NAME | * := [[fd . --max-depth 3]] + The basename of the generated files + + NUM | *([0-9]) := 0 | 1 | 2 | 3 | 4 + Possible numbers of pages, can be more than 4 + + DEVICE := [[$(cat %DEVICE_FUNCTION)]] + Possible scanner names + + METHOD := ADF | Flatbed + The scanning method to use, not all scanners support both of + these. The default is ADF +EOF +} + +scan_adf() { + device="$1" + sides_per_page="$2" + method="ADF" + for i in $(seq "$sides_per_page"); do + do_until_success \ + "scanimage --format=tiff --progress --source='$method' --device='$device' --batch=%d.tif --batch-increment='$sides_per_page' --batch-start='$i'" \ + "warn 'Retrying scan, as we assume a network error!'" + + if [ "$sides_per_page" -ne 1 ]; then + msg "Finished turn, please change side!" + readp "Press enter to continue" noop + fi + done +} +process_images_adf() { + tiff_temp_path="$1" + output_directory="$2" + name="$3" + + counter=0 + pdf_counter=0 + image_cache="$(mktmp)" + while read -r scanned_image; do + dbg "$scanned_image (scanned_image) at $counter (counter)" + echo "$scanned_image" >>"$image_cache" + : $((counter += 1)) + if [ "$counter" = "$number_of_pages" ]; then + dbg "$counter == $number_of_pages" + counter=0 + convert_images "$image_cache" "${name}_$pdf_counter" "$output_directory" + : $((pdf_counter += 1)) + printf "" >"$image_cache" + fi + done <"$(tmp_pipe fd . "$tiff_temp_path" "|" sort -V)" +} + +scan_flatbed() { + device="$1" + number_of_pages"$2" + method="Flatbed" + for i in $(seq "$number_of_pages"); do + do_until_success \ + "scanimage --format=tiff --progress --source='$method' --device='$device' --output-file=$i.tiff" \ + "warn 'Retrying scan, as we assume a network error!'" + if [ "$number_of_pages" -ne 1 ]; then + msg "Finished turn, please change side!" + readp "Press enter to continue" noop + fi + done +} +process_images_flatbed() { + tiff_temp_path="$1" + output_directory="$2" + name="$3" + + counter=0 + image_cache="$(mktmp)" + while read -r scanned_image; do + echo "$scanned_image" >>"$image_cache" + : $((counter += 1)) + if [ "$counter" = "$number_of_pages" ]; then + counter=0 + convert_images "$image_cache" "$name" "$output_directory" + printf "" >"$image_cache" + fi + done <"$(tmp_pipe fd . "$tiff_temp_path" "|" sort -V)" +} +convert_images() { + image_cache="$1" + pdf_name="$2" + output_dir="$3" + + set -- + while read -r image; do + dbg "setting image: $image" + set -- "$@" "$image" + done <"$image_cache" + + while [ -e "$output_dir/${pdf_name}.pdf" ]; do + pdf_name="${pdf_name}_$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 25)" + done + dbg "using pdf_name: $pdf_name" + convert "$@" -compress jpeg -quality 100 "$output_dir/${pdf_name}.pdf" +} + +scan() { + number_of_pages="$1" + device="$2" + output_directory="$(readlink -f "$3")" + name="$4" + method="$5" + + [ -z "$number_of_pages" ] && die "Parameter 'number_of_pages' is not set!" + [ -z "$device" ] && die "Parameter 'device' is not set!" + [ -z "$output_directory" ] && die "Parameter 'output_directory' is not set!" + [ -z "$name" ] && die "Parameter 'name' is not set!" + [ -z "$method" ] && die "Parameter 'method' is not set!" + + tiff_temp_path="$(mktmp -d)" + cd "$tiff_temp_path" || die "Bug" + + msg "Started scanning..." + if [ "$method" = "Flatbed" ]; then + scan_flatbed "$device" "$number_of_pages" + else + scan_adf "$device" "$number_of_pages" + fi + + msg "Creating output directory..." + mkdir "$output_directory" + cd "$output_directory" || die "Bug" + + msg "Converting images to pdfs..." + if [ "$method" = "Flatbed" ]; then + process_images_flatbed "$tiff_temp_path" "$output_directory" "$name" + else + process_images_adf "$tiff_temp_path" "$output_directory" "$name" + fi +} + +for input in "$@"; do + case "$input" in + "--help" | "-h") + help + exit 0 + ;; + "--version" | "-v") + version + exit 0 + ;; + esac +done + +number_of_pages="1" +unset device +output_directory="$(pwd)/pdf" +unset name +method="ADF" + +while [ "$#" -ne 0 ]; do + case "$1" in + "--help" | "-h") ;; + "--version" | "-v") ;; + "--out-dir" | "-o") + shift 1 + output_directory="$1" + ;; + "--name" | "-n") + shift 1 + name="$1" + ;; + "--num-pages" | "-p") + shift 1 + number_of_pages="$1" + ;; + "--device" | "-d") + shift 1 + device="$1" + ;; + "--method" | "-m") + shift 1 + method="$1" + ;; + *) + die "Command line arg $1 does not exist. See --help for a list." + ;; + esac + shift 1 +done +scan "$number_of_pages" "$device" "$output_directory" "$name" "$method" diff --git a/pkgs/sources/scripts/source/apps/fupdate.1.md b/pkgs/sources/scripts/source/apps/fupdate.1.md new file mode 100644 index 00000000..710e8fb7 --- /dev/null +++ b/pkgs/sources/scripts/source/apps/fupdate.1.md @@ -0,0 +1,70 @@ +% FUPDATE(1) fupdate 1.0.0 +% Soispha +% May 2023 + +# NAME + +fupdate - updates your flake, while checking for common mistakes + +# SYNOPSIS + +**fupdate** list of \[*flake*|*\<some word>*|*--help*|*-h*\] + +# DESCRIPTION + +Argument can be stacked, this makes it possible to specify multiple targets to be updated in succession. See the Examples section for further details. + +No argument or *flake* +: **fupdate**, when executed without arguments or with *flake*, will update your *flake.lock*, check for duplicate flake inputs, i.e., an input has an input declared, which you have also declared as input, and will run a script called *update.sh*, if you allow it. +The allowance for the script is asked, when you run **fupdate** and the found script is not yet allowed. Furthermore, the allowance is based on the concrete sha256 hash of the script, so any changes will require another allowance. + +**\<some word>** as argument +: If the executable **update-\<some word>** is reachable thought the PATH variable, than this is run. Otherwise, the program will exit. + +# OPTIONS + +**--help**, **-h** +: Displays a help message and exit. + +**--version**, **-v** +: Displays the software version and exit. + +# EXAMPLES + +**fupdate** or **fupdate flake** +: Updates your *flake.lock*. See the Description section for further details. + +**fupdate sys** +: Run the executable **update-sys**, if it exists. See the Description section for further details. + +**fupdate flake sys docs** +: First updates your flake, then, if the command succeeded, runs **update-sys**, afterweich **update-docs** is run. + +# FILES + +*update.sh* +: This is supposed to be a shell script located in your flake base directory, i.e., the directory which contains both a *flake.nix* and a *flake.lock* file. + +*~/.local/share/flake-update/* +: **fupdate** will store the hashes to the allowed *update.sh* files here. + +# BUGS + +Report bugs to <https://codeberg.org/soispha/flake_update/issues>. + +# COPYRIGHT + +Copyright (C) 2023 Soispha + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. diff --git a/pkgs/sources/scripts/source/apps/fupdate.sh b/pkgs/sources/scripts/source/apps/fupdate.sh new file mode 100755 index 00000000..4322610a --- /dev/null +++ b/pkgs/sources/scripts/source/apps/fupdate.sh @@ -0,0 +1,197 @@ +#! /usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +UPDATE_SCRIPT_NAME="update.sh" +CONFIG_DIRECTORY_PATH="$HOME/.local/share/flake-update" + +# Both are used in version() +# shellcheck disable=SC2034 +AUTHORS="Soispha" +# shellcheck disable=SC2034 +YEARS="2023" + +UPDATE_SCRIPT_NOT_WANTED=false + +# Searches upward for a `UPDATE_SCRIPT_NAME` script +# Returns a path to the script if it exists, otherwise nothing is returned +check_for_update_script() { + dirname="$(search_upward_files "$UPDATE_SCRIPT_NAME")" + if [ "$dirname" ]; then + printf "%s/%s" "$dirname" "$UPDATE_SCRIPT_NAME" + fi +} + +# Checks if a given path to the update script is allowed. +# Takes the path as input +# Return 0, if allowed, 1 if not. +check_for_allowed_update_script() { + update_script="$1" + config_path="${CONFIG_DIRECTORY_PATH}${update_script}" + update_script_hash="$(sha256sum "$update_script")" + if [ -f "$config_path" ]; then + if [ "$(cat "$config_path")" = "$update_script_hash" ]; then + dbg "Recorded hash matches" + return 0 + else + dbg "Recorded hash \'$(cat "$config_path")\' does not match real hash \'$update_script_hash\', assuming not allowed" + return 1 + fi + else + dbg "Path \'$config_path\' does not exist, assuming not allowed" + return 1 + fi +} + +# Asks the user if they want to allow a given script. +# Takes the path as input +ask_to_allow_update_script() { + update_script="$1" + config_path="${CONFIG_DIRECTORY_PATH}${update_script}" + update_script_hash="$(sha256sum "$update_script")" + println "\033[2J" # clear the screen + cat "$update_script" + readp "Do you want to allow this script?[N/y]: " allow + # shellcheck disable=SC2154 + dbg "allow is: $allow" + case "$allow" in + [yY]) + dbg "allowed script" + dbg "storing contents in: $config_path" + mkdir --parents "$(dirname "$config_path")" + print "$update_script_hash" >"$config_path" + ;; + *) + UPDATE_SCRIPT_NOT_ALLOWED=true + ;; + esac +} + +# Runs the provided script and continues to update the nix flake +# Takes the path to the script and the directory to the flake as arguments +# If the path to the update script is empty, it will be ignored +update() { + update_script="$1" + flake_base_dir="$2" + shift 2 + dbg "Provided following args to update script: '$*'" + + cd "$flake_base_dir" || die "Provided dir \'$flake_base_dir\' can not be accessed" + dbg "changed directory to: $flake_base_dir" + + nix flake update + + if ! [ "$update_script" = "" ] && ! [ "$UPDATE_SCRIPT_NOT_WANTED" = "true" ]; then + "$update_script" "$@" + fi + + if grep '[^0-9]_[0-9]' flake.lock >/dev/null; then + batgrep '[^0-9]_[0-9]' flake.lock + die "Your flake.nix contains duplicate inputs!" + fi +} + +help() { + cat <<EOF +This is a Nix flake update manager. + +USAGE: + $NAME [--help | --version] [flake [--no-script] | <some other command>] + +OPTIONS: + --help | -h + Display this help and exit. + + --version | -v + Display version and copyright information and exit. + + --no-script + Avoid running the 'update.sh' script +COMMANDS: + flake + update the flake project + + <some other command> + runs a executable called "update-<some other command>", if it exists +EOF +} + +main() { + if ! [ "$UPDATE_SCRIPT_NOT_ALLOWED" = true ]; then + update_script="$(check_for_update_script)" + flake_base_dir="$(search_flake_base_dir)" # Assume, that the update script is in the base dir + dbg "update_script is: $update_script" + dbg "flake_base_dir is: $flake_base_dir" + + if [ "$update_script" = "" ]; then + update "" "$flake_base_dir" "$@" + elif check_for_allowed_update_script "$update_script" && ! [ "$update_script" = "" ]; then + update "$update_script" "$flake_base_dir" "$@" + else + ask_to_allow_update_script "$update_script" + main "$@" + fi + fi +} + +if [ "$#" -eq 0 ]; then + main + exit 0 +fi + +for input in "$@"; do + case "$input" in + "--help" | "-h") + help + exit 0 + ;; + "--version" | "-v") + version + exit 0 + ;; + "--no-script" | "-n") + UPDATE_SCRIPT_NOT_WANTED=true + ;; + "--") + end_of_cli_options=true + + # Stop processing args after that marker. + break + ;; + esac + [ "$end_of_cli_options" = "true" ] && break +done + +case "$1" in +"flake") + shift 1 + + # Filter out fupdate specific flags + while [ "$1" != "--" ]; do + # FIXME: This check allows to add a flag multiple times, but this should probably + # not be allowed <2024-03-29> + case "$1" in + "--no-script" | "-n") + shift 1 + ;; + *) + break + ;; + esac + done + + [ "$1" = "--" ] && shift 1 + main "$@" + ;; +*) + command="$1" + shift 1 + [ "$1" = "--" ] && shift 1 + if which update-"$command" >/dev/null 2>&1; then + update-"$command" "$@" + else + die "command \"update-$command\" is not executable, or does not exist" + fi + ;; +esac diff --git a/pkgs/sources/scripts/source/apps/git-edit-index.sh b/pkgs/sources/scripts/source/apps/git-edit-index.sh new file mode 100755 index 00000000..e73dc53c --- /dev/null +++ b/pkgs/sources/scripts/source/apps/git-edit-index.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH + +# needed for help() and version +# shellcheck disable=2034 +AUTHORS="Soispha" +# shellcheck disable=2034 +YEARS="2024" +# shellcheck disable=2034 +VERSION="1.0.0" + +# NAME is from the wrapper +# shellcheck disable=SC2269 +NAME="$NAME" + +help() { + cat <<EOF +Edit a file from the index. This script does not touch the unstaged variant of the file. + +USAGE: + $NAME [OPTIONS] [--] FILES.. + +OPTIONS: + -- + Stop parsing options and interpret everything as an file. + + --help | -h + Display this help and exit. + + --version | -v + Display version and copyright information and exit. +ARGUMENTS: + FILES := [[ git diff --name-only --cached --diff-filter=AM ]] + The files to edit. + +EOF +} + +GIT_DIR="$(git rev-parse --show-toplevel)" +materialize_file() { + git diff --cached "$1" >"$GIT_DIR/.git/EDIT_INDEX_PATCH" + + git add "$1" + git restore --staged "$1" + cat "$1" >"$GIT_DIR/.git/EDIT_INDEX_FILE" + git restore "$1" + + git apply "$GIT_DIR/.git/EDIT_INDEX_PATCH" + "$EDITOR" "$1" + + git add "$1" + mv "$GIT_DIR/.git/EDIT_INDEX_FILE" "$1" +} + +edit() { + files_to_add="$(mktmp)" + realpath --relative-to=. "$@" >"$files_to_add" + + index_files="$(mktmp)" + git diff --name-only --cached --diff-filter=AM >"$index_files" + + while read -r file; do + if grep -q "$file" "$files_to_add"; then + sed -i "s|$file||" "$files_to_add" + materialize_file "$file" + fi + done <"$index_files" + + files_to_check="$(mktmp)" + clean "$files_to_add" >"$files_to_check" + if [ "$(wc -l <"$files_to_check")" -gt 0 ]; then + warn "Could not edit every file:" + cat "$files_to_add" + fi +} + +for arg in "$@"; do + case "$arg" in + "--help" | "-h") + help + exit 0 + ;; + "--version" | "-v") + version + exit 0 + ;; + "--") + end_of_cli_options=true + ;; + esac + [ "$end_of_cli_options" = "true" ] && break +done + +edit "$@" + +# vim: ft=sh |