From 983253a27f829f4fabd44e4b9843057fafc9949b Mon Sep 17 00:00:00 2001 From: getzze Date: Thu, 13 Jul 2017 21:42:26 +0100 Subject: [PATCH] Allow asynchronous call (for Awesome4+) (#32) --- README.md | 6 ++-- init.lua | 67 +++++++++++++++++++++++++++------------------ widgets/pkg_all.lua | 38 ++++++++++++++++++------- 3 files changed, 73 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 02350bb..985a2cc 100644 --- a/README.md +++ b/README.md @@ -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** diff --git a/init.lua b/init.lua index f236007..3751fa1 100644 --- a/init.lua +++ b/init.lua @@ -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, diff --git a/widgets/pkg_all.lua b/widgets/pkg_all.lua index 3899554..5a812e2 100644 --- a/widgets/pkg_all.lua +++ b/widgets/pkg_all.lua @@ -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 })