mpvrpco '{ "command": ["get_property", "percent-pos"] }' | jq .data | sed 's/\..*/%/' 2>/dev/null ||:
}
+# run if not running.
+#
+# Note: this does not work with shell scripts as they are normally
+# invoked, because the ps output has the interpreter at the start.
+# A workaround is to invoke the command in that format, or we could
+# do various other workarounds.
+#
+# background, this relies on how ps converts newlines in arguments to spaces, and
+# assumes we won't be searching for a command with spaces in its arguments
+rinr() {
+ if ps h -o args -C "${1##*/}" | grep -Fxqv "$*" &>/dev/null || [[ $? == 141 ]]; then
+ "$@"
+ fi
+}
+# variation of above: run or wait if running
+rowir() {
+ local pid
+ pid=$(ps h -o 'pid,args' -C "${1##*/}" | sed -r 's/^[[:space:]]*([0-9]+)[[:space:]](.*)/\1\n\2/' | grep -B1 -Fx "$*" | head -n1 ||: )
+ if [[ $pid ]]; then
+ # https://unix.stackexchange.com/questions/427115/listen-for-exit-of-process-given-pid
+ tail --pid="$pid" -f /dev/null
+ else
+ "$@"
+ fi
+}
+
+mpvrpc-loadfile() {
+ local path nextpath cachedir finalpath nextpath count
+ cachedir=$HOME/.iank-music-cache
+ path="$1"
+ nextpath="$2"
+
+ # note: logic duplicated in beetpull
+ local remote_p=true
+ if [[ $HOSTNAME == kd ]]; then
+ remote_p=false
+ fi
+
+ if $remote_p; then
+ finalpath="$cachedir${path#/i/m}"
+ rowir rsync --partial -a --inplace --mkpath "b8.nz:$path" "$finalpath"
+ finalnextpath="$cachedir${nextpath#/i/m}"
+ count=$(pgrep -a -f "^rsync --partial -a --inplace --mkpath $cachdir" || [[ $? == 1 ]] )
+ # allow us to start 2 rsyncs in the background
+ if [[ $count == [01] ]]; then
+ rinr rsync --partial -a --inplace --mkpath "b8.nz:$nextpath" "$finalnextpath" &
+ fi
+ else
+ finalpath="$path"
+ fi
+ mpvrpc '{ "command": ["loadfile", "'"$finalpath"'"] }'
+}
+
# tag with beets.
# usage: beetag [-r] [-s] QUERY
# it lists the query, reads an input char for tagging one by one.
fi
### end arg processing ###
- beetpull
+ # note: I used to do beetpull here, but mpv + ssfs on slowish
+ # connection leads to bad/buggy result.
do_rare_genres=false
volume=70
first_play=false
for (( i=0; i<20; i++ )); do
if [[ $(mpvrpco '{ "command": ["get_property", "idle-active"] }' 2>/dev/null | jq .data) == true ]]; then
- mpvrpc '{ "command": ["loadfile", "'"$path"'"] }' 2>/dev/null
+ mpvrpc-loadfile "$path" 2>/dev/null
break
fi
sleep .1
done
else
- mpvrpc '{ "command": ["loadfile", "'"$path"'"] }'
+ mpvrpc-loadfile "$path"
fi
erasable_line=false
fi
doplay=false
else
doplay=true
- mpvrpc '{ "command": ["loadfile", "'"$path"'"] }'
+ mpvrpc-loadfile "$path"
erasable_line=false
fi
beetag-nostatus 1
}
# Bitcoin holds open the wallet file. this causes problems for a
-# secondary computer running bitcoin and receiving a backup. So, as a
-# workaround, I intend to manually enable the wallet when I want to use
-# it and leave it disabled otherwise.
+# secondary computer running bitcoin and receiving a backup (as of
+# 2023). However, in 2024-02, I ran a backup where a receiving machine
+# had the wallet enabled and there was no error, so I don't know if this
+# is still an issue or likely it is an inconsistent behavior.
+#
+# As a workaround, this function is for enabling the wallet when I want
+# to use it and leave it disabled otherwise.
walleton() {
local active
active=false
fi
active=true
m ser stop bitcoind
+ else
+ echo note: bitcoind not active
fi
m rm /var/lib/bitcoind/wallets
if $active; then
+ # note, starting bitcoin always fails, but it actually
+ # succeeds. But this is strangely not consistent.
m ser start bitcoind
if ! $no_on; then
m rm /tmp/no-bitcoinon
digdiff @ns{1,2}.iankelling.org "$@"
}
-tsr() { # ts run
- "$@" |& ts || return $?
-}
-
dup() {
local ran_d
ran_d=false
vpn_ips[kw]=27
vpn_ips[bo]=28
vpn_ips[frodo]=34
+vpn_ips[s23b]=49
vpn-ips-update() {
local host ipsuf f files
"$@" |& pee "xclip -r -selection clipboard" cat
}
-# x copy
+# xorg copy. copy text piped into command
xc() {
xclip -r -selection clipboard
}
e spamtest error: expected 1 arg, filename >&2
return 1
fi
-
- spamdpid=$(systemctl status spamassassin| sed -n '/^ *Main PID:/s/[^0-9]//gp')
- spamcpre="nsenter -t $spamdpid -n -m"
- s $spamcpre sudo -u Debian-exim spamassassin -t --cf='score PYZOR_CHECK 0' <"$1"
+ sdncmdroot spamassassin sudo -u Debian-exim spamassassin -t --cf='score PYZOR_CHECK 0' <"$1"
}
$s /a/exe/teeu "$@"
}
+# execute exim in its namespace. Useful args like -Mrm
enn() {
local ecmd pid
ecmd="/usr/sbin/exim4 -C /etc/exim4/my.conf"
if ip a show veth1-mail &>/dev/null; then
s $ecmd "$@"
- return
+ else
+ sdncmdroot exim4 $ecmd "$@"
fi
- pid=$(pgrep -f "/usr/sbin/exim4 -bd -q10m -C /etc/exim4/my.conf"|h1)
- m s nsenter -t $pid -n -m $ecmd "$@"
}
# get pid of systemd service
m sudo nsenter -t $pid -n -m sudo -u $USER -i bash
}
-sdnbashroot() { # systemd namespace bash
+sdnbashroot() { # systemd namespace bash as root
local unit pid
if (( $# != 1 )); then
echo $0: error wrong number of args >&2
}
-sdncmd() { # systemd namespace cmd
+# systemd namespace cmd
+# usage: UNIT CMD...
+sdncmd() {
local unit pid tmpf
- if (( $# <= 2 )); then
+ if (( $# <= 1 )); then
echo $0: error wrong number of args >&2
return 1
fi
m sudo nsenter -t $pid -n -m sudo -u $USER -i bash -c ". $tmpf & rm $tmpf"
}
+sdncmdroot() { # systemd namespace root command
+ local unit pid
+ if (( $# < 2 )); then
+ echo $0: error wrong number of args >&2
+ return 1
+ fi
+ unit=$1
+ shift
+ pid=$(servicepid $unit)
+ m sudo nsenter -t $pid -n -m "$@"
+}
+
mailnnbash() {
sdnbash mailnn
# }
eximbash() {
- local pid
- pid=$(pgrep -f "/usr/sbin/exim4 -bd -q10m -C /etc/exim4/my.conf"|h1)
- if [[ ! $pid ]]; then
- echo "eximbash: failed to find exim pid. systemctl -n 30 status exim4:"
- systemctl status exim4
- fi
- m sudo nsenter -t $pid -n -m
+ sdnbashroot exim4
}
spamnn() {
local spamdpid
m sudo nsenter -t $spamdpid -n -m sudo -u Debian-exim spamassassin "$@"
}
unboundbash() {
- m sudo nsenter -t "$(systemctl status unbound| sed -n '/^ *Main PID:/s/[^0-9]//gp')" -n -m sudo -u $USER -i bash
+ sdnbashroot unbound
}
nmtc() {
vpncmd() {
- m sudo -E env "PATH=$PATH" nsenter -t "$(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*client.conf")" -n "$@"
+ sdncmd openvpn-client-tr@client.service "$@"
}
-
vpni() {
- vpncmd sudo -u iank env "PATH=$PATH" "$@"
+ sdncmd openvpn-client-tr@client.service bash
}
vpnbash() {
- vpncmd bash
+ sdncmdroot openvpn-client-tr@client.service bash
}
um() {
local sink card
sink=$(pactl get-default-sink)
- if [[ $sink != auto_null ]]; then
- return
+ if [[ $sink == auto_null ]]; then
+ # guessing there is just one with an off profile. otherwise we will
+ # need some other solution, like storing the card identifier that we
+ # muted with nap.
+ card=$(pacmd list-cards | sed -n '/^[[:space:]]*index:/{s/^[[:space:]]*index://;h};/^[[:space:]]*active profile: <off>$/{g;p;q}')
+ m pacmd set-card-profile "$card" output:analog-stereo
fi
- # guessing there is just one with an off profile. otherwise we will
- # need some other solution, like storing the card identifier that we
- # muted with nap.
- card=$(pacmd list-cards | sed -n '/^[[:space:]]*index:/{s/^[[:space:]]*index://;h};/^[[:space:]]*active profile: <off>$/{g;p;q}')
- m pacmd set-card-profile "$card" output:analog-stereo
-
- pactl set-sink-mute @DEFAULT_SINK@ false
+ m pactl set-sink-mute @DEFAULT_SINK@ false
rm -f /tmp/ianknap
}
rgv -m 5 -- "$*" $paths /a/t.org /p/w.org /a/work.org ||:
}
+# re on common fsf files
+ref() {
+ local paths
+ paths="/f/gluestick /f/brains /f/s /c"
+ find $paths -not \( -name .svn -prune -o -name .git -prune \
+ -o -name .hg -prune -o -name .editor-backups -prune \
+ -o -name .undo-tree-history -prune \) 2>/dev/null | grep -iP --color=auto -- "$*" ||:
+ rgv -- "$*" $paths /a/work.org ||:
+}
+
# for use in /f/bind
fupzone() {
rm -fv /tmp/noi3bar
}
+# example:
+# <#part type="image/jpeg" filename="/home/iank/2023-12-24-ski-trip.jpg" disposition=attachment> <#/part>
+#
+attach-txt() {
+ local f
+ for f; do
+ if [[ ! -s $f ]]; then
+ e "error: empty or non-existent file $f"
+ return 1
+ fi
+ done
+ for f; do
+ echo '<#part type="image/jpeg" filename="'"$(rl "$f")"'" disposition=attachment> <#/part>'
+ done | ec
+}
+
+ctof() {
+ units "tempC($1)" tempF
+}
+
+ftoc() {
+ units "tempF($1)" tempC
+}
export BASEFILE_DIR=/a/bin/fai-basefiles