-- EPG Aggregator
-- Required Astra 5.62-rc8 or newer
--
-- Installation:
-- 1. Install Astra: https://cesbo.com/astra/quick-start/
-- 2. Save script into the file: /etc/astra/epg.lua
-- 3. Change options in the script:
-- 3.1. epg_file - full path to the file to save EPG
-- 3.2. epg_save_interval - save EPG into the file each 60 seconds
-- 3.3. epg_server_port - port to receive EPG from Astra
-- 3.4. epg_expire - expiration time. Channel will be excluded from EPG if has no updates more than 24 hours
-- 3.5. epg_stalker - if true, convert <sub-title/> to <desc/>
-- 4. Launch Astra: astra /etc/astra/epg.lua --daemon
-- 5. In the Stream options (on Astra that receives channels), set EPG Export option. Format: JSON and Destination: http://server-address:5000 (server-address - ip address of the server with this script, 5000 - is a port number defined in the epg_server_port)
--
epg_file = "/tmp/epg.xml"
epg_save_interval = 60
epg_server_port = 5000
epg_expire = 24 * 60 * 60
epg_stalker = false
--
epg_list = {}
function epg_save()
local channels = {}
local items = {}
local ctime = os.time()
for id, data in pairs(epg_list) do
if data.expire < ctime then
epg_list[id] = nil
else
table.insert(channels, { id = id, name = data.name })
for _, x in ipairs(data.items) do
table.insert(items, x)
end
end
end
table.sort(channels, function(a, b)
return a.id < b.id
end)
table.sort(items, function(a, b)
return a.start_ut < b.start_ut
end)
local result = epg_utils.format["xmltv"]({ channels = channels, items = items })
local fd = assert(io.open(epg_file, "w"))
fd:write(result.content)
fd:close()
end
timer({
interval = epg_save_interval,
callback = function()
epg_save()
end
})
function on_http_request(server, client, request)
if not request then
return nil
end
local data = json.decode(request.content)
if not data or not data.items then
server:abort(client, 400)
return nil
end
if data.name then
-- deprecated
data.channels = {{ id = data.name, name = data.name }}
for _,x in ipairs(data.items) do
x.channel = data.name
end
data.name = nil
end
if not data.channels then
server:abort(client, 400)
return nil
end
if epg_stalker then
for _,x in ipairs(data.items) do
x["desc"], x["subtitle"] = x["subtitle"], nil
end
end
local ch = data.channels[1]
epg_list[ch.id] = {
name = ch.name,
items = data.items,
expire = os.time() + epg_expire
}
server:send(client, {
code = 200,
headers = { "Connection: close" }
})
end
http_server({
port = epg_server_port,
route = {{"/", on_http_request}}
})
Comments