mirror of
https://github.com/DigitalDevices/octonet.git
synced 2023-10-10 11:36:52 +00:00
Channelscan
Added features to TransponderList.json Allow to define sort order for channels Allow overwrite channel title,group,pids Define custom groups (i.e. favourites) Removed client side sorting from browsertv.html Reworked creating ChannelList.json from legacy database to allow serveside sorting.
This commit is contained in:
@@ -127,12 +127,12 @@ function AddRow(table,name,request,tracks)
|
||||
table.appendChild(row);
|
||||
}
|
||||
|
||||
function TitleCompare(a,b)
|
||||
{
|
||||
if( a.Title.toUpperCase() < b.Title.toUpperCase() ) return -1;
|
||||
if( a.Title.toUpperCase() > b.Title.toUpperCase() ) return 1;
|
||||
return 0;
|
||||
}
|
||||
// function TitleCompare(a,b)
|
||||
// {
|
||||
// if( a.Title.toUpperCase() < b.Title.toUpperCase() ) return -1;
|
||||
// if( a.Title.toUpperCase() > b.Title.toUpperCase() ) return 1;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
var url = "/channellist.lua?select=json";
|
||||
@@ -200,10 +200,10 @@ function myFunction(response) {
|
||||
Index = Index + 1;
|
||||
}
|
||||
}
|
||||
for(var i = 0; i < SourceList.length; i++ )
|
||||
{
|
||||
SourceList[i].ChannelList.sort(TitleCompare);
|
||||
}
|
||||
// for(var i = 0; i < SourceList.length; i++ )
|
||||
// {
|
||||
// SourceList[i].ChannelList.sort(TitleCompare);
|
||||
// }
|
||||
document.Source.Select.selectedIndex = LastSource;
|
||||
SetSource(LastSource);
|
||||
}
|
||||
|
@@ -70,44 +70,52 @@ function CreateM3U(host)
|
||||
return table.concat(m3u)
|
||||
end
|
||||
|
||||
function JSONSource(host,SourceList,Title,System)
|
||||
local json = {}
|
||||
local src = ""
|
||||
local sep1 = "\n"
|
||||
local sep2 = "\n"
|
||||
local function CompareTitle(a,b)
|
||||
return a.Title < b.Title
|
||||
end
|
||||
|
||||
function Legacy2JSON()
|
||||
local newencoder = require("lunajson.encoder")
|
||||
local SourceList = LoadSourceList()
|
||||
local ChannelList = {}
|
||||
ChannelList.GroupList = {}
|
||||
local Group
|
||||
local Channel
|
||||
local f,c
|
||||
|
||||
table.insert(json,' "'..Title..'": [')
|
||||
sep1 = "\n"
|
||||
for _,f in pairs(SourceList) do
|
||||
if not System or f.system == System or f.system == System.."2" then
|
||||
table.insert(json,sep1)
|
||||
sep1 = ",\n"
|
||||
table.insert(json,' {\n')
|
||||
table.insert(json,' "Title": "'..f.title..'",\n')
|
||||
table.insert(json,' "ChannelList": [')
|
||||
Group = { Title=f.title, ChannelList = { } }
|
||||
table.insert(ChannelList.GroupList,Group)
|
||||
|
||||
if System == "dvbs" then
|
||||
src = 'src='..f.src..'&'
|
||||
if f.system == "dvbs" or f.system == "dvbs2" then
|
||||
src = 'src='..f.src..'&'
|
||||
end
|
||||
for _,c in ipairs(f.ChannelList) do
|
||||
local tracks = {}
|
||||
local track
|
||||
for track in c.tracks:gmatch("%d+") do
|
||||
table.insert(tracks,tonumber(track))
|
||||
end
|
||||
tracks[0] = #tracks
|
||||
|
||||
sep2 = "\n"
|
||||
for _,c in ipairs(f.ChannelList) do
|
||||
table.insert(json,sep2)
|
||||
sep2 = ",\n"
|
||||
table.insert(json,' {\n')
|
||||
table.insert(json,' "Title": "'..string.gsub(c.title,'"','\\"')..'",\n')
|
||||
table.insert(json,' "Request": "?'..src..c.request..'",\n')
|
||||
table.insert(json,' "Tracks": ['..c.tracks..']\n')
|
||||
table.insert(json,' }')
|
||||
end
|
||||
Channel = { Title=c.title,
|
||||
Request = '?'..src..c.request,
|
||||
Tracks=tracks }
|
||||
|
||||
table.insert(json,'\n ]\n')
|
||||
table.insert(json,' }')
|
||||
table.insert(Group.ChannelList,Channel)
|
||||
end
|
||||
end
|
||||
table.insert(json,'\n ]')
|
||||
|
||||
return table.concat(json)
|
||||
for _,Group in ipairs(ChannelList.GroupList) do
|
||||
table.sort(Group.ChannelList,CompareTitle)
|
||||
Group.ChannelList[0] = #Group.ChannelList
|
||||
end
|
||||
table.sort(ChannelList.GroupList,CompareTitle)
|
||||
ChannelList.GroupList[0] = #ChannelList.GroupList
|
||||
|
||||
local encode = newencoder()
|
||||
local data = encode(ChannelList)
|
||||
return data
|
||||
end
|
||||
|
||||
function CreateJSON(host)
|
||||
@@ -117,17 +125,7 @@ function CreateJSON(host)
|
||||
data = file:read("*a")
|
||||
file:close()
|
||||
else
|
||||
local SourceList = LoadSourceList()
|
||||
local json = {}
|
||||
table.insert(json,"{\n")
|
||||
|
||||
table.insert(json,JSONSource(host,SourceList,"GroupList",nil) .. "\n")
|
||||
--~ table.insert(json,JSONSource(host,SourceList,"SourceListSat","dvbs") .. ",\n")
|
||||
--~ table.insert(json,JSONSource(host,SourceList,"SourceListCable","dvbc") .. ",\n")
|
||||
--~ table.insert(json,JSONSource(host,SourceList,"SourceListTer","dvbt") .. "\n")
|
||||
|
||||
table.insert(json,"}\n")
|
||||
data = table.concat(json)
|
||||
data = Legacy2JSON()
|
||||
end
|
||||
return data
|
||||
end
|
||||
@@ -160,6 +158,7 @@ if method == "GET" then
|
||||
contenttype = "text/m3u; charset=utf-8"
|
||||
data = CreateM3U(host)
|
||||
elseif string.match(query,"select=json") then
|
||||
filename = "ChannelList.json"
|
||||
contenttype = "application/json; charset=utf-8"
|
||||
data = CreateJSON(host)
|
||||
end
|
||||
|
@@ -130,38 +130,36 @@ ScanReq.onreadystatechange=function()
|
||||
|
||||
function GetStatus()
|
||||
{
|
||||
ScanReq.open("GET", "/channelscan.lua?select=status", true);
|
||||
ScanReq.open("GET", "/channelscan.lua?select=status&t=" + Math.random(), true);
|
||||
ScanReq.send();
|
||||
}
|
||||
|
||||
function ScanStatus(response)
|
||||
{
|
||||
var s = JSON.parse(response);
|
||||
var done = false;
|
||||
var done = true;
|
||||
if( s.status )
|
||||
{
|
||||
if( s.status == "active" )
|
||||
{
|
||||
document.getElementById("scancount").firstChild.nodeValue = s.count;
|
||||
document.getElementById("scantext").firstChild.nodeValue = s.msg;
|
||||
done = false;
|
||||
}
|
||||
else if( s.status == "busy" )
|
||||
{
|
||||
document.getElementById("scancount").firstChild.nodeValue = "\u00A0";
|
||||
document.getElementById("scantext").firstChild.nodeValue = "BUSY";
|
||||
done = true;
|
||||
}
|
||||
else if( s.status == "done" )
|
||||
{
|
||||
document.getElementById("scancount").firstChild.nodeValue = s.count;
|
||||
document.getElementById("scantext").firstChild.nodeValue = "Channels found";
|
||||
done = true;
|
||||
}
|
||||
else if( s.status == "deleted" )
|
||||
{
|
||||
document.getElementById("scancount").firstChild.nodeValue = "\u00A0";
|
||||
document.getElementById("scantext").firstChild.nodeValue = "Channel list deleted";
|
||||
done = true;
|
||||
}
|
||||
else if( s.status == "restored" )
|
||||
{
|
||||
@@ -170,7 +168,10 @@ function ScanStatus(response)
|
||||
document.getElementById("scantext").firstChild.nodeValue = "Nothing restored";
|
||||
else
|
||||
document.getElementById("scantext").firstChild.nodeValue = "Previous channel list restored";
|
||||
done = true;
|
||||
}
|
||||
else if( s.status == "retry" )
|
||||
{
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,8 +217,9 @@ function InitiateScan()
|
||||
|
||||
if( param != "" )
|
||||
{
|
||||
ScanReq.open("GET", "/channelscan.lua?select=scan" + param + "&sitables=1&sort=1&restartdms=1", true);
|
||||
ScanReq.send();
|
||||
ScanReq.open("POST", "/channelscan.lua", true);
|
||||
ScanReq.setRequestHeader("Content-type","application/x-www-form-urlencoded");
|
||||
ScanReq.send("select=scan" + param + "&sitables=1&sort=1&restartdms=1");
|
||||
document.getElementById("scancount").firstChild.nodeValue = "\u00A0";
|
||||
document.getElementById("scantext").firstChild.nodeValue = "Scanning...";
|
||||
}
|
||||
@@ -237,15 +239,16 @@ function PollStatus()
|
||||
function DeleteScan()
|
||||
{
|
||||
DisableButtons(true);
|
||||
ScanReq.open("GET", "/channelscan.lua?select=delete", true);
|
||||
ScanReq.send();
|
||||
ScanReq.setRequestHeader("Content-type","application/x-www-form-urlencoded");
|
||||
ScanReq.send("select=delete");
|
||||
}
|
||||
|
||||
function RestoreScan()
|
||||
{
|
||||
DisableButtons(true);
|
||||
ScanReq.open("GET", "/channelscan.lua?select=restore", true);
|
||||
ScanReq.send();
|
||||
ScanReq.open("POST", "/channelscan.lua", true);
|
||||
ScanReq.setRequestHeader("Content-type","application/x-www-form-urlencoded");
|
||||
ScanReq.send("select=restore");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@@ -55,121 +55,164 @@ local function LoadTransponderList()
|
||||
return tl
|
||||
end
|
||||
|
||||
if method == "GET" then
|
||||
local filename = nil
|
||||
local contenttype = "application/json; charset=utf-8"
|
||||
local data = nil
|
||||
|
||||
local function GetCMD(s)
|
||||
local q,v
|
||||
local params = ""
|
||||
local cmd = ""
|
||||
for q,v in query:gmatch("(%a+)=([%w%.]+)") do
|
||||
for q,v in s:gmatch("(%a+)=([%w%.]+)") do
|
||||
if q == "select" then
|
||||
cmd = v
|
||||
else
|
||||
elseif q ~= "t" then
|
||||
params = params.." "..q.."="..v
|
||||
end
|
||||
end
|
||||
return cmd,params
|
||||
end
|
||||
|
||||
if cmd == "keys" then
|
||||
local tl = LoadTransponderList()
|
||||
if tl then
|
||||
local kl = { KeyList = { } }
|
||||
local s
|
||||
for _,s in ipairs(tl.SourceList) do
|
||||
table.insert(kl.KeyList, { Key=s.Key,Title=s.Title,DVBType=s.DVBType })
|
||||
end
|
||||
kl.KeyList[0] = #kl.KeyList
|
||||
local encode = newencoder()
|
||||
data = encode(kl)
|
||||
local function Keys()
|
||||
local data = nil
|
||||
local tl = LoadTransponderList()
|
||||
if tl then
|
||||
local kl = { KeyList = { } }
|
||||
local s
|
||||
for _,s in ipairs(tl.SourceList) do
|
||||
table.insert(kl.KeyList, { Key=s.Key,Title=s.Title,DVBType=s.DVBType })
|
||||
end
|
||||
elseif cmd == "scan" then
|
||||
local rc = os.execute("mkdir /tmp/doscan.lock")
|
||||
if rc ~= 0 then
|
||||
data = '{"status":"busy"}'
|
||||
else
|
||||
data = '{"status":"retry"}'
|
||||
local f = io.open("/tmp/doscan.msg","w+")
|
||||
if f then
|
||||
f:write("Scanning")
|
||||
f:close()
|
||||
end
|
||||
os.execute("/var/channels/doscan.lua "..params.." >/tmp/doscan.log 2>&1 &")
|
||||
end
|
||||
elseif cmd == "status" then
|
||||
local js = { }
|
||||
local f = io.open("/tmp/doscan.lock/doscan.msg")
|
||||
kl.KeyList[0] = #kl.KeyList
|
||||
local encode = newencoder()
|
||||
data = encode(kl)
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
local function Scan(params)
|
||||
local data = nil
|
||||
local rc = os.execute("mkdir /tmp/doscan.lock")
|
||||
if rc ~= 0 then
|
||||
data = '{"status":"busy"}'
|
||||
else
|
||||
data = '{"status":"retry"}'
|
||||
local f = io.open("/tmp/doscan.msg","w+")
|
||||
if f then
|
||||
f:write("Scanning")
|
||||
f:close()
|
||||
end
|
||||
os.execute("/var/channels/doscan.lua "..params.." >/tmp/doscan.log 2>&1 &")
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
local function Status()
|
||||
local data = nil
|
||||
local js = { }
|
||||
local f = io.open("/tmp/doscan.lock/doscan.msg")
|
||||
if f then
|
||||
js.status = "active"
|
||||
local m = f:read("*l")
|
||||
local count,msg = m:match("(%d+):(.*)")
|
||||
js.count = count
|
||||
js.msg = msg
|
||||
f:close()
|
||||
else
|
||||
f = io.open("/tmp/doscan.msg")
|
||||
if f then
|
||||
js.status = "active"
|
||||
local m = f:read("*l")
|
||||
local count,msg = m:match("(%d+):(.*)")
|
||||
js.count = count
|
||||
js.msg = msg
|
||||
if count and msg then
|
||||
js.count = count
|
||||
js.msg = msg
|
||||
js.status = "done"
|
||||
else
|
||||
if m == "Scanning" then
|
||||
js.status = "retry"
|
||||
else
|
||||
js.status = nil
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
else
|
||||
f = io.open("/tmp/doscan.msg")
|
||||
if f then
|
||||
local m = f:read("*l")
|
||||
local count,msg = m:match("(%d+):(.*)")
|
||||
if count and msg then
|
||||
js.count = count
|
||||
js.msg = msg
|
||||
js.status = "done"
|
||||
else
|
||||
if m == "Scanning" then
|
||||
js.status = "retry"
|
||||
else
|
||||
js.status = nil
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
else
|
||||
js.status = ""
|
||||
end
|
||||
end
|
||||
local encode = newencoder()
|
||||
data = encode(js)
|
||||
elseif cmd == "delete" then
|
||||
local rc = os.execute("mkdir /tmp/doscan.lock")
|
||||
if rc ~= 0 then
|
||||
data = '{"status":"busy"}'
|
||||
else
|
||||
data = '{"status":"deleted"}'
|
||||
os.execute("rm /config/ChannelList.json");
|
||||
os.execute("rm /tmp/doscan.msg");
|
||||
os.execute("rm -rf /tmp/doscan.lock");
|
||||
end
|
||||
elseif cmd == "restore" then
|
||||
local rc = os.execute("mkdir /tmp/doscan.lock")
|
||||
if rc ~= 0 then
|
||||
data = '{"status":"busy"}'
|
||||
else
|
||||
local rc = os.execute("mv /config/ChannelList.bak /config/ChannelList.json");
|
||||
if rc == 0 then
|
||||
data = '{"status":"restored", "count":1}'
|
||||
else
|
||||
data = '{"status":"restored", "count":0}'
|
||||
end
|
||||
os.execute("rm /tmp/doscan.msg");
|
||||
os.execute("rm -rf /tmp/doscan.lock");
|
||||
js.status = ""
|
||||
end
|
||||
end
|
||||
local encode = newencoder()
|
||||
data = encode(js)
|
||||
return data
|
||||
end
|
||||
|
||||
if data then
|
||||
http_print(proto.." 200" )
|
||||
http_print("Pragma: no-cache")
|
||||
http_print("Cache-Control: no-cache")
|
||||
http_print("Content-Type: "..contenttype)
|
||||
if filename then
|
||||
http_print('Content-Disposition: filename="'..filename..'"')
|
||||
end
|
||||
http_print(string.format("Content-Length: %d",#data))
|
||||
http_print()
|
||||
http_print(data)
|
||||
local function Delete()
|
||||
local data = nil
|
||||
local rc = os.execute("mkdir /tmp/doscan.lock")
|
||||
if rc ~= 0 then
|
||||
data = '{"status":"busy"}'
|
||||
else
|
||||
SendError("404","not found")
|
||||
data = '{"status":"deleted"}'
|
||||
os.execute("rm /config/ChannelList.json");
|
||||
os.execute("rm /tmp/doscan.msg");
|
||||
os.execute("rm -rf /tmp/doscan.lock");
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
local function Restore()
|
||||
local data = nil
|
||||
local rc = os.execute("mkdir /tmp/doscan.lock")
|
||||
if rc ~= 0 then
|
||||
data = '{"status":"busy"}'
|
||||
else
|
||||
local rc = os.execute("mv /config/ChannelList.bak /config/ChannelList.json");
|
||||
if rc == 0 then
|
||||
data = '{"status":"restored", "count":1}'
|
||||
else
|
||||
data = '{"status":"restored", "count":0}'
|
||||
end
|
||||
os.execute("rm /tmp/doscan.msg");
|
||||
os.execute("rm -rf /tmp/doscan.lock");
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
local filename = nil
|
||||
local contenttype = "application/json; charset=utf-8"
|
||||
local data = nil
|
||||
local cmd = ""
|
||||
local params
|
||||
|
||||
if method == "GET" then
|
||||
cmd,params = GetCMD(query)
|
||||
elseif method == "POST" and clength and ctype then
|
||||
if ctype:match("application/x%-www%-form%-urlencoded") then
|
||||
local query = io.read(tonumber(clength))
|
||||
query = string.gsub(query,"\r","")
|
||||
cmd,params = GetCMD(query)
|
||||
end
|
||||
else
|
||||
SendError("500","What")
|
||||
return
|
||||
end
|
||||
|
||||
if cmd == "keys" then
|
||||
data = Keys()
|
||||
elseif cmd == "scan" then
|
||||
data = Scan(params)
|
||||
elseif cmd == "status" then
|
||||
data = Status()
|
||||
elseif cmd == "delete" then
|
||||
data = Delete()
|
||||
elseif cmd == "restore" then
|
||||
data = Restore()
|
||||
end
|
||||
|
||||
if data then
|
||||
http_print(proto.." 200" )
|
||||
http_print("Pragma: no-cache")
|
||||
http_print("Cache-Control: no-cache")
|
||||
http_print("Content-Type: "..contenttype)
|
||||
if filename then
|
||||
http_print('Content-Disposition: filename="'..filename..'"')
|
||||
end
|
||||
http_print(string.format("Content-Length: %d",#data))
|
||||
http_print()
|
||||
http_print(data)
|
||||
else
|
||||
SendError("404","not found")
|
||||
end
|
||||
|
Reference in New Issue
Block a user