X-Git-Url: https://git.madduck.net/etc/awesome.git/blobdiff_plain/4c392a6d980af9c72052145c6a7a812c51e6ecee..5e047618339863d023c6806081e8df3193bd7641:/.config/awesome/lain/widget/fs.lua

diff --git a/.config/awesome/lain/widget/fs.lua b/.config/awesome/lain/widget/fs.lua
index 473bd33..58fbf93 100644
--- a/.config/awesome/lain/widget/fs.lua
+++ b/.config/awesome/lain/widget/fs.lua
@@ -1,24 +1,39 @@
-
 --[[
-                                                  
-     Licensed under GNU General Public License v2 
-      * (c) 2013, Luke Bonham                     
-                                                  
---]]
 
-local helpers  = require("lain.helpers")
-local shell    = require("awful.util").shell
-local focused  = require("awful.screen").focused
-local wibox    = require("wibox")
-local naughty  = require("naughty")
-local string   = string
-local tonumber = tonumber
+     Licensed under GNU General Public License v2
+      * (c) 2018, Uli Schlacter
+      * (c) 2018, Otto Modinos
+      * (c) 2013, Luca CPZ
+
+--]]
 
--- File system disk space usage
+local helpers    = require("lain.helpers")
+local Gio        = require("lgi").Gio
+local focused    = require("awful.screen").focused
+local wibox      = require("wibox")
+local naughty    = require("naughty")
+local math       = math
+local string     = string
+local tconcat    = table.concat
+local type       = type
+local tonumber   = tonumber
+local query_size = Gio.FILE_ATTRIBUTE_FILESYSTEM_SIZE
+local query_free = Gio.FILE_ATTRIBUTE_FILESYSTEM_FREE
+local query_used = Gio.FILE_ATTRIBUTE_FILESYSTEM_USED
+local query      = query_size .. "," .. query_free .. "," .. query_used
+
+-- File systems info
 -- lain.widget.fs
 
 local function factory(args)
-    local fs = { unit  = { ["mb"] = 1024, ["gb"] = 1024^2 }, widget = wibox.widget.textbox() }
+    local fs = {
+        widget = wibox.widget.textbox(),
+        units = {
+            [1] = "Kb", [2] = "Mb", [3] = "Gb",
+            [4] = "Tb", [5] = "Pb", [6] = "Eb",
+            [7] = "Zb", [8] = "Yb"
+        }
+    }
 
     function fs.hide()
         if not fs.notification then return end
@@ -27,29 +42,21 @@ local function factory(args)
     end
 
     function fs.show(seconds, scr)
-        fs.update()
-        fs.hide()
-
-        if fs.followtag then
-            fs.notification_preset.screen = focused()
-        else
-            fs.notification_preset.screen = scr or 1
-        end
-
-        fs.notification = naughty.notify({
+        fs.hide(); fs.update()
+        fs.notification_preset.screen = fs.followtag and focused() or scr or 1
+        fs.notification = naughty.notify {
             preset  = fs.notification_preset,
-            timeout = seconds or 5
-        })
+            timeout = type(seconds) == "number" and seconds or 5
+        }
     end
 
-    local args             = args or {}
-    local timeout          = args.timeout or 600
-    local partition        = args.partition or "/"
-    local showpopup        = args.showpopup or "on"
-    local notify           = args.notify or "on"
-    local settings         = args.settings or function() end
+    local args      = args or {}
+    local timeout   = args.timeout or 600
+    local partition = args.partition
+    local threshold = args.threshold or 99
+    local showpopup = args.showpopup or "on"
+    local settings  = args.settings or function() end
 
-    fs.options             = args.options
     fs.followtag           = args.followtag or false
     fs.notification_preset = args.notification_preset
 
@@ -61,54 +68,74 @@ local function factory(args)
         }
     end
 
-    helpers.set_map(partition, false)
-
     function fs.update()
