Allow asynchronous call (for Awesome4+) (#32)

This commit is contained in:
getzze 2017-07-13 21:42:26 +01:00 committed by Jörg Thalheim
parent fe10ee8201
commit 983253a27f
3 changed files with 73 additions and 38 deletions

View File

@ -395,9 +395,11 @@ Supported platforms: platform independent.
- Arguments:
* Takes the Linux or BSD distribution name as an argument, i.e. `"Arch"`,
`"FreeBSD"`
`"Arch C"`, `"Arch S"`, `"Debian"`, `"Ubuntu"`, `"Fedora"`, `"FreeBSD"`,
`"Mandriva"`
- Returns:
* Returns 1st value as the count of available updates
* Returns 1st value as the count of available updates, 2nd as the list of
packages to update
**vicious.widgets.raid**

View File

@ -49,38 +49,52 @@ local function update(widget, reg, disablecache)
local t = os.time()
local data = {}
-- Check for chached output newer than the last update
if widget_cache[reg.wtype] ~= nil then
local c = widget_cache[reg.wtype]
if (c.time == nil or c.time <= t-reg.timer) or disablecache then
c.time, c.data = t, reg.wtype(reg.format, reg.warg)
local function format_data(data)
local ret
if type(data) == "table" then
if type(reg.format) == "string" then
ret = helpers.format(reg.format, data)
elseif type(reg.format) == "function" then
ret = reg.format(widget, data)
end
end
data = c.data
else
data = reg.wtype and reg.wtype(reg.format, reg.warg)
return ret or data
end
if type(data) == "table" then
if type(reg.format) == "string" then
data = helpers.format(reg.format, data)
elseif type(reg.format) == "function" then
data = reg.format(widget, data)
local function update_value(data, t, cache)
if widget.add_value ~= nil then
widget:add_value(tonumber(data) and tonumber(data)/100)
elseif widget.set_value ~= nil then
widget:set_value(tonumber(data) and tonumber(data)/100)
elseif widget.set_markup ~= nil then
widget:set_markup(data)
else
widget.text = data
end
-- Update cache
if t and cache then
cache.time, cache.data = t, data
end
end
if widget.add_value ~= nil then
widget:add_value(tonumber(data) and tonumber(data)/100)
elseif widget.set_value ~= nil then
widget:set_value(tonumber(data) and tonumber(data)/100)
elseif widget.set_markup ~= nil then
widget:set_markup(data)
else
widget.text = data
-- Check for cached output newer than the last update
local c = widget_cache[reg.wtype]
if c and c.time and c.data and t < c.time+reg.timer and not disablecache then
return update_value(format_data(c.data))
elseif reg.wtype then
if reg.wtype.async then
if not reg.lock then
reg.lock = true
return reg.wtype.async(reg.warg,
function(data)
update_value(format_data(data), t, c)
reg.lock=false
end)
end
else
return update_value(format_data(reg.wtype(nil, reg.warg)), t, c)
end
end
return data
end
-- }}}
@ -147,6 +161,7 @@ function vicious.register(widget, wtype, format, timer, warg)
local reg = {
-- Set properties
wtype = wtype,
lock = false,
format = format,
timer = timer,
warg = warg,

View File

@ -7,6 +7,7 @@
local io = { popen = io.popen }
local math = { max = math.max }
local setmetatable = setmetatable
local spawn = require("awful.spawn")
-- }}}
@ -16,11 +17,10 @@ local pkg_all = {}
-- {{{ Packages widget type
local function worker(format, warg)
function pkg_all.async(warg, callback)
if not warg then return end
-- Initialize counters
local updates = 0
local manager = {
["Arch"] = { cmd = "pacman -Qu" },
["Arch C"] = { cmd = "checkupdates" },
@ -33,16 +33,34 @@ local function worker(format, warg)
}
-- Check if updates are available
local _pkg = manager[warg]
local f = io.popen(_pkg.cmd)
for line in f:lines() do
updates = updates + 1
local function parse(str, skiprows)
local size, lines, first = 0, "", skiprows or 0
for line in str:gmatch("[^\r\n]+") do
if size >= first then
lines = lines .. (size == first and "" or "\n") .. line
end
size = size + 1
end
size = math.max(size-first, 0)
return {size, lines}
end
f:close()
return {_pkg.sub and math.max(updates-_pkg.sub, 0) or updates}
-- Select command
local _pkg = manager[warg]
spawn.easy_async(_pkg.cmd, function(stdout) callback(parse(stdout, _pkg.sub)) end)
end
-- }}}
-- {{{ Packages widget type
local function worker(format, warg)
local ret = nil
pkg_all.async(warg, function(data) ret = data end)
while ret==nil do end
return ret
end
-- }}}
return setmetatable(pkg_all, { __call = function(_, ...) return worker(...) end })