X-Git-Url: https://git.xandkar.net/?a=blobdiff_plain;f=home%2Flib%2Flogin_functions.sh;h=51bc7f5afb485ec90e771bcc95f456ae1f1ebec4;hb=857e80acff709b05a4f4c2ade3911df7593c0ec8;hp=0f0ab7da8c6c41b083fa6d33debb3a67368c900d;hpb=d72bfd8f319a8f37d17e6fb50d3db5701bd94cc3;p=khome.git diff --git a/home/lib/login_functions.sh b/home/lib/login_functions.sh index 0f0ab7d..51bc7f5 100644 --- a/home/lib/login_functions.sh +++ b/home/lib/login_functions.sh @@ -7,7 +7,6 @@ d() { shell_activity_report() { # TODO: optional concrete number output - # TODO: manual weekday calc (since forking date is so expensive) # TODO: optional combinations of granularities: hour, weekday, month, year local group_by="$1" case "$group_by" in @@ -15,8 +14,8 @@ shell_activity_report() { 'dow') ;; '') group_by='dow';; *) - echo "Usage: $0 DIRECTORY [mon|dow]" >&2 - exit 1 + echo "Usage: $0 [mon|dow]" >&2 + kill -INT $$ esac history \ | awk -v group_by="$group_by" ' @@ -141,8 +140,8 @@ top_commands() { # TODO: Consider using numfmt instead of awk tdu() { du "$1" \ - | sort -n -k 1 -r \ - | head -50 \ + | sort -n -k 1 \ + | tail -50 \ | awk ' { size = $1 @@ -157,8 +156,8 @@ tdu() { # Top Disk-Using Files tduf() { find "$1" -type f -printf '%s\t%p\0' \ - | sort -z -n -k 1 -r \ - | head -z -n 50 \ + | sort -z -n -k 1 \ + | tail -z -n 50 \ | gawk -v RS='\0' ' { size = $1 @@ -207,17 +206,27 @@ void_pkgs() { # Colorful man man() { - LESS_TERMCAP_md=$'\e[01;31m' \ + # mb: begin blink + # md: begin bold + # me: end bold, blink and underline + # + # so: begin standout (reverse video) + # se: end standout + # + # us: begin underline + # ue: end underline + + LESS_TERMCAP_md=$'\e[01;30m' \ LESS_TERMCAP_me=$'\e[0m' \ - LESS_TERMCAP_se=$'\e[0m' \ LESS_TERMCAP_so=$'\e[01;44;33m' \ + LESS_TERMCAP_se=$'\e[0m' \ + LESS_TERMCAP_us=$'\e[01;33m' \ LESS_TERMCAP_ue=$'\e[0m' \ - LESS_TERMCAP_us=$'\e[01;32m' \ command man "$@" } experiment() { - cd "$(~/bin/experiment $@)" || exit 1 + cd "$(~/bin/experiment $@)" || kill -INT $$ } hump() { @@ -228,21 +237,29 @@ howto() { cat "$(find ~/Archives/Documents/HOWTOs -mindepth 1 -maxdepth 1 | sort | fzf)" } -yt() { - local _yt_uri - local _yt_id - local _yt_title - local _yt_dir +_yt() { + local -r base_dir="$1" + local -r opts="$2" + local -r uri="$3" + + local -r id=$(youtube-dlc --get-id "$uri") + local -r title=$(youtube-dlc --get-title "$uri" | sed 's/[^A-Za-z0-9._-]/_/g') + local -r dir="${base_dir}/${title}--${id}" - _yt_uri="$1" - _yt_id=$(youtube-dl --get-id "$_yt_uri") - _yt_title=$(youtube-dl --get-title "$_yt_uri") - _yt_dir="${DIR_YOUTUBE}/individual-videos/${_yt_title}--${_yt_id}" + mkdir -p "$dir" + cd "$dir" || kill -INT $$ + echo "$uri" > 'uri' + youtube-dlc $opts -c --write-description --write-info-json "$uri" +} + +yt_audio() { + local -r uri="$1" + _yt "${DIR_YOUTUBE_AUDIO}/individual" '-f 140' "$uri" +} - mkdir -p "$_yt_dir" - cd "$_yt_dir" || exit 1 - echo "$_yt_uri" > 'uri' - youtube-dl -c --write-description --write-info-json "$_yt_uri" +yt_video() { + local -r uri="$1" + _yt "${DIR_YOUTUBE_VIDEO}/individual" "$uri" } gh_fetch_repos() { @@ -250,11 +267,12 @@ gh_fetch_repos() { } gh_clone() { - gh_user_type="$1" - gh_user_name="$2" - gh_dir="${DIR_GITHUB}/${gh_user_name}" + local -r gh_user_type="$1" + local -r gh_user_name="$2" + + local -r gh_dir="${DIR_GITHUB}/${gh_user_name}" mkdir -p "$gh_dir" - cd "$gh_dir" || exit 1 + cd "$gh_dir" || kill -INT $$ gh_fetch_repos "$gh_user_type" "$gh_user_name" \ | jq --raw-output '.[] | select(.fork | not) | .git_url' \ | parallel -j 25 \ @@ -273,7 +291,7 @@ gh_clone_repo() { gh_username=$(echo "$1" | awk -F / '"$1 == "https" && $3 == github.com" {print $4}') gh_dir="${DIR_GITHUB}/${gh_username}" mkdir -p "$gh_dir" - cd "$gh_dir" || exit 1 + cd "$gh_dir" || kill -INT $$ git clone "$1" } @@ -285,9 +303,11 @@ $(date '+%F %A') Morning report -------------- -### Previous +### Prev -### Current +### Curr + +### Next ### Blockers @@ -298,7 +318,7 @@ EOF work_log() { mkdir -p "$DIR_WORK_LOG" - file_work_log_today="${DIR_WORK_LOG}/$(date +%F).md" + local -r file_work_log_today="${DIR_WORK_LOG}/$(date +%F).md" if [ ! -f "$file_work_log_today" ] then work_log_template > "$file_work_log_today" @@ -313,7 +333,12 @@ note() { } weather() { - curl "http://wttr.in/$WEATHER_LOCATION" + local _weather_location + case "$1" in + '') _weather_location="$WEATHER_LOCATION";; + *) _weather_location="$1" + esac + curl "http://wttr.in/$_weather_location?format=v2" } bt_devs_paired() { @@ -329,10 +354,12 @@ bt_devs() { } run() { - stderr="$(mktemp)" + local -r stderr="$(mktemp)" + + local code urgency + $@ 2> >(tee "$stderr") code="$?" - urgency='' case "$code" in 0) urgency='normal';; *) urgency='critical' @@ -340,3 +367,164 @@ run() { notify-send -u "$urgency" "Job done: $code" "$(cat $stderr)" rm "$stderr" } + +bar_gauge() { + local -r width="$1" + + awk -v width="$width" ' + { + cur = $1 + max = $2 + lab = $3 + + u = num_scale(cur, max, 1, width) + + printf "%s%s[", lab, lab ? " " : "" + for (i=1; i<=width; i++) { + c = i <= u ? "|" : "-" + printf "%s", c + } + printf "]\n" + } + + function num_scale(src_cur, src_max, dst_min, dst_max) { + return dst_min + ((src_cur * (dst_max - dst_min)) / src_max) + } + ' +} + +motd_batt() { + case "$(uname)" in + 'Linux') + upower --dump \ + | awk ' + /^Device:[ \t]+/ { + device["path"] = $2 + next + } + + / battery/ && device["path"] { + device["is_battery"] = 1 + next + } + + / percentage:/ && device["is_battery"] { + device["battery_percentage"] = $2 + sub("%$", "", device["battery_percentage"]) + next + } + + /^$/ { + if (device["is_battery"] && device["path"] == "/org/freedesktop/UPower/devices/DisplayDevice") + print device["battery_percentage"], 100, "batt" + delete device + } + ' + ;; + esac +} + +indent() { + awk -v unit="$1" '{printf "%s%s\n", unit, $0}' +} + +motd() { + local -r bar_width='60' + local -r indent_unit=' ' + + uname -srvmo + hostname | figlet + uptime + + echo + + printf 'tmux sessions: %d\n' "$(tmux ls 2> /dev/null | wc -l)" + + echo + + echo 'Resources' + ( + free | awk '$1 == "Mem:" {print $3, $2, "mem"}' + df ~ | awk 'NR == 2 {print $3, $3 + $4, "disk"}' + motd_batt + ) \ + | bar_gauge "$bar_width" \ + | column -t \ + | indent "$indent_unit" + + echo + + echo 'Network' + echo "${indent_unit}if" + (ifconfig; iwconfig) 2> /dev/null \ + | awk ' + /^[^ ]/ { + device = $1 + sub(":$", "", device) + if ($4 ~ "ESSID:") { + _essid = $4 + sub("^ESSID:\"", "", _essid) + sub("\"$", "", _essid) + essid[device] = _essid + } + next + } + + /^ / && $1 == "inet" { + address[device] = $2 + next + } + + /^ +Link Quality=[0-9]+\/[0-9]+ +Signal level=/ { + split($2, lq_parts_eq, "=") + split(lq_parts_eq[2], lq_parts_slash, "/") + cur = lq_parts_slash[1] + max = lq_parts_slash[2] + link[device] = cur / max * 100 + next + } + + END { + for (device in address) + if (device != "lo") { + l = link[device] + e = essid[device] + l = l ? sprintf("%.0f%%", l) : "--" + e = e ? e : "--" + print device, address[device], e, l + } + } + ' \ + | column -t \ + | indent "${indent_unit}${indent_unit}" + + # WARN: ensure: $USER ALL=(ALL) NOPASSWD:/bin/netstat + + echo "${indent_unit}-->" + + printf '%sUDP: ' "${indent_unit}${indent_unit}" + sudo -n netstat -ulnp \ + | awk 'NR > 2 {print $6}' \ + | awk -F/ '{print $2}' \ + | sort -u \ + | xargs \ + | column -t + + printf '%sTCP: ' "${indent_unit}${indent_unit}" + sudo -n netstat -tlnp \ + | awk 'NR > 2 {print $7}' \ + | awk -F/ '{print $2}' \ + | sort -u \ + | xargs \ + | column -t + + echo "${indent_unit}<->" + + printf '%sTCP: ' "${indent_unit}${indent_unit}" + sudo -n netstat -tnp \ + | awk 'NR > 2 && $6 == "ESTABLISHED" {print $7}' \ + | awk -F/ '{print $2}' \ + | sort -u \ + | xargs \ + | column -t +}