diff options
Diffstat (limited to 'plugins/degesch/last-fm.lua')
-rw-r--r-- | plugins/degesch/last-fm.lua | 178 |
1 files changed, 0 insertions, 178 deletions
diff --git a/plugins/degesch/last-fm.lua b/plugins/degesch/last-fm.lua deleted file mode 100644 index 6ade80d..0000000 --- a/plugins/degesch/last-fm.lua +++ /dev/null @@ -1,178 +0,0 @@ --- --- last-fm.lua: "now playing" feature using the last.fm API --- --- Dependencies: lua-cjson (from luarocks e.g.) --- --- I call this style closure-oriented programming --- --- Copyright (c) 2016, Přemysl Eric Janouch <p@janouch.name> --- --- Permission to use, copy, modify, and/or distribute this software for any --- purpose with or without fee is hereby granted. --- --- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES --- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF --- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY --- SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES --- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION --- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN --- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --- - -local cjson = require "cjson" - --- Setup configuration to load last.fm API credentials from -local user, api_key -degesch.setup_config { - user = { - type = "string", - comment = "last.fm username", - on_change = function (v) user = v end - }, - api_key = { - type = "string", - comment = "last.fm API key", - on_change = function (v) api_key = v end - }, -} - --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --- Generic error reporting -local report_error = function (buffer, error) - buffer:log ("last-fm error: " .. error) -end - --- Process data return by the server and extract the now playing song -local process = function (buffer, data, action) - -- There's no reasonable Lua package to parse HTTP that I could find - local s, e, v, status, message = string.find (data, "(%S+) (%S+) .+\r\n") - if not s then return "server returned unexpected data" end - if status ~= "200" then return status .. " " .. message end - - local s, e = string.find (data, "\r\n\r\n") - if not s then return "server returned unexpected data" end - - local parser = cjson.new () - data = parser.decode (string.sub (data, e + 1)) - if not data.recenttracks or not data.recenttracks.track then - return "invalid response" end - - -- Need to make some sense of the XML automatically converted to JSON - local text_of = function (node) - if type (node) ~= "table" then return node end - return node["#text"] ~= "" and node["#text"] or nil - end - - local name, artist, album - for i, track in ipairs (data.recenttracks.track) do - if track["@attr"] and track["@attr"].nowplaying then - if track.name then name = text_of (track.name) end - if track.artist then artist = text_of (track.artist) end - if track.album then album = text_of (track.album) end - end - end - - if not name then - action (false) - else - local np = "\"" .. name .. "\"" - if artist then np = np .. " by " .. artist end - if album then np = np .. " from " .. album end - action (np) - end -end - --- Set up the connection and make the request -local on_connected = function (buffer, c, host, action) - -- Buffer data in the connection object - c.data = "" - c.on_data = function (data) - c.data = c.data .. data - end - - -- And process it after we receive everything - c.on_eof = function () - error = process (buffer, c.data, action) - if error then report_error (buffer, error) end - c:close () - end - c.on_error = function (e) - report_error (buffer, e) - end - - -- Make the unencrypted HTTP request - local url = "/2.0/?method=user.getrecenttracks&user=" .. user .. - "&limit=1&api_key=" .. api_key .. "&format=json" - c:send ("GET " .. url .. " HTTP/1.1\r\n") - c:send ("User-agent: last-fm.lua\r\n") - c:send ("Host: " .. host .. "\r\n") - c:send ("Connection: close\r\n") - c:send ("\r\n") -end - --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --- Avoid establishing more than one connection at a time -local running - --- Initiate a connection to last.fm servers -async, await = degesch.async, coroutine.yield -local make_request = function (buffer, action) - if not user or not api_key then - report_error (buffer, "configuration is incomplete") - return - end - - if running then running:cancel () end - running = async.go (function () - local c, host, e = await (async.dial ("ws.audioscrobbler.com", 80)) - if e then - report_error (buffer, e) - else - on_connected (buffer, c, host, action) - end - running = nil - end) -end - --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -local now_playing - -local tell_song = function (buffer) - if now_playing == nil then - buffer:log ("last-fm: I don't know what you're listening to") - elseif not now_playing then - buffer:log ("last-fm: not playing anything right now") - else - buffer:log ("last-fm: now playing: " .. now_playing) - end -end - -local send_song = function (buffer) - if not now_playing then - tell_song (buffer) - else - buffer:execute ("/me is listening to " .. now_playing) - end -end - --- Hook input to simulate new commands -degesch.hook_input (function (hook, buffer, input) - if input == "/np" then - make_request (buffer, function (np) - now_playing = np - send_song (buffer) - end) - elseif input == "/np?" then - make_request (buffer, function (np) - now_playing = np - tell_song (buffer) - end) - elseif input == "/np!" then - send_song (buffer) - else - return input - end -end) |