All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
   3      Licensed under GNU General Public License v2
 
   4       * (c) 2018, Uli Schlacter
 
   5       * (c) 2018, Otto Modinos
 
  10 local helpers    = require("lain.helpers")
 
  11 local Gio        = require("lgi").Gio
 
  12 local focused    = require("awful.screen").focused
 
  13 local wibox      = require("wibox")
 
  14 local naughty    = require("naughty")
 
  16 local sformat    = string.format
 
  17 local tconcat    = table.concat
 
  18 local tonumber   = tonumber
 
  19 local query_size = Gio.FILE_ATTRIBUTE_FILESYSTEM_SIZE
 
  20 local query_free = Gio.FILE_ATTRIBUTE_FILESYSTEM_FREE
 
  21 local query_used = Gio.FILE_ATTRIBUTE_FILESYSTEM_USED
 
  22 local query      = query_size .. "," .. query_free .. "," .. query_used
 
  27 local function factory(args)
 
  29         widget = wibox.widget.textbox(),
 
  31             [1] = "Kb", [2] = "Mb", [3] = "Gb",
 
  32             [4] = "Tb", [5] = "Pb", [6] = "Eb",
 
  33             [7] = "Zb", [8] = "Yb"
 
  38         if not fs.notification then return end
 
  39         naughty.destroy(fs.notification)
 
  43     function fs.show(seconds, scr)
 
  44         fs.hide(); fs.update()
 
  45         fs.notification_preset.screen = fs.followtag and focused() or scr or 1
 
  46         fs.notification = naughty.notify {
 
  47             preset  = fs.notification_preset,
 
  48             timeout = seconds or 5
 
  52     local args      = args or {}
 
  53     local timeout   = args.timeout or 600
 
  54     local partition = args.partition
 
  55     local showpopup = args.showpopup or "on"
 
  56     local settings  = args.settings or function() end
 
  58     fs.followtag           = args.followtag or false
 
  59     fs.notification_preset = args.notification_preset
 
  61     if not fs.notification_preset then
 
  62         fs.notification_preset = {
 
  63             font = "Monospace 10",
 
  70         local notifytable = { [1] = sformat("%-10s %-5s %s\t%s\t\n", "fs", "used", "free", "size") }
 
  73         for _, mount in ipairs(Gio.unix_mounts_get()) do
 
  74             local path = Gio.unix_mount_get_mount_path(mount)
 
  75             local root = Gio.File.new_for_path(path)
 
  76             local info = root:query_filesystem_info(query)
 
  79                 local size = info:get_attribute_uint64(query_size)
 
  80                 local used = info:get_attribute_uint64(query_used)
 
  81                 local free = info:get_attribute_uint64(query_free)
 
  84                     local units = math.floor(math.log(size)/math.log(1024))
 
  87                         units      = fs.units[units],
 
  88                         percentage = math.floor(100 * used / size), -- used percentage
 
  89                         size       = size / math.pow(1024, math.floor(units)),
 
  90                         used       = used / math.pow(1024, math.floor(units)),
 
  91                         free       = free / math.pow(1024, math.floor(units))
 
  94                     if fs_now[path].percentage > 0 then -- don't notify unused file systems
 
  95                         notifytable[#notifytable+1] = sformat("\n%-10s %-5s %3.2f\t%3.2f\t%s", path,
 
  96                         fs_now[path].percentage .. "%", fs_now[path].free, fs_now[path].size,
 
 106         if partition and fs_now[partition] and fs_now[partition].used >= 99 then
 
 107             if not helpers.get_map(partition) then
 
 109                     preset = naughty.config.presets.critical,
 
 111                     text   = partition .. " is full",
 
 113                 helpers.set_map(partition, true)
 
 115                 helpers.set_map(partition, false)
 
 119         fs.notification_preset.text = tconcat(notifytable)
 
 122     if showpopup == "on" then
 
 123        fs.widget:connect_signal('mouse::enter', function () fs.show(0) end)
 
 124        fs.widget:connect_signal('mouse::leave', function () fs.hide() end)
 
 127     helpers.newtimer(partition or "fs", timeout, fs.update)