+++ /dev/null
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- Version 2, December 2004
-
- Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
-
- Everyone is permitted to copy and distribute verbatim or modified
- copies of this license document, and changing it is allowed as long
- as the name is changed.
-
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. You just DO WHAT THE FUCK YOU WANT TO.
-urlbase="mpd.lua?"
+urlbase="/cgi-bin/mpd.cgi?"
minScrollHeight=200
currentState=""
function RefreshTime() {
if (currentSeconds) {
currentTime = toHHMMSS(currentSeconds)
- trackTime = toHHMMSS(trackSeconds)
- nowPlayingTime = currentTime+"/"+trackTime
+ if (trackSeconds) {
+ trackTime = toHHMMSS(trackSeconds)
+ nowPlayingTime = currentTime+"/"+trackTime
+ } else {
+ nowPlayingTime = currentTime
+ }
} else {
nowPlayingTime = "-:--/-:--"
}
nowTime = Date.now()
delta = (nowTime - updateTime)/1000
currentSeconds = updateSeconds + Math.round(delta)
- if (currentSeconds > trackSeconds) {
+ if (trackSeconds && (currentSeconds > trackSeconds)) {
currentSeconds = trackSeconds
}
RefreshTime()
if (this.readyState != 4 || this.status != 200) return;
var returnedData = JSON.parse(this.responseText);
trackName = GetFilename(returnedData['current_playing']);
+ try {
+ var trackName=decodeURI(trackName).replace(/%2C/g,",")
+ }
+ catch(e) {
+ console.log(trackName)
+ }
trackNo = returnedData['song'];
+ trackId = returnedData['songid']
currentState = returnedData['state'];
document.title='MPD Player: '+trackName;
if (trackNo) {
var items = document.getElementById('items');
var table = items.getElementsByClassName('track');
- var current_track="track_"+trackNo;
+ var current_track="track_"+trackId;
for (var i = 0; i < table.length; i++) {
if (table[i].id==current_track) {
table[i].classList.add("itemActive");
var even = 0;
for (var key in returnedData) {
var rec=returnedData[key];
- var name=GetFilename(rec["name"]);
+ var name=GetFilename(rec["title"]);
+ try {
+ var name=decodeURI(name).replace(/%2C/g,",")
+ }
+ catch(e) {
+ console.log(name)
+ }
var id=rec["id"];
if (even) {
itemsText = itemsText + "<tr id=\"track_"+id+"\" class=\"track "+evText+"\">\
<td class=\"track_number\">\
- <a name=\""+id+"\">"+(Number(id)+1)+"</a></td>\
+ <a name=\""+id+"\">"+(Number(key)+1)+"</a></td>\
</td>\
<td class=\"file\">\
<span class=\"link\" onclick=\"PlaylistCommand('playitem',"+id+")\">"+name+"</span>\
var playlistMenuText = "<table>\
<tr>\
- <td><span onclick=\"RefreshPlaylist()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\
+ <td><span onclick=\"RefreshPageContent()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\
<td><span onclick=\"return confirm('Add all to the list, are you sure?') ? PlaylistEditCommand('add','"+EscapeStr(dir)+"') : false;\" ><img class=\"medium-button\" title=\"Add all\" src=\"images/plus.svg\"></span><td>\
</tr>\
</table>";
} else {
var tailName=name
};
+ try {
+ var tailName=decodeURI(tailName).replace(/%2C/g,",")
+ }
+ catch(e) {
+ console.log(tailName)
+ }
if (type == "directory" || type == "file") {
if (even) {
var returnedData = JSON.parse(this.responseText);
playlistMenuText="<table>\
<tr>\
- <td><span onclick=\"RefreshPlaylist()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\
+ <td><span onclick=\"RefreshPageContent()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\
<td><span onclick=\"confirm('Clear current playlist, are you sure?') ? PlaylistCommandRefStatus('clear') : false;\" ><img class=\"medium-button\" title=\"Clear all\" src=\"images/cancel.svg\"></span><td>\
</tr>\
</table>";
+++ /dev/null
-urlbase="mpd.lua?"
-minScrollHeight=200
-
-currentState=""
-
-function GetFilename(url)
-{
- if (url)
- return url.split('/').pop().split('#')[0].split('?')[0];
-}
-
-function EscapeStr(str) {
- res = str.replace(/'/g,"\\'");
- return res;
-}
-
-function SetSize() {
- var w = window,
- d = document,
- e = d.documentElement,
- g = d.getElementsByTagName('body')[0],
- body_h = g.clientHeight,
- window_h = w.innerHeight|| e.clientHeight|| g.clientHeight,
- items = d.getElementById('items'),
- current_h = items.clientHeight,
- new_h=(window_h-body_h)+current_h;
- if (new_h>minScrollHeight) {
- items.style.height=new_h+"px";
- }
-}
-
-function toHHMMSS(seconds) {
- var hours = Math.floor(seconds / 3600);
- seconds -= hours*3600;
- var minutes = Math.floor(seconds / 60);
- seconds -= minutes*60;
-
- if (hours < 10) {hours = "0"+hours;}
- if (minutes < 10) {minutes = "0"+minutes;}
- if (seconds < 10) {seconds = "0"+seconds;}
- if (hours == 0) {
- return minutes+':'+seconds;
- } else {
- return hours+':'+minutes+':'+seconds;
- }
-}
-
-function RefreshTime() {
- if (currentSeconds) {
- currentTime = toHHMMSS(currentSeconds)
- trackTime = toHHMMSS(trackSeconds)
- nowPlayingTime = currentTime+"/"+trackTime
- } else {
- nowPlayingTime = "-:--/-:--"
- }
- document.getElementById('nowplaying_tracklen').innerHTML=nowPlayingTime;
-}
-
-function PeriodicRefreshTime() {
- if (currentState == "play") {
- nowTime = Date.now()
- delta = (nowTime - updateTime)/1000
- currentSeconds = updateSeconds + Math.round(delta)
- if (currentSeconds > trackSeconds) {
- currentSeconds = trackSeconds
- }
- RefreshTime()
- }
-}
-
-function RefreshPageStatus() {
-
- var req = new XMLHttpRequest();
-
- req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- var returnedData = JSON.parse(this.responseText);
- trackName = GetFilename(returnedData['current_playing']);
- trackNo = returnedData['song'];
- currentState = returnedData['state'];
- document.title='MPD Player: '+trackName;
- if (trackNo) {
- var nowPlayingTrackNo=String(1+Number(trackNo))
- } else {
- var nowPlayingTrackNo="-"
- }
- nowPlayingTrack = nowPlayingTrackNo + '/' + returnedData['playlistlength'];
- nowPlayingName = trackName;
- playingTime = returnedData['time']
- if (playingTime) {
- var splits = playingTime.split(":")
- updateTime = Date.now()
- currentSeconds = Number(splits[0])
- updateSeconds = currentSeconds
- trackSeconds = Number(splits[1])
- } else {
- currentSeconds = null
- }
- if (currentState=='stop') {
- nowPlayingName = '<font color="gray">' + nowPlayingName+ '</font>'
- }
- document.getElementById('nowplaying_trackno').innerHTML=nowPlayingTrack;
- document.getElementById('nowplaying_trackname').innerHTML=nowPlayingName;
- RefreshTime()
- if (currentState=="play") {
- document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('pause')\"><img class=\"button\" title=\"Pause\" src=\"images/pause.svg\"></span>";
- } else {
- document.getElementById('playpausebutton').innerHTML="<span onclick=\"Command('play')\"><img class=\"button\" title=\"Play\" src=\"images/play-button.svg\"></span>";
- }
- if (currentState=="stop") {
- document.getElementById('stopbutton').innerHTML="<span><img class=\"button\" src=\"images/stopoff.svg\"></span>";
- } else {
- document.getElementById('stopbutton').innerHTML="<span onclick=\"Command('stop')\"><img class=\"button\" title=\"Stop\" src=\"images/stop.svg\"></span>";
- }
- if (returnedData["repeat"]=="1") {
- document.getElementById('repeatstate').innerHTML="<img class=\"button\" title=\"Replay is on\" src=\"images/replay.svg\"></a>";
- } else {
- document.getElementById('repeatstate').innerHTML="<img class=\"button\" title=\"Replay is off\" src=\"images/replayoff.svg\"></a>";
- }
- document.getElementById('volume_total').innerHTML="<div id=\"volume_actual\" style=\"width:"+returnedData["volume"]+"%\">";
-
- var items = document.getElementById('items');
- var table = items.getElementsByClassName('track');
- var current_track="track_"+trackNo;
- for (var i = 0; i < table.length; i++) {
- if (table[i].id==current_track) {
- table[i].classList.add("itemActive");
- } else {
- table[i].classList.remove("itemActive")
- }
- }
-
- };
-
- req.open("GET", urlbase+"status", true);
- req.send();
-
-}
-
-function RefreshPlaylist() {
-
-var req = new XMLHttpRequest();
-
-req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- var returnedData = JSON.parse(this.responseText);
-
- var playlistMenuText = "<table>\
- <tr>\
- <td><span onclick=\"EditPlayList()\"><img class=\"medium-button\" title=\"Files\" src=\"images/folder.svg\"></span><td>\
- <td><span onclick=\"LoadPlayList()\"><img class=\"medium-button\" title=\"Lists\" src=\"images/list.svg\"></span><td>\
- <td><span onclick=\"SavePlayList()\"><img class=\"medium-button\" title=\"Save current list\" src=\"images/download.svg\"></span><td>\
- <td><span onclick=\"return confirm('Clear current playlist, are you sure?') ? PlaylistCommand('clear') : false;\" ><img class=\"medium-button\" title=\"Clear current list\" src=\"images/cancel.svg\"></span><td>\
- </tr>\
- </table>";
-
- var itemsText="<table>\
- <tr id=\"items_heading\">\
- <td></td class=\"track_number\"><td class=\"file\">Title</td><td class=\"medium-button\" colspan=\"3\">Controls</td>\
- </tr>";
-
- var even = 0;
- for (var key in returnedData) {
- var rec=returnedData[key];
- var name=GetFilename(rec["name"]);
- var id=rec["id"];
-
- if (even) {
- evText="itemEven";
- } else {
- evText="itemOdd";
- };
-
- even = ! even;
-
- itemsText = itemsText + "<tr id=\"track_"+id+"\" class=\"track "+evText+"\">\
- <td class=\"track_number\">\
- <a name=\""+id+"\">"+(Number(id)+1)+"</a></td>\
- </td>\
- <td class=\"file\">\
- <span class=\"link\" onclick=\"PlaylistCommand('playitem',"+id+")\">"+name+"</span>\
- </td>\
- <td class=\"move\">\
- <span onclick=\"PlaylistCommand('moveup',"+id+")\"><img class=\"small-button\" title=\"Move up\" src=\"images/up-arrow.svg\"></span>\
- </td>\
- <td class=\"move\">\
- <span onclick=\"PlaylistCommand('movedown',"+id+")\"><img class=\"small-button\" title=\"Move down\" src=\"images/down-arrow.svg\"></span>\
- </td>\
- <td class=\"remove\">\
- <span onclick=\"PlaylistCommand('remove',"+id+")\"><img class=\"small-button\" title=\"Remove\" src=\"images/cancel.svg\"></span>\
- </td>\
- </tr>";
- }
-
- itemsText = itemsText + "</table>";
-
- document.getElementById('items').innerHTML=itemsText;
- document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
- document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
-};
-
-req.open("GET", urlbase+"playlist", true);
-req.send();
-
-}
-
-function EditPlayList(dir) {
-
-var req = new XMLHttpRequest();
-
-req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- var returnedData = JSON.parse(this.responseText);
-
- var playlistMenuText = "<table>\
- <tr>\
- <td><span onclick=\"RefreshPlaylist()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\
- <td><span onclick=\"return confirm('Add all to the list, are you sure?') ? PlaylistEditCommand('add','"+EscapeStr(dir)+"') : false;\" ><img class=\"medium-button\" title=\"Add all\" src=\"images/plus.svg\"></span><td>\
- </tr>\
- </table>";
-
- var itemsText= "<table>\
- <tr id=\"items_heading\">\
- <td></td class=\"track_number\"><td class=\"file\">Title</td><td colspan=\"2\">Controls</td>\
- </tr>";
-
- var even = 0;
- if (dir) {
- var lastSlash=dir.lastIndexOf("/");
- if (lastSlash>0) {
- var upperLevel=dir.slice(0,lastSlash);
- } else {
- var upperLevel="";
- }
- even = ! even;
- var itemsText = itemsText + "<tr class=\"itemOdd\">\
- <td class=\"track_number\"></td>\
- <td class=\"file\"><span class=\"link\" onclick=\"EditPlayList('"+upperLevel+"')\">..</span></td>\
- <td></td><td></td>";
- }
-
- var i = 0;
- for (var key in returnedData) {
- var rec=returnedData[key];
- var type=rec["type"];
- var name=rec["name"];
- var lastSlash=name.lastIndexOf("/");
- if (lastSlash>0) {
- var tailName=name.slice(lastSlash+1);
- } else {
- var tailName=name
- };
-
- if (type == "directory" || type == "file") {
- if (even) {
- evText="itemEven";
- } else {
- evText="itemOdd";
- };
-
- i = i + 1;
- even = ! even;
-
- itemsText = itemsText + "<tr class=\""+evText+"\">\
- <td class=\"track_number\">\
- <a name=\""+i+"\"></a></td>\
- </td>";
-
- if (type == "directory") {
- itemsText = itemsText + "<td class=\"file\">\
- <span class=\"link\" onclick=\"EditPlayList('"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\
- <span onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img class=\"small-button\" title=\"Add\" src=\"images/plus.svg\"></span></td>";
- };
-
- if (type == "file") {
- itemsText = itemsText + "<td class=\"file\">\
- <span class=\"link\" onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\">"+tailName+"</span></td><td>\
- <span onclick=\"PlaylistEditCommand('add','"+EscapeStr(name)+"')\"><img class=\"small-button\" title=\"Add\" src=\"images/plus.svg\"></span></td>";
- };
-
- itemsText = itemsText + "</tr>";
-
- }
-
- }
-
- var itemsText = itemsText+"</table>";
- document.getElementById('items').innerHTML=itemsText;
- document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
- document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
-};
-
-if (!dir) { dir = ''; };
-
-req.open("GET", urlbase+"lists|edit|"+dir, true);
-req.send();
-
-}
-
-function LoadPlayList() {
-
-var req = new XMLHttpRequest();
-
-req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- var returnedData = JSON.parse(this.responseText);
- playlistMenuText="<table>\
- <tr>\
- <td><span onclick=\"RefreshPlaylist()\"><img class=\"medium-button\" title=\"Home\" src=\"images/list.svg\"></span><td>\
- <td><span onclick=\"confirm('Clear current playlist, are you sure?') ? PlaylistCommandRefStatus('clear') : false;\" ><img class=\"medium-button\" title=\"Clear all\" src=\"images/cancel.svg\"></span><td>\
- </tr>\
- </table>";
- itemsText="<table>\
- <tr id=\"items_heading\">\
- <td class=\"track_number\"></td><td class=\"file\">Name</td><td>Controls</td>\
- </tr>";
-
- var even = 0;
- for (var key in returnedData) {
- var name=returnedData[key];
-
- if (even) {
- evText="itemEven";
- } else {
- evText="itemOdd";
- };
-
- even = ! even;
-
- itemsText = itemsText + "<tr class=\""+evText+"\">\
- <td class=\"track_number\"><a name=\"0\"></a></td>\
- <td class=\"file\"><span class=\"link\" onclick=\"PlaylistEditCommandRefFull('load','"+EscapeStr(name)+"')\">"+name+"</td>\
- <td class=\"controls\"><span onclick=\"confirm('Delete playlist "+name+", are you sure?') ? DelPlayList('"+EscapeStr(name)+"') : false;\"><img class=\"small-button\" title=\"Delete\" src=\"images/minus.svg\"></span></td>\
- </tr>";
- }
-
- itemsText=itemsText+"</table>";
- document.getElementById('items').innerHTML=itemsText;
- document.getElementById('playlist_menu_top').innerHTML=playlistMenuText;
- document.getElementById('playlist_menu_bottom').innerHTML=playlistMenuText;
-};
-
-req.open("GET", urlbase+"lists|load", true);
-req.send();
-
-}
-
-function SavePlayList() {
-
-var name=window.prompt('List name','');
-
-var req = new XMLHttpRequest();
-
-req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- if (this.responseText != 'OK') {
- window.alert(this.responseText);
- }
-};
-
-req.open("GET", urlbase+"lists|save|"+name, true);
-req.send();
-
-}
-
-function DelPlayList(item) {
-
-var req = new XMLHttpRequest();
-
-req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- LoadPlayList();
- RefreshPageStatus();
-};
-
-req.open("GET", urlbase+"lists|delete|"+item, true);
-req.send();
-
-}
-
-function RefreshPageContent() {
- RefreshPlaylist();
- RefreshPageStatus();
-}
-
-function Command(cmd) {
-
-var req = new XMLHttpRequest();
-
-req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- RefreshPageStatus();
-};
-
-req.open("GET", urlbase+cmd, true);
-req.send();
-
-}
-
-function PlaylistCommand(cmd,item) {
-
-var req = new XMLHttpRequest();
-
-req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- RefreshPageContent();
-};
-
-req.open("GET", urlbase+"cpl|"+cmd+"|"+item, true);
-req.send();
-
-}
-
-function PlaylistCommandRefStatus(cmd,item) {
-
-var req = new XMLHttpRequest();
-
-req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- RefreshPageStatus();
-};
-
-req.open("GET", urlbase+"cpl|"+cmd+"|"+item, true);
-req.send();
-
-}
-
-function PlaylistEditCommand(cmd,item) {
-
-var req = new XMLHttpRequest();
-
-req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- RefreshPageStatus();
-};
-
-req.open("GET", urlbase+"lists|"+cmd+"|"+item, true);
-req.send();
-
-}
-
-function PlaylistEditCommandRefFull(cmd,item) {
-
-var req = new XMLHttpRequest();
-
-req.onreadystatechange = function () {
- if (this.readyState != 4 || this.status != 200) return;
- RefreshPageContent();
-};
-
-req.open("GET", urlbase+"lists|"+cmd+"|"+item, true);
-req.send();
-
-}
-
-function subscribe_status() {
- var xhr = new XMLHttpRequest();
-
- xhr.onreadystatechange = function() {
- if (this.readyState != 4) return;
- if (this.status == 200) {
- RefreshPageStatus()
- setTimeout(subscribe_status,1000)
- } else {
- setTimeout(subscribe_status,15000)
- }
- }
- xhr.open("GET", urlbase+"idle", true);
- xhr.send();
-}
-
-setTimeout(subscribe_status,5000)
-setInterval(PeriodicRefreshTime, 1000);
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
+hasuci = false
+
if hasuci then
x = uci.cursor()
else
- config = arg[1]
- if not config then
- config="/etc/mpd-lua.json"
- end
+ config="/etc/mpd-lua.json"
settings={}
local open = io.open
- local file = open(config, "r")
+ file = open(config, "r")
if file then
- local content = file:read "*a"
+ content = file:read "*a"
file:close()
settings=json.decode(content)
end
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']
+ 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))
+++ /dev/null
-#!/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