summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--downloader.lua55
-rw-r--r--iptv-menu-dl.lua48
-rw-r--r--main.lua27
3 files changed, 68 insertions, 62 deletions
diff --git a/downloader.lua b/downloader.lua
new file mode 100644
index 0000000..67fb675
--- /dev/null
+++ b/downloader.lua
@@ -0,0 +1,55 @@
+-- Copyright 2025 David Vazgenovich Shakaryan
+
+local utils = require('mp.utils')
+
+local downloader = {}
+local mt = {}
+mt.__index = mt
+
+function downloader.new()
+ return setmetatable({
+ pending = {},
+ running = false,
+ }, mt)
+end
+
+function mt:exec(url, file, cb)
+ if utils.file_info(file) then
+ self:exec_next()
+ return
+ end
+
+ local cmd = {'curl', '-sSfLo', file, url}
+ print('exec: ' .. utils.to_string(cmd))
+
+ self.running = true
+ mp.command_native_async({
+ name = 'subprocess',
+ args = cmd,
+ playback_only = false,
+ }, function(success, res)
+ self.running = false
+ self:exec_next()
+ if cb and success and res.status == 0 then
+ cb(url, file)
+ end
+ end)
+end
+
+function mt:exec_next()
+ if #self.pending > 0 then
+ self:exec(unpack(table.remove(self.pending)))
+ end
+end
+
+-- more recently requested downloads are executed first, as they are more
+-- likely to be used for the current display state
+function mt:schedule(...)
+ if self.running then
+ self.pending[#self.pending+1] = {...}
+ else
+ self:exec(...)
+ end
+end
+
+return downloader
diff --git a/iptv-menu-dl.lua b/iptv-menu-dl.lua
deleted file mode 100644
index a207c91..0000000
--- a/iptv-menu-dl.lua
+++ /dev/null
@@ -1,48 +0,0 @@
--- Copyright 2025 David Vazgenovich Shakaryan
-
-local utils = require('mp.utils')
-
-local queue = {}
-
-function download(target, name, url, path)
- if utils.file_info(path) then
- return
- end
-
- local cmd = 'curl -sSfLo \'' .. path .. '\'' .. ' \'' .. url .. '\''
- print('exec: ' .. cmd)
- local ret = os.execute(cmd)
-
- if ret == 0 then
- mp.commandv('script-message-to', target, name, url, path)
- end
-end
-
-function process_next()
- download(unpack(table.remove(queue)))
-
- if #queue > 0 then
- mp.add_timeout(0, process_next)
- end
-end
-
-mp.register_script_message('download-file', function(...)
- queue[#queue+1] = {...}
-
- -- we want the ability for a later request to be downloaded before
- -- earlier ones, e.g., to prioritise the image for the current menu.
- --
- -- using a small timeout between receiving a message and processing it
- -- allows for multiple pending messages to be received before any are
- -- processed. however, immediately scheduling a timer for each request
- -- does not work, as all elapsed timeouts are executed before any new
- -- messages are received.
- --
- -- the workaround is to schedule a timeout only when adding to an empty
- -- queue and have each callback schedule an additional timeout if the
- -- queue is not empty after completion. this effectively results in new
- -- messages being received after each download.
- if #queue == 1 then
- mp.add_timeout(0, process_next)
- end
-end)
diff --git a/main.lua b/main.lua
index 1d2d252..88e15bc 100644
--- a/main.lua
+++ b/main.lua
@@ -1,6 +1,7 @@
-- Copyright 2025 David Vazgenovich Shakaryan
-local xclib = require('xc')
+local _downloader = require('downloader')
+local _xc = require('xc')
local utils = require('mp.utils')
@@ -26,7 +27,8 @@ local colours = {
local script_name = mp.get_script_name()
local script_dir = mp.get_script_directory()
-local xc = xclib.new({
+local downloader = _downloader.new()
+local xc = _xc.new({
server = mp.get_opt('iptv_menu.xc_server'),
user = mp.get_opt('iptv_menu.xc_user'),
pass = mp.get_opt('iptv_menu.xc_pass'),
@@ -133,6 +135,8 @@ local function write_json_file(fn, data)
f:close()
end
+local update_osd
+
local function get_image_path(url, dl)
local path = 'img/' .. url:gsub('%W', '_')
@@ -142,10 +146,12 @@ local function get_image_path(url, dl)
end
if dl then
- mp.commandv('script-message-to',
- 'iptv_menu_dl', 'download-file',
- script_name, 'downloaded-image', -- callback
- url, path)
+ downloader:schedule(url, path, function(_, file)
+ if osd_img and file == osd_img.path then
+ update_osd()
+ end
+ end)
+
return path
end
end
@@ -480,7 +486,7 @@ local function remove_osd_image()
osd_img = nil
end
-local function update_osd()
+function update_osd()
local out = {}
if depth > 1 then
@@ -1366,12 +1372,6 @@ local function toggle_menu()
end
end
-mp.register_script_message('downloaded-image', function(url, path)
- if osd_img and path == osd_img.path then
- update_osd()
- end
-end)
-
mp.observe_property('osd-dimensions', 'native', function(_, val)
osd_width = val.w
osd_height = val.h
@@ -1394,4 +1394,3 @@ mp.add_forced_key_binding('TAB', 'toggle-menu', toggle_menu)
bind_menu_keys()
load_data()
push_group_menu(objects['root'])
-mp.commandv('load-script', script_dir .. '/iptv-menu-dl.lua')