dotfiles

Mahdi's dotfiles
git clone git://mahdi.pw/dotfiles.git
Log | Files | Refs | Submodules | README | LICENSE

dwm-bar (11084B)


      1 #!/bin/sh
      2 # TODO: Add OpenBSD support for Volume, Battery Modules
      3 
      4 # ------------------ #
      5 # ----- Config ----- #
      6 # ------------------ #
      7 # Cache directory
      8 CACHE_DIR=${XDG_CACHE_HOME:-$HOME/.cache}/dwm-bar
      9 [ -d "$CACHE_DIR" ] || mkdir -p "$CACHE_DIR"
     10 
     11 # The location for weather module, the necessary information is parsed from:
     12 # v2d.wttr.in/${WEATHER_LOC}
     13 WEATHER_LOC="Babol"
     14 
     15 # List of modules
     16 full_mods="Weather PublicIP PrivateIP Keyboard Battery Brightness Volume CPUtemp Memory Uptime DTime"
     17 opts_mods="
     18 Volume Memory DTime
     19 Volume CPUtemp Uptime DTime
     20 Keyboard Battery Brightness DTime
     21 Weather Battery Brightness DTime
     22 Weather Keyboard Battery Brightness DTime
     23 Weather PublicIP PrivateIP Uptime DTime
     24 "
     25 
     26 # Store Kernel's Name (Linux/FreeBSD/OpenBSD)
     27 KERNEL=$(uname -s)
     28 
     29 case "$KERNEL" in
     30 	Linux*)
     31 		TEMPERATURE_FILES="
     32 		/sys/class/thermal/thermal_zone0/temp
     33 		/sys/class/thermal/thermal_zone1/temp
     34 		/sys/class/thermal/thermal_zone2/temp
     35 		/sys/class/hwmon/hwmon0/temp1_input
     36 		/sys/class/hwmon/hwmon1/temp1_input
     37 		/sys/class/hwmon/hwmon2/temp1_input
     38 		/sys/class/hwmon/hwmon0/device/temp1_input
     39 		/sys/class/hwmon/hwmon1/device/temp1_input
     40 		/sys/class/hwmon/hwmon2/device/temp1_input
     41 		null
     42 		"
     43 
     44 		for file in $TEMPERATURE_FILES; do
     45 			TEMP_FILE=$file
     46 			[ -f "$TEMP_FILE" ] && break
     47 		done
     48 
     49 		[ "$TEMP_FILE" = "null" ] && unset TEMP_FILE
     50 	;;
     51 esac
     52 
     53 
     54 # ------------------ #
     55 # ---- Modules ----- #
     56 # ------------------ #
     57 Weather(){
     58 	weather_file="$CACHE_DIR/.weather"
     59 	weather_file_last=$(stat -c%Y "$weather_file")
     60 	if [ "$(date +%s)" -ge $((weather_file_last+3600)) ]; then
     61 		for interface in $(find /sys/class/net -depth | \
     62 			sed '/\/lo$/d;/\/net$/d'); do
     63 			if [ "$(cat "$interface" 2>/dev/null)" -eq 1 ]; then
     64 				rm "$weather_file"
     65 				break
     66 			fi
     67 		done
     68 	fi
     69 	weather=$(cat "$weather_file" 2>/dev/null)
     70 	
     71 	if [ ! "$weather" ]; then
     72 		weather=$(curl -s "v2d.wttr.in/$WEATHER_LOC" | \
     73 			sed "/Weather:/!d;s/Weather://;s/,//g;
     74 				s/+//g;s/°C.*//;s/.*m//;s/ //;s/ //;s/ //")
     75 		weather="${weather}°C"
     76 		echo "$weather" > "$weather_file"
     77 	fi
     78 
     79 	[ "$weather" ] && printf "%s" "$weather"
     80 }
     81 
     82 PublicIP(){
     83 	publicip_file="$CACHE_DIR/.publicip"
     84 	publicip_last=$(stat -c%Y "$publicip_file")
     85 	if [ "$(date +%s)" -ge $((publicip_last+300)) ]; then
     86 		for interface in $(find /sys/class/net -depth | \
     87 						 sed '/\/lo$/d;/\/net$/d'); do
     88 			if [ "$(cat "$interface" 2>/dev/null)" -eq 1 ]; then
     89 				rm "$publicip_file"
     90 				break
     91 			fi
     92 		done
     93 	fi
     94 	PUBLIC_IP=$(cat "$publicip_file" 2>/dev/null)
     95 	
     96 	if [ ! "$PUBLIC_IP" ]; then
     97 		RESOLVERS='resolver1.opendns.com resolver2.opendns.com resolver3.opendns.com resolver4.opendns.com'
     98 		for resolver in $RESOLVERS ; do
     99 			PUBLIC_IP=$(host myip.opendns.com "$resolver" | \
    100 				grep "myip.opendns.com has" | awk '{print $4}')
    101 			[ -n "$PUBLIC_IP" ] && break
    102 		done
    103 		echo "$PUBLIC_IP" > "$publicip_file"
    104 	fi
    105 
    106 	[ "$PUBLIC_IP" ] && printf " %s" "$PUBLIC_IP"
    107 }
    108 
    109 PrivateIP(){
    110 	case "$KERNEL" in
    111 		Darwin*|FreeBSD*|OpenBSD*)
    112 			PRIVATE_IP=$(ifconfig | grep "inet " | \
    113 				grep -Fv 127.0.0.1 | awk '{print $2}')
    114 		;;
    115 		Linux*)
    116 			PRIVATE_IP=$(ip a | sed '/inet.*scope global/!d' | \
    117 				grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' | sed -n '1p')
    118 		;;
    119 	esac
    120 
    121 	[ "$PRIVATE_IP" ] && printf " %s" "$PRIVATE_IP"
    122 }
    123 
    124 Keyboard(){
    125 	KBD_LAYOUTS=$(setxkbmap -query | awk '/layout/{print $2}' | \
    126 		tr ',' '\n' | awk '{print NR-1":"$1}')
    127 	KBD=$(xset -q | grep LED | awk '{print substr($10,5,1)}')
    128 	KBD=$(echo "$KBD_LAYOUTS" | sed "/^$KBD:/!d;s/.*://")
    129 	[ "$KBD" ] && printf " %s" "$KBD"
    130 }
    131 
    132 Battery() {
    133 	CHARGING_ICON=''
    134 	WARNING_ICON=''
    135 	BATTERY_FULL_ICON=''
    136 	BATTERY_2_ICON=''
    137 	BATTERY_3_ICON=''
    138 	BATTERY_4_ICON=''
    139 
    140 	FULL_AT=98
    141 	WARNING_AT=15
    142 
    143 	BAT_ICON=""
    144 	ICON=""
    145 
    146 	case "$KERNEL" in
    147 		Linux*)
    148 			BAT=$(find /sys/class/power_supply/ -name "BAT*")
    149 			if [ -d "$BAT" ]; then
    150 				CAPACITY=$(cat "$BAT/capacity")
    151 				CHARGING=$(cat "$BAT/status")
    152 			fi
    153 			[ "$CHARGING" = "Charging" ] && ICON=$CHARGING_ICON 
    154 		;;
    155 		FreeBSD*)
    156 			CAPACITY=$(sysctl -n hw.acpi.battery.life)
    157 			CHARGING=$(sysctl -n hw.acpi.battery.state)
    158 			[ "$CHARGING" -eq 2 ] && ICON=$CHARGING_ICON 
    159 		;;
    160 	esac
    161 
    162 	[ -z "$ICON" ] && [ "$CAPACITY" -le "$WARNING_AT" ] && ICON=$WARNING_ICON
    163 
    164 	if [ "$CAPACITY" -ge "$FULL_AT" ]; then
    165 		BAT_ICON=$BATTERY_FULL_ICON
    166 		CAPACITY=100
    167 	elif [ "$CAPACITY" -le 25 ]; then
    168 		BAT_ICON=$BATTERY_4_ICON
    169 	elif [ "$CAPACITY" -le 60 ]; then
    170 		BAT_ICON=$BATTERY_3_ICON
    171 	elif [ "$CAPACITY" -le "$FULL_AT" ]; then
    172 		BAT_ICON=$BATTERY_2_ICON
    173 	fi
    174 
    175 	[ "$ICON" ]	&& printf "%s " "$ICON"
    176 	[ "$BAT_ICON" ] && printf "%s " "$BAT_ICON"
    177 	[ "$CAPACITY" ] && printf "%s%%" "$CAPACITY"
    178 
    179 	CHARG_BAT="$CACHE_DIR/.battery-charge"
    180 	if [ "$CHARGING" = "Charging" ] || [ "$CHARGING" -eq 2 ]; then
    181 		[ -e "$CHARG_BAT" ] && return;
    182 		touch "$CHARG_BAT"
    183 		notify "Charging - ${ICON} ${BAT_ICON} ${CAPACITY}%"
    184 		rm "$LOW_BAT"
    185 	else
    186 		[ -e "$CHARG_BAT" ] || return;
    187 		notify "Discharging - ${BAT_ICON} ${CAPACITY}%"
    188 		rm "$CHARG_BAT"
    189 	fi
    190 
    191 	LOW_BAT="$CACHE_DIR/.battery-low"
    192 	if [ "$CAPACITY" -le "$WARNING_AT" ] && \
    193 		[ ! -e "$LOW_BAT" ] && [ ! -e "$CHARG_BAT" ]; then
    194 		touch "$LOW_BAT"
    195 		notify "${WARNING_ICON} Low Battery
    196 ${BAT_ICON} ${CAPACITY}% Remains"
    197 	fi
    198 }
    199 
    200 Brightness() {
    201 	case "$KERNEL" in
    202 		*Linux*)
    203 			BRIGHTNESS_CARD=$(find /sys/class/backlight -depth | head -n 1)
    204 			BRIGHTNESS_MAX=$(cat "$BRIGHTNESS_CARD/max_brightness")
    205 			BRIGHTNESS=$(cat "$BRIGHTNESS_CARD/brightness")
    206 			BRIGHTNESS=$((BRIGHTNESS*100/BRIGHTNESS_MAX))
    207 			BRIGHTNESS=${BRIGHTNESS%.*}
    208 		;;
    209 		FreeBSD*)
    210 			BRIGHTNESS=$(backlight | cut -d ' ' -f 2)
    211 		;;
    212 		OpenBSD*)
    213 			BRIGHTNESS=$(apm -l)
    214 		;;
    215 	esac
    216 	if [ "$BRIGHTNESS" -le 25 ]; then
    217 		ICON=""
    218 	elif [ "$BRIGHTNESS" -le 60 ]; then
    219 		ICON=""
    220 	else
    221 		ICON=""
    222 	fi
    223 	[ "$BRIGHTNESS" ] && printf "%s %s%%" "$ICON" "$BRIGHTNESS"
    224 }
    225 
    226 Volume() {
    227 	case "$KERNEL" in
    228 		Linux*)
    229 			if pactl stat >/dev/null 2>&1; then
    230 				DEFAULT_SINK=$(pactl get-default-sink)
    231 				VOLUME=$(pactl get-sink-volume "$DEFAULT_SINK" | \
    232 					awk '/%/{sub(/%/, "", $5);print $5}')
    233 			else
    234 				VOLUME=$(amixer sget Master on | \
    235 					grep -o '[0-9]*%' | sed 's/%//')
    236 			fi
    237 		;;
    238 		FreeBSD*)
    239 			VOLUME=$(mixer -s vol | cut -d ':' -f 2)
    240 		;;
    241 	esac
    242 	if [ "$VOLUME" -le 25 ]; then
    243 		ICON=""
    244 	elif [ "$VOLUME" -le 60 ]; then
    245 		ICON=""
    246 	else
    247 		ICON=""
    248 	fi
    249 	[ "$VOLUME" ] && printf "%s %s%%" "$ICON" "$VOLUME"
    250 }
    251 
    252 CPUtemp() {
    253 	case "$KERNEL" in
    254 		Linux*)
    255 			[ -z "$TEMP_FILE" ] || \
    256 				TEMP=$(sed 's/...$//' "$TEMP_FILE" 2>/dev/null)
    257 		;;
    258 		FreeBSD*)
    259 			TEMP=$(sysctl -n dev.cpu.0.temperature | sed 's/\..*//')
    260 		;;
    261 		OpenBSD*)
    262 			TEMP=$(sysctl hw.sensors | \
    263 				awk -F '=| degC' '/lm0.temp|cpu0.temp/ {print $2; exit}' | \
    264 				sed 's/00/0/')
    265 		;;
    266 	esac
    267 	[ "$TEMP" ] && printf " %s°C" "$TEMP"
    268 }
    269 
    270 Memory() {
    271 	case "$KERNEL" in
    272 		Linux*)
    273 			free=$(awk	'/^MemFree/{free=$2}
    274 					 /^Buffers/{buff=$2}
    275 					 /^Cached/{cached=$2}
    276 					 /^SReclaimable/{rec=$2}
    277 					 /^MemTotal/{total=$2}
    278 					 END{print (free+buff+cached+rec)}' /proc/meminfo)
    279 			total=$(awk '/^MemTotal/ {print $2}' /proc/meminfo)
    280 		;;
    281 		FreeBSD*)
    282 			total=$(sysctl -n hw.physmem)
    283 			pagesize=$(sysctl -n hw.pagesize)
    284 			inactive=$(($(sysctl -n vm.stats.vm.v_inactive_count) * pagesize))
    285     			unused=$(($(sysctl -n vm.stats.vm.v_free_count) * pagesize))
    286     			cache=$(($(sysctl -n vm.stats.vm.v_cache_count) * pagesize))
    287 			free=$((inactive+unused+cache))
    288 		;;
    289 		OpenBSD*)
    290 			total=$(sysctl -n hw.physmem)
    291 			free=$(vmstat | awk 'END {printf $5}')
    292 		;;
    293 	esac
    294 	USAGE=$(((total-free)*100/total))
    295 	[ "$USAGE" ] && printf " %s%%" "${USAGE%.*}"
    296 }
    297 
    298 Uptime() {
    299 	case "$KERNEL" in
    300 		Linux*)
    301 			SECS=$(sed 's/\..*//g' /proc/uptime)
    302 		;;
    303 		*BSD*)
    304 			SECS=$(($(date +%s)-$(sysctl -n kern.boottime | \
    305 				cut -d ',' -f 1 | cut -d '=' -f 2)))
    306 		;;
    307 	esac
    308 	if [ "$SECS" -ge 86400 ]; then
    309 		D=$((SECS / 60 / 60 / 24))
    310 		H=$((SECS / 60/ 60 % 24))
    311 		M=$((SECS / 60 % 60))
    312 		UPTIME="${D}d ${H:-0}h ${M:-0}m"
    313 	elif [ "$SECS" -ge 3600 ]; then
    314 		H=$((SECS / 60/ 60 % 24))
    315 		M=$((SECS / 60 % 60))
    316 		UPTIME="${H}h ${M:-0}m"
    317 	elif [ "$SECS" -ge 60 ]; then
    318 		M=$((SECS / 60 % 60))
    319 		UPTIME="${M}m"
    320 	else
    321 		UPTIME="${SECS}s"
    322 	fi
    323 	[ "$UPTIME" ] && printf " %s" "$UPTIME"
    324 }
    325 
    326 DTime() {
    327 	DAY=$(date +%d | sed -e 's/^0//g')
    328 	day_suffix() {
    329 		case "$DAY" in
    330 			1|01|21|31) echo "st";;
    331 			2|02|22)    echo "nd";;
    332 			3|03|23)    echo "rd";;
    333 			*)          echo "th";;
    334 		esac
    335 	}
    336 	DATE=$(date "+$DAY$(day_suffix) %b %I:%M %p")
    337 	[ "$DATE" ] && printf " %s" "$DATE"
    338 }
    339 
    340 # ------------------ #
    341 # --- Functions ---- #
    342 # ------------------ #
    343 usage() {
    344 	printf "%s [-m modules] [-M] [-h]\n" "$0"
    345 	exit 2
    346 }
    347 stopbar() {
    348 	for pid in $(ps ax | grep "/bin/sh.*dwm-bar" | awk '{print $1}'); do
    349 		[ "$pid" = "$$" ] && continue
    350 		kill -9 "$pid" 2>/dev/null
    351 		wait
    352 	done
    353 }
    354 startbar() {
    355 	c=1
    356 	while ! pgrep -x dwm 2>/dev/null; do
    357 		sleep 1;
    358 		c=$((c+1))
    359 		[ "$c" = 10 ] && exit 2
    360 	done
    361 	mods_list=$(cat "$CACHE_DIR/Modules" 2>/dev/null)
    362 	mods_list=${mods_list:-$full_mods}
    363 	mods=${mods:-$mods_list}
    364 	c=1
    365 	for mod in $mods; do
    366 		mod_prefix=""
    367 		mod_suffix=""
    368 		mod_sep=" | "
    369 		#mod_prefix=" [ "
    370 		#mod_suffix=" ] "
    371 		#mod_sep=""
    372 		if [ "$c" = 1 ]; then
    373 			output="$mod_prefix%$mod%$mod_suffix"
    374 		else
    375 			output="$output$mod_sep$mod_prefix%$mod%$mod_suffix"
    376 		fi
    377 		c=$((c+1))
    378 	done
    379 	# Add padding
    380 	output=" $output "
    381 	while true; do
    382 		out=$output
    383 		for mod in $mods; do
    384 			unset mod_output
    385 			#mod_output=$($mod)
    386 			mod_output=$(cat "$CACHE_DIR/mod-$mod")
    387 			if [ -z "$mod_output" ]; then
    388 				out=$(printf "%s" "$out" | \
    389 					sed "s|$mod_sep$mod_prefix%$mod%$mod_suffix||")
    390 				continue
    391 			fi
    392 			out=$(echo "$out" | sed "s|%$mod%|$mod_output|")
    393 		done
    394 		dwm -s "$out"
    395 		sleep 1
    396 	done
    397 }
    398 
    399 updatebar() {
    400 	mods_list=$(cat "$CACHE_DIR/Modules")
    401 	mods_list=${mods_list:-$full_mods}
    402 	while true; do
    403 		for mod in ${mods:-$mods_list}; do
    404 			printf '%s' "$($mod)" > "$CACHE_DIR/mod-$mod"
    405 		done
    406 	done
    407 }
    408 
    409 main() {
    410 	while getopts "m:M" flag; do
    411 		case "$flag" in
    412 		M)
    413 			full_text="[All Modules]"
    414 			rest="[Restart Modules]"
    415 			cust="[Custom Modules]"
    416 			opts=$(echo "$opts_mods" | \
    417 				sed 's/^[ \t]*//g;/^ *$/d' | column -t)
    418 			choice=$(printf "%s\n" \
    419 				"$full_text" "$rest" "$cust" "$opts" | dmenu -i -l 20)
    420 			[ -z "$choice" ] && choice=$(cat "$CACHE_DIR/Modules")
    421 			case "$choice" in
    422 				"$cust")
    423 					HEIGHT=$(($(echo "$full_mods" | wc -w)+2))
    424 					WIDTH=$(($(echo "$full_mods" | tr ' ' '\n' | wc -L)*2))
    425 					[ "$WIDTH" -lt 30 ] && WIDTH="30"
    426 					"$TERMINAL" -c "st-float" -g "${WIDTH}x${HEIGHT}+400+150" \
    427 						-e sh -c "echo \"$full_mods\" | tr ' ' '\n' | \
    428 							smenu -m \"Select Modules:\" -l -P -n 100 -q | \
    429 							tr '\n' ' ' > \"$CACHE_DIR/Modules.tmp\""
    430 					mods=$(cat "$CACHE_DIR/Modules.tmp")
    431 					[ -z "$mods" ] && mods=$(cat "$CACHE_DIR/Modules")
    432 					rm "$CACHE_DIR/Modules.tmp"
    433 				;;
    434 				"$rest")
    435 					mods=$(cat "$CACHE_DIR/Modules")
    436 				;;
    437 				"$full_text")
    438 					mods=$full_mods
    439 				;;
    440 				*)
    441 					mods=$choice
    442 				;;
    443 			esac
    444 			echo "$mods" > "$CACHE_DIR/Modules"
    445 		;;
    446 		m)
    447 			mods=$OPTARG
    448 			echo "$mods" > "$CACHE_DIR/Modules"
    449 		;;
    450 		*) usage ;;
    451 		esac
    452 	done
    453 
    454 	stopbar
    455 	updatebar &
    456 	startbar &
    457 }
    458 
    459 main "$@"