X-Git-Url: https://git.madduck.net/etc/awesome.git/blobdiff_plain/8d37b9a1e4521a220f20ce2e1414f656aa3a5015..466c48d20a13a447afaec373b700a5cd2e3fa877:/widgets/mpd.lua

diff --git a/widgets/mpd.lua b/widgets/mpd.lua
index 8ba1cde..1972050 100644
--- a/widgets/mpd.lua
+++ b/widgets/mpd.lua
@@ -8,105 +8,121 @@
 --]]
 
 local helpers      = require("lain.helpers")
+local async        = require("lain.asyncshell")
 
-local util         = require("awful.util")
-local beautiful    = require("beautiful")
+local escape_f     = require("awful.util").escape
 local naughty      = require("naughty")
 local wibox        = require("wibox")
 
-local io           = io
 local os           = { execute  = os.execute,
                        getenv   = os.getenv }
-local string       = { gmatch   = string.gmatch }
+local math         = { floor    = math.floor }
+local mouse        = mouse
+local string       = { format   = string.format,
+                       match    = string.match,
+                       gmatch   = string.gmatch }
 
 local setmetatable = setmetatable
 
 -- MPD infos
 -- lain.widgets.mpd
-local mpd = { id = nil }
-
-function worker(args)
-    local args      = args or {}
-    local timeout   = args.timeout or 1
-    local password  = args.password or ""
-    local host      = args.host or "127.0.0.1"
-    local port      = args.port or "6600"
-    local music_dir = args.music_dir or os.getenv("HOME") .. "/Music"
-    local settings  = args.settings or function() end
+local mpd = {}
+
+local function worker(args)
+    local args        = args or {}
+    local timeout     = args.timeout or 2
+    local password    = args.password or ""
+    local host        = args.host or "127.0.0.1"
+    local port        = args.port or "6600"
+    local music_dir   = args.music_dir or os.getenv("HOME") .. "/Music"
+    local cover_size  = args.cover_size or 100
+    local default_art = args.default_art or ""
+    local followmouse = args.followmouse or false
+    local echo_cmd    = args.echo_cmd or "echo"
+    local settings    = args.settings or function() end
 
     local mpdcover = helpers.scripts_dir .. "mpdcover"
     local mpdh = "telnet://" .. host .. ":" .. port
-    local echo = "echo 'password " .. password .. "\nstatus\ncurrentsong\nclose'"
+    local echo = echo_cmd .. " 'password " .. password .. "\nstatus\ncurrentsong\nclose'"
+
+    mpd.widget = wibox.widget.textbox('')
 
-    widget = wibox.widget.textbox('')
+    mpd_notification_preset = {
+        title   = "Now playing",
+        timeout = 6
+    }
 
     helpers.set_map("current mpd track", nil)
 
-    function 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 = util.escape(v)
-                elseif k == "Title"  then mpd_now.title  = util.escape(v)
-                elseif k == "Album"  then mpd_now.album  = util.escape(v)
-                elseif k == "Date"   then mpd_now.date   = util.escape(v)
+    function mpd.update()
+        async.request(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh, function (f)
+            mpd_now = {
+                state   = "N/A",
+                file    = "N/A",
+                name    = "N/A",
+                artist  = "N/A",
+                title   = "N/A",
+                album   = "N/A",
+                date    = "N/A",
+                time    = "N/A",
+                elapsed = "N/A"
+            }
+
+            for line in string.gmatch(f, "[^\n]+") 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 == "Name"    then mpd_now.name    = escape_f(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)
+                    elseif k == "Time"    then mpd_now.time    = v
+                    elseif k == "elapsed" then mpd_now.elapsed = string.match(v, "%d+")
+                    end
                 end
             end
-        end
-
-        f:close()
-
-        notification_preset = {
-            title   = "Now playing",
-            text    = mpd_now.artist .. " ("   ..
-                      mpd_now.album  .. ") - " ..
-                      mpd_now.date   .. "\n"   ..
-                      mpd_now.title,
-            fg      = beautiful.fg_normal or "#FFFFFF",
-            bg      = beautiful.bg_normal or "#000000",
-            timeout = 6
-        }
-
-        settings()
-
-        if mpd_now.state == "play"
-        then
-            if mpd_now.title ~= helpers.get_map("current mpd track")
-            then
-                helpers.set_map("current mpd track", mpd_now.title)
 
-                os.execute(mpdcover .. " '" .. music_dir .. "' '"
-                           .. mpd_now.file .. "'")
+            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.id = naughty.notify({
-                    preset = notification_preset,
-                    icon = "/tmp/mpdcover.png",
-                    replaces_id = mpd.id
-                }).id
+            if mpd_now.state == "play"
+            then
+                if mpd_now.title ~= helpers.get_map("current mpd track")
+                then
+                    helpers.set_map("current mpd track", mpd_now.title)
+
+                    if string.match(mpd_now.file, "http.*://") == nil
+                    then -- local file
+                        os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir,
+                                   mpd_now.file, cover_size, default_art))
+                        current_icon = "/tmp/mpdcover.png"
+                    else -- http stream
+                        current_icon = default_art
+                    end
+
+                    if followmouse then
+                        mpd_notification_preset.screen = mouse.screen
+                    end
+
+                    mpd.id = naughty.notify({
+                        preset = mpd_notification_preset,
+                        icon = current_icon,
+                        replaces_id = mpd.id,
+                    }).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, update)
-
-    output = { widget = widget, notify = update }
+    helpers.newtimer("mpd", timeout, mpd.update)
 
-    return setmetatable(output, { __index = output.widget })
+    return setmetatable(mpd, { __index = mpd.widget })
 end
 
 return setmetatable(mpd, { __call = function(_, ...) return worker(...) end })