filebin() { basePath=/srv/www/files ssh ymir find /srv/www/files -type f -printf "$'%T@ %TY-%Tm-%TdT%TH:%TM %P\\\\0'" | sort -zn | cut -z -d ' ' -f 2- \ | while IFS= read -r -d $'\0' l; do IFS=' ' read -r t p <<<"${l}" printf "%s https://f.141.li/%s\n" "${t}" "${p}" done } push2bin() { if [[ ${#@} -eq 1 && ! -r ${1} ]]; then uux -p 'ymir!push2bin' $(echo -n "${1:t}" | tr -c $'[:alnum:]+-=.' '_') else for f (${@}); do uux -p 'ymir!push2bin' $(echo -n "${f:t}" | tr -c $'[:alnum:]+-=.' '_') <${f} done fi } genmail() { local baseName="" local target="" if [[ ${#@} -ge 1 ]]; then target=${1} shift fi if [[ ${#@} -ge 1 ]]; then baseName=$(pwgen ${@}) else baseName=$(pwgen -v -A -0 16 1) fi baseName=$(tr -cd $'[:alnum:]!#$%&*+-/=?^_{|}~.' <<<${baseName}) address=${baseName}@141.li insertAddr() { echo "${baseName} gkleen" | ssh ymir tee -a /srv/mail/spm 1>/dev/null \ } printf "%s\n" ${address} read -q 'cont?Continue [y/N]? ' || return insertAddr } s() { dir=$(pwd) [[ ${#@} -ge 1 ]] && dir=$1 shellFile=$(findNix ${@}) [[ ${#@} -ge 1 ]] && shift typeset -a cmd if [[ -d ${dir}/.nix-gc-roots ]]; then cmd=(persistent-nix-shell ${shellFile} ${S_EXTRA_ARGS} ${@}) else cmd=(nix-shell ${shellFile} ${S_EXTRA_ARGS} ${@}) fi if [[ -n "${S_SYSTEMD}" ]]; then systemd-run --user --slice=development.slice --collect -E PATH=${PATH} -p WorkingDirectory=${dir} -- ${cmd} else ( cd ${dir} exec ${cmd} ) fi } sz() { typeset -a S_EXTRA_ARGS S_EXTRA_ARGS=(--run "env __ETC_ZSHENV_SOURCED=1 zsh") s ${@} } st() { typeset -a S_EXTRA_ARGS S_EXTRA_ARGS=(--run "tmux new-session env __ETC_ZSHENV_SOURCED=1 zsh") s ${@} } stt() { typeset -a S_EXTRA_ARGS S_SYSTEMD=true S_EXTRA_ARGS=(--run "urxvt -e tmux -S .tmux.sock new-session env __ETC_ZSHENV_SOURCED=1 zsh") s ${@} } se() { typeset -a S_EXTRA_ARGS S_SYSTEMD=true S_EXTRA_ARGS=(--run "emacs") s ${@} } findNix() { if [[ $#@ -eq 0 ]]; then findNix $(pwd) elif [[ -f "$1" ]]; then print ${1:a} elif [[ -d "$1" && -f "$1"/shell.nix ]]; then print ${1:a}/shell.nix elif [[ -d "$1" && -f "$1"/default.nix ]]; then print ${1:a}/default.nix elif [[ -d "$1" && "$1" != "/" ]]; then findNix ${1:h} else printf "Traversed directories to ‘/’ and found no shell specification\n" >&2 return 1 fi } dir() { curlArchive=false templateArchive="" repoUrl="" nixShell="" findNix=false dir="" forceShell=false wormhole=false gitWorktree="" # notmuchMsg="" quickserve=false modifyPDF="" while getopts ':t:a:s:Sd:ir:wqg:p:' arg; do case $arg in "t") ;; "a") if [[ ${OPTARG} =~ "://" ]]; then templateArchive=${OPTARG} curlArchive=true else templateArchive=${OPTARG:a} fi ;; "s") nixShell=${OPTARG:a} ;; "S") findNix=true ;; "d") dir=${OPTARG} ;; "i") forceShell=true ;; "r") repoUrl=${OPTARG} ;; "w") wormhole=true ;; "g") gitWorktree=${OPTARG} ;; # "n") notmuchMsg=${OPTARG} ;; "q") quickserve=true ;; "p") modifyPDF=${OPTARG:a} ;; *) printf "Invalid option: %s\n" $arg >&2; exit 2 ;; esac done shift $((OPTIND - 1)) if [[ -z ${dir} && ${#@} -ge 1 ]]; then dir=${1} shift fi [[ -n ${dir} ]] || return 2; if [[ ! -e ${dir} ]]; then if [[ -z "${gitWorktree}" ]]; then mkdir -vp ${dir} else git -C ${gitWorktree} worktree add ${dir} fi else gitWorktree="" fi cleanup() { cd ${modifyPDF:h} [[ -n ${modifyPDF} ]] && nix shell nixos#imagemagick -c convert -verbose ${dir}/${modifyPDF:t:r}_*.png(on) ${modifyPDF} } ( trap cleanup EXIT cd ${dir} export dir; ${findNix} && { nixShell=$(findNix) || return $? } [[ -n ${repoUrl} ]] && git clone -- ${repoUrl} . [[ -n ${modifyPDF} ]] && templateArchive=${modifyPDF} if [[ -n ${templateArchive} ]]; then ( archiveFile="" cleanup() { [[ -n "${archiveFile}" ]] && rm -fv ${archiveFile} } trap cleanup EXIT if ${curlArchive}; then archiveFile=$(mktemp -t "archive.XXXXXXXXXX.${templateArchive:t}") curl -L -o ${archiveFile} ${templateArchive} templateArchive=${archiveFile} fi unpack=true while ${unpack}; do case $(file --brief --mime-type --dereference ${templateArchive}) in application/zip) unzip ${templateArchive} unpack=false ;; application/vnd.debian.binary-package) nix shell nixos#binutils --command ar x ${templateArchive} mkdir control data tar -C control -xvaf control.* tar -C data -xvaf data.* unpack=false ;; application/x-rpm) cpioArchive=$(mktemp -t "archive.XXXXXXXXXX.${templateArchive:t:r}.cpio") nix shell nixos#busybox --command rpm2cpio ${templateArchive} > ${cpioArchive} templateArchive=${cpioArchive} unpack=true ;; application/x-cpio) cpio --extract --make-directories --no-absolute-filenames -F ${templateArchive} unpack=false ;; application/pdf) nix shell nixos#ghostscript nixos#imagemagick -c convert -verbose -density 400 ${templateArchive} ${modifyPDF:t:r}_%0d.png unpack=false ;; *) tar -xvaf ${templateArchive} unpack=false ;; esac done ) fi # if [[ -n ${notmuchMsg} ]]; then # getMimeTypes() { # nix-shell -p mailcap --run "find \${buildInputs} -path '*/etc/mime.types' | head -n 1 | xargs -- cat" # } # typeset -a messages # messages=(${(z)$(notmuch search --output=messages ${notmuchMsg})}) # for message (${messages}); do # typeset -A notmuchAtts # notmuchAtts=() # while IFS= read -r -d $'\n' line; do # [[ ${line} =~ '(attachment|part)\{ ID: ([0-9]+)' ]] || continue # attId=${match[2]} # [[ ${line} =~ 'Content-type: multipart/' ]] && continue # fName="part_${attId}" # [[ ${line} =~ 'Filename: (([^,]|,[^ ])+)' ]] && fName=${match[1]} # if [[ ${#messages} -gt 1 ]]; then # fName="${message}/${fName}" # fi # fExt="${fName:e}" # [[ -n "${fExt}" ]] && fName="${fName:r}" # if [[ -z "${fExt}" && ${line} =~ 'Content-type: (([^,]|,[^ ])+)$' ]]; then # fExt=$(getMimeTypes | grep ${match[1]}$'\t' | head -n 1 | awk '{ print $2; }') # fi # mkdir -p ${fName:h} # if [[ -n "${fExt}" ]]; then # fName=$(mktemp -p . "${fName}.XXXXXX.${fExt}") # else # fName=$(mktemp -p . "${fName}.XXXXXX") # fi # notmuchAtts[${attId}]=${fName} # done <<(notmuch show --decrypt=false -- ${message} | tr -d $'\f') # for attId fName in ${(kv)notmuchAtts}; do # [[ -d ${fName:h} ]] || mkdir -p ${fName:h} # printf "#%d → ‘%s’\n" "${attId}" "${fName}" >&2 # notmuch show --decrypt=false --part=${attId} -- ${message} | pv -W -D 2 -i 0.1 >${fName} # done # done # fi ${wormhole} && wormhole receive if ${quickserve}; then quickserve --root . --upload . --show-hidden --tar gz fi if [[ ${#@} -eq 0 ]] || ${forceShell}; then if [[ ${#@} -gt 0 ]]; then if [[ -z ${nixShell} ]]; then ${@} else nix-shell ${nixShell} --run "${@}" fi fi cd $(pwd) # Needed for mounting to work isSingleDir() { typeset -a contents contents=(*(N) .*(N)) if [[ ${#contents} -eq 1 && -d ${contents[1]} ]]; then print ${contents[1]} return 0 else return 1 fi } while d=$(isSingleDir); do cd ${d}; done if [[ -z ${nixShell} ]]; then zsh else nix-shell ${nixShell} --run zsh fi else if [[ -z ${nixShell} ]]; then ${@} else nix-shell ${nixShell} --run "${@}" fi fi ) } tmpdir() { cleanup() { cd / unmount() { printf "Unmounting %s\n" ${1} >&2 fusermount -u ${1} || umount ${1} || sudo umount ${1} } if mountpoint -q -- ${dir}; then unmount ${dir} || return $? else while read -d $'\0' subDir; do mountpoint -q -- ${subDir} || continue unmount ${subDir} || return $? done <<<$(find ${dir} -xdev -type d -print0 | sort -zr) fi rm -rfv --one-file-system -- ${dir} } local tmpdir="" while getopts ':t:a:s:Sd:ir:wqg:p:' arg; do case $arg in "t") tmpdir="=${OPTARG}" ;; "?"|":") printf "Invalid option: %s\n" $arg >&2; exit 2 ;; esac done ( trap cleanup EXIT local dir=$(mktemp -ud --tmpdir${tmpdir} ${0}.XXXXXXXXXX || return $?) ( dir -d ${dir} ${@} ) ) } inhibit-sleep() { if systemctl --user is-active prevent-suspend.service 1>/dev/null; then echo "Allowing suspend" systemctl --user stop prevent-suspend.service else echo "Inhibiting suspend" systemctl --user start prevent-suspend.service fi } qr() { qrencode -l M -o - -t ANSIUTF8 $@ } clock() { tty-clock -sSbc -C 7 -d 0 -a 100000000 } public-ip() { curl -s -H 'Accept: application/json' $@ ifconfig.co | jq -r '.ip' } nix-ghci() { pkgExpr="" if [[ ${#@} -gt 0 ]]; then pkgExpr="${1}" shift fi nix-shell -p "with (import {}); pkgs.haskellPackages.ghcWithPackages (p: with p; [${pkgExpr}])" --run "ghci ${@}" } swap() { f1=${1} f2=${2} if [[ -z "${f1}" || ! -e "${f1}" ]]; then printf "‘%s’ does not exist\n" "${f1}" >&2 return 2 fi if [[ -z "${f2}" || ! -e "${f2}" ]]; then printf "‘%s’ does not exist\n" "${f2}" >&2 return 2 fi tmpfile=$(mktemp --dry-run --tmpdir=${f1:h} .swap.XXXXXXXXXX) mv -v ${f1} ${tmpfile} mv -v ${f2} ${f1} mv -v ${tmpfile} ${f2} } ls() { exa --all --group-directories-first --colour=always $@ | less --mouse -FR } l() { ls --long --binary --git --time-style=iso --header $@ } re() { systemctl --restart $@ } ure() { systemctl --user --restart $@ } u2wdb() { ssh -t postgres@uniworxdb2 psql uni2work } ssh-installer() { ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentityFile=~/.ssh/gkleen@sif.midgard.yggdrasil $@ } dichotomic_search() { min=$1; shift max=$1; shift while [[ $min -lt $max ]]; do # Compute the mean between min and max, rounded up to the superior unit current=$(( (min + max + 1 ) / 2 )) if $@ $current; then min=$current else max=$((current - 1)) fi done echo $min } while read -r -d $'\0' d _ s; do hash -d ${s}=${d} done < <(find ~/projects ~/uni -regextype posix-extended -maxdepth 2 -type d -regex '\S+/[0-9]{2}[ws]/\S+' -print0 2>/dev/null | \ sed -zr 's|(.*/([0-9]{2}[ws])/(.+))|\1 \2 \3|' | \ sort -z -r -k2 | sort -z -s -k3 | uniq -z -f 2) alias '..'='cd ..' alias rzadm=$'tmpdir -i sh -c \'mkdir adm; sshfs gkleen@mgmt01:/adm adm\'' alias -g L='| less' alias -g S='&> /dev/null' alias -g G='| grep' alias -g B='&> /dev/null &' alias -g BB='&> /dev/null &!' export DEFAULT_USER=gkleen export EDITOR=emacsclient bindkey -e bindkey ';5C' emacs-forward-word bindkey ';5D' emacs-backward-word bindkey '^[[1;5C' emacs-forward-word bindkey '^[[1;5D' emacs-backward-word