commit df4ccada33502da30fad1a215e12b3ab95d0c516 Author: yosh Date: Wed May 3 18:29:22 2023 -0400 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..f82a861 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# misc scripts +just a bunch of random scripts I use, all which vary in documentation and quality. everything is written in posix shell, but nothing is guaranteed to be 100% posix. all of these are made primarily for my sake with no real intentions of developing for others. diff --git a/albumsetup b/albumsetup new file mode 100755 index 0000000..270ffae --- /dev/null +++ b/albumsetup @@ -0,0 +1,133 @@ +#!/bin/sh +set -euf + +EXT="flac" # default +NL=" +" + +err() { echo "$*" >&2 ; } +die() { err "$*" && exit 1 ; } +clean() { + trap 'exit' INT HUP EXIT + rm -f "$PICTURE" +} + +# wrapper to grab a specific tag from flac/opus/mp3 +grabtag() { + case ${1##*.} in + flac) metaflac --show-tag="$2" "$1" | cut -d '=' -f 2- ;; + opus) opusinfo "$1" | awk -v RS='\n\t' -v FS='=' -v OFS='' "/^$2=/"'{$1=""; print $0}' ;; + mp3) + case "$2" in + ARTIST) id3 -q '%_a' "$1" ;; + ALBUM) id3 -q '%_A' "$1" ;; + TRACKNUMBER) id3 -q '%_###T' "$1" ;; + TITLE) id3 -q '%_t' "$1" ;; + ALBUMARTIST) id3 -2 -q "%|%{TPE2}||%{TXXX:ALBUM ARTIST}|?" "$1" ;; + *) printf 'unknown' ;; + esac + ;; + *) die 'unknown tag used for mp3' + esac +} + +# grab track info, make tracknumber 3-padded just in case for long albums +# (no album has > 999 tracks. I think.) +grabinfo() { + DURATION="$(ffprobe -v quiet -of csv=p=0 -show_entries format=duration "$1")" + ARTIST="$(grabtag "$1" ARTIST)" + ALBUM="$(grabtag "$1" ALBUM)" + TITLE="$(grabtag "$1" TITLE)" + TRACKNUMBER="$(printf '%03d' "$(grabtag "$1" TRACKNUMBER)")" +} + +ffconv() { + IFS=" " + ffmpeg ${VERBOSE--loglevel error} -y -loop 1 -framerate 4 -f image2 -i "$1" ${FULLALBUM:+-safe 0 -f concat} -i "$2" \ + -t "${TOTALTIME:-$DURATION}" \ + -pix_fmt yuv420p \ + ${acopy:--c:a libopus -b:a 256k} \ + -r 4 \ + -b:v 500k \ + -c:v libvpx \ + -cpu-used -5 \ + -deadline realtime \ + "$3" + err "Successfully converted $2" +} + +SONG="" FULLALBUM="" AUTOPIC="" +OUTDIR="/tmp/albumsetup/${PWD##*/}" +while getopts :aovd:e:p:s: OPT; do + case "$OPT" in + a) AUTOPIC=1 ;; # autopic + o) FULLALBUM=1 ;; + v) VERBOSE="" ;; # can use ${var-rep} for this + d) cd "$OPTARG" && OUTDIR="${OUTDIR%/*}/${PWD##*/}" ;; + e) EXT="$OPTARG" ;; + p) tmpimg="$OPTARG" ;; + s) SONG="$OPTARG" && OUTDIR="${OUTDIR%/*}" ;; # individual song + *) die "albumsetup: invalid option: -$OPTARG" ;; + esac +done +shift "$((OPTIND - 1))" + +[ ! -f "$tmpimg" ] && die "Image not specified! This is required even with AUTOPIC!" +[ "$AUTOPIC" ] && [ "$SONG" ] && die "AUTOPIC doesn't make sense in SONG mode!" +[ "$AUTOPIC" ] && [ "$FULLALBUM" ] && die "AUTOPIC doesn't make sense in FULLALBUM mode!" + +mkdir -p "$OUTDIR" + +# convert cover image. it has to be wider than 1:1 so youtube doesn't convert it to a short +# if image is wider than 1:1, just resize height. if not, pad with black +PICTURE="$OUTDIR/ALBUMSETUP_IMG.png" +magick convert "$tmpimg" -resize 1280x720 -background black -gravity center -extent 722x720 "$PICTURE" + +trap 'clean' INT HUP EXIT +[ "$EXT" = "opus" ] && acopy="-c:a copy" # copy audio codec if opus since output codec is opus + +# individual song +if [ "$SONG" ]; then + grabinfo "$SONG" + ffconv "$PICTURE" "$SONG" "$OUTDIR/SONG ${ARTIST%%/*} - ${TITLE%%/*}.webm" # substitution mods are to not create directories +# one continuous video with timestamps +elif [ "$FULLALBUM" ]; then + TOTALTIME=0 # keeping track of timestamps + IFS="$NL" + for f in $(fd -d 1 -e "$EXT"); do + grabinfo "$f" + + # make timestamp + printf '%02d:%02d:%02d - %s\n' \ + "$((${TOTALTIME%%.*} / 3600))" "$((${TOTALTIME%%.*} % 3600 / 60))" "$((${TOTALTIME%%.*} % 60))" \ + "$ARTIST - $TITLE" >> "$OUTDIR/metadata.txt" + # add to total time, but this is as a float remember that + TOTALTIME="$(echo "$TOTALTIME + $DURATION" | bc)" + # build ffmpeg concat metadata + sf="$(printf '%s' "$f" | sed "s/'/'\\\\''/g")" # make safe filename for ffmpeg concat; replace all ' with '\'' + echo "file '${PWD}/$sf'" >> "$OUTDIR/ffmpeg_tracklist.txt" + done + [ ! -f "$OUTDIR/ffmpeg_tracklist.txt" ] && die "No files found!" + ffconv "$PICTURE" "$OUTDIR/tracklist.txt" "$OUTDIR/$ARTIST - $ALBUM.webm" + rm "$OUTDIR/ffmpeg_tracklist.txt" +else # individual tracks for a full album + IFS="$NL" + for f in $(fd -d 1 -e "$EXT"); do + grabinfo "$f" + + # metadata print + printf '%s %s - %s - %s\n' "${TRACKNUMBER:-000}" "${ARTIST:-unknown artist}" "${ALBUM:-unknown album}" "${TITLE:-unknown title}" >> "$OUTDIR/metadata.txt" + # try making auto pic + # if $PIC_AUTO doesn't exist (i.e. trackXXX.(jpg|png), use $PICTURE as fallback + [ "$AUTOPIC" ] && PIC_AUTO="$(fd -e jpg -e png "^track$TRACKNUMBER")" + err "Converting $f" + ffconv "${PIC_AUTO:-$PICTURE}" "$f" "$OUTDIR/$TRACKNUMBER ${ARTIST%%/*} - ${TITLE%%/*}.webm" + done + [ ! -f "$OUTDIR/metadata.txt" ] && die "No files found!" + # sort by correct track numbers then remove track numbers later + sort -o "$OUTDIR/metadata.txt.sorted" "$OUTDIR/metadata.txt" + while read -r line; do + echo "$line" | cut -d ' ' -f 2- + done <"$OUTDIR/metadata.txt.sorted" >"$OUTDIR/metadata.txt" + rm "$OUTDIR/metadata.txt.sorted" +fi diff --git a/avalifetch b/avalifetch new file mode 100755 index 0000000..73747e6 --- /dev/null +++ b/avalifetch @@ -0,0 +1,87 @@ +#!/bin/sh +set -euf + +COLORS="178 245 36 163 239 15" +ASCIIART="$XDG_CONFIG_HOME/neofetch/avali" +GAP=2 + +system_info() { + # use the function "iprint" for everything + # use $(col x) to get an arbitrary 0-255 color + # use $(bold) to bold, $(res) to reset formatting + iprint "$(col 10)$(bold)${USER}$(res)$(col 15)@$(bold)$(col 10)$(uname -n)" + iprint "$(col 7)$(bold)--------------" + iprint "$(col 15)$(bold)OS:$(res)$(col 10) Void Linux" + iprint "$(col 15)$(bold)Kernel:$(res)$(col 11) $(uname -r)" + iprint "$(col 15)$(bold)Shell:$(res)$(col 13) ${SHELL##*/}" + iprint "$(col 15)$(bold)WM:$(res)$(col 7) awesome" + iprint "$(col 15)$(bold)Terminal:$(res)$(col 7) urxvt" +# iprint "$(col 15)$(bold)CPU:$(res)$(col 7) $(cat /proc/cpuinfo | grep -i '^model name' | sort -u | sed -r 's/^model name\t: (.+)/\1/')" + iprint "$(col 15)$(bold)Packages:$(res)$(col 7) $(xbps-query -l | rg -c .)" + iprint "$(col 15)$(bold)Uptime:$(res)$(col 7) $(uptime -p | cut -d ' ' -f 2-)" + iprint "$(col 15)$(bold)Song:$(res)$(col 7) $(mpc -f '%artist% - %title%' current)" + iprint "$(col 7)$(bold)--------------" + iprint "" + iprint "$(col 0)███$(col 1)███$(col 2)███$(col 3)███$(col 4)███$(col 5)███$(col 6)███$(col 7)███" + iprint "$(col 8)███$(col 9)███$(col 10)███$(col 11)███$(col 12)███$(col 13)███$(col 14)███$(col 15)███" +} + +# <-+-+-+-+-+- CONFIGURATION ENDS -+-+-+-+-+-> # + +colres='\033[m' + +process_colors() { +# colindex=1 +# while IFS=" " read -r curcol; do +# colesc="$(tput setaf "$curcol")" +# c$colindex="$colesc" +# colindex="$(($colindex + 1))" +# done <<-EOF +# "$COLORS" +# EOF + c1="$(printf '%b\033[38;5;%sm' "$colres" "$1")" + c2="$(printf '%b\033[38;5;%sm' "$colres" "$2")" + c3="$(printf '%b\033[38;5;%sm' "$colres" "$3")" + c4="$(printf '%b\033[38;5;%sm' "$colres" "$4")" + c5="$(printf '%b\033[38;5;%sm' "$colres" "$5")" + c6="$(printf '%b\033[38;5;%sm' "$colres" "$6")" +} + +process_ascii() { + # get maximum line length + maxlen="$(sed -e 's/\${c[1-6]}//g' "$ASCIIART" | wc -L)" + linecount="$(grep -c '^' "$ASCIIART")" + + # actually do color replacement + final_ascii="$(sed \ + -e "s/\${c1}/$c1/g" \ + -e "s/\${c2}/$c2/g" \ + -e "s/\${c3}/$c3/g" \ + -e "s/\${c4}/$c4/g" \ + -e "s/\${c5}/$c5/g" \ + -e "s/\${c6}/$c6/g" \ + "$ASCIIART")" + + info_padding=$((GAP+maxlen)) +} + +col() { printf "\033[38;5;%sm" "$1"; } +bold() { printf '\033[1m'; } +res() { printf '\033[0m'; } +# reset formatting, move to padding, print line +iprint() { printf "%b%s\n" "\033[0m\033[${info_padding}C" "$1"; } + +print_all() { + tput rmam # disable line wrapping + printf '%s\n' "$final_ascii" + printf '\0337 \033[?25l' # save cursor pos & hide it + printf "\033[%sF" "$linecount" # + system_info + tput smam # enable line wrapping + printf '\0338\n\033[?25h' # restore cursor pos & unhide it +} + +set -f -- $COLORS && set +f +process_colors "$@" +process_ascii +print_all diff --git a/discogarchive b/discogarchive new file mode 100755 index 0000000..75d16c1 --- /dev/null +++ b/discogarchive @@ -0,0 +1,53 @@ +#!/bin/sh +set -euf + +BN="${0##*/}" +NL=' +' + +errecho() { + >&2 echo "$*" +} + +fail() { + errecho "error: $BN: $*" + exit 1 +} + +clean() { + rm -f "$FILE" + rm -f "$tmpfile" +} + +FILE="/tmp/$(printf '%s' "$1" | cut -d '/' -f 3).html" +BASEURL="${1%/*}" +trap 'clean' INT HUP QUIT EXIT +curl -s "$1" -o "$FILE" + +tmpfile="$(mktemp -u)" +# albums and tracks +for type in album track; do + while IFS= read -r url; do + curl -s -o "$tmpfile" "$url" + artist="$(pup 'script[type="application/ld+json"]' 'text{}' <"$tmpfile" | jq -r '.byArtist.name')" + name="$(pup 'script[type="application/ld+json"]' 'text{}' <"$tmpfile" | jq -r '.name')" + if [ "$(pup 'span:contains("name your price"), button:contains("Free Download")' <"$tmpfile")" ]; then + eval 'contained_'"$type"'s="$artist - $name
${NL}${contained_'"$type"'s:-}"' + echo "CONTAINED $type: $artist - $name" + else + eval 'uncontained_'"$type"'s="$artist - $name
${NL}${uncontained_'"$type"'s:-}"' + echo "UNCONTAINED $type: $artist - $name" + fi + done <<-EOF + $(rg -e '"(/'"$type"'/.+)"' -or "$BASEURL"'$1' "$FILE") + EOF +done + +if [ "${uncontained_albums:-}" ] || [ "${uncontained_tracks:-}" ]; then + printf '
Uncontained Releases
\n%s\n%s\n
Contained Releases
\n%s\n%s\n' \ + "${uncontained_albums:+$uncontained_albums
}" "${uncontained_tracks:+SINGLES
$uncontained_tracks
}" \ + "${contained_albums:+$contained_albums}" "${contained_tracks:+
SINGLES
$NL$contained_tracks}" +else + printf '
Contained Releases
\n%s\n%s\n' \ + "${contained_albums:+$contained_albums}" "${contained_tracks:+
SINGLES
$NL$contained_tracks}" +fi diff --git a/doasedit b/doasedit new file mode 100755 index 0000000..e88bc39 --- /dev/null +++ b/doasedit @@ -0,0 +1,37 @@ +#!/bin/sh +set -f + +ercho() { echo "$*" >&2 ; } +error() { ercho "$*" && exit 1 ; } +TMPDIR="${TMPDIR:-/tmp}" +ed="${VISUAL:-vi}" + +clean() { + [ -f "$tmpfile" ] && rm -f "$tmpfile" +} + +[ "$(whoami)" = "root" ] && error "Cannot be run as root!" +[ -z "$1" ] && error "No files provided!" + +trap 'clean' 1 INT HUP KILL EXIT + +for f; do + [ ! -f "$f" ] && ercho "File $f is not a regular file, is not accessible by the user, or does not exist. Skipping..." && continue + tmpfile="$(mktemp -t doasedit_XXXXXXXX)" || error "Cannot make temp file for $f! Exiting..." + + cp -fp "$f" "$tmpfile" || error "Cannot copy file $f! Exiting..." + ercho "$ed '$f'" + + $ed "$tmpfile" || error "Exit code != 0 by editor. Exiting..." + + cmp "$f" "$tmpfile" >/dev/null 2>&1 + ec=$? + if [ $ec -eq 1 ]; then + if [ ! -w "$f" ]; then doas mv -f "$tmpfile" "$f"; else mv -f "$tmpfile" "$f" && echo "$f didn't need root perms!"; fi + elif [ $ec -eq 0 ]; then + ercho "File not changed, skipping..." + else + ercho "Problem running diff on $f! Skipping..." + fi + rm -f "$tmpfile" +done diff --git a/ffrec b/ffrec new file mode 100755 index 0000000..127f1d3 --- /dev/null +++ b/ffrec @@ -0,0 +1,43 @@ +#!/bin/sh +set -eu + +OUTFILE="$HOME/Pictures/Screenshots/$(date +"%Y-%m-%d_%H-%M-%S").mp4" + +LOCKFILE="/tmp/ffrec.pid" +[ -s "$LOCKFILE" ] && xargs kill < "$LOCKFILE" && notify-send "Recording saved to $OUTFILE" && rm -f "$LOCKFILE" && exit 0 + +errecho() { + >&2 echo "$@" +} + +usage() { + errecho "usage: ${0##*/} [-h] [-a SOURCE] [-r FPS]" + errecho + errecho " -h: show this message and exit" + errecho " -a: record audio from SOURCE (only with PA / pipewire-pulse) (set to \"\" for alsa output)" + errecho " -r: set recording framerate to FPS (default: 60)" +} + +while getopts :ha:r: OPT; do + case "$OPT" in + h) usage; exit 0;; + a) AUDIO="-f pulse -i ${OPTARG:-alsa_output.pci-0000_30_00.6.analog-stereo.monitor}" ;; + r) FPS="$OPTARG" ;; + *) errecho "ffrec: invalid option: -$OPTARG"; exit 1 ;; + esac +done + +IFS=" " read -r SIZE OFFSET <<-EOF + $(hacksaw -f "%wx%h %x,%y") +EOF +[ -z "$SIZE" ] && exit 1 # if slop was cancelled don't record + +( + flock -n 9 + set -f + ffmpeg -thread_queue_size 512 -f x11grab -show_region 1 -framerate "${FPS:-60}" -s "$SIZE" -i "$DISPLAY.0+$OFFSET" ${AUDIO:-} -c:v libx264 -crf 21 -preset:v fast "$OUTFILE" & + set +f + echo "$!" > "$LOCKFILE" + notify-send "Recording Started!" + wait +) 9>"$LOCKFILE" diff --git a/moovcheck b/moovcheck new file mode 100755 index 0000000..8d9b840 --- /dev/null +++ b/moovcheck @@ -0,0 +1,2 @@ +#!/bin/sh +ffprobe -v trace -i "$1" 2>&1 | rg -e type:\'mdat\' -e type:\'moov\' diff --git a/n b/n new file mode 100755 index 0000000..5518f1f --- /dev/null +++ b/n @@ -0,0 +1,23 @@ +#!/bin/sh +# nnn previewer wrapper +set -euf + +if [ "${NNNLVL:-0}" -ge 1 ]; then + echo "don't nest nnn!" && exit +fi + +[ "${TMUX:-}" ] && exec nnn + +vars="NNN_BATTHEME=Dracula +NNN_BATSTYLE=full +NNN_TERMINAL=urxvt +" +IFS=' +' +varstring="" +for env in $vars; do + export "${env?}" + varstring="$varstring -e $env" +done; unset IFS + +tmux new $varstring -s nnn -c exec nnn "${PWD:-"$HOME"}" || tmux new-window -t nnn: nnn "${PWD:-"$HOME"}" \; a -t nnn diff --git a/nsxiv-rifle b/nsxiv-rifle new file mode 100755 index 0000000..a6c4e6a --- /dev/null +++ b/nsxiv-rifle @@ -0,0 +1,41 @@ +#!/bin/sh + +TMPDIR="${XDG_RUNTIME_DIR}" +tmp="$TMPDIR/nsxiv_rifle_$$" + +is_img_extension() { + rg -i '\.(jpe?g|png|gif|svg|webp|tiff|heif|avif|ico|bmp|jxl)$' +} + +listfiles() { + fd . -L -d 1 -t f "$1" | + is_img_extension | sort | tee "$tmp" +} + +open_img() { + file="$1"; shift; + # only go through listfiles() if the file has a valid img extension + if echo "$file" | is_img_extension >/dev/null 2>&1; then + trap 'rm -f "$tmp"' EXIT + count="$(listfiles "${file%/*}" | rg -nF "$file")" + fi + if [ -n "$count" ]; then + nsxiv -i -n "${count%%:*}" "$@" -- < "$tmp" + else + # fallback incase file didn't have a valid extension, or we couldn't + # find it inside the list + nsxiv "$@" -- "$file" + fi +} + +[ "$1" = '--' ] && shift +case "$1" in + "") echo "Usage: ${0##*/} PICTURES" >&2; exit 1 ;; + /*) open_img "$1" ;; + "~"/*) open_img "$HOME/${1#"~"/}" ;; + trash:///*) + trash_dir="${XDG_DATA_HOME:-$HOME/.local/share}/Trash/files" + open_img "${trash_dir}$(uri2path "$1")" -N "nsxiv_trash" + ;; + *) open_img "$PWD/$1" ;; +esac diff --git a/pw b/pw new file mode 100755 index 0000000..6116fa3 --- /dev/null +++ b/pw @@ -0,0 +1,27 @@ +#!/bin/sh +set -euf + +PASSAGE_DIR="${PASSAGE_DIR:-$HOME/.passage/store}" +PASSAGE_IDENTITIES_FILE="${PASSAGE_IDENTITIES_FILE:-$HOME/.passage/identities}" +PASSAGE_ROOT="${PASSAGE_DIR%/*}" +STORE_LOCK="$PASSAGE_ROOT/store.tar.age" + +lock() { + [ -d "$PASSAGE_DIR" ] && agetar -e -R "$PASSAGE_DIR/.age-recipients" -o "$STORE_LOCK" "$PASSAGE_DIR" && rm -rf "$PASSAGE_DIR" +} + +unlock() { + [ -f "$STORE_LOCK" ] && agetar -d -i "$PASSAGE_ROOT/identities" -o "$PASSAGE_ROOT" "$STORE_LOCK" && rm -rf "$STORE_LOCK" +} + +while getopts :lu OPT; do + case "$OPT" in + l) lock ;; + u) unlock ;; + *) exit 1 ;; + esac +done + +[ -d "$PASSAGE_DIR" ] && STATE=UNLOCKED + +echo "Password store is ${STATE:-LOCKED}" diff --git a/screenshot b/screenshot new file mode 100755 index 0000000..57f9051 --- /dev/null +++ b/screenshot @@ -0,0 +1,72 @@ +#!/bin/sh +set -ef + +OUTFILE="$HOME/Pictures/Screenshots/$(date +"%Y-%m-%d_%H-%M-%S").jxl" # output file template, change as needed +DMENUOPTS="-c -z 128 -bw 2" # custom dmenu options + +clean() { + [ "$nsxiv_pid" ] && kill "$nsxiv_pid" + [ "$tmpfreeze" ] && rm -f "$tmpfreeze" + rm -f "$tmpfp" +} + +save() { + cjxl "$tmpfp" -d 0.0 "$OUTFILE" && notify-send -u low "$OUTFILE" + exit 0 +} + +savemenu() { printf 'save?' | dmenu $DMENUOPTS -l 1 && save; } + +choose() { + while true; do + case "$(printf "save\nedit\nscan\nupload" | dmenu $DMENUOPTS -l 4)" in + save) save ;; + edit) + h1="$(md5sum "$tmpfp")" + gimp -n "$tmpfp" + h2="$(md5sum "$tmpfp")" + [ "$h1" != "$h2" ] && save # changed, save + ;; + scan) + zdata="$(zbarimg -1 "$tmpfp")" || zdata="error: scan failed with exit code $?" + export zdata + urxvt -g 75x25 -e sh -c 'printf "%s\n" "${zdata#*:}" | vim -' & + printf '%s\n' "${zdata#*:}" + ;; + upload) + owo -u "$tmpfp" | xclip -sel clipboard && notify-send "uploaded and copied successfully!" || notify-send "upload error! you should probably save the image" + ;; + *) break ;; + esac + done +} + +ss() { + [ "$ssopts" = "-g" ] && ssopts="$(hacksaw -f "-i %i -g %g")" + shotgun $ssopts "$tmpfp" + [ "$nsxiv_pid" ] && kill "$nsxiv_pid" && nsxiv_pid="" # unfreeze + xclip -selection clipboard -t image/png < "$tmpfp" # copy screenshot + choose +} + +freeze() { + tmpfreeze="$(mktemp -t screenshot_freeze_XXXX.png)" + shotgun "$tmpfreeze" + nsxiv -b -N SCREENSHOT_FREEZE "$tmpfreeze" & + nsxiv_pid=$! + # window manager makes it fullscreen (yippee!) +} + +tmpfp="$(mktemp -t screenshot_XXXX.png)" +trap 'clean' INT HUP EXIT + +while getopts :srwf OPT; do + case "$OPT" in + s) ssopts="-s" ;; # screen + r) ssopts="-g" ;; # region + w) ssopts="-i $(xdotool getactivewindow)" ;; # active window + f) freeze ;; # freeze screen, only useful with -r + *) echo "invalid option: -$OPTARG" && exit 1 ;; + esac +done +ss diff --git a/stranslate b/stranslate new file mode 100755 index 0000000..54daa7a --- /dev/null +++ b/stranslate @@ -0,0 +1,53 @@ +#!/bin/sh + +# DEFAULT OPTIONS +INSTANCE="https://translate.tiekoetter.com/" +ENGINE="google" +FLANG="auto" +TLANG="en" + +BN="${0##*/}" + +errecho() { + >&2 echo "$@" +} + +fail() { + errecho "error: $BN: $*" + exit 1 +} + +usage() { + errecho \ +"usage: $BN [-h] [-i INSTANCE] [-e ENGINE] [-f LANG] [-t LANG] TEXT +translate text using simplytranslate + + -h show this help + -i choose simplytranslate instance + default: \"$INSTANCE\" + -e use ENGINE to translate + default: \"$ENGINE\" + -f translate from LANG + default: \"$FLANG\" + -t translate to LANG + default: \"$TLANG\"" + exit 0 +} + +# Read options +while getopts :hi:f:t: OPT; do + case "$OPT" in + h) usage ;; + i) INSTANCE="$OPTARG" ;; + e) ENGINE="$OPTARG" ;; + f) FLANG="$OPTARG" ;; + t) TLANG="$OPTARG" ;; + *) fail "unknown option: -$OPTARG. run $BN -h to see all options" ;; + esac +done +shift $((OPTIND - 1)) + +[ "$*" ] || set -- "$(cat /dev/stdin)" +[ "$*" ] || usage + +curl -s "${INSTANCE}/api/translate?engine=${ENGINE}&from=${FLANG}&to=${TLANG}&text=$(jq -rn --arg x "$*" '$x|@uri')" | jq -r '."translated-text"' diff --git a/unityextract b/unityextract new file mode 100755 index 0000000..9996c66 --- /dev/null +++ b/unityextract @@ -0,0 +1,5 @@ +#!/bin/sh +set -euf + +tar xf "$1" +fd '^asset$' -x sh -c 'SRC="$1"; DESTFILE="$(cat "${SRC%/*}/pathname")"; mkdir -p "UNITYEXTRACT/${DESTFILE%/*}"; mv "$SRC" "UNITYEXTRACT/$DESTFILE"' sh diff --git a/xbps-clean b/xbps-clean new file mode 100755 index 0000000..38b4ef8 --- /dev/null +++ b/xbps-clean @@ -0,0 +1,16 @@ +#!/bin/sh + +while getopts :d OPT; do + case "$OPT" in + d) DEL=1 ;; + *) echo "invalid option: -$OPTARG" && exit 1 ;; + esac +done + +for x in /var/cache/xbps/*.xbps; do + xbps-query "$(xbps-uhelper binpkgver "$x")" 1>/dev/null 2>&1 + if [ $? -eq 2 ]; then + echo "${x%.*}" + [ "$DEL" ] && rm "${x%.*}".* + fi +done