Re-use AWK components
authorSiraaj Khandkar <siraaj@khandkar.net>
Wed, 29 Aug 2018 18:19:59 +0000 (14:19 -0400)
committerSiraaj Khandkar <siraaj@khandkar.net>
Wed, 29 Aug 2018 18:19:59 +0000 (14:19 -0400)
37 files changed:
.gitignore
Makefile [new file with mode: 0644]
bin/khatus_gen_bar_make_status [new file with mode: 0755]
bin/khatus_gen_make_status_bar [deleted file]
bin/khatus_monitor_devices [deleted file]
bin/khatus_monitor_energy [deleted file]
bin/khatus_monitor_errors [deleted file]
bin/khatus_parse_fan_file [deleted file]
bin/khatus_parse_free [deleted file]
bin/khatus_parse_sys_block_stat [deleted file]
sanity_check
src/awk/exe/actuate_alert_to_notify_send.awk [moved from bin/khatus_actuate_alert_to_notify_send with 54% similarity]
src/awk/exe/actuate_device_add_to_automount.awk [moved from bin/khatus_actuate_device_add_to_automount with 78% similarity]
src/awk/exe/actuate_status_bar_to_xsetroot_name.awk [moved from bin/khatus_actuate_status_bar_to_xsetroot_name with 73% similarity]
src/awk/exe/bar.awk [moved from bin/khatus_bar with 52% similarity]
src/awk/exe/monitor_devices.awk [new file with mode: 0755]
src/awk/exe/monitor_energy.awk [new file with mode: 0755]
src/awk/exe/monitor_errors.awk [new file with mode: 0755]
src/awk/exe/parse_bluetoothctl_show.awk [moved from bin/khatus_parse_bluetoothctl_show with 88% similarity]
src/awk/exe/parse_df_pcent.awk [moved from bin/khatus_parse_df_pcent with 52% similarity]
src/awk/exe/parse_fan_file.awk [new file with mode: 0755]
src/awk/exe/parse_free.awk [new file with mode: 0755]
src/awk/exe/parse_ip_addr.awk [moved from bin/khatus_parse_ip_addr with 91% similarity]
src/awk/exe/parse_iwconfig.awk [moved from bin/khatus_parse_iwconfig with 92% similarity]
src/awk/exe/parse_loadavg_file.awk [moved from bin/khatus_parse_loadavg_file with 77% similarity]
src/awk/exe/parse_metar_d_output.awk [moved from bin/khatus_parse_metar_d_output with 78% similarity]
src/awk/exe/parse_mpd_status_currentsong.awk [moved from bin/khatus_parse_mpd_status_currentsong with 95% similarity]
src/awk/exe/parse_pactl_list_sinks.awk [moved from bin/khatus_parse_pactl_list_sinks with 90% similarity]
src/awk/exe/parse_ps.awk [moved from bin/khatus_parse_ps with 80% similarity]
src/awk/exe/parse_sys_block_stat.awk [new file with mode: 0755]
src/awk/exe/parse_udevadm_monitor_block.awk [moved from bin/khatus_parse_udevadm_monitor_block with 91% similarity]
src/awk/exe/parse_upower.awk [moved from bin/khatus_parse_upower with 91% similarity]
src/awk/lib/alert.awk [new file with mode: 0755]
src/awk/lib/cache.awk [new file with mode: 0755]
src/awk/lib/msg_in.awk [new file with mode: 0755]
src/awk/lib/msg_out.awk [new file with mode: 0755]
src/awk/lib/util.awk [new file with mode: 0755]

index 8fce603..f01981c 100644 (file)
@@ -1 +1,22 @@
 data/
