[{wifi,wifiiw}_linux] Deprecate io.popen

This commit is contained in:
Nguyễn Gia Phong 2019-05-29 21:45:28 +07:00
parent 7ae6a84b52
commit 62e9a757df
4 changed files with 84 additions and 123 deletions

View File

@ -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)

View File

@ -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)
## <a name="custom-widget"></a>Custom widget types

View File

@ -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)

View File

@ -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)