1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
-- Copyright 2025 David Vazgenovich Shakaryan
local util = require('util')
local catalogue = {}
local mt = {}
mt.__index = mt
function catalogue.new()
o = setmetatable({data = {}}, mt)
o:add({
type = 'group',
id = 'root',
})
o:add({
type = 'group',
id = 'favourites',
parent_id = 'root',
name = 'Favourites',
lazy = true, -- prevent infinite recursion on search
})
return o
end
function mt:get(id)
return self.data[id]
end
function mt:add(entry)
self.data[entry.id] = entry
if entry.type == 'group' then
entry.children = {}
end
if not entry.parent_id then
return
end
-- dump any entries referencing nonexistent categories into a single
-- catchall category
if not self.data[entry.parent_id] then
entry.parent_id = entry.section .. ':category:catchall'
if not self.data[entry.parent_id] then
self:add({
section = entry.section,
type = 'group',
group_type = 'category',
id = entry.parent_id,
parent_id = entry.section .. ':category:0',
-- non-ascii symbol to sort near end
name = '🞷CATCHALL🞷',
})
end
end
local parent_children = self.data[entry.parent_id].children
parent_children[#parent_children+1] = entry
end
function mt:load_xc_section(section)
self:add({
section = section.id,
type = 'group',
group_type = 'category',
id = section.id .. ':category:0',
parent_id = 'root',
name = section.name,
})
-- currently, this will not correctly handle subcategories which come
-- before their parent category
for _, v in ipairs(section.categories) do
self:add({
section = section.id,
type = 'group',
group_type = 'category',
id = section.id .. ':category:' .. v.category_id,
parent_id = section.id .. ':category:' .. v.parent_id,
name = util.strip(v.category_name),
})
end
for _, v in ipairs(section.elements) do
local vv = {
section = section.id,
parent_id = section.id .. ':category:' .. v.category_id,
name = util.strip(v.name),
}
if section.type == 'series' then
vv.type = 'group'
vv.group_type = 'series'
vv.id = section.id .. ':series:' .. v.series_id
vv.series_id = v.series_id
vv.image = v.cover
vv.lazy = true -- avoid API calls on search
else
vv.type = 'stream'
vv.id = section.id .. ':stream:' .. v.stream_id
vv.stream_type = v.stream_type
vv.stream_id = v.stream_id
vv.image = v.stream_icon
vv.epg_channel_id = v.epg_channel_id
end
self:add(vv)
end
end
function mt:load_xc_data(sections)
for _, v in ipairs(sections) do
self:load_xc_section(v)
end
end
return catalogue
|