+bin/khatus_bar
+bin/khatus_actuate_alert_to_notify_send
+bin/khatus_actuate_device_add_to_automount
+bin/khatus_actuate_status_bar_to_xsetroot_name
+bin/khatus_monitor_devices
+bin/khatus_monitor_energy
+bin/khatus_monitor_errors
+bin/khatus_parse_bluetoothctl_show
+bin/khatus_parse_df_pcent
+bin/khatus_parse_fan_file
+bin/khatus_parse_free
+bin/khatus_parse_ip_addr
+bin/khatus_parse_iwconfig
+bin/khatus_parse_loadavg_file
+bin/khatus_parse_metar_d_output
+bin/khatus_parse_mpd_status_currentsong
+bin/khatus_parse_pactl_list_sinks
+bin/khatus_parse_ps
+bin/khatus_parse_sys_block_stat
+bin/khatus_parse_udevadm_monitor_block
+bin/khatus_parse_upower
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..9b1553b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,194 @@
+PATH_TO_AWK := /usr/bin/awk
+AWK_EXECUTABLES := \
+       bin/khatus_bar \
+       bin/khatus_actuate_alert_to_notify_send \
+       bin/khatus_actuate_device_add_to_automount \
+       bin/khatus_actuate_status_bar_to_xsetroot_name \
+       bin/khatus_monitor_devices \
+       bin/khatus_monitor_energy \
+       bin/khatus_monitor_errors \
+       bin/khatus_parse_bluetoothctl_show \
+       bin/khatus_parse_df_pcent \
+       bin/khatus_parse_fan_file \
+       bin/khatus_parse_free \
+       bin/khatus_parse_ip_addr \
+       bin/khatus_parse_iwconfig \
+       bin/khatus_parse_loadavg_file \
+       bin/khatus_parse_metar_d_output \
+       bin/khatus_parse_mpd_status_currentsong \
+       bin/khatus_parse_pactl_list_sinks \
+       bin/khatus_parse_ps \
+       bin/khatus_parse_sys_block_stat \
+       bin/khatus_parse_udevadm_monitor_block \
+       bin/khatus_parse_upower
+
+.PHONY: \
+       build \
+       clean
+
+
+build: $(AWK_EXECUTABLES)
+
+clean:
+       rm $(AWK_EXECUTABLES)
+
+
+bin/khatus_bar: \
+       src/awk/exe/bar.awk \
+       src/awk/lib/cache.awk \
+       src/awk/lib/msg_in.awk \
+       src/awk/lib/msg_out.awk \
+       src/awk/lib/util.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_actuate_alert_to_notify_send: \
+       src/awk/exe/actuate_alert_to_notify_send.awk \
+       src/awk/lib/msg_in.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_actuate_device_add_to_automount: \
+       src/awk/exe/actuate_device_add_to_automount.awk \
+       src/awk/lib/msg_in.awk \
+       src/awk/lib/msg_out.awk \
+       src/awk/lib/alert.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_actuate_status_bar_to_xsetroot_name: \
+       src/awk/exe/actuate_status_bar_to_xsetroot_name.awk \
+       src/awk/lib/msg_in.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_monitor_devices: \
+       src/awk/exe/monitor_devices.awk \
+       src/awk/lib/msg_in.awk \
+       src/awk/lib/msg_out.awk \
+       src/awk/lib/alert.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_monitor_energy: \
+       src/awk/exe/monitor_energy.awk \
+       src/awk/lib/msg_in.awk \
+       src/awk/lib/msg_out.awk \
+       src/awk/lib/alert.awk \
+       src/awk/lib/util.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_monitor_errors: \
+       src/awk/exe/monitor_errors.awk \
+       src/awk/lib/msg_in.awk \
+       src/awk/lib/msg_out.awk \
+       src/awk/lib/alert.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_bluetoothctl_show: \
+       src/awk/exe/parse_bluetoothctl_show.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_df_pcent: \
+       src/awk/exe/parse_df_pcent.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_fan_file: \
+       src/awk/exe/parse_fan_file.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_free: \
+       src/awk/exe/parse_free.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_ip_addr: \
+       src/awk/exe/parse_ip_addr.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_iwconfig: \
+       src/awk/exe/parse_iwconfig.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_loadavg_file: \
+       src/awk/exe/parse_loadavg_file.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_metar_d_output: \
+       src/awk/exe/parse_metar_d_output.awk \
+       src/awk/lib/msg_out.awk \
+       src/awk/lib/util.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_mpd_status_currentsong: \
+       src/awk/exe/parse_mpd_status_currentsong.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_pactl_list_sinks: \
+       src/awk/exe/parse_pactl_list_sinks.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_ps: \
+       src/awk/exe/parse_ps.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_sys_block_stat: \
+       src/awk/exe/parse_sys_block_stat.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_udevadm_monitor_block: \
+       src/awk/exe/parse_udevadm_monitor_block.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
+
+bin/khatus_parse_upower: \
+       src/awk/exe/parse_upower.awk \
+       src/awk/lib/msg_out.awk
+       echo '#! $(PATH_TO_AWK) -f' > $@
+       cat $^ >> $@
+       chmod +x $@
diff --git a/bin/khatus_gen_bar_make_status b/bin/khatus_gen_bar_make_status
new file mode 100755 (executable)
index 0000000..00e5506
--- /dev/null
@@ -0,0 +1,39 @@
+#! /usr/bin/awk -f
+
+BEGIN {
+    aliases["@energy"]    = "bar_make_status_energy()"
+    aliases["@memory"]    = "bar_make_status_mem()"
+    aliases["@processes"] = "bar_make_status_procs()"
+    aliases["@cpu"]       = "bar_make_status_cpu()"
+    aliases["@disk"]      = "bar_make_status_disk()"
+    aliases["@net"]       = "bar_make_status_net()"
+    aliases["@bluetooth"] = "bar_make_status_bluetooth()"
+    aliases["@backlight"] = "bar_make_status_screen_brightness()"
+    aliases["@volume"]    = "bar_make_status_volume()"
+    aliases["@mpd"]       = "bar_make_status_mpd()"
+    aliases["@weather"]   = "bar_make_status_weather()"
+    aliases["@datetime"]  = "bar_make_status_datetime()"
+    out = "function bar_make_status(    position, bar, sep, i, j) {\n"
+    n = split(Status_Bar, s, ",")
+    for (i=1; i<=n; i++) {
+        alias = s[i]
+        function_call = aliases[alias]
+        if (function_call) {
+            out = out "        position[++i] = " function_call ";\n"
+        } else {
+            printf("Unexpected status bar component alias: \"%s\"\n", alias) \
+                > "/dev/stderr"
+            exit(1)
+        }
+    }
+    out = out "\
+        bar = \"\";\
+        sep = \"\";\
+        for (j = 1; j <= i; j++) {\
+           bar = bar sep position[j];\
+           sep = \" \";\
+        }\
+        return bar;\
+    }";
+    print out
+}
diff --git a/bin/khatus_gen_make_status_bar b/bin/khatus_gen_make_status_bar
deleted file mode 100755 (executable)
index 50e1b03..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    aliases["@energy"]    = "make_status_energy()"
-    aliases["@memory"]    = "make_status_mem()"
-    aliases["@processes"] = "make_status_procs()"
-    aliases["@cpu"]       = "make_status_cpu()"
-    aliases["@disk"]      = "make_status_disk()"
-    aliases["@net"]       = "make_status_net()"
-    aliases["@bluetooth"] = "make_status_bluetooth()"
-    aliases["@backlight"] = "make_status_screen_brightness()"
-    aliases["@volume"]    = "make_status_volume()"
-    aliases["@mpd"]       = "make_status_mpd()"
-    aliases["@weather"]   = "make_status_weather()"
-    aliases["@datetime"]  = "make_status_datetime()"
-    out = "function make_status_bar(    position, bar, sep, i, j) {\n"
-    n = split(Status_Bar, s, ",")
-    for (i=1; i<=n; i++) {
-        alias = s[i]
-        function_call = aliases[alias]
-        if (function_call) {
-            out = out "        position[++i] = " function_call ";\n"
-        } else {
-            printf("Unexpected status bar component alias: \"%s\"\n", alias) \
-                > "/dev/stderr"
-            exit(1)
-        }
-    }
-    out = out "\
-        bar = \"\";\
-        sep = \"\";\
-        for (j = 1; j <= i; j++) {\
-           bar = bar sep position[j];\
-           sep = \" \";\
-        }\
-        return bar;\
-    }";
-    print out
-}
diff --git a/bin/khatus_monitor_devices b/bin/khatus_monitor_devices
deleted file mode 100755 (executable)
index 915933c..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-     FS = msg_fs ? msg_fs : "|"
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
-$1 == "OK" && \
-$2 == "khatus_sensor_devices" \
-{
-    alert("low", "BlockDeviceEvent", $3 " " $4)
-}
-
-function alert(priority, subject, body) {
-    # priority : "low" | "med" | "hi"
-    # subject  : no spaces
-    # body     : anything
-    print("OK", "khatus_monitor_devices", "alert", priority, subject, body)
-}
diff --git a/bin/khatus_monitor_energy b/bin/khatus_monitor_energy
deleted file mode 100755 (executable)
index 24a4b74..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-     FS = msg_fs ? msg_fs : "|"
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-
-    # TODO: Read spec from a file
-    bat_alert_spec[100] = "low|Energy_Bellow_Full|Must have perfection!"
-    bat_alert_spec[50] = "low|Energy_Bellow_Half|Where is the charger?"
-    bat_alert_spec[20] = "med|Energy_Low|Get the charger."
-    bat_alert_spec[15] = "med|Energy_Low|Get the charger!"
-    bat_alert_spec[10] = "hi|Energy_Low|Plug it in, ASAP!"
-    bat_alert_spec[5]  = "hi|Energy_CRITICALLY_Low|CHARGE NOW!!! GO GO GO!!!"
-}
-
-$1 == "OK" && \
-$2 == "khatus_sensor_energy" && \
-$3 == "line_power" {
-    line_power_prev = line_power_curr
-    line_power_curr = $4
-    if (line_power_curr == "no" && line_power_prev != "no") {
-        alert("low", "PowerUnplugged", "")
-    }
-}
-
-$1 == "OK" && \
-$2 == "khatus_sensor_energy" && \
-$3 == "battery_state" {
-    battery_state_prev = battery_state_curr
-    battery_state_curr = $4
-}
-
-$1 == "OK" && \
-$2 == "khatus_sensor_energy" && \
-$3 == "battery_percentage" {
-    # TODO: Re-think the spec - can't rely on order of keys
-    battery_percentage = ensure_numeric($4)
-    if (battery_state_curr == "discharging") {
-        for (threshold in bat_alert_spec) {
-            threshold = ensure_numeric(threshold)
-            if (battery_percentage <= threshold && !alerted[threshold]) {
-                split(bat_alert_spec[threshold], msg, "|")
-                priority = msg[1]
-                subject = msg[2]
-                body = sprintf("%d%% %s", battery_percentage, msg[3])
-                alert(priority, subject, body)
-                alerted[threshold]++
-            }
-        }
-    } else {
-        delete alerted
-    }
-}
-
-function alert(priority, subject, body) {
-    # priority : "low" | "med" | "hi"
-    # subject  : no spaces
-    # body     : anything
-    print("OK", "khatus_monitor_energy", "alert", priority, subject, body)
-}
-
-function ensure_numeric(n) {
-    return n + 0
-}
-
-#-------------------------------
-# Why do we need ensure_numeric?
-#-------------------------------
-# awk appears to be guessing the type of an inputted scalar based on usage, so
-# if we read-in a number, but did not use it in any numeric operations, but did
-# use as a string (even in just a format string!) - it will be treated as a
-# string and can lead to REALLY SURPRISING behavior in conditional statements,
-# where smaller number may compare as greater than the bigger ones, such as.
-#
-# Demo:
-#
-# $ awk 'BEGIN {x = "75"; y = "100"; sprintf("x: %d, y: %d\n", x, y); if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
-# 75 < 100
-# $ awk 'BEGIN {x = "75"; y = "100"; sprintf("x: %s, y: %d\n", x, y); if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
-# 75 > 100
-
-# However, once used as a number, seems to stay that way even after being
-# used as string:
-#
-# $ awk 'BEGIN {x = "75"; y = "100"; x + y; sprintf("x: %s, y: %d\n", x, y); if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
-# 75 < 100
-# 
-# $ awk 'BEGIN {x = "75"; y = "100"; x + y; sprintf("x: %s, y: %d\n", x, y); z = x y; if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
-# 75 < 100
-# 
-# $ awk 'BEGIN {x = "75"; y = "100"; x + y; z = x y; if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
-# 75 < 100
-# $ awk 'BEGIN {x = "75"; y = "100"; z = x y; if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
-# 75 > 100
diff --git a/bin/khatus_monitor_errors b/bin/khatus_monitor_errors
deleted file mode 100755 (executable)
index 5f3f3b1..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-     FS = msg_fs ? msg_fs : "|"
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
-/^ERROR/ {
-    src = $2
-    # Not just using $6 for body - because body might contain a character
-    # identical to FS
-    len_line = length($0)
-    len_head = length($1 FS $2 FS)
-    len_body = len_line - len_head
-    body = substr($0, len_head + 1, len_body)
-    alert("hi", "Error_in_" src, body)
-}
-
-function alert(priority, subject, body) {
-    # priority : "low" | "med" | "hi"
-    # subject  : no spaces
-    # body     : anything
-    print("OK", "khatus_monitor_errors", "alert", priority, subject, body)
-}
diff --git a/bin/khatus_parse_fan_file b/bin/khatus_parse_fan_file
deleted file mode 100755 (executable)
index 120e150..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
-{
-    key = $1
-    sub(":$", "", key)
-    val = $2
-    print(key, val)
-}
diff --git a/bin/khatus_parse_free b/bin/khatus_parse_free
deleted file mode 100755 (executable)
index 452f44d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
-$1 == "Mem:" {
-    print("total", $2)
-    print("used" , $3)
-}
diff --git a/bin/khatus_parse_sys_block_stat b/bin/khatus_parse_sys_block_stat
deleted file mode 100755 (executable)
index 923e3ee..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
-{
-    print("sectors_read"   , $3)
-    print("sectors_written", $7)
-}
index b9022a1..ed7f574 100755 (executable)
@@ -9,7 +9,7 @@
         -v Opt_Net_Interfaces_To_Show=wlp3s0 \
         -v Opt_Pulseaudio_Sink=0 \
         -v GC_Interval=300 \
