diff --git a/README.md b/README.md index b134f1b..59f9cde 100644 --- a/README.md +++ b/README.md @@ -335,8 +335,10 @@ Supported platforms: platform independent (required tools: `curl`). * Argument: an array including password, hostname and port in that order. `nil` fields will be fallen back to default (`localhost:6600` without password). -* Returns a table with string keys: `${volume}`, `${state}`, `${Artist}`, - `${Title}`, `${Album}`, `${Genre}` and optionally `${Name}` and `${file}`. +* Returns a table with string keys: `${volume}`, `${bitrate}`, `${elapsed}`, + `${duration}` (in seconds), `${Elapsed}`, `${Duration}` (in [hh:]mm:ss), + `${random}`, `${repeat}`, `${state}`, `${Artist}`, `${Title}`, `${Album}`, + `${Genre}` and optionally `${Name}` and `${file}`. ### vicious.widgets.net diff --git a/helpers.lua b/helpers.lua index d3ed859..4e0a072 100644 --- a/helpers.lua +++ b/helpers.lua @@ -136,6 +136,25 @@ function helpers.uformat(array, key, value, unit) end -- }}} +-- {{{ Format playing progress +function helpers.format_progress(elapsed, duration) + local em, es = elapsed / 60, elapsed % 60 + local dm, ds = duration / 60, duration % 60 + + if dm < 10 then + return ("%d:%02d"):format(em, es), ("%d:%02d"):format(dm, ds) + elseif dm < 60 then + return ("%02d:%02d"):format(em, es), ("%02d:%02d"):format(dm, ds) + elseif dm < 600 then + return ("%d:%02d:%02d"):format(em / 60, em % 60, es), + ("%d:%02d:%02d"):format(dm / 60, dm % 60, ds) + else + return ("%02d:%02d:%02d"):format(em / 60, em % 60, es), + ("%02d:%02d:%02d"):format(dm / 60, dm % 60, ds) + end +end +-- }}} + -- {{{ Escape a string function helpers.escape(text) local xml_entities = { diff --git a/widgets/mpd_all.lua b/widgets/mpd_all.lua index 47208e5..4eebe6e 100644 --- a/widgets/mpd_all.lua +++ b/widgets/mpd_all.lua @@ -17,39 +17,52 @@ local helpers = require("vicious.helpers") local mpd_all = {} +-- {{{ Return true if number is nonzero +local function cbool(number) + return type(number) == "number" and number ~= 0 or number +end +-- }}} + + -- {{{ MPD widget type local function worker(format, warg) - local mpd_state = { - ["{volume}"] = 0, - ["{state}"] = "N/A", - ["{Artist}"] = "N/A", - ["{Title}"] = "N/A", - ["{Album}"] = "N/A", - ["{Genre}"] = "N/A", - --["{Name}"] = "N/A", - --["{file}"] = "N/A", + -- Fallback values + local mpd_state = { + ["{volume}"] = 0, + ["{bitrate}"] = 0, + ["{elapsed}"] = 0, + ["{duration}"] = 0, + ["{repeat}"] = false, + ["{random}"] = false, + ["{state}"] = "N/A", + ["{Artist}"] = "N/A", + ["{Title}"] = "N/A", + ["{Album}"] = "N/A", + ["{Genre}"] = "N/A", + --["{Name}"] = "N/A", + --["{file}"] = "N/A", } - -- Fallback to MPD defaults - local pass = warg and (warg.password or warg[1]) or "\"\"" - local host = warg and (warg.host or warg[2]) or "127.0.0.1" - local port = warg and (warg.port or warg[3]) or "6600" - - -- Construct MPD client options - local mpdh = "telnet://"..host..":"..port - local echo = "echo 'password "..pass.."\nstatus\ncurrentsong\nclose'" + -- Construct MPD client options, fallback to defaults when necessary + local query = ("printf 'password %s\nstatus\ncurrentsong\nclose\n'"):format( + warg and (warg.password or warg[1]) or '""') + local connect = ("curl --connect-timeout 1 -fsm 3 telnet://%s:%s"):format( + warg and (warg.host or warg[2]) or "127.0.0.1", + warg and (warg.port or warg[3]) or "6600") -- Get data from MPD server - local f = io.popen(echo.." | curl --connect-timeout 1 -fsm 3 "..mpdh) - + local f = io.popen(query .. "|" .. connect) for line in f:lines() do for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do local key = "{" .. k .. "}" - if k == "volume" then + if k == "volume" or k == "bitrate" or + k == "elapsed" or k == "duration" then mpd_state[key] = v and tonumber(v) + elseif k == "repeat" or k == "random" then + mpd_state[key] = cbool(v) elseif k == "state" then mpd_state[key] = helpers.capitalize(v) - elseif k == "Artist" or k == "Title" or + elseif k == "Artist" or k == "Title" or --k == "Name" or k == "file" or k == "Album" or k == "Genre" then mpd_state[key] = v @@ -58,6 +71,10 @@ local function worker(format, warg) end f:close() + -- Formatted elapsed and duration + mpd_state["{Elapsed}"], mpd_state["{Duration}"] = helpers.format_progress( + mpd_state["{elapsed}"], mpd_state["{duration}"]) + return mpd_state end -- }}}