summaryrefslogtreecommitdiff
path: root/main.lua
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2025-05-21 04:49:30 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2025-05-21 04:49:30 -0700
commit48fcfe19baae31c2e1635c911f7383d6d58d2aa1 (patch)
tree34d88c77352c151378fd47234d25aa59df2e9dbf /main.lua
parent29e4c12898b232ec7c3af563f27aa1f5638fe0da (diff)
downloadmpv-iptv-menu-48fcfe19baae31c2e1635c911f7383d6d58d2aa1.tar.gz
mpv-iptv-menu-48fcfe19baae31c2e1635c911f7383d6d58d2aa1.tar.xz
split util functions to new fileHEADmaster
Diffstat (limited to 'main.lua')
-rw-r--r--main.lua143
1 files changed, 38 insertions, 105 deletions
diff --git a/main.lua b/main.lua
index 3b5c3d9..acb7646 100644
--- a/main.lua
+++ b/main.lua
@@ -1,9 +1,10 @@
-- Copyright 2025 David Vazgenovich Shakaryan
+local util = require('util')
local _downloader = require('downloader')
local _xc = require('xc')
-local utils = require('mp.utils')
+local mp_utils = require('mp.utils')
-- font size is in units of osd height, which is scaled to 720
local font_size = 20
@@ -27,6 +28,7 @@ local colours = {
local script_name = mp.get_script_name()
local script_dir = mp.get_script_directory()
+
local downloader = _downloader.new()
local xc = _xc.new({
server = mp.get_opt('iptv_menu.xc_server'),
@@ -59,88 +61,12 @@ local depth = 0
local menus = {}
local key_bindings = {}
-local function copy_table(t)
- local u = {}
- for k, v in pairs(t) do
- u[k] = v
- end
- return u
-end
-
-local function reverse(t)
- for i = 1, #t/2 do
- t[i], t[#t-i+1] = t[#t-i+1], t[i]
- end
-end
-
-local function strip(str)
- return (str:gsub('^%s*(.-)%s*$', '%1'))
-end
-
-local function utf8_seek(str, pos, n)
- local step = n > 0 and 1 or -1
- local test = n > 0
- and function() return pos > #str end
- or function() return pos <= 1 end
-
- while n ~= 0 and not test() do
- repeat
- pos = pos + step
- until test() or bit.band(str:byte(pos), 0xc0) ~= 0x80
-
- n = n - step
- end
-
- return pos
-end
-
--- returns table of strings wrapped at width. spaces are not removed, resulting
--- in width-1 visible chars; newlines and end of string are handled similarly
--- for consistency. words longer than width are not broken.
-local function wrap(str, width, cont_width)
- local t = {}
- local start, stop = 0, 0
- while stop < #str do
- local i = str:find('[ \n]', stop + 1) or #str + 1
- if i - start >= width then
- t[#t+1] = str:sub(start, stop)
- start = stop + 1
- if cont_width then
- width = cont_width
- end
- end
- stop = i
- if str:byte(stop) == 10 or stop >= #str then
- t[#t+1] = str:sub(start, stop - 1) .. ' '
- start = stop + 1
- end
- end
-
- return t
-end
-
-local function read_json_file(fn)
- local f = io.open(script_dir .. '/' .. fn, 'r')
- if not f then
- return {}
- end
- local json = f:read('*all')
- f:close()
- return utils.parse_json(json)
-end
-
-local function write_json_file(fn, data)
- local f = io.open(script_dir .. '/' .. fn, 'w')
- f:write(utils.format_json(data), '\n')
- f:close()
-end
-
local update_osd
local function get_image_path(url, dl)
local path = 'img/' .. url:gsub('%W', '_')
- local f = utils.file_info(path)
+ local f = mp_utils.file_info(path)
if f then
return path
end
@@ -198,18 +124,20 @@ local function load_section(section, name)
name=name,
})
- local tmp = read_json_file(section .. '_categories.json')
+ local tmp = util.read_json_file(
+ mp_utils.join_path(script_dir, section .. '_categories.json'))
for _, v in ipairs(tmp) do
v.section = section
v.type = 'group'
v.group_type = 'category'
v.id = section .. ':category:' .. v.category_id
v.parent_id = section .. ':category:' .. v.parent_id
- v.name = strip(v.category_name)
+ v.name = util.strip(v.category_name)
add_object(v)
end
- tmp = read_json_file(section .. '_streams.json')
+ local tmp = util.read_json_file(
+ mp_utils.join_path(script_dir, section .. '_streams.json'))
for _, v in ipairs(tmp) do
v.section = section
if v.series_id then
@@ -222,7 +150,7 @@ local function load_section(section, name)
v.id = section .. ':stream:' .. v.stream_id
end
v.parent_id = section .. ':category:' .. v.category_id
- v.name = strip(v.name)
+ v.name = util.strip(v.name)
add_object(v)
end
end
@@ -243,7 +171,8 @@ local function epg_parse_time(str)
end
local function load_epg()
- local tmp = read_json_file('epg.json')
+ local tmp = util.read_json_file(
+ mp_utils.join_path(script_dir, 'epg.json'))
for _, v in ipairs(tmp) do
local ch = v.channel:lower()
local prog = {
@@ -285,7 +214,8 @@ local function load_data()
load_section('series', 'Series')
load_epg()
- favourites = read_json_file('favourites.json')
+ favourites = util.read_json_file(
+ mp_utils.join_path(script_dir, 'favourites.json'))
-- json loading/dumping breaks when the table is empty, so we need a
-- dummy value to prevent that
if next(favourites) == nil then
@@ -440,7 +370,7 @@ local function update_osd_image(path, menu_res)
disp = true
else
- local f = utils.file_info(path)
+ local f = mp_utils.file_info(path)
if f then
local cmd = 'magick \'' .. path .. '\'' ..
' -background none' ..
@@ -638,12 +568,12 @@ local function toggle_menu_sort()
if not menu.sorted_options then
menu.orig_options = menu.options
- menu.sorted_options = copy_table(menu.options)
+ menu.sorted_options = util.copy_table(menu.options)
sort_options(menu.sorted_options)
if menu.search_options then
menu.orig_search_options = menu.search_options
- menu.sorted_search_options = copy_table(
+ menu.sorted_search_options = util.copy_table(
menu.search_options)
sort_options(menu.sorted_search_options)
end
@@ -718,14 +648,14 @@ local function favourites_group_menu_options(group)
path[#path+1] = curr
end
- obj = copy_table(obj)
+ obj = util.copy_table(obj)
add_programme(obj, time)
local c = group_count(obj)
if c then
obj.info = tostring(c)
end
if #path > 0 and curr.parent_id == 'root' then
- reverse(path)
+ util.reverse(path)
obj.path = path
end
options[#options+1] = obj
@@ -755,7 +685,7 @@ local function series_group_menu_options(series)
if info.episodes and info.episodes[season_num] then
for i, episode in pairs(info.episodes[season_num]) do
episodes[#episodes+1] = {
- name=strip(episode.title),
+ name=util.strip(episode.title),
type='stream',
stream_type='series',
id=series.section .. ':stream:' ..
@@ -774,7 +704,7 @@ local function series_group_menu_options(series)
group_type='season',
id=series.section .. 'series:season:' .. season.id,
children=episodes,
- name=strip(season.name),
+ name=util.strip(season.name),
info=count,
}
end
@@ -794,7 +724,7 @@ local function group_menu_options(group)
local options = {}
local time = os.time()
for i, v in ipairs(group.children) do
- v = copy_table(v)
+ v = util.copy_table(v)
add_programme(v, time)
local c = group_count(v)
if c then
@@ -865,7 +795,8 @@ local function favourite_option()
favourites[id] = true
end
- write_json_file('favourites.json', favourites)
+ util.write_json_file(mp_utils.join_path(script_dir, 'favourites.json'),
+ favourites)
update_osd()
end
@@ -930,7 +861,7 @@ local function open_epg_programme(prog)
if prog.desc then
options[#options+1] = {name=' '}
- for _, v in ipairs(wrap(prog.desc, 80)) do
+ for _, v in ipairs(util.wrap(prog.desc, 80)) do
options[#options+1] = {name=v}
end
end
@@ -981,7 +912,7 @@ local function add_info_field(dst, k, v, fmt)
return
end
- local str = strip(tostring(v))
+ local str = util.strip(tostring(v))
if fmt then
str = string.format(fmt, str)
end
@@ -990,7 +921,7 @@ local function add_info_field(dst, k, v, fmt)
end
-- continuation lines are 4 chars shorter and indented with 2 em spaces
- for i, v in ipairs(wrap(str, 80, 76)) do
+ for i, v in ipairs(util.wrap(str, 80, 76)) do
if i > 1 then
v = '\226\128\131\226\128\131' .. v
end
@@ -1013,7 +944,7 @@ local function open_option_movie_info(opt)
if info.description then
options[#options+1] = {name=' '}
- for _, v in ipairs(wrap(info.description, 80)) do
+ for _, v in ipairs(util.wrap(info.description, 80)) do
options[#options+1] = {name=v}
end
end
@@ -1112,13 +1043,13 @@ local function search_menu_options_build(options, t, path)
t[v.type] = {}
end
- local v = copy_table(v)
+ local v = util.copy_table(v)
v.path = path
t[v.type][#t[v.type]+1] = v
-- contents of lazy-loaded groups should not be searchable
if v.type == 'group' and not v.lazy then
- local path = copy_table(path)
+ local path = util.copy_table(path)
path[#path+1] = v
search_menu_options_build(
group_menu_options(v), t, path)
@@ -1173,7 +1104,7 @@ local function update_search_matches()
end
if #matches > 0 then
- local t = copy_table(v)
+ local t = util.copy_table(v)
t.matches = matches
options[#options+1] = t
end
@@ -1201,7 +1132,7 @@ local function search_input_bs()
return
end
- local pos = utf8_seek(menu.search_text, menu.search_cursor, -1)
+ local pos = util.utf8_seek(menu.search_text, menu.search_cursor, -1)
menu.search_text = menu.search_text:sub(1, pos - 1) ..
menu.search_text:sub(menu.search_cursor)
menu.search_cursor = pos
@@ -1215,8 +1146,8 @@ local function search_input_del()
end
menu.search_text = menu.search_text:sub(1, menu.search_cursor - 1) ..
- menu.search_text:sub(
- utf8_seek(menu.search_text, menu.search_cursor, 1))
+ menu.search_text:sub(util.utf8_seek(
+ menu.search_text, menu.search_cursor, 1))
update_search_matches()
end
@@ -1233,12 +1164,14 @@ end
local function search_cursor_left()
local menu = menus[depth]
- set_search_cursor(utf8_seek(menu.search_text, menu.search_cursor, -1))
+ set_search_cursor(util.utf8_seek(
+ menu.search_text, menu.search_cursor, -1))
end
local function search_cursor_right()
local menu = menus[depth]
- set_search_cursor(utf8_seek(menu.search_text, menu.search_cursor, 1))
+ set_search_cursor(util.utf8_seek(
+ menu.search_text, menu.search_cursor, 1))
end
local function search_cursor_start()