diff options
-rwxr-xr-x | alarm | 11 | ||||
-rwxr-xr-x | backlight | 23 | ||||
-rwxr-xr-x | bell | 7 | ||||
-rwxr-xr-x | ccgsl | 7 | ||||
-rwxr-xr-x | cfg | 29 | ||||
-rwxr-xr-x | chmodef | 6 | ||||
-rwxr-xr-x | curlqb | 27 | ||||
-rwxr-xr-x | dateft | 29 | ||||
-rwxr-xr-x | dirnameall | 19 | ||||
-rwxr-xr-x | gita | 17 | ||||
-rwxr-xr-x | gitfork | 10 | ||||
-rwxr-xr-x | gitmetap | 17 | ||||
-rwxr-xr-x | gitmetar | 7 | ||||
-rwxr-xr-x | gitpu | 19 | ||||
-rwxr-xr-x | grrc | 4 | ||||
-rwxr-xr-x | il | 6 | ||||
-rwxr-xr-x | lastarg | 5 | ||||
-rwxr-xr-x | loop | 15 | ||||
-rwxr-xr-x | lsp | 3 | ||||
-rwxr-xr-x | mll | 6 | ||||
-rwxr-xr-x | mmi | 27 | ||||
-rwxr-xr-x | mpra | 44 | ||||
-rwxr-xr-x | mpva | 17 | ||||
-rwxr-xr-x | mpvy | 44 | ||||
-rwxr-xr-x | mvln | 27 | ||||
-rwxr-xr-x | mvtr | 11 | ||||
-rwxr-xr-x | mvtu | 13 | ||||
-rwxr-xr-x | news | 31 | ||||
-rwxr-xr-x | o | 27 | ||||
-rwxr-xr-x | orgext | 18 | ||||
-rwxr-xr-x | pa | 8 | ||||
-rwxr-xr-x | pq | 13 | ||||
-rwxr-xr-x | px | 10 | ||||
-rwxr-xr-x | qg | 15 | ||||
-rwxr-xr-x | qw | 16 | ||||
-rwxr-xr-x | rate | 11 | ||||
-rwxr-xr-x | reco | 28 | ||||
-rwxr-xr-x | rfp | 11 | ||||
-rwxr-xr-x | sbar | 77 | ||||
-rwxr-xr-x | ta | 5 | ||||
-rwxr-xr-x | time-uuid | 6 | ||||
-rwxr-xr-x | topa | 8 | ||||
-rwxr-xr-x | vinfo | 4 | ||||
-rwxr-xr-x | wh | 11 | ||||
-rwxr-xr-x | wtr | 43 | ||||
-rwxr-xr-x | xmq | 3 |
46 files changed, 795 insertions, 0 deletions
@@ -0,0 +1,11 @@ +#!/bin/sh + +min="$1" +[ "$1" ] && shift +printf "notify-send -u critical %s; bell" "$(/usr/bin/printf '%q ' "${@:-alarm}")" | at now + "${min:-0}" minutes && [ "$min" ] && [ "$min" -ne 0 ] && notify-send "Successfully Scheduled" + +# at used to not like string like 'Boiling Water!', don't know why now it works, if see similar issue, use folllowing codes +#at now + "$1" minutes << EOF && notify-send 'Successfully Scheduled' +#notify-send -u critical "${2:-alarm}" +#bell +#EOF diff --git a/backlight b/backlight new file mode 100755 index 0000000..3de87f5 --- /dev/null +++ b/backlight @@ -0,0 +1,23 @@ +#!/bin/sh + +brightness=$(cat /sys/class/backlight/intel_backlight/brightness) +max_brightness=$(cat /sys/class/backlight/intel_backlight/max_brightness) +step=$((max_brightness/20)) + +case "$1" in + '-u') + case "$brightness" in + 0) echo 1;; + 1) echo "$step";; + *) echo "$((brightness+step))";; + esac + ;; + '-d') + case "$brightness" in + 1) echo 0;; + "$step") echo 1;; + *) echo "$((brightness-step))";; + esac + ;; + *) exit 1;; +esac > /sys/class/backlight/intel_backlight/brightness @@ -0,0 +1,7 @@ +#!/bin/sh + +bef="$(amixer get Master | awk -F '[][]' 'END{print $2}')" +amixer set Master 10% +# code steal from https://unix.stackexchange.com/a/163716/459013 +speaker-test -t sine -f 1000 -l 1 +amixer set Master "$bef" @@ -0,0 +1,7 @@ +#!/bin/sh +# steal codes from https://github.com/LukeSmithxyz/voidrice/blob/master/.local/bin/compiler + +base="${1%.*}" +# -lm link math library? needed for sqrt(). not sure +# https://stackoverflow.com/questions/44175151/what-is-the-meaning-of-lm-in-gcc +cc -Wall -lgsl -lgslcblas -lm -o "$base" "$1" && ./"$base" @@ -0,0 +1,29 @@ +#!/bin/sh + +umask 077 +while getopts lsmM opt; do + case $opt in + #c) + # work_tree_dir="$HOME" + # meta_file="$XDG_CONFIG_HOME/myconf/cfg${opt}_meta" + # cmd="git --git-dir=$HOME/.cfg$opt/ --work-tree=$HOME" + # ;; + l|s) + work_tree_dir=/ + meta_file="/etc/myconf/cfg${opt}_meta" + cmd="sudo -E git --git-dir=/etc/.cfg$opt/ --work-tree=/" + ;; + m) + sudo gitmetap "$cmd" "$work_tree_dir" "$meta_file" + $cmd diff + exit + ;; + M) + sudo gitmetar "$meta_file" + exit + ;; + \?) exit 1;; + esac +done +shift $((OPTIND-1)) +$cmd "$@" @@ -0,0 +1,6 @@ +#!/bin/sh +# chmodef: CHMOD DEFault + +# https://wiki.archlinux.org/title/File_permissions_and_attributes#Numeric_method +find "$@" -type d -execdir chmod 755 -- '{}' \+ +find "$@" -type f -execdir chmod 644 -- '{}' \+ @@ -0,0 +1,27 @@ +#!/bin/sh + +# need --no-clobber if don't want overwrite when same name +# if do this also need change .py.1 to .py else qbt will not accept +# also if a.py and a_1.py, qbt will not accept the latter, maybe need to change some .py codes inside +# now, I choose to let three files to be overwrited, those are "with categories" .py files that overwrite without categories .py files, which is what I want so I don't use --no-clobber +curl -s 'https://github.com/qbittorrent/search-plugins/wiki/Unofficial-search-plugins' | awk -F'"' ' +/user-content-plugins-for-private-sites/ {exit} +/\.py/ { + url=$2 + getline + getline + getline + if($0 !~ /❗|✖/) + print url +} +' | xargs curl -s -Z -L --remote-name-all --create-dirs --output-dir "$1" -- + +# an alternative awk command: +#awk -F'"' ' +#/require an account/ {exit} +#/\.py/ { +# url=$2 +# line=NR +#} +#url && NR==line+3 && !/❗|✖/ {print url} +#' @@ -0,0 +1,29 @@ +#!/bin/sh +# DATE From To + +while getopts cfF:t:T: opt; do + case $opt in + c) tz_from="Asia/Shanghai";; + f) tz_from="$(tzselect)";; + F) tz_from="$OPTARG";; + # one extra ',' at the end will not let `for tz in ...` loop one extra time? + t) for i in $(seq "$OPTARG"); do + tz_to="$(tzselect),$tz_to" + done;; + T) tz_to="$OPTARG,$tz_to";; + \?) exit 1;; + esac +done +shift $((OPTIND-1)) + +time_from="TZ=\"${tz_from:-$(readlink /etc/localtime | sed 's#.*/\(.*/.*\)$#\1#')}\" ${1:-now}" + +date -d "$time_from" +TZ="Asia/Shanghai" date -d "$time_from" +date -d "$time_from" -u +date -d "$time_from" +%s +[ "$tz_from" ] && [ "$tz_from" != "Asia/Shanghai" ] && TZ="$tz_from" date -d "$time_from" +IFS=',' +for tz in $tz_to; do + TZ="$tz" date -d "$time_from" +done diff --git a/dirnameall b/dirnameall new file mode 100755 index 0000000..befd347 --- /dev/null +++ b/dirnameall @@ -0,0 +1,19 @@ +#!/bin/sh + +while read -r line; do + if [ "$paths" ]; then + paths="$paths +$line" + else + paths="$line" + fi +done + +dirs="$paths" +while [ "$dirs" != '.' ]; do + [ "$dirs" ] && paths="$paths +$dirs" + dirs="$(echo "$dirs" | tr '\n' '\0' | xargs -0 dirname | awk '!a[$0]++')" +done + +echo "$paths" | awk '!a[$0]++' | grep -v '^\.$' @@ -0,0 +1,17 @@ +#!/bin/sh +# note message string must come after options + +cmd=git + +while getopts ls f; do + case $f in + l|s) cmd="cfg -$f";; + \?) exit 1;; + esac +done +shift $((OPTIND-1)) + +mes="${1:-update}" + +$cmd commit --all -m "$mes" +$cmd push @@ -0,0 +1,10 @@ +#!/bin/sh + +git clone "$1" +cd "$(basename "$1" .git)" || exit +git remote add upstream "$2" +if ! git checkout fly; then + git branch fly + git checkout fly + git push --set-upstream origin fly +fi diff --git a/gitmetap b/gitmetap new file mode 100755 index 0000000..c058986 --- /dev/null +++ b/gitmetap @@ -0,0 +1,17 @@ +#!/bin/sh +# GIT META Print + +# -rw-r--r-- == binary 110100100 == octal 644 +# https://stackoverflow.com/a/1796009 +$1 ls-tree -r --name-only --full-tree HEAD | dirnameall | awk -v a="$2/" '{printf("%s%s\n",a,$0)}' | tr '\n' '\0' | xargs -0 ls -ldA -- | awk '{ + k=0 + for(i=0;i<=8;i++) + k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i)) + if(k) { + for(i=10;$i && $i!="->";i++) + $9=$9" "$i + printf("%0o %s %s %s\n",k,$3,$4,$9) + } +}' > "$3" + +#$1 ls-tree -r --name-only --full-tree HEAD | awk -v a="$2/" '{printf("%s%s\n",a,$0)}' | tr '\n' '\0' | xargs -0 ls -ldA -- | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k){for(i=10;$i && $i!="->";i++)$9=$9" "$i;printf("%0o %s %s %s\n",k,$3,$4,$9)}}' > "$3" diff --git a/gitmetar b/gitmetar new file mode 100755 index 0000000..1bfdc15 --- /dev/null +++ b/gitmetar @@ -0,0 +1,7 @@ +#!/bin/sh +# GIT META Read + +while read -r mod user group path; do + chown -hc "$user:$group" -- "$path" + [ "$mod" -ne 777 ] && chmod -c "$mod" -- "$path" +done < "$1" @@ -0,0 +1,19 @@ +#!/bin/sh + +if [ -z "$1" ]; then + git checkout master + git pull upstream master + git push + git checkout fly + git merge --no-edit master + git push +else + for dir; do + git -C "$dir" checkout master + git -C "$dir" pull upstream master + git -C "$dir" push + git -C "$dir" checkout fly + git -C "$dir" merge --no-edit master + git -C "$dir" push + done +fi @@ -0,0 +1,4 @@ +#!/bin/sh +# GRep -R Code + +[ "$1" ] && find "$HOME/archive/programs/public_archive_codes" "$HOME/archive/programs/private_archive_codes" "$HOME/archive/programs/me106_proj_fall2021" "$HOME/archive/programs/car_job/av_dev" "$HOME/archive/programs/VisualDimension" "$XDG_DOCUMENTS_DIR/notes" -mindepth 1 -maxdepth 1 -path "*/\.git" -prune -o -type d -print0 2>/dev/null | xargs -0 grep -s --color=always -iIR "$@" "$HOME/.local/bin" "$HOME/.bashrc" "$HOME/.profile" "$HOME/.xinitrc" "$HOME/programs/suckless/dwm_fly/config.def.h" "$XDG_CONFIG_HOME/nsxiv/exec/key-handler" | "$PAGER" @@ -0,0 +1,6 @@ +#!/bin/sh +# InterpoLation + +# x=$1, xa=$2, xb=$3, ya=$4, yb=$5 +# https://en.wikipedia.org/wiki/Interpolation#Linear_interpolation +echo "scale=4;$4+($5-$4)*($1-$2)/($3-$2)" | bc @@ -0,0 +1,5 @@ +#!/bin/sh +# usage: lastarg "$@" + +shift $(($# - 1)) +echo "$1" @@ -0,0 +1,15 @@ +#!/bin/sh + +while getopts t: opt; do + case $opt in + t) time="$OPTARG";; + \?) exit 1;; + esac +done +shift $((OPTIND-1)) + +while :; do + # suggested by https://github.com/koalaman/shellcheck/wiki/SC2294 + "$@" + sleep "${time:-1}" +done @@ -0,0 +1,3 @@ +#!/bin/sh + +loop ssh "${1:-pp}" @@ -0,0 +1,6 @@ +#!/bin/sh +# Map Latitude Longitude + +# https://help.openstreetmap.org/questions/9669/jumping-to-a-specific-set-of-coordinates-on-the-map +# another way is to manually search xx.xxxxx,xx.xxxxx +o "$BROWSER" "https://www.openstreetmap.org/?mlat=$1&mlon=$2&zoom=5" @@ -0,0 +1,27 @@ +#!/bin/sh + +mi () { + make + sudo make install +} + +origin="$PWD" +cmd='mi' + +while getopts q opt; do + case $opt in + q) cmd='qmake6;mi';; + \?) exit 1;; + esac +done +shift $((OPTIND-1)) + +if [ -z "$1" ]; then + eval "$cmd" +else + for dir; do + cd "$dir" || exit + eval "$cmd" + cd "$origin" || exit + done +fi @@ -0,0 +1,44 @@ +#!/bin/sh +# MakePkg Repo-Add + +fn () { + if ! { [ -f PKGBUILD ] || [ -h PKGBUILD ];}; then + exit + fi + find . -maxdepth 1 -type f -name "*.pkg.tar.$ext*" -delete + makepkg --sign -sf + newpkg="$(find . -maxdepth 1 -type f -name "*.pkg.tar.$ext")" + [ -d ../repo ] || mkdir ../repo + mv "$newpkg" "$newpkg.sig" ../repo + # need manually repo-add new database for first time initialization + repo-add -s -v -R "$(find ../repo -maxdepth 1 -type f -name '*.db.tar.gz')" "../repo/$newpkg" + # seems no need to delete *.old and *.old.sig, see https://mirror.fcix.net/archlinux/core/os/x86_64/ it do include *.old + #find ../repo -maxdepth 1 -type f \( -name '*.old' -o -name '*.old.sig' \) -delete +} + +ext=zst +copy_any= + +while getopts ac opt; do + case $opt in + # arch linux arm still using .xz instead of .zst as package compression format + a) ext=xz;; + # copy arch linux fly-any repo + c) copy_any=1;; + \?) exit 1;; + esac +done +shift $((OPTIND-1)) + +if [ $# -eq 0 ]; then + fn +else + for dir; do + cd -- "$(realpath -- "$dir")" || exit + fn + done +fi + +[ "$copy_any" ] && sudo rsync -vPrlt --delete ../repo/ /srv/http/mirrors/archlinux/fly/os/any + +upd -p @@ -0,0 +1,17 @@ +#!/bin/sh +# MPV Audio + +# fzf has --read0, maybe useful +# use --loop-file for single file, better performance maybe +# fzf --scheme=path for better fzf result when searching path, like the old time: +# https://github.com/junegunn/fzf/commit/6fb41a202a97ad3f2437f6e5aee8890268560412 + +if [ $# -eq 0 ]; then + find "$XDG_MUSIC_DIR" | fzf -m --print0 --scheme=path +fi | xargs -0 sh -c ' +if [ $# -eq 1 ] && ! [ -d "$1" ]; then + mpv --af= --loop-file=inf --video=no "$1" +else + mpv --af= --shuffle --loop-playlist=inf --video=no "$@" +fi +' shell "$@" @@ -0,0 +1,44 @@ +#!/bin/sh +# MPV Yank/Youtube videos +# references: +# https://www.rockyourcode.com/til-how-to-watch-youtube-videos-with-mpv-and-keyboard-shortcuts/ + +fps=30 +height=$SCR_HEIGHT +url="$(xsel -ob)" +flag=s + +# option f and h may do nothing if redownload? since same filename exist. yt-dlp won't download same file even without --auto-file-renameing=false. how improve? pass argument to aria2c? +while getopts Aabd:f:h:su: opt; do + case $opt in + # s: streaming, a: aria2c then mpv, A: aria2c + A|a|s) flag=$opt;; + b) format='bestvideo+bestaudio/best';; + d) download_dir="$OPTARG";; + f) fps="$OPTARG";; + h) height="$OPTARG";; + u) url="$OPTARG";; + \?) exit 1;; + esac +done +if [ -z "$format" ]; then + #vformat="[height<=?$height][fps<=?$fps][vcodec!^=?vp9][vcodec!^=?av01]" + vformat="[height<=?$height][fps<=?$fps][vcodec!^=?av01]" + # usually get .mp4 video + .webm audio on youtube, yt-dlp needs to merge them to .mkv + # it used to cause problem, but I forget + format="bestvideo$vformat+bestaudio/best$vformat" +fi + +case $flag in + # here if use --write-sub, mpv doesn't recognize subtitles? + # --embed-subs is a little bit better, but still worse then direct streaming + # --sponsorblock-remove will make audio/video goes out of sync, need --force-keyframes-at-cuts which need re-encode which is slow, more see comments at the bottom of https://github.com/yt-dlp/yt-dlp/issues/871 + # another way is using mpv-sponsorblock-minimal-git for streaming and sponsorblock-mpv-local for local videos + A) yt-dlp -f "$format" --embed-subs -P "${download_dir:-"$XDG_DOWNLOAD_DIR/mpvy/"}" --sponsorblock-remove default --sponsorblock-mark default "$url";; + a) yt-dlp -f "$format" --embed-subs -P "${download_dir:-"$XDG_DOWNLOAD_DIR/mpvy/"}" --sponsorblock-remove default --sponsorblock-mark default "$url" --exec 'mpv --fs --speed=2';; + s) mpv --ytdl-format="$format" --ytdl-raw-options='write-sub=' --fs --speed=2 "$url";; +esac +# not sure if this is the best practice, but it seems working ;) +status=$? +[ $status -ne 0 ] && notify-send 'mpvy failed' +exit $status @@ -0,0 +1,27 @@ +#!/bin/sh +# edge cases give me headache + +lns () { + # prevent `mvln file1 file1` or `mvln dir1/file1 dir1/` + # which means `ln -s samename samename` or `ln -s dir/file dir/` + # both $1 and $2 here are realpath + [ "$1" != "$2" ] && ln -s -- "$1" "$2" +} + +mv -i -- "$@" +# consider `mvln file1 dir/file2` +if [ $# -eq 2 ] && ! [ -d "$2" ]; then + # use realpath here + lns "$(realpath "$2")" "$(realpath "$1")" +else + dir="$(realpath -- "$(lastarg "$@")")" + # steal from https://unix.stackexchange.com/a/353833/459013 + while [ $# -gt 1 ]; do + to="$(realpath -- "$1")" + # prevent `mvln dir1/ dir1/` + if [ "$dir" != "$to" ]; then + lns "$dir/$(basename "$1")" "$to" + fi + shift + done +fi @@ -0,0 +1,11 @@ +#!/bin/sh + +# can use ls pipe to sed pipe to bash, similar to eval? see comment at link: +# link also show perl-rename approach +# https://linuxconfig.org/rename-all-files-from-uppercase-to-lowercase-characters +# if only change ' ' to '_' `rename` might be sufficient, for upper to lower case might need perl-rename if want concise + +# ./_filename will be renamed ./filename, not what I want, need improve +# -exec can't replace -execdir here, can write a -exec version + +find "$@" -depth -execdir sh -c 'dest="$(echo "$1" | tr -d "\047" | sed -E -e "s/([[:lower:]])([[:upper:]])/\1_\2/g" | tr "[:upper:] " "[:lower:]_" | tr -s "[:punct:]" | sed -E -e "s#/-#/#g" -e "s/_([[:punct:]])/\1/g" -e "s/([[:punct:]])_/\1/g" | tr -s "[:punct:]")"; [ -e "$dest" ] || mv -v -- "$1" "$dest"' shell '{}' \; @@ -0,0 +1,13 @@ +#!/bin/sh +# MV Time-Uuid + +find "$@" -type f -execdir sh -c ' + file="$(basename "$1")" + ext="${file##*.}" + if [ "$ext" != "$file" ]; then + dest="$(time-uuid).$ext" + else + dest="$(time-uuid)" + fi + [ -e "dest" ] || mv -v -- "$1" "$dest" +' shell '{}' \; @@ -0,0 +1,31 @@ +#!/bin/sh + +daily () { + # mail.yahoo.com/d/folders/6 is spam folder + o "$BROWSER" https://github.com/notifications https://mail.google.com 'https://mail.google.com/mail/u/0/#spam' https://mail.yahoo.com https://mail.yahoo.com/d/folders/6 https://en.wikipedia.org/wiki/Portal:Current_events + # alacritty --hold must be before -e + # full window: -w156, am and pm in one line: -w114 + o alacritty --hold -e rem -cu+2 -@ -w114 + o alacritty --hold -e wtr + o alacritty -e newsboat + o alacritty --hold -e pass practice_password0 +} + +monthly () { + o "$BROWSER" https://smtp.cheogram.com/ http://download.huzheng.org + o alacritty --hold -e rate + # Show 3 months' remind. I use 3 months because it is better to know I20 deadline 3 months earlier so I have 2 months to prepare the money for extension. + # (2*31+30+6)/7=14. Consider month 1 day 1 is on Sunday and make sure month 3 day 31 is shown. Tested with `rem -cu+14 -@ -w114 2025-03-01` + o alacritty --hold -e sh -c 'rem -cu+14 -@ -w114 | $PAGER' +} + +if [ $# -eq 0 ]; then + daily +else + while getopts m opt; do + case $opt in + m) monthly;; + \?) exit 1;; + esac + done +fi @@ -0,0 +1,27 @@ +#!/bin/sh + +# useful links +# https://stackoverflow.com/questions/3430330/best-way-to-make-a-shell-script-daemon +# https://serverfault.com/questions/117152/do-background-processes-get-a-sighup-when-logging-off +# https://wiki.archlinux.org/title/default_applications + +# I don't care about errors, I don't want to handle errors, just shut up please. +# nohup seems not necessary if don't care about daemon SIGHUP requirement + +# when close a shell script's stdout or stderr with `>&-` or `2>&-`, `xsel -ib` in that script has no effect +# https://github.com/kfish/xsel/issues/43 +# using `>&-` or `2>&-` doesn't completely close mpv's output when run sth. like `o mpv file.mkv` +# base on above observations, I choose to use `>/dev/null 2>&1` instead + +# need ; before } when it is in the same line as { ? https://www.shellcheck.net/wiki/SC1056 + +if [ $# -eq 1 ] && [ -e "$1" ] && { ! [ -x "$1" ] || [ -d "$1" ];}; then + case "$1" in + # libreoffice, please don't let firefox eat your shit + *.docx|*.pptx) cmd=libreoffice;; + *) cmd=xdg-open;; + esac + nohup "$cmd" "$1" 0<&- >/dev/null 2>&1 & +else + nohup "$@" 0<&- >/dev/null 2>&1 & +fi @@ -0,0 +1,18 @@ +#!/bin/sh + +outdir () { + find . -type f -execdir mv -t "$PWD" -- '{}' \+ + find . -mindepth 1 -maxdepth 1 -type d -execdir rmdir -- '{}' \+ +} + +indir () { + # https://stackoverflow.com/questions/1842254/how-can-i-find-all-of-the-distinct-file-extensions-in-a-folder-hierarchy + find . -maxdepth 1 -type f | awk -F. '!a[$NF]++{print $NF}' | xargs mkdir -- + find . -mindepth 1 -maxdepth 1 -type d -execdir basename -az -- '{}' \+ | xargs -0 -I _ find . -maxdepth 1 -type f -name '*._' -execdir mv -t '_' -- '{}' \+ +} + +case "$1" in + '-o') outdir;; + '-i') indir;; + *) outdir; indir;; +esac @@ -0,0 +1,8 @@ +#!/bin/sh +# Ping Alarm + +while ! ping -w5 "$1"; do + sleep 5 +done +notify-send "$1 on" +bell @@ -0,0 +1,13 @@ +#!/bin/sh +# Pacman Query, to manually determine remove the package or not + +[ "$1" ] && { + #sed -n '/^Depends On/,/^Conflicts With/{/^Conflicts With/!p}; /^Description\|^URL\|^Groups\|^Installed Size\|^Install Reason/p' + pacman -Qi "$1" | awk '/^Groups/{f=1} /^Conflicts With/{f=0} f||/^Description|^URL|^Installed Size|^Install Reason/' + printf '\n' + pacman -Ql "$1" | grep '/bin/[^$]' + printf '\n' + pactree -r "$1" + printf '\n' + grrc "$1" +} | "$PAGER" @@ -0,0 +1,10 @@ +#!/bin/sh +# Printf Xsel + +if [ $# -eq 0 ]; then + /usr/bin/printf '%q' "$PWD" +else + for dir; do + /usr/bin/printf '%q ' "$(realpath -- "$dir")" + done +fi | xsel -ib @@ -0,0 +1,15 @@ +#!/bin/sh + +# more resources see comments in my script qw +# https://guix.gnu.org/manual/en/html_node/Running-Guix-in-a-VM.html +# `-enable-kvm` same as `-accel kvm`, see archwiki +qemu-system-x86_64 \ + -accel kvm \ + -cpu host \ + -device virtio-blk,drive=myhd \ + -display gtk,zoom-to-fit=on \ + -drive if=none,file="$XDG_DOWNLOAD_DIR/qemu/guix.img",format=qcow2,id=myhd \ + -m 8G \ + -nic user,model=virtio-net-pci,hostfwd=::53684-:22 \ + -smp 2,sockets=1,cores=1,threads=2 \ + -usb -device usb-tablet @@ -0,0 +1,16 @@ +#!/bin/sh + +# For better performance, it needs CPU-pinning with `taskset`, GPU pass-through, and other more tweaks +# https://github.com/cardi/qemu-windows-10 +# https://wiki.archlinux.org/title/QEMU +## https://wiki.archlinux.org/title/QEMU#Mouse_integration +# https://qemu-project.gitlab.io/qemu/system/devices/usb.html +qemu-system-x86_64 \ + -accel kvm \ + -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time \ + -display gtk,zoom-to-fit=on \ + -drive file="$XDG_DOWNLOAD_DIR/qemu/win10.img",format=qcow2 \ + -m 8G \ + -nic user,hostfwd=::53683-:22 \ + -smp 2,sockets=1,cores=1,threads=2 \ + -usb -device usb-tablet @@ -0,0 +1,11 @@ +#!/bin/sh + +while getopts f:t: opt; do + case $opt in + f) from="$OPTARG";; + t) to="$(echo "$OPTARG" | tr '[:lower:]' '[:upper:]')";; + \?) exit 1;; + esac +done +# https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates +curl -s "https://api.coinbase.com/v2/exchange-rates?currency=${from:-xmr}" | jq -r ".data.rates.${to:-USD}" @@ -0,0 +1,28 @@ +#!/bin/sh + +# useful urls: +# https://github.com/LukeSmithxyz/voidrice/blob/master/.local/bin/dmenurecord +# https://wiki.archlinux.org/title/FFmpeg#Screen_capture +# https://trac.ffmpeg.org/wiki/Capture/Desktop + +infofile="/tmp/recoinfo" +recodir="$XDG_VIDEOS_DIR/recordings/" +tmpdir="$recodir/tmp/" +mkdir -p "$recodir" "$tmpdir" + +if [ -e "$infofile" ]; then + read -r pid tmpfile < "$infofile" + kill "$pid" + notify-send 'finish recording, start converting' + ffmpeg -i "$tmpfile" "$recodir/$(time-uuid).mkv" + notify-send 'finish converting' + rm "$tmpfile" "$infofile" +else + tmpfile="$tmpdir/$(time-uuid).mkv" + notify-send 'prepare recording' + # arch wiki way, no audio, less cpu use during capturing (fast?), large file size, need convert afterward + xrectsel '%w %h %x %y' | xargs sh -c 'ffmpeg -y -loglevel quiet -f x11grab -framerate 25 -s "$2x$3" -i "$DISPLAY+$4,$5" -c:v ffvhuff "$1" & echo $!' shell "$tmpfile" | xargs -I {} printf '%s\t%s' '{}' "$tmpfile" > "$infofile" + # another way to get subshell ffmpeg child pid + #xrectsel '%w %h %x %y' | xargs sh -c 'ffmpeg -y -f x11grab -framerate 25 -s "$2x$3" -i "$DISPLAY+$4,$5" -c:v ffvhuff "$1"' shell "$tmpfile" & + #printf '%s\t%s' "$(ps -o pid= --ppid $!)" "$tmpfile" > "$infofile" +fi @@ -0,0 +1,11 @@ +#!/bin/sh + +if grep -q '^//user_pref("privacy.resistFingerprinting", false);$' "$HOME/.mozilla/firefox/xxxxxxxx.fly/user-overrides.js"; then + sed -i 's#^//\(user_pref("privacy.resistFingerprinting", false);\)$#\1#' "$HOME/.mozilla/firefox/xxxxxxxx.fly/user-overrides.js" + notify-send -u critical 'RFP disabled' +else + sed -i 's#^\(user_pref("privacy.resistFingerprinting", false);\)$#//\1#' "$HOME/.mozilla/firefox/xxxxxxxx.fly/user-overrides.js" + notify-send 'RFP enabled' +fi +upd -j +o "$BROWSER" @@ -0,0 +1,77 @@ +#!/bin/sh +# modified from pystardust, GPLv3 license: https://github.com/pystardust/sbar + +# INIT +sec=0 + +# MODULES +update_time () { + time="$(date '+%a %m/%d %H:%M') $(TZ=Asia/Shanghai date '+/%d %H:') $(date -u '+/%d %H:')" +} + +#update_cap () { +# cap="$(if xset q | grep -q "Caps Lock: *on"; then echo A; else echo a; fi)" +#} + +update_net () { + net="$(if nmcli -t --fields type,state device | grep -q '^\(ethernet\|wifi\):connected$'; then echo 1; else echo 0; fi)" + nm_device_state="$(nmcli -t --fields device,state device)" + vpn="$( + if echo "$nm_device_state" | grep -q '^wg_ka:connected$'; then + echo K + elif echo "$nm_device_state" | grep -q '^wg_studio:connected$'; then + echo S + else + echo 0 + fi + )" +} + +update_vol () { + # $(NF-1) for both alsa and pulseaudio + vol="$(amixer get Master | awk -F'[][]' 'END{printf("%d %s",($(NF-1)=="on")?1:0,$2)}')" +} + +update_mic () { + # $(NF-1) for both alsa and pulseaudio + mic="$(amixer get Capture | awk -F '[][]' 'END{print ($(NF-1)=="on")?1:0}')" +} + +update_bat () { + bat="$(cat /sys/class/power_supply/BAT0/capacity)%" +} + +update_gpu () { + gpu="$(envycontrol -q | awk 'END{print toupper(substr($NF,0,1))}')" +} + +display () { + xsetroot -name "$time | N $net V $vpn | M $vol C $mic | $gpu | $bat" +} + +# modules that don't update on their own need to be run at the start for getting their initial value +update_net +update_vol +update_mic +update_gpu + +# SIGNALLING +# trap "<function>;display" "RTMIN+n" +trap "update_mic;display" "RTMIN" +trap "update_vol;display" "RTMIN+1" +# xev can't read my toggle internet keyboard key, don't know what key to use in sxhkd to send signal +trap "update_net;display" "RTMIN+2" +# to update it from external commands +## kill -m $(pidof -x sbar) +# where m = 34 + n + +while :; do + sleep 1 & + wait + [ $((sec % 5 )) -eq 0 ] && update_time # update time every 5 seconds + [ $((sec % 60)) -eq 0 ] && update_net + [ $((sec % 60)) -eq 0 ] && update_bat + # how often the display updates ( 5 seconds ) + [ $((sec % 5 )) -eq 0 ] && display + sec=$((sec + 1)) +done @@ -0,0 +1,5 @@ +#!/bin/sh +# TIme Alarm + +time -p "$@" +o alarm 0 'Command Finished' "$(/usr/bin/printf '%q ' "$@")" diff --git a/time-uuid b/time-uuid new file mode 100755 index 0000000..bdaf4b3 --- /dev/null +++ b/time-uuid @@ -0,0 +1,6 @@ +#!/bin/sh + +# echo current nanosecond since epoch and alpha-numerically ordered UUID +# https://stackoverflow.com/questions/28681650/generate-alpha-numerically-ordered-uuids-over-time?noredirect=1&lq=1 +# https://askubuntu.com/questions/342842/what-does-this-command-mean-awk-f-print-4 +echo "$(date '+%s-%N')-$(uuidgen -t | awk -F- '{OFS="-"; print $3,$2,$1,$4,$5}')" @@ -0,0 +1,8 @@ +#!/bin/sh + +o alacritty -e htop +#o alacritty -e radeontop -c +o alacritty -e iotop +o alacritty -e nethogs +o alacritty -e intel_gpu_top +o alacritty -e nvtop @@ -0,0 +1,4 @@ +#!/bin/sh + +# steal from https://github.com/HiPhish/info.vim +"$EDITOR" -RM +"Info $1 $2" +only @@ -0,0 +1,11 @@ +#!/bin/sh + +# blue, see `man terminfo` +setaf="$(tput setaf 4)" +sgr0="$(tput sgr0)" + +# dash `command -V "$@"` will only output first command's type, same as `type`, but different than posix specification? so not use here +for cmd in type whatis whereis which "pacman -Qo --color always"; do + printf '\n%s\n%s\n' "$setaf$cmd $*$sgr0" "$($cmd "$@" 2>&1)" + #printf '\n\033[0;34m%s\033[0m\n%s\n' "$setaf$cmd $*$sgr0" "$($cmd "$@" 2>&1)" +done | "$PAGER" @@ -0,0 +1,43 @@ +#!/bin/sh + +# https://github.com/open-meteo/open-meteo +i=0 +curl -s -G -d "latitude=${1:-37.34}" -d "longitude=${2:--121.89}" -d 'daily=weathercode,temperature_2m_max,temperature_2m_min,sunrise,sunset' -d 'timezone=auto' 'https://api.open-meteo.com/v1/forecast' | jq -r '[.daily|.time, .weathercode, .temperature_2m_max, .temperature_2m_min, .sunrise, .sunset]|transpose|.[]|@tsv' | while read -r time code max min sunrise sunset; do + # https://open-meteo.com/en/docs + case "$code" in + 0) code='clear sky';; + 1) code='mainly clear';; + 2) code='partly cloudy';; + 3) code=overcast;; + 45) code=fog;; + 48) code='depositing rime fog';; + 51) code='light drizzle';; + 53) code='moderate drizzle';; + 55) code='dense drizzle';; + 56) code='light freezing drizzle';; + 57) code='dense freezing drizzle';; + 61) code='slight rain';; + 63) code='moderate rain';; + 65) code='heavy rain';; + 66) code='light freeze rain';; + 67) code='heavy freeze rain';; + 71) code='slight snow fall';; + 73) code='moderate snow fall';; + 75) code='heavy snow fall';; + 77) code='snow grains';; + 80) code='slight rain showers';; + 81) code='moderate rain showers';; + 82) code='violent rain showers';; + 85) code='slight snow showers';; + 86) code='heavy snow showers';; + 95) code='slight or moderate thunderstorm';; + 96) code='thunderstorm with slight hail';; + 99) code='thunderstorm with heavy hail';; + *) exit 1;; + esac + if [ "$i" -ne 1 ]; then + printf 'sunrise: %s | sunset: %s\n' "${sunrise#*T}" "${sunset#*T}" + i=1 + fi + printf '%s\t%s\t%s\t%s\n' "${time#*-}" "$max" "$min" "$code" +done @@ -0,0 +1,3 @@ +#!/bin/sh + +xdg-mime query filetype "$1" | tee /dev/tty | xargs xdg-mime query default |