]> git.madduck.net Git - etc/awesome.git/commitdiff

madduck's git repository

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

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

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

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

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

Merge pull request #57 from axujen/centerwork-master-fix
authorLuke Bonham <copycat-killer@users.noreply.github.com>
Fri, 8 Aug 2014 11:30:47 +0000 (13:30 +0200)
committerLuke Bonham <copycat-killer@users.noreply.github.com>
Fri, 8 Aug 2014 11:30:47 +0000 (13:30 +0200)
layout.centerwork: Use the first client (master) as the central window.

14 files changed:
asyncshell.lua [new file with mode: 0644]
widgets/alsa.lua
widgets/alsabar.lua
widgets/base.lua
widgets/calendar.lua
widgets/cpu.lua
widgets/fs.lua
widgets/imap.lua
widgets/maildir.lua
widgets/mpd.lua
widgets/net.lua
widgets/sysload.lua
widgets/temp.lua
widgets/yawn/init.lua

diff --git a/asyncshell.lua b/asyncshell.lua
new file mode 100644 (file)
index 0000000..51885e8
--- /dev/null
@@ -0,0 +1,82 @@
+
+--[[
+                                                  
+     Licensed under GNU General Public License v2 
+      * (c) 2013, Alexander Yakushev              
+                                                  
+--]]
+
+-- Asynchronous io.popen for Awesome WM.
+-- How to use...
+-- ...asynchronously:
+-- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end)
+-- ...synchronously
+-- wwidget.text = asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error"
+
+-- This makes things faster, but puts weight on sysload and is more cpu demanding.
+
+local spawn = require('awful.util').spawn
+
+asyncshell               = {}
+asyncshell.request_table = {}
+asyncshell.id_counter    = 0
+asyncshell.folder        = "/tmp/asyncshell"
+asyncshell.file_template = asyncshell.folder .. '/req'
+
+-- Create a directory for asynchell response files
+os.execute("mkdir -p " .. asyncshell.folder)
+
+-- Returns next tag - unique identifier of the request
+local function next_id()
+   asyncshell.id_counter = (asyncshell.id_counter + 1) % 100000
+   return asyncshell.id_counter
+end
+
+-- Sends an asynchronous request for an output of the shell command.
+-- @param command Command to be executed and taken output from
+-- @param callback Function to be called when the command finishes
+-- @return Request ID
+function asyncshell.request(command, callback)
+   local id = next_id()
+   local tmpfname = asyncshell.file_template .. id
+   asyncshell.request_table[id] = {callback = callback}
+   local req =
+      string.format("sh -c '%s > %s; " ..
+                    'echo "asyncshell.deliver(%s)" | ' ..
+                    "awesome-client' 2> /dev/null",
+                    string.gsub(command, "'", "'\\''"), tmpfname,
+                    id, tmpfname)
+   spawn(req, false)
+   return id
+end
+
+-- Calls the remembered callback function on the output of the shell
+-- command.
+-- @param id Request ID
+-- @param output The output file of the shell command to be delievered
+function asyncshell.deliver(id)
+   if asyncshell.request_table[id] and
+      asyncshell.request_table[id].callback then
+      local output = io.open(asyncshell.file_template .. id, 'r')
+      asyncshell.request_table[id].callback(output)
+   end
+end
+
+-- Sends a synchronous request for an output of the command. Waits for
+-- the output, but if the given timeout expires returns nil.
+-- @param command Command to be executed and taken output from
+-- @param timeout Maximum amount of time to wait for the result
+-- @return File handler on success, nil otherwise
+function asyncshell.demand(command, timeout)
+   local id = next_id()
+   local tmpfname = asyncshell.file_template .. id
+   local f = io.popen(string.format("(%s > %s; echo asyncshell_done) & " ..
+                                    "(sleep %s; echo asynchell_timeout)",
+                                    command, tmpfname, timeout))
+   local result = f:read("*line")
+   if result == "asyncshell_done" then
+      return io.open(tmpfname)
+   end
+end
+
+return asyncshell
index 4ed4f9c2b1bbc99cdd71b54539a890418acc887d..f62a150d18fcd7969accaeb53118841117d05107 100644 (file)
@@ -30,7 +30,7 @@ local function worker(args)
 
     function alsa.update()
         local f = assert(io.popen('amixer -M get ' .. channel))
-        local mixer = f:read("*all")
+        local mixer = f:read("*a")
         f:close()
 
         volume_now = {}
