Compare commits

...

9 commits

Author SHA1 Message Date
xeruf
6533464fd2 bin: update scripts 2025-02-04 11:57:49 +01:00
xeruf
c4c3b4d492 bin: vpn scripts 2025-02-04 11:56:52 +01:00
xeruf
a1df1394cc config/sway: windows defaults 2025-02-04 11:56:52 +01:00
xeruf
090ef5220f config/sway: touchpad adjustments 2025-02-04 11:56:52 +01:00
xeruf
e8bea8cd10 config/doom: updates 2025-02-04 11:56:48 +01:00
xeruf
a7275911b4 config/bash: hestia commands and others 2025-02-04 11:55:40 +01:00
xeruf
c587fda4c9 config/aichat/roles: new roles format 2025-02-04 11:55:40 +01:00
xeruf
151f2f4e8a bin/bag: update for btrfs snapshots 2025-02-04 11:55:40 +01:00
xeruf
cf33fa7b79 shell/music: update playlist dir 2025-02-04 11:55:40 +01:00
52 changed files with 406 additions and 138 deletions

View file

@ -0,0 +1,6 @@
Convert the following contact details into carddav format importable by nextcloud.
A blank line separates another contact.
Output one long file.
Ensure that TYPE= is used for TEL.
Convert phone numbers into E.123 international notation defaulting to Germany +49 as national prefix.
Create a unique UID.

View file

@ -0,0 +1 @@
convert __ARG1__ below to __ARG2__

View file

@ -0,0 +1 @@
convert different ways of __INPUT__ to emoji

View file

@ -0,0 +1 @@
Translate between English and German. Provide multiple translation options if it is only a word or a short phrase.

View file

@ -0,0 +1 @@
You are a teacher of IT for somebody with very basic knowledge. Translate the following passages to German and explain.

View file

@ -0,0 +1 @@
Help me write a message in an emotional conversation.

View file

@ -0,0 +1 @@
Suggest recipes involving the following ingredients.

View file

@ -0,0 +1 @@
I want you to act as a linux shell expert. Always answer with code, then explain. My primary shell is zsh with oh-my-zsh and vi bindings on Manjaro Arch Linux with Sway Wayland Window Manager in the Kitty Terminal.

View file

@ -0,0 +1 @@
Act as a translator between english/german and swahili. Explain each translation. Breakdown swahili words.

View file

