diff options
Diffstat (limited to 'ar/.local/bin/statusbar')
27 files changed, 1402 insertions, 0 deletions
diff --git a/ar/.local/bin/statusbar/sb-battery b/ar/.local/bin/statusbar/sb-battery new file mode 100755 index 0000000..faf3d04 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-battery @@ -0,0 +1,68 @@ +#!/bin/sh + +# Prints all batteries, their percentage remaining and an emoji corresponding +# to charge status (π for plugged up, π for discharging on battery, etc.). + +# Function to get the battery status icon +get_status_icon() { + case "$1" in + Full) echo "β‘" ;; + Discharging) echo "π" ;; + Charging) echo "π" ;; + "Not charging") echo "π" ;; + Unknown) echo "β»οΈ" ;; + *) echo "" ;; + esac +} + +# Function to print battery status +battery_status() { + device=$1 + capacity=$(cat "$device/capacity" 2>/dev/null) + status=$(cat "$device/status" 2>/dev/null) + icon=$(get_status_icon "$status") + [ -z "$icon" ] && return + case $(basename "$device") in + BAT?*) + [ "$icon" = "π" ] && [ "$capacity" -le 25 ] && warn="β" + printf "%s%s%d%%" "$icon" "$warn" "$capacity" + ;; + hid*) + model="$(cat "$device/model_name")" + notify-send "$icon $model:" "$capacity%" + ;; + esac + unset warn +} + +devices() { + for battery in /sys/class/power_supply/$1; do + battery_status "$battery" + done && printf "\\n" +} + +bluetooth() { + bluedevices=$(upower -e | grep -iv 'line' | grep -iv 'display' | grep -v 'BAT[0-9]' | grep -v 'hid') + for bluedevice in $bluedevices; do + bluedevice_name=$(upower -i "$bluedevice" | grep "model" | awk -F ': ' '{print $2}' | sed 's/ //g') + bluedevice_battery=$(upower -i "$bluedevice" | grep "percentage" | awk -F ': ' '{print $2}' | sed 's/ //g') + if [ -n "$bluedevice_battery" ]; then + notify-send "π $bluedevice_name:" "$bluedevice_battery" + fi + done +} + +# Handle mouse click actions +case "$BLOCK_BUTTON" in +2) bluetooth && devices "hid*" ;; # Middle click for Bluetooth battery levels +3) notify-send "π Battery module" "\- π: discharging +- π: not charging +- β»οΈ: stagnant charge +- π: charging +- β‘: fully charged +- β: battery very low! +- Middle click: bluetooth battery levels via upower" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +devices "BAT?*" diff --git a/ar/.local/bin/statusbar/sb-bghitness b/ar/.local/bin/statusbar/sb-bghitness new file mode 100755 index 0000000..0aabfb6 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-bghitness @@ -0,0 +1,19 @@ +#!/bin/sh + +# current brightness +curr_brightness=$(cat /sys/class/backlight/*/brightness) + +# max_brightness +max_brightness=$(cat /sys/class/backlight/*/max_brightness) + +# brightness percentage +brightness_per=$((100 * curr_brightness / max_brightness)) + +case $BLOCK_BUTTON in +3) notify-send "π‘ Brightness module" "\- Shows current brightness level βοΈ." ;; +4) pkexec brillo -A 5 -q ;; +5) pkexec brillo -U 5 -q ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +echo "π‘${brightness_per}%" diff --git a/ar/.local/bin/statusbar/sb-brightness b/ar/.local/bin/statusbar/sb-brightness new file mode 100755 index 0000000..909e676 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-brightness @@ -0,0 +1,11 @@ +#!/bin/sh + +case $BLOCK_BUTTON in +3) notify-send "π Backlight module +- Scroll up & down changes backlight" ;; +4) monbright -inc 5 ;; +5) monbright -dec 5 ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +monitorbright diff --git a/ar/.local/bin/statusbar/sb-clock b/ar/.local/bin/statusbar/sb-clock new file mode 100755 index 0000000..e0e8c53 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-clock @@ -0,0 +1,77 @@ +#!/bin/sh + +# Get current hour and minute +hour=$(date '+%I') +minute=$(date '+%M') +calendar="ποΈ" + +# Determine the icon based on hour and minute +if crontab -l 2>/dev/null | grep -q '^[^#[:space:]]'; then + if [ "$minute" -ge 30 ]; then + case "$hour" in + "00" | "12") icon="π§" ;; # 12:30 + "01" | "13") icon="π" ;; # 1:30 + "02" | "14") icon="π" ;; # 2:30 + "03" | "15") icon="π" ;; # 3:30 + "04" | "16") icon="π" ;; # 4:30 + "05" | "17") icon="π " ;; # 5:30 + "06" | "18") icon="π‘" ;; # 6:30 + "07" | "19") icon="π’" ;; # 7:30 + "08" | "20") icon="π£" ;; # 8:30 + "09" | "21") icon="π€" ;; # 9:30 + "10" | "22") icon="π₯" ;; # 10:30 + "11" | "23") icon="π¦" ;; # 11:30 + esac + else + case "$hour" in + "00" | "12") icon="π" ;; # 12:00 + "01" | "13") icon="π" ;; # 1:00 + "02" | "14") icon="π" ;; # 2:00 + "03" | "15") icon="π" ;; # 3:00 + "04" | "16") icon="π" ;; # 4:00 + "05" | "17") icon="π" ;; # 5:00 + "06" | "18") icon="π" ;; # 6:00 + "07" | "19") icon="π" ;; # 7:00 + "08" | "20") icon="π" ;; # 8:00 + "09" | "21") icon="π" ;; # 9:00 + "10" | "22") icon="π" ;; # 10:00 + "11" | "23") icon="π" ;; # 11:00 + esac + fi +else + icon="β°" +fi + +# Shows the current moon phase. +moonfile="${XDG_DATA_HOME:-${HOME}/.local/share}/moonphase" + +[ -s "$moonfile" ] && [ "$(stat -c %y "$moonfile" 2>/dev/null | cut -d' ' -f1)" = "$(date '+%Y-%m-%d')" ] || + { curl -sf "wttr.in/?format=%m" >"$moonfile" || exit 1; } + +moon="$(cat "$moonfile")" + +case $BLOCK_BUTTON in +1) + notify-send "This Month" "$(cal | sed "s/\<$(date +'%B' | tr -d ' ')\>/<b><span color='blue'>&<\/span><\/b>/;s/\<$(date +'%Y' | sed 's/ //g')\>/<b><span color='blue'>&<\/span><\/b>/;s/\<$(date +'%B' | sed 's/ //g')\>/<b><span color='blue'>&<\/span><\/b>/;s/\<$(date +'%e' | sed 's/ //g')\>/<b><span color='red'>&<\/span><\/b>/")" && notify-send "Appointments" "$(calcurse -d3)" + ;; +2) setsid -f "$TERMINAL" -e calcurse ;; +3) + notify-send "π
Time/date module" "\- Left click to show upcoming appointments for the next three days via \`calcurse -d3\` and show the month via \`cal\` +- Left click also displays the current time in other cities. +- Middle click opens calcurse if installed" + notify-send "π Moon phase module" "Displays current moon phase +- π: New +- π: Waxing Crescent +- π: First Quarter +- π: Waxing Gibbous +- π: Full +- π: Waning Gibbous +- π: Last Quarter +- π: Waning Crescent" + ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +7) timezones ;; +esac + +# Output the formatted date and time +date "+${moon-$calendar}%a,%d $icon%H:%M" diff --git a/ar/.local/bin/statusbar/sb-cpu b/ar/.local/bin/statusbar/sb-cpu new file mode 100755 index 0000000..9dfbb54 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-cpu @@ -0,0 +1,12 @@ +#!/bin/sh + +case $BLOCK_BUTTON in +1) notify-send "π₯ CPU hogs" "$(ps axch -o cmd:15,%cpu --sort=-%cpu | head)\\n(100% per core)" ;; +2) setsid -f "$TERMINAL" -e htop ;; +3) notify-send "π₯ CPU module " "\- Shows CPU temperature +- Left click to show intensive processes +- Middle click to open htop" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +sensors | awk '/Core 0/ {printf "π%dΒ°\n", $3}' diff --git a/ar/.local/bin/statusbar/sb-cpubars b/ar/.local/bin/statusbar/sb-cpubars new file mode 100755 index 0000000..ce677ef --- /dev/null +++ b/ar/.local/bin/statusbar/sb-cpubars @@ -0,0 +1,44 @@ +#!/bin/sh + +# Module showing CPU load as a changing bars. +# Just like in polybar. +# Each bar represents amount of load on one core since +# last run. + +# Cache in tmpfs to improve speed and reduce SSD load +cache=/tmp/cpubarscache + +case $BLOCK_BUTTON in +2) setsid -f "$TERMINAL" -e htop ;; +3) notify-send "πͺ¨ CPU load module" "Each bar represents one CPU core" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +# id total idle +stats=$(awk '/cpu[0-9]+/ {printf "%d %d %d\n", substr($1,4), ($2 + $3 + $4 + $5), $5 }' /proc/stat) +[ ! -f $cache ] && echo "$stats" >"$cache" +old=$(cat "$cache") +printf "πͺ¨" +echo "$stats" | while read -r row; do + id=${row%% *} + rest=${row#* } + total=${rest%% *} + idle=${rest##* } + + case "$(echo "$old" | awk '{if ($1 == id) + printf "%d\n", (1 - (idle - $3) / (total - $2))*100 /12.5}' \ + id="$id" total="$total" idle="$idle")" in + + "0") printf "β" ;; + "1") printf "β" ;; + "2") printf "β" ;; + "3") printf "β" ;; + "4") printf "β
" ;; + "5") printf "β" ;; + "6") printf "β" ;; + "7") printf "β" ;; + "8") printf "β" ;; + esac +done +printf "\\n" +echo "$stats" >"$cache" diff --git a/ar/.local/bin/statusbar/sb-disk b/ar/.local/bin/statusbar/sb-disk new file mode 100755 index 0000000..3c92f00 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-disk @@ -0,0 +1,27 @@ +#!/bin/sh + +# Status bar module for disk space +# $1 should be drive mountpoint, otherwise assumed /. + +location=${1:-/} + +[ -d "$location" ] || exit + +case "$location" in +"/home"*) icon="π " ;; +"/mnt"*) icon="πΎ" ;; +*) icon="π»" ;; +esac + +usage=$(df -h "$location" | awk ' /[0-9]/ {print $3 "/" $2}') + +case $BLOCK_BUTTON in +1) notify-send "π½ Disk space" "$(df -h --output=target,used,size)" ;; +2) notify-send "π½ Disk usage" "$icon: $usage" ;; +3) notify-send "π½ Disk module" "\- Shows used hard drive space +- Left click to show all disk info +- Middle click to show disk usage" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +printf "%s%s\n" "$icon" "$(df -hP "$location" | awk ' /[0-9]/ {print $5}')" diff --git a/ar/.local/bin/statusbar/sb-ecrypt b/ar/.local/bin/statusbar/sb-ecrypt new file mode 100755 index 0000000..24c4cb3 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-ecrypt @@ -0,0 +1,12 @@ +#!/bin/sh + +is_mounted() { mount | grep -q "$HOME/Private"; } + +case $BLOCK_BUTTON in +1) "${XDG_SCRIPTS_HOME:-${HOME}/.local/bin}/ecrypt" ;; +3) notify-send "π Encrypted Media Folder " "\- Shows mount status of Media +- Left click to toggle mount" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +is_mounted "$MOUNT_POINT" && echo "π" || echo "π" diff --git a/ar/.local/bin/statusbar/sb-forecast b/ar/.local/bin/statusbar/sb-forecast new file mode 100755 index 0000000..9966c61 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-forecast @@ -0,0 +1,402 @@ +#!/bin/sh + +# Displays today's snow chance (π), precipication chance (β), humidity (π§), wind speed (π), and current (feel like) temperature (π). +# Usually intended for the statusbar. + +LOCATION=$(curl -s http://ip-api.com/json | jq -r '[.regionName, .countryCode] | join(",")') + +url="${WTTRURL:-wttr.in}" +weatherreport="${XDG_CACHE_HOME:-${HOME}/.cache}/weatherreport" +weatherreportjson="${XDG_CACHE_HOME:-${HOME}/.cache}/weatherreport.json" + +error() { + notify-send -u critical "β Failed to update 'weather$1'" + exit 1 +} + +# Get a weather report from 'wttr.in' and save it locally. +getweatherreport() { + (timeout --signal=1 10s curl -sf "$url/$LOCATION" >"$weatherreport" && + printf "\nUpdated: %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" >>"$weatherreport") || + error "report" +} + +getweatherreportjson() { + timeout --signal=1 10s curl -sf "$url/$LOCATION?format=j1" >"$weatherreportjson" || error "reportjson" +} + +# Forecast should be updated every 3 hours, but set 3600 to check for reliability. +checkforecast() { + [ -s "$1" ] && [ "$(($(date +%s) - $(stat -c %Y "$1")))" -le 3600 ] +} + +get_current_hour() { date +%H | sed 's/^0*//'; } + +get_nearest_hourly() { + current_hour=$(get_current_hour) + hour_index=$((current_hour / 3)) + jq ".weather[0].hourly[$hour_index]" "$weatherreportjson" +} + +getprecip() { get_nearest_hourly | jq -r '.chanceofrain'; } + +gethighprecip() { jq -r '.weather[0].hourly[].chanceofrain' "$weatherreportjson" | sort -rn | head -1; } + +getsnow() { get_nearest_hourly | jq -r '.chanceofsnow'; } + +getwind() { get_nearest_hourly | jq -r '.windspeedKmph'; } + +gettemp() { get_nearest_hourly | jq -r '.tempC'; } + +getfeelslike() { get_nearest_hourly | jq -r '.FeelsLikeC'; } + +getlowtemp() { jq -r '.weather[0].hourly[].tempC' "$weatherreportjson" | sort -n | head -1; } + +gethightemp() { jq -r '.weather[0].hourly[].tempC' "$weatherreportjson" | sort -rn | head -1; } + +gethumidity() { + humidity=$(get_nearest_hourly | jq -r '.humidity') + case "$humidity" in + [0-9] | [1-2][0-9]) echo "ποΈ: $humidity%" ;; + [3-4][0-9]) echo "π²: $humidity%" ;; + [5-6][0-9]) echo "π§: $humidity%" ;; + [7-8][0-9]) echo "π¦: $humidity%" ;; + 9[0-9] | 100) echo "π: $humidity%" ;; + esac +} + +getdesc() { get_nearest_hourly | jq -r '.weatherDesc[0].value' | sed 's/ $//'; } + +showweather() { + case "$(gettemp)" in + -[0-9]* | 0) icon="π₯Ά" ;; # Temperature <= 0 + [1-9] | [1-2][0-9]) icon="π" ;; # Temperature 1β29 + 3* | [4-9]*) icon="π₯΅" ;; # Temperature >= 30 + esac + [ -n "$(gettemp)" ] && echo "$icon$(gettemp)Β°" +} + +todayweather() { + printf "π Today's weather: %s\nπ: %s%%\nβ: %s(%s)mβ§Έs\n%s\nπ: %sm/s\nπ: %sΒ°(%sΒ°)\nπ₯Ά: %sΒ°\nπ₯΅: %sΒ°\n" \ + "$(getdesc)" "$(getsnow)" "$(getprecip)" "$(gethighprecip)" "$(gethumidity)" "$(getwind)" "$(gettemp)" "$(getfeelslike)" "$(getlowtemp)" "$(gethightemp)" +} + +# Show a Doppler RADAR of a user's preferred location. + +secs=600 # Download a new doppler radar if one hasn't been downloaded in $secs seconds. +radarloc="${XDG_CACHE_HOME:-${HOME}/.cache}/radar" +doppler="${XDG_CACHE_HOME:-${HOME}/.cache}/doppler.gif" + +pickloc() { + chosen="$(echo "US: CONUS: Continental United States +US: Northeast +US: Southeast +US: PacNorthWest +US: PacSouthWest +US: UpperMissVly +US: SouthMissVly +US: SouthPlains +US: NorthRockies +US: SouthRockies +US: Alaska +US: Carib +US: Hawaii +US: CentGrLakes +US: Conus-Large +US: KABR: Aberdeen, SD +US: KBIS: Bismarck, ND +US: KFTG: Denver/Boulder, CO +US: KDMX: Des Moines, IA +US: KDTX: Detroit, MI +US: KDDC: Dodge City, KS +US: KDLH: Duluth, MN +US: KCYS: Cheyenne, WY +US: KLOT: Chicago, IL +US: KGLD: Goodland, KS +US: KUEX: Hastings, NE +US: KGJX: Grand Junction, CO +US: KGRR: Grand Rapids, MI +US: KMVX: Fargo/Grand Forks, ND +US: KGRB: Green Bay, WI +US: KIND: Indianapolis, IN +US: KJKL: Jackson, KY +US: KARX: La Crosse, WI +US: KILX: Lincoln/Central Illinois, IL +US: KLVX: Louisville, KY +US: KMQT: Marquette +US: KMKX: Milwaukee, WI +US: KMPX: Minneapolis, MN +US: KAPX: Gaylord/Alpena, MI +US: KLNX: North Platte, NE +US: KIWX: N. Webster/Northern, IN +US: KOAX: Omaha, NE +US: KPAH: Paducah, KY +US: KEAX: Pleasant Hill, MO +US: KPUX: Pueblo, CO +US: KDVN: Quad Cities, IA +US: KUDX: Rapid City, SD +US: KRIW: Riverton, WY +US: KSGF: Springfield, MO +US: KLSX: St. LOUIS, MO +US: KFSD: Sioux Falls, SD +US: KTWX: Topeka, KS +US: KICT: Wichita, KS +US: KVWX: Paducah, KY +US: ICAO: Responsible Wfo +US: KLTX: WILMINGTON, NC +US: KCCX: State College/Central, PA +US: KLWX: Sterling, VA +US: KFCX: Blacksburg/Roanoke, VA +US: KRAX: Raleigh/Durham, NC +US: KGYX: Portland, ME +US: KDIX: Mt Holly/Philadelphia, PA +US: KPBZ: Pittsburgh, PA +US: KAKQ: Wakefield, VA +US: KMHX: Morehead City, NC +US: KGSP: Greer/Greenville/Sprtbg, SC +US: KILN: Wilmington/Cincinnati, OH +US: KCLE: Cleveland, OH +US: KCAE: Columbia, SC +US: KBGM: Binghamton, NY +US: KENX: Albany, NY +US: KBUF: Buffalo, NY +US: KCXX: Burlington, VT +US: KCBW: Caribou, ME +US: KBOX: Boston /Taunton, MA +US: KOKX: New York City, NY +US: KCLX: Charleston, SC +US: KRLX: Charleston, WV +US: ICAO: Responsible WFO +US: KBRO: Brownsville, TX +US: KABX: Albuquerque, NM +US: KAMA: Amarillo, TX +US: KFFC: Peachtree City/Atlanta, GA +US: KEWX: Austin/Sanantonio, TX +US: KBMX: Birmingham, AL +US: KCRP: Corpus Christi, TX +US: KFWS: Dallas / Ft. Worth, TX +US: KEPZ: El Paso, TX +US: KHGX: Houston/ Galveston, TX +US: KJAX: Jacksonville, FL +US: KBYX: Key West, FL +US: KMRX: Morristown/knoxville, TN +US: KLBB: Lubbock, TX +US: KLZK: Little Rock, AR +US: KLCH: Lake Charles, LA +US: KOHX: Nashville, TN +US: KMLB: Melbourne, FL +US: KNQA: Memphis, TN +US: KAMX: Miami, FL +US: KMAF: Midland/odessa, TX +US: KTLX: Norman, OK +US: KHTX: Huntsville, AL +US: KMOB: Mobile, AL +US: KTLH: Tallahassee, FL +US: KTBW: Tampa Bay Area, FL +US: KSJT: San Angelo, TX +US: KINX: Tulsa, OK +US: KSRX: Tulsa, OK +US: KLIX: New Orleans/slidell, LA +US: KDGX: Jackson, MS +US: KSHV: Shreveport, LA +US: ICAO: Responsible WFO +US: KLGX: Seattle / Tacoma, WA +US: KOTX: Spokane, WA +US: KEMX: Tucson, AZ +US: KYUX: Phoenix, AZ +US: KNKX: San Diego, CA +US: KMUX: Monterey/san Francisco, CA +US: KHNX: San Joaquin/hanford, CA +US: KSOX: San Diego, CA +US: KATX: Seattle / Tacoma, WA +US: KIWA: Phoenix, AZ +US: KRTX: Portland, OR +US: KSFX: Pocatello, ID +US: KRGX: Reno, NV +US: KDAX: Sacramento, CA +US: KMTX: Salt Lake City, UT +US: KPDT: Pendleton, OR +US: KMSX: Missoula, MT +US: KESX: Las Vegas, NV +US: KVTX: Los Angeles, CA +US: KMAX: Medford, OR +US: KFSX: Flagstaff, AZ +US: KGGW: Glasgow, MT +US: KLRX: Elko, NV +US: KBHX: Eureka, CA +US: KTFX: Great Falls, MT +US: KCBX: Boise, ID +US: KBLX: Billings, MT +US: KICX: Salt Lake City, UT +US: ICAO: Responsible Wfo W/ MSCF +US: PABC: Anchorage, AK +US: PAPD: Fairbanks, AK +US: PHKM: Honolulu, HI +US: PAHG: Anchorage, AK +US: PAKC: Anchorage, AK +US: PAIH: Anchorage, AK +US: PHMO: Honolulu, HI +US: PAEC: Fairbanks, AK +US: TJUA: San Juan, PR +US: PACG: Juneau, AK +US: PHKI: Honolulu, HI +US: PHWA: Honolulu, HI +US: ICAO: Responsible Wfo W/ MSCF +US: KFDR: Norman, OK +US: PGUA: Guam +US: KBBX: Sacramento, CA +US: KFDX: Albuquerque, NM +US: KGWX: Jackson, MS +US: KDOX: Wakefield, VA +US: KDYX: San Angelo, TX +US: KEYX: Las Vegas, NV +US: KEVX: Mobile, AL +US: KHPX: Paducah, KY +US: KTYX: Burlington, VT +US: KGRK: Dallas / Ft. Worth, TX +US: KPOE: Lake Charles, LA +US: KEOX: Tallahassee, FL +US: KHDX: El Paso, TX +US: KDFX: San Antonio, TX +US: KMXX: Birmingham, AL +US: KMBX: Bismarck, ND +US: KVAX: Jacksonville, FL +US: KJGX: Peachtree City/atlanta, GA +US: KVNX: Norman, OK +US: KVBX: Vandenberg Afb: Orcutt, CA +EU: Europe +EU: GB: Great Brittain +EU: SCAN: Scandinavia. Norway, Sweden And Denmark +EU: ALPS: The Alps +EU: NL: The Netherlands +EU: DE: Germany +EU: SP: Spain +EU: FR: France +EU: IT: Italy +EU: PL: Poland +EU: GR: Greece +EU: TU: Turkey +EU: RU: Russia +EU: BA: Bahrain +EU: BC: Botswana +EU: SE: Republic of Seychelles +EU: HU: Hungary +EU: UK: Ukraine +AF: AF: Africa +AF: WA: West Africa +AF: ZA: South Africa +AF: DZ: Algeria +AF: CE: Canary Islands +AF: NG: Nigeria +AF: TD: Chad +AF: CG: Democratic Republic of Congo +AF: EG: Egypt +AF: ET: Ethiopia +AF: CM: Cameroon +AF: IS: Israel +AF: LY: Libya +AF: MG: Madagascar +AF: MO: Morocco +AF: BW: Namibia +AF: SA: Saudi Arabia +AF: SO: Somalia +AF: SD: Sudan +AF: TZ: Tanzania +AF: TN: Tunisia +AF: ZM: Zambia +AF: KE: Kenya +AF: AO: Angola +DE: BAW: Baden-WΓΌrttemberg +DE: BAY: Bavaria +DE: BBB: Berlin +DE: BBB: Brandenburg +DE: HES: Hesse +DE: MVP: Mecklenburg-Western Pomerania +DE: NIB: Lower Saxony +DE: NIB: Bremen +DE: NRW: North Rhine-Westphalia +DE: RPS: Rhineland-Palatinate +DE: RPS: Saarland +DE: SAC: Saxony +DE: SAA: Saxony-Anhalt +DE: SHH: Schleswig-Holstein +DE: SHH: Hamburg +DE: THU: Thuringia" | dmenu -r -i -l 50 -p "Select a radar to use as default:" | tr "[:lower:]" "[:upper:]")" + + # Ensure user did not escape. + [ -z "$chosen" ] && exit 1 + + # Set continent code and radar code. + continentcode=${chosen%%:*} + radarcode=${chosen#* } radarcode=${radarcode%:*} + + # Print codes to $radarloc file. + printf "%s,%s\\n" "$continentcode" "$radarcode" >"$radarloc" +} + +getdoppler() { + cont=$(cut -c -2 "$radarloc") + loc=$(cut -c 4- "$radarloc") + notify-send "π¦οΈ Doppler RADAR" "Pulling most recent Doppler RADAR for $loc." + case "$cont" in + "US") curl -sL "https://radar.weather.gov/ridge/standard/${loc}_loop.gif" >"$doppler" ;; + "EU") curl -sL "https://api.sat24.com/animated/${loc}/rainTMC/2/" >"$doppler" ;; + "AF") curl -sL "https://api.sat24.com/animated/${loc}/rain/2/" >"$doppler" ;; + "DE") + loc="$(echo "$loc" | tr "[:upper:]" "[:lower:]")" + curl -sL "https://www.dwd.de/DWD/wetter/radar/radfilm_${loc}_akt.gif" >"$doppler" + ;; + esac +} + +showdoppler() { setsid -f mpv --no-osc --loop=inf --no-terminal "$doppler"; } + +case $BLOCK_BUTTON in +1) + [ "$MANPAGER" = "less -s" ] && pager=true || pager=false + [ "$pager" = "false" ] && { + export MANPAGER='less -s' + export LESS="R" + export LESS_TERMCAP_mb="$(printf '%b' '[1;31m')" + export LESS_TERMCAP_md="$(printf '%b' '[1;36m')" + export LESS_TERMCAP_me="$(printf '%b' '[0m')" + export LESS_TERMCAP_so="$(printf '%b' '[01;44;33m')" + export LESS_TERMCAP_se="$(printf '%b' '[0m')" + export LESS_TERMCAP_us="$(printf '%b' '[1;32m')" + export LESS_TERMCAP_ue="$(printf '%b' '[0m')" + export LESSOPEN="| /usr/bin/highlight -O ansi %s 2>/dev/null" + } + setsid -f "$TERMINAL" -e less -Sf "${XDG_CACHE_HOME:-${HOME}/.cache}/weatherreport" + [ "$pager" = "false" ] && { + export MANPAGER="sh -c 'col -bx | bat -l man -p'" + export MANROFFOPT="-c" + } + ;; +2) + [ ! -f "$radarloc" ] && pickloc && getdoppler + [ $(($(date '+%s') - $(stat -c %Y "$doppler"))) -gt "$secs" ] && getdoppler + showdoppler + ;; +3) + notify-send "π Weather module (updates every 3 hours)" "\- Left click for full forecast +- Shift + left click to update forecast +π: Chance of snow (hidden if it's 0) +β: Chance of rain +π§: Humidity (icon changes depending on the level) +π: Wind speed +π: Current (feel like) temperature +π₯Ά: Daily lowest temperature +π₯΅: Daily highest temperature" + notify-send "$(todayweather)" + notify-send "πΊοΈ Doppler RADAR module" "\- Middle click for local Doppler RADAR +- Shift + middle click to update RADAR location +After $secs seconds, new clicks will also automatically update the doppler RADAR" + ;; +6) getweatherreport && getweatherreportjson && notify-send "π Updated forecast" ;; +7) pickloc && getdoppler && showdoppler ;; +8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +checkforecast "$weatherreport" || { getweatherreport && pkill -RTMIN+15 "${STATUSBAR:-dwmblocks}" && sleep 3; } +checkforecast "$weatherreportjson" || { getweatherreportjson && pkill -RTMIN+15 "${STATUSBAR:-dwmblocks}" && sleep 3; } +showweather diff --git a/ar/.local/bin/statusbar/sb-help-icon b/ar/.local/bin/statusbar/sb-help-icon new file mode 100755 index 0000000..2717758 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-help-icon @@ -0,0 +1,22 @@ +#!/bin/sh + +# The clickable help menu. Middle click to restart wm. + +# If dwm is running, use dwm's readme and restart. +pidof dwm >/dev/null && + READMEFILE=/usr/local/share/dwm/thesiah.mom +restartwm() { pkill -HUP dwm; } || + restartwm() { i3 restart; } + +case $BLOCK_BUTTON in +1) groff -mom "${READMEFILE:-${XDG_DATA_HOME:-${HOME}/.local/share}/thesiah/thesiah.mom}" -Tpdf | zathura - ;; +2) restartwm ;; +3) notify-send "β Help module" "\- Left click to open THESIAH guide +- Middle click to refresh window manager +- Shift + Middle click to run system action +- Shift + Right clict to lock screen" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +7) sysact ;; +8) slock ;; +esac +echo "β" diff --git a/ar/.local/bin/statusbar/sb-internet b/ar/.local/bin/statusbar/sb-internet new file mode 100755 index 0000000..3d4ff4e --- /dev/null +++ b/ar/.local/bin/statusbar/sb-internet @@ -0,0 +1,42 @@ +#!/bin/sh + +# Show wifi π and percent strength or π‘ if none. +# Show π if connected to ethernet or β if none. +# Show π°οΈ if a vpn connection is active + +case $BLOCK_BUTTON in +1) + "$TERMINAL" -e nmtui + pkill -RTMIN+7 dwmblocks + ;; +3) notify-send "π Internet module" "\- Left click to connect +β: wifi disabled +π‘: no wifi connection +π: wifi connection with quality +β: no ethernet +π: ethernet working +π°οΈ: vpn is active +" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +# Wifi +if [ "$(cat /sys/class/net/w*/operstate 2>/dev/null)" = 'up' ]; then + wifiicon="$(awk '/^\s*w/ { print "π" int($3 * 100 / 70) "%" }' /proc/net/wireless)" +elif [ "$(cat /sys/class/net/w*/operstate 2>/dev/null)" = 'down' ]; then + [ "$(cat /sys/class/net/w*/flags 2>/dev/null)" = '0x1003' ] && wifiicon="π‘" || wifiicon="β" +fi + +# Ethernet +[ "$(cat /sys/class/net/e*/operstate 2>/dev/null)" = 'up' ] && ethericon="π" || ethericon="β" + +# TUN +[ -n "$(cat /sys/class/net/tun*/operstate 2>/dev/null)" ] && tunicon=" π°οΈ" + +if [ "$(cat /sys/class/net/w*/operstate 2>/dev/null)" = 'up' ] && [ ! "$(cat /sys/class/net/e*/operstate 2>/dev/null)" = 'up' ]; then + printf "%s%s\n" "$wifiicon" "$tunicon" +elif [ ! "$(cat /sys/class/net/w*/operstate 2>/dev/null)" = 'up' ] && [ "$(cat /sys/class/net/e*/operstate 2>/dev/null)" = 'up' ]; then + printf "%s%s\n" "$ethericon" "$tunicon" +else + printf "%s%s%s\n" "$wifiicon" " $ethericon" "$tunicon" +fi diff --git a/ar/.local/bin/statusbar/sb-iplocate b/ar/.local/bin/statusbar/sb-iplocate new file mode 100755 index 0000000..d84445e --- /dev/null +++ b/ar/.local/bin/statusbar/sb-iplocate @@ -0,0 +1,15 @@ +#!/bin/sh + +# Gets your public ip address checks which country you are in and +# displays that information in the statusbar +# +# https://www.maketecheasier.com/ip-address-geolocation-lookups-linux/ + +set -e + +ifinstalled "geoip" +addr="$(geoiplookup "$(curl -sfm 1 ifconfig.me 2>/dev/null)")" +name="${addr##*, }" +flag="$(grep "flag: $name" "${XDG_DATA_HOME:-${HOME}/.local/share}/larbs/emoji")" +flag="${flag%% *}" +printf "%s %s\\n" "$flag" "$name" diff --git a/ar/.local/bin/statusbar/sb-keyboard b/ar/.local/bin/statusbar/sb-keyboard new file mode 100755 index 0000000..6329020 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-keyboard @@ -0,0 +1,35 @@ +#!/bin/sh + +# works on any init system +# requirements: dmenu, xorg-setxkbmap +kb="$(setxkbmap -query | grep -oP 'layout:\s*\K\w+')" || exit 1 + +case $BLOCK_BUTTON in +1) fcitx5-remote -t && kill -44 "$(pidof "${STATUSBAR:-dwmblocks}")" ;; +2) + kb_choice="$(awk '/! layout/{flag=1; next} /! variant/{flag=0} flag {print $2, "- " $1}' /usr/share/X11/xkb/rules/base.lst | dmenu -l 15)" + [ -z "$kb_choice" ] && exit 0 + kb="$(echo "$kb_choice" | awk '{print $3}')" + setxkbmap "$kb" + pkill -RTMIN+10 "${STATUSBAR:-dwmblocks}" + ;; +3) notify-send "β¨οΈ Input Method module" "\- Shows current input method (defalt US) +- Left click to switch language (EN/KO) +- Middle click to change keyboard" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +if [ "$kb" = "us" ] || [ "$kb" = "kr" ]; then + if [ "$(fcitx5-remote)" -eq 1 ]; then + echo "β¨οΈUS" + elif [ "$(fcitx5-remote)" -eq 2 ]; then + case "$(fcitx5-remote -n)" in + *ko* | *Korean* | *hangul*) echo "β¨οΈKO" ;; + *) echo "β¨οΈ$(setxkbmap -query | grep 'layout:' | sed 's/layout:\s*\(\S*\)/\1/g')" ;; + esac + else + echo "β¨οΈ??" + fi +else + echo "β¨οΈ$kb" +fi diff --git a/ar/.local/bin/statusbar/sb-mailbox b/ar/.local/bin/statusbar/sb-mailbox new file mode 100755 index 0000000..4496efc --- /dev/null +++ b/ar/.local/bin/statusbar/sb-mailbox @@ -0,0 +1,23 @@ +#!/bin/sh + +# Displays number of unread mail and an loading icon if updating. +# When clicked, brings up `neomutt`. + +case $BLOCK_BUTTON in +1) + setsid -w -f "$TERMINAL" -e neomutt + pkill -RTMIN+20 "${STATUSBAR:-dwmblocks}" + ;; +2) setsid -f mw -Y >/dev/null ;; +3) notify-send "π¬ Mail module" "\- Shows unread mail +- Shows π if syncing mail +- Left click opens neomutt +- Middle click syncs mail" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +unread="$(find "${XDG_DATA_HOME:-${HOME}/.local/share}"/mail/*/[Ii][Nn][Bb][Oo][Xx]/new/* -type f | wc -l 2>/dev/null)" + +pidof mbsync >/dev/null 2>&1 && icon="π" + +[ "$unread" = "0" ] && [ "$icon" = "" ] || echo "π¬$unread$icon" diff --git a/ar/.local/bin/statusbar/sb-memory b/ar/.local/bin/statusbar/sb-memory new file mode 100755 index 0000000..bc7085a --- /dev/null +++ b/ar/.local/bin/statusbar/sb-memory @@ -0,0 +1,18 @@ +#!/bin/sh + +case $BLOCK_BUTTON in +1) notify-send "π Memory hogs" "$( + ps axch -o cmd:15,%mem --sort=-%mem | head + echo + free --mebi | sed -n '2{p;q}' | awk '{printf ("π%2.2fGB/%2.2fGB\n", ( $3 / 1024), ($2 / 1024))}' +)" ;; +2) setsid -f "$TERMINAL" -e htop ;; +3) notify-send "π Memory module" "\- Shows Memory used/total +- Left click to show memory hogs +- Middle click to open htop" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +[ $(xrandr | grep "\*" | awk '{print $1}' | sed 's/x[0-9]*//g') -lt 1920 ] && + free --mebi | sed -n '2{p;q}' | awk '{printf ("π%d%%\n", ($3/$2)*100+0.5 )}' || + free --mebi | sed -n '2{p;q}' | awk '{printf ("π%dGB/%dGB", $3/1000+0.5,$2/1000+0.5)}' diff --git a/ar/.local/bin/statusbar/sb-mpdup b/ar/.local/bin/statusbar/sb-mpdup new file mode 100755 index 0000000..90e9c7e --- /dev/null +++ b/ar/.local/bin/statusbar/sb-mpdup @@ -0,0 +1,8 @@ +#!/bin/sh + +# This loop will update the mpd statusbar module whenever a command changes the +# music player's status. mpd must be running on X's start for this to work. + +while :; do + mpc idle >/dev/null && kill -57 "$(pidof "${STATUSBAR:-dwmblocks}")" || break +done diff --git a/ar/.local/bin/statusbar/sb-music b/ar/.local/bin/statusbar/sb-music new file mode 100755 index 0000000..e47fb06 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-music @@ -0,0 +1,78 @@ +#!/bin/bash + +truncate_string() { + local input="$1" + local max_length="$2" + if [ "${#input}" -gt "$max_length" ]; then + echo "${input:0:$((max_length - 2))}.." + else + echo "$input" + fi +} + +filter() { + if ps -C mpd >/dev/null 2>&1; then + screen_width=$(xrandr | grep '\*' | awk '{print $1}' | cut -d'x' -f1) + artist=$(mpc current -f %artist%) + title=$(mpc current -f %title%) + + if [ "$screen_width" -le 2048 ]; then + max_length=$((screen_width / 100)) + artist=$(truncate_string "$artist" "$max_length") + title=$(truncate_string "$title" "$max_length") + else + artist="$(mpc current -f %artist%)" + title="$(mpc current -f %title%)" + fi + + case "$(mpc status %state%)" in + "playing") prefix="π΅" ;; + "paused") prefix="βΈ" ;; + *) return ;; + esac + + indicators="" + [ "$(mpc status %single%)" = "on" ] && indicators="${indicators}π" + [ "$(mpc status %random%)" = "on" ] && indicators="${indicators}π" + [ "$(mpc status %repeat%)" = "on" ] && indicators="${indicators}π" + + sig=$(grep "${0##*/}" "${XDG_SOURCES_HOME:-${HOME}/.local/src}/suckless/dwmblocks/config.h" | awk -F',' '{print $3}') + case $sig in + *0*) + echo "$prefix$artist - $title$([ -n "$indicators" ] && echo "$indicators")" + ;; + *1*) + echo "$prefix$artist - $title $(mpc status %currenttime%)/$(mpc status %totaltime%)$([ -n "$indicators" ] && echo "$indicators")" + ;; + esac + fi +} + +[ "$(grep "${0##*/}" "${XDG_SOURCES_HOME:-${HOME}/.local/src}/suckless/dwmblocks/config.h" | awk -F',' '{print $3}')" -eq 0 ] && { + pidof -x sb-mpdup >/dev/null 2>&1 || sb-mpdup >/dev/null 2>&1 & +} + +# Handling interaction based on button press +case $BLOCK_BUTTON in +1) # left click, opens ncmpcpp + mpc status | filter + setsid -f "$TERMINAL" -e ncmpcpp + ;; +2) mpc toggle | filter ;; # middle click, pause/unpause +3) # right click + notify-send "π΅ Music module" "\- Shows mpd song playing and status +- π΅ if playing +- βΈ if paused +- π if single on +- π if repeat on +- π if random on +- Left click opens ncmpcpp +- Middle click pauses/unpause +- Scroll changes track" + notify-send "π΅ $(mpc current)" "βοΈ $(mpc queued)" + ;; +4) mpc prev | filter ;; # scroll up, previous +5) mpc next | filter ;; # scroll down, next +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +*) mpc status | filter ;; # default, show current status +esac diff --git a/ar/.local/bin/statusbar/sb-nettraf b/ar/.local/bin/statusbar/sb-nettraf new file mode 100755 index 0000000..7bba320 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-nettraf @@ -0,0 +1,29 @@ +#!/bin/sh + +# Module showing network traffic. Shows how much data has been received (RX) or +# transmitted (TX) since the previous time this script ran. So if run every +# second, gives network traffic per second. + +case $BLOCK_BUTTON in +1) setsid -f "$TERMINAL" -e bmon ;; +3) notify-send "π Network traffic module" "π»: Traffic received +πΊ: Traffic transmitted" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +update() { + sum=0 + for arg; do + read -r i <"$arg" + sum=$((sum + i)) + done + cache=/tmp/${1##*/} + [ -f "$cache" ] && read -r old <"$cache" || old=0 + printf %d\\n "$sum" >"$cache" + printf %d\\n $((sum - old)) +} + +rx=$(update /sys/class/net/[ew]*/statistics/rx_bytes) +tx=$(update /sys/class/net/[ew]*/statistics/tx_bytes) + +printf "π»%4sB πΊ%4sB\\n" $(numfmt --to=iec $rx $tx) diff --git a/ar/.local/bin/statusbar/sb-news b/ar/.local/bin/statusbar/sb-news new file mode 100755 index 0000000..8bbbbf1 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-news @@ -0,0 +1,17 @@ +#!/bin/sh + +# Displays number of unread news items and an loading icon if updating. +# When clicked, brings up `newsboat`. + +case $BLOCK_BUTTON in +1) setsid "$TERMINAL" -e newsboat ;; +2) setsid -f newsup >/dev/null && exit ;; +3) notify-send "π° News module" "\- Shows unread news items +- Shows π if updating with \`newsup\` +- Left click opens newsboat +- Middle click syncs RSS feeds +<b>Note:</b> Only one instance of newsboat (including updates) may be running at a time" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +cat /tmp/newsupdate 2>/dev/null || echo "$(newsboat -x print-unread | awk '{ if($1>0) print "π°" $1}')$(cat "${XDG_CONFIG_HOME:-${HOME}/.config}"/newsboat/.update 2>/dev/null)" diff --git a/ar/.local/bin/statusbar/sb-packages b/ar/.local/bin/statusbar/sb-packages new file mode 100755 index 0000000..5955c75 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-packages @@ -0,0 +1,37 @@ +#!/bin/sh + +# Displays number of upgradeable packages. +# For this to work, have a `pacman -Sy` command run in the background as a +# cronjob every so often as root. This script will then read those packages. +# When clicked, it will run an upgrade via pacman. +# +# Add the following text as a file in /usr/share/libalpm/hooks/statusbar.hook: +# +# [Trigger] +# Operation = Upgrade +# Type = Package +# Target = * +# +# [Action] +# Description = Updating statusbar... +# When = PostTransaction +# Exec = /usr/bin/pkill -RTMIN+16 dwmblocks # Or i3blocks if using i3. + +case $BLOCK_BUTTON in +1) setsid -f "$TERMINAL" -e sb-popupgrade && remaps ;; +2) notify-send "$(/usr/bin/pacman -Qu)" "$(/usr/bin/yay -Qu --aur)" ;; +3) notify-send "π Upgrade module" "π¦: number of upgradable 'pacman' packages +π§°: number of upgradable 'yay' packages +- Left click to upgrade all packages +- Middle click to show upgradable packages" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +pacnum=$(pacman -Qu | grep -Fcv "[ignored]" | sed "s/^/π¦/;s/^π¦0$//g") +yaynum=$(yay -Qu --aur | grep -Fcv "[ignored]" | sed "s/^/π§°/;s/^π§°0$//g") +upgradable="" +[ -n "$pacnum" ] && upgradable="${upgradable}${pacnum} " +[ -n "$yaynum" ] && upgradable="${upgradable}${yaynum} " +upgradable=$(echo "$upgradable" | sed 's/ *$//') + +printf "%s\n" "$upgradable" diff --git a/ar/.local/bin/statusbar/sb-popupgrade b/ar/.local/bin/statusbar/sb-popupgrade new file mode 100755 index 0000000..14036eb --- /dev/null +++ b/ar/.local/bin/statusbar/sb-popupgrade @@ -0,0 +1,9 @@ +#!/bin/sh + +printf "Beginning upgrade\\n" + +yay -Syu +pkill -RTMIN+16 "${STATUSBAR:-dwmblocks}" + +printf "\\nUpgrade complete.\\nPress <Enter> to exit window.\\n\\n" +read -r _ diff --git a/ar/.local/bin/statusbar/sb-price b/ar/.local/bin/statusbar/sb-price new file mode 100755 index 0000000..46731c2 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-price @@ -0,0 +1,67 @@ +#!/bin/sh + +# Usage: +# price <currency-base currency> <name of currency> <icon> <signal> +# price bat-btc "Basic Attention Token" π¦ 24 +# This will give the price of BAT denominated in BTC and will update on +# signal 24. +# When the name of the currency is multi-word, put it in quotes. + +[ -z "$1" ] && exit 1 + +url="${CRYPTOURL:-rate.sx}" +target="${1%%-*}" +denom="${1##*-}" +name="${2:-$1}" +icon="${3:-π°}" +case "$denom" in +"$target" | usd) + denom="usd" + symb="$" + ;; +gbp) symb="Β£" ;; +eur) symb="β¬" ;; +btc) symb="ο
" ;; +esac +interval="@1d" # History contained in chart preceded by '@' (7d = 7 days) +dir="${XDG_CACHE_HOME:-${HOME}/.cache}/crypto-prices" +pricefile="$dir/$target-$denom" +chartfile="$dir/$target-$denom-chart" +filestat="$(stat -c %x "$pricefile" 2>/dev/null)" + +[ -d "$dir" ] || mkdir -p "$dir" + +updateprice() { curl -sf \ + --fail-early "${denom}.${url}/1${target}" "${denom}.${url}/${target}${interval}" \ + --output "$pricefile" --output "$chartfile" || + rm -f "$pricefile" "$chartfile"; } + +[ "${filestat%% *}" != "$(date '+%Y-%m-%d')" ] && + updateme="1" + +case $BLOCK_BUTTON in +1) setsid "$TERMINAL" -e less -Srf "$chartfile" ;; +2) + notify-send -u low "$icon Updating..." "Updating $name price..." + updateme="1" + showupdate="1" + ;; +3) + uptime="$(date -d "$filestat" '+%D at %T' | sed "s|$(date '+%D')|Today|")" + notify-send "$icon $name module" "\- <b>Exact price: \$$(cat "$pricefile")</b> +- Left click for chart of changes +- Middle click to update +- Shows π if updating prices +- <b>Last updated: +$uptime</b>" + ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +[ -n "$updateme" ] && + updateprice "$target" && + [ -n "$showupdate" ] && + notify-send "$icon Update complete" "$name price is now +\$$(cat "$pricefile")" + +[ -f "$pricefile" ] && printf "%s%s%0.2f" "$icon" "$symb" "$(cat "$pricefile")" diff --git a/ar/.local/bin/statusbar/sb-queues b/ar/.local/bin/statusbar/sb-queues new file mode 100755 index 0000000..7cd48a7 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-queues @@ -0,0 +1,40 @@ +#!/bin/sh + +notify_filenames() { + while IFS= read -r line; do + id=$(echo "$line" | awk '{print $1}') + url=$(tsp -l | awk -v id="$id" 'flag && /notify-send/ {print $0; flag=0} $1 == id {flag=1}' | grep -o 'https://[^\"]*') + if [ -n "$url" ]; then + decoded_url=$(echo "$url" | sed 's/&/\&/g') + yt-dlp --no-playlist --simulate --get-filename "$decoded_url" 2>/dev/null | while IFS= read -r filename; do + notify-send "π½ Downloading:" "$filename" + done + else + notify-send "πͺΉ No URL extracted for task $id" + fi + done <<EOF +$(tsp -l | awk '/running/ && /yt-dlp/') +EOF + if [ -z "$url" ]; then + notify-send "π€ No active yt-dlp downloads" + fi + pkill -RTMIN+21 "${STATUSBAR:-dwmblocks}" +} + +# This block displays the number of running and queued background tasks. Requires tsp. +num=$(tsp -l | awk -v numr=0 -v numq=0 '{if (!/notify-send/ && /running/) numr++; if (!/notify-send/ && /queued/) numq++} END{print numr"|"numq}') + +# Handle mouse clicks +case $BLOCK_BUTTON in +1) setsid -f "$TERMINAL" -e sh -c 'tsp -l; echo "\nPress enter to close..." ; read REPLY' ;; +2) setsid -f "$TERMINAL" -e sh -c 'tsp -t' ;; +3) + notify_filenames + notify-send "π Tasks module" "π€: number of running/queued background tasks +- Left click to show all tasks +- Middle click to show the current task progress" + ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +cat /tmp/qplaylist 2>/dev/null || ([ "$num" != "0|0" ] && echo "π€$num") diff --git a/ar/.local/bin/statusbar/sb-repos b/ar/.local/bin/statusbar/sb-repos new file mode 100755 index 0000000..1dad9f1 --- /dev/null +++ b/ar/.local/bin/statusbar/sb-repos @@ -0,0 +1,130 @@ +#!/bin/bash + +pidof transmission-daemon >/dev/null && exit 1 + +# Directories containing Git repositories +DOTFILES_REPOS="$HOME/.dotfiles" +SUCKLESS_REPOS="$HOME/.local/src/suckless" +PRIVATE_REPOS="$HOME/Private/repos" +PUBLIC_REPOS="$HOME/Public/repos" + +# Icon indicators +DOTFILES_ICON="βοΈ" +SUCKLESS_ICON="π " +PRIVATE_ICON="π " +PUBLIC_ICON="π’" + +# Function to parse Git status and format symbols +get_git_status_symbols() { + git status --porcelain | awk ' + { + if ($1 == "??") { + changes["?"]++ + } else if ($1 ~ /^[MADR]$/) { + changes[$1]++ + } + } + END { + for (change in changes) { + printf "%s%s", change, changes[change] + } + }' +} + +# Function to check for unpushed commits +get_unpushed_commits() { git cherry -v 2>/dev/null | wc -l; } + +# Function to check for unpulled commits +get_unpulled_commits() { git rev-list --count HEAD..@{upstream} 2>/dev/null; } + +# Function to check Git repository status for multiple repos +check_multi_repo_status() { + local dir="$1" + local icon="$2" + local status="" + local changed_repos="" + + while IFS= read -r git_dir; do + local repo_dir="${git_dir%/.git}" + cd "$repo_dir" || continue + + changes=$(get_git_status_symbols) + unpushed=$(get_unpushed_commits) + unpulled=$(get_unpulled_commits) + + if [ -n "$changes" ] || [ "$unpushed" -gt 0 ] || [ "$unpulled" -gt 0 ]; then + status+="$icon$changes" + [ "$unpushed" -gt 0 ] && status+="β$unpushed" + [ "$unpulled" -gt 0 ] && status+="β$unpulled" + status+=" " + changed_repos+="$repo_dir" + fi + done < <(find "$dir" -mindepth 2 -maxdepth 2 -type d -name ".git" 2>/dev/null) + + printf "%s%s" "$status" "$changed_repos" +} + +# Function to check Git repository status for a single repository +check_single_repo_status() { + local dir="$1" + local icon="$2" + local repo_status="" + local changed_repo="" + + if [ -d "$dir/.git" ]; then + cd "$dir" || return + + changes=$(get_git_status_symbols) + unpushed=$(get_unpushed_commits) + unpulled=$(get_unpulled_commits) + + if [ -n "$changes" ] || [ "$unpushed" -gt 0 ] || [ "$unpulled" -gt 0 ]; then + repo_status+="$icon$changes" + [ "$unpushed" -gt 0 ] && repo_status+="β$unpushed" + [ "$unpulled" -gt 0 ] && repo_status+="β$unpulled" + repo_status+=" " + changed_repo="$dir" + fi + fi + + printf "%s%s" "$repo_status" "$changed_repo" +} + +# Check statuses for repositories +dotfiles_status=$(check_single_repo_status "$DOTFILES_REPOS" "$DOTFILES_ICON" | awk -F' ' '{print $1}') +dotfiles_changes=$(check_single_repo_status "$DOTFILES_REPOS" "$DOTFILES_ICON" | awk -F' ' '{print $2}') + +suckless_status=$(check_single_repo_status "$SUCKLESS_REPOS" "$SUCKLESS_ICON" | awk -F' ' '{print $1}') +suckless_changes=$(check_single_repo_status "$SUCKLESS_REPOS" "$SUCKLESS_ICON" | awk -F' ' '{print $2}') + +private_status=$(check_multi_repo_status "$PRIVATE_REPOS" "$PRIVATE_ICON" | awk -F' ' '{print $1}') +private_changes=$(check_multi_repo_status "$PRIVATE_REPOS" "$PRIVATE_ICON" | awk -F' ' '{print $2}') + +public_status=$(check_multi_repo_status "$PUBLIC_REPOS" "$PUBLIC_ICON" | awk -F' ' '{print $1}') +public_changes=$(check_multi_repo_status "$PUBLIC_REPOS" "$PUBLIC_ICON" | awk -F' ' '{print $1}') + +[ -f /tmp/gitsync ] && rm -f /tmp/gitsync + +# Combine statuses +output="" +[ -n "$dotfiles_status" ] && output+="$dotfiles_status " +[ -n "$suckless_status" ] && output+="$suckless_status " +[ -n "$private_status" ] && output+="$private_status " +[ -n "$public_status" ] && output+="$public_status " + +# Trim trailing spaces and display output +output="${output%"${output##*[! ]}"}" +[ -n "$output" ] && (cat /tmp/gitsync 2>/dev/null || echo "$output") + +openrepos() { + all_changed_repos="$dotfiles_changes"$'\n'"$suckless_changes"$'\n'"$private_changes"$'\n'"$public_changes" + [ -n "$all_changed_repos" ] && exec "$TERMINAL" -e opensessions "$(echo "$all_changed_repos" | grep -v '^$')" +} + +# Handle button actions +case "$BLOCK_BUTTON" in +1) openrepos ;; +3) notify-send "ο Git module" "\- Shows git repositories changes +- Left click opens changed repositories" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; # Launch editor for the script +esac diff --git a/ar/.local/bin/statusbar/sb-tasks b/ar/.local/bin/statusbar/sb-tasks new file mode 100755 index 0000000..66be81b --- /dev/null +++ b/ar/.local/bin/statusbar/sb-tasks @@ -0,0 +1,84 @@ +#!/bin/sh + +# Get the current time and the time in one hour +now=$(date +%s) +in_one_hour=$(date -d "+1 hour" +%s) + +# Check for tasks due in the next hour +tasks_due_today=$(task due:tomorrow _ids) +tasks_due_count=0 +tasks_due_list="" + +for task_id in $tasks_due_today; do + task_due_date=$(task _get "$task_id".due) + task_due_epoch=$(date -d "$task_due_date" +%s) + task_description=$(task _get "$task_id".description) + + # Check if the task is due within the next hour + if [ "$task_due_epoch" -gt "$now" ] && [ "$task_due_epoch" -le "$in_one_hour" ]; then + tasks_due_list="$tasks_due_list- $task_description\n" + tasks_due_count=$((tasks_due_count + 1)) + fi +done + +# Check for overdue tasks (tasks with due date in the past) +overdue_tasks=$(task +OVERDUE _ids) +overdue_count=0 +overdue_list="" + +for task_id in $overdue_tasks; do + task_description=$(task _get "$task_id".description) + overdue_list="$overdue_list- $task_description\n" + overdue_count=$((overdue_count + 1)) +done + +# Check for follow-up tasks +follow_up_tasks=$(task follow.is:Y _ids -PARENT) +follow_up_count=0 +follow_up_list="" + +for task_id in $follow_up_tasks; do + task_due_date=$(task _get "$task_id".due) + task_due_epoch=$(date -d "$task_due_date" +%s) + task_description=$(task _get "$task_id".description) + + # Ensure that follow-up tasks are only shown if they are not overdue + if [ "$task_due_epoch" -ge "$now" ]; then + follow_up_list="$follow_up_list- $task_description\n" + follow_up_count=$((follow_up_count + 1)) + fi +done + +check_task_sync() { + if [ "$(task _get tw.syncneeded)" -eq 1 ]; then + tasks-sync + notify-send "π Tasks synced" + fi +} + +# Handle mouse clicks +case $BLOCK_BUTTON in +1) # Combine actions for button 1 and button 2 + notify-send "π Follow-up task(s) to complete:" "$(printf "%b" "$follow_up_list") +π Tasks due in the next hour: +$(printf "%b" "$tasks_due_list") +β° Overdue Tasks: +$(printf "%b" "$overdue_list")" + ;; +2) check_task_sync ;; +3) + notify-send "ποΈ Task Module" "Shows task counts. +- Left click: Show tasks due soon. +- Middle click: Show follow-up tasks." + ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +# Output task information to dwmblocks +output="" + +[ "$overdue_count" -gt 0 ] && output="${output}β°$overdue_count " +[ "$follow_up_count" -gt 0 ] && output="${output}π$follow_up_count " +[ "$tasks_due_count" -gt 0 ] && output="${output}π$tasks_due_count " && notify-send -u critical "π Tasks Remained!" "$tasks_due_list" +[ "$(task _get tw.syncneeded)" -eq 1 ] && output="${output}π " +echo "${output%* }" diff --git a/ar/.local/bin/statusbar/sb-torrent b/ar/.local/bin/statusbar/sb-torrent new file mode 100755 index 0000000..79da88d --- /dev/null +++ b/ar/.local/bin/statusbar/sb-torrent @@ -0,0 +1,33 @@ +#!/bin/sh + +status=$(transmission-remote -l | grep % | + sed " # The letters are for sorting and will not appear + s/.*Stopped.*/A π/; + s/.*Seeding.*/Z π±/; + s/.*100%.*/N β
/; + s/.*Idle.*/B π°οΈ/; + s/.*Uploading.*/L πΌ/; + s/.*%.*/M π½/" | + sort -h | uniq -c | awk '{print $3 $1}' | paste -sd ' ' -) + +if [ -z "$status" ]; then + echo "$status" +else + pidof transmission-daemon >/dev/null && echo "π²" +fi + +case $BLOCK_BUTTON in +1) setsid -f "$TERMINAL" -e stig ;; +2) td-toggle ;; +3) notify-send "π± Torrent module" "\- Left click to open stig +- Middle click to toggle transmission +- Shift click to edit script +Module shows number of torrents: +π: paused +π°: idle (seeds needed) +πΌ: uploading (unfinished) +π½: downloading +β
: done +π±: done and seeding" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac diff --git a/ar/.local/bin/statusbar/sb-volume b/ar/.local/bin/statusbar/sb-volume new file mode 100755 index 0000000..800f19e --- /dev/null +++ b/ar/.local/bin/statusbar/sb-volume @@ -0,0 +1,43 @@ +#!/bin/sh + +# Prints the current volume or π if muted. + +case $BLOCK_BUTTON in +1) + setsid -w -f "$TERMINAL" -e pulsemixer + pkill -RTMIN+5 "${STATUSBAR:-dwmblocks}" + ;; +2) wpctl set-mute @DEFAULT_SINK@ toggle ;; +4) wpctl set-volume @DEFAULT_SINK@ 1%+ ;; +5) wpctl set-volume @DEFAULT_SINK@ 1%- ;; +3) notify-send "π’ Volume module" "\- Shows volume π, π if muted +- Middle click to mute +- Scroll to change" ;; +6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +vol="$(wpctl get-volume @DEFAULT_AUDIO_SINK@)" + +# If muted, print π and exit. +[ "$vol" != "${vol%\[MUTED\]}" ] && echo π && exit + +vol="${vol#Volume: }" + +split() { + # For ommiting the . without calling and external program. + IFS=$2 + set -- $1 + printf '%s' "$@" +} + +vol="$(printf "%.0f" "$(split "$vol" ".")")" + +case 1 in +$((vol > 100))) icon="π’" ;; +$((vol >= 70))) icon="π" ;; +$((vol >= 30))) icon="π" ;; +$((vol >= 1))) icon="π" ;; +*) echo π && exit ;; +esac + +echo "$icon$vol%" |