index e185c761290d3b700f39710cc7b1340acf314bf1..8675cb52bb2542978a584ab9e18b4b1b848505b5 100644 (file)
@@ -116,7 +116,7 @@ local function worker(args)
     function alsabar.update()
         -- Get mixer control contents
         local f = io.popen("amixer -M get " .. alsabar.channel)
-        local mixer = f:read("*all")
+        local mixer = f:read("*a")
         f:close()
 
         -- Capture mixer control state:          [5%] ... ... [on]
index 4f28e07bae46777f6733df0257463e6a80a727ff..6b808b7fc066d27b8fc607ab213deb2b22bee7a8 100644 (file)
@@ -26,7 +26,7 @@ local function worker(args)
 
     function base.update()
         local f = assert(io.popen(cmd))
-        output = f:read("*all")
+        output = f:read("*a")
         f:close()
         widget = base.widget
         settings()
index 4e6eda764447ec15408d4ebe1d1277d7be2e6e56..c690e3f4893cdd436755986f4a2d6e5a045b506b 100644 (file)
@@ -88,7 +88,7 @@ function calendar:show(t_out, inc_offset)
              .. calendar.font_size .. "'><b>"
              .. f:read() .. "</b>\n\n"
              .. f:read() .. "\n"
-             .. f:read("*all"):gsub("\n*$", "")
+             .. f:read("*a"):gsub("\n*$", "")
              .. "</span></tt>"
     f:close()
 
index 7c1ecb032b3f613f30423fcb467219e7bc6bf9da..96e0d3b3a38315496c32e9cc628377bc25435786 100644 (file)
@@ -58,7 +58,7 @@ local function worker(args)
         local dactive = active - cpu.last_active
         local dtotal = total - cpu.last_total
 
-        cpu_now = {}
+        cpu_noj = {}
         cpu_now.usage = tostring(math.ceil((dactive / dtotal) * 100))
 
         widget = cpu.widget
index 867ce3f3c4ac9117210a070565db98d557269a36..8127c287c39dedb2173af0c1cf53272bf3a45c30 100644 (file)
@@ -40,7 +40,7 @@ function fs:show(t_out)
     fs:hide()
 
     local f = io.popen(helpers.scripts_dir .. "dfs")
-    ws = f:read("*all"):gsub("\n*$", "")
+    ws = f:read("*a"):gsub("\n*$", "")
     f:close()
 
     notification = naughty.notify({
index c4040323f3d897412bc28e800b9d4d288bd6324f..1dca87cddfc856c8350243e1fbbabcc741b50233 100644 (file)
@@ -7,11 +7,11 @@
 --]]
 
 local helpers      = require("lain.helpers")
+local async        = require("lain.asyncshell")
 
 local naughty      = require("naughty")
 local wibox        = require("wibox")
 
-local io           = { popen  = io.popen }
 local string       = { format = string.format,
                        gsub   = string.gsub }
 local tonumber     = tonumber
@@ -42,7 +42,7 @@ local function worker(args)
     if not is_plain
     then
         local f = io.popen(password)
-        password = f:read("*all"):gsub("\n", "")
+        password = f:read("*a"):gsub("\n", "")
         f:close()
     end
 
@@ -57,34 +57,37 @@ local function worker(args)
         curl = string.format("%s --url imaps://%s:%s/INBOX -u %s:%s %s -k",
                head_command, server, port, mail, password, request)
 
-        f = io.popen(curl)
-        ws = f:read("*all")
-        f:close()
-
-        _, mailcount = string.gsub(ws, "%d+", "")
-        _ = nil
+        async.request(curl, function(f) 
+            ws = f:read("*a")
+            f:close()
+
+            _, mailcount = string.gsub(ws, "%d+", "")
+            _ = nil
+
+            widget = imap.widget
+            settings()
+
+            if mailcount >= 1 and mailcount > helpers.get_map(mail)
+            then
+                if mailcount == 1 then
+                    nt = mail .. " has one new message"
+                else
+                    nt = mail .. " has <b>" .. mailcount .. "</b> new messages"
+                end
+                naughty.notify({
+                    preset = mail_notification_preset,
+                    text = nt,
+                    screen = client.focus and client.focus.screen or 1
+                })
+            end
 
-        widget = imap.widget
-        settings()
+            helpers.set_map(mail, mailcount)
+        end)
 