@ -9,7 +9,8 @@ ds() {
grep -v '\b/[^/ ]*/[^/]*/[^/]*$' |
awk -v a="\033[31m" -v b="\033[33m" -v c="\033[35m" -v n="\033[0m" 'NR==1 {printf "%-20s %6s %7s %9s %s\n",$1,$5,$3,$4,$6} NR>1 {u=$5; printf (u > 98) ? a : (u > 96) ? b : (u > 90) ? c : ""; printf "%-20s %6s %6.1fG %8.1fG %s\n",$1,$5,$3/1024,$4/1024,$6; printf n}';
}
ds
export -f ds
timeout 1s bash -c ds
test $(id -u) -eq 0 || sudo=sudo
@ -34,6 +35,7 @@ ff() {
}
xtrace () {
trap 'set +x' INT
set -x
"$@"
set +x
@ -82,6 +84,7 @@ __u="$sudo apt update && $sudo apt upgrade"
alias u="$__u"
alias ur="tmux new-session -s upgrade '$__u && $sudo reboot'"
alias dif='diff --color=always --side-by-side --report-identical-files'
# Diff recursively
difr() { diff --color=always --unified=1 --recursive "$@" | less --RAW-CONTROL-CHARS --quit-on-intr --quit-if-one-screen; }
# Copy recursively with rsync

View file

@ -1,7 +1,7 @@
set -o pipefail
alias localip="ip addr show | grep -E '(ens|eth)' | grep -oP '"'(?<=inet\s)\d+(\.\d+){3}'"' | head -1"
ip=`localip`
IP=$(localip)
logs() {
if test $# -eq 0
@ -15,6 +15,23 @@ logs() {
fi
}
hestia() {
test $# -eq 0 && cd "$HESTIA" && return 0
test "$1" = "-x" && shift && set -x
command=$1
shift
echo '>' sudo "$(which $command)" "$@" >&2
export SHELLOPTS
sudo --preserve-env=SHELLOPTS timeout 30s $(which $command) "$@"
set +x
}
accessible() {
dir=/home/*/web/$1/public_html
sudo chmod -v 755 $dir
sudo chown -v :sudo $dir
}
monitor() {
file=gatus.yaml
echo 'customer-endpoint: &customer
@ -24,7 +41,7 @@ monitor() {
endpoints:' >$file
for user in $(list users)
do group="$(hestia v-list-user $user | head -3 | cut -d':' -f2 | tr -s ' ' | sed 'N;s/\n/:/;N;s/\n / (/;s/$/)/')"
for domain in $(hestia v-list-web-domains $user | grep "$ip" | awk '{print $1}')
for domain in $(hestia v-list-web-domains $user | grep "$IP" | awk '{print $1}')
do echo '- name: "'$domain'"
<<: *customer
group: "'$group'"
@ -56,7 +73,7 @@ letsencrypt() {
for domain in $(hestia v-list-mail-domains $user | tail +3 | awk '{print $1}')
do hestia v-list-mail-domain-ssl $user $domain | grep -q . || hestia v-add-letsencrypt-domain $user $domain '' yes
done
for domain in $(hestia v-list-web-domains $user | grep "$ip" | awk '{print $1}')
for domain in $(hestia v-list-web-domains $user | grep "$IP" | awk '{print $1}')
do #echo commented out due to command echoing in hestia alias
#echo "Checking $user $domain" >&2
hestia v-list-web-domain $user $domain | grep -q REDIRECT && continue
@ -64,7 +81,7 @@ letsencrypt() {
hestia v-list-web-domain-ssl $user $domain | grep . >/dev/null && continue
#echo "Generating Certificate" >&2
hestia v-add-letsencrypt-domain $user $domain $(hestia v-list-web-domain $user $domain | grep ALIAS | tr -s ' ' | cut -d' ' -f2- | tr ' ' ',')
echo "$domain: ${?}"
echo "$domain status code: ${?}"
done
echo "Waiting an hour to not trigger letsencrypt rate limits..."
time=0
@ -95,19 +112,61 @@ list() {
fi
}
hestia() {
test $# -eq 0 && cd "$HESTIA" && return 0
test "$1" = "-x" && shift && set -x
command=$1
shift
echo '>' sudo "$(which $command)" "$@" >&2
export SHELLOPTS
sudo --preserve-env=SHELLOPTS timeout 30s $(which $command) "$@"
set +x
domain() {
if test $# -eq 0
then while read -r domain
do test -n "$domain" || break
domain "$domain"
done
return $?
fi
echo
for domain; do
domain=$(echo "$domain" | rev | cut -d. -f-2 | rev)
date=$(grep "$domain (" cu_invoicelineitems.csv | grep -v SSL | tail -1 | cut -d\" -f8 | sed -sE 's/.* - (.*)\).*/\1/')
datec=$(grep ",$domain," portfolio_domains_2025-01-13.csv | cut -d, -f3 | cut -dT -f1)
contact=$(grep ",$domain," domains.csv | cut -d, -f3 || grep ",$domain," portfolio_domains_2025-01-13.csv | cut -d, -f25)
renew=$(grep ",$domain," domains.csv | cut -d, -f10 || grep ",$domain," portfolio_domains_2025-01-13.csv | cut -d, -f6 | cut -dT -f1)
iddomain="$(idn2 "$domain")"
echo "$(timeout .3s dig +short NS "$iddomain" | sort | head -1 | grep . || echo " ") $(timeout .3s dig +short A "$iddomain" | head -1 | grep . || echo " ") ${date:-C$datec} ${renew:- } $domain $contact"
done
}
accessible() {
dir=/home/*/web/$1/public_html
sudo chmod -v 755 $dir
sudo chown -v :sudo $dir
domains() {
set -o pipefail
sudo $HESTIA/bin/v-list-users | tail +3 | grep -v ssh- | while read user
do
name="$($HESTIA/bin/v-list-user $(echo "$user" | cut -d\ -f1) | grep 'FULL NAME:' | cut -d: -f2)"
if test -t 1
then echo "$user" | awk '{print ""$3" "$1" '"$(echo $name)"'"}'
else echo "$user" | awk '{print "\n"$3" "$1" '"$(echo $name)"'"}' | tr '[a-z]' '[A-Z]'
fi
sudo $HESTIA/bin/v-list-dns-domains $(echo "$user" | cut -d\ -f1) | tail +3 | while read domain
do domain="${domain%% *}"
if test $(echo "$domain" | tr -cd '.' | wc -c) -ne 1
then #echo "Ignoring invalid DNS-Domain $domain" >&2
continue
fi
domain "$domain"
done
done
echo
if test -t 1
then echo "VAUTRON"
else echo "VAUTRON"
fi
for domain in $(cut -d, -f2 domains.csv)
do domain "$domain"
done
echo
if test -t 1
then echo "AUTODNS"
else echo "AUTODNS"
fi
for domain in $(cut -d, -f2 portfolio_domains_2025-01-13.csv)
do domain "$domain"
done
}

View file

@ -1,17 +0,0 @@
[[ $- == *i* ]] && zfs list -d 0
alias cluster='scr corosync && scr pvesr'
qcow() { qemu-img convert $1 -O qcow2 ${2:-$1}.qcow2; }
extrac() {
for var; do
arg=${var%.lzo}
out=$(basename ${arg%.vma})
lzop -x $arg.lzo
vma.py $arg $out || vma.py $(basename $arg) $out && (
cd $out && find drive-* -exec qemu-img convert {} -O qcow2 $out-{}.qcow2 \;
)
#vma extract $arg $out &&
#( cd $out && find *.raw -exec qemu-img convert {} -O qcow2 $arg-{}.qcow2 \; )
done
}

1
.config/bash/na.bash Symbolic link
View file

@ -0,0 +1 @@
pve.bash

View file

@ -663,6 +663,7 @@ Version 2019-11-04 2021-02-16"
"E" 'org-export-repeat
:desc "Save and Export" "be" (lambda () (interactive) (basic-save-buffer) (org-export-repeat))
:localleader
":" 'org-babel-mark-block
"E" 'org-export-repeat
)
@ -696,7 +697,7 @@ Version 2019-11-04 2021-02-16"
(setq org-export-with-tags nil
org-export-with-tasks 'done
org-export-with-todo-keywords nil
org-export-with-toc nil
; only apply to tex, not html: org-export-with-toc nil
org-export-with-section-numbers nil
org-export-with-broken-links 't
org-ascii-text-width 999
@ -1061,11 +1062,11 @@ This is 0.3 red + 0.59 green + 0.11 blue and always between 0 and 255."
)
(use-package vc-fossil
;; Keep from loading unnecessarily at startup.
:defer t
;; This allows VC to load vc-fossil when needed.
:init (add-to-list 'vc-handled-backends 'Fossil))
;(use-package vc-fossil
; ;; Keep from loading unnecessarily at startup.
; :defer t
; ;; This allows VC to load vc-fossil when needed.
; :init (add-to-list 'vc-handled-backends 'Fossil))
(use-package! chordpro-mode
:mode ("\\.cho\\'" . chordpro-mode)

View file

@ -41,26 +41,22 @@
(setq straight-host-usernames '((github . "xeruf")))
;;; Multimedia & Integration
(package! emms)
(package! exiftool)
(package! elpher)
;(package! emms)
;(package! exiftool)
;(package! elpher)
(package! activity-watch-mode :recipe (:fork t)) ; eagle eyes
(package! kill-or-bury-alive) ; https://github.com/mrkkrp/kill-or-bury-alive
(package! recompile-on-save)
(package! vc-fossil)
;(package! vc-fossil)
;;; Prettification
(package! dired+)
(package! xterm-color)
(package! rainbow-mode)
(package! rainbow-mode) ; Colorize color names in buffers
;;; ORG
(unpin! org-journal)
(package! org :pin "ca873f7")
(package! websocket)
(package! org-roam-ui
:recipe (:host github :repo "org-roam/org-roam-ui" :files ("*.el" "out")))
@ -95,6 +91,8 @@
(package! ess)
(package! helm-dash)
;; https://www.emacswiki.org/emacs/CsvMode
(package! csv-mode)

View file

@ -26,10 +26,19 @@
))
))
(defun list-non-hidden-directories (directory)
"List all non-hidden subdirectories in DIRECTORY and return them as a list."
(let ((dir-list (directory-files directory t))
(directories '()))
(dolist (file dir-list directories)
(when (and (file-directory-p file) ; Check if it's a directory
(not (string-prefix-p "." (file-name-nondirectory file)))) ; Check if it's not hidden
(setq directories (cons file directories))))))
(use-package! recentf
:config
(add-to-list 'recentf-exclude "writing\\/tug")
(add-to-list 'recentf-exclude "\\.\\(sync\\|stversions\\|stfolder\\)")
(add-to-list 'recentf-list (expand-file-name "5-incubator/downloads/" user-data-dir))
(add-to-list 'recentf-list (expand-file-name "5-incubator/download/" user-data-dir))
(setq recentf-list (append (list-non-hidden-directories user-data-dir) recentf-list))
(setq recentf-keep '(recentf-keep-default-predicate file-remote-p "/ssh:.*"))
)

View file

@ -1,25 +1,20 @@
export AUDIO="$DATA/audio"
MUSIC_RAW="$AUDIO/songs/_raw"
alias scbra='scpr zebra "/srv/funkwhale/data/music${PWD/$MUSIC}"'
# See also scripts/pl
# Finds common music files in the current directory, optionally taking a regex
findsongs() {
find -regextype posix-extended -maxdepth 1 -type f \
-iregex "${1:-.*\.(mp3|flac|wav|m4a)}" -printf "%P\n"
}
addtopl() {
pl=$1
shift
playlists=$MUSIC/Playlists
realpath --relative-to $playlists "$@" | tee -a $playlists/$pl*
}
addmix() {
AUDIO="$DATA/audio"
mv -v "$1.cue" "$AUDIO/recordings/cues"
addsong "$1.flac" Mixes
}
# Used to keep music directory small, pretty much obsolete now
MUSIC_RAW="$d4/songs/_raw"
addsong() {
test "$1" = "-q" && shift && quick="true"
@ -41,6 +36,7 @@ addsong() {
test ! "$PWD" -ef "$MUSIC_RAW/$2" && mv -v "$raw.flac" "$MUSIC_RAW/$2" && (test "$isflac" || rm -v "$1")
}
# Execute inside an album folder with the desired target path
addalbum() {
mkdir -p "$MUSIC/$1"
mkdir -p "$MUSIC_RAW/$1"
@ -86,8 +82,10 @@ updatemusic() {
formatsongs() {
(
find -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | formatin
find "$@" "$PWD" -type d | while read d;
find "${@:-$PWD}" -type d | while read d;
do builtin cd "$d" && findsongs | formatin
test $(find -maxdepth 1 -name '01 *' | wc -l) -gt 1 -a $(find -maxdepth 1 -name '02 *' | wc -l) -eq 0 &&
zmv -W '01 *' '*'
done
)
# fd --no-ignore-vcs --type f --extension opus --exec opusdec --quiet "{}" "{.}.wav" \; ".*" "$@"

View file

@ -8,6 +8,7 @@ assign [class="zoom"] number 7
assign [class="steam"] number 8
assign [class="DeltaChat"] number 8
assign [class="discord"] number 9
assign [class="Slack"] number 9
#assign [title="Telegram"] number 9
assign [app_id="org.telegram.desktop" tiling] number 9
assign [class="Signal"] number 9

View file

@ -4,10 +4,3 @@ input * {
xkb_numlock enabled
xkb_options caps:escape_shifted_capslock
}
input "type:touchpad" {
tap enabled
natural_scroll disabled
accel_profile adaptive
dwt disabled
pointer_accel 0.4 # set mouse sensitivity (between -1 and 1)
}

View file

@ -1,2 +1,3 @@
$bindsym $mod+Alt+Shift+Up sticky toggle
for_window [app_id="dragon-drop"] floating enable, sticky enable
for_window [app_id="swappy"] floating enable, sticky enable

View file

@ -1,11 +1,30 @@
input type:touchpad {
tap enabled
natural_scroll disabled
events enabled
dwt enabled
# TODO disabled_on_external_mouse
accel_profile adaptive
pointer_accel 0.4 # set mouse sensitivity (between -1 and 1)
}
# FW16 Touchpad
# Also 2362:628:PIXA3854:00_093A:0274_Mouse
input 2362:628:PIXA3854:00_093A:0274_Touchpad {
pointer_accel 1
}
# TODO not working
$bindsym $mod+Alt+t swaymsg input type:touchpad events toggle
#$bindsym $mod+Alt+t swaymsg input type:touchpad events toggle
#input "pointer:motion:MSFT0002:01.*" {
# xinput events disable type:touchpad
#input type:mouse {
# accel_profile adaptive
# pointer_accel 1
#}
#
## Ploopy
#input 20547:23622:Ploopy_Corporation_Thumb_Trackball_Mouse {
# accel_profile adaptive
# pointer_accel 1
#}

View file

@ -2,6 +2,15 @@
# Automatically set screen brightness based on time of day.
# OLD: value=$(expr 100 - $(expr 13 - $(date +%H) | tr -d -) \* 5)
# S Function: echo "(c($(date +%H) / 4 - 3) + 1) * 50" | bc -l
value=$(echo "l=(100 - 1.5 * ( 11 - $(date +%H) ) ^ 2); if(l > 0) l else 3" | bc -l)
light -S $value
{ date && echo $value; } >>/var/log/autolight
# summertime: value=$(echo "l=(100 - 1.5 * ( 11 - $(date +%H) ) ^ 2); if(l > 0) l else 3" | bc -l)
value=$(echo "l=(100 - 3 * ( 12 - $(date +%H) ) ^ 2); if(l > 0) l else 3" | bc -l)
if test "$1" != "-n"; then
light -S $value
inputmodule-control led-matrix --brightness $(echo $value / 5 + 2 | bc)
if ! test -w /var/log/autolight
then
sudo chown :$(id -g) /var/log
sudo chmod g+w /var/log
fi
fi
printf "Set Light Level %4.1f at %s\n" "$value" "$(date)" | tee -a /var/log/autolight

View file

@ -43,10 +43,6 @@ fileinfo() {
tput rmso
size=$(stat --format=%s "$arg")
# Check if SSH key (<10KB then read)
if test "$size" -lt 10000
then $elevate ssh-keygen -l -f "$arg" 2>/dev/null
fi
# I think this check is here to avoid scrolling text interpreted as video
#probe="$($elevate ffprobe "$arg" 2>&1)"
#echo $probe | grep -v -e '00:00:00.04' -e 'ansi' &&
@ -59,7 +55,12 @@ fileinfo() {
) - birth %.10w mod %.10y" "$arg" | numfmt --field=3 --to=iec-i --padding=6 --suffix=B
fi
done
# Check if SSH key (<10KB then read)
if test "${size:-99999}" -lt 10000
then $elevate ssh-keygen -l -f "$arg" 2>/dev/null || true
fi
tput sgr0
pacman -Qo "$arg" 2>/dev/null || true
}
prefix=/tmp/b
@ -77,7 +78,7 @@ for arg; do
fi
# amount of items to display per line in a grid for two lines max
grid=$(expr $(tput cols) / \( 25 - \( $# / 2 \) \& $# \< 30 \| 5 \))
tmpfile="$prefix/$(basename -- "$arg")_$(dd "if=$arg" bs=512 count=10 2>/dev/null | md5sum | tr -d ' ' || true)"
tmpfile="$prefix/$(basename -- "$arg")_$(dd "if=$arg" bs=1M count=16 2>/dev/null | md5sum | cut -d ' ' -f1 || true)"
mkdir -p "$prefix"
case "$mime" in
(*\ application/pdf)
@ -108,8 +109,13 @@ for arg; do
! $inspect &&
# TODO sometimes duration mismatch for short videos
test $(printf "%.0f" $(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$arg")) -gt 3 &&
mtn -q -i -t -W -r$(expr 5 - $# \& $# \< 4 \| 1) -D6 -b 0.6 -c $grid -w $(expr $(tput cols) '*' 20) \
-O "$prefix" -o "$suffix" "$arg" &&
{ mtn -q -i -t \
-D6 -b 0.6 \
-r$(expr 5 - $# \& $# \< 4 \| 1) -c $grid -w $(expr $(tput cols) '*' 20) \
-W -O "$prefix" -o "$suffix" "$arg" ||
mtn -q -i -t \
-W -O "$prefix" -o "$suffix" "$arg"
} &&
timg -W "$prefix/$(basename -- "${arg%.*}")$suffix"
;;
(*\ image/*)
@ -154,7 +160,8 @@ for arg; do
;;
(*:\ SQLite\ *\ database*) highlight "Tables" && sqlite3 "$arg" ".tables";; # TODO for few tables: SELECT * FROM db LIMIT 3; | cut -c-$col
(*:\ data) ;;
(*\ key) bat+=("$arg");;
(*\ key) bat+=("$arg")
continue;;
(*) bat+=("$arg")
timga+=("$arg")
continue
@ -245,15 +252,16 @@ if test "$ls" -o $# -le $(echo "$flags" | wc -w); then
checkperm .
# Alternative: find -exec ls -dl {} +
{
# TODO handle single quotes in filenames
# TODO listing sometimes doubles as exa prints partial listings while working
timeout .6s sh -c "
if test '$tree'
then $elevate tree -a --dirsfirst --du -h -C -L 3 $flags -- $(printf "'%s' " "${ls[@]:-.}")
# Below issues are fixed by disabling timeout, maybe an alternative can be found to prevent hanging on huge dirs
# handle single quotes in filenames
# listing sometimes doubles as exa prints partial listings while working
#timeout .6s sh -c "
if test -n "$tree"
then $elevate tree -a --dirsfirst --du -h -C -L 3 $flags -- "${ls[@]:-.}"
elif which exa 2>/dev/null >&2
then $elevate exa --icons --color=always --long --group --classify --all --all --sort=modified --reverse $flags -- $(printf "'%s' " "${ls[@]:-.}")
else $elevate ls -l $(test $# -gt ${#ls[@]} && echo '-d') --color=always --human-readable --si --group-directories-first --file-type --dereference-command-line-symlink-to-dir --all $flags -- $(printf "'%s' " "${ls[@]:-.}")
then $elevate exa --icons --color=always --long --group --classify --all --all --sort=modified --reverse $flags -- "${ls[@]:-.}"
else $elevate ls -l $(test $# -gt ${#ls[@]} && echo '-d') --color=always --human-readable --si --group-directories-first --file-type --dereference-command-line-symlink-to-dir --all $flags -- "${ls[@]:-.}"
fi
" || $elevate ls $(test $# -gt ${#ls[@]} && echo "-d") --color=always --human-readable --si --dereference-command-line --all --sort=none $flags -- "${ls[@]:-.}"
#" || $elevate ls $(test $# -gt ${#ls[@]} && echo "-d") --color=always --human-readable --si --dereference-command-line --all --sort=none $flags -- "${ls[@]:-.}"
} | $pager --quit-if-one-screen
fi

View file

@ -20,7 +20,8 @@ name="::$(test -n "$name" && echo "$name" || cat /etc/hostname)_${1:-system}_$(d
echo "Backing up as $name"
# TODO ignore electron caches
${run:-sudo --preserve-env=BORG_REPO BORG_PASSPHRASE="$($BORG_PASSCOMMAND)" borg} create --exclude-caches $args \
$(echo $DIRS_IGNORE_SAFE -x 'software-challenge/**/build' -x state/emacs -x state/go -x .local/lib -x .cpan -x *cache -x $HOME/.gem |
$(echo $DIRS_IGNORE_SAFE -x .snapshots -x 'software-challenge/**/build' -x state/emacs -x state/go -x .local/lib -x .cpan -x *cache -x $HOME/.gem |
sed 's|-x \([^ ]\+\)|-e sh:**/\1|g') \
"$name" $(test $# -eq 0 && echo etc home root || test $# -eq 1 && echo $1) "${@:2}" 2>&1
"$name" $(test $# -eq 0 && echo etc $HOME root || test $# -eq 1 && echo $1) "${@:2}" 2>&1
test -n "$run" || sudo chown -R $USER:$USER "$BORG_REPO"
$(cat /tmp/after-borg || true)

View file

@ -1,5 +1,5 @@
#!/bin/sh -e
# Suspend screen until enter is pressed
# Suspend screen until enter is pressed or interrupted
test "$1" && sleep $1
dpms() {
if test $XDG_SESSION_TYPE = wayland
@ -9,5 +9,6 @@ dpms() {
}
dpms off
trap 'dpms on' INT
sleep 99999
sleep 3
read _
dpms on

23
.local/bin/scripts/contact Executable file
View file

@ -0,0 +1,23 @@
#!/bin/sh -e
# Process raw contact data into a vcard and save it to nextcloud
echo "Finish input with Ctrl-D" >&2
inputfile=/tmp/aichat-contact
cat >"$inputfile"
while test "$accept" != "y"
do printf "\nProcessing...\n" >&2
vcard="$(aichat --role carddav <"$inputfile")"
echo "$vcard"
printf "Accept? ([y]es/[n]o/[c]ancel) " >&2
read -r accept
test "$accept" != "c" || exit $?
done
uid=$(echo "$vcard" | grep UID | grep --only-matching '[-0-9a-fx]\{36\}')
echo
ncfields=$(pass show service/nextcloud)
ncfield() {
echo "$ncfields" | head -$1 | tail -1
}
echo "$vcard" | curl -o /tmp/contact -w "HTTP Response Code from $(ncfield 3): %{http_code}\n" -u $(ncfield 2):$(ncfield 1) "$(ncfield 3)/remote.php/dav/addressbooks/users/$(ncfield 2)/${1:-contacts}/$uid.vcf" -X PUT -H 'Depth: 0' -H 'Content-Type: text/vcard; charset=utf-8;' -H 'DNT: 1' --data-binary @-
cat /tmp/contact

View file

@ -22,8 +22,10 @@ then highlight "Write Test"
test -s $tempfile ||
( highlight "Preparing random bits:" &&
sudo dd status=progress if=/dev/urandom of=$tempfile bs=1M count=$count ) &&
sha1sum $tempfile
highlight "Copying random bits:" &&
sudo dd status=progress if=$tempfile of=.$count bs=1M count=$count
sha1sum .$count
highlight "Copying zero bits:" &&
sudo dd status=progress if=/dev/zero of=.$count bs=1M count=$count
sudo rm .$count

View file

@ -4,17 +4,19 @@ d5=$DATA/5-*
dow=$d5/download
# Internal Duplicates
rmlint --rank-by=Olam -o pretty -o sh:/tmp/dow.sh $dow/*.*
script1=/tmp/dedup-download_$(date +%s)_internal.sh
rmlint --rank-by=Olam -o pretty -o sh:$script1 $dow/*.*
printf "Enter to confirm, any text to skip (answer does not matter if nothing is printed above this). "
read -r answer
test -n "$answer" || /tmp/dow.sh -d
test -n "$answer" || $script1 -d
# Songs
mv -v -- $dow/*.mp3 $dow/*.flac $dow/*.wav $MUSIC/
mv -v -- $dow/*.iso $DATA/4-*/flash/
# Data-dir duplicates
rmlint --keep-all-tagged --max-depth=5 --rank-by=Odlam -o pretty -o sh:/tmp/dow.sh $d5 // $DATA/1-* $DATA/2-* $DATA/3-* $DATA/4-*
script2=/tmp/dedup-download_$(date +%s)_data.sh
rmlint --keep-all-tagged --max-depth=5 --rank-by=Odlam -o pretty -o sh:$script2 $d5 // $DATA/1-* $DATA/2-* $DATA/3-* $DATA/4-*
printf "Enter to confirm, any text to skip (answer does not matter if nothing is printed above this). "
read -r answer
test -n "$answer" || /tmp/dow.sh -d
test -n "$answer" || $script2 -d

12
.local/bin/scripts/ecled Executable file
View file

@ -0,0 +1,12 @@
#!/bin/sh -e
# Make controlling framework leds from framework more accessible
case $# in
(0)
for led in $(sudo ectool led '' query 2>&1 | tail -1 | cut -d: -f2)
do
highlight $led
sudo ectool led $led query
done;;
(1) sudo ectool led "$@" query;;
(*) sudo ectool led "$@";;
esac

View file

@ -10,7 +10,7 @@ listconf() {
find "${XDG_CONFIG_HOME:-$HOME/.config}" /etc /var/lib/postgres /var/lib/pleroma/static/instance \
-maxdepth 4 -follow \
\( -name Partitions -o -name mdn -o -name .git -o -name .local -o -name plugged \) -prune -o \
! \( -iname "*.markdown" -o -iname "*.md" -o -name "Network Persistent State" -o -iname "*.pem" \) -a \
! \( -iname "*.markdown" -o -name "Network Persistent State" -o -iname "*.pem" \) -a \
-type f -readable -exec grep -lI '' {} + 2>/dev/null
} | dedup-lines
}

View file

@ -1,5 +1,5 @@
#!/bin/sh
# View song metadata using ffprobe
# View media metadata using ffprobe
# Accepts filenames from args or stdin (one file per line)
# TODO only print header when interactive
if test "$#" -eq 0
@ -7,5 +7,7 @@ then cat
else printf '%s\n' "$@"
fi | while read f; do
highlight "$f"
find "$f" -type f -exec ffprobe -loglevel 20 -print_format default=noprint_wrappers=1 -show_format -pretty {} \;
find "$f" -type f -exec ffprobe -hide_banner \
-loglevel $(expr 34 - $#) -print_format default=noprint_wrappers=1 -show_format -pretty {} \;
# loglevel: from 32 shows stream details (steps of 8), so only for small groups
done | less

View file

@ -5,7 +5,7 @@
# args: either a playlist file name, or a list of terms which all have to match
# TODO fails on "Alchemy"
# TODO implement finding by tags
PLAYLISTS="${PLAYLISTS:-$MUSIC/Playlists}"
PLAYLISTS="${PLAYLISTS:-$MUSIC/playlists}"
mpc -q clear || mpdr
if test -z "$1"
then mp -q "$PLAYLISTS/focus.m3u"

8
.local/bin/scripts/fw-clock Executable file
View file

@ -0,0 +1,8 @@
#!/bin/sh -e
# Creates a breathing clock in a tmux session (9-16)
# or fixed brightness
tmux new-session -d -s ledmatrix \; \
send-keys 'retry inputmodule-control led-matrix --clock' C-m \; \
split-window -v \; \
send-keys "while test $(expr 12 - $(date +%H) | tr -d -) -lt 4; do inputmodule-control led-matrix --breathing; done
autolight" C-m

58
.local/bin/scripts/gol Executable file
View file

@ -0,0 +1,58 @@
#!/bin/bash -e
# Run Game of Life on the Framework 16 matrix with the given input string
CFG="${XDG_CONFIG_HOME}/fwledmatrix/combos"
mkdir -p "$(dirname "$CFG")"
alphabet=({A..Z} = + '!' '.' ':') # -
case "$1" in
(--iter)
# Iterate over all combinations
for l1 in "${alphabet[@]}" ""; do
for l2 in "${alphabet[@]}" ""; do
for l3 in "${alphabet[@]}" ""; do
for l4 in "${alphabet[@]}" ""; do
for l5 in "${alphabet[@]}" ""; do
combination="${l1}${l2}${l3}${l4}${l5}"
echo "$combination"
gol "$combination"
done
done
done
done
done
;;
(--random)
# Function to generate a random combination
generate_random_combination() {
local combination=""
for _ in {1..5}; do
# Select a random letter from the alphabet
random_letter=${alphabet[$RANDOM % ${#alphabet[@]}]}
combination+="$random_letter"
done
echo "$combination"
}
while true
do gol "$(generate_random_combination)"
done
;;
(""|--known)
while true
do gol "$(shuf -n 1 "$CFG")"
done
;;
(*)
inputmodule-control led-matrix --stop-game
string="$(echo "$@" | tr 'a-z' 'A-Z')"
echo "Running '$string'"
inputmodule-control led-matrix --string "$string"
sleep 1
inputmodule-control led-matrix --start-game game-of-life --game-param current-matrix
while ! read -r -t 30 game_continue
do inputmodule-control led-matrix --sleeping false
done
if test -n "$game_continue"
then echo "$string" >>"$CFG"
fi
;;
esac

View file

@ -26,7 +26,7 @@ showinfo() {
cmd="$1"
case "$cmd" in
(fwupdmgr|hunt|rdoc|gh|chordpro|pdfjam|reflector|topgrade|r128gain|7z|kubectl|diffr|docker|jrnl|difft|wiked-diff|qpdf|ninja|qobuz-dl|beet)
(fwupdmgr|hunt|rdoc|gh|chordpro|pdfjam|reflector|topgrade|r128gain|7z|kubectl|diffr|docker|jrnl|difft|wiked-diff|qpdf|ninja|qobuz-dl|beet|flux)
unbuffer "$@" --help | sed 's|^[^ ].*:|\0|' | $paginate;;
(sqlcmd) sqlcmd -?;;
(exa) "$0" eza;;

View file

@ -5,8 +5,8 @@ if test $# -eq 0
then
set -x
$0 sleep uni nap cry tech read dev phone bike tour laptop computer piano faith health lens Zinc \
girl CB Claudia Kerstin Turi Taura \
Erlangen Bayreuth Berlin ICF
girl CB Claudia Turi Taura \
Erlangen Bayreuth Berlin
true $?
else
for arg

View file

@ -14,15 +14,22 @@ case $1 in
#done &
# TODO handle labels with spaces
lsblk --list --noheadings --output name,label,fstype,mountpoint | grep -v LUKS | grep -v '/' | grep ".\+ [^ ]\+";
awk '$1 !~ /^#/ && NF>=2 {print $2}' /etc/fstab | while read fstab_mount; do
if ! grep -qs " $fstab_mount " /proc/mounts; then
echo "$fstab_mount"
fi
done;
} | fzf --exit-0 | sed "s/^\([^ ]\+ \+\)\?\([^ ]\+\) \+[^ ]\+ *$/\2/"
);;
(--help) echo "$_help" && exit 0;;
(-u) shift
for last; do true; done
sudo umount --verbose "$@"
code=$?
sudo rm -df "$last"
exit $code;;
exit $?
#code=$?
#sudo rm -df "$last"
#exit $code
;;
(*) arg=$1
shift;;
esac
@ -39,13 +46,13 @@ then loopdevice="$(sudo losetup -f)"
fi
# FSTAB: BY LABEL
if grep --word-regexp "LABEL=$arg" /etc/fstab
if grep --word-regexp "^LABEL=$arg" /etc/fstab
then # have to mount twice as the first one might be creating the directory
mount -L "$arg" "$@" 2>/dev/null || mount -L "$arg" "$@"
exit $?
fi
# FSTAB: BY MOUNTPOINT/NAME
if grep --word-regexp "$arg" /etc/fstab
# FSTAB: BY MOUNTPOINT/NAME - does not find by UUID
if sudo findmnt --fstab | grep --word-regexp "$arg"
then mount "$arg" "$@"; exit $?
fi

View file

@ -4,9 +4,15 @@
# depends: xargs realpath mpc
# env: MUSIC
# TODO auto-convert unknown types with ffmpeg to flac rather than linking (wav, opus, ...)
if test $# -eq 0
then echo "Usage: $0 [files...]"
mpdr
mpc play
exit 0
fi
MPD_CONF=${XDG_CONFIG_HOME:-$HOME/.config}/mpd/mpd.conf
MUSIC="${MUSIC:-$(cat $MPD_CONF | grep music_directory | cut -d'"' -f2 | sed "s|~|$HOME|")}"
PLAYLISTS="$(cat $MPD_CONF | grep playlist_directory | cut -d'"' -f2 | sed "s|~|$HOME|" || echo "$MUSIC/Playlists")"
PLAYLISTS="$(cat $MPD_CONF | grep playlist_directory | cut -d'"' -f2 | sed "s|~|$HOME|" || echo "$MUSIC/playlists")"
LINKS="$MUSIC/.links"
if test "$1" = "-r"
then shift
@ -16,7 +22,7 @@ then shift
do
matchname="$(basename -- "$arg" | sed 's|\(\[.*\)\]|\\\1\\]|;s|\?|\\?|')"
filepath="$({ find "$(dirname -- "$arg")" -maxdepth 1 -name "$matchname" -exec realpath {} + ||
find "$(dirname -- "$arg")" "$MUSIC/$(dirname -- "$arg")" "$MUSIC/Playlists/$(dirname -- "$arg")" -maxdepth 1 \
find "$(dirname -- "$arg")" "$MUSIC/$(dirname -- "$arg")" "$PLAYLISTS/$(dirname -- "$arg")" -maxdepth 1 \
-name "$matchname*" -exec realpath {} +; } 2>/dev/null)"
test -n "$verbose" && echo "Scanning path '$filepath' $(
test "$arg" != "$filepath" && echo "from '$arg' ")(MUSIC: '$MUSIC', PWD: '$PWD')" >&2

View file

@ -1,7 +1,7 @@
#!/bin/sh -e
# Reload mpd with appropriate config
yadm alt
cd $XDG_CONFIG_HOME/mpd
cd ${XDG_CONFIG_HOME:-/home/janek/.config}/mpd
mv *template ..
mv ../*template .
systemctl --user restart mpd

View file

@ -1,5 +1,8 @@
#!/bin/sh -e
# MPC add file to queue
# Add file to mpd queue
if test $# -eq 0
then mpc --format "%album% %track% > %artist% - %title% (%genre% aus %date%)" current
fi
for arg
do fullpath=$(realpath "$arg")
mpc insert "${fullpath/$MUSIC\//}"

View file

@ -1,3 +1,6 @@
#!/bin/sh -e
# Toggle NordVPN
nordvpn status | grep --color=never Disconnected && nordvpn connect de || nordvpn disconnect; nordvpn status
if test $# -gt 0
then nordvpn connect "$@"
else nordvpn status | grep --color=never Disconnected && nordvpn connect de || nordvpn disconnect; nordvpn status
fi

View file

@ -5,6 +5,7 @@
test $# -gt 0 && command=$1 && shift
test "$1" = '-v' && verbose='true' && shift || verbose='false'
! test -d "$MUSIC" && echo "No music directory!" && exit 1
playlists="$MUSIC/playlists"
case $command in
(update)
for pl; do
@ -19,7 +20,18 @@ case $command in
done | tee $pl
echo "Backup of $pl saved to $bak" >&2
done;;
(edit) ${EDITOR:-nano} $(find $MUSIC/Playlists -iname "$1\.*" | grep . || find $MUSIC/Playlists -iname "$1*");;
(edit) ${EDITOR:-nano} $(find "$playlists" -iname "$1\.*" | grep . || find "$playlists" -iname "$1*");;
(add) # Add current mpc song or given songs to playlist
pl=$1
shift
playlist="$playlists/$pl"*
test -e "$playlist" || { playlist="$playlists/$pl.m3u8" && touch "$playlist"; }
if test $# -gt 0
then realpath --relative-to $playlists "$@"
else mpc current -f "../%file%"
fi | tee -a $playlist
echo "...added to $playlist"
;;
(make)
if test $1 = d
then shift && i=1; while test $i -le ${1:-9}; do $0 make "${2:-Ω}$i" "empty$i"; ((i++)); done

View file

@ -1,6 +1,8 @@
#!/bin/sh -e
# Remove recursively safely
case "$1" in ([0-9]) depth=$1; shift;; esac
if test "$1" == "--"; then shift; fi
for f in "${@:-$PWD}"
do
test -w "$(dirname "$f")" && elevate="" || elevate=sudo
@ -15,7 +17,7 @@ do
fi
# Clean empty files
$elevate find -name '.thumbnails' -printf 'Pre-cleaning %p\n' -exec rm -r {} +
$elevate find "$f" -name '.thumbnails' -printf 'Pre-cleaning %p\n' -exec rm -r {} +
$elevate find -H "$f" -maxdepth $(expr 1 \& "$f" = "/" \| 5 \& $# \> 0 \| 3) \
\( -name '.stfolder' -o -name '.*keep' -o -name '*.py' -o -name 'nodelay.txt' -o -name '.git' -o -name 'tmp' -o -name '.nomedia' -o -name '__init__.py' -o -name '*ignore' -o -name 'instalee' \) \
\( -type d -o -type f \) -prune -o -empty -printf 'Removing empty %p\n' -exec rm -d {} +

View file

@ -1,7 +1,6 @@
#!/bin/sh
#!/bin/sh -e
# Recursively add replaygain to the given files or from the current directory
#rsgain custom --album --skip-existing --tagmode=i "${@:-${MUSIC:-.}}"
beet replaygain -a -t 4 -w ||
r128gain $(test -f "$1" || echo '--recursive') --skip-tagged --preserve-times 1 "${@:-.}"
nice -n 8 rsgain easy --skip-existing --multithread=${SPARE_CORES:-3} "${@:-.}"
#test $# -eq 0 && nice -n 8 beet replaygain --album --threads=${SPARE_CORES:-3} --write "$@"
# Need a find command, call for each album
# rsgain easy --skip-existing --multithread=${SPARE_CORES:-3} "${@:-.}"
#rsgain custom --album --skip-existing --tagmode=i "${@:-${MUSIC:-.}}"

View file

@ -4,6 +4,7 @@
export chars=$(expr $(tput cols) - 60)
case "$1" in (+*) size=${1#+}G; depth=2; shift;; esac
case "$1" in ([0-9]) depth=$1; shift;; esac
(du --max-depth "${depth:-1}" -xhat ${size:-50M} "$@" | sort -h | grep -v "^0") |
du="du --max-depth '${depth:-1}' -xha"
($du -t ${size:-50M} "$@" | sort -h | grep -v "^0") |
while read line; do echo "$(tput smso)$line$(tput rmso) $(pacman -Qqo $(echo $line | awk '{print $2}') 2>/dev/null | paste -s -d',' | sed "s/\(.\{${chars}\}\).*/\1.../")"; done || #| column -t ||
(du --max-depth "${depth:-1}" -xha "$@" | sort -h | tail)
($du "$@" | sort -h | tail)

View file

@ -1,5 +1,7 @@
#!/bin/sh -e
# Put system to sleep after specified number of seconds
# If used in a pipe, put a command into /tmp/save to override
mpc pause || mpdr
$(which timer || sleep) "${@:-30}"
systemctl suspend
# TODO delay in case I happen to still be on PC - use idle?
$(cat /tmp/save 2>/dev/null) || systemctl suspend

View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/sh -ex
# Force Sway Scaling
shift=1
scale=1

View file

@ -10,8 +10,8 @@ case "$1" in
sudo mkdir -p /etc/yadm
sudo chown -R $USER /etc/yadm
sysyadm clone -w / gitea@git.jfischer.org:xeruf/etc.git --bootstrap;;
(init) sudo -E sysyadm init -b main -w /;;
(*) sudo -E sysyadm "$@";;
(init) sudo "$(which sysyadm)" init -b main -w /;;
(*) sudo --preserve-env=PATH,XDG_CONFIG_HOME "$(which sysyadm)" "$@";;
esac
#sudo chmod +rw /tmp/git -R 2>/dev/null
sudo chown -R $USER /etc/yadm

View file

@ -1,5 +1,5 @@
#!/bin/sh -e
# Type in NoVNC - from clipboard or interactively with german layout
# Type in NoVNC with X tools - from clipboard or interactively with german layout
xdotool search --onlyvisible --classname Navigator windowactivate # Activate Firefox
if test $# -gt 0
then

View file

@ -1,7 +1,8 @@
#!/bin/sh
temp=$(mktemp)
#temp=$(mktemp)
target=$(pass app/voidcat)
for arg; do
extension=$(echo "$arg" | sed 's/.*\.//')
echo "Uploading $arg"
{ curl --progress-bar -X POST \
-H "V-Content-Type: $(file --mime-type -b $1)" \
@ -9,6 +10,6 @@ echo "Uploading $arg"
-H "V-Filename: $arg" \
-H "Authorization: Bearer $(echo "$target" | head -1)" \
--data-binary @$arg \
$(echo "$target" | tail -1); echo; } | tee -a $temp
$(echo "$target" | tail -1); echo; } | sed "s/\$/.$extension/"
done
test $# -gt 1 && echo && cat $temp | sed 's|http:|https:|'
#test $# -gt 1 && echo && #sed 's|http:|https:|' "$temp"

View file

@ -1,3 +1,29 @@
#!/bin/sh -e
test -f "$1" || cd "$XDG_DATA_HOME/openvpn"
tmux new-session -s "$@" "sudo openvpn $@ || read"
case "$1" in
("") tmux new-session -s "vpn" "tmux ls; $SHELL";;
(forti)
if ip route | grep -q ppp0
then echo "Device ppp0 already in use!"
else sudo tmux new-session -s "$1" '
set -x
route="$(ip route | grep default | sort | head -1)"
# Start openfortivpn in the background
openfortivpn &
VPN_PID=$!
# Wait a little for the VPN to establish the connection
sleep 5
# TODO Loop
# Delete the default route set by openfortivpn (ppp0)
ip route del default dev ppp0
# Add the default route via the local network
eval "ip route add $route"
ip route add 134.245.0.0/16 dev ppp0;
ip route
wait $VPN_PID
echo "VPN has disconnected."
'
fi
;;
(*) tmux new-session -s "$@" "sudo openvpn $@ || read";;
esac

View file

@ -1,5 +1,5 @@
#!/bin/sh -e
# Save wl clipboard image with last copied url
file="$(date +%y%m%d-%H%M%S)_$(cliphist list | grep https:// | head -1 | rev | cut -d/ -f1 | rev).png"
file="$(date +%y%m%d-%H%M%S)_$(cliphist list | grep --max-count 1 https:// | sed 's|/$||' | rev | cut -d/ -f1 | rev).png"
wl-paste >"$file"
b "$file"