X-Git-Url: https://git.rvb.name/mpd-lua.git/blobdiff_plain/759671cb4bae0c5a209dc4406f5e5c3b46316375..6c4cba13d034c0c7675e8f2aa3ee04ad24c911e1:/mpd.lua~ diff --git a/mpd.lua~ b/mpd.lua~ deleted file mode 100755 index 97ac4f4..0000000 --- a/mpd.lua~ +++ /dev/null @@ -1,417 +0,0 @@ -#!/usr/bin/lua - -local hasuci,uci = pcall(require,"uci") - -require("socket") -json=require("json") - -function url_decode(str) - if not str then return nil end - str = string.gsub (str, "+", " ") - str = string.gsub (str, "%%(%x%x)", function(h) return - string.char(tonumber(h,16)) end) - str = string.gsub (str, "\r\n", "\n") - return str -end - -function split(s, delimiter) - local result = {}; - for match in (s..delimiter):gmatch("(.-)"..delimiter) do - result[#result+1] = match; - end - return result; -end - -function string.starts(String,Start) - return string.sub(String,1,string.len(Start))==Start -end - -function process_playlist(playlist) - local res={} - for _,record in pairs(playlist) do - local splitted = split(record,": ") - local name = splitted[2] - local splitted = split(splitted[1],":") - local id = splitted[1] - local rectype = splitted[2] - local rec = {} - if not (id == "OK") then - rec["id"] = id - rec["type"] = rectype - rec["name"] = name - res[id] = rec - end - end - return res -end - -function process_playlists(playlists) - local res={} - for _,record in pairs(playlists) do - local splitted = split(record,": ") - if splitted[1]=="playlist" then - res[#res+1] = splitted[2] - end - end - return res -end - -function process_directory(directory) - local res={} - for _,record in pairs(directory) do - local splitted = split(record,": ") - if splitted[1]=="directory" or splitted[1]=="file" then - local rec={} - rec["type"] = splitted[1] - rec["name"] = splitted[2] - res[#res+1] = rec - end - end - return res -end - -function mpd_new(settings) - local client = {} - if settings == nil then settings = {} end - - client.hostname = settings.hostname or "localhost" - client.port = settings.port or 6600 - client.desc = settings.desc or client.hostname - client.password = settings.password - client.timeout = settings.timeout or 1 - client.retry = settings.retry or 60 - - return client -end - -function mpd_send(mpd,action,raw) - - local command = string.format("%s\n", action) - local values = {} - - -- connect to MPD server if not already done. - if not mpd.connected then - local now = os.time(); - if not mpd.last_try or (now - mpd.last_try) > mpd.retry then - mpd.socket = socket.tcp() - mpd.socket:settimeout(mpd.timeout, 't') - mpd.last_try = os.time() - mpd.connected = mpd.socket:connect(mpd.hostname, mpd.port) - if not mpd.connected then - return { errormsg = "could not connect" } - end - mpd.last_error = nil - - -- Read the server's hello message - local line = mpd.socket:receive("*l") - if not line:match("^OK MPD") then -- Invalid hello message? - mpd.connected = false - return { errormsg = string.format("invalid hello message: %s", line) } - else - _, _, mpd.version = string.find(line, "^OK MPD ([0-9.]+)") - end - - -- send the password if needed - if mpd.password then - local rsp = mpd_send(mpd,string.format("password %s", mpd.password)) - if rsp.errormsg then - return rsp - end - end - else - local retry_sec = mpd.retry - (now - mpd.last_try) - return { errormsg = string.format("%s (retrying in %d sec)", mpd.last_error, retry_sec) } - end - end - - mpd.socket:send(command) - - local line = ""; err=0 - while not line:match("^OK$") do - line, err = mpd.socket:receive("*l") - if not line then -- closed,timeout (mpd killed?) - mpd.last_error = err - mpd.connected = false - mpd.socket:close() - return mpd_send(mpd,action) - end - - if line:match("^ACK") then - return { errormsg = line } - end - - if not raw then - - local pattern = string.format("(%s)", ": ") - local i = string.find (line, pattern, 0) - - if i ~= nil then - local key=string.sub(line,1,i-1) - local value=string.sub(line,i+2,-1) - values[string.lower(key)] = value - end - - else - - values[#values+1]=line - - end - end - - return values -end - -if hasuci then - - x = uci.cursor() - - settings = {} - settings['host'] = x.get("mpd","server","host") or "localhost" - settings['port'] = x.get("mpd","server","port") or 6600 - settings['timeout'] = x.get("mpd","server","timeout") or 1 - - volstep = x.get("mpd","control","volume_step") or 3 - - password = x.get("mpd","server","password") - -else - - config = arg[1] - if not config then - config="/etc/mpd-lua.json" - end - - settings={} - local open = io.open - local file = open(config, "r") - if file then - local content = file:read "*a" - file:close() - settings=json.decode(content) - end - - settings['host'] = settings['host'] or "localhost" - settings['port'] = settings["port"] or 6600 - settings['timeout'] = settings["timeout"] or 1 - - volstep = settings["volstep"] or 3 - -end - - -if password then - settings["password"] = password -end - -m = mpd_new(settings) - -command = url_decode(os.getenv('QUERY_STRING')) - -if not command or command=="" then - command="idle" -end - -if command=="play" or command=="pause" or command=="stop" then - - res=mpd_send(m,command) - -elseif command=="previous" or command=="next" then - - res=mpd_send(m,"play") - res=mpd_send(m,command) - -elseif command=="idle" then - - m.timeout=30 - res=mpd_send(m,command) - -elseif command=="vold" then - - status=mpd_send(m,"status") - volume=tonumber(status["volume"]) - res=mpd_send(m,"setvol "..(volume-volstep)) - -elseif command=="volu" then - - status=mpd_send(m,"status") - volume=tonumber(status["volume"]) - res=mpd_send(m,"setvol "..(volume+volstep)) - -elseif string.starts(command,"fastfwd") then - - cmd=split(command,"|") - skip=tonumber(cmd[2]) - if not skip then - skip=15 - end - - status=mpd_send(m,"status") - rec_time=status["time"] - song=status["song"] - - if song then - - if rec_time then - rec_time=split(rec_time,":") - cur_time=tonumber(rec_time[1]) - - track_time=tonumber(rec_time[2]) - cur_time=cur_time+skip - if cur_time>track_time then - cur_time=track_time - end - - mpd_send(m,"seek "..song.." "..cur_time) - - else - - mpd_send(m,"play") - - end - - end - - res={} - -elseif string.starts(command,"rewind") then - - cmd=split(command,"|") - skip=tonumber(cmd[2]) - if not skip then - skip=15 - end - - status=mpd_send(m,"status") - rec_time=status["time"] - song=status["song"] - - if song then - - if rec_time then - rec_time=split(rec_time,":") - cur_time=tonumber(rec_time[1]) - - track_time=tonumber(rec_time[2]) - cur_time=cur_time-skip - if cur_time<0 then - cur_time=0 - end - - mpd_send(m,"seek "..song.." "..cur_time) - - else - - mpd_send(m,"play") - mpd_send(m,"previous") - - end - - end - - res={} - -elseif command=="status" then - - res=mpd_send(m,"status") - song=res["song"] - playlist=mpd_send(m,"playlist",1) - pl=process_playlist(playlist) - - if song then - res['current_playing']=pl[song]['name'] - else - res['song']="--" - res['current_playing']="---" - end - -elseif command=="playlist" then - - playlist=mpd_send(m,"playlist",1) - res=process_playlist(playlist) - -elseif command=="repeat" then - - status=mpd_send(m,"status") - rep=1-status["repeat"] - res=mpd_send(m,"repeat "..rep) - -elseif string.starts(command,"cpl") then - - cmd=split(command,"|") - id=cmd[3] - command=cmd[2] - - if command=="playitem" then - command="play "..id - res=mpd_send(m,command) - end - - if command=="clear" then - res=mpd_send(m,"clear") - end - - if command=="remove" then - command="delete "..id - res=mpd_send(m,command) - end - - if command=="moveup" then - command="swap "..id.." "..(id-1) - res=mpd_send(m,command) - end - - if command=="movedown" then - command="swap "..id.." "..(id+1) - res=mpd_send(m,command) - end - -elseif string.starts(command,"lists") then - - cmd=split(command,"|") - command=cmd[2] - - if command=="load" then - if not cmd[3] then - lists=mpd_send(m,"listplaylists",1) - res=process_playlists(lists) - else - res=mpd_send(m,"load "..cmd[3],1) - end - end - - if command=="save" and cmd[3] then - res=mpd_send(m,"save "..cmd[3],1) - end - - if command=="delete" and cmd[3] then - res=mpd_send(m,"rm "..cmd[3],1) - end - - if command=="edit" then - if cmd[3] then - dir=mpd_send(m,"lsinfo \""..cmd[3].."\"",1) - else - dir=mpd_send(m,"lsinfo",1) - end - res=process_directory(dir) - end - - if command=="add" then - res={} - if cmd[3] then - res=mpd_send(m,"add \""..cmd[3].."\"") - end - end - -end - -if not res then - print("Content-Type: text/plain\r\n") - print("MPD server - unknown command "..command) -elseif (res['error_msg']) then - print("Content-Type: text/plain\r\n") - print("MPD server connection error: "..res['error_msg']) -else - print "Content-Type: text/plain\r\n" - print(json.encode(res)) -end