commit 60052659b98832c78c902e4f27ecee2663d8e913 parent 10e16c2fb2266bb2b46ec7ea64d721de0c29a0d9 Author: Sebastiano Tronto <sebastiano@tronto.net> Date: Wed, 6 May 2026 08:30:49 +0200 Added scripts Diffstat:
| A | scripts/2fa | | | 21 | +++++++++++++++++++++ |
| A | scripts/aoc | | | 52 | ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/battery-checknow | | | 22 | ++++++++++++++++++++++ |
| A | scripts/battery-status | | | 17 | +++++++++++++++++ |
| A | scripts/clip | | | 63 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/cth | | | 8 | ++++++++ |
| A | scripts/cubeviz | | | 62 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/dmenu-bookmarks | | | 14 | ++++++++++++++ |
| A | scripts/dmenu-dwm-sessionmanager | | | 44 | ++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/dmenu-filepicker | | | 47 | +++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/dmenu-screenshot | | | 40 | ++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/dmenu-unmount | | | 49 | +++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/dmenu-urlselect | | | 28 | ++++++++++++++++++++++++++++ |
| A | scripts/event | | | 154 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/feed | | | 97 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/ffmpeg-facecam | | | 6 | ++++++ |
| A | scripts/ffmpeg-screenrecord | | | 8 | ++++++++ |
| A | scripts/mail-compose | | | 6 | ++++++ |
| A | scripts/mergepdf | | | 26 | ++++++++++++++++++++++++++ |
| A | scripts/notify | | | 37 | +++++++++++++++++++++++++++++++++++++ |
| A | scripts/old/brightness | | | 16 | ++++++++++++++++ |
| A | scripts/old/dmenu-filepicker-old | | | 31 | +++++++++++++++++++++++++++++++ |
| A | scripts/old/dunst-toggle | | | 14 | ++++++++++++++ |
| A | scripts/old/gfmt | | | 9 | +++++++++ |
| A | scripts/old/mail-checknow | | | 18 | ++++++++++++++++++ |
| A | scripts/old/mblaze-extras | | | 61 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/old/notify-battery | | | 10 | ++++++++++ |
| A | scripts/old/notify-status | | | 7 | +++++++ |
| A | scripts/old/notify-time | | | 15 | +++++++++++++++ |
| A | scripts/old/sfeed-browser | | | 80 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/old/theme | | | 23 | +++++++++++++++++++++++ |
| A | scripts/old/togglemute | | | 18 | ++++++++++++++++++ |
| A | scripts/old/volume | | | 13 | +++++++++++++ |
| A | scripts/old/xkboptions | | | 6 | ++++++ |
| A | scripts/old/xprop-active-window-id | | | 6 | ++++++ |
| A | scripts/open-file | | | 122 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/open-stdin | | | 12 | ++++++++++++ |
| A | scripts/open-url | | | 28 | ++++++++++++++++++++++++++++ |
| A | scripts/popup-cal12 | | | 6 | ++++++ |
| A | scripts/popup-cal3 | | | 6 | ++++++ |
| A | scripts/popup-terminal | | | 5 | +++++ |
| A | scripts/secret | | | 52 | ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/sel | | | 136 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/spawn | | | 5 | +++++ |
| A | scripts/status | | | 13 | +++++++++++++ |
| A | scripts/status-linux | | | 52 | ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/status-openbsd | | | 26 | ++++++++++++++++++++++++++ |
| A | scripts/templess | | | 10 | ++++++++++ |
| A | scripts/terminal | | | 7 | +++++++ |
| A | scripts/trash | | | 44 | ++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/unused/addressgrep | | | 8 | ++++++++ |
| A | scripts/unused/alg | | | 444 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/unused/config-backup | | | 28 | ++++++++++++++++++++++++++++ |
| A | scripts/unused/dmenu-mail-aliases | | | 29 | +++++++++++++++++++++++++++++ |
| A | scripts/unused/dmenu-websearch | | | 8 | ++++++++ |
| A | scripts/unused/practice | | | 170 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/unused/share | | | 13 | +++++++++++++ |
| A | scripts/unused/translate | | | 11 | +++++++++++ |
| A | scripts/unused/websearch | | | 11 | +++++++++++ |
| A | scripts/unused/xplumb | | | 65 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scripts/urlgrep | | | 9 | +++++++++ |
| A | scripts/virename | | | 25 | +++++++++++++++++++++++++ |
| A | scripts/xedit | | | 9 | +++++++++ |
| A | scripts/xedit-filter | | | 9 | +++++++++ |
| A | scripts/xroot-update | | | 8 | ++++++++ |
| A | scripts/xwallpaper-random-notify | | | 17 | +++++++++++++++++ |
66 files changed, 2516 insertions(+), 0 deletions(-)
diff --git a/scripts/2fa b/scripts/2fa @@ -0,0 +1,21 @@ +#!/bin/sh + +# 2-factor authentication based on oathtool + +# Usage: 2fa service [time] + +# Requires: secret, oathtool + +secrets_folder="$HOME/box/secrets" + +if [ -z "$1" ]; then + echo "usage: 2fa service [time]" + exit 1 +fi + +if [ -n "$2" ]; then + t="-N $2" +fi + +secret="$(secret show "$secrets_folder/$1-2fa")" +oathtool -b --totp "$secret" $t diff --git a/scripts/aoc b/scripts/aoc @@ -0,0 +1,52 @@ +#!/bin/sh + +# Set up a working environment for Advent of Code (https://adventofcode.com/). +# Requires tmux, lynx, curl and a valid AOC_SESSION_COOKIE session cookie. + +# usage: aoc [yyyy nn] +# If yyyy (year) and nn (day, with leading zero if single digit) are not +# specified, the current year and day are used. + +editor="vi a.py" +basedir="$HOME/src/aoc" +lynx_cookie_file="$(mktemp)" +clibrowser="lynx -cookie_file=$lynx_cookie_file" + +year="${1:-$(date +'%Y')}" +day="${2:-$(date +'%d')}" +daynozero="$(echo "$day" | sed 's/^0//')" + +cd "$basedir/$year/$day" + +# Download the puzzle input and save it to input.txt +if [ ! -e input.txt ]; then + url="https://adventofcode.com/$year/day/$daynozero/input" + curl "$url" -H "cookie: session=$AOC_SESSION_COOKIE" -o input.txt +fi + +# Download the problem statement page and split out the code blocks +url="https://adventofcode.com/$year/day/$daynozero" +curl "$url" | sed -n '/<pre><code>/,/<\/code><\/pre>/ p' | (\ + i=1 + rm -f "code-$i.txt" + IFS='' + while read -r line; do + if [ "$line" = "</code></pre>" ]; then + i=$((i + 1)) + rm -f "code-$i.txt" + else + echo "$line" | sed 's/<.*>//g' >> "code-$i.txt" + fi + done +) + +# Open a tmux session with lynx in its own windows, and an editor and a +# terminal in split view. +printf 'adventofcode.com\tFALSE\t/\tTRUE\t2079722976\tsession\t%s' \ + "$AOC_SESSION_COOKIE" > "$lynx_cookie_file" +tmux new-session \; \ + send-keys "$editor" C-m \; \ + split-window -h \; \ + select-pane -t 0 \; \ + new-window \; \ + send-keys "$clibrowser $url" C-m \; diff --git a/scripts/battery-checknow b/scripts/battery-checknow @@ -0,0 +1,22 @@ +#!/bin/sh + +# Check battery state, save result to a file. Pop up notification if changed. +# Requires: battery-status, notify-battery + +file="${XDG_DATA_HOME:-$HOME/.local/share}/batterystatus" +notify=${NOTIFY:-"notify push"} +low=20 +crit=15 + +new=$(battery-status) +level=$(echo "$new" | sed 's/%.*//') +status=$(echo "$new" | awk '{print $2}') + +[ "$status" = "Discharging" ] && [ "$level" -le "$low" ] && status="Low" +[ "$status" = "Discharging" ] && [ "$level" -le "$crit" ] && status="Critical" + +if [ "$status" != "$(cat "$file")" ] || [ "$status" = "Critical" ]; then + $notify "Battery: $(battery-status)" +fi + +echo "$status" > "$file" diff --git a/scripts/battery-status b/scripts/battery-status @@ -0,0 +1,17 @@ +#!/bin/sh + +# Send battery information to stdout + +# Get battery status +battery="/sys/class/power_supply/BAT0" +message="" + +if [ -d $battery ]; then + capacity=$(cat $battery/capacity) + status=$(cat $battery/status) + message="$capacity% $status" +else + message="No battery" +fi + +echo "$message" diff --git a/scripts/clip b/scripts/clip @@ -0,0 +1,63 @@ +#!/bin/sh + +# A primitive clipboard manager. Saves the current selection and clipboard +# to a temporary file and shows all saved selections in dmenu for the user +# to select one. Duplicate selections are avoided. + +# Bugs (wontfix): the program fails if it can't create the temporary +# directory with the designated name. + +# Usage: clip [-m menu] + +# Requires: xsel, dmenu (or similar) + +menu="dmenu -i -l 25" + +usage() { + echo "Usage: clip [-m MENU]" +} + +while getopts "m:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done +shift "$((OPTIND - 1))" + +dir="/tmp/clipdir" +mkdir -p "$dir" + +file1="$(mktemp -p "$dir" "$(date +%s)".XXXXXX)" +file2="$(mktemp -p "$dir" "$(date +%s)"b.XXXXX)" +echo "created $file1" +echo "created $file2" +xsel > "$file1" +xsel -b > "$file2" + +# Avoid duplicates +for f in "$dir"/*; do + [ "$f" != "$file1" ] && if diff "$f" "$file1"; then rm "$file1"; fi + [ "$f" != "$file2" ] && if diff "$f" "$file2"; then rm "$file2"; fi +done + +list="$(mktemp)" +ls "$dir" > "$list"; + +lines="$(mktemp)" +for f in "$dir"/*; do + nlines="$(wc -l "$f" | awk '{print $1}')" + fclean="$(echo "$f" | sed "s|$dir\/||")" + printf '%s (%s) | %s\n' \ + "$fclean" "$((1+nlines))" "$(head -n 1 "$f")" >> "$lines" +done + +selected=$(sort -r "$lines" | $menu | awk '{print $1}') +if [ -n "$selected" ]; then + xsel -ib < "$dir/$selected" +fi diff --git a/scripts/cth b/scripts/cth @@ -0,0 +1,8 @@ +#!/bin/sh + +# Print a function or struct defintion from a C file +# see https://sebastiano.tronto.net/blog/2022-06-12-shell-ide-sed + +name=$1 +shift +sed -n "/^$name/,/^}/ p" "$@" diff --git a/scripts/cubeviz b/scripts/cubeviz @@ -0,0 +1,62 @@ +#!/bin/sh + +# Get images for a Rubik's cube state from http://cube.rider.biz/visualcube.php +# Can be used with a local installation of visualcube. + +# Usage: cubeviz [type] [alg] +# See usage() for details +# Requires: curl, ImageMagick + +visualcube="http://cube.rider.biz/visualcube.php" + +usage() { + echo "Usage: cubeviz [type] [alg]" + echo "Types: trigger" + echo "Alg: use the standard notation" +} + +trigger() { + alg="$(echo "$1" | tr "'" "3" | tr -d " ")" + w="wwwwwwwww" + y="yyyyyyyyy" + l="lllllllll" + d="ddddddddd" + t="ttttttttt" + ud="$visualcube?fmt=svg&fc=$y$l$l$y$l$l&size=200&view=plan" + top="$ud&alg=$alg" + bottom="$ud&alg=${alg}x2" + s="$visualcube?fmt=svg&fc=$y$t$t$y$t$t&size=200&r=y30x-30" + side="$s&co=30&alg=$alg" + + d="pics_tmp" + f="trigger_$alg.png" + + # We need some temporary files because visualcube is broken + # on Conrad's website and cannot output formats other than svg. + mkdir "$d" + curl "$top" > $d/top.svg + curl "$bottom" > $d/bottom.svg + curl "$side" > $d/side.svg + + c="convert -density 400" + $c $d/top.svg $d/top.png + $c $d/bottom.svg $d/bottom.png + $c $d/side.svg $d/side.png + + montage -tile 2x2 -mode concatenate \ + $d/top.png $d/side.png $d/bottom.png $f + + rm -r "$d" +} + +[ -z "$2" ] && usage && exit 1 + +case "$1" in + trigger) + trigger "$2" + ;; + *) + usage + exit 1 + ;; +esac diff --git a/scripts/dmenu-bookmarks b/scripts/dmenu-bookmarks @@ -0,0 +1,14 @@ +#!/bin/sh + +# A bookmark browser based on dmenu + +# Usage: dmenu-bookmarks [picker options...] + +# Requires: dmenu-filepicker (or similar), open-url + +dir=$HOME/box/bookmarks +picker="dmenu-filepicker" + +$picker "$@" "$dir" | while read -r line; do + cat "$line" +done | xargs open-url diff --git a/scripts/dmenu-dwm-sessionmanager b/scripts/dmenu-dwm-sessionmanager @@ -0,0 +1,44 @@ +#!/bin/sh + +# Prompts menu to shutdown/reboot/close dwm +# Requires: dmenu (or equivalent), dwm (optional) + +# Usage: dmenu-dwm-sessionmanager [-m menu] + +#sudo=sudo +sudo=doas +wmname="dwm" +shutdown_cmd="$sudo poweroff" +reboot_cmd="$sudo reboot" +closewm_cmd="pkill $wmname" + +menu="dmenu -i" +prompt="Do you want to quit?" + +usage() { + echo "Usage: dmenu-dwm-sessionmanager [-m MENU]" +} + +while getopts "m:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +value=$(printf 'Shutdown\nReboot\nQuit dwm\n' | $menu -p "$prompt") + +if [ "$value" = "Shutdown" ]; then + $shutdown_cmd +elif [ "$value" = "Reboot" ]; then + $reboot_cmd +elif [ "$value" = "Quit $wmname" ]; then + $closewm_cmd +fi + diff --git a/scripts/dmenu-filepicker b/scripts/dmenu-filepicker @@ -0,0 +1,47 @@ +#!/bin/sh + +# A dmenu-based file picker (prints selected file to stdout) +# Requires: dmenu (or similar) + +# Usage: dmenu-filepicker [-m menu] [path] + +menu="dmenu -i -l 15" + +usage() { + echo "Usage: dmenu-filepicker [-m MENU] [PATH]" +} + +while getopts "m:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +fullpath=$(realpath "${@:-"$(pwd)"}") + +while true; do + if [ "$sel" = "." ]; then + echo "$fullpath" | sed 's|/\.||' + break + elif [ -d "$fullpath" ] || [ -z "$fullpath" ]; then + if [ -z "$fullpath" ]; then fp="/"; else fp="$fullpath"; fi + sel=$(ls -a "$fp" | sed 's|.*/||' | $menu) + if [ "$sel" = ".." ]; then + fullpath=$(echo "$fullpath" | sed "s|/[^/]*$||") + else + fullpath=$(echo "$sel" | sed "s|^|$fullpath/|") + fi + else + echo "$fullpath" + break + fi + + [ -z "$sel" ] && break +done diff --git a/scripts/dmenu-screenshot b/scripts/dmenu-screenshot @@ -0,0 +1,40 @@ +#!/bin/sh + +# Screenshot utility +# Requires: dmenu (or similar), imagemagick + +# Usage: dmenu-screenshot [-m menu] + +usage() { + echo "Usage: dmenu-screenshot [-m MENU]" +} + +menu="dmenu -i" +prompt="Select type of screenshot:" + +while getopts "m:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +folder="$HOME/box/pictures/screenshots" +filename="screenshot_$(date +%Y-%m-%d-%H%M%S).png" +filepath="${folder}/${filename}" + +t=$(printf 'Full\nSelection\n' | $menu -p "$prompt") +if [ "$t" = "Full" ]; then + op="-window root" +else + pkill xbanish # otherwise I can't use mouse to select area +fi + +[ -n "$t" ] && sleep 0.1 && import $op "$filepath" +spawn xbanish # This can be removed if you don't use xbanish diff --git a/scripts/dmenu-unmount b/scripts/dmenu-unmount @@ -0,0 +1,49 @@ +#!/bin/sh + +# Prompts selection for mounted devices and unmounts the selected one +# Requires: udevil, dmenu (or similar), notify-send or similar (optional) + +# Usage: dmenu-unmount [-m menu] [-w writer] +# Example: dmenu-unmount -m slmenu -w echo + +menu=dmenu +writeout=${NOTIFY:-"notify push"} + +usage() { + echo "Usage: dmenu-unmount [-m MENU] [-w WRITER]" + echo "Example: dmenu-unmount -m slmenu -w echo" +} + +while getopts "m:w:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + w) + writeout="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +listdev=$(grep "media" /proc/mounts | sed 's/\/media.*\///g' | \ + awk '{print $1" ("$2")"}') + +if [ -z "$listdev" ]; then + $writeout "Nothing to unmount" +else + seldev=$(echo "$listdev" | $menu | awk '{print $1}') + if [ -n "$seldev" ]; then + udevil unmount "$seldev" + failed=$(udevil info "$seldev" | grep mounted | awk '{print $3}') + if [ "$failed" -eq 1 ]; then + $writeout "Unmount FAILED" "Device is still mounted!" + else + $writeout "Device unmounted" + fi + fi +fi diff --git a/scripts/dmenu-urlselect b/scripts/dmenu-urlselect @@ -0,0 +1,28 @@ +#!/bin/sh + +# Finds all URLs in stdin and prompts a dmenu choice, then writes the selected +# url to stdout. +# Requires: dmenu (or similar), urlgrep + +# Usage: dmenu-urlselect [-m menu] + +menu="dmenu -i -l 20" + +usage() { + echo "Usage: dmenu-urlselect [-m MENU]" +} + +while getopts "m:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +urlgrep | $menu diff --git a/scripts/event b/scripts/event @@ -0,0 +1,154 @@ +#!/bin/sh + +# Manage events (replacement for https://git.tronto.net/sdep) + +# Usage: event [command [argument]] +# See usage() for details + +file="$HOME/box/events" # Change to $XDG_DATA_HOME/events or whatever +editor=${EDITOR:-vi} + +usage() { + echo "Usage: event [command]" + echo "Commands:" + echo " add [day] Add a new event (default date: none)" + echo " day: today, t; tomorrow, tm" + echo " clear Sort and cleanup event file" + echo " edit Open event file in $editor" + echo " list [date] List all events on date (default: all events)" + echo " date: now, n; today, t; tomorrow, tm;" + echo " week, w; nextweek, nw;" + echo " future, f; past, p" +} + +secondstoday() { + if [ "$(uname)" = "Linux" ]; then + date -d @$1 +'%Y-%m-%d' + else # Assume BSD date + date -r $1 +'%Y-%m-%d' + fi +} + +secondstomin() { + if [ "$(uname)" = "Linux" ]; then + date -d @$1 +'%Y-%m-%d %H:%M' + else # Assume BSD date + date -r $1 +'%Y-%m-%d %H:%M' + fi +} + +datetoseconds() { + # Read date in YYYY-MM-DD HH:MM format + if [ "$(uname)" = "Linux" ]; then + date -d "$1 $2" +'%s' + else # Assume BSD date + date -f '%Y-%m-%d %H:%M' -j "$1 $2" +'%s' + fi +} + +today() { echo "$(date +'%Y-%m-%d') 00:00"; } +dayplus() { + d="$1" + n="$(datetoseconds $(today))" + echo "$((n+d*60*60*24))" +} +monday() { d="$(date +%u)"; dayplus "$((1-d))"; } +monday1() { d="$(date +%u)"; dayplus "$((8-d))"; } +monday2() { d="$(date +%u)"; dayplus "$((15-d))"; } +daydiff() { + ar="$1" + d="$(date +%u)" + case "$ar" in + mon|monday) + w=1 + ;; + tue|tuesday) + w=2 + ;; + wed|wednesday) + w=3 + ;; + thu|thursday) + w=4 + ;; + fri|friday) + w=5 + ;; + sat|saturday) + w=6 + ;; + sun|sunday) + w=7 + ;; + *) + w=0 + ;; + esac + [ "$w" = "0" ] && echo "" || echo "$(((w-d+7) % 7))" +} + +secondsline() { + # TODO: this function is not needed, need similar one with weekday + line="$(cat)" + s="$(datetoseconds $line)" + t="$(echo "$line" | sed -E 's/....-..-.. .{1,2}:.. //g')" + echo "$s $t" +} + +filterlines() { + while read -r line; do + cleanline="$(echo "$line" | awk '{print $1, $2}')" + s="$(datetoseconds $cleanline)" + [ "$s" -ge "$1" ] && [ "$s" -lt "$2" ] && echo "$line" + done +} + +list() { + if [ -z "$1" ]; then + cat + elif [ "$1" = "now" ] || [ "$1" = "n" ]; then + grep "$(date +'%Y-%m-%d %H:%M')" + elif [ "$1" = "today" ] || [ "$1" = "t" ]; then + grep "$(date +'%Y-%m-%d')" + elif [ "$1" = "tomorrow" ] || [ "$1" = "tm" ]; then + grep "$(secondstoday $(dayplus 1))" + elif [ "$1" = "week" ] || [ "$1" = "w" ]; then + filterlines "$(monday)" "$(monday1)" + elif [ "$1" = "nextweek" ] || [ "$1" = "nw" ]; then + filterlines "$(monday1)" "$(monday2)" + elif [ "$1" = "future" ] || [ "$1" = "f" ]; then + filterlines "$(date +%s)" "9999999999" + elif [ "$1" = "past" ] || [ "$1" = "p" ]; then + filterlines "0" "$(date +%s)" + fi +} + +case "$1" in + add) + if [ "$2" = "today" ] || [ "$2" = "t" ]; then + d="$(date +'%Y-%m-%d')" + elif [ "$2" = "tomorrow" ] || [ "$2" = "tm" ]; then + d="$(secondstoday $(dayplus 1))" + elif [ -n "$2" ]; then + d="$(secondstoday $(dayplus $(daydiff $2)))" + fi + [ -n "$d" ] && printf '%s ' "$d" + read -r line + [ -n "$d" ] && line="$d $line" + echo "$line" >> "$file" + ;; + clear) + tmp=$(mktemp) + cat "$file" | list future | sort > "$tmp" + mv "$tmp" "$file" + ;; + edit) + "$editor" "$file" + ;; + list) + cat "$file" | list $2 | sort + ;; + *) + usage + ;; +esac diff --git a/scripts/feed b/scripts/feed @@ -0,0 +1,97 @@ +#!/bin/sh + +# RSS feed manager + +# Requires: sfeed, sfeed_plain (get), dmenu, open-url (menu) + +# Usage: feed [-m menu] [get|menu|clear|show] + +dir=$HOME/box/sfeed +feeddir=$dir/urls +destdir=$dir/new +readdir=$dir/last +menu="${FEEDMENU:-dmenu -l 20 -i}" +urlopener=open-url + +usage() { + echo "Usage: feed [get|menu|clear|show]" +} + +getnew() { + for f in "$feeddir"/*; do + read -r url < "$f" + name=$(basename "$f") + printf '%s... ' "$name" + + d="$destdir/$name" + r="$readdir/$name" + + [ -f "$r" ] && read -r lr < "$r" || lr=0 + + # Get new feed items + tmp=$(mktemp) + curl -s "$url" | sfeed | \ + awk -v lr="$lr" '$1 > lr {print $0}' | \ + tee "$tmp" | sfeed_plain >> "$d" + + # Update last time stamp + awk -v lr="$lr" '$1 > lr {lr=$1} END {print lr}' <"$tmp" >"$r" + + printf 'downloaded\n' + done +} + +show() { + for f in "$destdir"/*; do + ff=$(basename "$f") + if [ -s "$f" ]; then + sort -r "$f" | while read -r line; do + printf '%20s %s\n' "$ff" "$line" + done + fi + done +} + +selectmenu() { + $menu | awk '{print $NF}' | xargs $urlopener +} + +while getopts "m:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done + +shift $((OPTIND - 1)) + +if [ -z "$1" ]; then + usage + exit 1 +fi + +case "$1" in + get) + getnew + countnew=$(cat "$destdir"/* | wc -l) + echo "$countnew new feed items" + ;; + menu) + show | selectmenu + ;; + clear) + rm -r "$destdir"/* + ;; + show) + show + ;; + *) + usage + exit 1 + ;; +esac diff --git a/scripts/ffmpeg-facecam b/scripts/ffmpeg-facecam @@ -0,0 +1,6 @@ +#!/bin/sh + +# Opens a window streaming from the webcam +# Requires: ffplay (part of ffmpeg) + +ffplay -i /dev/video0 diff --git a/scripts/ffmpeg-screenrecord b/scripts/ffmpeg-screenrecord @@ -0,0 +1,8 @@ +#!/bin/sh + +# One-line screen record with ffmpeg (I always forget the command) +# Requires: ffmpeg + +outfile=${1:-output.mkv} + +ffmpeg -f x11grab -i :0 -f pulse -i default "$outfile" diff --git a/scripts/mail-compose b/scripts/mail-compose @@ -0,0 +1,6 @@ +#!/bin/sh + +# Open a mail composer. +# Requires: mblaze, terminal + +terminal mcom "$@" diff --git a/scripts/mergepdf b/scripts/mergepdf @@ -0,0 +1,26 @@ +#!/bin/sh + +# Merge multiple pdf files into one +# Requires: gs + +# Usage: mergepdf [-o outname] file1.pdf file2.pdf ... + +outname=merged.pdf + +usage() { + echo "Usage: mergepdf [-o OUTFILE] file1.pdf file2.pdf ..." +} + +while getopts "o:" opt; do + case "$opt" in + o) + outname="$OPTARG" + ;; + *) + usage + ;; + esac +done +shift $((OPTIND - 1)) + +gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile="$outname" "$@" diff --git a/scripts/notify b/scripts/notify @@ -0,0 +1,37 @@ +#!/bin/sh + +# Simple notification manager. +# Notifications are sent to a log file together with a time stamp. +# Requires: xroot-update (optional) + +# Usage: notify [push MESSAGE | clean | edit | show] + +update=xroot-update +file="${XDG_DATA_HOME:-.local/share}/notify" +date=$(date +'%H:%M') + +usage() { + echo "Usage: notify [push MESSAGE | clean | edit | show]" +} + +touch "$file" +case "$1" in + push) + echo "[$date $2]" >> "$file" + $update + ;; + clean) + printf "" > "$file" + $update + ;; + edit) + $EDITOR "$file" + ;; + show) + cat "$file" + ;; + *) + usage + exit 1 + ;; +esac diff --git a/scripts/old/brightness b/scripts/old/brightness @@ -0,0 +1,16 @@ +#!/bin/sh + +# Increase / decrease brightness, and pops up a notification +# Requires: xbacklight, a notification program such as herbe or notify-send +# Usage: brightness {inc|dec} n + +# ksh completion +# set -A complete_brightness_1 inc dec +# set -A complete_brightness_2 5 + +#notify="notify-send" +notify="herbe" + +pkill herbe # comment this too if not using herbe + +xbacklight -$1 $2 && $notify "Brightness: $(xbacklight | sed 's/\..*$//')%" diff --git a/scripts/old/dmenu-filepicker-old b/scripts/old/dmenu-filepicker-old @@ -0,0 +1,31 @@ +#!/bin/sh + +# A dmenu-based file picker (prints selected file to stdout) +# Requires: dmenu (or similar) +# Usage: dmenu-filepicker [path] + +menu=${MENU:-dmenu} +menuopts="-i -l 15" + +basedir="$(pwd)" + +next="${@:-$(pwd)}" + +while true; do + if [ -z "$next" ]; then + break + elif [ "$next" = "." ]; then + pwd + break + elif [ -d "$next" ]; then + cd "$next" + next=$(ls -a | $menu $menuopts) + else + echo "$next" | while read line; do + echo "$(pwd)/$line" + done + break + fi +done + +cd "$basedir" diff --git a/scripts/old/dunst-toggle b/scripts/old/dunst-toggle @@ -0,0 +1,14 @@ +#!/bin/sh + +# Toggle "do not disturbe" mode with dunst +# Requires: dunst, notify-send + +if [ "$(dunstctl is-paused)" = "false" ]; then + notify-send -t 3000 "Notifications: OFF" "Notifications will be hidden" + sleep 3 + dunstctl set-paused true +else + dunstctl set-paused false + notify-send -t 3000 "Notifications: ON" "Notifications reactivated" +fi + diff --git a/scripts/old/gfmt b/scripts/old/gfmt @@ -0,0 +1,9 @@ +#!/bin/sh + +# Format text from gemtext format to short lines with double \n + +# TODO: remove double spacing from within ``` + +sed 's///' | \ +sed 'a\\' | \ +fold -sw 80 diff --git a/scripts/old/mail-checknow b/scripts/old/mail-checknow @@ -0,0 +1,18 @@ +#!/bin/sh + +# Check for new email, save result to file. +# Requires: mpop, notify-send or similar + +file="$XDG_DATA_HOME/newmail" +#notify="notify-send" +notify=herbe + +l=$(cat "$file") +n=$(mpop -s | awk '/new*./{print $2}') + +if [ -n "$n" ]; then + echo "$n" > "$file" + if [ "$n" != "no" ] && [ "$l" != "$n" ]; then + $notify "New email ($n)" + fi +fi diff --git a/scripts/old/mblaze-extras b/scripts/old/mblaze-extras @@ -0,0 +1,61 @@ +#!/bin/sh + +# Useful extra commands for mblaze + +# Requires: mblaze, mpop + +# Usage: mblaze-extras command +# List of commands: +# get [filter] +# pick [field] +# save +# scan [folder] + +menu=${MENU:-dmenu} +mdir=$HOME/mail +mpopdir=$HOME/.config/mpop + +mbextra_scan() { + folder=${1:-inbox} + mlist -t $mdir/$folder | mthread | mseq -S + mscan +} + +mbextra_get() { + mpop --filter=$mpopdir/filter-$1.sh + minc -q $mdir/inbox + mbextra_scan inbox +} + +mbextra_pick() { + field=$1 + shift + mpick -t "$field =~~ \"$@\"" +} + +mbextra_save() { + dir=$2 + [ -z "$dir" ] && dir=$(dmenu-filepicker) + mkdir -p "$dir" + + if [ ! -d "$dir" ]; then + echo "No directory selected, skipping." + else + cd "$dir" + mshow -x $1 + fi +} + +if [ -z "$1" ]; then + echo "Usage: mblaze-extras COMMAND" +elif [ "$1" = "scan" ]; then + mbextra_scan $2 +elif [ "$1" = "get" ]; then + mbextra_get $2 +elif [ "$1" = "save" ]; then + shift + mbextra_save $@ +elif [ "$1" = "pick" ]; then + shift + mbextra_pick $@ +fi diff --git a/scripts/old/notify-battery b/scripts/old/notify-battery @@ -0,0 +1,10 @@ +#!/bin/sh + +# Popup battery notification, based on the script battery-status + +# Requires: notify-send or similar + +#notify=notify-send +notify=herbe + +$notify "Battery" "$(battery-status)" diff --git a/scripts/old/notify-status b/scripts/old/notify-status @@ -0,0 +1,7 @@ +#!/bin/sh + +# Simple script to send a notification displaying the output of status + +# Requires: status, herbe (or similar, e.g. notify-send) + +herbe "$(status '\n\n')" diff --git a/scripts/old/notify-time b/scripts/old/notify-time @@ -0,0 +1,15 @@ +#!/bin/sh + +# Little notification to show time and date + +# Requires: notify-send or similar + +# TODO: check if it still works with notify-send + +#notify=notify-send +notify=herbe + +t=$(date +"%H:%M:%S") +d=$(date +"%d %B %Y, %A") + +$notify "$t" "$d" diff --git a/scripts/old/sfeed-browser b/scripts/old/sfeed-browser @@ -0,0 +1,80 @@ +#!/bin/sh + +# This script is based on sfeed (https://codemadness.org/sfeed.html), but +# it allows you organize your feeds in directories and subdirectories. +# In your $sfd directory (see below) you should have two folders: +# urls: it can contain more subfolders and files. Each file should contain +# only one line with the url to the feed. The name of the file is the +# name of the feed (it can contains spaces and such). +# files: this one can be empty, it will be filled with the feed files +# An older version of this script also marked viewed items and removed +# them before displaying the choice of feeds. Contact me if you are interested +# in using it. + +# Requires: sfeed, dmenu-file-picker (or similar), open-url (or similar) + +# Usage: sfeed-browser [-m menu] + +filepicker="dmenu-filepicker" # Try "nnn -p -" +menu="dmenu -l 35 -i" +urlopener=open-url +sfd="$HOME/box/sfeed" +showlast=10 + +usage() { + echo "sfeed-browser [-m MENU]" +} + +while getopts "m:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done + +# Might add more stuff later +fixurl() { + sed 's/old\.reddit\.com/reddit\.com/' +} + +dirtofeedpaths() { + while read -r line; do + find "$line" | while read -r fname; do + [ -f "$fname" ] && echo "$fname" + done + done +} + +pathstosfeedrc() { + printf 'sfeedpath="%s"\n\nfeeds() {\n' "$sfd/files" + while read -r line; do + feedname=$(echo "$line" | sed 's/.*\///') + read -r feedurl <"$line" + printf '\tfeed "%s" "%s"\n' "$feedname" "$feedurl" + done + printf "}\n" +} + +feedmenu() { + while read -r line; do + feedname=$(echo "$line" | sed 's/.*\///') + sfeed_plain "$sfd/files/$feedname" | head -$showlast + done | $menu +} + +openfeeds() { + while read -r line; do + url=$(echo "$line" | sed 's/.*[\t ]//' | fixurl) + [ -n "$url" ] && echo "$url" + done | xargs $urlopener +} + +$filepicker "$@" "$sfd/urls" | dirtofeedpaths > "$sfd/last" +pathstosfeedrc < "$sfd/last" > "$sfd/sfeedrc" +sfeed_update "$sfd/sfeedrc" +feedmenu < "$sfd/last" | openfeeds diff --git a/scripts/old/theme b/scripts/old/theme @@ -0,0 +1,23 @@ +#!/bin/sh + +# This script is a shortcut to change between a dark and a light theme +# for my terminal emulator (st). + +# Usage: theme (dark|light) + +src=$HOME/.local/src + +case "$@" in + dark) + cd $src/st-darkbg + ;; + light) + cd $src/st-lightbg + ;; + *) + echo "usage: theme (dark|light)" + exit 1 + ;; +esac + +make && sudo make install diff --git a/scripts/old/togglemute b/scripts/old/togglemute @@ -0,0 +1,18 @@ +#!/bin/sh + +# Toggle mute state and notify +# Requires: pulsemixer, notify-send or similar + +#notify=notify-send +notify=herbe + +ismute=$(pulsemixer --toggle-mute --get-mute) + +if [ "$ismute" = "1" ]; then + m="muted" +else + m="unmuted" +fi + +pkill herbe # comment this line too if not using herbe +$notify "Audio $m" diff --git a/scripts/old/volume b/scripts/old/volume @@ -0,0 +1,13 @@ +#!/bin/sh + +# Change volume and notify +# Usage: volume {+n|-n} +# Requires: pulsemixer, notify-send or similar + +#notify=notify-send +notify=herbe + +newvol=$(pulsemixer --change-volume "$1" --get-volume | awk '{print $1}') + +pkill herbe # comment this line too if not using herbe +$notify "Volume" "$newvol%" diff --git a/scripts/old/xkboptions b/scripts/old/xkboptions @@ -0,0 +1,6 @@ +#!/bin/sh + +# Loads my xkboptions + +setxkbmap -option compose:ralt +setxkbmap -option caps:swapescape diff --git a/scripts/old/xprop-active-window-id b/scripts/old/xprop-active-window-id @@ -0,0 +1,6 @@ +#!/bin/sh + +# Get the ID of the current active window (hexadecimal) +# Requires: xprop + +xprop -root | grep _NET_ACTIVE_WINDOW | head -1 | sed 's/.* //' diff --git a/scripts/open-file b/scripts/open-file @@ -0,0 +1,122 @@ +#!/bin/sh + +# Inspired by https://github.com/salman-abedin/launch.sh +# Launches files based on their mimetypes +# Requires: dmenu_path or similar (fallback), dmenu-filepicker + +# Usage: open-file [-m menu] [-s launcher] [-t mimetype] [files...] + +menu="dmenu -i -l 15" + +# Change default apps here +video=${VIDEO:-vlc} +music=${MUSIC:-vlc} +pdf=${PDF:-zathura} +img="${IMGVIEW:-nsxiv}" +word="${WORDS:-libreoffice}" +sheet="${SHEETS:-libreoffice}" +html="${BROWSER:-firefox} --new-window" +xedit="${XEDIT:-xedit}" + +usage() { + echo "Usage: open-file [-m MENU] [-s LAUNCHER] [-t MIMETYPE] [files...]" +} + +openfile() { + f="$*" + localmime="$mimetype" + + [ ! -f "$f" ] && echo "$f: bad argument" && exit 1 + [ -z "$mimetype" ] && localmime="$(file --mime-type "$f" -bL)" + + prog="" + case "$localmime" in + video/*) + prog="$video" + ;; + audio/*) + prog="$music" + ;; + application/pdf | application/postscript | image/vnd.djvu) + prog="$pdf" + ;; + image/*) + prog="$img" + ;; + application/msword | \ + application/vnd.oasis.opendocument.text | text/rtf | \ + application/vnd.openxmlformats-officedocument.wordprocessingml.*) + prog="$word" + ;; + application/ms-excel | \ + application/vnd.oasis.opendocument.spreadsheet | \ + application/vnd.openxmlformats-officedocument.spreadsheetml.*) + prog="$sheet" + ;; + text/html | text/enriched) + prog="$html" + ;; + text/*) + prog="$xedit" + ;; + application/zip) + prog="unzip" + ;; + application/x-rar-compressed) + prog="unrar" + ;; + application/x-archive | application/x-tar | \ + application/x-bzip2 | application/gzip | application/x-lzip | \ + application/x-lzma | application/x-xz | application/x-gtar) + prog="tar -tavf" + ;; + application/java-archive) + prog="java -jar" + ;; + *) + if [ "$menu" = dmenu ]; then + menuprompt="-p \"How to open $f? \"" + else + menuprompt="--prompt=\"How to open $f? \"" + fi + prog=$(dmenu_path | $menu "$menuprompt") + ;; + esac + + if [ -n "$prog" ]; then + $launcher $prog "$f" + else + exit 1 + fi +} + +while getopts "m:s:t:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + s) + launcher="$OPTARG" + ;; + t) + mimetype="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done + +shift $((OPTIND - 1)) + +if [ -n "$1" ]; then + while [ -n "$1" ]; do + openfile "$1" & + shift + done +else + dmenu-filepicker -m "$menu" | while read -r line; do + openfile "$line" & + done +fi diff --git a/scripts/open-stdin b/scripts/open-stdin @@ -0,0 +1,12 @@ +#!/bin/sh + +# Saves standard input in a temporary file and opens it (spawn) +# Usage: open-stdin +# Requires: open-file (or set $OPENER to e.g. xdg-open) + +folder=${TMPDIR:-/tmp} +open=${OPENER:-open-file} + +tempfile=$(mktemp -p "$folder") + +cat > "$tempfile" && $open $@ "$tempfile" diff --git a/scripts/open-url b/scripts/open-url @@ -0,0 +1,28 @@ +#!/bin/sh + +# Open link in preferred application +# Requires: mail-compose, spawn, xsel (optional) + +browser=${BROWSER:-firefox} +imageviewer=${IMAGEVIEWER:-nsxiv} + +[ -z "$1" ] && exit 0 + +# Optional: copy url to clipboard +echo "$@" | xsel -ib + +case "$@" in + mailto:*) + mail-compose "$@" + ;; + *.jpg | *.jpeg | *.png) + spawn "$imageviewer" "$@" + ;; + *.gif) + spawn "$imageviewer" "$@" + ;; + *) + spawn "$browser" "$@" + ;; +esac + diff --git a/scripts/popup-cal12 b/scripts/popup-cal12 @@ -0,0 +1,6 @@ +#!/bin/sh + +# Popup terminal displaying cal -3 +# Requires: st (suckless terminal) + +st -T "stfloat" -g 69x36+620+250 -e sh -c "cal $(date +%Y); read x" diff --git a/scripts/popup-cal3 b/scripts/popup-cal3 @@ -0,0 +1,6 @@ +#!/bin/sh + +# Popup terminal displaying cal -3 +# Requires: st (suckless terminal) + +st -T "stfloat" -g 68x11+620+450 -e sh -c 'cal -3; read x' diff --git a/scripts/popup-terminal b/scripts/popup-terminal @@ -0,0 +1,5 @@ +#!/bin/sh + +# TODO maybe I want to run e.g. tmux in this? + +st -T "stfloat" -g 85x25+550+300 tmux new-session "$@" diff --git a/scripts/secret b/scripts/secret @@ -0,0 +1,52 @@ +#!/bin/sh + +# Encrypt and decrypt files using a fixed cipher and passphrase. +# The first line of the (unencrypted) file is considered the "password", +# the rest can be anything. + +# Usage: secret command file +# Available commands: +# clip: copy the secret to clipboard; deleted after 10 seconds +# edit: edit or add a file +# show: show the full encrypted file + +# Requires: openssl, xsel (for clip only) + +# ksh completion +# set -A complete_sel_1 clip edit show +# set -A complete_sel_2 box/secret + +opts="aes-256-cbc -iter 1000" # options for openssl +timeout=10 # timeout for clip, in ms +editor=${EDITOR:-vi} + +if [ -z "$1" ] || [ -z "$2" ]; then + echo "usage: secret command file" +else +case "$1" in + clip) + openssl $opts -d < "$2" | head -n 1 | xargs printf "%s" | xsel -ib + sleep $timeout && xsel -db & + ;; + edit) + tempfile=$(mktemp) + if [ -f "$2" ]; then + openssl $opts -d < "$2" > "$tempfile" + fi + $editor "$tempfile" + read -p "Are you sure? [N/yes] " an + if [ "$an" = yes ] || [ "$an" = Yes ] || [ "$an" = YES ]; then + openssl $opts < "$tempfile" > "$2" + else + echo "Changes discarded" + fi + rm "$tempfile" + ;; + show) + openssl $opts -d < "$2" + ;; + *) + echo "$1: not a valid command" + ;; +esac +fi diff --git a/scripts/sel b/scripts/sel @@ -0,0 +1,136 @@ +#!/bin/sh + +# Allow bulk operations on a list of selected files. + +# Requires: dmenu (or similar), trash (optional), open-file (for open only) + +# Usage: sel [-m menu] [command] +# If no command is specified, shows the list of selected files +# Commands: +# add [files...]: add files to selection +# addall: add all files in the current folder to selection +# clear: clear selection +# cp: copy to current dir, possbily after editing filenames +# edit: open selection in editor +# mv: move to current dir, possbily after editing filenames +# open: open files using open-file +# rm: remove selected files and clear selection + +# TODO: The usage of paste(1) is a bit of a hack, and for example it does +# not work if filenames contain tab characters. Fix this. + +# Bug (probably not fixing this, use virename): moving a file to +# itself gives an error and rm is not run. + +file="$XDG_DATA_HOME/selectedfiles" +menu="" # default uses dmenu-filepicker default +editor=${EDITOR:-vi} +rm="trash rm" # replace with rm -r if you don't use trash + +usage() { + echo "Usage: sel [-m MENU] [COMMAND]" + echo "If no COMMAND is specified, shows the list of selected files" + echo "Possible commands:" + echo " add [files...]: add files to selection" + echo " addall: add all files in the current folder to selection" + echo " clear: clear selection" + echo " cp: copy to current dir, possbily after editing filenames" + echo " edit: open selection in editor" + echo " mv: move to current dir, possbily after editing filenames" + echo " open: open files using open-file" + echo " rm: remove selected files and clear selection" +} + +while getopts "m:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +add() { + shift 1 + if [ -z "$1" ]; then + if [ -n "$menu" ]; then + dmenu-filepicker -m "$menu" >> "$file" + else + dmenu-filepicker >> "$file" + fi + else + for i in "$@"; do realpath "$i" >> "$file"; done + fi + sort -u -o "$file" "$file" +} + +clear() { + cat /dev/null > "$file" +} + +cphere() { + file2=$(mktemp) + sed 's/^.*\///' "$file" > "$file2" + $editor "$file2" + if [ "$(wc -l "$file" | awk '{print $1}')" != \ + "$(wc -l "$file2" | awk '{print $1}')" ]; then + echo "Error reading new file names" + return 1 + else + paste "$file" "$file2" | while read -r f; do + fold=$(echo "$f" | sed 's/ .*//') + fnew=$(echo "$f" | sed 's/.* //') + cp -R "$fold" ./"$fnew" || return 1 + done + fi +} + +open() { + while read -r f; do + open-file "$f" + done < "$file" +} + +remove() { + while read -r f; do + $rm "$f" + done < "$file" +} + +if [ -z "$1" ]; then + cat "$file" +else +case "$1" in + add) + add "$@" + ;; + addall) + add ./* + ;; + clear) + clear + ;; + cp) + cphere && clear + ;; + edit) + $editor "$file" + ;; + mv) + cphere && (remove; clear) + ;; + open) + open + ;; + rm) + remove && clear + ;; + *) + echo "$1: not a valid sel command" + ;; +esac +fi diff --git a/scripts/spawn b/scripts/spawn @@ -0,0 +1,5 @@ +#!/bin/sh + +# Simple command to spawn and detach an application + +"$@" >/dev/null 2>&1 & diff --git a/scripts/status b/scripts/status @@ -0,0 +1,13 @@ +#!/bin/sh + +# Calls one of the system-specific status scripts to display +# a line of text with some status information (battery, date...) + +case "$(uname)" in +OpenBSD) + status-openbsd + ;; +*) + status-linux + ;; +esac diff --git a/scripts/status-linux b/scripts/status-linux @@ -0,0 +1,52 @@ +#!/bin/sh + +# Prints some status info to stdout. Includes: +# - date and time +# - battery +# - wifi (requires nmcli) +# - past notifications (requires notify) + +# Usage: status [separator] + +sep=${1:-" | "} + +time=$(date +"%H:%M") +date=$(date +"%a %d %b") + +if [ "$(pulsemixer --get-mute)" -eq 1 ]; then + volume="Muted" +else + volume="Vol $(pulsemixer --get-volume | awk '{print $1}')%" +fi + +bat="/sys/class/power_supply/BAT0" +if [ -d $bat ]; then + charge_status="$(cat $bat/status | awk '{print substr ($0, 0, 2)}')" + battery="Bat $(cat $bat/capacity)% $charge_status" +else + battery="No battery" +fi + +# NetworkManager has a dreadful command line interface +# It makes cry every time +# pls help +#nwline="$(nmcli device status | head -n 2 | tail -n 1)" +#nwclean="$(echo "$nwline" | sed 's/ *$//' | sed 's/.* //')" +#network="Network: $nwclean" + +# Thank you iwctl for saving us from this dreadful existence +network="$(iwctl station wlan0 show | grep 'Connected network' | awk '{print $3}')" +if [ "$(cat /sys/class/net/eth0/carrier)" = 1 ]; then + if [ -z "$network" ]; then + network="eth" + else + network="eth & $network" + fi +fi + +noticount=$(notify show | wc -l) + +printf '%s' "$network$sep$volume$sep$battery$sep$date$sep$time" +[ "$noticount" = "1" ] && printf '%s' "$sep$(notify show)" +[ "$noticount" -gt "1" ] && printf '%s' "${sep}[$noticount]" +printf '\n' diff --git a/scripts/status-openbsd b/scripts/status-openbsd @@ -0,0 +1,26 @@ +#!/bin/sh + +# Prints some status info to stdout. Includes: +# - date and time +# - battery +# - wifi (requires ifconfig on OpenBSD) + +# Usage: status [separator] + +sep=${1:-" | "} + +time=$(date +"%H:%M") +date=$(date +"%d %b") +battery="$(apm | grep -o '[^ ]*%')" +ifconfig="$(ifconfig athn0)" +network="$(echo "$ifconfig" | grep status | sed 's/.*status: //')" +if [ "$network" = "active" ]; then + nwid="$(echo "$ifconfig" | grep nwid | sed 's/.*nwid //;s/ chan.*//')" + if [ -z "$nwid" ]; then + nwid="$(echo "$ifconfig" | grep ieee80211 | \ + sed 's/.*ieee80211: join //' | sed 's/ chan.*//')" + fi +fi +network="$(printf "%.20s" "$nwid")" # Make it shorter + +echo "$network$sep$battery$sep$date$sep$time" diff --git a/scripts/templess b/scripts/templess @@ -0,0 +1,10 @@ +#!/bin/sh + +# Write standard in to a temporary file and sends it to a pager. +# This is used to be able to pipe the content displayed by less to +# an external program. + +pager=${PAGER:-less} +tempfile=$(mktemp) + +cat > "$tempfile" && $pager "$tempfile" diff --git a/scripts/terminal b/scripts/terminal @@ -0,0 +1,7 @@ +#!/bin/sh + +# My default terminal + +terminal=${TERMINAL:-"st -e tmux new-session "$@""} + +$terminal diff --git a/scripts/trash b/scripts/trash @@ -0,0 +1,44 @@ +#!/bin/sh + +# Simple trash management. Files are moved to a directory named with the +# current date. + +# Usage: trash [rm FILE(s)|ls|empty] + +# ksh completion +# set -A complete_trash_1 rm ls empty + +trashfolder=$XDG_DATA_HOME/mytrash + +usage() { + echo "Usage: trash [rm FILES... | ls | empty]" +} + +if [ -z "$1" ]; then + usage + exit 1 +fi + +case "$1" in + empty) + # little check + if [ -n "$trashfolder" ]; then + rm -rf "${trashfolder:?}"/* + fi + ;; + ls) + ls "$trashfolder" + ;; + rm) + curdir=$(pwd | sed 's|.*/||') + thisfolder="$trashfolder/$(date +'%Y-%m-%d-%s')-$curdir" + mkdir -p "$thisfolder" + shift 1 + mv "$@" "$thisfolder" + ;; + + *) + usage + exit 1 + ;; +esac diff --git a/scripts/unused/addressgrep b/scripts/unused/addressgrep @@ -0,0 +1,8 @@ +#!/bin/sh + +# Find all email addresses in stdin, print them newline-separated to stdout + +reg='[a-z0-9\._\+\-%]+@[a-z0-9\._\+\-%]+\.[a-zA-Z]+' + +grep -Pio "$reg" + diff --git a/scripts/unused/alg b/scripts/unused/alg @@ -0,0 +1,444 @@ +#!/bin/sh + +# Script to store and access blindsolving algs (speedcubing stuff) + +# Example: alg e FG - opens up editor to edit $basedir/edges/$ebuffer/RD/LD +# Example: alg c UBL E - prints out all first algs for UBL-FDR-* + +usage() { + echo "Usage:" + echo "alg" + echo "alg edit (c|e|w|x|t) [buffer] (1 letter|2 letters)" + echo "alg export (c|e|w|x|t|all)" +} + +default_editor=vi +basedir="$HOME/box/speedcubing/bld/algs" +ebuffer=UR +cbuffer=UFR +wbuffer=UFr +xbuffer=Ubl +tbuffer=Uf + +edge() { + [ "$1" = "a" ] && echo FU + [ "$1" = "b" ] && echo UF + [ "$1" = "c" ] && echo UL + [ "$1" = "d" ] && echo UB + [ "$1" = "e" ] && echo FD + [ "$1" = "f" ] && echo RD + [ "$1" = "g" ] && echo LD + [ "$1" = "i" ] && echo FR + [ "$1" = "j" ] && echo LU + [ "$1" = "k" ] && echo RB + [ "$1" = "l" ] && echo DF + [ "$1" = "m" ] && echo DB + [ "$1" = "n" ] && echo DR + [ "$1" = "o" ] && echo FL + [ "$1" = "p" ] && echo DL + [ "$1" = "r" ] && echo BU + [ "$1" = "s" ] && echo BD + [ "$1" = "t" ] && echo BL + [ "$1" = "u" ] && echo BR + [ "$1" = "v" ] && echo LF + [ "$1" = "w" ] && echo LB + [ "$1" = "z" ] && echo RF +} + +corner() { + [ "$1" = "a" ] && echo FUL + [ "$1" = "b" ] && echo UBL + [ "$1" = "c" ] && echo UFL + [ "$1" = "d" ] && echo UBR + [ "$1" = "e" ] && echo FDR + [ "$1" = "f" ] && echo RDB + [ "$1" = "g" ] && echo LDF + [ "$1" = "j" ] && echo LUF + [ "$1" = "k" ] && echo RUB + [ "$1" = "l" ] && echo DFR + [ "$1" = "m" ] && echo DBR + [ "$1" = "n" ] && echo DFL + [ "$1" = "o" ] && echo FDL + [ "$1" = "p" ] && echo DBL + [ "$1" = "r" ] && echo BUR + [ "$1" = "s" ] && echo BUL + [ "$1" = "t" ] && echo BDL + [ "$1" = "u" ] && echo BDR + [ "$1" = "v" ] && echo LUB + [ "$1" = "w" ] && echo LDB + [ "$1" = "z" ] && echo RDF +} + +wing() { + [ "$1" = "a" ] && echo FUl + [ "$1" = "b" ] && echo URb + [ "$1" = "c" ] && echo ULf + [ "$1" = "d" ] && echo UBl + [ "$1" = "e" ] && echo FDr + [ "$1" = "f" ] && echo RDb + [ "$1" = "g" ] && echo LDf + [ "$1" = "i" ] && echo FRu + [ "$1" = "j" ] && echo LUb + [ "$1" = "k" ] && echo RBu + [ "$1" = "l" ] && echo DFl + [ "$1" = "m" ] && echo DBr + [ "$1" = "n" ] && echo DRf + [ "$1" = "o" ] && echo FLd + [ "$1" = "p" ] && echo DLb + [ "$1" = "r" ] && echo BUr + [ "$1" = "s" ] && echo BDl + [ "$1" = "t" ] && echo BLu + [ "$1" = "u" ] && echo BRd + [ "$1" = "v" ] && echo LFu + [ "$1" = "w" ] && echo LBd + [ "$1" = "x" ] && echo RUf + [ "$1" = "z" ] && echo RFd +} + +xcenter() { + [ "$1" = "a" ] && echo Ful + [ "$1" = "b" ] && echo Ufr + [ "$1" = "c" ] && echo Ufl + [ "$1" = "d" ] && echo Ubr + [ "$1" = "e" ] && echo Fdr + [ "$1" = "f" ] && echo Rdb + [ "$1" = "g" ] && echo Ldf + [ "$1" = "i" ] && echo Fur + [ "$1" = "j" ] && echo Luf + [ "$1" = "k" ] && echo Rub + [ "$1" = "l" ] && echo Dfr + [ "$1" = "m" ] && echo Dbr + [ "$1" = "n" ] && echo Dfl + [ "$1" = "o" ] && echo Fdl + [ "$1" = "p" ] && echo Dbl + [ "$1" = "r" ] && echo Bur + [ "$1" = "s" ] && echo Bul + [ "$1" = "t" ] && echo Bdl + [ "$1" = "u" ] && echo Bdr + [ "$1" = "v" ] && echo Lub + [ "$1" = "w" ] && echo Ldb + [ "$1" = "x" ] && echo Ruf + [ "$1" = "z" ] && echo Rdf +} + +tcenter() { + [ "$1" = "a" ] && echo Fu + [ "$1" = "b" ] && echo Ur + [ "$1" = "c" ] && echo Ul + [ "$1" = "d" ] && echo Ub + [ "$1" = "e" ] && echo Fd + [ "$1" = "f" ] && echo Rd + [ "$1" = "g" ] && echo Ld + [ "$1" = "i" ] && echo Fr + [ "$1" = "j" ] && echo Lu + [ "$1" = "k" ] && echo Rb + [ "$1" = "l" ] && echo Df + [ "$1" = "m" ] && echo Db + [ "$1" = "n" ] && echo Dr + [ "$1" = "o" ] && echo Fl + [ "$1" = "p" ] && echo Dl + [ "$1" = "r" ] && echo Bu + [ "$1" = "s" ] && echo Bd + [ "$1" = "t" ] && echo Bl + [ "$1" = "u" ] && echo Br + [ "$1" = "v" ] && echo Lf + [ "$1" = "w" ] && echo Lb + [ "$1" = "x" ] && echo Ru + [ "$1" = "z" ] && echo Rf +} + +edit() { + mkdir -p "$basedir/$1/$2/$3" + $editor "$basedir/$1/$2/$3/$4" +} + +showall_c() { + all_letters="a b c d e f g j k l m n o p r s t u v w z" + buffer="$1" + firstletter="$2" + firsttarget="$(corner $firstletter)" + for secondletter in $all_letters; do + secondtarget="$(corner $secondletter)" + f="$basedir/corners/$buffer/$firsttarget/$secondtarget" + [ -f "$f" ] || continue + line="$(head -n 1 "$f")" + printf '%s %s\n' "$firstletter$secondletter" "$line" + done +} + +showall_e() { + all_letters="a b c d e f g i j k l m n o p r s t u v w z" + buffer="$1" + firstletter="$2" + firsttarget="$(edge $firstletter)" + for secondletter in $all_letters; do + secondtarget="$(edge $secondletter)" + f="$basedir/edges/$buffer/$firsttarget/$secondtarget" + [ -f "$f" ] || continue + line="$(head -n 1 "$f")" + printf '%s %s\n' "$firstletter$secondletter" "$line" + done +} + +showall_w() { + all_letters="a b c d e f g i j k l m n o p r s t u v w x z" + buffer="$1" + firstletter="$2" + firsttarget="$(wing $firstletter)" + for secondletter in $all_letters; do + secondtarget="$(wing $secondletter)" + f="$basedir/wings/$buffer/$firsttarget/$secondtarget" + [ -f "$f" ] || continue + line="$(head -n 1 "$f")" + printf '%s %s\n' "$firstletter$secondletter" "$line" + done +} + +showall_x() { + all_letters="a b c d e f g i j k l m n o p r s t u v w x z" + buffer="$1" + firstletter="$2" + firsttarget="$(xcenter $firstletter)" + for secondletter in $all_letters; do + secondtarget="$(xcenter $secondletter)" + f="$basedir/xcenters/$buffer/$firsttarget/$secondtarget" + [ -f "$f" ] || continue + line="$(head -n 1 "$f")" + printf '%s %s\n' "$firstletter$secondletter" "$line" + done +} + +showall_t() { + all_letters="a b c d e f g i j k l m n o p r s t u v w x z" + buffer="$1" + firstletter="$2" + firsttarget="$(tcenter $firstletter)" + for secondletter in $all_letters; do + secondtarget="$(tcenter $secondletter)" + f="$basedir/tcenters/$buffer/$firsttarget/$secondtarget" + [ -f "$f" ] || continue + line="$(head -n 1 "$f")" + printf '%s %s\n' "$firstletter$secondletter" "$line" + done +} + +export_csv_c() { + sorted_letters="d b c l n p m k z f j v w g a o e s r u t" + buffer="$cbuffer" + f="$basedir/corners/$buffer" + printf '"",' + for first in $sorted_letters; do + printf '"%s",' "$(corner $first)" + done + printf '\n' + for first in $sorted_letters; do + firstpiece="$(corner $first)" + printf '"%s",' "$firstpiece" + for second in $sorted_letters; do + g="$f/$firstpiece/$(corner $second)" + if [ "$first" = "$second" ] || [ ! -f "$g" ]; then + printf '"",' + else + printf '"%s",' "$(head -n 1 "$g")" + fi + done + printf '\n' + done +} + +export_csv_e() { + sorted_letters="d c b n l p m k z f v j w g i a o e t r u s" + buffer="$ebuffer" + f="$basedir/edges/$buffer" + printf '"",' + for first in $sorted_letters; do + printf '"%s",' "$(edge $first)" + done + printf '\n' + for first in $sorted_letters; do + firstpiece="$(edge $first)" + printf '"%s",' "$firstpiece" + for second in $sorted_letters; do + g="$f/$firstpiece/$(edge $second)" + if [ "$first" = "$second" ] || [ ! -f "$g" ]; then + printf '"",' + else + printf '"%s",' "$(head -n 1 "$g")" + fi + done + printf '\n' + done +} + +export_csv_w() { + sorted_letters="b d c n l p m k x z f v j w g i a o e t r u s" + buffer="$wbuffer" + f="$basedir/wings/$buffer" + printf '"",' + for first in $sorted_letters; do + printf '"%s",' "$(wing $first)" + done + printf '\n' + for first in $sorted_letters; do + firstpiece="$(wing $first)" + printf '"%s",' "$firstpiece" + for second in $sorted_letters; do + g="$f/$firstpiece/$(wing $second)" + if [ "$first" = "$second" ] || [ ! -f "$g" ]; then + printf '"",' + else + printf '"%s",' "$(head -n 1 "$g")" + fi + done + printf '\n' + done +} + +export_csv_x() { + sorted_letters="d c b l n p m k x z f j v w g i a o e s r u t" + buffer="$xbuffer" + f="$basedir/xcenters/$buffer" + printf '"",' + for first in $sorted_letters; do + printf '"%s",' "$(xcenter $first)" + done + printf '\n' + for first in $sorted_letters; do + firstpiece="$(xcenter $first)" + printf '"%s",' "$firstpiece" + for second in $sorted_letters; do + g="$f/$firstpiece/$(xcenter $second)" + if [ "$first" = "$second" ] || [ ! -f "$g" ]; then + printf '"",' + else + printf '"%s",' "$(head -n 1 "$g")" + fi + done + printf '\n' + done +} + +export_csv_t() { + sorted_letters="d c b l n p m k x z f j v w g i a o e s r u t" + buffer="$tbuffer" + f="$basedir/tcenters/$buffer" + printf '"",' + for first in $sorted_letters; do + printf '"%s",' "$(tcenter $first)" + done + printf '\n' + for first in $sorted_letters; do + firstpiece="$(tcenter $first)" + printf '"%s",' "$firstpiece" + for second in $sorted_letters; do + g="$f/$firstpiece/$(tcenter $second)" + if [ "$first" = "$second" ] || [ ! -f "$g" ]; then + printf '"",' + else + printf '"%s",' "$(head -n 1 "$g")" + fi + done + printf '\n' + done +} + +run() { + case "$1" in + edit) + editor="$default_editor" + shift + ;; + export) + if [ "$2" = "all" ]; then + mkdir -p bldsheets + export_csv_c > bldsheets/corners.csv + export_csv_e > bldsheets/edges.csv + export_csv_w > bldsheets/wings.csv + export_csv_x > bldsheets/xcenters.csv + export_csv_t > bldsheets/tcenters.csv + echo "Sheets exported to bldsheets/" + return + fi + #TODO add option for alternative buffers + [ "$2" != "c" ] && [ "$2" != "e" ] && \ + [ "$2" != "w" ] && [ "$2" != "x" ] && \ + [ "$2" != "t" ] && usage && return + export_csv_$2 + return + ;; + *) + editor="cat" + ;; + esac + + type="$1" + if [ -z "$3" ]; then + letters="$2" + cbuf="$cbuffer" + ebuf="$ebuffer" + wbuf="$wbuffer" + xbuf="$xbuffer" + tbuf="$tbuffer" + else + letters="$3" + cbuf="$2" + ebuf="$2" + wbuf="$2" + xbuf="$2" + tbuf="$2" + fi + + letter1="$(echo "$letters" | cut -c 1)" + letter2="$(echo "$letters" | cut -b 2)" + + [ -z "$letter1" ] && usage && return + + case "$type" in + c) + if [ -n "$letter2" ]; then + edit corners $cbuf $(corner $letter1) $(corner $letter2) + else + showall_c $cbuf $letter1 + fi + ;; + e) + if [ -n "$letter2" ]; then + edit edges $ebuf $(edge $letter1) $(edge $letter2) + else + showall_e $ebuf $letter1 + fi + ;; + w) + if [ -n "$letter2" ]; then + edit wings $wbuf $(wing $letter1) $(wing $letter2) + else + showall_w $wbuf $letter1 + fi + ;; + x) + if [ -n "$letter2" ]; then + edit xcenters $xbuf $(xcenter $letter1) $(xcenter $letter2) + else + showall_x $xbuf $letter1 + fi + ;; + t) + if [ -n "$letter2" ]; then + edit tcenters $tbuf $(tcenter $letter1) $(tcenter $letter2) + else + showall_t $tbuf $letter1 + fi + ;; + *) + usage + ;; + esac +} + +if [ -n "$1" ]; then + run $@ +else + while read -r args; do + [ -n "$args" ] && run $args + done +fi diff --git a/scripts/unused/config-backup b/scripts/unused/config-backup @@ -0,0 +1,28 @@ +#!/bin/sh + +# Copy my config files to my backup folder + +folder=$HOME/box/configbackups + +dotfiles=".bash_profile .bashrc .profile .inputrc .mblaze .nexrc .tmux.conf .virc .xinitrc .config/isyncrc" +config="colors fontconfig git imv msmtp zathura" +src="dmenu dwm st" + +for d in config home src ssh; do mkdir -p "$folder/$d"; done + +# copy + +for i in $dotfiles; + do cp -Rf "$HOME"/"$i" "$folder"/home/ +done + +for i in $config + do cp -Rf "$HOME"/.config/"$i" "$folder"/config/ +done + +for i in $src + do mkdir "$folder"/src/"$i" + cp -f "$HOME"/.local/src/"$i"/*.{c,h} "$folder"/src/"$i"/ +done + +cp "$HOME"/.ssh/config "$folder"/ssh/ diff --git a/scripts/unused/dmenu-mail-aliases b/scripts/unused/dmenu-mail-aliases @@ -0,0 +1,29 @@ +#!/bin/sh + +# Select mail alias via dmenu +# The email address must be the second word in a line of $aliasfile +# Requires: dmenu (or similar) + +# Usage: dmenu-mail-aliases [-m menu] + +usage() { + echo "Usage: dmenu-mail-aliases [-m MENU]" +} + +menu="dmenu -l 20" +aliasfile="$HOME/.mblaze/aliases" + +while getopts "m:" opt; do + case "$opt" in + m) + menu="$OPTARG" + ;; + *) + usage + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +$menu <"$aliasfile" | awk '{print $NF}' diff --git a/scripts/unused/dmenu-websearch b/scripts/unused/dmenu-websearch @@ -0,0 +1,8 @@ +#!/bin/sh + +# dmenu prompt for websearch +# Requires: dmenu (or similar), websearch + +menu=${MENU:-dmenu} + +websearch "$(echo "" | $menu -p "websearch:")" diff --git a/scripts/unused/practice b/scripts/unused/practice @@ -0,0 +1,170 @@ +#!/bin/sh + +# Script based on nissy (see https://nissy.tronto.net) to practice FMC + +# Usage: practice [eo|dr|htr|slice] + +nissy="nissy" +prompt="Press enter for a new scramble, Ctr+C (or Ctrl+Z) to quit:" + +usage() { + echo "Usage: practice [eo|dr|htr|fin]" + exit 1 +} + +practice_eo() { + nextscr="$(${nissy} scramble fmc)" + while true; do + scr="$nextscr" + echo "Scramble: $scr" + nextscr="$(${nissy} scramble fmc)" + eofb="$(${nissy} solve -N -M 4 eofb -p "$scr")" + eorl="$(${nissy} solve -N -M 4 eorl -p "$scr")" + eoud="$(${nissy} solve -N -M 4 eoud -p "$scr")" + nfbn="$(echo "$eofb" | grep -v '^$' | grep -Fv '(' | wc -l)" + nrln="$(echo "$eorl" | grep -v '^$' | grep -Fv '(' | wc -l)" + nudn="$(echo "$eoud" | grep -v '^$' | grep -Fv '(' | wc -l)" + nfbi="$(echo "$eofb" | grep '^(' | wc -l)" + nrli="$(echo "$eorl" | grep '^(' | wc -l)" + nudi="$(echo "$eoud" | grep '^(' | wc -l)" + nfbniss="$(echo "$eofb" | grep -v '^(' | grep '(' | wc -l)" + nrlniss="$(echo "$eorl" | grep -v '^(' | grep '(' | wc -l)" + nudniss="$(echo "$eoud" | grep -v '^(' | grep '(' | wc -l)" + nfb="$((nfbn + nfbi + nfbniss))" + nrl="$((nrln + nrli + nrlniss))" + nud="$((nudn + nudi + nudniss))" + n5linear="$(${nissy} solve -L -m 5 -M 5 eo -c "$scr")" + n5niss="$(${nissy} solve -N -m 5 -M 5 eo -c "$scr")" + n5nonlinear="$((n5niss - n5linear))" + read -r x + echo "FB: $nfb ($nfbn normal, $nfbi inverse, $nfbniss niss)" + echo "RL: $nrl ($nrln normal, $nrli inverse, $nrlniss niss)" + echo "UD: $nud ($nudn normal, $nudi inverse, $nudniss niss)" + echo "5 movers: $n5linear linear, $n5nonlinear NISS'd" + read -r x + echo "$eofb" + echo "---" + echo "$eorl" + echo "---" + echo "$eoud" + printf '\n%s' "$prompt" + read -r x + done +} + +practice_dr() { + nextscr="$(${nissy} scramble eo)" + while true; do + scr="$nextscr" + echo "Scramble: $scr" + nextscr="$(${nissy} scramble eo)" + soleo="$(${nissy} solve -o -p drud-eofb "$scr")" + neo="$(echo "$soleo" | grep -v '^$' | wc -l)" + leo="$(echo "$soleo" | head -n 1 | wc -w)" + solht="$(${nissy} solve -o -p drud "$scr")" + nht="$(echo "$solht" | grep -v '^$' | wc -l)" + lht="$(echo "$solht" | head -n 1 | wc -w)" + soleolr="$(${nissy} solve -o -p drrl-eofb "$scr")" + neolr="$(echo "$soleolr" | grep -v '^$' | wc -l)" + leolr="$(echo "$soleolr" | head -n 1 | wc -w)" + solhtlr="$(${nissy} solve -o -p drrl "$scr")" + nhtlr="$(echo "$solhtlr" | grep -v '^$' | wc -l)" + lhtlr="$(echo "$solhtlr" | head -n 1 | wc -w)" + read -r x + echo "DR on U/D: $leo moves ($neo solutions)" + if [ "$nht" != "$neo" ]; then + echo "Breaking EO: $lht moves ($nht solutions)" + fi + echo "DR on R/L: $leolr moves ($neolr solutions)" + if [ "$nhtlr" != "$neolr" ]; then + echo "Breaking EO: $lhtlr moves ($nhtlr solutions)" + fi + read -r x + echo "On U/D:" + echo "$soleo" + echo "" + if [ "$nht" != "$neo" ] || [ "$lht" != "$leo" ]; then + echo "Breaking EO:" + echo "$solht" + echo "" + fi + echo "On R/L:" + echo "$soleolr" + echo "" + if [ "$nhtlr" != "$neolr" ] || [ "$lhtlr" != "$leolr" ]; then + echo "Breaking EO:" + echo "$solhtlr" + echo "" + fi + printf '\n%s' "$prompt" + read -r x + done +} + +practice_htr() { + nextscr="$(${nissy} scramble dr)" + while true; do + scr="$nextscr" + echo "Scramble: $scr" + nextscr="$(${nissy} scramble dr)" + sol="$(${nissy} solve -o -p htr "$scr")" + nsol="$(echo "$sol" | grep -v '^$' | wc -l)" + len="$(echo "$sol" | head -n 1 | wc -w)" + fin="$(${nissy} solve -o -p drfin "$scr")" + lenf="$(echo "$fin" | head -n 1 | wc -w)" + slice="$(${nissy} solve -o -p drslice "$scr")" + lens="$(echo "$slice" | head -n 1 | wc -w)" + read -r x + echo "$len moves ($nsol solutions)" + read -r x + echo "$sol" + if [ "$lenf" != "$lens" ]; then + echo "" + echo "Optimal leave slice ($lens):" + echo "$slice" + fi + echo "" + echo "Optimal DR finish ($lenf):" + echo "$fin" + printf '\n%s' "$prompt" + read -r x + done +} + +practice_fin() { + nextscr="$(${nissy} scramble htr)" + while true; do + scr="$nextscr" + echo "Scramble: $scr" + nextscr="$(${nissy} scramble htr)" + sol="$(${nissy} solve -o -p drudslice "$scr")" + nsol="$(echo "$sol" | grep -v '^$' | wc -l)" + len="$(echo "$sol" | head -n 1 | wc -w)" + fin="$(${nissy} solve -o -p drudfin "$scr")" + nfin="$(echo "$fin" | grep -v '^$' | wc -l)" + lenf="$(echo "$fin" | head -n 1 | wc -w)" + opt="$(${nissy} solve -o -p "$scr")" + leno="$(echo "$opt" | head -n 1 | wc -w)" + read -r x + echo "Leave slice: $len moves ($nsol solutions)" + if [ "$lenf" != "$len" ]; then + echo "DR finish: $lenf moves" + fi + read -r x + echo "$sol" + if [ "$lenf" != "$len" ]; then + echo "" + echo "Optimal DR finish ($lenf):" + echo "$fin" + fi + if [ "$leno" != "$lenf" ]; then + echo "" + echo "Optimal DR-breaking ($leno):" + echo "$opt" + fi + printf '\n%s' "$prompt" + read -r x + done +} + +"practice_$1" || usage diff --git a/scripts/unused/share b/scripts/unused/share @@ -0,0 +1,13 @@ +#!/bin/sh + +# One-liner to upload stuff to my webserver + +srv=tronto.net +dir=$(tr -cd 'a-z0-9' < /dev/random | fold -w 8 | head -n 1) +htp=https://share.tronto.net/$dir +pth=/var/www/htdocs/share.tronto.net/$dir +url=$srv:$pth + +ssh tronto.net mkdir "$pth" +scp "$@" "$url"/ +for i in "$@"; do echo "$htp/$(basename $i)"; done diff --git a/scripts/unused/translate b/scripts/unused/translate @@ -0,0 +1,11 @@ +#!/bin/sh + +# Opens google translate + +translator="https://translate.google.com/" +from=$1 +to=$2 + +shift 2 +text=$(echo "$@" | sed 's/ /\%20/g') +open-url "${translator}?sl=${from}&tl=${to}&text=${text}&op=translate" diff --git a/scripts/unused/websearch b/scripts/unused/websearch @@ -0,0 +1,11 @@ +#!/bin/sh + +# Perform a web search + +browser=${BROWSER:-firefox} +searchengine="https://www.startpage.com/sp/search?query=" +#searchengine="https://duckduckgo.com/?q=" +#searchendinge="https://www.google.com/search?q=" + +arg=$(echo "$@" | sed 's/ /\+/g') +[ -n "$arg" ] && spawn "$browser" "${searchengine}$arg" diff --git a/scripts/unused/xplumb b/scripts/unused/xplumb @@ -0,0 +1,65 @@ +#!/bin/sh + +# My interpretation of a plumber (plan9 style). +# It scans the selected text (xsel) and decides what to do with it among +# some possibilities (open file, open url, man page...). If none is matched, +# a choice is prompted. + +# Requires: dmenu (or similar), mail-compose, open-file, terminal, websearch, +# xedit, xsel + +# TODO: +# send mail to email address; +# calendar if it is a date +# choice: pipe to another program + +browser=${BROWSER:-firefox} +menu=${MENU:-dmenu} +menuopts="-l 10" + +text=$(xsel | sed 's/\n/ /g') +if [ "${#text}" -ge 11 ]; then + shorttext=$(echo "$text" | cut -b 1-10)... +else + shorttext="$text" +fi + +choice() { + chosen=$(printf "websearch\nedit" | \ + $menu $menuopts -p "What to do with \"$shorttext\"?") + + if [ "$chosen" = "websearch" ]; then + websearch "$text" + elif [ "$chosen" = "edit" ]; then + f=$(mktemp) + xsel > "$f" + xedit "$f" + fi +} + +trymail() { + addr=$(echo "$1" | addressgrep) + ( [ -n "$addr" ] && mail-compose "$addr" ) || return 1 +} + +tryman() { + number=$(echo "$1" | sed 's/[^1-8]//g') + name=$(echo "$1" | sed 's/([1-8])//g' | sed 's/ //g') + if [ "$(man -w "$number" "$name" | wc -l)" = 1 ]; then + terminal -e man "$number" "$name" + return 0 + else + return 1 + fi +} + +tryurl() { + url=$(echo "$1" | urlgrep) + ( [ -n "$url" ] && "$browser" "$url" ) || return 1 +} + +#open-file -s spawn "$text" || \ +tryurl "$text" || \ +trymail "$text" || \ +tryman "$text" || \ +choice diff --git a/scripts/urlgrep b/scripts/urlgrep @@ -0,0 +1,9 @@ +#!/bin/sh + +# Find all URLs in stdin, print them newline-separated to stdout + +protocols='http|https|ftp|sftp|gemini|mailto' +valid_chars="][a-zA-Z0-9_~/?#@!$&'()*+=.,;:-" +regex="(($protocols):|www\.)[$valid_chars]+" + +egrep -o "$regex" diff --git a/scripts/virename b/scripts/virename @@ -0,0 +1,25 @@ +#!/bin/sh + +# Rename all files in the current directory with a visual editor. +# Similar to sel add all && sel mv, but it actually works. + +file=$(mktemp) +file2=$(mktemp) +editor=${EDITOR:-vi} + +ls | tee "$file" > "$file2" +$editor "$file2" + +if [ "$(wc -l "$file" | awk '{print $1}')" != \ + "$(wc -l "$file2" | awk '{print $1}')" ]; then + echo "Error reading new file names" +else + paste "$file" "$file2" | while read -r f; do + fold=$(echo "$f" | sed 's/ .*//') + fnew=$(echo "$f" | sed 's/.* //') + if [ "$fold" != "$fnew" ]; then + mv "$fold" "$fnew" \ + || echo "Error renaming $fold to $fnew" + fi + done +fi diff --git a/scripts/xedit b/scripts/xedit @@ -0,0 +1,9 @@ +#!/bin/sh + +# My X editor +# Requires: terminal + +editor=${EDITOR:-${VISUAL:-vi}} +xed=${XEDIT:-"terminal "$editor""} + +$xed "$@" diff --git a/scripts/xedit-filter b/scripts/xedit-filter @@ -0,0 +1,9 @@ +#!/bin/sh + +# Open stdin in a text editor and sends modified selection to stdout +# Requires: xedit + +f=$(mktemp) +cat > "$f" +xedit "$f" && cat "$f" + diff --git a/scripts/xroot-update b/scripts/xroot-update @@ -0,0 +1,8 @@ +#!/bin/sh + +# Updates the xroot window with info from status +# Requires: status + +# Usage: xroot-update + +xsetroot -name " $(status) " diff --git a/scripts/xwallpaper-random-notify b/scripts/xwallpaper-random-notify @@ -0,0 +1,17 @@ +#!/bin/sh + +# Set a random background from the wallpapers folder and notify about it +# Requires: xwallpaper (or feh), notify-send or similar (optional) + +#notify=notify-send +notify="notify push" + +folder=~/pictures/wallpapers +pic=$(ls $folder | sort -R | head -1) + +# Alternative: use feh +#feh --bg-fill --no-fehbg "$folder"/"$pic" +xwallpaper --zoom "$folder"/"$pic" + +# Uncomment to notify +#$notify "Background of the day" "$pic"