diff options
| -rw-r--r-- | catalogue.lua | 13 | ||||
| -rw-r--r-- | epg.lua | 5 | ||||
| -rw-r--r-- | main.lua | 1 | ||||
| -rw-r--r-- | rt.lua | 155 |
4 files changed, 129 insertions, 45 deletions
diff --git a/catalogue.lua b/catalogue.lua index 425dc17..7bd8eb0 100644 --- a/catalogue.lua +++ b/catalogue.lua @@ -70,6 +70,19 @@ function mt:add(entry) return entry end +function mt:prune_children(entry, is_child) + for _, v in ipairs(entry.children) do + self.data[v.id] = nil + if v.children then + self:prune_children(v, true) + end + end + + if not is_child then + entry.children = {} + end +end + function mt:path_to_root(entry) local path = {} @@ -8,13 +8,16 @@ function epg.new() return setmetatable({channels = {}}, mt) end +function mt:clear() + self.channels = {} +end + -- local (non-DST) offset from UTC local tz_offset do local t = os.time() tz_offset = os.time(os.date('*t', t)) - os.time(os.date('!*t', t)) end - local function parse_time(str) local y, m, d, hh, mm, ss, zsign, zh, zm = str:match( '(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d) ([+-])(%d%d)(%d%d)') @@ -130,6 +130,7 @@ input.define_mapping('MENU', { ['BS'] = {rt.prev_menu}, ['/'] = {rt.start_search}, ['Ctrl+s'] = {rt.toggle_menu_sort}, + ['Ctrl+r'] = {rt.reload_option}, ['Ctrl+R'] = {rt.reload_data}, ['ENTER'] = {rt.select_option}, @@ -39,46 +39,58 @@ local function series_children(series) cache_miss_status_msg('Loading series info...'))) end -local function catalogue_add_section(src_id, sect, cats, elems) +local function catalogue_add_section_root(src_id, section, name) ctx.catalogue:add({ src_id = src_id, - section = sect.id, + section = section, type = 'group', group_type = 'cat', - id = src_id .. ':' .. sect.id .. ':cat:0', + id = src_id .. ':' .. section .. ':cat:0', parent_id = 'root', - name = sect.name, + name = name, }) +end - -- currently, this will not correctly handle subcategories which come - -- before their parent category - for _, v in ipairs(cats) do - ctx.catalogue:add({ - src_id = src_id, - section = sect.id, - type = 'group', - group_type = 'cat', - id = src_id .. ':' .. sect.id .. ':cat:' .. - v.category_id, - parent_id = src_id .. ':' .. sect.id .. ':cat:' .. - v.parent_id, - name = util.strip(v.category_name), - }) +local function catalogue_add_section_data(src_id, section, cats, elems) + local pending = cats + local final = false + while #pending > 0 do + local skipped = {} + for _, v in ipairs(pending) do + local parent_id = src_id .. ':' .. section .. + ':cat:' .. v.parent_id + if final or ctx.catalogue:get(parent_id) then + ctx.catalogue:add({ + src_id = src_id, + section = section, + type = 'group', + group_type = 'cat', + id = src_id .. ':' .. section .. + ':cat:' .. v.category_id, + parent_id = parent_id, + name = util.strip(v.category_name), + }) + else + skipped[#skipped+1] = v + end + end + final = #pending == #skipped + pending = skipped end for _, v in ipairs(elems) do local vv = { src_id = src_id, - section = sect.id, - parent_id = src_id .. ':' .. sect.id .. ':cat:' .. + section = section, + parent_id = src_id .. ':' .. section .. ':cat:' .. v.category_id, name = util.strip(v.name), } - if sect.type == 'series' then + if section == 'series' then vv.type = 'group' vv.group_type = 'series' - vv.id = src_id .. ':' .. sect.id .. ':series:' .. + vv.id = src_id .. ':' .. section .. ':series:' .. v.series_id vv.series_id = v.series_id vv.img_url = util.strip_ne(v.cover) @@ -87,7 +99,7 @@ local function catalogue_add_section(src_id, sect, cats, elems) vv.children_f = series_children else vv.type = 'stream' - vv.id = src_id .. ':' .. sect.id .. ':stream:' .. + vv.id = src_id .. ':' .. section .. ':stream:' .. v.stream_id vv.stream_type = v.stream_type vv.stream_id = v.stream_id @@ -99,15 +111,37 @@ local function catalogue_add_section(src_id, sect, cats, elems) end end -function rt.load_data_src(src, force) - local pre = src.name and src.name .. ' | ' or '' - local arr = { - {id = 'live', name = pre .. 'Channels', type = 'live'}, - {id = 'movie', name = pre .. 'Movies', type = 'vod'}, - {id = 'series', name = pre .. 'Series', type = 'series'}, - } +local SECTION_LABELS = { + live = 'Channels', + movie = 'Movies', + series = 'Series', +} + +local SECTION_XC_FUNCS = { + live = {'get_live_categories', 'get_live_streams'}, + movie = {'get_vod_categories', 'get_vod_streams'}, + series = {'get_series_categories', 'get_series'}, +} - local base_str = 'Loading catalogue' +local function load_data_src_section(src, section, call_opts, prune) + local cat_f, elem_f = unpack(SECTION_XC_FUNCS[section]) + local cats = src.xc:with_opts(cat_f, call_opts) + local elems = src.xc:with_opts(elem_f, call_opts) + if not cats or not elems then + return + end + + if prune then + ctx.catalogue:prune_children(ctx.catalogue:get( + src.id .. ':' .. section .. ':cat:0')) + end + + catalogue_add_section_data(src.id, section, cats, elems) +end + +local function load_data_src(src, force) + local base_str = src.name and 'Loading catalogue » ' .. src.name or + 'Loading catalogue' local sect_str local disp_str local call_opts = { @@ -127,18 +161,18 @@ function rt.load_data_src(src, force) end end, } - for _, sect in ipairs(arr) do - sect_str = base_str .. ' » ' .. sect.name - local cats = src.xc:with_opts( - 'get_' .. sect.type .. '_categories', call_opts) - local elems = src.xc:with_opts( - sect.type == 'series' and 'get_series' or - ('get_' .. sect.type .. '_streams'), - call_opts) - catalogue_add_section(src.id, sect, cats, elems) - end - - osd:set_status('Loading EPG...') + for _, section in ipairs({'live', 'movie', 'series'}) do + local label = SECTION_LABELS[section] + sect_str = base_str .. (src.name and ' | ' or ' » ') .. label + catalogue_add_section_root( + src.id, section, + src.name and src.name .. ' | ' .. label or label) + load_data_src_section(src, section, call_opts) + end + + osd:set_status( + src.name and 'Loading EPG » ' .. src.name .. '...' or + 'Loading EPG...') osd:redraw(state) src.epg:load_xc_data( src.xc:with_opts('get_epg', {force = not not force})) @@ -171,13 +205,45 @@ function rt.load_data(force) }) for _, v in ipairs(ctx.src_order) do - rt.load_data_src(ctx.src[v], force) + load_data_src(ctx.src[v], force) end local t = util.read_json_file(config.favourites_file) state.favourites = t.favourites or {} end +function rt.reload_option() + if state.depth > 1 then + osd:flash_error('Can only reload data from root menu') + return + end + + local menu = state:menu() + local opt = menu.options[menu.cursor] + if not opt.src_id or not opt.section then + osd:flash_error('Selected option is not reloadable') + return + end + + osd:set_status('Loading catalogue » ' .. opt.name .. '...') + osd:redraw(state) + local src = ctx.src[opt.src_id] + load_data_src_section(src, opt.section, {force = true}, true) + rawset(opt, 'info', nil) + if opt.section == 'live' then + osd:set_status( + src.name and 'Loading EPG » ' .. src.name .. '...' or + 'Loading EPG...') + osd:redraw(state) + local data = src.xc:with_opts('get_epg', {force = true}) + if data then + src.epg:clear() + src.epg:load_xc_data(data) + end + end + osd:set_status() +end + local function save_favourites() util.write_json_file( config.favourites_file, {favourites = state.favourites}) @@ -780,6 +846,7 @@ function rt.reload_data() rt.load_data(true) state.depth = 0 rt.push_group_menu(ctx.catalogue:get('root')) + osd:dirty() end function rt.set_osc_visibility(osd_hidden) |
