aboutsummaryrefslogtreecommitdiffstats
path: root/.config/init
diff options
context:
space:
mode:
Diffstat (limited to '.config/init')
-rwxr-xr-x.config/init/funcs/audio-convert50
-rw-r--r--.config/init/helpers175
2 files changed, 117 insertions, 108 deletions
diff --git a/.config/init/funcs/audio-convert b/.config/init/funcs/audio-convert
index 24c5d62..9d153d4 100755
--- a/.config/init/funcs/audio-convert
+++ b/.config/init/funcs/audio-convert
@@ -1,5 +1,5 @@
#!/usr/bin/env zsh
-# concatenate multiple audio files into one
+# use parallel jobs to convert audio files from one format to another
source "$HOME/.config/init/helpers" || exit 1
@@ -24,21 +24,13 @@ local pid
trap_abort() {
echo ""
- print-error "process interrupted"
- # race condition-y, but eh
- repeat 5; do
- [[ -z $pid ]] && sleep 0.1 || break
- done
- [[ -z $pid ]] || kill -s SIGKILL $pid
- exit 1
+ abort "process interrupted"
}
trap 'trap_abort' SIGABRT SIGHUP SIGINT SIGQUIT SIGTERM
local codecpat='^(opus|mp3|vorbis|flac)$'
local bitratepat='^[1-9][0-9]*k$'
-local metadatapat='^(true|false)$'
-local jobcountpat='^[1-9][0-9]*$'
local qpatvorbis='^([0-9]|10)$'
local qpatmp3='^[0-9]$'
@@ -54,6 +46,7 @@ local qstr
local jobcount
+local args
local parseerr=$(2>&1 zparseopts -D -E -M -A args \
c: -codec:=c \
b: -bitrate:=b \
@@ -61,6 +54,7 @@ local parseerr=$(2>&1 zparseopts -D -E -M -A args \
d: -dest:=d -destination:=d \
j: -jobs:=j \
m:: -metadata::=m \
+ f:: -force::=f \
h -help=h | cut -d ' ' -f 2-)
[[ -z $parseerr ]] || abort $parseerr
@@ -72,6 +66,7 @@ zparseopts -D -E -M -A args \
d: -dest:=d -destination:=d \
j: -jobs:=j \
m:: -metadata::=m \
+ f:: -force::=f \
h -help=h
local optarg
@@ -106,24 +101,26 @@ for opt in ${(@k)args}; do
;;
-q) qstr=$optarg ;;
-d) dirstr=$optarg ;;
- -j) [[ $optarg =~ $jobcountpat ]] || \
+ -j) [[ $optarg =~ $posunsignedpat ]] || \
abort "job count must be a non-negative integer"
jobcount=$optarg
;;
-m) if [[ $optarg ]]; then
- [[ $optarg =~ $metadatapat ]] || \
- abort "metadata must be either \`true\` or \`false\`"
+ [[ $optarg =~ $boolpat ]] || \
+ abort "metadata must be a boolean value (e.g. \`true\` or \`false\`)"
- [[ $optarg == "false" ]] && metastr="" \
+ [[ $optarg =~ $booltpat ]] && metastr=("-map_metadata" "0") \
|| metastr=("-map_metadata" "-1")
else
- metastr=("-map_metadata" "-1")
+ metastr=("-map_metadata" "0")
fi
;;
-h) usage ;;
esac
done
+[[ $#@ -eq 0 ]] && abort "no input files specified"
+
[[ -z $codecstr ]] && codecstr='libopus'
[[ -z $bitratestr ]] && bitratestr='35k'
[[ -z $codecprintstr ]] && codecprintstr='opus'
@@ -135,17 +132,17 @@ done
if [[ ! -z $qstr ]]; then
[[ -z $bitratset ]] || abort "-b and -q are not compatible"
[[ $codecstr == "libopus" ]] && abort "-q cannot be used with opus"
- [[ $codecstr == "libflac" ]] && abort "-q cannot be used with flac"
+ [[ $codecstr == "flac" ]] && abort "-q cannot be used with flac"
[[ $codecstr == "libvorbis" ]] && [[ ! $qstr =~ $qpatvorbis ]] \
&& abort "for vorbis, -q must be in the range [0-10]"
[[ $codecstr == "libmp3lame" ]] && [[ ! $qstr =~ $qpatmp3 ]] \
&& abort "for mp3, -q must be in the range [0-9]"
-else
fi
-[[ $codecstr == "flac" ]] && bitratestr=''
-
-[[ $#@ -eq 0 ]] && abort "no input files specified"
+if [[ $codecstr == "flac" ]]; then
+ bitratestr=''
+ [[ -z $bitrateset ]] || abort "-b cannot be used with flac"
+fi
local roots=(${@:t:r})
local uniqroots=(${(u)roots})
@@ -182,6 +179,7 @@ local jobstr=$jobcount
coproc {
local joblist=()
+ local c
while read -d $'\0' c; do
[[ $c == "done" ]] && break
local f=${c:s/file:/}
@@ -206,24 +204,20 @@ coproc {
echo "done"
}
-pid=$!
-
repeat $jobcount; do
if [[ $#@ -gt 0 ]]; then
- 1>&p printf "%s\0" $@[1]
+ 1>&p printf "file:%s\0" $@[1]
shift
fi
done
while read -p line; do
[[ $line == "done" ]] && coproc exit && break
- echo "$line"
+ echo $line
if [[ $#@ -gt 0 ]]; then
- 1>&p printf "%s\0" "file:${@[1]}"
+ 1>&p printf "file:%s\0" $@[1]
shift
else
- 1>&p printf "%s\0" "done"
+ 1>&p printf "done\0"
fi
done | progress-bar $filecount "using $jobstr to convert $totalstr to $codecprintstr"
-
-2>/dev/null wait $pid
diff --git a/.config/init/helpers b/.config/init/helpers
index 37ae17a..e1ac96e 100644
--- a/.config/init/helpers
+++ b/.config/init/helpers
@@ -1,3 +1,42 @@
+#!/usr/bin/env zsh
+
+# patterns for option matching
+boolpat='^(true|yes|on|1|false|no|off|0)$'
+booltpat='^(true|yes|on|1)$'
+boolfpat='^(false|no|off|0)$'
+
+intpat='^[-+]?[0-9]+$'
+unsignedpat='^[0-9]+$'
+posunsignedpat='^[1-9][0-9]*$'
+floatpat='^[-+]?[0-9]+(\.[0-9]*|e(0|[-+]?[1-9][0-9]*)|\.[0-9]*e(0|[-+]?[1-9][0-9]*$'
+
+termcolourpat='^(black|light_black|red|light_red|green|light_green|yellow|light_yellow|blue|light_blue|magenta|light_magenta|cyan|light_cyan|white|light_white)$'
+
+# $1 - colour
+termcolourpat2escape() {
+ [[ $#@ -eq 1 ]] || {echo 'badcolour'; return 1}
+ [[ $1 =~ $termcolourpat ]] || {echo 'badcolour'; return 1}
+
+ case $1 in
+ 'black') printf '\e[30m' ;;
+ 'light_black') printf '\e[1;30m' ;;
+ 'red') printf '\e[31m' ;;
+ 'light_red') printf '\e[1;31m' ;;
+ 'green') printf '\e[32m' ;;
+ 'light_green') printf '\e[1;32m' ;;
+ 'yellow') printf '\e[33m' ;;
+ 'light_yellow') printf '\e[1;33m' ;;
+ 'blue') printf '\e[34m' ;;
+ 'light_blue') printf '\e[1;34m' ;;
+ 'magenta') printf '\e[35m' ;;
+ 'light_magenta') printf '\e[1;35m' ;;
+ 'cyan') printf '\e[36m' ;;
+ 'light_cyan') printf '\e[1;36m' ;;
+ 'white') printf '\e[37m' ;;
+ 'light_white') printf '\e[1;37m' ;;
+ esac
+}
+
# $1 - message
print-error() {
1>&2 echo "\e[1;31merror:\e[0m $1"
@@ -9,23 +48,41 @@ abort() {
exit 1
}
+# $1 - seconds
+sec2time() {
+ zmodload zsh/datetime || return 1
+
+ if [[ $1 -lt 0 ]]; then
+ printf "??:??:??"
+ return 0
+ fi
+
+ if [[ $1 -lt 86400 ]]; then
+ TZ=UTC strftime '%H:%M:%S' $1
+ return 0
+ fi
+
+ if [[ $1 -ge 8640000 ]]; then
+ printf "forever?"
+ return 0
+ fi
+
+ printf "~%02d days" "$(($1 / 86400))"
+}
+
# $1 - count
# $2 - message (opt)
-# $3 - colourpat (opt)
+# $3 - colour (opt)
progress-bar() {
-
- zmodload zsh/datetime zsh/mathfunc || return 1
+ zmodload zsh/mathfunc zsh/datetime || return 1
[[ $#@ -ne 0 ]] && [[ $#@ -lt 4 ]] || return 1
- local countpat='^[1-9][0-9]*$'
- local colourpat='^(black|light_black|red|light_red|green|light_green|yellow|light_yellow|blue|light_blue|magenta|light_magenta|cyan|light_cyan|white|light_white)$'
-
local count
- [[ $1 =~ $countpat ]] && count=$1 || return 1
- if [[ ! -z $3 ]]; then
- [[ $3 =~ $colourpat ]] || return 1
- fi
+ [[ $1 =~ $posunsignedpat ]] && count=$1 || return 1
+ [[ ! -z $3 ]] && {
+ [[ $3 =~ $termcolourpat ]] || return 1
+ }
local message
local colour
@@ -33,35 +90,19 @@ progress-bar() {
[[ -z $2 ]] && message='waiting' || message=$2
[[ -z $3 ]] && colour='yellow' || colour=$3
- case $colour in
- 'black') colour='\e[30m' ;;
- 'light_black') colour='\e[1;30m' ;;
- 'red') colour='\e[31m' ;;
- 'light_red') colour='\e[1;31m' ;;
- 'green') colour='\e[32m' ;;
- 'light_green') colour='\e[1;32m' ;;
- 'yellow') colour='\e[33m' ;;
- 'light_yellow') colour='\e[1;33m' ;;
- 'blue') colour='\e[34m' ;;
- 'light_blue') colour='\e[1;34m' ;;
- 'magenta') colour='\e[35m' ;;
- 'light_magenta') colour='\e[1;35m' ;;
- 'cyan') colour='\e[36m' ;;
- 'light_cyan') colour='\e[1;36m' ;;
- 'white') colour='\e[37m' ;;
- 'light_white') colour='\e[1;37m' ;;
- esac
+ colour=$(termcolourpat2escape $colour)
local i=0
local starttime=$EPOCHREALTIME
local lasttime=$starttime
- local thistime=$starttime
+ local thistime=$starttime
+ local now=$starttime
local elapsed=0
while true; do
-
- local now=$EPOCHREALTIME
[[ $i -eq $count ]] && break
+ now=$EPOCHREALTIME
+
local width=$COLUMNS
local statwidth=$(( ($#count * 2) + 35))
local progwidth=$(($width - $statwidth - 3))
@@ -70,19 +111,10 @@ progress-bar() {
if [[ $i -eq 0 ]]; then
eta='??:??:??'
else
- local left=$(( ($count - $i) * ($elapsed / $i) - ($now - $lasttime) ))
- if [[ $left -ge 86400 ]]; then
- eta=' days...'
- elif [[ $left -le 0 ]]; then
- eta='00:00:00'
- else
- eta=$(strftime '%H:%M:%S' ${$(( ceil($left + 802800) )):s/\./})
- fi
+ eta=$(sec2time ${$(( ceil( ($count - $i) * ($elapsed / $i) - ($now - $lasttime) ) )):s/\./})
fi
- local rt=$(($now - $starttime))
- [[ $rt -ge 86400 ]] && rt=' days...' \
- || rt=$(strftime '%H:%M:%S' ${$(( floor($rt + 802800) )):s/\./})
+ local rt=$(sec2time ${$(( floor( ($now - $starttime) ) )):s/\./} )
local fpart=""
local epart=""
@@ -96,7 +128,7 @@ progress-bar() {
$i \
read -t 0.2 \
- && thistime=$EPOCHREALTIME \
+ && thistime=$EPOCHREALTIME \
&& elapsed=$(($elapsed - $lasttime + $thistime)) \
&& lasttime=$thistime \
&& i=$(($i + 1))
@@ -104,23 +136,21 @@ progress-bar() {
printf "\e[F"
done
- [[ $i -eq $count ]] && echo "\e[G\e[32m$message... done!\e[0m\e[J" \
+ [[ $i -eq $count ]] \
+ && echo "\e[G\e[32m$message... done in $(sec2time ${$(( floor($elapsed) )):s/\./})\e[0m\e[J" \
|| echo "\e[G\e[31m$message... failed!\e[0m\e[J"
}
# $1 - pid
# $2 - message (opt)
-# $3 - colourpat (opt)
+# $3 - colour (opt)
wait-anim() {
[[ $#@ -ne 0 ]] && [[ $#@ -lt 4 ]] || return 1
- local pidpat='^[1-9][0-9]*$'
- local colourpat='^(black|light_black|red|light_red|green|light_green|yellow|light_yellow|blue|light_blue|magenta|light_magenta|cyan|light_cyan|white|light_white)$'
-
- [[ $1 =~ $pidpat ]] || return 1
- if [[ ! -z $3 ]]; then
- [[ $3 =~ $colourpat ]] || return 1
- fi
+ [[ $1 =~ $posunsignedpat ]] || return 1
+ [[ ! -z $3 ]] && {
+ [[ $3 =~ $termcolourpat ]] || return 1
+ }
local message
local colour
@@ -128,28 +158,9 @@ wait-anim() {
[[ -z $2 ]] && message='waiting' || message=$2
[[ -z $3 ]] && colour='yellow' || colour=$3
- case $colour in
- 'black') colour='\e[30m' ;;
- 'light_black') colour='\e[1;30m' ;;
- 'red') colour='\e[31m' ;;
- 'light_red') colour='\e[1;31m' ;;
- 'green') colour='\e[32m' ;;
- 'light_green') colour='\e[1;32m' ;;
- 'yellow') colour='\e[33m' ;;
- 'light_yellow') colour='\e[1;33m' ;;
- 'blue') colour='\e[34m' ;;
- 'light_blue') colour='\e[1;34m' ;;
- 'magenta') colour='\e[35m' ;;
- 'light_magenta') colour='\e[1;35m' ;;
- 'cyan') colour='\e[36m' ;;
- 'light_cyan') colour='\e[1;36m' ;;
- 'white') colour='\e[37m' ;;
- 'light_white') colour='\e[1;37m' ;;
- esac
+ colour=$(termcolourpat2escape $colour)
- local curframe
local frames
-
case $(($RANDOM % 7)) in
0) frames=('▁' '▂' '▃' '▄' '▅' '▆' '▇' '█' '▇' '▆' '▅' '▄' '▃' '▂') ;;
1) frames=(' ' '▖' '▚' '▝' ' ' '▘' '▞' '▗') ;;
@@ -160,19 +171,23 @@ wait-anim() {
6) frames=('O' 'o' '.' 'o') ;;
esac
- local rval
-
- {
- wait $1
- rval=$?
- echo "done"
- } | while true; do
+ local curframe
+ coproc while true; do
[[ -z $curframe ]] && curframe=0
- printf "\e[G\e[K|\e[1;32m${frames[$(($curframe + 1))]}\e[0m| $colour$message...\e[0m"
+ printf "\e[G\e[K|\e[1;32m${frames[$(($curframe + 1))]}\e[0m| $colour$message...\e[0m\n"
curframe=$(( ($curframe + 1) % $#frames ))
read -t 0.2 && break
done
+ while read -p line; do
+ printf $line
+ done &
+ local printer=$!
+
+ local rval
+ 2>/dev/null wait $1 && rval=$? && echo "done" >&p
+ 2>/dev/null wait $printer
+
[[ $rval -eq 0 ]] && printf "\e[G\e[K\e[32m$message... done!\e[0m\n" \
|| printf "\e[G\e[K\e[31m$message... failed!\e[0m\n"