1
0
mirror of https://github.com/DigitalDevices/octonet.git synced 2023-10-10 13:36:52 +02:00
octonet/octoserve/var/channels/doscan.lua
mvoelkel e65fb9aaab 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.
2016-01-24 12:58:42 +01:00

365 lines
11 KiB
Lua
Executable File

#!/usr/bin/lua
--
local newdecoder = require("lunajson.decoder")
local newencoder = require("lunajson.encoder")
local function GetIPAddr()
local myip = nil
local ifconfig = io.popen("ifconfig eth0")
if ifconfig then
local eth0 = ifconfig:read("*a")
ifconfig:close()
myip = string.match(eth0,"inet addr%:(%d+%.%d+%.%d+%.%d+)")
end
return myip
end
local function LoadTransponderList(infile)
local tl = nil
local f = nil
if infile then
f = io.open(infile,"r")
else
f = io.open("/config/TransponderList.json","r")
if not f then
f = io.open("/var/channels/TransponderList.json","r")
end
end
if f then
local t = f:read("*a")
f:close()
local decode = newdecoder()
tl = decode(t)
end
return tl
end
local function GetGroup(ChannelList,Title)
local Group
for _,c in ipairs(ChannelList.GroupList) do
if c.Title == Title then
Group = c
end
end
if not Group then
Group = { Title=Title, ChannelList = { } }
table.insert(ChannelList.GroupList,Group)
end
return Group
end
local function CompareTitle(a,b)
if a.Order then
if b.Order then
if a.Order == b.Order then
return a.Title < b.Title
else
return a.Order < b.Order
end
else
return true
end
elseif b.Order then
return false
end
return a.Title < b.Title
end
local function Report(count,Title)
local f = io.open("/tmp/doscan.lock/doscan.tmp","w+")
if f then
f:write(count..":"..Title)
f:close()
os.execute("mv /tmp/doscan.lock/doscan.tmp /tmp/doscan.lock/doscan.msg")
end
end
local keys = {}
local include_radio = 1
local include_encrypted = 0
local infile = nil
local outfile = "/config/ChannelList.json"
local ipAddr = nil
local sort = nil
local include_sitables = nil
local restart_dms = nil
local a
for _,a in ipairs(arg) do
local par,val = a:match("(%a+)=(.+)")
if par == "key" then
local key,src = val:match("(%w+)%.(%d+)")
if key then
keys[key] = tonumber(src)
else
keys[val] = 1
end
elseif par == "radio" then
include_radio = tonumber(val)
elseif par == "enc" then
include_encrypted = tonumber(val)
elseif par == "sort" then
sort = val
elseif par == "sitables" then
include_sitables = val
elseif par == "restartdms" then
restart_dms = val
elseif par == "in" then
infile = val
elseif par == "out" then
outfile = val
elseif par == "ip" then
ipAddr = val
end
end
if not ipAddr then
ipAddr = GetIPAddr()
end
local tl = LoadTransponderList(infile)
local CIMappings = {}
if tl.CIMapList then
local CIMap
local ID
for _,CIMap in ipairs(tl.CIMapList) do
for _,ID in ipairs(CIMap.CIMappings) do
CIMappings[ID] = CIMap
end
end
end
local ChannelOverwrites = {}
if tl.ChannelOverwriteList then
local ChannelOverwrite
for _,ChannelOverwrite in ipairs(tl.ChannelOverwriteList) do
ChannelOverwrites[ChannelOverwrite.ID] = ChannelOverwrite
end
end
local ChannelList = {}
ChannelList.GroupList = {}
if tl.GroupList then
local Group
local Order
for _,Group in ipairs(tl.GroupList) do
local g = GetGroup(ChannelList,Group.Title)
if Group.Order then
g.Order = Group.Order
end
end
end
local Max = 999999
local Count = 0
local ChannelCount = 0
Report(ChannelCount,"*")
if tl.SourceList then
local Source
for _,Source in ipairs(tl.SourceList) do
if keys[Source.Key] then
Report(ChannelCount,Source.Title)
print("Scanning: "..Source.Title)
local SourceOptions = ""
if Source.DVBType == "S" then
SourceOptions = '--src='..keys[Source.Key].." "
end
for _,Transponder in ipairs(Source.TransponderList) do
Count = Count + 1
if Count > Max then
break
end
local Params = ""
local p,v
for p,v in Transponder.Request:gmatch("(%a+)=([%w%.]+)") do
if p == "freq" then
Params = Params .. " --freq="..v
elseif p == "pol" then
Params = Params .. " --pol="..v
elseif p == "msys" then
Params = Params .. " --msys="..v
elseif p == "sr" then
Params = Params .. " --sr="..v
elseif p == "mtype" then
Params = Params .. " --mtype="..v
end
end
local Options = SourceOptions
if Transponder.UseNIT then
Options = SourceOptions.."--use_nit "
end
print("--------------------------------------------------------------")
print('octoscan '..Options..Params..' '..ipAddr)
local octoscan = io.popen('octoscan '..Options..Params..' '..ipAddr,"r")
if octoscan then
while true do
local line = octoscan:read("*l")
if not line then
break
end
print(line)
local pname = "?"
local sname = "?"
local onid = 0
local tsid = 0
local sid = 0
local pids = ""
local tracks= { }
local isradio = false
local isencrypted = false
if line == "BEGIN" then
while true do
line = octoscan:read("*l")
if not line then
break
end
print(line)
if line == "END" then
local all_pids = "0"
if include_sitables then
--~ if isencrypted then
--~ all_pids = all_pids..",1"
--~ end
all_pids = all_pids..",16,17,18,20"
end
local cireq = ""
local ID = string.format("%s:%d:%d:%d",Source.Key,onid,tsid,sid)
if isencrypted then
local CIMap = CIMappings[ID]
if CIMap then
local pmt = pids:match("(%d+),?")
if pmt then
cireq = "&x_ci="..CIMap.Slot.."&x_pmt="..pmt.."."..sid
isencrypted = false
end
end
end
if pname == "" then
pname = Source.Title
end
local gname = pname
if isradio then
gname = "Radio - "..gname
end
local Order = none
local ChannelOverwrite = ChannelOverwrites[ID]
if ChannelOverwrite then
Order = ChannelOverwrite.Order
if ChannelOverwrite.Group then
gname = ChannelOverwrite.Group
end
if ChannelOverwrite.pids then
gname = ChannelOverwrite.pids
end
if ChannelOverwrite.Title then
sname = ChannelOverwrite.Title
end
end
if #pids > 0 then
all_pids = all_pids..","..pids
end
local channel = { Title=sname,
Request = '?'..Request..cireq.."&pids="..all_pids,
Tracks=tracks,
ID=ID, Order=Order }
if ((not isradio) or (include_radio > 0)) and ((not isencrypted) or (include_encrypted > 0)) then
local group = GetGroup(ChannelList,gname)
if group then
table.insert(group.ChannelList,channel)
ChannelCount = ChannelCount + 1
Report(ChannelCount,sname)
end
end
break
end
local par,val = line:match("^ (%a+):(.*)")
if par == "RADIO" then
isradio = true
elseif par == "PNAME" then
pname = val
elseif par == "SNAME" then
sname = val
elseif par == "ONID" then
onid = tonumber(val)
elseif par == "TSID" then
tsid = tonumber(val)
elseif par == "SID" then
sid = tonumber(val)
elseif par == "PIDS" then
pids = val
elseif par == "APIDS" then
local track
for track in val:gmatch("%d+") do
table.insert(tracks,tonumber(track))
end
tracks[0] = #tracks
elseif par == "ENC" then
isencrypted = true
end
end
elseif line:sub(1,5) == "TUNE:" then
Request = line:sub(6)
end
end
octoscan:close()
end
end
end
end
for _,group in ipairs(ChannelList.GroupList) do
if sort then
table.sort(group.ChannelList,CompareTitle)
end
for _,channel in ipairs(group.ChannelList) do
channel.Order = nil
end
group.ChannelList[0] = #group.ChannelList
end
if sort then
table.sort(ChannelList.GroupList,CompareTitle)
end
for _,group in ipairs(ChannelList.GroupList) do
group.Order = nil
end
ChannelList.GroupList[0] = #ChannelList.GroupList
local encode = newencoder()
cl = encode(ChannelList)
if outfile == "/config/ChannelList.json" then
os.execute("mv /config/ChannelList.json /config/ChannelList.bak")
end
if cl then
local f = io.open(outfile,"w+")
if f then
f:write(cl)
f:close()
end
end
end
Report(ChannelCount,"Done")
os.execute("mv /tmp/doscan.lock/doscan.msg /tmp/doscan.msg")
if restart_dms then
os.execute("/etc/init.d/S92dms restart")
end
os.execute("rm -rf /tmp/doscan.lock");