#!/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 = nil local isencrypted = false local hasepg = nil if line == "SERVICE" 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 pids = 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, Radio=isradio } if not hasepg then channel.NoEPG = true end 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 == "EIT" then if val:sub(2,2) == "1" then hasepg = true end 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,"Channels found") 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");