#!/usr/bin/lua
-require "uci"
+local hasuci,uci = pcall(require,"uci")
+
require("socket")
json=require("json")
return str
end
+function url_encode(str)
+
+ --Ensure all newlines are in CRLF form
+ str = string.gsub (str, "\r?\n", "\r\n")
+
+ --Percent-encode all non-unreserved characters
+ --as per RFC 3986, Section 2.3
+ --(except for space, which gets plus-encoded)
+ str = string.gsub (str, "([^%w%-%.%_%~:/])",
+ function (c) return string.format ("%%%02X", string.byte(c)) end)
+
+ --Convert spaces to plus signs
+ str = string.gsub (str, " ", "+")
+
+ return str
+end
+
function split(s, delimiter)
local result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
return string.sub(String,1,string.len(Start))==Start
end
+function filename(path)
+ local path_elems=split(path,'/')
+ return path_elems[#path_elems]
+end
+
function process_playlist(playlist)
local res={}
+ local rec={}
for _,record in pairs(playlist) do
+ if record=="OK" then
+ break
+ end
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
+ local fieldname = string.lower(splitted[1])
+ local fieldvalue = splitted[2]
+ rec[fieldname] = fieldvalue
+ if fieldname=="id" then
+ local title = rec['title']
+ if title then
+ local filtered_title=string.gsub(string.lower(title),'track','')
+ local filtered_title=string.gsub(filtered_title,'[ _.-]','')
+ else
+ filtered_title=""
+ end
+ if not filtered_title or string.len(filtered_title)<4 then
+ if title then
+ rec['title']=title..' - '..filename(rec['file'])
+ else
+ rec['title']=filename(rec['file'])
+ end
+ end
+ res[#res+1] = rec
+ rec={}
end
end
return res
end
+function find_by_id(playlist,id)
+ for key,record in pairs(playlist) do
+ if record['id']==id then
+ return key
+ end
+ end
+ return nil
+end
+
function process_playlists(playlists)
local res={}
for _,record in pairs(playlists) do
function mpd_new(settings)
local client = {}
+
if settings == nil then settings = {} end
client.hostname = settings.hostname or "localhost"
return values
end
-x = uci.cursor()
+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
+ 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
+ volstep = x.get("mpd","control","volume_step") or 3
-password = x.get("mpd","server","password")
+ password = x.get("mpd","server","password")
+
+else
+
+ config="/etc/mpd-lua.json"
+
+ settings={}
+ local open = io.open
+ file = open(config, "r")
+ if file then
+ 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
status=mpd_send(m,"status")
rec_time=status["time"]
- song=status["song"]
+ song=status["songid"]
if song then
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)
+ if track_time then
+ cur_time=cur_time+skip
+ if cur_time>track_time then
+ cur_time=track_time
+ end
+ end
+ mpd_send(m,"seekid "..song.." "..cur_time)
else
status=mpd_send(m,"status")
rec_time=status["time"]
- song=status["song"]
+ song=status["songid"]
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)
-
+ print(song)
+ print(cur_time)
+ mpd_send(m,"seekid "..song.." "..cur_time)
+
else
mpd_send(m,"play")
elseif command=="status" then
res=mpd_send(m,"status")
- song=res["song"]
- playlist=mpd_send(m,"playlist",1)
- pl=process_playlist(playlist)
-
+ song=tonumber(res["songid"])
if song then
- res['current_playing']=pl[song]['name']
- else
- res['song']="--"
+ playlist=mpd_send(m,"playlistid "..song,1)
+ pl=process_playlist(playlist)
+ res['current_playing']=pl[1]['title']
+ else
res['current_playing']="---"
end
elseif command=="playlist" then
- playlist=mpd_send(m,"playlist",1)
+ playlist=mpd_send(m,"playlistinfo",1)
res=process_playlist(playlist)
elseif command=="repeat" then
command=cmd[2]
if command=="playitem" then
- command="play "..id
+ command="playid "..id
res=mpd_send(m,command)
end
end
if command=="remove" then
- command="delete "..id
+ command="deleteid "..id
res=mpd_send(m,command)
end
if command=="moveup" then
- command="swap "..id.." "..(id-1)
+ playlist=mpd_send(m,"playlistinfo ",1)
+ pl=process_playlist(playlist)
+ idx=find_by_id(pl,id)
+ if idx>1 then
+ command="swap "..(idx-1).." "..(idx-2)
+ end
res=mpd_send(m,command)
end
if command=="movedown" then
- command="swap "..id.." "..(id+1)
+ playlist=mpd_send(m,"playlistinfo ",1)
+ pl=process_playlist(playlist)
+ idx=find_by_id(pl,id)
+ if idx<#pl then
+ command="swap "..(idx-1).." "..(idx)
+ end
res=mpd_send(m,command)
end
lists=mpd_send(m,"listplaylists",1)
res=process_playlists(lists)
else
- res=mpd_send(m,"load "..cmd[3],1)
+ 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)
+ res=mpd_send(m,"save \""..cmd[3].."\"",1)
end
if command=="delete" and cmd[3] then
- res=mpd_send(m,"rm "..cmd[3],1)
+ res=mpd_send(m,"rm \""..cmd[3].."\"",1)
end
if command=="edit" then
res={}
if cmd[3] then
res=mpd_send(m,"add \""..cmd[3].."\"")
+ if (res['errormsg']) then
+ path=url_encode(cmd[3])
+ res=mpd_send(m,"add \""..path.."\"")
+ 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
+elseif (res['errormsg']) then
print("Content-Type: text/plain\r\n")
- print("MPD server connection error: "..res['error_msg'])
+ print("MPD server connection error: "..res['errormsg'])
else
print "Content-Type: text/plain\r\n"
print(json.encode(res))