-        if mailcount >= 1 and mailcount > helpers.get_map(mail)
-        then
-            if mailcount == 1 then
-                nt = mail .. " has one new message"
-            else
-                nt = mail .. " has <b>" .. mailcount .. "</b> new messages"
-            end
-            naughty.notify({
-                preset = mail_notification_preset,
-                text = nt,
-                screen = client.focus and client.focus.screen or 1
-            })
-        end
-
-        helpers.set_map(mail, mailcount)
     end
 
     helpers.newtimer(mail, timeout, update, true)
+
     return setmetatable(imap, { __index = imap.widget })
 end
 
index 8fe097ece1c991cca0e16afb319a7909683cd13a..bd792210530346d92ae92de247ee6310ab817bff 100644 (file)
@@ -53,7 +53,7 @@ local function worker(args)
                 local np = io.popen("find " .. line ..
                                     "/new -mindepth 1 -type f " ..
                                     "-not -name '.*' -printf a")
-                local mailstring = np:read("*all")
+                local mailstring = np:read("*a")
 
                 -- Strip off leading mailpath.
                 local box = string.match(line, mailpath .. "/*([^/]+)")
index 73efebb48b3423b164a98bf0b73a1241fa2fa7bd..385b5bb8cd469ba9976be28c6f2dcca9ae29218b 100644 (file)
@@ -8,6 +8,7 @@
 --]]
 
 local helpers      = require("lain.helpers")
+local async        = require("lain.asyncshell")
 
 local escape_f     = require("awful.util").escape
 local naughty      = require("naughty")
@@ -50,56 +51,54 @@ local function worker(args)
     helpers.set_map("current mpd track", nil)
 
     function mpd.update()
-        mpd_now = {
-            state  = "N/A",
-            file   = "N/A",
-            artist = "N/A",
-            title  = "N/A",
-            album  = "N/A",
-            date   = "N/A"
-        }
-
-        local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh)
-
-        for line in f:lines() do
-            for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
-                if     k == "state"  then mpd_now.state  = v
-                elseif k == "file"   then mpd_now.file   = v
-                elseif k == "Artist" then mpd_now.artist = escape_f(v)
-                elseif k == "Title"  then mpd_now.title  = escape_f(v)
-                elseif k == "Album"  then mpd_now.album  = escape_f(v)
-                elseif k == "Date"   then mpd_now.date   = escape_f(v)
+        async.request(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh, function (f)
+            mpd_now = {
+                state  = "N/A",
+                file   = "N/A",
+                artist = "N/A",
+                title  = "N/A",
+                album  = "N/A",
+                date   = "N/A"
+            }
+
+            for line in f:lines() do
+                for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
+                    if     k == "state"  then mpd_now.state  = v
+                    elseif k == "file"   then mpd_now.file   = v
+                    elseif k == "Artist" then mpd_now.artist = escape_f(v)
+                    elseif k == "Title"  then mpd_now.title  = escape_f(v)
+                    elseif k == "Album"  then mpd_now.album  = escape_f(v)
+                    elseif k == "Date"   then mpd_now.date   = escape_f(v)
+                    end
                 end
             end
-        end
 
-        f:close()
+            mpd_notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist,
+                                           mpd_now.album, mpd_now.date, mpd_now.title)
+            widget = mpd.widget
+            settings()
 
-        mpd_notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist,
-                                       mpd_now.album, mpd_now.date, mpd_now.title)
-        widget = mpd.widget
-        settings()
-
-        if mpd_now.state == "play"
-        then
-            if mpd_now.title ~= helpers.get_map("current mpd track")
+            if mpd_now.state == "play"
             then
-                helpers.set_map("current mpd track", mpd_now.title)
-
-                os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir,
-                           mpd_now.file, cover_size, default_art))
-
-                mpd.id = naughty.notify({
-                    preset = mpd_notification_preset,
-                    icon = "/tmp/mpdcover.png",
-                    replaces_id = mpd.id,
-                    screen = client.focus and client.focus.screen or 1
-                }).id
+                if mpd_now.title ~= helpers.get_map("current mpd track")
+                then
+                    helpers.set_map("current mpd track", mpd_now.title)
+
+                    os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir,
+                               mpd_now.file, cover_size, default_art))
+
+                    mpd.id = naughty.notify({
+                        preset = mpd_notification_preset,
+                        icon = "/tmp/mpdcover.png",
+                        replaces_id = mpd.id,
+                        screen = client.focus and client.focus.screen or 1
+                    }).id
+                end
+            elseif mpd_now.state ~= "pause"
+            then
+                helpers.set_map("current mpd track", nil)
             end
