From 6f002577b993d0c8e9a35f1bac27139bb35b063f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Thu, 16 May 2019 18:52:22 +0700 Subject: [PATCH 01/28] [volume_freebsd] Use spawn.easy_async instead of io.popen NOTE: Similar to volume_linux, the default mute symbol has also been changed. --- Changes.md | 4 ++-- widgets/volume_freebsd.lua | 35 ++++++++++++++--------------------- widgets/volume_linux.lua | 1 + 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/Changes.md b/Changes.md index cb0f732..3ca064e 100644 --- a/Changes.md +++ b/Changes.md @@ -1,6 +1,6 @@ IMPORTANT: -- `volume_linux` now uses ๐Ÿ”‰ and ๐Ÿ”ˆ instead of โ™ซ and โ™ฉ to show mute state. +- `volume` now uses ๐Ÿ”‰ and ๐Ÿ”ˆ instead of โ™ซ and โ™ฉ to show mute state. This BREAKS backward compatibility if users substitute custom symbols from these default. @@ -16,7 +16,7 @@ Added: Fixed: -- [volume_linux] Deprecate `io.popen` +- [volume] Deprecate `io.popen` - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) diff --git a/widgets/volume_freebsd.lua b/widgets/volume_freebsd.lua index 200f4b7..5927150 100644 --- a/widgets/volume_freebsd.lua +++ b/widgets/volume_freebsd.lua @@ -1,9 +1,8 @@ -- {{{ Grab environment local tonumber = tonumber -local io = { popen = io.popen } -local setmetatable = setmetatable local string = { match = string.match } -local helpers = require("vicious.helpers") +local helpers = require"vicious.helpers" +local spawn = require"vicious.spawn" -- }}} @@ -13,26 +12,20 @@ local volume_freebsd = {} -- {{{ Volume widget type -local function worker(format, warg) - if not warg then return end +local STATE = { on = '๐Ÿ”‰', off = '๐Ÿ”ˆ' } - local mixer_state = { "โ™ซ", "โ™ฉ" } - - -- Get mixer control contents - f = io.popen("mixer -s " .. helpers.shellquote(warg)) - local mixer = f:read() - f:close() - - -- Capture mixer control state: [5%] ... ... [on] - local voll, volr = string.match(mixer, "([%d]+):([%d]+)$") - - if voll == "0" and volr == "0" then - return {0, 0, mixer_state[2]} - else - return {voll, volr, mixer_state[1]} - end +local function parse(stdout, stderr, exitreason, exitcode) + -- Capture mixer control state, e.g. 42 : 42 + local voll, volr = string.match(stdout, "([%d]+):([%d]+)$") + if voll == "0" and volr == "0" then return { 0, 0, STATE.off } end + return { tonumber(voll), tonumber(volr), STATE.on } +end +function volume_freebsd.async(format, warg, callback) + if not warg then return callback{} end + spawn.easy_async("mixer -s " .. helpers.shellquote(warg), + function (...) callback(parse(...)) end) end -- }}} -return setmetatable(volume_freebsd, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(volume_freebsd) diff --git a/widgets/volume_linux.lua b/widgets/volume_linux.lua index 098017d..3c281af 100644 --- a/widgets/volume_linux.lua +++ b/widgets/volume_linux.lua @@ -4,6 +4,7 @@ --------------------------------------------------- -- {{{ Grab environment +local type = type local tonumber = tonumber local string = { match = string.match } local table = { concat = table.concat } From 383d91399f79618f1363eee43ee0799c97ca9551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Thu, 16 May 2019 21:50:42 +0700 Subject: [PATCH 02/28] [gmail] Switch to awful.spawn.easy_async --- Changes.md | 2 +- widgets/gmail_all.lua | 74 ++++++++++++++----------------------------- 2 files changed, 24 insertions(+), 52 deletions(-) diff --git a/Changes.md b/Changes.md index 3ca064e..a506ea2 100644 --- a/Changes.md +++ b/Changes.md @@ -16,7 +16,7 @@ Added: Fixed: -- [volume] Deprecate `io.popen` +- [volume,gmail] Deprecate `io.popen` - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) diff --git a/widgets/gmail_all.lua b/widgets/gmail_all.lua index db868c3..7e897b8 100644 --- a/widgets/gmail_all.lua +++ b/widgets/gmail_all.lua @@ -6,12 +6,10 @@ -- {{{ Grab environment local type = type local tonumber = tonumber -local io = { popen = io.popen } -local setmetatable = setmetatable +local string = { match = string.match } + local helpers = require("vicious.helpers") -local string = { - match = string.match -} +local spawn = require("vicious.spawn") -- }}} @@ -19,59 +17,33 @@ local string = { -- vicious.widgets.gmail local gmail_all = {} - --- {{{ Variable definitions -local rss = { - inbox = "https://mail.google.com/mail/feed/atom", - unread = "https://mail.google.com/mail/feed/atom/unread", - --labelname = "https://mail.google.com/mail/feed/atom/labelname", -} - --- Default is just Inbox -local feed = rss.inbox -local mail = { - ["{count}"] = 0, - ["{subject}"] = "N/A" -} --- }}} - - -- {{{ Gmail widget type -local function worker(format, warg) - -- Get info from the Gmail atom feed - local f = io.popen("curl --connect-timeout 1 -m 3 -fsn " .. helpers.shellquote(feed)) - - -- Could be huge don't read it all at once, info we are after is at the top - local xml = f:read(2000) - - if xml == nil then - return mail - end - - mail["{count}"] = -- Count comes before messages and matches at least 0 - tonumber(string.match(xml, "([%d]+)")) or mail["{count}"] +local function parse(warg, stdout, stderr, exitreason, exitcode) + local count = -- Count comes before messages and matches at least 0 + tonumber(string.match(stdout, "([%d]+)")) or 0 -- Find subject tag - local title = string.match(xml, ".-(.-)") + local title = string.match(stdout, ".-(.-)") or "N/A" - if title ~= nil then - -- Check if we should scroll, or maybe truncate - if warg then - if type(warg) == "table" then - title = helpers.scroll(title, warg[1], warg[2]) - else - title = helpers.truncate(title, warg) - end - end - - -- Spam sanitize the subject and store - mail["{subject}"] = title + -- Check if we should scroll, or maybe truncate + if type(warg) == "number" then + title = helpers.truncate(title, warg) + elseif type(warg) == "table" then + title = helpers.scroll(title, warg[1], warg[2]) end - f:close() + return { ["{count}"] = count, ["{subject}"] = title } +end - return mail +function gmail_all.async(format, warg, callback) + -- Get info from the Gmail atom feed using curl --netrc. + -- With username 'user' and password 'pass' + -- $HOME/.netrc should look similar to: + -- machine mail.google.com login user password pass + -- BE AWARE THAT MAKING THESE SETTINGS IS A SECURITY RISK! + spawn.easy_async("curl -fsn https://mail.google.com/mail/feed/atom", + function (...) callback(parse(warg, ...)) end) end -- }}} -return setmetatable(gmail_all, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(gmail_all) From 992d835c2ea6acc939e454d37baf8c1219dfbb69 Mon Sep 17 00:00:00 2001 From: mutlusun Date: Sun, 26 May 2019 19:17:21 +0200 Subject: [PATCH 03/28] [battery_freebsd] switch to awful.spawn.easy_async --- Changes.md | 2 +- widgets/bat_freebsd.lua | 48 +++++++++++++++++++------------------- widgets/volume_freebsd.lua | 4 ++-- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Changes.md b/Changes.md index a506ea2..2fd183d 100644 --- a/Changes.md +++ b/Changes.md @@ -16,7 +16,7 @@ Added: Fixed: -- [volume,gmail] Deprecate `io.popen` +- [volume,gmail,battery(FreeBSD)] Deprecate `io.popen` - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) diff --git a/widgets/bat_freebsd.lua b/widgets/bat_freebsd.lua index 8139b4c..10091c0 100644 --- a/widgets/bat_freebsd.lua +++ b/widgets/bat_freebsd.lua @@ -1,23 +1,23 @@ -- {{{ Grab environment -local setmetatable = setmetatable local tonumber = tonumber -local io = { popen = io.popen } local math = { floor = math.floor } local helpers = require("vicious.helpers") +local spawn = require("vicious.spawn") local string = { gmatch = string.gmatch, match = string.match, format = string.format } - -- }}} + +-- Battery: provides battery level of requested battery +-- vicious.widgets.battery_freebsd local bat_freebsd = {} -local function worker(format, warg) - local battery = warg or "batt" +-- {{{ Battery widget type +local function parse(stdout, stderr, exitreason, exitcode) local bat_info = {} - local f = io.popen("acpiconf -i " .. helpers.shellquote(battery)) - for line in f:lines("*line") do + for line in string.gmatch(s,"[^\n]+") do for key,value in string.gmatch(line, "(.+):%s+(.+)") do bat_info[key] = value end @@ -25,22 +25,15 @@ local function worker(format, warg) -- current state -- see: https://github.com/freebsd/freebsd/blob/master/usr.sbin/acpi/acpiconf/acpiconf.c - local state - if bat_info["State"] == "high" then - state = "โ†ฏ" - elseif bat_info["State"] == "charging" then - state = "+" - elseif bat_info["State"] == "critical charging" then - state = "+" - elseif bat_info["State"] == "discharging" then - state = "-" - elseif bat_info["State"] == "critical discharging" then - state = "!" - elseif bat_info["State"] == "critical" then - state = "!" - else - state = "N/A" - end + local battery_state = { + ["high"] = "โ†ฏ", + ["charging"] = "+", + ["critical charging"] = "+", + ["discharging"] = "-", + ["critical discharging"] = "!", + ["critical"] = "!", + } + local state = battery_state[bat_info["State"]] or "N/A" -- battery capacity in percent local percent = tonumber(string.match(bat_info["Remaining capacity"], "[%d]+")) @@ -72,4 +65,11 @@ local function worker(format, warg) return {state, percent, time, wear, rate} end -return setmetatable(bat_freebsd, { __call = function(_, ...) return worker(...) end }) +function battery_freebsd.async(format, warg, callback) + local battery = warg or "batt" + spawn.easy_async("acpiconf -i " .. helpers.shellquote(battery), + function (...) callback(parse(...)) end) +end +-- }}} + +return helpers.setasyncall(battery_freebsd) diff --git a/widgets/volume_freebsd.lua b/widgets/volume_freebsd.lua index 5927150..7b78078 100644 --- a/widgets/volume_freebsd.lua +++ b/widgets/volume_freebsd.lua @@ -1,8 +1,8 @@ -- {{{ Grab environment local tonumber = tonumber local string = { match = string.match } -local helpers = require"vicious.helpers" -local spawn = require"vicious.spawn" +local helpers = require("vicious.helpers") +local spawn = require("vicious.spawn") -- }}} From 73b664b63e6ad673ab6870c0430cdb1a44e4b1c1 Mon Sep 17 00:00:00 2001 From: mutlusun Date: Mon, 27 May 2019 09:42:22 +0200 Subject: [PATCH 04/28] [FreeBSD] switched to async call (and fixed previous bug) --- widgets/bat_freebsd.lua | 6 +++--- widgets/mem_freebsd.lua | 40 ++++++++++++++++++++++++-------------- widgets/volume_freebsd.lua | 4 ++-- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/widgets/bat_freebsd.lua b/widgets/bat_freebsd.lua index 10091c0..f2cf8eb 100644 --- a/widgets/bat_freebsd.lua +++ b/widgets/bat_freebsd.lua @@ -17,7 +17,7 @@ local bat_freebsd = {} -- {{{ Battery widget type local function parse(stdout, stderr, exitreason, exitcode) local bat_info = {} - for line in string.gmatch(s,"[^\n]+") do + for line in string.gmatch(stdout, "[^\n]+") do for key,value in string.gmatch(line, "(.+):%s+(.+)") do bat_info[key] = value end @@ -65,11 +65,11 @@ local function parse(stdout, stderr, exitreason, exitcode) return {state, percent, time, wear, rate} end -function battery_freebsd.async(format, warg, callback) +function bat_freebsd.async(format, warg, callback) local battery = warg or "batt" spawn.easy_async("acpiconf -i " .. helpers.shellquote(battery), function (...) callback(parse(...)) end) end -- }}} -return helpers.setasyncall(battery_freebsd) +return helpers.setasyncall(bat_freebsd) diff --git a/widgets/mem_freebsd.lua b/widgets/mem_freebsd.lua index 66dbbaf..4a162c1 100644 --- a/widgets/mem_freebsd.lua +++ b/widgets/mem_freebsd.lua @@ -1,9 +1,12 @@ -- {{{ Grab environment local tonumber = tonumber -local setmetatable = setmetatable local math = { floor = math.floor } -local io = { popen = io.popen } local helpers = require("vicious.helpers") +local spawn = require("vicious.spawn") +local string = { + match = string.match, + gmatch = string.gmatch +} -- }}} -- Mem: provides RAM and Swap usage statistics @@ -12,7 +15,7 @@ local mem_freebsd = {} -- {{{ Memory widget type -local function worker(format) +local function parse(stdout, stderr, exitreason, exitcode) local pagesize = tonumber(helpers.sysctl("hw.pagesize")) local vm_stats = helpers.sysctl_table("vm.stats.vm") local _mem = { buf = {}, total = nil } @@ -54,19 +57,20 @@ local function worker(format) _swp.total = 0 _swp.buf.free = 0 - -- Read output of swapinfo in Mbytes - local f = io.popen("swapinfo -m") - -- Skip first line (table header) - f:read("*line") + -- Read output of swapinfo in Mbytes (from async function call) -- Read content and sum up - for line in f:lines() do - local ltotal, lused, lfree = string.match(line, "%s+([%d]+)%s+([%d]+)%s+([%d]+)") - -- Add swap space in Mbytes - _swp.total = _swp.total + tonumber(ltotal) - _swp.inuse = _swp.inuse + tonumber(lused) - _swp.buf.free = _swp.buf.free + tonumber(lfree) + local counter = 1 + for line in string.gmatch(stdout, "[^\n]+") do + -- Skip first line (table header) + if counter ~= 1 then + local ltotal, lused, lfree = string.match(line, "%s+([%d]+)%s+([%d]+)%s+([%d]+)") + -- Add swap space in Mbytes + _swp.total = _swp.total + tonumber(ltotal) + _swp.inuse = _swp.inuse + tonumber(lused) + _swp.buf.free = _swp.buf.free + tonumber(lfree) + end + counter = counter + 1 end - f:close() -- Calculate percentage _swp.usep = math.floor(_swp.inuse / _swp.total * 100) @@ -82,4 +86,10 @@ local function worker(format) _mem.wirep, _mem.wire, _mem.notfreeablep, _mem.notfreeable } end -return setmetatable(mem_freebsd, { __call = function(_, ...) return worker(...) end }) +function mem_freebsd.async(format, warg, callback) + spawn.easy_async("swapinfo -m", + function (...) callback(parse(...)) end) +end +-- }}} + +return helpers.setasyncall(mem_freebsd) diff --git a/widgets/volume_freebsd.lua b/widgets/volume_freebsd.lua index 7b78078..d86957a 100644 --- a/widgets/volume_freebsd.lua +++ b/widgets/volume_freebsd.lua @@ -16,14 +16,14 @@ local STATE = { on = '๐Ÿ”‰', off = '๐Ÿ”ˆ' } local function parse(stdout, stderr, exitreason, exitcode) -- Capture mixer control state, e.g. 42 : 42 - local voll, volr = string.match(stdout, "([%d]+):([%d]+)$") + local voll, volr = string.match(stdout, "([%d]+):([%d]+)\n$") if voll == "0" and volr == "0" then return { 0, 0, STATE.off } end return { tonumber(voll), tonumber(volr), STATE.on } end function volume_freebsd.async(format, warg, callback) if not warg then return callback{} end - spawn.easy_async("mixer -s " .. helpers.shellquote(warg), + spawn.easy_async("mixer " .. helpers.shellquote(warg), function (...) callback(parse(...)) end) end -- }}} From 06d96a92baaaa309155f0c9a62ba5169953eec8d Mon Sep 17 00:00:00 2001 From: mutlusun Date: Mon, 27 May 2019 09:52:00 +0200 Subject: [PATCH 05/28] [net_freebsd] Switched to async spawn --- widgets/net_freebsd.lua | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/widgets/net_freebsd.lua b/widgets/net_freebsd.lua index f78b016..2aa1180 100644 --- a/widgets/net_freebsd.lua +++ b/widgets/net_freebsd.lua @@ -1,10 +1,12 @@ -- {{{ Grab environment local tonumber = tonumber local os = { time = os.time } -local setmetatable = setmetatable local helpers = require("vicious.helpers") -local io = { popen = io.popen } -local string = { match = string.match } +local spawn = require("vicious.spawn") +local string = { + match = string.match, + gmatch = string.gmatch +} -- }}} @@ -21,15 +23,13 @@ local unit = { ["b"] = 1, ["kb"] = 1024, } -- {{{ Net widget type -local function worker(format, warg) - if not warg then return end +local function parse(stdout, stderr, exitreason, exitcode) local args = {} local buffer = nil - local f = io.popen("netstat -n -b -I " .. helpers.shellquote(warg)) local now = os.time() - for line in f:lines() do + for line in string.gmatch(stdout, "[^\n]+") do if not (line:find(" Date: Wed, 29 May 2019 14:24:24 +0700 Subject: [PATCH 06/28] [mdir] Switch to async call mdir is only semi-tested that it does work: I have not set up maildir to check if the matching patterns are correct --- Changes.md | 2 +- widgets/mdir_all.lua | 43 +++++++++++++++++++++---------------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/Changes.md b/Changes.md index 2fd183d..c277149 100644 --- a/Changes.md +++ b/Changes.md @@ -16,7 +16,7 @@ Added: Fixed: -- [volume,gmail,battery(FreeBSD)] Deprecate `io.popen` +- [volume,gmail,bat_freebsd,mem_freebsd,net_freebsd,mdir] Deprecate `io.popen` - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) diff --git a/widgets/mdir_all.lua b/widgets/mdir_all.lua index 793609e..184f41e 100644 --- a/widgets/mdir_all.lua +++ b/widgets/mdir_all.lua @@ -5,9 +5,10 @@ --------------------------------------------------- -- {{{ Grab environment -local io = { popen = io.popen } -local setmetatable = setmetatable -local helpers = require("vicious.helpers") +local type = type + +local helpers = require"vicious.helpers" +local spawn = require"vicious.spawn" -- }}} @@ -17,27 +18,25 @@ local mdir_all = {} -- {{{ Maildir widget type -local function worker(format, warg) - if not warg then return end - - -- Initialize counters - local count = { new = 0, cur = 0 } - - for i=1, #warg do - quoted_path = helpers.shellquote(warg[i]) - -- Recursively find new messages - local f = io.popen("find "..quoted_path.." -type f -wholename '*/new/*'") - for line in f:lines() do count.new = count.new + 1 end - f:close() - - -- Recursively find "old" messages lacking the Seen flag - local f = io.popen("find "..quoted_path.." -type f -regex '.*/cur/.*2,[^S]*$'") - for line in f:lines() do count.cur = count.cur + 1 end - f:close() +function mdir_all.async(format, warg, callback) + if type(warg) ~= "table" then return callback{} end + local starting_points = "" + for i,dir in ipairs(warg) do + starting_points = starting_points .. " " .. helpers.shellquote(dir) end + if starting_points == "" then return callback{ 0, 0 } end - return {count.new, count.cur} + local new, cur = 0, 0 + spawn.with_line_callback( + "find" .. starting_points .. " -type f -regex '.*/cur/.*2,[^S]*$';", + { stdout = function (filename) cur = cur + 1 end, + output_done = function () + spawn.with_line_callback( + "find" .. starting_points .. " -type f -path '*/new/*';", + { stdout = function (filename) new = new + 1 end, + output_done = function () callback{ new, cur } end }) + end }) end -- }}} -return setmetatable(mdir_all, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(mdir_all) From 62e9a757dfd3b88c45f60407671db26987c8f088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Wed, 29 May 2019 21:45:28 +0700 Subject: [PATCH 07/28] [{wifi,wifiiw}_linux] Deprecate io.popen --- Changes.md | 6 ++- README.md | 12 +++-- widgets/wifi_linux.lua | 109 +++++++++++++-------------------------- widgets/wifiiw_linux.lua | 80 +++++++++++++--------------- 4 files changed, 84 insertions(+), 123 deletions(-) diff --git a/Changes.md b/Changes.md index c277149..be479f5 100644 --- a/Changes.md +++ b/Changes.md @@ -6,6 +6,7 @@ IMPORTANT: Added: +- [wifi_linux] Expose frequency and transmission power - `spawn` as a fallback for `awful.spawn` in case Vicious is used as a stand-alone library. This wrapper, however, does NOT provide the facilities to asynchronously spawn new processes. It also lacks a few features such as @@ -16,7 +17,10 @@ Added: Fixed: -- [volume,gmail,bat_freebsd,mem_freebsd,net_freebsd,mdir] Deprecate `io.popen` +- Deprecate the use of `io.popen` in following widgets: + * wifi_linux, wifiiw_linux + * bat_freebsd, mem_freebsd, net_freebsd + * volume, gmail, mdir - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) diff --git a/README.md b/README.md index d8ff255..4e9b50e 100644 --- a/README.md +++ b/README.md @@ -514,8 +514,10 @@ Provides wireless information for a requested interface. Supported platforms: GNU/Linux. * Argument: the network interface, e.g. `"wlan0"` -* Returns a table with string keys: `${ssid}`, `${mode}`, `${chan}`, `${rate}`, - `${link}`, `${linp}` (link quality in percent) and `${sign}` (signal level) +* Returns a table with string keys: `${ssid}`, `${mode}`, `${chan}`, + `${rate}` (Mb/s), `${freq}` (MHz), `${txpw}` (transmission power, in dBm), + `${sign}` (signal level), `${link}` and `${linp}` (link quality + per 70 and per cent) ### vicious.widgets.wifiiw @@ -525,9 +527,9 @@ vicious.widgets.wifi, but uses `iw` instead of `iwconfig`). Supported platforms: GNU/Linux. * Argument: the network interface, e.g. `"wlan0"` -* Returns a table with string keys: `${ssid}`, `${mode}`, `${chan}`, `${rate}`, - `${freq}`, `${linp}` (link quality in percent), `${txpw}` (tx power) and - `${sign}` (signal level) +* Returns a table with string keys: `${ssid}`, `${mode}`, `${chan}`, + `${rate}` (Mb/s), `${freq}` (MHz), `${linp}` (link quality in percent), + `${txpw}` (transmission power, in dBm) and `${sign}` (signal level, in dBm) ## Custom widget types diff --git a/widgets/wifi_linux.lua b/widgets/wifi_linux.lua index 423765a..b7a3fd8 100644 --- a/widgets/wifi_linux.lua +++ b/widgets/wifi_linux.lua @@ -4,89 +4,50 @@ --------------------------------------------------- -- {{{ Grab environment +local type = type local tonumber = tonumber -local math = { ceil = math.ceil } -local setmetatable = setmetatable -local helpers = require("vicious.helpers") -local io = { - open = io.open, - popen = io.popen -} -local string = { - find = string.find, - match = string.match -} +local math = { floor = math.floor } + +local helpers = require"vicious.helpers" +local spawn = require"vicious.spawn" -- }}} --- Wifi: provides wireless information for a requested interface +-- Wifi: provides wireless information for a requested interface using iwconfig -- vicious.widgets.wifi local wifi_linux = {} - --- {{{ Variable definitions -local iwconfig = "iwconfig" -local iwcpaths = { "/sbin", "/usr/sbin", "/usr/local/sbin", "/usr/bin" } --- }}} - - -- {{{ Wireless widget type -local function worker(format, warg) - if not warg then return end - - -- Default values - local winfo = { - ["{ssid}"] = "N/A", - ["{mode}"] = "N/A", - ["{chan}"] = 0, - ["{rate}"] = 0, - ["{link}"] = 0, - ["{linp}"] = 0, - ["{sign}"] = 0 - } - - -- Sbin paths aren't in user PATH, search for the binary - if iwconfig == "iwconfig" then - for _, p in ipairs(iwcpaths) do - local f = io.open(p .. "/iwconfig", "rb") - if f then - iwconfig = p .. "/iwconfig" - f:close() - break - end - end - end - - -- Get data from iwconfig where available - local f = io.popen(iwconfig .." ".. helpers.shellquote(warg) .. " 2>&1") - local iw = f:read("*all") - f:close() - - -- iwconfig wasn't found, isn't executable, or non-wireless interface - if iw == nil or string.find(iw, "No such device") then - return winfo - end - - -- Output differs from system to system, some stats can be - -- separated by =, and not all drivers report all stats - -- SSID can have almost anything in it - winfo["{ssid}"] = string.match(iw, 'ESSID[=:]"(.-)"') or winfo["{ssid}"] - winfo["{mode}"] = -- Modes are simple, but also match the "-" in Ad-Hoc - string.match(iw, "Mode[=:]([%w%-]*)") or winfo["{mode}"] - winfo["{chan}"] = -- Channels are plain digits - tonumber(string.match(iw, "Channel[=:]([%d]+)") or winfo["{chan}"]) - winfo["{rate}"] = -- Bitrate can start with a space, we don't want to display Mb/s - tonumber(string.match(iw, "Bit Rate[=:]([%s]?[%d%.]*)") or winfo["{rate}"]) - winfo["{link}"] = -- Link quality can contain a slash (32/70), match only the first number - tonumber(string.match(iw, "Link Quality[=:]([%d]+)") or winfo["{link}"]) - winfo["{sign}"] = -- Signal level can be a negative value, don't display decibel notation - tonumber(string.match(iw, "Signal level[=:]([%-]?[%d]+)") or winfo["{sign}"]) - - -- Link quality percentage if quality was available - if winfo["{link}"] ~= 0 then winfo["{linp}"] = math.ceil(winfo["{link}"] / 0.7) end - +local function parser(stdout, stderr, exitreason, exitcode) + local winfo = {} + -- Output differs from system to system, stats can be separated by + -- either = or :. Some stats may not be supported by driver. + -- SSID can have almost anything in it. + winfo["{ssid}"] = stdout:match'ESSID[=:]"(.-)"' or "N/A" + -- Modes are simple, but also match the "-" in Ad-Hoc + winfo["{mode}"] = stdout:match"Mode[=:]([%w%-]+)" or "N/A" + winfo["{chan}"] = tonumber(stdout:match"Channel[=:](%d+)" or 0) + winfo["{rate}"] = -- Bitrate without unit (Mb/s) + tonumber(stdout:match"Bit Rate[=:]%s?([%d%.]+)" or 0) + winfo["{freq}"] = -- Frequency in MHz (is output always in GHz?) + tonumber(stdout:match"Frequency[=:]%s?([%d%.]+)" or 0) * 1000 + winfo["{txpw}"] = -- Transmission power in dBm + tonumber(stdout:match"Tx%-Power[=:](%d+)" or 0) + winfo["{link}"] = -- Link quality over 70 + tonumber(stdout:match"Link Quality[=:](%d+)" or 0) + winfo["{linp}"] = -- Link quality percentage if quality was available + winfo["{link}"] ~= 0 and math.floor(winfo["{link}"]/0.7 + 0.5) or 0 + -- Signal level without unit (dBm), can be negative value + winfo["{sign}"] = tonumber(stdout:match"Signal level[=:](%-?%d+)" or 0) return winfo end + +function wifi_linux.async(format, warg, callback) + if type(warg) ~= "string" then return callback{} end + spawn.easy_async_with_shell( + "PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin iwconfig " .. warg, + function (...) callback(parser(...)) end) +end -- }}} -return setmetatable(wifi_linux, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(wifi_linux) diff --git a/widgets/wifiiw_linux.lua b/widgets/wifiiw_linux.lua index 82d4e3f..25aebe1 100644 --- a/widgets/wifiiw_linux.lua +++ b/widgets/wifiiw_linux.lua @@ -4,63 +4,57 @@ --------------------------------------------------- -- {{{ Grab environment +local type = type local tonumber = tonumber -local setmetatable = setmetatable + local helpers = require("vicious.helpers") -local io = { - open = io.open, - popen = io.popen -} -local string = { - find = string.find, - match = string.match -} +local spawn = require("vicious.spawn") -- }}} --- Wifiiw: provides wireless information for a requested interface using iw instead of deprecated iwconfig +-- Wifiiw: provides wireless information for a requested interface +-- using iw instead of deprecated iwconfig -- vicious.widgets.wifiiw local wifiiw_linux = {} +local LINK = "PATH=$PATH:/sbin/:/usr/sbin:/usr/local/sbin iw dev %s link" +local INFO = "PATH=$PATH:/sbin/:/usr/sbin:/usr/local/sbin iw dev %s info" -- {{{ Wireless widget type -local function worker(format, warg) - if not warg then return end - - -- Default values +function wifiiw_linux.async(format, warg, callback) + if type(warg) ~= "string" then return callback{} end local winfo = {} - -- Get data from iw where available - local f = io.popen("export PATH=$PATH:/sbin/:/usr/sbin:/usr/local/sbin;" .. - "iw dev ".. helpers.shellquote(tostring(warg)) .. " link 2>&1;" .. - "iw dev ".. helpers.shellquote(tostring(warg)) .. " info 2>&1") - local iwresult = f:read("*all") - f:close() - - -- iw wasn't found, isn't executable, or non-wireless interface - if iwresult == nil or string.find(iwresult, "No such device") then - return winfo + local function parse_link(stdout) + winfo["{ssid}"] = stdout:match"SSID: ([^\n]*)" or "N/A" + winfo["{freq}"] = tonumber(stdout:match"freq: (%d+)" or 0) + winfo["{sign}"] = -- Signal level can be negative; w/o unit (dBm) + tonumber(stdout:match"signal: (%-?%d+)" or 0) + winfo["{linp}"] = -- Link Quality (-100dBm->0%, -50dBm->100%) + winfo["{sign}"] ~= 0 and 200 + winfo["{sign}"]*2 or 0 + winfo["{rate}"] = -- Transmission rate, without unit (Mb/s) + tonumber(stdout:match"tx bitrate: ([%d%.]+)" or 0) end - -- string match is simple in most cases, because iw uses a new line for every info - winfo["{ssid}"] = -- SSID can have almost anything in it until new line - string.match(iwresult, "SSID: ([^\n]*)") or "N/A" - winfo["{mode}"] = -- everything after 'type ' until new line - string.match(iwresult, "type ([^\n]*)") or "N/A" - winfo["{chan}"] = -- Channels are plain digits - tonumber(string.match(iwresult, "channel ([%d]+)") or 0) - winfo["{rate}"] = -- We don't want to display Mb/s - tonumber(string.match(iwresult, "tx bitrate: ([%d%.]*)") or 0) - winfo["{freq}"] = -- Frequency are plain digits - tonumber(string.match(iwresult, "freq: ([%d]+)") or 0) - winfo["{sign}"] = -- Signal level can be a negative value, don't display decibel notation - tonumber(string.match(iwresult, "signal: (%-[%d]+)") or 0) - winfo["{linp}"] = -- Link Quality using the Windows definition (-50dBm->100%, -100dBm->0%) - (winfo["{sign}"] ~= 0 and 100 - ((winfo["{sign}"] * -2) - 100) or 0) - winfo["{txpw}"] = -- TX Power can be a negative value, don't display decibel notation - tonumber(string.match(iwresult, "txpower ([%-]?[%d]+)") or 0) - return winfo + local function parse_info(stdout) + winfo["{mode}"] = stdout:match"type ([^\n]*)" or "N/A" + winfo["{chan}"] = tonumber(stdout:match"channel (%d+)" or 0) + -- Transmission power, without unit (dBm) + winfo["{txpw}"] = tonumber(stdout:match"txpower (%-?%d+)" or 0) + end + + spawn.easy_async_with_shell( + LINK:format(warg), + function (stdout, stderr, exitreason, exitcode) + parse_link(stdout) + spawn.easy_async_with_shell( + INFO:format(warg), + function (stdout, stderr, exitreason, exitcode) + parse_info(stdout) + callback(winfo) + end) + end) end -- }}} -return setmetatable(wifiiw_linux, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(wifiiw_linux) From db446c35d902659ce117ade88b789acae9b2f8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Wed, 5 Jun 2019 10:57:18 +0700 Subject: [PATCH 08/28] [mpd] Deprecate io.popen --- Changes.md | 2 +- widgets/mpd_all.lua | 65 +++++++++++++++++++++------------------------ 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/Changes.md b/Changes.md index be479f5..22fb202 100644 --- a/Changes.md +++ b/Changes.md @@ -20,7 +20,7 @@ Fixed: - Deprecate the use of `io.popen` in following widgets: * wifi_linux, wifiiw_linux * bat_freebsd, mem_freebsd, net_freebsd - * volume, gmail, mdir + * volume, gmail, mdir, mpd - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) diff --git a/widgets/mpd_all.lua b/widgets/mpd_all.lua index 0504c4a..4c2f524 100644 --- a/widgets/mpd_all.lua +++ b/widgets/mpd_all.lua @@ -5,11 +5,10 @@ -- {{{ Grab environment local tonumber = tonumber -local io = { popen = io.popen } -local setmetatable = setmetatable -local string = { gmatch = string.gmatch } -local helpers = require("vicious.helpers") local math = { floor = math.floor } + +local helpers = require"vicious.helpers" +local spawn = require"vicious.spawn" -- }}} @@ -55,7 +54,7 @@ end -- }}} -- {{{ MPD widget type -local function worker(format, warg) +function mpd_all.async(format, warg, callback) -- Fallback values local mpd_state = { ["{volume}"] = 0, @@ -81,36 +80,34 @@ local function worker(format, warg) warg and (warg.port or warg[3]) or "6600") -- Get data from MPD server - local f = io.popen(query .. "|" .. connect) - for line in f:lines() do - for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do - local key = "{" .. k .. "}" - if k == "volume" or k == "bitrate" or - k == "elapsed" or k == "duration" then - mpd_state[key] = v and tonumber(v) - elseif k == "repeat" or k == "random" then - mpd_state[key] = cbool(v) - elseif k == "state" then - mpd_state[key] = helpers.capitalize(v) - elseif k == "Artist" or k == "Title" or - --k == "Name" or k == "file" or - k == "Album" or k == "Genre" then - mpd_state[key] = v + spawn.with_line_callback_with_shell(query .. "|" .. connect, { + stdout = function (line) + for k, v in line:gmatch"([%w]+):[%s](.*)$" do + local key = "{" .. k .. "}" + if k == "volume" or k == "bitrate" or + k == "elapsed" or k == "duration" then + mpd_state[key] = v and tonumber(v) + elseif k == "repeat" or k == "random" then + mpd_state[key] = cbool(v) + elseif k == "state" then + mpd_state[key] = helpers.capitalize(v) + elseif k == "Artist" or k == "Title" or + --k == "Name" or k == "file" or + k == "Album" or k == "Genre" then + mpd_state[key] = v + end end - end - end - f:close() - - -- Formatted elapsed and duration - mpd_state["{Elapsed}"], mpd_state["{Duration}"] = format_progress( - mpd_state["{elapsed}"], mpd_state["{duration}"]) - - -- Formatted playing progress percentage - mpd_state["{Progress}"] = format_progress_percentage( - mpd_state["{elapsed}"], mpd_state["{duration}"]) - - return mpd_state + end, + output_done = function () + -- Formatted elapsed and duration + mpd_state["{Elapsed}"], mpd_state["{Duration}"] = format_progress( + mpd_state["{elapsed}"], mpd_state["{duration}"]) + -- Formatted playing progress percentage + mpd_state["{Progress}"] = format_progress_percentage( + mpd_state["{elapsed}"], mpd_state["{duration}"]) + callback(mpd_state) + end }) end -- }}} -return setmetatable(mpd_all, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(mpd_all) From c91167f954ab5032347c182d2c56aa2385713571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Sat, 22 Jun 2019 03:03:19 +0700 Subject: [PATCH 09/28] [hwmontemp_linux] Deprecate io.popen Note that all failures now return an empty table instead of { N/A }, since N/A indicates missing information from a successful attempt. --- Changes.md | 2 +- widgets/hwmontemp_linux.lua | 76 ++++++++++++++----------------------- 2 files changed, 29 insertions(+), 49 deletions(-) diff --git a/Changes.md b/Changes.md index 22fb202..85ba41d 100644 --- a/Changes.md +++ b/Changes.md @@ -18,7 +18,7 @@ Added: Fixed: - Deprecate the use of `io.popen` in following widgets: - * wifi_linux, wifiiw_linux + * wifi_linux, wifiiw_linux, hwmontemp_linux * bat_freebsd, mem_freebsd, net_freebsd * volume, gmail, mdir, mpd - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo diff --git a/widgets/hwmontemp_linux.lua b/widgets/hwmontemp_linux.lua index d995e72..9182932 100644 --- a/widgets/hwmontemp_linux.lua +++ b/widgets/hwmontemp_linux.lua @@ -4,57 +4,37 @@ ---------------------------------------------------------------- -- environment -local io = { popen = io.popen, open = io.open } -local assert = assert -local setmetatable = setmetatable +local type = type +local tonumber = tonumber +local io = { open = io.open } --- sysfs prefix for hwmon devices -local sys_hwmon = "/sys/class/hwmon/" --- cache table for hwmon device names -local paths = {} - --- transparently caching hwmon device name lookup -function name_to_path(name) - if paths[name] then return paths[name] end - - for sensor in io.popen("ls -1 " .. sys_hwmon):lines() do - local path = sys_hwmon .. sensor - local f = assert(io.open(path .. "/name", "r")) - local sname = f:read("*line") - f:close() - if sname == name then - paths[name] = path - return path - end - end - - return nil -end +local helpers = require"vicious.helpers" +local spawn = require"vicious.spawn" -- hwmontemp: provides name-indexed temps from /sys/class/hwmon -- vicious.widgets.hwmontemp -local hwmontemp_linux = {} - -function worker(format, warg) - assert(type(warg) == "table", "invalid hwmontemp argument: must be a table") - name = warg[1] - - if not warg[2] then - input = 1 - else - input = warg[2] - end - - local sensor = name_to_path(name) - if not sensor then return { "N/A" } end - - local f = assert(io.open(("%s/temp%d_input"):format(sensor, input), "r")) - local temp = f:read("*line") - f:close() - - return { temp / 1000 } -end - -return setmetatable(hwmontemp_linux, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall{ + async = function (format, warg, callback) + if type(warg) ~= "table" or type(warg[1]) ~= "string" then + return callback{} + end + local input = warg[2] + if type(input) == "number" then + input = ("temp%d_input"):format(input) + else + input = "temp1_input" + end + spawn.easy_async_with_shell( + "grep " .. warg[1] .. " -wl /sys/class/hwmon/*/name", + function (stdout, stderr, exitreason, exitcode) + if exitreason == "exit" and exitcode == 0 then + local f = io.open(stdout:gsub("name%s+", input), "r") + callback{ tonumber(f:read"*line") / 1000 } + f:close() + else + callback{} + end + end) + end } -- vim: ts=4:sw=4:expandtab From 565d74cc8bc4df9a0044f64de1fb960ef3912ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Sat, 22 Jun 2019 17:25:18 +0700 Subject: [PATCH 10/28] [fs] Deprecate io.popen Also clarify unit prefix convention --- Changes.md | 2 +- README.md | 1 + widgets/fs_all.lua | 64 +++++++++++++++++----------------------------- 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/Changes.md b/Changes.md index 85ba41d..0836c31 100644 --- a/Changes.md +++ b/Changes.md @@ -20,7 +20,7 @@ Fixed: - Deprecate the use of `io.popen` in following widgets: * wifi_linux, wifiiw_linux, hwmontemp_linux * bat_freebsd, mem_freebsd, net_freebsd - * volume, gmail, mdir, mpd + * volume, gmail, mdir, mpd, fs - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) diff --git a/README.md b/README.md index 56da125..f88b39a 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,7 @@ Supported platforms: platform independent. * Returns a table with string keys, using mount points as a base, e.g. `${/ size_mb}`, `${/ size_gb}`, `${/ used_mb}`, `${/ used_gb}`, `${/ used_p}`, `${/ avail_mb}`, `${/ avail_gb}`, `${/ avail_p}`, `${/home size_mb}`, etc. + mb and gb refer to mebibyte and gibibyte respectively. ### vicious.widgets.gmail diff --git a/widgets/fs_all.lua b/widgets/fs_all.lua index b577431..9c4e5d0 100644 --- a/widgets/fs_all.lua +++ b/widgets/fs_all.lua @@ -6,50 +6,34 @@ -- {{{ Grab environment local tonumber = tonumber -local io = { popen = io.popen } -local setmetatable = setmetatable -local string = { match = string.match } -local helpers = require("vicious.helpers") + +local helpers = require"vicious.helpers" +local spawn = require"vicious.spawn" -- }}} +-- Mebibyte and gibibyte respectively, because backward compatibility +local UNIT = { mb = 1024, gb = 1024^2 } -- FS: provides file system disk space usage -- vicious.widgets.fs -local fs_all = {} +return helpers.setasyncall{ + async = function(format, warg, callback) + local fs_info = {} -- Get data from df + spawn.with_line_callback_with_shell( + warg and "LC_ALL=C df -kP" or "LC_ALL=C df -klP", + { stdout = function (line) + -- (1024-blocks) (Used) (Available) (Capacity)% (Mounted on) + local s, u, a, p, m = line:match( + "^.-%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%%%s+([%p%w]+)") + if u and m then -- Handle 1st line and broken regexp + helpers.uformat(fs_info, m .. " size", s, UNIT) + helpers.uformat(fs_info, m .. " used", u, UNIT) + helpers.uformat(fs_info, m .. " avail", a, UNIT) --- Variable definitions -local unit = { ["mb"] = 1024, ["gb"] = 1024^2 } - --- {{{ Filesystem widget type -local function worker(format, warg) - local cmd = "LC_ALL=C df -kP" - if not warg then - -- List only local filesystems by default - cmd = cmd .. " -l" - end - - local fs_info = {} -- Get data from df - local f = io.popen(cmd) - - for line in f:lines() do -- Match: (size) (used)(avail)(use%) (mount) - local s = string.match(line, "^.-[%s]([%d]+)") - local u,a,p = string.match(line, "([%d]+)[%D]+([%d]+)[%D]+([%d]+)%%") - local m = string.match(line, "%%[%s]+([%p%w]+)") - - if u and m then -- Handle 1st line and broken regexp - helpers.uformat(fs_info, m .. " size", s, unit) - helpers.uformat(fs_info, m .. " used", u, unit) - helpers.uformat(fs_info, m .. " avail", a, unit) - - fs_info["{" .. m .. " used_p}"] = tonumber(p) - fs_info["{" .. m .. " avail_p}"] = 100 - tonumber(p) - end - end - f:close() - - return fs_info -end --- }}} - -return setmetatable(fs_all, { __call = function(_, ...) return worker(...) end }) + fs_info["{" .. m .. " used_p}"] = tonumber(p) + fs_info["{" .. m .. " avail_p}"] = 100 - tonumber(p) + end + end, + output_done = function () callback(fs_info) end }) + end } From 0e7f5e5bcbd4a3d77070ed52f2d7fe5e8a8fff68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Sat, 22 Jun 2019 18:12:37 +0700 Subject: [PATCH 11/28] [hddtemp_linux] Deprecate io.popen --- Changes.md | 2 +- widgets/hddtemp_linux.lua | 44 ++++++++++++++------------------------- 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/Changes.md b/Changes.md index 0836c31..92c91d8 100644 --- a/Changes.md +++ b/Changes.md @@ -18,7 +18,7 @@ Added: Fixed: - Deprecate the use of `io.popen` in following widgets: - * wifi_linux, wifiiw_linux, hwmontemp_linux + * wifi_linux, wifiiw_linux, hwmontemp_linux, hddtemp_linux * bat_freebsd, mem_freebsd, net_freebsd * volume, gmail, mdir, mpd, fs - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo diff --git a/widgets/hddtemp_linux.lua b/widgets/hddtemp_linux.lua index c46eb13..b381f2f 100644 --- a/widgets/hddtemp_linux.lua +++ b/widgets/hddtemp_linux.lua @@ -5,36 +5,24 @@ -- {{{ Grab environment local tonumber = tonumber -local io = { popen = io.popen } -local setmetatable = setmetatable -local string = { gmatch = string.gmatch } -local helpers = require("vicious.helpers") + +local helpers = require"vicious.helpers" +local spawn = require"vicious.spawn" -- }}} -- Hddtemp: provides hard drive temperatures using the hddtemp daemon -- vicious.widgets.hddtemp -local hddtemp_linux = {} - - --- {{{ HDD Temperature widget type -local function worker(format, warg) - -- Fallback to default hddtemp port - if warg == nil then warg = 7634 end - - local hdd_temp = {} -- Get info from the hddtemp daemon - local quoted = helpers.shellquote(warg) - local f = io.popen("echo | curl --connect-timeout 1 -fsm 3 telnet://127.0.0.1:"..quoted) - - for line in f:lines() do - for d, t in string.gmatch(line, "|([%/%a%d]+)|.-|([%d]+)|[CF]+|") do - hdd_temp["{"..d.."}"] = tonumber(t) - end - end - f:close() - - return hdd_temp -end --- }}} - -return setmetatable(hddtemp_linux, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall{ + async = function(format, warg, callback) + if warg == nil then warg = 7634 end -- fallback to default hddtemp port + local hdd_temp = {} -- get info from the hddtemp daemon + spawn.with_line_callback_with_shell( + "echo | curl -fs telnet://127.0.0.1:" .. warg, + { stdout = function (line) + for d, t in line:gmatch"|([%/%w]+)|.-|(%d+)|[CF]|" do + hdd_temp["{"..d.."}"] = tonumber(t) + end + end, + output_done = function () callback(hdd_temp) end }) + end } From b8afc3aafc2f22cbf63f2b7d811941aa5f9f1542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Thu, 4 Jul 2019 21:46:58 +0700 Subject: [PATCH 12/28] [cmus] Deprecate io.popen and promote to widgets/ --- README.md | 10 ++++++ contrib/README.md | 2 ++ contrib/cmus_all.lua | 75 +------------------------------------------- widgets/cmus_all.lua | 49 +++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 74 deletions(-) mode change 100644 => 120000 contrib/cmus_all.lua create mode 100644 widgets/cmus_all.lua diff --git a/README.md b/README.md index f88b39a..a6d8e59 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,16 @@ Supported platforms: GNU/Linux (require `sysfs`), FreeBSD (require `acpiconf`), * `$4`: Wear level in percent * `$5`: Current (dis)charge rate in Watt +### vicious.contrib.cmus + +Provides cmus player information using `cmus-remote`. + +Supported platforms: platform independent. + +* Argument: a table whose first field is the socket including host (or nil). +* Returns a table with string keys: `${status}`, `${artist}`, `${title}`, + `${duration}`, `${file}`, `${continue}`, `${shuffle}`, `${repeat}`. + ### vicious.widgets.cpu Provides CPU usage for all available CPUs/cores. Since this widget type give diff --git a/contrib/README.md b/contrib/README.md index 106363f..54a39a7 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -87,6 +87,8 @@ yellow - in progress. ### vicious.contrib.cmus +NOTE: This widget type has been promoted to `widgets`. + Provides cmus player information using `cmus-remote`. Supported platforms: platform independent. diff --git a/contrib/cmus_all.lua b/contrib/cmus_all.lua deleted file mode 100644 index e2567e8..0000000 --- a/contrib/cmus_all.lua +++ /dev/null @@ -1,74 +0,0 @@ ------------------------------------------------------------ --- Licensed under the GNU General Public License v2 --- * (c) 2017, JuanKman94 ------------------------------------------------------------ - --- {{{ Grab environment -local tonumber = tonumber -local io = { popen = io.popen } -local setmetatable = setmetatable -local string = { gmatch = string.gmatch, format = string.format } -local helpers = require("vicious.helpers") --- }}} - --- Cmus: provides CMUS information --- vicious.widgets.cmus -local cmus_all = {} - --- {{{ CMUS widget type -local function worker(format, warg) - local cmus_state = { - ["{duration}"] = 0, - ["{file}"] = "N/A", - ["{status}"] = "N/A", - ["{title}"] = "N/A", - ["{artist}"] = "N/A", - ["{continue}"] = "off", - ["{shuffle}"] = "off", - ["{repeat}"] = "off", - } - - -- Fallback to CMUS defaults - local host = warg and (warg.host or warg[1]) or os.getenv("CMUS_SOCKET") - - if not host then - if os.getenv("XDG_RUNTIME_DIR") then - host = os.getenv("XDG_RUNTIME_DIR") .. "/cmus-socket" - else - host = os.getenv("HOME") .. "/.config/cmus/socket" - end - end - - -- Get data from CMUS server - local f = io.popen("cmus-remote --query --server " .. helpers.shellquote(host)) - - for line in f:lines() do - for module, value in string.gmatch(line, "([%w]+) (.*)$") do - if module == "file" or module == "status" then - cmus_state["{"..module.."}"] = value - elseif module == "duration" then - cmus_state["{"..module.."}"] = tonumber(value) - else - for k, v in string.gmatch(value, "([%w]+) (.*)$") do - if module == "tag" then - if k == "title" or k == "artist" then - cmus_state["{"..k.."}"] = v - end - elseif module == "set" then - if k == "continue" or k == "shuffle" or k == "repeat" then - if v == "true" then - cmus_state["{"..k.."}"] = "on" - end - end - end - end - end - end - end - f:close() - - return cmus_state -end --- }}} - -return setmetatable(cmus_all, { __call = function(_, ...) return worker(...) end }) diff --git a/contrib/cmus_all.lua b/contrib/cmus_all.lua new file mode 120000 index 0000000..1627269 --- /dev/null +++ b/contrib/cmus_all.lua @@ -0,0 +1 @@ +widgets/cmus_all.lua \ No newline at end of file diff --git a/widgets/cmus_all.lua b/widgets/cmus_all.lua new file mode 100644 index 0000000..04581bf --- /dev/null +++ b/widgets/cmus_all.lua @@ -0,0 +1,49 @@ +----------------------------------------------------------- +-- Licensed under the GNU General Public License v2 +-- * (c) 2017, JuanKman94 +----------------------------------------------------------- + +-- {{{ Grab environment +local type = type +local tonumber = tonumber +local os = { getenv = os.getenv } + +local helpers = require"vicious.helpers" +local spawn = require"vicious.spawn" +-- }}} + +-- Cmus: provides CMUS information +-- vicious.widgets.cmus +return helpers.setasyncall{ + async = function (format, warg, callback) + local server = "" + if type(warg) == "table" then + server = " --server " .. helpers.shellquote(warg.host or warg[1]) + elseif CMUS_SOCKET then + server = " --server " .. helpers.shellquote(os.getenv"CMUS_SOCKET") + end + + local cmus_state = { ["{duration}"] = 0, ["{file}"] = "N/A", + ["{status}"] = "N/A", ["{title}"] = "N/A", + ["{artist}"] = "N/A", ["{continue}"] = "off", + ["{shuffle}"] = "off", ["{repeat}"] = "off" } + + spawn.with_line_callback("cmus-remote --query" .. server, { + stdout = function (line) + for module, value in line:gmatch"([%w]+) (.*)$" do + if module == "file" or module == "status" then + cmus_state["{"..module.."}"] = value + elseif module == "duration" then + cmus_state["{"..module.."}"] = tonumber(value) + else + local k, v = value:gmatch("([%w]+) (.*)$")() + if module == "tag" then + cmus_state["{"..k.."}"] = v + elseif module == "set" and v == "true" then + cmus_state["{"..k.."}"] = "on" + end + end + end + end, + output_done = function () callback(cmus_state) end }) + end } From ca075d0c8e68571ffc3500023eaf81cbf48741a1 Mon Sep 17 00:00:00 2001 From: Xaver Hellauer Date: Thu, 18 Jul 2019 20:34:42 +0200 Subject: [PATCH 13/28] BSSID in vicious.widgets.wifiiw --- README.md | 2 +- widgets/wifiiw_linux.lua | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a6d8e59..fe8b1e2 100644 --- a/README.md +++ b/README.md @@ -538,7 +538,7 @@ vicious.widgets.wifi, but uses `iw` instead of `iwconfig`). Supported platforms: GNU/Linux. * Argument: the network interface, e.g. `"wlan0"` -* Returns a table with string keys: `${ssid}`, `${mode}`, `${chan}`, +* Returns a table with string keys: `${bssid}`, `${ssid}`, `${mode}`, `${chan}`, `${rate}` (Mb/s), `${freq}` (MHz), `${linp}` (link quality in percent), `${txpw}` (transmission power, in dBm) and `${sign}` (signal level, in dBm) diff --git a/widgets/wifiiw_linux.lua b/widgets/wifiiw_linux.lua index 25aebe1..48e97e2 100644 --- a/widgets/wifiiw_linux.lua +++ b/widgets/wifiiw_linux.lua @@ -26,6 +26,7 @@ function wifiiw_linux.async(format, warg, callback) local winfo = {} local function parse_link(stdout) + winfo["{bssid}"] = stdout:match"Connected to ([%x:]*)" or "N/A" winfo["{ssid}"] = stdout:match"SSID: ([^\n]*)" or "N/A" winfo["{freq}"] = tonumber(stdout:match"freq: (%d+)" or 0) winfo["{sign}"] = -- Signal level can be negative; w/o unit (dBm) From df4048da3767140078782e50d555d7d9f6037155 Mon Sep 17 00:00:00 2001 From: mutlusun Date: Wed, 31 Jul 2019 17:09:11 +0200 Subject: [PATCH 14/28] [thermal_freebsd] Deprecate synchronous sysctl --- Changes.md | 2 +- helpers.lua | 19 ++++++++++++++++++- widgets/thermal_freebsd.lua | 26 ++++++++++++-------------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/Changes.md b/Changes.md index 92c91d8..590447f 100644 --- a/Changes.md +++ b/Changes.md @@ -19,7 +19,7 @@ Fixed: - Deprecate the use of `io.popen` in following widgets: * wifi_linux, wifiiw_linux, hwmontemp_linux, hddtemp_linux - * bat_freebsd, mem_freebsd, net_freebsd + * bat_freebsd, mem_freebsd, net_freebsd, thermal_freebsd * volume, gmail, mdir, mpd, fs - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome diff --git a/helpers.lua b/helpers.lua index 2f56a2b..ed11043 100644 --- a/helpers.lua +++ b/helpers.lua @@ -19,10 +19,12 @@ local getmetatable = getmetatable local string = { upper = string.upper, lower = string.lower, - format = string.format + format = string.format, + match = string.match, } local pcall = pcall local assert = assert +local spawn = require("vicious.spawn") -- }}} @@ -260,6 +262,21 @@ function helpers.sysctl_table(syspath) end -- }}} +-- {{{ Return result from sysctl variable as table (async) +function helpers.sysctl_async(path, parse) + local ret = {} + local path = table.concat(path, " ") + + spawn.with_line_callback("sysctl " .. helpers.shellquote(path), { + stdout = function(line) + local key, value = string.match(line, "(.+): (.+)") + ret[key] = value + end, + output_done = function() parse(ret) end + }) +end +-- }}} + return helpers -- }}} diff --git a/widgets/thermal_freebsd.lua b/widgets/thermal_freebsd.lua index 3387a52..5a7dbe7 100644 --- a/widgets/thermal_freebsd.lua +++ b/widgets/thermal_freebsd.lua @@ -1,5 +1,4 @@ -- {{{ Grab environment -local setmetatable = setmetatable local string = { match = string.match } local helpers = require("vicious.helpers") -- }}} @@ -9,26 +8,25 @@ local helpers = require("vicious.helpers") -- vicious.widgets.thermal local thermal_freebsd = {} - -- {{{ Thermal widget type -local function worker(format, warg) - if not warg then return end +function thermal_freebsd.async(format, warg, callback) + if not warg then return callback{} end if type(warg) ~= "table" then warg = { warg } end local thermals = {} - for i=1, #warg do - local output = helpers.sysctl(warg[i]) - - if not output then - thermals[i] = -1 - else - thermals[i] = string.match(output, "[%d]+") + helpers.sysctl_async(warg, function(ret) + for i=1, #warg do + if ret[warg[i]] ~= nil then + thermals[i] = string.match(ret[warg[i]], "[%d]+") + else + thermals[i] = "N/A" + end end - end - return thermals + callback(thermals) + end) end -- }}} -return setmetatable(thermal_freebsd, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(thermal_freebsd) From 2b60a72d069887a2a1c60a06f932eb7f5cd8253e Mon Sep 17 00:00:00 2001 From: mutlusun Date: Wed, 31 Jul 2019 17:51:47 +0200 Subject: [PATCH 15/28] [uptime_freebsd] Deprecate synchronous sysctl --- Changes.md | 2 +- helpers.lua | 20 +++++++++++++++----- widgets/thermal_freebsd.lua | 14 +++++++++++--- widgets/uptime_freebsd.lua | 22 +++++++++++++--------- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/Changes.md b/Changes.md index 590447f..765058c 100644 --- a/Changes.md +++ b/Changes.md @@ -19,7 +19,7 @@ Fixed: - Deprecate the use of `io.popen` in following widgets: * wifi_linux, wifiiw_linux, hwmontemp_linux, hddtemp_linux - * bat_freebsd, mem_freebsd, net_freebsd, thermal_freebsd + * bat_freebsd, mem_freebsd, net_freebsd, thermal_freebsd, uptime_freebsd * volume, gmail, mdir, mpd, fs - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome diff --git a/helpers.lua b/helpers.lua index ed11043..3ce5323 100644 --- a/helpers.lua +++ b/helpers.lua @@ -21,7 +21,9 @@ local string = { lower = string.lower, format = string.format, match = string.match, + find = string.find, } +local table = { concat = table.concat } local pcall = pcall local assert = assert local spawn = require("vicious.spawn") @@ -263,14 +265,22 @@ end -- }}} -- {{{ Return result from sysctl variable as table (async) -function helpers.sysctl_async(path, parse) +function helpers.sysctl_async(path_table, parse) local ret = {} - local path = table.concat(path, " ") + local path = {} - spawn.with_line_callback("sysctl " .. helpers.shellquote(path), { + for i=1,#path_table do + path[i] = helpers.shellquote(path_table[i]) + end + + path = table.concat(path, " ") + + spawn.with_line_callback("sysctl " .. path, { stdout = function(line) - local key, value = string.match(line, "(.+): (.+)") - ret[key] = value + if not string.find(line, "sysctl: unknown oid") then + local key, value = string.match(line, "(.+): (.+)") + ret[key] = value + end end, output_done = function() parse(ret) end }) diff --git a/widgets/thermal_freebsd.lua b/widgets/thermal_freebsd.lua index 5a7dbe7..623df69 100644 --- a/widgets/thermal_freebsd.lua +++ b/widgets/thermal_freebsd.lua @@ -13,10 +13,18 @@ function thermal_freebsd.async(format, warg, callback) if not warg then return callback{} end if type(warg) ~= "table" then warg = { warg } end - local thermals = {} - helpers.sysctl_async(warg, function(ret) - for i=1, #warg do + local thermals = {} + + for k, v in pairs(ret) do + print(k, v) + end + + for i=1,#warg do + print(warg[i]) + print(ret[warg[i]]) + print(ret["hw.acpi.thermal.tz0.temperature"]) + print(ret['hw.acpi.thermal.tz0.temperature']) if ret[warg[i]] ~= nil then thermals[i] = string.match(ret[warg[i]], "[%d]+") else diff --git a/widgets/uptime_freebsd.lua b/widgets/uptime_freebsd.lua index 9e075e5..09ee75e 100644 --- a/widgets/uptime_freebsd.lua +++ b/widgets/uptime_freebsd.lua @@ -14,17 +14,21 @@ local uptime_freebsd = {} -- {{{ Uptime widget type -local function worker(format) - local l1, l5, l15 = string.match(helpers.sysctl("vm.loadavg"), "{ ([%d]+%.[%d]+) ([%d]+%.[%d]+) ([%d]+%.[%d]+) }") - local up_t = os.time() - tonumber(string.match(helpers.sysctl("kern.boottime"), "sec = ([%d]+)")) +function uptime_freebsd.async(format, warg, callback) + helpers.sysctl_async({ "vm.loadavg", + "kern.boottime" }, + function(ret) + local l1, l5, l15 = string.match(ret["vm.loadavg"], "{ ([%d]+%.[%d]+) ([%d]+%.[%d]+) ([%d]+%.[%d]+) }") + local up_t = os.time() - tonumber(string.match(ret["kern.boottime"], "sec = ([%d]+)")) - -- Get system uptime - local up_d = math.floor(up_t / (3600 * 24)) - local up_h = math.floor((up_t % (3600 * 24)) / 3600) - local up_m = math.floor(((up_t % (3600 * 24)) % 3600) / 60) + -- Get system uptime + local up_d = math.floor(up_t / (3600 * 24)) + local up_h = math.floor((up_t % (3600 * 24)) / 3600) + local up_m = math.floor(((up_t % (3600 * 24)) % 3600) / 60) - return {up_d, up_h, up_m, l1, l5, l15} + return callback({ up_d, up_h, up_m, l1, l5, l15 }) + end) end -- }}} -return setmetatable(uptime_freebsd, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(uptime_freebsd) From 04e8a49d2e0ecfb0eede7459544233ad2abee45b Mon Sep 17 00:00:00 2001 From: mutlusun Date: Wed, 31 Jul 2019 18:07:04 +0200 Subject: [PATCH 16/28] [cpu_freebsd] Deprecate synchronous sysctl --- Changes.md | 3 +- widgets/cpu_freebsd.lua | 69 ++++++++++++++++++------------------- widgets/thermal_freebsd.lua | 8 ----- widgets/uptime_freebsd.lua | 1 - 4 files changed, 36 insertions(+), 45 deletions(-) diff --git a/Changes.md b/Changes.md index 765058c..de6da4a 100644 --- a/Changes.md +++ b/Changes.md @@ -19,7 +19,8 @@ Fixed: - Deprecate the use of `io.popen` in following widgets: * wifi_linux, wifiiw_linux, hwmontemp_linux, hddtemp_linux - * bat_freebsd, mem_freebsd, net_freebsd, thermal_freebsd, uptime_freebsd + * bat_freebsd, mem_freebsd, net_freebsd, thermal_freebsd, uptime_freebsd, + cpu_freebsd * volume, gmail, mdir, mpd, fs - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome diff --git a/widgets/cpu_freebsd.lua b/widgets/cpu_freebsd.lua index 044286c..c6e5272 100644 --- a/widgets/cpu_freebsd.lua +++ b/widgets/cpu_freebsd.lua @@ -1,7 +1,5 @@ -- {{{ Grab environment local helpers = require("vicious.helpers") -local tonumber = tonumber -local setmetatable = setmetatable local math = { floor = math.floor } local string = { gmatch = string.gmatch } -- }}} @@ -16,54 +14,55 @@ local cpu_total = {} local cpu_idle = {} -- {{{ CPU widget type -local function worker(format) - local cp_times = helpers.sysctl("kern.cp_times") +function cpu_freebsd.async(format, warg, callback) local matches = {} local tmp_total = {} local tmp_idle = {} local tmp_usage = {} - -- Read input data - for v in string.gmatch(cp_times, "([%d]+)") do - table.insert(matches, v) - end + helpers.sysctl_async({ "kern.cp_times" }, function(ret) + -- Read input data + for v in string.gmatch(ret["kern.cp_times"], "([%d]+)") do + table.insert(matches, v) + end - -- Set first value of function tables - if #cpu_total == 0 then -- check for empty table + -- Set first value of function tables + if #cpu_total == 0 then -- check for empty table + for i = 1, #matches / 5 + 1 do + cpu_total[i] = 0 + cpu_idle[i] = 0 + end + end for i = 1, #matches / 5 + 1 do - cpu_total[i] = 0 - cpu_idle[i] = 0 + tmp_total[i] = 0 + tmp_idle[i] = 0 + tmp_usage[i] = 0 end - end - for i = 1, #matches / 5 + 1 do - tmp_total[i] = 0 - tmp_idle[i] = 0 - tmp_usage[i] = 0 - end - -- CPU usage - for i, v in ipairs(matches) do - local index = math.floor((i-1) / 5) + 2 -- current cpu + -- CPU usage + for i, v in ipairs(matches) do + local index = math.floor((i-1) / 5) + 2 -- current cpu - tmp_total[1] = tmp_total[1] + v - tmp_total[index] = tmp_total[index] + v + tmp_total[1] = tmp_total[1] + v + tmp_total[index] = tmp_total[index] + v - if (i-1) % 5 == 4 then - tmp_idle[1] = tmp_idle[1] + v - tmp_idle[index] = tmp_idle[index] + v + if (i-1) % 5 == 4 then + tmp_idle[1] = tmp_idle[1] + v + tmp_idle[index] = tmp_idle[index] + v + end end - end - for i = 1, #tmp_usage do - tmp_usage[i] = tmp_total[i] - cpu_total[i] - tmp_usage[i] = math.floor((tmp_usage[i] - (tmp_idle[i] - cpu_idle[i])) / tmp_usage[i] * 100) - end + for i = 1, #tmp_usage do + tmp_usage[i] = tmp_total[i] - cpu_total[i] + tmp_usage[i] = math.floor((tmp_usage[i] - (tmp_idle[i] - cpu_idle[i])) / tmp_usage[i] * 100) + end - cpu_total = tmp_total - cpu_idle = tmp_idle + cpu_total = tmp_total + cpu_idle = tmp_idle - return tmp_usage + return callback(tmp_usage) + end) end -- }}} -return setmetatable(cpu_freebsd, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(cpu_freebsd) diff --git a/widgets/thermal_freebsd.lua b/widgets/thermal_freebsd.lua index 623df69..c550f1a 100644 --- a/widgets/thermal_freebsd.lua +++ b/widgets/thermal_freebsd.lua @@ -16,15 +16,7 @@ function thermal_freebsd.async(format, warg, callback) helpers.sysctl_async(warg, function(ret) local thermals = {} - for k, v in pairs(ret) do - print(k, v) - end - for i=1,#warg do - print(warg[i]) - print(ret[warg[i]]) - print(ret["hw.acpi.thermal.tz0.temperature"]) - print(ret['hw.acpi.thermal.tz0.temperature']) if ret[warg[i]] ~= nil then thermals[i] = string.match(ret[warg[i]], "[%d]+") else diff --git a/widgets/uptime_freebsd.lua b/widgets/uptime_freebsd.lua index 09ee75e..a48f64e 100644 --- a/widgets/uptime_freebsd.lua +++ b/widgets/uptime_freebsd.lua @@ -1,6 +1,5 @@ -- {{{ Grab environment local tonumber = tonumber -local setmetatable = setmetatable local math = { floor = math.floor } local string = { match = string.match } local helpers = require("vicious.helpers") From d6e21f71d04bb18be85e47b5468647286e395500 Mon Sep 17 00:00:00 2001 From: mutlusun Date: Wed, 31 Jul 2019 18:22:49 +0200 Subject: [PATCH 17/28] [cpufreq_freebsd][fanspeed_freebsd] Deprecate syncronous sysctl --- Changes.md | 2 +- widgets/cpufreq_freebsd.lua | 19 +++++++++---------- widgets/fanspeed_freebsd.lua | 34 +++++++++++++++++++++++----------- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Changes.md b/Changes.md index de6da4a..403d325 100644 --- a/Changes.md +++ b/Changes.md @@ -20,7 +20,7 @@ Fixed: - Deprecate the use of `io.popen` in following widgets: * wifi_linux, wifiiw_linux, hwmontemp_linux, hddtemp_linux * bat_freebsd, mem_freebsd, net_freebsd, thermal_freebsd, uptime_freebsd, - cpu_freebsd + cpu_freebsd, cpufreq_freebsd, fanspeed_freebsd * volume, gmail, mdir, mpd, fs - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome diff --git a/widgets/cpufreq_freebsd.lua b/widgets/cpufreq_freebsd.lua index 351cc68..c53e2d7 100644 --- a/widgets/cpufreq_freebsd.lua +++ b/widgets/cpufreq_freebsd.lua @@ -1,6 +1,5 @@ -- {{{ Grab environment local tonumber = tonumber -local setmetatable = setmetatable local helpers = require("vicious.helpers") -- }}} @@ -11,24 +10,24 @@ local cpufreq_freebsd = {} -- {{{ CPU frequency widget type -local function worker(format, warg) - if not warg then return end +function cpufreq_freebsd.async(format, warg, callback) + if not warg then return callback({}) end -- Default frequency and voltage values local freqv = { ["mhz"] = "N/A", ["ghz"] = "N/A", ["v"] = "N/A", ["mv"] = "N/A", + ["governor"] = "N/A", } - local freq = tonumber(helpers.sysctl("dev.cpu." .. warg .. ".freq")) + helpers.sysctl_async({ "dev.cpu." .. warg .. ".freq" }, function(ret) + freqv.mhz = tonumber(ret["dev.cpu." .. warg .. ".freq"]) + freqv.ghz = freqv.mhz / 1000 - freqv.mhz = freq - freqv.ghz = freq / 1000 + return callback({freqv.mhz, freqv.ghz, freqv.mv, freqv.v, freqv.governor}) + end) - local governor = "N/A" - - return {freqv.mhz, freqv.ghz, freqv.mv, freqv.v, governor} end -- }}} -return setmetatable(cpufreq_freebsd, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(cpufreq_freebsd) diff --git a/widgets/fanspeed_freebsd.lua b/widgets/fanspeed_freebsd.lua index 774b0da..b8d1a60 100644 --- a/widgets/fanspeed_freebsd.lua +++ b/widgets/fanspeed_freebsd.lua @@ -1,5 +1,4 @@ -- {{{ Grab environment -local setmetatable = setmetatable local helpers = require("vicious.helpers") local tonumber = tonumber -- }}} @@ -10,19 +9,32 @@ local tonumber = tonumber -- expects one (1) full sysctl string to entry -- e.g.: "dev.acpi_ibm.0.fan_speed" +-- fanspeed: provides speed level of main fan +-- vicious.widgets.fanspeed +-- +-- expects one (1) full sysctl string to entry +-- e.g.: "dev.acpi_ibm.0.fan_speed" local fanspeed_freebsd = {} -local function worker(format, warg) - if not warg then return end +-- {{{ fanspeed widget type +function fanspeed_freebsd.async(format, warg, callback) + if not warg then return callback({}) end + if type(warg) ~= "table" then warg = { warg } end - local fanspeed = helpers.sysctl(warg) + helpers.sysctl_async(warg, function(ret) + local fanspeed = {} - if not fanspeed then - -- use negative fanspeed to indicate error - return {-1} - else - return {tonumber(fanspeed)} - end + for i=1,#warg do + if ret[warg[i]] ~= nil then + fanspeed[i] = tonumber(ret[warg[i]]) + else + fanspeed[i] = "N/A" + end + end + + callback(fanspeed) + end) end +-- }}} -return setmetatable(fanspeed_freebsd, { __call = function(_, ...) return worker(...) end }) +return helpers.setasyncall(fanspeed_freebsd) From 875e98e24e9e38a68642fa4f6d06ee9f07bdf714 Mon Sep 17 00:00:00 2001 From: mutlusun Date: Wed, 31 Jul 2019 18:26:06 +0200 Subject: [PATCH 18/28] [helpers.lua] Removed old sysctl functions --- Changes.md | 5 +++++ helpers.lua | 38 -------------------------------------- 2 files changed, 5 insertions(+), 38 deletions(-) diff --git a/Changes.md b/Changes.md index 403d325..3334c44 100644 --- a/Changes.md +++ b/Changes.md @@ -26,6 +26,11 @@ Fixed: - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) +Removed: +- `helpers.sysctl` and `helpers.sysctl_table` were removed in favour of + `helpers.sysctl_async`. + + # Changes in 2.3.3 Feature: Add battery widget type for OpenBSD diff --git a/helpers.lua b/helpers.lua index 3ce5323..f99605c 100644 --- a/helpers.lua +++ b/helpers.lua @@ -226,44 +226,6 @@ function helpers.scroll(text, maxlen, widget) end -- }}} --- {{{ Return result from one sysctl variable as string -function helpers.sysctl(path) - local fd = io.popen("sysctl -n " .. helpers.shellquote(path)) - - if not fd then - return - end - - local ret = fd:read() - - fd:close() - - return ret -end --- }}} - --- {{{ Return result from multiple sysctl variables as table -function helpers.sysctl_table(syspath) - return setmetatable({ _path = syspath }, - { __index = function(table, index) - local path = "sysctl -n " .. helpers.shellquote(table._path .. "." .. index) - local f = io.popen(path) - if f then - local s = f:read("*all") - f:close() - if select(2, s:gsub("\n", "\n")) > 1 then - local o = { _path = path} - setmetatable(o, getmetatable(table)) - return o - else - return s - end - end - end - }) -end --- }}} - -- {{{ Return result from sysctl variable as table (async) function helpers.sysctl_async(path_table, parse) local ret = {} From f5060093c66e47a509ac2611cfea5af3c1c5c4e4 Mon Sep 17 00:00:00 2001 From: mutlusun Date: Wed, 31 Jul 2019 18:46:01 +0200 Subject: [PATCH 19/28] [os_all] Splitted into os_linux and os_bsd --- widgets/os_bsd.lua | 47 ++++++++++++++++++++++++++++ widgets/{os_all.lua => os_linux.lua} | 20 ++---------- 2 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 widgets/os_bsd.lua rename widgets/{os_all.lua => os_linux.lua} (76%) diff --git a/widgets/os_bsd.lua b/widgets/os_bsd.lua new file mode 100644 index 0000000..cfe2170 --- /dev/null +++ b/widgets/os_bsd.lua @@ -0,0 +1,47 @@ +--------------------------------------------------- +-- Licensed under the GNU General Public License v2 +-- * (c) 2010, Adrian C. +--------------------------------------------------- + +-- {{{ Grab environment +local los = { getenv = os.getenv } +local string = { match = string.match } +local helpers = require("vicious.helpers") +local spawn = require("vicious.spawn") +-- }}} + + +-- OS: provides operating system information +-- vicious.widgets.os +local os_bsd = {} + + +-- {{{ Operating system widget type +local function parse(stdout, stderr, exitreason, exitcode) + local system = { + ["ostype"] = "N/A", + ["hostname"] = "N/A", + ["osrelease"] = "N/A", + ["username"] = "N/A", + ["entropy"] = "N/A", + ["entropy_p"] = "N/A" + } + + -- BSD manual page: uname(1) + system["ostype"], system["hostname"], system["osrelease"] = + string.match(stdout, "([%w]+)[%s]([%w%p]+)[%s]([%w%p]+)") + + -- Get user from the environment + system["username"] = los.getenv("USER") + + return {system["ostype"], system["osrelease"], system["username"], + system["hostname"], system["entropy"], system["entropy_p"]} +end + +function os_bsd.async(format, warg, callback) + spawn.easy_async("uname -snr", + function (...) callback(parse(...)) end) +end +-- }}} + +return helpers.setasyncall(os_bsd) diff --git a/widgets/os_all.lua b/widgets/os_linux.lua similarity index 76% rename from widgets/os_all.lua rename to widgets/os_linux.lua index 4c41338..1a6eec7 100644 --- a/widgets/os_all.lua +++ b/widgets/os_linux.lua @@ -6,21 +6,17 @@ -- {{{ Grab environment local pairs = pairs local tonumber = tonumber -local io = { popen = io.popen } local math = { ceil = math.ceil } local los = { getenv = os.getenv } local setmetatable = setmetatable local helpers = require("vicious.helpers") -local string = { - gsub = string.gsub, - match = string.match -} +local string = { gsub = string.gsub } -- }}} -- OS: provides operating system information -- vicious.widgets.os -local os_all = {} +local os_linux = {} -- {{{ Operating system widget type @@ -42,16 +38,6 @@ local function worker(format) end end - -- BSD manual page: uname(1) - if system["ostype"] == "N/A" then - local f = io.popen("uname -snr") - local uname = f:read("*line") - f:close() - - system["ostype"], system["hostname"], system["osrelease"] = - string.match(uname, "([%w]+)[%s]([%w%p]+)[%s]([%w%p]+)") - end - -- Linux manual page: random(4) if kernel.random then -- Linux 2.6 default entropy pool is 4096-bits @@ -70,4 +56,4 @@ local function worker(format) end -- }}} -return setmetatable(os_all, { __call = function(_, ...) return worker(...) end }) +return setmetatable(os_linux, { __call = function(_, ...) return worker(...) end }) From 268f4acfd91b95b32d521b31bd97e9fb41717733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Fri, 16 Aug 2019 20:43:28 +0700 Subject: [PATCH 20/28] [bat_openbsd] Deprecate io.popen --- Changes.md | 3 +- widgets/bat_openbsd.lua | 128 +++++++++++++++++++++++----------------- 2 files changed, 75 insertions(+), 56 deletions(-) diff --git a/Changes.md b/Changes.md index 3334c44..6dfe537 100644 --- a/Changes.md +++ b/Changes.md @@ -21,16 +21,17 @@ Fixed: * wifi_linux, wifiiw_linux, hwmontemp_linux, hddtemp_linux * bat_freebsd, mem_freebsd, net_freebsd, thermal_freebsd, uptime_freebsd, cpu_freebsd, cpufreq_freebsd, fanspeed_freebsd + * bat_openbsd * volume, gmail, mdir, mpd, fs - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) Removed: + - `helpers.sysctl` and `helpers.sysctl_table` were removed in favour of `helpers.sysctl_async`. - # Changes in 2.3.3 Feature: Add battery widget type for OpenBSD diff --git a/widgets/bat_openbsd.lua b/widgets/bat_openbsd.lua index 752a666..ced83d8 100644 --- a/widgets/bat_openbsd.lua +++ b/widgets/bat_openbsd.lua @@ -1,67 +1,85 @@ +-- bat_openbsd.lua - provide battery information on OpenBSD +-- Copyright (C) 2019 Enric Morales +-- Copyright (C) 2019 Nguyแป…n Gia Phong +-- +-- This file is part of Vicious. +-- +-- Vicious is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as +-- published by the Free Software Foundation, either version 2 of the +-- License, or (at your option) any later version. +-- +-- Vicious is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Affero General Public License for more details. +-- +-- You should have received a copy of the GNU Affero General Public License +-- along with Vicious. If not, see . + -- {{{ Grab environment -local setmetatable = setmetatable local tonumber = tonumber -local string = { format = string.format, gmatch = string.gmatch } -local io = { popen = io.popen } local math = { floor = math.floor, modf = math.modf } + +local helpers = require"vicious.helpers" +local spawn = require"vicious.spawn" -- }}} -local bat_openbsd = {} +local STATES = { [0] = "โ†ฏ", -- not charging + [1] = "-", -- discharging + [2] = "!", -- critical + [3] = "+", -- charging + [4] = "N/A", -- unknown status + [255] = "N/A" } -- unimplemented by the driver -local function worker(format, warg) - local battery = warg or "bat0" - local filter = string.format("hw.sensors.acpi%s", battery) - local cmd = string.format("sysctl -a | grep '^%s'", filter) - local proc = io.popen(cmd) +return helpers.setasyncall{ + async = function (format, warg, callback) + local filter = "hw.sensors.acpi" .. (warg or "bat0") + local pattern = filter .. ".(%S+)=(%S+)" + local bat_info = {} - local bat_info = {} - for line in proc:lines("*l") do - for key, value in string.gmatch(line, "(%S+)=(%S+)") do - key = key:gsub(filter .. ".", "") - bat_info[key] = value - end - end + spawn.with_line_callback_with_shell( + ("sysctl -a | grep '^%s'"):format(filter), + { stdout = function (line) + for key, value in line:gmatch(pattern) do + bat_info[key] = value + end + end, + output_done = function () + -- current state + local state = STATES[tonumber(bat_info.raw0)] - -- current state - local states = {[0] = "โ†ฏ", -- not charging - [1] = "-", -- discharging - [2] = "!", -- critical - [3] = "+", -- charging - [4] = "N/A", -- unknown status - [255] = "N/A"} -- unimplemented by the driver - local state = states[tonumber(bat_info.raw0)] + -- battery capacity in percent + local percent = tonumber( + bat_info.watthour3 / bat_info.watthour0 * 100) - -- battery capacity in percent - local percent = tonumber(bat_info.watthour3 / bat_info.watthour0 * 100) + local time + if tonumber(bat_info.power0) < 1 then + time = "โˆž" + else + local raw_time = bat_info.watthour3 / bat_info.power0 + local hours, hour_fraction = math.modf(raw_time) + local minutes = math.floor(60 * hour_fraction) + time = ("%d:%0.2d"):format(hours, minutes) + end - local time - if tonumber(bat_info.power0) < 1 then - time = "โˆž" - else - local raw_time = bat_info.watthour3 / bat_info.power0 - local hours, hour_fraction = math.modf(raw_time) - local minutes = math.floor(60 * hour_fraction) - time = string.format("%d:%0.2d", hours, minutes) - end + -- calculate wear level from (last full / design) capacity + local wear = "N/A" + if bat_info.watthour0 and bat_info.watthour4 then + local l_full = tonumber(bat_info.watthour0) + local design = tonumber(bat_info.watthour4) + wear = math.floor(l_full / design * 100) + end - -- calculate wear level from (last full / design) capacity - local wear = "N/A" - if bat_info.watthour0 and bat_info.watthour4 then - local l_full = tonumber(bat_info.watthour0) - local design = tonumber(bat_info.watthour4) - wear = math.floor(l_full / design * 100) - end + -- dis-/charging rate as presented by battery + local rate = bat_info.power0 - -- dis-/charging rate as presented by battery - local rate = bat_info.power0 - - -- returns - -- * state (high "โ†ฏ", discharging "-", charging "+", N/A "โŒ" } - -- * remaining_capacity (percent) - -- * remaining_time, by battery - -- * wear level (percent) - -- * present_rate (W) - return {state, percent, time, wear, rate} -end - -return setmetatable(bat_openbsd, { __call = function(_, ...) return worker(...) end }) + -- Pass the following arguments to callback function: + -- * battery state symbol (โ†ฏ, -, !, + or N/A) + -- * remaining_capacity (in percent) + -- * remaining_time, by battery + -- * wear level (in percent) + -- * present_rate (in Watts) + callback{state, percent, time, wear, rate} + end }) + end } From 9d562d4e5e18e078f1006f1959a5cab1421ed7cc Mon Sep 17 00:00:00 2001 From: mutlusun Date: Fri, 23 Aug 2019 09:46:57 +0200 Subject: [PATCH 21/28] add os widget to changes.md --- Changes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changes.md b/Changes.md index 3334c44..4ae50c2 100644 --- a/Changes.md +++ b/Changes.md @@ -25,6 +25,7 @@ Fixed: - [mpd] Lua 5.3 compatibility (for real this time); also correct a typo - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) +- [os] Splitted os_all into os_linux and os_bsd (and refactored to async) Removed: - `helpers.sysctl` and `helpers.sysctl_table` were removed in favour of From b7490a20af6745cee3aee14e50385ec2656b2763 Mon Sep 17 00:00:00 2001 From: mutlusun Date: Fri, 23 Aug 2019 09:51:23 +0200 Subject: [PATCH 22/28] improved sysctl_async documentation line --- helpers.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers.lua b/helpers.lua index f99605c..5fab4cf 100644 --- a/helpers.lua +++ b/helpers.lua @@ -226,7 +226,7 @@ function helpers.scroll(text, maxlen, widget) end -- }}} --- {{{ Return result from sysctl variable as table (async) +-- {{{ Parse output of sysctl command calling the `parse` function function helpers.sysctl_async(path_table, parse) local ret = {} local path = {} From a23952f555c053a91b5f10bee71ba029d55f195d Mon Sep 17 00:00:00 2001 From: mutlusun Date: Fri, 23 Aug 2019 09:58:40 +0200 Subject: [PATCH 23/28] corrected symbolic link to cmus_all --- contrib/cmus_all.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/cmus_all.lua b/contrib/cmus_all.lua index 1627269..4ba2bda 120000 --- a/contrib/cmus_all.lua +++ b/contrib/cmus_all.lua @@ -1 +1 @@ -widgets/cmus_all.lua \ No newline at end of file +../widgets/cmus_all.lua \ No newline at end of file From 8092915e86265edb4ed9d8ed0c28094b12bc68b6 Mon Sep 17 00:00:00 2001 From: mutlusun Date: Fri, 23 Aug 2019 10:08:05 +0200 Subject: [PATCH 24/28] [fanspeed_freebsd] Multiple fans are now supported --- README.md | 7 ++++--- widgets/fanspeed_freebsd.lua | 9 ++------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a0d553a..ad391b3 100644 --- a/README.md +++ b/README.md @@ -228,12 +228,13 @@ Returns a table with string keys: `${sda total_s}`, `${sda total_kb}`, ### vicious.widget.fanspeed -Provides fanspeed information for specified fan. +Provides fanspeed information for specified fans. Supported platforms: FreeBSD. -* Argument: full `sysctl` string to entry, e.g. `"dev.acpi_ibm.0.fan_speed"` -* Returns speed of specified fan in RPM, `-1` on error (probably wrong string) +* Argument: full `sysctl` string to one or multiple entries, e.g. + `"dev.acpi_ibm.0.fan_speed"` +* Returns speed of specified fan in RPM, `"N/A"` on error (probably wrong string) ### vicious.widgets.fs diff --git a/widgets/fanspeed_freebsd.lua b/widgets/fanspeed_freebsd.lua index b8d1a60..5be26ef 100644 --- a/widgets/fanspeed_freebsd.lua +++ b/widgets/fanspeed_freebsd.lua @@ -4,15 +4,10 @@ local tonumber = tonumber -- }}} --- fanspeed: provides speed level of main fan --- --- expects one (1) full sysctl string to entry --- e.g.: "dev.acpi_ibm.0.fan_speed" - --- fanspeed: provides speed level of main fan +-- fanspeed: provides speed level of fans -- vicious.widgets.fanspeed -- --- expects one (1) full sysctl string to entry +-- expects one or multiple full sysctl strings to entry -- e.g.: "dev.acpi_ibm.0.fan_speed" local fanspeed_freebsd = {} From bc134d87926731ef52755edc63b0e3b619238386 Mon Sep 17 00:00:00 2001 From: mutlusun Date: Fri, 23 Aug 2019 10:45:43 +0200 Subject: [PATCH 25/28] [mem_freebsd] Correct async behaviour --- widgets/mem_freebsd.lua | 170 +++++++++++++++++++++++----------------- 1 file changed, 96 insertions(+), 74 deletions(-) diff --git a/widgets/mem_freebsd.lua b/widgets/mem_freebsd.lua index 4a162c1..ebc4484 100644 --- a/widgets/mem_freebsd.lua +++ b/widgets/mem_freebsd.lua @@ -5,7 +5,8 @@ local helpers = require("vicious.helpers") local spawn = require("vicious.spawn") local string = { match = string.match, - gmatch = string.gmatch + gmatch = string.gmatch, + find = string.find } -- }}} @@ -15,80 +16,101 @@ local mem_freebsd = {} -- {{{ Memory widget type -local function parse(stdout, stderr, exitreason, exitcode) - local pagesize = tonumber(helpers.sysctl("hw.pagesize")) - local vm_stats = helpers.sysctl_table("vm.stats.vm") - local _mem = { buf = {}, total = nil } - - -- Get memory space in bytes - _mem.total = tonumber(vm_stats.v_page_count) * pagesize - _mem.buf.free = tonumber(vm_stats.v_free_count) * pagesize - _mem.buf.laundry = tonumber(vm_stats.v_laundry_count) * pagesize - _mem.buf.cache = tonumber(vm_stats.v_cache_count) * pagesize - _mem.buf.wired = tonumber(vm_stats.v_wire_count) * pagesize - - -- Rework into megabytes - _mem.total = math.floor(_mem.total/1048576) - _mem.buf.free = math.floor(_mem.buf.free/1048576) - _mem.buf.laundry = math.floor(_mem.buf.laundry/1048576) - _mem.buf.cache = math.floor(_mem.buf.cache/1048576) - _mem.buf.wired = math.floor(_mem.buf.wired/1048576) - - -- Calculate memory percentage - _mem.free = _mem.buf.free + _mem.buf.cache - -- used memory basically consists of active+inactive+wired - _mem.inuse = _mem.total - _mem.free - _mem.notfreeable = _mem.inuse - _mem.buf.laundry - _mem.wire = _mem.buf.wired - - _mem.usep = math.floor(_mem.inuse / _mem.total * 100) - _mem.wirep = math.floor(_mem.wire / _mem.total * 100) - _mem.notfreeablep = math.floor(_mem.notfreeable / _mem.total * 100) - - -- Get swap states - local vm_swap_total = tonumber(helpers.sysctl("vm.swap_total")) - local vm_swap_enabled = tonumber(helpers.sysctl("vm.swap_enabled")) - local _swp = { buf = {}, total = nil } - - if vm_swap_enabled == 1 and vm_swap_total > 0 then - -- Initialise variables - _swp.usep = 0 - _swp.inuse = 0 - _swp.total = 0 - _swp.buf.free = 0 - - -- Read output of swapinfo in Mbytes (from async function call) - -- Read content and sum up - local counter = 1 - for line in string.gmatch(stdout, "[^\n]+") do - -- Skip first line (table header) - if counter ~= 1 then - local ltotal, lused, lfree = string.match(line, "%s+([%d]+)%s+([%d]+)%s+([%d]+)") - -- Add swap space in Mbytes - _swp.total = _swp.total + tonumber(ltotal) - _swp.inuse = _swp.inuse + tonumber(lused) - _swp.buf.free = _swp.buf.free + tonumber(lfree) - end - counter = counter + 1 - end - - -- Calculate percentage - _swp.usep = math.floor(_swp.inuse / _swp.total * 100) - else - _swp.usep = -1 - _swp.inuse = -1 - _swp.total = -1 - _swp.buf.free = -1 - end - - return { _mem.usep, _mem.inuse, _mem.total, _mem.free, - _swp.usep, _swp.inuse, _swp.total, _swp.buf.free, - _mem.wirep, _mem.wire, _mem.notfreeablep, _mem.notfreeable } -end - function mem_freebsd.async(format, warg, callback) - spawn.easy_async("swapinfo -m", - function (...) callback(parse(...)) end) + helpers.sysctl_async({ "hw.pagesize", + "vm.stats.vm", + "vm.swap_total", + "vm.swap_enabled" }, + function(ret) + + local pagesize = tonumber(ret["hw.pagesize"]) + local _mem = { buf = {}, total = nil } + + -- Get memory space in bytes + _mem.total = tonumber(ret["vm.stats.vm.v_page_count"]) * pagesize + _mem.buf.free = tonumber(ret["vm.stats.vm.v_free_count"]) * pagesize + _mem.buf.laundry = tonumber(ret["vm.stats.vm.v_laundry_count"]) * pagesize + _mem.buf.cache = tonumber(ret["vm.stats.vm.v_cache_count"]) * pagesize + _mem.buf.wired = tonumber(ret["vm.stats.vm.v_wire_count"]) * pagesize + + -- Rework into megabytes + _mem.total = math.floor(_mem.total/1048576) + _mem.buf.free = math.floor(_mem.buf.free/1048576) + _mem.buf.laundry = math.floor(_mem.buf.laundry/1048576) + _mem.buf.cache = math.floor(_mem.buf.cache/1048576) + _mem.buf.wired = math.floor(_mem.buf.wired/1048576) + + -- Calculate memory percentage + _mem.free = _mem.buf.free + _mem.buf.cache + -- used memory basically consists of active+inactive+wired + _mem.inuse = _mem.total - _mem.free + _mem.notfreeable = _mem.inuse - _mem.buf.laundry + _mem.wire = _mem.buf.wired + + _mem.usep = math.floor(_mem.inuse / _mem.total * 100) + _mem.wirep = math.floor(_mem.wire / _mem.total * 100) + _mem.notfreeablep = math.floor(_mem.notfreeable / _mem.total * 100) + + -- Get swap states + local vm_swap_total = tonumber(ret["vm.swap_total"]) + local vm_swap_enabled = tonumber(ret["vm.swap_enabled"]) + local _swp = { buf = {}, total = nil } + + if vm_swap_enabled == 1 and vm_swap_total > 0 then + -- Initialise variables + _swp.usep = 0 + _swp.inuse = 0 + _swp.total = 0 + _swp.buf.free = 0 + + -- Read output of swapinfo in Mbytes (from async function call) + -- Read content and sum up + spawn.with_line_callback("swapinfo -m", { + stdout = function(line) + if not string.find(line, "Device") then + local ltotal, lused, lfree = string.match(line, "%s+([%d]+)%s+([%d]+)%s+([%d]+)") + -- Add swap space in Mbytes + _swp.total = _swp.total + tonumber(ltotal) + _swp.inuse = _swp.inuse + tonumber(lused) + _swp.buf.free = _swp.buf.free + tonumber(lfree) + end + end, + output_done = function() + print(_swp.inuse, _swp.total) + _swp.usep = math.floor(_swp.inuse / _swp.total * 100) + callback({ _mem.usep, + _mem.inuse, + _mem.total, + _mem.free, + _swp.usep, + _swp.inuse, + _swp.total, + _swp.buf.free, + _mem.wirep, + _mem.wire, + _mem.notfreeablep, + _mem.notfreeable }) + end + }) + else + _swp.usep = -1 + _swp.inuse = -1 + _swp.total = -1 + _swp.buf.free = -1 + callback({ _mem.usep, + _mem.inuse, + _mem.total, + _mem.free, + _swp.usep, + _swp.inuse, + _swp.total, + _swp.buf.free, + _mem.wirep, + _mem.wire, + _mem.notfreeablep, + _mem.notfreeable }) + end + end) end -- }}} From 025d2e1ad55bb1e3fbb52d6c39771729e6375122 Mon Sep 17 00:00:00 2001 From: mutlusun Date: Fri, 23 Aug 2019 10:51:15 +0200 Subject: [PATCH 26/28] added type to environmet where missing --- widgets/fanspeed_freebsd.lua | 1 + widgets/mpd_all.lua | 2 +- widgets/thermal_freebsd.lua | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/widgets/fanspeed_freebsd.lua b/widgets/fanspeed_freebsd.lua index 5be26ef..e55a51f 100644 --- a/widgets/fanspeed_freebsd.lua +++ b/widgets/fanspeed_freebsd.lua @@ -1,6 +1,7 @@ -- {{{ Grab environment local helpers = require("vicious.helpers") local tonumber = tonumber +local type = type -- }}} diff --git a/widgets/mpd_all.lua b/widgets/mpd_all.lua index 4c2f524..e8a5afd 100644 --- a/widgets/mpd_all.lua +++ b/widgets/mpd_all.lua @@ -6,7 +6,7 @@ -- {{{ Grab environment local tonumber = tonumber local math = { floor = math.floor } - +local type = type local helpers = require"vicious.helpers" local spawn = require"vicious.spawn" -- }}} diff --git a/widgets/thermal_freebsd.lua b/widgets/thermal_freebsd.lua index c550f1a..8979822 100644 --- a/widgets/thermal_freebsd.lua +++ b/widgets/thermal_freebsd.lua @@ -1,6 +1,7 @@ -- {{{ Grab environment local string = { match = string.match } local helpers = require("vicious.helpers") +local type = type -- }}} From 83efd26802ee926ca39868555c3f160f6adae778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Fri, 23 Aug 2019 22:50:13 +0700 Subject: [PATCH 27/28] Nitpick style, mainly to make luacheck happy Only cover the widget types that were recently refactored. A few conventions are set as followed: * Textwidth is preferably 80, since the whole point of tiling windows is to be able to view more pane of codes * Standard, 3rd-party and local require should be grouped together * Closing parentheses should not be on lines by themselves There should be a style guide to clarify these. --- .luacheckrc | 10 ++++- Changes.md | 3 ++ helpers.lua | 37 +++++++++------- widgets/bat_freebsd.lua | 14 +++---- widgets/bat_openbsd.lua | 81 +++++++++++++++++------------------- widgets/cmus_all.lua | 6 ++- widgets/cpu_freebsd.lua | 9 ++-- widgets/cpufreq_freebsd.lua | 19 ++++++--- widgets/fanspeed_freebsd.lua | 3 +- widgets/mdir_all.lua | 2 +- widgets/mem_freebsd.lua | 64 ++++++++++++++-------------- widgets/mpd_all.lua | 19 +++++---- widgets/net_freebsd.lua | 14 ++++--- widgets/os_linux.lua | 8 ++-- widgets/thermal_freebsd.lua | 3 +- widgets/uptime_freebsd.lua | 28 +++++++------ widgets/wifiiw_linux.lua | 4 +- 17 files changed, 182 insertions(+), 142 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index 7aacbc1..6c05d07 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -3,7 +3,15 @@ std = "min" -- Global objects defined by the C code read_globals = { - "timer", -- deprecated, but used in older versions. + "timer", -- deprecated, but used in older versions. } +-- Warnings to be ignored +ignore = { + "212", -- Unused argument. +} + +-- Not enforced, but preferable +max_code_line_length = 80 + -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/Changes.md b/Changes.md index 4873286..bc453fa 100644 --- a/Changes.md +++ b/Changes.md @@ -1,3 +1,5 @@ +# Changes in 2.4.0 (WIP) + IMPORTANT: - `volume` now uses ๐Ÿ”‰ and ๐Ÿ”ˆ instead of โ™ซ and โ™ฉ to show mute state. @@ -27,6 +29,7 @@ Fixed: - [pkg,weather,contrib/btc] Allow function call without Awesome - [pkg] Use more updated front-ends for Debian/Ubuntu (apt) and Fedora (dnf) - [os] Splitted os_all into os_linux and os_bsd (and refactored to async) +- Tweak `.luacheckrc` to suit functional style and soft-limit text width to 80 Removed: diff --git a/helpers.lua b/helpers.lua index 5fab4cf..c3d4a22 100644 --- a/helpers.lua +++ b/helpers.lua @@ -34,6 +34,12 @@ local spawn = require("vicious.spawn") -- vicious.helpers local helpers = {} +-- {{{ Constants definitions +local OS_UNSUPPORTED_ERR = "Vicious: platform not supported: %s" +local NOT_FOUND_MSG = "module '%s' not found" +local NOT_FOUND_ERR = [[ +Vicious: %s is not available for the current platform or does not exist]] +-- }}} -- {{{ Variable definitions local scroller = {} @@ -56,8 +62,8 @@ end -- }}} -- {{{ Loader of vicious modules -function helpers.wrequire(table, key) - local ret = rawget(table, key) +function helpers.wrequire(collection, key) + local ret = rawget(collection, key) if ret then return ret @@ -69,27 +75,26 @@ function helpers.wrequire(table, key) openbsd = { "openbsd", "bsd", "all" } } - local os = ostable[helpers.getos()] - assert(os, "Vicious: platform not supported: " .. helpers.getos()) + local platform = ostable[helpers.getos()] + assert(platform, OS_UNSUPPORTED_ERR:format(helpers.getos())) - for i = 1, #os do - local name = table._NAME .. "." .. key .. "_" .. os[i] + local basename = collection._NAME .. '.' .. key + for i = 1, #platform do + local name = basename .. '_' .. platform[i] local status, value = pcall(require, name) if status then ret = value break end - local not_found_msg = "module '"..name.."' not found" - -- ugly but there is afaik no other way to check if a module exists - if value:sub(1, #not_found_msg) ~= not_found_msg then - -- module found, but different issue -> let's raise the real error - require(name) + -- This is ugly but AFAWK there is no other way to check for + -- the type of error. If other error get caught, raise it. + if value:find(NOT_FOUND_MSG:format(name), 1, true) == nil then + require(name) end end - assert(ret, "Vicious: widget " .. table._NAME .. "." .. key .. " not available for current platform or does not exist") - + assert(ret, NOT_FOUND_ERR:format(basename)) return ret end -- }}} @@ -110,8 +115,8 @@ end -- {{{ Expose path as a Lua table function helpers.pathtotable(dir) return setmetatable({ _path = dir }, - { __index = function(table, index) - local path = table._path .. '/' .. index + { __index = function(self, index) + local path = self._path .. '/' .. index local f = io.open(path) if f then local s = f:read("*all") @@ -120,7 +125,7 @@ function helpers.pathtotable(dir) return s else local o = { _path = path } - setmetatable(o, getmetatable(table)) + setmetatable(o, getmetatable(self)) return o end end diff --git a/widgets/bat_freebsd.lua b/widgets/bat_freebsd.lua index f2cf8eb..c6e743c 100644 --- a/widgets/bat_freebsd.lua +++ b/widgets/bat_freebsd.lua @@ -1,13 +1,13 @@ -- {{{ Grab environment local tonumber = tonumber local math = { floor = math.floor } -local helpers = require("vicious.helpers") -local spawn = require("vicious.spawn") local string = { gmatch = string.gmatch, - match = string.match, format = string.format } + +local helpers = require("vicious.helpers") +local spawn = require("vicious.spawn") -- }}} -- Battery: provides battery level of requested battery @@ -36,7 +36,7 @@ local function parse(stdout, stderr, exitreason, exitcode) local state = battery_state[bat_info["State"]] or "N/A" -- battery capacity in percent - local percent = tonumber(string.match(bat_info["Remaining capacity"], "[%d]+")) + local percent = tonumber(bat_info["Remaining capacity"]:match"[%d]+") -- use remaining (charging or discharging) time calculated by acpiconf local time = bat_info["Remaining time"] @@ -47,13 +47,13 @@ local function parse(stdout, stderr, exitreason, exitcode) -- calculate wear level from (last full / design) capacity local wear = "N/A" if bat_info["Last full capacity"] and bat_info["Design capacity"] then - local l_full = tonumber(string.match(bat_info["Last full capacity"], "[%d]+")) - local design = tonumber(string.match(bat_info["Design capacity"], "[%d]+")) + local l_full = tonumber(bat_info["Last full capacity"]:match"[%d]+") + local design = tonumber(bat_info["Design capacity"]:match"[%d]+") wear = math.floor(l_full / design * 100) end -- dis-/charging rate as presented by battery - local rate = string.match(bat_info["Present rate"], "([%d]+)%smW") + local rate = bat_info["Present rate"]:match"([%d]+)%smW" rate = string.format("%2.1f", tonumber(rate / 1000)) -- returns diff --git a/widgets/bat_openbsd.lua b/widgets/bat_openbsd.lua index ced83d8..6718b9b 100644 --- a/widgets/bat_openbsd.lua +++ b/widgets/bat_openbsd.lua @@ -34,52 +34,49 @@ local STATES = { [0] = "โ†ฏ", -- not charging return helpers.setasyncall{ async = function (format, warg, callback) - local filter = "hw.sensors.acpi" .. (warg or "bat0") - local pattern = filter .. ".(%S+)=(%S+)" - local bat_info = {} + if warg == nil then warg = 'bat0' end + local pattern = ("hw.sensors.acpi%s.(%S+)=(%S+)"):format(warg) - spawn.with_line_callback_with_shell( - ("sysctl -a | grep '^%s'"):format(filter), - { stdout = function (line) - for key, value in line:gmatch(pattern) do - bat_info[key] = value - end - end, - output_done = function () - -- current state - local state = STATES[tonumber(bat_info.raw0)] + spawn.async( + "sysctl -a", + function (stdout, stderr, exitreason, exitcode) + local bat_info = {} + for key, value in stdout:gmatch(pattern) do + bat_info[key] = value + end - -- battery capacity in percent - local percent = tonumber( - bat_info.watthour3 / bat_info.watthour0 * 100) + -- current state + local state = STATES[tonumber(bat_info.raw0)] - local time - if tonumber(bat_info.power0) < 1 then - time = "โˆž" - else - local raw_time = bat_info.watthour3 / bat_info.power0 - local hours, hour_fraction = math.modf(raw_time) - local minutes = math.floor(60 * hour_fraction) - time = ("%d:%0.2d"):format(hours, minutes) - end + -- battery capacity in percent + local percent = tonumber( + bat_info.watthour3 / bat_info.watthour0 * 100) - -- calculate wear level from (last full / design) capacity - local wear = "N/A" - if bat_info.watthour0 and bat_info.watthour4 then - local l_full = tonumber(bat_info.watthour0) - local design = tonumber(bat_info.watthour4) - wear = math.floor(l_full / design * 100) - end + local time = "โˆž" + if tonumber(bat_info.power0) >= 1 then + local raw_time = bat_info.watthour3 / bat_info.power0 + local hours, hour_fraction = math.modf(raw_time) + local minutes = math.floor(60 * hour_fraction) + time = ("%d:%0.2d"):format(hours, minutes) + end - -- dis-/charging rate as presented by battery - local rate = bat_info.power0 + -- calculate wear level from (last full / design) capacity + local wear = "N/A" + if bat_info.watthour0 and bat_info.watthour4 then + local l_full = tonumber(bat_info.watthour0) + local design = tonumber(bat_info.watthour4) + wear = math.floor(l_full / design * 100) + end - -- Pass the following arguments to callback function: - -- * battery state symbol (โ†ฏ, -, !, + or N/A) - -- * remaining_capacity (in percent) - -- * remaining_time, by battery - -- * wear level (in percent) - -- * present_rate (in Watts) - callback{state, percent, time, wear, rate} - end }) + -- dis-/charging rate as presented by battery + local rate = bat_info.power0 + + -- Pass the following arguments to callback function: + -- * battery state symbol (โ†ฏ, -, !, + or N/A) + -- * remaining_capacity (in percent) + -- * remaining_time, by battery + -- * wear level (in percent) + -- * present_rate (in Watts) + callback{state, percent, time, wear, rate} + end) end } diff --git a/widgets/cmus_all.lua b/widgets/cmus_all.lua index 04581bf..25c1a9a 100644 --- a/widgets/cmus_all.lua +++ b/widgets/cmus_all.lua @@ -12,6 +12,8 @@ local helpers = require"vicious.helpers" local spawn = require"vicious.spawn" -- }}} +local CMUS_SOCKET = helpers.shellquote(os.getenv"CMUS_SOCKET") + -- Cmus: provides CMUS information -- vicious.widgets.cmus return helpers.setasyncall{ @@ -19,8 +21,8 @@ return helpers.setasyncall{ local server = "" if type(warg) == "table" then server = " --server " .. helpers.shellquote(warg.host or warg[1]) - elseif CMUS_SOCKET then - server = " --server " .. helpers.shellquote(os.getenv"CMUS_SOCKET") + elseif CMUS_SOCKET ~= nil then + server = " --server " .. CMUS_SOCKET end local cmus_state = { ["{duration}"] = 0, ["{file}"] = "N/A", diff --git a/widgets/cpu_freebsd.lua b/widgets/cpu_freebsd.lua index c6e5272..972eca0 100644 --- a/widgets/cpu_freebsd.lua +++ b/widgets/cpu_freebsd.lua @@ -1,7 +1,8 @@ -- {{{ Grab environment -local helpers = require("vicious.helpers") local math = { floor = math.floor } local string = { gmatch = string.gmatch } + +local helpers = require("vicious.helpers") -- }}} @@ -39,7 +40,7 @@ function cpu_freebsd.async(format, warg, callback) tmp_usage[i] = 0 end - -- CPU usage + -- CPU usage for i, v in ipairs(matches) do local index = math.floor((i-1) / 5) + 2 -- current cpu @@ -54,7 +55,9 @@ function cpu_freebsd.async(format, warg, callback) for i = 1, #tmp_usage do tmp_usage[i] = tmp_total[i] - cpu_total[i] - tmp_usage[i] = math.floor((tmp_usage[i] - (tmp_idle[i] - cpu_idle[i])) / tmp_usage[i] * 100) + tmp_usage[i] = math.floor( + (tmp_usage[i] - (tmp_idle[i] - cpu_idle[i])) + / tmp_usage[i] * 100) end cpu_total = tmp_total diff --git a/widgets/cpufreq_freebsd.lua b/widgets/cpufreq_freebsd.lua index c53e2d7..6acf2f0 100644 --- a/widgets/cpufreq_freebsd.lua +++ b/widgets/cpufreq_freebsd.lua @@ -20,13 +20,20 @@ function cpufreq_freebsd.async(format, warg, callback) ["governor"] = "N/A", } - helpers.sysctl_async({ "dev.cpu." .. warg .. ".freq" }, function(ret) - freqv.mhz = tonumber(ret["dev.cpu." .. warg .. ".freq"]) - freqv.ghz = freqv.mhz / 1000 - - return callback({freqv.mhz, freqv.ghz, freqv.mv, freqv.v, freqv.governor}) - end) + helpers.sysctl_async( + { "dev.cpu." .. warg .. ".freq" }, + function (ret) + freqv.mhz = tonumber(ret["dev.cpu." .. warg .. ".freq"]) + freqv.ghz = freqv.mhz / 1000 + return callback({ + freqv.mhz, + freqv.ghz, + freqv.mv, + freqv.v, + freqv.governor + }) + end) end -- }}} diff --git a/widgets/fanspeed_freebsd.lua b/widgets/fanspeed_freebsd.lua index e55a51f..a60b272 100644 --- a/widgets/fanspeed_freebsd.lua +++ b/widgets/fanspeed_freebsd.lua @@ -1,7 +1,8 @@ -- {{{ Grab environment -local helpers = require("vicious.helpers") local tonumber = tonumber local type = type + +local helpers = require("vicious.helpers") -- }}} diff --git a/widgets/mdir_all.lua b/widgets/mdir_all.lua index 184f41e..7853d54 100644 --- a/widgets/mdir_all.lua +++ b/widgets/mdir_all.lua @@ -21,7 +21,7 @@ local mdir_all = {} function mdir_all.async(format, warg, callback) if type(warg) ~= "table" then return callback{} end local starting_points = "" - for i,dir in ipairs(warg) do + for _,dir in ipairs(warg) do starting_points = starting_points .. " " .. helpers.shellquote(dir) end if starting_points == "" then return callback{ 0, 0 } end diff --git a/widgets/mem_freebsd.lua b/widgets/mem_freebsd.lua index ebc4484..369039e 100644 --- a/widgets/mem_freebsd.lua +++ b/widgets/mem_freebsd.lua @@ -1,13 +1,14 @@ -- {{{ Grab environment local tonumber = tonumber local math = { floor = math.floor } -local helpers = require("vicious.helpers") -local spawn = require("vicious.spawn") -local string = { +local string = { match = string.match, gmatch = string.gmatch, find = string.find } + +local helpers = require("vicious.helpers") +local spawn = require("vicious.spawn") -- }}} -- Mem: provides RAM and Swap usage statistics @@ -17,21 +18,21 @@ local mem_freebsd = {} -- {{{ Memory widget type function mem_freebsd.async(format, warg, callback) - helpers.sysctl_async({ "hw.pagesize", + helpers.sysctl_async({ "hw.pagesize", "vm.stats.vm", "vm.swap_total", "vm.swap_enabled" }, function(ret) - local pagesize = tonumber(ret["hw.pagesize"]) + local pgsz = tonumber(ret["hw.pagesize"]) local _mem = { buf = {}, total = nil } -- Get memory space in bytes - _mem.total = tonumber(ret["vm.stats.vm.v_page_count"]) * pagesize - _mem.buf.free = tonumber(ret["vm.stats.vm.v_free_count"]) * pagesize - _mem.buf.laundry = tonumber(ret["vm.stats.vm.v_laundry_count"]) * pagesize - _mem.buf.cache = tonumber(ret["vm.stats.vm.v_cache_count"]) * pagesize - _mem.buf.wired = tonumber(ret["vm.stats.vm.v_wire_count"]) * pagesize + _mem.total = tonumber(ret["vm.stats.vm.v_page_count"]) * pgsz + _mem.buf.free = tonumber(ret["vm.stats.vm.v_free_count"]) * pgsz + _mem.buf.laundry = tonumber(ret["vm.stats.vm.v_laundry_count"]) * pgsz + _mem.buf.cache = tonumber(ret["vm.stats.vm.v_cache_count"]) * pgsz + _mem.buf.wired = tonumber(ret["vm.stats.vm.v_wire_count"]) * pgsz -- Rework into megabytes _mem.total = math.floor(_mem.total/1048576) @@ -68,46 +69,47 @@ function mem_freebsd.async(format, warg, callback) spawn.with_line_callback("swapinfo -m", { stdout = function(line) if not string.find(line, "Device") then - local ltotal, lused, lfree = string.match(line, "%s+([%d]+)%s+([%d]+)%s+([%d]+)") + local ltotal, lused, lfree = string.match( + line, "%s+([%d]+)%s+([%d]+)%s+([%d]+)") -- Add swap space in Mbytes _swp.total = _swp.total + tonumber(ltotal) _swp.inuse = _swp.inuse + tonumber(lused) _swp.buf.free = _swp.buf.free + tonumber(lfree) end end, - output_done = function() + output_done = function() print(_swp.inuse, _swp.total) _swp.usep = math.floor(_swp.inuse / _swp.total * 100) - callback({ _mem.usep, - _mem.inuse, - _mem.total, + callback({ _mem.usep, + _mem.inuse, + _mem.total, _mem.free, - _swp.usep, - _swp.inuse, - _swp.total, + _swp.usep, + _swp.inuse, + _swp.total, _swp.buf.free, - _mem.wirep, - _mem.wire, - _mem.notfreeablep, + _mem.wirep, + _mem.wire, + _mem.notfreeablep, _mem.notfreeable }) - end + end }) else _swp.usep = -1 _swp.inuse = -1 _swp.total = -1 _swp.buf.free = -1 - callback({ _mem.usep, - _mem.inuse, - _mem.total, + callback({ _mem.usep, + _mem.inuse, + _mem.total, _mem.free, - _swp.usep, - _swp.inuse, - _swp.total, + _swp.usep, + _swp.inuse, + _swp.total, _swp.buf.free, - _mem.wirep, - _mem.wire, - _mem.notfreeablep, + _mem.wirep, + _mem.wire, + _mem.notfreeablep, _mem.notfreeable }) end end) diff --git a/widgets/mpd_all.lua b/widgets/mpd_all.lua index e8a5afd..b54a1e2 100644 --- a/widgets/mpd_all.lua +++ b/widgets/mpd_all.lua @@ -7,6 +7,7 @@ local tonumber = tonumber local math = { floor = math.floor } local type = type + local helpers = require"vicious.helpers" local spawn = require"vicious.spawn" -- }}} @@ -24,7 +25,7 @@ end -- }}} -- {{{ Format playing progress -function format_progress(elapsed, duration) +local function format_progress(elapsed, duration) local em, es = math.floor(elapsed / 60), math.floor(elapsed % 60) local dm, ds = math.floor(duration / 60), math.floor(duration % 60) @@ -32,18 +33,22 @@ function format_progress(elapsed, duration) return ("%d:%02d"):format(em, es), ("%d:%02d"):format(dm, ds) elseif dm < 60 then return ("%02d:%02d"):format(em, es), ("%02d:%02d"):format(dm, ds) - elseif dm < 600 then - return ("%d:%02d:%02d"):format(math.floor(em / 60), math.floor(em % 60), es), - ("%d:%02d:%02d"):format(math.floor(dm / 60), math.floor(dm % 60), ds) + end + + local eh, dh = math.floor(em / 60), math.floor(dm / 60) + em, dm = math.floor(em % 60), math.floor(dm % 60) + if dm < 600 then + return ("%d:%02d:%02d"):format(eh, em, es), + ("%d:%02d:%02d"):format(dh, dm, ds) else - return ("%02d:%02d:%02d"):format(math.floor(em / 60), math.floor(em % 60), es), - ("%02d:%02d:%02d"):format(math.floor(dm / 60), math.floor(dm % 60), ds) + return ("%02d:%02d:%02d"):format(eh, em, es), + ("%02d:%02d:%02d"):format(dh, dm, ds) end end -- }}} -- {{{ Format playing progress (percentage) -function format_progress_percentage(elapsed, duration) +local function format_progress_percentage(elapsed, duration) if duration > 0 then local percentage = math.floor((elapsed / duration) * 100 + 0.5) return ("%d%%"):format(percentage) diff --git a/widgets/net_freebsd.lua b/widgets/net_freebsd.lua index 2aa1180..41a2eb7 100644 --- a/widgets/net_freebsd.lua +++ b/widgets/net_freebsd.lua @@ -1,12 +1,13 @@ -- {{{ Grab environment local tonumber = tonumber local os = { time = os.time } -local helpers = require("vicious.helpers") -local spawn = require("vicious.spawn") -local string = { +local string = { match = string.match, gmatch = string.gmatch } + +local helpers = require("vicious.helpers") +local spawn = require("vicious.spawn") -- }}} @@ -28,7 +29,7 @@ local function parse(stdout, stderr, exitreason, exitcode) local args = {} local buffer = nil local now = os.time() - + for line in string.gmatch(stdout, "[^\n]+") do if not (line:find(" Date: Sat, 24 Aug 2019 13:49:42 +0700 Subject: [PATCH 28/28] Revert bat_openbsd since the change is unnecessary --- widgets/bat_openbsd.lua | 81 +++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/widgets/bat_openbsd.lua b/widgets/bat_openbsd.lua index 6718b9b..ced83d8 100644 --- a/widgets/bat_openbsd.lua +++ b/widgets/bat_openbsd.lua @@ -34,49 +34,52 @@ local STATES = { [0] = "โ†ฏ", -- not charging return helpers.setasyncall{ async = function (format, warg, callback) - if warg == nil then warg = 'bat0' end - local pattern = ("hw.sensors.acpi%s.(%S+)=(%S+)"):format(warg) + local filter = "hw.sensors.acpi" .. (warg or "bat0") + local pattern = filter .. ".(%S+)=(%S+)" + local bat_info = {} - spawn.async( - "sysctl -a", - function (stdout, stderr, exitreason, exitcode) - local bat_info = {} - for key, value in stdout:gmatch(pattern) do - bat_info[key] = value - end + spawn.with_line_callback_with_shell( + ("sysctl -a | grep '^%s'"):format(filter), + { stdout = function (line) + for key, value in line:gmatch(pattern) do + bat_info[key] = value + end + end, + output_done = function () + -- current state + local state = STATES[tonumber(bat_info.raw0)] - -- current state - local state = STATES[tonumber(bat_info.raw0)] + -- battery capacity in percent + local percent = tonumber( + bat_info.watthour3 / bat_info.watthour0 * 100) - -- battery capacity in percent - local percent = tonumber( - bat_info.watthour3 / bat_info.watthour0 * 100) + local time + if tonumber(bat_info.power0) < 1 then + time = "โˆž" + else + local raw_time = bat_info.watthour3 / bat_info.power0 + local hours, hour_fraction = math.modf(raw_time) + local minutes = math.floor(60 * hour_fraction) + time = ("%d:%0.2d"):format(hours, minutes) + end - local time = "โˆž" - if tonumber(bat_info.power0) >= 1 then - local raw_time = bat_info.watthour3 / bat_info.power0 - local hours, hour_fraction = math.modf(raw_time) - local minutes = math.floor(60 * hour_fraction) - time = ("%d:%0.2d"):format(hours, minutes) - end + -- calculate wear level from (last full / design) capacity + local wear = "N/A" + if bat_info.watthour0 and bat_info.watthour4 then + local l_full = tonumber(bat_info.watthour0) + local design = tonumber(bat_info.watthour4) + wear = math.floor(l_full / design * 100) + end - -- calculate wear level from (last full / design) capacity - local wear = "N/A" - if bat_info.watthour0 and bat_info.watthour4 then - local l_full = tonumber(bat_info.watthour0) - local design = tonumber(bat_info.watthour4) - wear = math.floor(l_full / design * 100) - end + -- dis-/charging rate as presented by battery + local rate = bat_info.power0 - -- dis-/charging rate as presented by battery - local rate = bat_info.power0 - - -- Pass the following arguments to callback function: - -- * battery state symbol (โ†ฏ, -, !, + or N/A) - -- * remaining_capacity (in percent) - -- * remaining_time, by battery - -- * wear level (in percent) - -- * present_rate (in Watts) - callback{state, percent, time, wear, rate} - end) + -- Pass the following arguments to callback function: + -- * battery state symbol (โ†ฏ, -, !, + or N/A) + -- * remaining_capacity (in percent) + -- * remaining_time, by battery + -- * wear level (in percent) + -- * present_rate (in Watts) + callback{state, percent, time, wear, rate} + end }) end }