X-Git-Url: https://git.madduck.net/etc/awesome.git/blobdiff_plain/586c54a25750fd90d91c15ac8eb818b2613de582..f76d33e8cd5bc84f44758e8047294227deb3f29d:/widget/fs.lua?ds=sidebyside diff --git a/widget/fs.lua b/widget/fs.lua index 49345ca..358d4dd 100644 --- a/widget/fs.lua +++ b/widget/fs.lua @@ -1,56 +1,60 @@ - --[[ - - 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 -local setmetatable = setmetatable + Licensed under GNU General Public License v2 + * (c) 2018, Uli Schlacter + * (c) 2018, Otto Modinos + * (c) 2013, Luca CPZ --- File system disk space usage --- lain.widget.fs -local fs = { unit = { ["mb"] = 1024, ["gb"] = 1024^2 } } +--]] -function fs.hide() - if not fs.notification then return end - naughty.destroy(fs.notification) - fs.notification = nil -end +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 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 -function fs.show(seconds, scr) - fs.update() +local function factory(args) + local fs = { + widget = wibox.widget.textbox(), + units = { + [1] = "Kb", [2] = "Mb", [3] = "Gb", + [4] = "Tb", [5] = "Pb", [6] = "Eb", + [7] = "Zb", [8] = "Yb" + } + } - fs.hide() + function fs.hide() + if not fs.notification then return end + naughty.destroy(fs.notification) + fs.notification = nil + end - if fs.followtag then - fs.notification_preset.screen = focused() - elseif scr then - fs.notification_preset.screen = scr or 1 + function fs.show(seconds, scr) + 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 + } end - fs.notification = naughty.notify({ - preset = fs.notification_preset, - timeout = seconds or 5 - }) -end + local args = args or {} + local timeout = args.timeout or 600 + local partition = args.partition + local showpopup = args.showpopup or "on" + local settings = args.settings or function() end -local function factory(args) - 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 - - fs.options = args.options fs.followtag = args.followtag or false fs.notification_preset = args.notification_preset @@ -62,56 +66,67 @@ local function factory(args) } end - fs.widget = wibox.widget.textbox() - - 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 %-5s %s\t%s\t\n", "path", "used", "free", "size") } + local pathlen = 10 + 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 %-5s %.2f\t%.2f\t%s", path, + fs_now[path].percentage .. "%", fs_now[path].free, fs_now[path].size, + fs_now[path].units) + + pathlen = math.max(pathlen, #path) + 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].used >= 99 then + if not helpers.get_map(partition) then + naughty.notify { preset = naughty.config.presets.critical, title = "Warning", - text = partition .. " is empty", - }) + text = partition .. " is full", + } helpers.set_map(partition, true) else helpers.set_map(partition, false) end - end) + end + + if pathlen > 10 then -- formatting aesthetics + for i = 1, #notifytable do + local pathspaces = notifytable[i]:match("/%w*[/%w*]*%s*") or notifytable[i]:match("path%s*") + notifytable[i] = notifytable[i]:gsub(pathspaces, pathspaces .. string.rep(" ", pathlen - 10) .. "\t") + 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 @@ -119,9 +134,9 @@ 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 -return setmetatable(fs, { __call = function(_, ...) return factory(...) end }) +return factory