-        elseif mpd_now.state ~= "pause"
-        then
-            helpers.set_map("current mpd track", nil)
-             end
+        end)
     end
 
     helpers.newtimer("mpd", timeout, mpd.update)
index 1e597319ceaddb68925992ff330e427b73bd36dd..7851d5a710da02ff8980523f6c3e97ef57db508b 100644 (file)
@@ -29,7 +29,7 @@ local net = {
 
 function net.get_device()
     f = io.popen("ip link show | cut -d' ' -f2,9")
-    ws = f:read("*all")
+    ws = f:read("*a")
     f:close()
     ws = ws:match("%w+: UP")
     if ws ~= nil then
index 2abac33a0c2ab62d8c1aed838df1a903758ac58a..b15b1bf8d80f848f8223dc2e7df292cd8c137a48 100644 (file)
@@ -30,7 +30,7 @@ local function worker(args)
 
     function update()
         local f = io.open("/proc/loadavg")
-        local ret = f:read("*all")
+        local ret = f:read("*a")
         f:close()
 
         load_1, load_5, load_15 = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)")
index 61a9aa5e6730ad2ab7bfdfe114a226039e89b8b1..4ae1c04ed574a4ffd64f7566155cd8cf22015f0a 100644 (file)
@@ -31,7 +31,7 @@ local function worker(args)
         local f = io.open(tempfile)
         if f ~= nil
         then
-            coretemp_now = tonumber(f:read("*all")) / 1000
+            coretemp_now = tonumber(f:read("*a")) / 1000
             f:close()
         else
             coretemp_now = "N/A"
index da2b856f033483329b9bccccb8bc1f6fd3c83674..033254e2cd3d6caf21854196d5a230ee6bcadd3d 100644 (file)
@@ -7,6 +7,7 @@
 --]]
 
 local newtimer     = require("lain.helpers").newtimer
+local async        = require("lain.asyncshell")
 
 local naughty      = require("naughty")
 local wibox        = require("wibox")
@@ -47,99 +48,102 @@ yawn_notification_preset = {}
 
 local function fetch_weather()
     local url = api_url .. units_set .. city_id
-    local f = io.popen("curl --connect-timeout 1 -fsm 3 '" .. url .. "'" )
-    local text = f:read("*all")
-    f:close()
+    local cmd = "curl --connect-timeout 1 -fsm 3 '" .. url .. "'"
 