-        -f <(./bin/khatus_gen_make_status_bar \
+        -f <(./bin/khatus_gen_bar_make_status \
                 -v Status_Bar='@energy,@memory,@processes,@cpu,@disk,@net,@bluetooth,@backlight,@volume,@mpd,@weather,@datetime' \
             ) \
     ) \
similarity index 54%
rename from bin/khatus_actuate_alert_to_notify_send
rename to src/awk/exe/actuate_alert_to_notify_send.awk
index e383917..eae5cb5 100755 (executable)
@@ -1,31 +1,23 @@
-#! /usr/bin/awk -f
-
 BEGIN {
     # Set the correct value as any other AWK variable:
     #
-    #   khatus_actuate_alert_to_notify_send -v display="$CORRECT_DISPLAY"
+    #   khatus_actuate_alert_to_notify_send -v Display="$CORRECT_DISPLAY"
     #
-    display = ":0"
-     FS = msg_fs ? msg_fs : "|"
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
+    Display = Display ? Display : ":0"
 }
 
 $1 == "OK" && \
-$3 == "alert" {
-    src      = $2
-    priority = $4
-    subject  = $5
+$2 == "alert" {
+    priority = $3
+    subject  = $4
 
-    # Not just using $6 for body - because body might contain a character
+    # Not just using $5 for body - because body might contain a character
     # identical to FS
     len_line = length($0)
     len_head = length($1 FS $2 FS $3 FS $4 FS $5 FS)
     len_body = len_line - len_head
     body = substr($0, len_head + 1, len_body)
 
-    sep = body ? "\n" : ""
-    body = body sep "--" src
     urgency = priority
     sub("hi" , "critical", urgency)
     sub("med", "normal"  , urgency)
@@ -33,7 +25,7 @@ $3 == "alert" {
     cmd = \
         sprintf(\
             "DISPLAY=%s notify-send -u %s %s \" %s\"",
-            display, urgency, subject, body \
+            Display, urgency, subject, body \
         )
     system(cmd)
     next
similarity index 78%
rename from bin/khatus_actuate_device_add_to_automount
rename to src/awk/exe/actuate_device_add_to_automount.awk
index a1e1448..9db7e9e 100755 (executable)
@@ -1,10 +1,4 @@
-#! /usr/bin/awk -f
-
 BEGIN {
-     FS = msg_fs ? msg_fs : "|"
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-    Module = "khatus_actuate_device_add_to_automount"
     # Typically some file manager (thunar, pcmanfm, etc.), but can be whatever.
     Execute_On_Mount = Execute_On_Mount ? Execute_On_Mount : ""
 }
@@ -46,10 +40,3 @@ function mount_device(path,    cmd, line, lines, line_count, status, i,
         alert("hi", "failed-to-mount-device", path)
     }
 }
-
-function alert(priority, subject, body) {
-    # priority : "low" | "med" | "hi"
-    # subject  : no spaces
-    # body     : anything
-    print("OK", Module, "alert", priority, subject, body)
-}
similarity index 73%
rename from bin/khatus_actuate_status_bar_to_xsetroot_name
rename to src/awk/exe/actuate_status_bar_to_xsetroot_name.awk
index f41cbd1..60966c3 100755 (executable)
@@ -1,11 +1,3 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-     FS = msg_fs ? msg_fs : "|"
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
 $1 == "OK" && \
 $2 == "khatus_bar" && \
 $3 == "status_bar" {
similarity index 52%
rename from bin/khatus_bar
rename to src/awk/exe/bar.awk
index b8e47e6..6862ee8 100755 (executable)
@@ -1,5 +1,3 @@
-#! /usr/bin/awk -f
-
 # Naming convention:
 #     Variables:
 #         - global, builtin : ALLCAPS
@@ -9,33 +7,6 @@
 #     Functions:
 #         - global, public  : snake_case
 
-BEGIN {
-     FS = msg_fs ? msg_fs : "|"
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-    GC_Interval = GC_Interval ? GC_Interval : 3600  # seconds
-
-    _total_to_diff["khatus_sensor_net_addr_io", "bytes_read"     ] = 1
-    _total_to_diff["khatus_sensor_net_addr_io", "bytes_written"  ] = 1
-    _total_to_diff["khatus_sensor_disk_io"    , "sectors_read"   ] = 1
-    _total_to_diff["khatus_sensor_disk_io"    , "sectors_written"] = 1
-
-    # (x * y) / z = x * w
-    #   ==> w = y / z
-    # (x * bytes_per_sector) / bytes_per_mb = x * scaling_factor
-    #   ==> scaling_factor = bytes_per_sector / bytes_per_mb
-    _bytes_per_sector = 512
-    _bytes_per_mb     = 1024 * 1024
-    _scale["khatus_sensor_disk_io", "sectors_written"] = _bytes_per_sector / _bytes_per_mb
-    _scale["khatus_sensor_disk_io", "sectors_read"   ] = _bytes_per_sector / _bytes_per_mb
-    # (x / y) = x * z
-    #   ==> z = 1 / y
-    # x / bytes_per_mb = x * scaling_factor
-    #   ==> scaling_factor = 1 / bytes_per_mb
-    _scale["khatus_sensor_net_addr_io", "bytes_written"] = 1 / _bytes_per_mb
-    _scale["khatus_sensor_net_addr_io", "bytes_read"   ] = 1 / _bytes_per_mb
-}
-
 # -----------------------------------------------------------------------------
 # Input
 # -----------------------------------------------------------------------------
@@ -45,105 +16,17 @@ $1 == "OK" {
 
 $1 == "OK" && \
 $2 == "khatus_sensor_datetime" {
-    # Code for make_status_bar definition is expected to be passed as an
+    # Code for bar_make_status is expected to be passed as an
     # additional source file, using  -f  flag.
-    print_msg_ok("status_bar", make_status_bar())
-}
-
-# -----------------------------------------------------------------------------
-# Cache
-# -----------------------------------------------------------------------------
-
-function cache_update(    src, key, val, len_line, len_head, len_val, time) {
-    src = $2
-    key = $3
-    # Not just using $4 for val - because an unstructured value (like name of a
-    # song) might contain a character identical to FS
-    len_line = length($0)
-    len_head = length($1 FS $2 FS $3 FS)
-    len_val  = len_line - len_head
-    val = substr($0, len_head + 1, len_val)
-    val = cache_maybe_total_to_diff(src, key, val)
-    val = cache_maybe_scale(src, key, val)
-    _cache[src, key] = val
-    time = cache_get_time()
-    _cache_mtime[src, key] = time
-    if (time % GC_Interval == 0) {
-        cache_gc()
-    }
-}
-
-function cache_get(result, src, key, ttl,    time, age, is_expired) {
-    time = cache_get_time()
-    _cache_atime[src, key] = time
-    age = time - _cache_mtime[src, key]
-    result["is_expired"] = ttl && age > ttl  # ttl = 0 => forever
-    result["value"] = _cache[src, key]
-}
-
-function cache_res_fmt_or_def(result, format, default) {
-    return result["is_expired"] ? default : sprintf(format, result["value"])
-}
-
-function cache_get_fmt_def(src, key, ttl, format, default,    result) {
-    default = default ? default : "--"
-    cache_get(result, src, key, ttl)
-    return cache_res_fmt_or_def(result, format, default)
-}
-
-function cache_get_time(    src, key, time) {
-    src = "khatus_sensor_datetime"
-    key = "epoch"
-    time = _cache[src, key]
-    _cache_atime[src, key] = time
-    return time
+    msg_out_ok("status_bar", bar_make_status())
 }
 
-function cache_gc(    src_and_key, parts, src, key, unused_for) {
-    for (src_and_key in _cache) {
-        split(src_and_key, parts, SUBSEP)
-        src = parts[1]
-        key = parts[2]
-        val = _cache[src, key]
-        unused_for = cache_get_time() - _cache_atime[src, key]
-        if (unused_for > GC_Interval) {
-            print_msg_info(\
-                "cache_gc",
-                sprintf(\
-                    "Deleting unused data SRC=%s KEY=%s VAL=%s",
-                    src, key, val\
-                ) \
-            )
-            delete _cache[src, key]
-        }
-    }
-}
-
-function cache_maybe_total_to_diff(src, key, val,    key_parts) {
-    split(key, key_parts, Kfs)
-    if (_total_to_diff[src, key_parts[1]]) {
-        _prev[src, key] = _curr[src, key]
-        _curr[src, key] = val
-        return (_curr[src, key] - _prev[src, key])
-    } else {
-        return val
-    }
-}
-
-function cache_maybe_scale(src, key, val,    key_parts) {
-    split(key, key_parts, Kfs)
-    if ((src SUBSEP key_parts[1]) in _scale) {
-        return val * _scale[src, key_parts[1]]
-    } else {
-        return val
-    }
-}
 
 # -----------------------------------------------------------------------------
 # Status bar
 # -----------------------------------------------------------------------------
 
-function make_status_energy(    state, charge, direction_of_change) {
+function bar_make_status_energy(    state, charge, direction_of_change) {
     cache_get(state , "khatus_sensor_energy", "battery_state"     , 0)
     cache_get(charge, "khatus_sensor_energy", "battery_percentage", 0)
 
@@ -158,7 +41,7 @@ function make_status_energy(    state, charge, direction_of_change) {
     return sprintf("E%s%d%%", direction_of_change, charge["value"])
 }
 
-function make_status_mem(    total, used, percent, status) {
+function bar_make_status_mem(    total, used, percent, status) {
     cache_get(total, "khatus_sensor_memory", "total", 5)
     cache_get(used , "khatus_sensor_memory", "used" , 5)
     # Checking total["value"] to avoid division by zero when data is missing
@@ -166,7 +49,7 @@ function make_status_mem(    total, used, percent, status) {
         !used["is_expired"] && \
         total["value"] \
         ) {
-        percent = round((used["value"] / total["value"]) * 100)
+        percent = util_round((used["value"] / total["value"]) * 100)
         status = sprintf("%d%%", percent)
     } else {
         status = "__"
@@ -174,7 +57,7 @@ function make_status_mem(    total, used, percent, status) {
     return sprintf("M=%s", status)
 }
 
-function make_status_procs() {
+function bar_make_status_procs() {
     # From man ps:
     #   D    uninterruptible sleep (usually IO)
     #   R    running or runnable (on run queue)
@@ -198,7 +81,7 @@ function make_status_procs() {
     return sprintf("P=[%s %sr %sd %st %si %sz]", all, r, d, t, i, z)
 }
 
-function make_status_cpu(    l, t, f) {
+function bar_make_status_cpu(    l, t, f) {
     l_src = "khatus_sensor_loadavg"
     t_src = "khatus_sensor_temperature"
     f_src = "khatus_sensor_fan"
@@ -208,7 +91,7 @@ function make_status_cpu(    l, t, f) {
     return sprintf("C=[%s %s°C %srpm]", l, t, f)
 }
 
-function make_status_disk(    u, w, r, src_u, src_io) {
+function bar_make_status_disk(    u, w, r, src_u, src_io) {
     src_u  = "khatus_sensor_disk_space"
     src_io = "khatus_sensor_disk_io"
     u = cache_get_fmt_def(src_u , "disk_usage_percentage", 10, "%s")
@@ -217,7 +100,7 @@ function make_status_disk(    u, w, r, src_u, src_io) {
     return sprintf("D=[%s%% %s▲ %s▼]", u, w, r)
 }
 
-function make_status_net(    \
+function bar_make_status_net(    \
     number_of_net_interfaces_to_show, \
     net_interfaces_to_show, \
     io, \
@@ -256,19 +139,19 @@ function make_status_net(    \
     return sprintf("N[%s]", out)
 }
 
-function make_status_bluetooth(    src, key) {
+function bar_make_status_bluetooth(    src, key) {
     src = "khatus_sensor_bluetooth_power"
     key = "power_status"
     return sprintf("B=%s", cache_get_fmt_def(src, key, 10, "%s"))
 }
 
-function make_status_screen_brightness(    src, key) {
+function bar_make_status_screen_brightness(    src, key) {
     src = "khatus_sensor_screen_brightness"
     key = "percentage"
     return sprintf("*%s%%", cache_get_fmt_def(src, key, 5, "%d"))
 }
 
-function make_status_volume(    sink, mu, vl, vr, show) {
+function bar_make_status_volume(    sink, mu, vl, vr, show) {
     sink = Opt_Pulseaudio_Sink
     cache_get(mu, "khatus_sensor_volume", "mute"      Kfs sink, 5)
     cache_get(vl, "khatus_sensor_volume", "vol_left"  Kfs sink, 5)
@@ -278,8 +161,8 @@ function make_status_volume(    sink, mu, vl, vr, show) {
              if (mu["value"] == "yes") {show = "X"}
         else if (mu["value"] == "no")  {show = vl["value"] " " vr["value"]}
         else {
-            print_msg_error(\
-                "make_status_volume", \
+            msg_out_error(\
+                "bar_make_status_volume", \
                 "Unexpected value for 'mute' field: " mu["value"] \
             )
         }
@@ -287,18 +170,18 @@ function make_status_volume(    sink, mu, vl, vr, show) {
     return sprintf("(%s)", show)
 }
 
-function make_status_mpd(    state, status) {
+function bar_make_status_mpd(    state, status) {
     cache_get(state, "khatus_sensor_mpd", "state", 5)
     if (!state["is_expired"] && state["value"]) {
         if (state["value"] == "play") {
-            status = make_status_mpd_state_known("▶")
+            status = bar_make_status_mpd_state_known("▶")
         } else if (state["value"] == "pause") {
-            status = make_status_mpd_state_known("❚❚")
+            status = bar_make_status_mpd_state_known("❚❚")
         } else if (state["value"] == "stop") {
-            status = make_status_mpd_state_known("⬛")
+            status = bar_make_status_mpd_state_known("⬛")
         } else {
-            print_msg_error(\
-                "make_status_mpd", \
+            msg_out_error(\
+                "bar_make_status_mpd", \
                 "Unexpected value for 'state' field: " state["value"] \
             )
             status = "--"
@@ -310,7 +193,7 @@ function make_status_mpd(    state, status) {
     return sprintf("[%s]", status)
 }
 
-function make_status_mpd_state_known(symbol,    s, song, time, percentage) {
+function bar_make_status_mpd_state_known(symbol,    s, song, time, percentage) {
     s = "khatus_sensor_mpd"
     song    = cache_get_fmt_def(s, "song"                   , 5, "%s", "?")
     time    = cache_get_fmt_def(s, "play_time_minimal_units", 5, "%s", "?")
@@ -319,41 +202,13 @@ function make_status_mpd_state_known(symbol,    s, song, time, percentage) {
     return sprintf("%s %s %s %s", symbol, time, percent, song)
 }
 
-function make_status_weather(    src, hour, t_f) {
+function bar_make_status_weather(    src, hour, t_f) {
     src = "khatus_sensor_weather"
     hour = 60 * 60
     t_f = cache_get_fmt_def(src, "temperature_f", 3 * hour, "%d")
     return sprintf("%s°F", t_f)
 }
 
-function make_status_datetime(    dt) {
+function bar_make_status_datetime(    dt) {
     return cache_get_fmt_def("khatus_sensor_datetime", "datetime", 5, "%s")
 }
-
-# -----------------------------------------------------------------------------
-# Output
-# -----------------------------------------------------------------------------
-
-function print_msg_ok(key, val) {
-    print_msg("OK", key, val, "/dev/stdout")
-}
-
-function print_msg_info(location, msg) {
-    print_msg("INFO", location, msg, "/dev/stderr")
-}
-
-function print_msg_error(location, msg) {
-    print_msg("ERROR", location, msg, "/dev/stderr")
-}
-
-function print_msg(status, key, val, channel) {
-    print(status, "khatus_bar", key, val) > channel
-}
-
-# -----------------------------------------------------------------------------
-# Numbers
-# -----------------------------------------------------------------------------
-
-function round(n) {
-    return int(n + 0.5)
-}
diff --git a/src/awk/exe/monitor_devices.awk b/src/awk/exe/monitor_devices.awk
new file mode 100755 (executable)
index 0000000..a37a30c
--- /dev/null
@@ -0,0 +1,5 @@
+$1 == "OK" && \
+$2 == "khatus_sensor_devices" \
+{
+    alert("low", "BlockDeviceEvent", $3 " " $4)
+}
diff --git a/src/awk/exe/monitor_energy.awk b/src/awk/exe/monitor_energy.awk
new file mode 100755 (executable)
index 0000000..0730ec7
--- /dev/null
@@ -0,0 +1,48 @@
+BEGIN {
+    # TODO: Read spec from a file
+    bat_alert_spec[100] = "low|Energy_Bellow_Full|Must have perfection!"
+    bat_alert_spec[50] = "low|Energy_Bellow_Half|Where is the charger?"
+    bat_alert_spec[20] = "med|Energy_Low|Get the charger."
+    bat_alert_spec[15] = "med|Energy_Low|Get the charger!"
+    bat_alert_spec[10] = "hi|Energy_Low|Plug it in, ASAP!"
+    bat_alert_spec[5]  = "hi|Energy_CRITICALLY_Low|CHARGE NOW!!! GO GO GO!!!"
+}
+
+$1 == "OK" && \
+$2 == "khatus_sensor_energy" && \
+$3 == "line_power" {
+    line_power_prev = line_power_curr
+    line_power_curr = $4
+    if (line_power_curr == "no" && line_power_prev != "no") {
+        alert("low", "PowerUnplugged", "")
+    }
+}
+
+$1 == "OK" && \
+$2 == "khatus_sensor_energy" && \
+$3 == "battery_state" {
+    battery_state_prev = battery_state_curr
+    battery_state_curr = $4
+}
+
+$1 == "OK" && \
+$2 == "khatus_sensor_energy" && \
+$3 == "battery_percentage" {
+    # TODO: Re-think the spec - can't rely on order of keys
+    battery_percentage = util_ensure_numeric($4)
+    if (battery_state_curr == "discharging") {
+        for (threshold in bat_alert_spec) {
+            threshold = util_ensure_numeric(threshold)
+            if (battery_percentage <= threshold && !_alerted[threshold]) {
+                split(bat_alert_spec[threshold], msg, "|")
+                priority = msg[1]
+                subject = msg[2]
+                body = sprintf("%d%% %s", battery_percentage, msg[3])
+                alert(priority, subject, body)
+                _alerted[threshold]++
+            }
+        }
+    } else {
+        delete _alerted
+    }
+}
diff --git a/src/awk/exe/monitor_errors.awk b/src/awk/exe/monitor_errors.awk
new file mode 100755 (executable)
index 0000000..a096db7
--- /dev/null
@@ -0,0 +1,10 @@
+/^ERROR/ {
+    src = $2
+    # Not just using $3 for body - because body might contain a character
+    # identical to FS
+    len_line = length($0)
+    len_head = length($1 FS $2 FS)
+    len_body = len_line - len_head
+    body = substr($0, len_head + 1, len_body)
+    alert("hi", "ERROR_IN_" src, body)
+}
similarity index 88%
rename from bin/khatus_parse_bluetoothctl_show
rename to src/awk/exe/parse_bluetoothctl_show.awk
index 0d56853..3a02897 100755 (executable)
@@ -1,10 +1,3 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
 /^Controller / {
     controller = $2
     controllers[++ctrl_count] = controller
similarity index 52%
rename from bin/khatus_parse_df_pcent
rename to src/awk/exe/parse_df_pcent.awk
index 7e4a534..c0925cf 100755 (executable)
@@ -1,10 +1,3 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
 NR == 2 {
        percentage = $1
        sub("%$", "", percentage)
diff --git a/src/awk/exe/parse_fan_file.awk b/src/awk/exe/parse_fan_file.awk
new file mode 100755 (executable)
index 0000000..3f86e88
--- /dev/null
@@ -0,0 +1,6 @@
+{
+    key = $1
+    sub(":$", "", key)
+    val = $2
+    print(key, val)
+}
diff --git a/src/awk/exe/parse_free.awk b/src/awk/exe/parse_free.awk
new file mode 100755 (executable)
index 0000000..3f48327
--- /dev/null
@@ -0,0 +1,4 @@
+$1 == "Mem:" {
+    print("total", $2)
+    print("used" , $3)
+}
similarity index 91%
rename from bin/khatus_parse_ip_addr
rename to src/awk/exe/parse_ip_addr.awk
index b1b2ecd..85333ee 100755 (executable)
@@ -1,10 +1,3 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
 /^[0-9]+:/ {
     sub(":$", "", $1)
     sub(":$", "", $2)
similarity index 92%
rename from bin/khatus_parse_iwconfig
rename to src/awk/exe/parse_iwconfig.awk
index a33b50f..95eedd1 100755 (executable)
@@ -1,5 +1,3 @@
-#! /usr/bin/awk -f
-#
 # Example iwconfig output:
 # -----------------------
 # $ iwconfig wlp3s0
 #
 # USAGE: khatus_parse_iwconfig -v requested_interface="$wifi_interface"
 
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
 /^[a-z0-9]+ +IEEE 802\.11 +ESSID:/ {
     interface = $1
     split($4, essid_parts, ":")
similarity index 77%
rename from bin/khatus_parse_loadavg_file
rename to src/awk/exe/parse_loadavg_file.awk
index f7665fa..22826ca 100755 (executable)
@@ -1,10 +1,3 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
 # 0.71 1.04 1.12 1/325 2409
 {
     split($4, sched, "/")
similarity index 78%
rename from bin/khatus_parse_metar_d_output
rename to src/awk/exe/parse_metar_d_output.awk
index 1dd2778..fa354da 100755 (executable)
@@ -1,13 +1,6 @@
-#! /usr/bin/awk -f
-#
 # Qualifying the name as "_d_output" lest it be mistaken for parser of actual
 # metar format.
 
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
 /METAR pattern not found in NOAA data/ {
     failures++
     exit
@@ -15,15 +8,15 @@ BEGIN {
 
 /[A-z][a-z]+ *: / {
     split($0, line, ":")
-    key = strip(line[1])
-    val = strip(line[2])
+    key = util_strip(line[1])
+    val = util_strip(line[2])
     values[NR] = val
     first[key] = NR
     last[key] = NR
 }
 
 /^ +/ {
-    values[NR] = strip($0)
+    values[NR] = util_strip($0)
     last[key] = NR
 }
 
@@ -45,9 +38,3 @@ END {
         }
     }
 }
-
-function strip(s) {
-    sub("^ *", "", s)
-    sub(" *$", "", s)
-    return s
-}
similarity index 95%
rename from bin/khatus_parse_mpd_status_currentsong
rename to src/awk/exe/parse_mpd_status_currentsong.awk
index c045c0f..c29f5fa 100755 (executable)
@@ -1,10 +1,3 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
 # Msg separator
 /^OK/ {msg_count++; next}
 
similarity index 90%
rename from bin/khatus_parse_pactl_list_sinks
rename to src/awk/exe/parse_pactl_list_sinks.awk
index 7ed10e6..6a2a4a1 100755 (executable)
@@ -1,10 +1,3 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
 /^Sink \#[0-9]+$/ {
     sub("^#", "", $2)
     sink = $2
similarity index 80%
rename from bin/khatus_parse_ps
rename to src/awk/exe/parse_ps.awk
index a0f41c5..518b4f3 100755 (executable)
@@ -1,10 +1,3 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = "|"
-    Kfs = ":"
-}
-
 {
     pid       = $1
     state     = $2
diff --git a/src/awk/exe/parse_sys_block_stat.awk b/src/awk/exe/parse_sys_block_stat.awk
new file mode 100755 (executable)
index 0000000..522dffb
--- /dev/null
@@ -0,0 +1,4 @@
+{
+    print("sectors_read"   , $3)
+    print("sectors_written", $7)
+}
similarity index 91%
rename from bin/khatus_parse_udevadm_monitor_block
rename to src/awk/exe/parse_udevadm_monitor_block.awk
index 75c00c3..6e6326e 100755 (executable)
@@ -1,9 +1,4 @@
-#! /usr/bin/awk -f
-
 BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-
     Re_Begin = "^UDEV + \[ *[0-9]+\.[0-9]+\] +"
 }
 
similarity index 91%
rename from bin/khatus_parse_upower
rename to src/awk/exe/parse_upower.awk
index af73e19..07af1cb 100755 (executable)
@@ -1,10 +1,3 @@
-#! /usr/bin/awk -f
-
-BEGIN {
-    OFS = msg_fs ? msg_fs : "|"
-    Kfs = key_fs ? key_fs : ":"
-}
-
 # When parsing 'upower --dump'
 /^Device:[ \t]+/ {
     device["path"] = $2
diff --git a/src/awk/lib/alert.awk b/src/awk/lib/alert.awk
new file mode 100755 (executable)
index 0000000..c043ea8
--- /dev/null
@@ -0,0 +1,6 @@
+function alert(priority, subject, body) {
+    # priority : "low" | "med" | "hi"
+    # subject  : string without spaces
+    # body     : anything
+    print("OK", "alert", priority, subject, body)
+}
diff --git a/src/awk/lib/cache.awk b/src/awk/lib/cache.awk
new file mode 100755 (executable)
index 0000000..fbdd122
--- /dev/null
@@ -0,0 +1,117 @@
+# Naming convention:
+#     Variables:
+#         - global, builtin : ALLCAPS
+#         - global, public  : Camel_Snake_Man_Bear_Pig
+#         - global, private : _snake_case_prefixed_underscore
+#         - local           : snake_case
+#     Functions:
+#         - global, public  : snake_case
+
+BEGIN {
+    GC_Interval = GC_Interval ? GC_Interval : 3600  # seconds
+
+    _total_to_diff["khatus_sensor_net_addr_io", "bytes_read"     ] = 1
+    _total_to_diff["khatus_sensor_net_addr_io", "bytes_written"  ] = 1
+    _total_to_diff["khatus_sensor_disk_io"    , "sectors_read"   ] = 1
+    _total_to_diff["khatus_sensor_disk_io"    , "sectors_written"] = 1
+
+    # (x * y) / z = x * w
+    #   ==> w = y / z
+    # (x * bytes_per_sector) / bytes_per_mb = x * scaling_factor
+    #   ==> scaling_factor = bytes_per_sector / bytes_per_mb
+    _bytes_per_sector = 512
+    _bytes_per_mb     = 1024 * 1024
+    _scale["khatus_sensor_disk_io", "sectors_written"] = _bytes_per_sector / _bytes_per_mb
+    _scale["khatus_sensor_disk_io", "sectors_read"   ] = _bytes_per_sector / _bytes_per_mb
+    # (x / y) = x * z
+    #   ==> z = 1 / y
+    # x / bytes_per_mb = x * scaling_factor
+    #   ==> scaling_factor = 1 / bytes_per_mb
+    _scale["khatus_sensor_net_addr_io", "bytes_written"] = 1 / _bytes_per_mb
+    _scale["khatus_sensor_net_addr_io", "bytes_read"   ] = 1 / _bytes_per_mb
+}
+
+function cache_update(    src, key, val, len_line, len_head, len_val, time) {
+    src = $2
+    key = $3
+    # Not just using $4 for val - because an unstructured value (like name of a
+    # song) might contain a character identical to FS
+    len_line = length($0)
+    len_head = length($1 FS $2 FS $3 FS)
+    len_val  = len_line - len_head
+    val = substr($0, len_head + 1, len_val)
+    val = cache_maybe_total_to_diff(src, key, val)
+    val = cache_maybe_scale(src, key, val)
+    _cache[src, key] = val
+    time = cache_get_time()
+    _cache_mtime[src, key] = time
+    if (time % GC_Interval == 0) {
+        cache_gc()
+    }
+}
+
+function cache_get(result, src, key, ttl,    time, age, is_expired) {
+    time = cache_get_time()
+    _cache_atime[src, key] = time
+    age = time - _cache_mtime[src, key]
+    result["is_expired"] = ttl && age > ttl  # ttl = 0 => forever
+    result["value"] = _cache[src, key]
+}
+
+function cache_res_fmt_or_def(result, format, default) {
+    return result["is_expired"] ? default : sprintf(format, result["value"])
+}
+
+function cache_get_fmt_def(src, key, ttl, format, default,    result) {
+    default = default ? default : "--"
+    cache_get(result, src, key, ttl)
+    return cache_res_fmt_or_def(result, format, default)
+}
+
+function cache_get_time(    src, key, time) {
+    src = "khatus_sensor_datetime"
+    key = "epoch"
+    time = _cache[src, key]
+    _cache_atime[src, key] = time
+    return time
+}
+
+function cache_gc(    src_and_key, parts, src, key, unused_for) {
+    for (src_and_key in _cache) {
+        split(src_and_key, parts, SUBSEP)
+        src = parts[1]
+        key = parts[2]
+        val = _cache[src, key]
+        unused_for = cache_get_time() - _cache_atime[src, key]
+        if (unused_for > GC_Interval) {
+            msg_out_info(\
+                "cache_gc",
+                sprintf(\
+                    "Deleting unused data SRC=%s KEY=%s VAL=%s",
+                    src, key, val\
+                ) \
+            )
+            delete _cache[src, key]
+        }
+    }
+}
+
+function cache_maybe_total_to_diff(src, key, val,    key_parts) {
+    split(key, key_parts, Kfs)
+    if (_total_to_diff[src, key_parts[1]]) {
+        _prev[src, key] = _curr[src, key]
+        _curr[src, key] = val
+        return (_curr[src, key] - _prev[src, key])
+    } else {
+        return val
+    }
+}
+
+function cache_maybe_scale(src, key, val,    key_parts) {
+    split(key, key_parts, Kfs)
+    if ((src SUBSEP key_parts[1]) in _scale) {
+        return val * _scale[src, key_parts[1]]
+    } else {
+        return val
+    }
+}
diff --git a/src/awk/lib/msg_in.awk b/src/awk/lib/msg_in.awk
new file mode 100755 (executable)
index 0000000..d1f62d6
--- /dev/null
@@ -0,0 +1,4 @@
+BEGIN {
+     FS = Msg_fs ? Msg_fs : "|"
+    Kfs = Key_fs ? Key_fs : ":"
+}
diff --git a/src/awk/lib/msg_out.awk b/src/awk/lib/msg_out.awk
new file mode 100755 (executable)
index 0000000..9207fd0
--- /dev/null
@@ -0,0 +1,20 @@
+BEGIN {
+    OFS = Msg_fs ? Msg_fs : "|"
+    Kfs = Key_fs ? Key_fs : ":"
+}
+
+function msg_out_ok(key, val) {
+    msg_out("OK", key, val, "/dev/stdout")
+}
+
+function msg_out_info(location, msg) {
+    msg_out("INFO", location, msg, "/dev/stderr")
+}
+
+function msg_out_error(location, msg) {
+    msg_out("ERROR", location, msg, "/dev/stderr")
+}
+
+function msg_out(status, key, val, channel) {
+    print(status, key, val) > channel
+}
diff --git a/src/awk/lib/util.awk b/src/awk/lib/util.awk
new file mode 100755 (executable)
index 0000000..b7a92e6
--- /dev/null
@@ -0,0 +1,43 @@
+function util_strip(s) {
+    sub("^ *", "", s)
+    sub(" *$", "", s)
+    return s
+}
+
+function util_round(n) {
+    return int(n + 0.5)
+}
+
+function util_ensure_numeric(n) {
+    return n + 0
+}
+
+#------------------------------------
+# Why do we need util_ensure_numeric?
+#------------------------------------
+# awk appears to be guessing the type of an inputted scalar based on usage, so
+# if we read-in a number, but did not use it in any numeric operations, but did
+# use as a string (even in just a format string!) - it will be treated as a
+# string and can lead to REALLY SURPRISING behavior in conditional statements,
+# where smaller number may compare as greater than the bigger ones, such as.
+#
+# Demo:
+#
+# $ awk 'BEGIN {x = "75"; y = "100"; sprintf("x: %d, y: %d\n", x, y); if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
+# 75 < 100
+# $ awk 'BEGIN {x = "75"; y = "100"; sprintf("x: %s, y: %d\n", x, y); if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
+# 75 > 100
+
+# However, once used as a number, seems to stay that way even after being
+# used as string:
+#
+# $ awk 'BEGIN {x = "75"; y = "100"; x + y; sprintf("x: %s, y: %d\n", x, y); if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
+# 75 < 100
+# 
+# $ awk 'BEGIN {x = "75"; y = "100"; x + y; sprintf("x: %s, y: %d\n", x, y); z = x y; if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
+# 75 < 100
+# 
+# $ awk 'BEGIN {x = "75"; y = "100"; x + y; z = x y; if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
+# 75 < 100
+# $ awk 'BEGIN {x = "75"; y = "100"; z = x y; if (x > y) {print "75 > 100"} else if (x < y) {print "75 < 100"}}'
+# 75 > 100
This page took 0.072356 seconds and 4 git commands to generate.