]> git.madduck.net Git - etc/awesome.git/blob - widget/fs.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

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.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

widget.fs: fix notification check, add threshold parameter for trigger
[etc/awesome.git] / widget / fs.lua
1 --[[
2
3      Licensed under GNU General Public License v2
4       * (c) 2018, Uli Schlacter
5       * (c) 2018, Otto Modinos
6       * (c) 2013, Luca CPZ
7
8 --]]
9
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")
15 local math       = math
16 local string     = string
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
23
24 -- File systems info
25 -- lain.widget.fs
26
27 local function factory(args)
28     local fs = {
29         widget = wibox.widget.textbox(),
30         units = {
31             [1] = "Kb", [2] = "Mb", [3] = "Gb",
32             [4] = "Tb", [5] = "Pb", [6] = "Eb",
33             [7] = "Zb", [8] = "Yb"
34         }
35     }
36
37     function fs.hide()
38         if not fs.notification then return end
39         naughty.destroy(fs.notification)
40         fs.notification = nil
41     end
42
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
49         }
50     end
51
52     local args      = args or {}
53     local timeout   = args.timeout or 600
54     local partition = args.partition
55     local threshold = args.threshold or 99
56     local showpopup = args.showpopup or "on"
57     local settings  = args.settings or function() end
58
59     fs.followtag           = args.followtag or false
60     fs.notification_preset = args.notification_preset
61
62     if not fs.notification_preset then
63         fs.notification_preset = {
64             font = "Monospace 10",
65             fg   = "#FFFFFF",
66             bg   = "#000000"
67         }
68     end
69
70     function fs.update()
71         local notifytable = { [1] = string.format("%-10s %-5s %s\t%s\t\n", "path", "used", "free", "size") }
72         local pathlen = 10
73         fs_now = {}
74
75         for _, mount in ipairs(Gio.unix_mounts_get()) do
76             local path = Gio.unix_mount_get_mount_path(mount)
77             local root = Gio.File.new_for_path(path)
78             local info = root:query_filesystem_info(query)
79
80             if info then
81                 local size = info:get_attribute_uint64(query_size)
82                 local used = info:get_attribute_uint64(query_used)
83                 local free = info:get_attribute_uint64(query_free)
84
85                 if size > 0 then
86                     local units = math.floor(math.log(size)/math.log(1024))
87
88                     fs_now[path] = {
89                         units      = fs.units[units],
90                         percentage = math.floor(100 * used / size), -- used percentage
91                         size       = size / math.pow(1024, math.floor(units)),
92                         used       = used / math.pow(1024, math.floor(units)),
93                         free       = free / math.pow(1024, math.floor(units))
94                     }
95
96                     if fs_now[path].percentage > 0 then -- don't notify unused file systems
97                         notifytable[#notifytable+1] = string.format("\n%-10s %-5s %.2f\t%.2f\t%s", path,
98                         fs_now[path].percentage .. "%", fs_now[path].free, fs_now[path].size,
99                         fs_now[path].units)
100
101                         pathlen = math.max(pathlen, #path)
102                     end
103                 end
104             end
105         end
106
107         widget = fs.widget
108         settings()
109
110         if partition and fs_now[partition] and fs_now[partition].percentage >= threshold then
111             if not helpers.get_map(partition) then
112                 naughty.notify {
113                     preset = naughty.config.presets.critical,
114                     title  = "Warning",
115                     text   = string.format("%s is above %d%% (%d%%)", partition, threshold, fs_now[partition].percentage)
116                 }
117                 helpers.set_map(partition, true)
118             else
119                 helpers.set_map(partition, false)
120             end
121         end
122
123         if pathlen > 10 then -- formatting aesthetics
124             for i = 1, #notifytable do
125                 local pathspaces = notifytable[i]:match("/%w*[/%w*]*%s*") or notifytable[i]:match("path%s*")
126                 notifytable[i] = notifytable[i]:gsub(pathspaces, pathspaces .. string.rep(" ", pathlen - 10) .. "\t")
127             end
128         end
129
130         fs.notification_preset.text = tconcat(notifytable)
131     end
132
133     if showpopup == "on" then
134        fs.widget:connect_signal('mouse::enter', function () fs.show(0) end)
135        fs.widget:connect_signal('mouse::leave', function () fs.hide() end)
136     end
137
138     helpers.newtimer(partition or "fs", timeout, fs.update)
139
140     return fs
141 end
142
143 return factory