Багфиксы. Обработка особенностей поведения mopidy и mpd. Обработка пустых и малознача...
[mpd-lua.git] / mpd.lua~
diff --git a/mpd.lua~ b/mpd.lua~
deleted file mode 100755 (executable)
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