-        fs_info, fs_now  = {}, {}
-        helpers.async({ shell, "-c", "/usr/bin/env LC_ALL=C df -k --output=target,size,used,avail,pcent" }, function(f)
-            for line in string.gmatch(f, "\n[^\n]+") do
-                local m,s,u,a,p = string.match(line, "(/.-%s).-(%d+).-(%d+).-(%d+).-([%d]+)%%")
-                m = m:gsub(" ", "") -- clean target from any whitespace
-
-                fs_info[m .. " size_mb"]  = string.format("%.1f", tonumber(s) / fs.unit["mb"])
-                fs_info[m .. " size_gb"]  = string.format("%.1f", tonumber(s) / fs.unit["gb"])
-                fs_info[m .. " used_mb"]  = string.format("%.1f", tonumber(u) / fs.unit["mb"])
-                fs_info[m .. " used_gb"]  = string.format("%.1f", tonumber(u) / fs.unit["gb"])
-                fs_info[m .. " used_p"]   = p
-                fs_info[m .. " avail_mb"] = string.format("%.1f", tonumber(a) / fs.unit["mb"])
-                fs_info[m .. " avail_gb"] = string.format("%.1f", tonumber(a) / fs.unit["gb"])
-                fs_info[m .. " avail_p"]  = string.format("%d", 100 - tonumber(p))
+        local notifytable = { [1] = string.format("%-10s %4s\t%6s\t%6s\t\n", "path", "used", "free", "size") }
+        local pathlen = 10
+        local maxpathidx = 1
+        fs_now = {}
+
+        for _, mount in ipairs(Gio.unix_mounts_get()) do
+            local path = Gio.unix_mount_get_mount_path(mount)
+            local root = Gio.File.new_for_path(path)
+            local info = root:query_filesystem_info(query)
+
+            if info then
+                local size = info:get_attribute_uint64(query_size)
+                local used = info:get_attribute_uint64(query_used)
+                local free = info:get_attribute_uint64(query_free)
+
+                if size > 0 then
+                    local units = math.floor(math.log(size)/math.log(1024))
+
+                    fs_now[path] = {
+                        units      = fs.units[units],
+                        percentage = math.floor(100 * used / size), -- used percentage
+                        size       = size / math.pow(1024, math.floor(units)),
+                        used       = used / math.pow(1024, math.floor(units)),
+                        free       = free / math.pow(1024, math.floor(units))
+                    }
+
+                    if fs_now[path].percentage > 0 then -- don't notify unused file systems
+                        notifytable[#notifytable+1] = string.format("\n%-10s %3s%%\t%6.2f\t%6.2f\t%s", path,
+                        math.floor(fs_now[path].percentage), fs_now[path].free, fs_now[path].size,
+                        fs_now[path].units)
+
+                        if #path > pathlen then
+                            pathlen = #path
+                            maxpathidx = #notifytable
+                        end
+                    end
+                end
             end
+        end
+
+        widget = fs.widget
+        settings()
 
-            fs_now.size_mb      = fs_info[partition .. " size_mb"]  or "N/A"
-            fs_now.size_gb      = fs_info[partition .. " size_gb"]  or "N/A"
-            fs_now.used         = fs_info[partition .. " used_p"]   or "N/A"
-            fs_now.used_mb      = fs_info[partition .. " used_mb"]  or "N/A"
-            fs_now.used_gb      = fs_info[partition .. " used_gb"]  or "N/A"
-            fs_now.available    = fs_info[partition .. " avail_p"]  or "N/A"
-            fs_now.available_mb = fs_info[partition .. " avail_mb"] or "N/A"
-            fs_now.available_gb = fs_info[partition .. " avail_gb"] or "N/A"
-
-            notification_preset = fs.notification_preset
-            widget = fs.widget
-            settings()
-
-            if notify == "on" and #fs_now.used > 0 and tonumber(fs_now.used) >= 99 and not helpers.get_map(partition) then
-                naughty.notify({
+        if partition and fs_now[partition] and fs_now[partition].percentage >= threshold then
+            if not helpers.get_map(partition) then
+                naughty.notify {
                     preset = naughty.config.presets.critical,
                     title  = "Warning",
-                    text   = partition .. " is full",
-                })
+                    text   = string.format("%s is above %d%% (%d%%)", partition, threshold, fs_now[partition].percentage)
+                }
                 helpers.set_map(partition, true)
             else
                 helpers.set_map(partition, false)
             end
-        end)
+        end
+
+        if pathlen > 10 then -- if are there paths longer than 10 chars, reformat first column accordingly
+            local pathspaces
+            for i = 1, #notifytable do
+                pathspaces = notifytable[i]:match("[ ]+")
+                if i ~= maxpathidx and pathspaces then
+                    notifytable[i] = notifytable[i]:gsub(pathspaces, pathspaces .. string.rep(" ", pathlen - 10))
+                end
+            end
+        end
 
-        local notifycmd = (fs.options and string.format("dfs %s", fs.options)) or "dfs"
-        helpers.async(helpers.scripts_dir .. notifycmd, function(ws)
-            fs.notification_preset.text = ws:gsub("\n*$", "")
-        end)
+        fs.notification_preset.text = tconcat(notifytable)
     end
 
     if showpopup == "on" then
@@ -116,7 +143,7 @@ local function factory(args)
        fs.widget:connect_signal('mouse::leave', function () fs.hide() end)
     end
 
-    helpers.newtimer(partition, timeout, fs.update)
+    helpers.newtimer(partition or "fs", timeout, fs.update)
 
     return fs
 end