-    -- In case of no connection or invalid city ID
-    -- widgets won't display
-    if text == "" or text:match("City not found")
-    then
-        yawn.icon:set_image(icon_path .. "na.png")
-        if text == "" then
-            weather_data = "Service not available at the moment."
-            yawn.widget:set_text(" N/A ")
-        else
-            weather_data = "City not found!\n" ..
-                           "Are you sure " .. city_id ..
-                           " is your Yahoo city ID?"
-            yawn.widget:set_text(" ? ")
+    async.request(cmd, function(f)
+        local text = f:read("*a")
+        f:close()
+
+        -- In case of no connection or invalid city ID
+        -- widgets won't display
+        if text == "" or text:match("City not found")
+        then
+            yawn.icon:set_image(icon_path .. "na.png")
+            if text == "" then
+                weather_data = "Service not available at the moment."
+                yawn.widget:set_text(" N/A ")
+            else
+                weather_data = "City not found!\n" ..
+                               "Are you sure " .. city_id ..
+                               " is your Yahoo city ID?"
+                yawn.widget:set_text(" ? ")
+            end
+            return
         end
-        return
-    end
 
-    -- Processing raw data
-    weather_data = text:gsub("<.->", "")
-    weather_data = weather_data:match("Current Conditions:.-Full") or ""
+        -- Processing raw data
+        weather_data = text:gsub("<.->", "")
+        weather_data = weather_data:match("Current Conditions:.-Full") or ""
 
-    -- may still happens in case of bad connectivity
-    if weather_data == "" then
-        yawn.icon:set_image(icon_path .. "na.png")
-        yawn.widget:set_text(" ? ")
-        return
-    end
+        -- may still happens in case of bad connectivity
+        if weather_data == "" then
+            yawn.icon:set_image(icon_path .. "na.png")
+            yawn.widget:set_text(" ? ")
+            return
+        end
 
-    weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ")
-    weather_data = weather_data:gsub("Forecast:.-\n", "")
-    weather_data = weather_data:gsub("\nFull", "")
-    weather_data = weather_data:gsub("[\n]$", "")
-    weather_data = weather_data:gsub(" [-] " , ": ")
-    weather_data = weather_data:gsub("[.]", ",")
-    weather_data = weather_data:gsub("High: ", "")
-    weather_data = weather_data:gsub(" Low: ", " - ")
-
-    -- Getting info for text widget
-    local now      = weather_data:sub(weather_data:find("Now:")+5,
-                     weather_data:find("\n")-1)
-    forecast       = now:sub(1, now:find(",")-1)
-    units          = now:sub(now:find(",")+2, -2)
-
-    -- Day/Night icon change
-    local hour = tonumber(os.date("%H"))
-    sky = icon_path
-
-    if forecast == "Clear"         or
-       forecast == "Fair"          or
-       forecast == "Partly Cloudy" or
-       forecast == "Mostly Cloudy"
-       then
-           if hour >= 6 and hour <= 18
+        weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ")
+        weather_data = weather_data:gsub("Forecast:.-\n", "")
+        weather_data = weather_data:gsub("\nFull", "")
+        weather_data = weather_data:gsub("[\n]$", "")
+        weather_data = weather_data:gsub(" [-] " , ": ")
+        weather_data = weather_data:gsub("[.]", ",")
+        weather_data = weather_data:gsub("High: ", "")
+        weather_data = weather_data:gsub(" Low: ", " - ")
+
+        -- Getting info for text widget
+        local now      = weather_data:sub(weather_data:find("Now:")+5,
+                         weather_data:find("\n")-1)
+        forecast       = now:sub(1, now:find(",")-1)
+        units          = now:sub(now:find(",")+2, -2)
+
+        -- Day/Night icon change
+        local hour = tonumber(os.date("%H"))
+        sky = icon_path
+
+        if forecast == "Clear"         or
+           forecast == "Fair"          or
+           forecast == "Partly Cloudy" or
+           forecast == "Mostly Cloudy"
            then
-               sky = sky .. "Day"
-           else
-               sky = sky .. "Night"
-           end
-    end
+               if hour >= 6 and hour <= 18
+               then
+                   sky = sky .. "Day"
+               else
+                   sky = sky .. "Night"
+               end
+        end
 
-    sky = sky  .. forecast:gsub(" ", ""):gsub("/", "") .. ".png"
+        sky = sky  .. forecast:gsub(" ", ""):gsub("/", "") .. ".png"
 
-    -- In case there's no defined icon for current forecast
-    if io.open(sky) == nil then
-        sky = icon_path .. "na.png"
-    end
+        -- In case there's no defined icon for current forecast
+        if io.open(sky) == nil then
+            sky = icon_path .. "na.png"
+        end
 
-    -- Localization
-    local f = io.open(localizations_path .. language, "r")
-    if language:find("en_") == nil and f ~= nil
-    then
-        f:close()
-        for line in io.lines(localizations_path .. language)
-        do
-            word = string.sub(line, 1, line:find("|")-1)
-            translation = string.sub(line, line:find("|")+1)
-            weather_data = string.gsub(weather_data, word, translation)
+        -- Localization
+        local f = io.open(localizations_path .. language, "r")
+        if language:find("en_") == nil and f ~= nil
+        then
+            f:close()
+            for line in io.lines(localizations_path .. language)
+            do
+                word = string.sub(line, 1, line:find("|")-1)
+                translation = string.sub(line, line:find("|")+1)
+                weather_data = string.gsub(weather_data, word, translation)
+            end
         end
-    end
 
-    -- Finally setting infos
-    yawn.icon:set_image(sky)
-    widget = yawn.widget
+        -- Finally setting infos
+        yawn.icon:set_image(sky)
+        widget = yawn.widget
 
-    _data = weather_data:match(": %S.-,") or weather_data
-    forecast = _data:gsub(": ", ""):gsub(",", "")
-    units = units:gsub(" ", "")
+        _data = weather_data:match(": %S.-,") or weather_data
+        forecast = _data:gsub(": ", ""):gsub(",", "")
+        units = units:gsub(" ", "")
 
-    settings()
+        settings()
+    end)
 end
 
 function yawn.hide()