update
This commit is contained in:
104
MPV/LUA/main.lua
104
MPV/LUA/main.lua
@@ -4,7 +4,7 @@ local msg = require 'mp.msg'
|
||||
|
||||
local M = {}
|
||||
|
||||
local MEDEIA_LUA_VERSION = '2026-03-21.1'
|
||||
local MEDEIA_LUA_VERSION = '2026-03-21.3'
|
||||
|
||||
-- Expose a tiny breadcrumb for debugging which script version is loaded.
|
||||
pcall(mp.set_property, 'user-data/medeia-lua-version', MEDEIA_LUA_VERSION)
|
||||
@@ -748,6 +748,7 @@ local _current_url_for_web_actions
|
||||
local _store_status_hint_for_url
|
||||
local _refresh_current_store_url_status
|
||||
local _skip_next_store_check_url = ''
|
||||
local _pick_folder_windows
|
||||
|
||||
local function _normalize_store_name(store)
|
||||
store = trim(tostring(store or ''))
|
||||
@@ -755,6 +756,22 @@ local function _normalize_store_name(store)
|
||||
return trim(store)
|
||||
end
|
||||
|
||||
local function _is_cached_store_name(store)
|
||||
local needle = _normalize_store_name(store)
|
||||
if needle == '' then
|
||||
return false
|
||||
end
|
||||
if type(_cached_store_names) ~= 'table' then
|
||||
return false
|
||||
end
|
||||
for _, name in ipairs(_cached_store_names) do
|
||||
if _normalize_store_name(name) == needle then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function _get_script_opts_dir()
|
||||
local dir = nil
|
||||
pcall(function()
|
||||
@@ -863,7 +880,7 @@ local function _is_pipeline_helper_ready()
|
||||
helper_version = mp.get_property_native('user-data/medeia-pipeline-helper-version')
|
||||
end
|
||||
helper_version = tostring(helper_version or '')
|
||||
if helper_version ~= '2026-03-22.2' then
|
||||
if helper_version ~= '2026-03-22.4' then
|
||||
return false
|
||||
end
|
||||
|
||||
@@ -930,7 +947,7 @@ local function _helper_ready_diagnostics()
|
||||
end
|
||||
return 'ready=' .. tostring(ready or '')
|
||||
.. ' helper_version=' .. tostring(helper_version or '')
|
||||
.. ' required_version=2026-03-22.2'
|
||||
.. ' required_version=2026-03-22.4'
|
||||
.. ' last_value=' .. tostring(_helper_ready_last_value or '')
|
||||
.. ' last_seen_age=' .. tostring(age)
|
||||
end
|
||||
@@ -973,11 +990,28 @@ end
|
||||
local function attempt_start_pipeline_helper_async(callback)
|
||||
-- Async version: spawn helper without blocking UI. Calls callback(success) when done.
|
||||
callback = callback or function() end
|
||||
local helper_start_state = M._helper_start_state or { inflight = false, callbacks = {} }
|
||||
M._helper_start_state = helper_start_state
|
||||
|
||||
local function finish(success)
|
||||
local callbacks = helper_start_state.callbacks or {}
|
||||
helper_start_state.callbacks = {}
|
||||
helper_start_state.inflight = false
|
||||
for _, cb in ipairs(callbacks) do
|
||||
pcall(cb, success)
|
||||
end
|
||||
end
|
||||
|
||||
if _is_pipeline_helper_ready() then
|
||||
callback(true)
|
||||
return
|
||||
end
|
||||
|
||||
if helper_start_state.inflight then
|
||||
table.insert(helper_start_state.callbacks, callback)
|
||||
_lua_log('attempt_start_pipeline_helper_async: join existing startup')
|
||||
return
|
||||
end
|
||||
|
||||
-- Debounce: don't spawn multiple helpers in quick succession
|
||||
local now = mp.get_time()
|
||||
@@ -987,6 +1021,8 @@ local function attempt_start_pipeline_helper_async(callback)
|
||||
return
|
||||
end
|
||||
_helper_start_debounce_ts = now
|
||||
helper_start_state.inflight = true
|
||||
helper_start_state.callbacks = { callback }
|
||||
|
||||
-- Clear any stale ready heartbeat from an earlier helper instance before spawning.
|
||||
pcall(mp.set_property, PIPELINE_READY_PROP, '')
|
||||
@@ -997,7 +1033,7 @@ local function attempt_start_pipeline_helper_async(callback)
|
||||
local python = _resolve_python_exe(true)
|
||||
if not python or python == '' then
|
||||
_lua_log('attempt_start_pipeline_helper_async: no python executable available')
|
||||
callback(false)
|
||||
finish(false)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -1015,7 +1051,7 @@ local function attempt_start_pipeline_helper_async(callback)
|
||||
|
||||
if not ok then
|
||||
_lua_log('attempt_start_pipeline_helper_async: spawn failed final=' .. tostring(detail or _describe_subprocess_result(result)))
|
||||
callback(false)
|
||||
finish(false)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -1026,13 +1062,13 @@ local function attempt_start_pipeline_helper_async(callback)
|
||||
if _is_pipeline_helper_ready() then
|
||||
timer:kill()
|
||||
_lua_log('attempt_start_pipeline_helper_async: helper ready')
|
||||
callback(true)
|
||||
finish(true)
|
||||
return
|
||||
end
|
||||
if mp.get_time() >= deadline then
|
||||
timer:kill()
|
||||
_lua_log('attempt_start_pipeline_helper_async: timeout waiting for ready')
|
||||
callback(false)
|
||||
finish(false)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -1954,6 +1990,7 @@ local function _start_screenshot_store_save(store, out_path, tags)
|
||||
return false
|
||||
end
|
||||
|
||||
local is_named_store = _is_cached_store_name(store)
|
||||
local tag_list = _normalize_tag_list(tags)
|
||||
local screenshot_url = trim(tostring((_current_url_for_web_actions and _current_url_for_web_actions()) or mp.get_property(CURRENT_WEB_URL_PROP) or ''))
|
||||
if screenshot_url == '' or not screenshot_url:match('^https?://') then
|
||||
@@ -1961,29 +1998,35 @@ local function _start_screenshot_store_save(store, out_path, tags)
|
||||
end
|
||||
local cmd = 'add-file -store ' .. quote_pipeline_arg(store)
|
||||
.. ' -path ' .. quote_pipeline_arg(out_path)
|
||||
_set_selected_store(store)
|
||||
if screenshot_url ~= '' then
|
||||
cmd = cmd .. ' -url ' .. quote_pipeline_arg(screenshot_url)
|
||||
end
|
||||
if is_named_store then
|
||||
_set_selected_store(store)
|
||||
end
|
||||
|
||||
local tag_suffix = (#tag_list > 0) and (' | tags: ' .. tostring(#tag_list)) or ''
|
||||
if #tag_list > 0 then
|
||||
local tag_string = table.concat(tag_list, ',')
|
||||
cmd = cmd .. ' | add-tag ' .. quote_pipeline_arg(tag_string)
|
||||
end
|
||||
if screenshot_url ~= '' then
|
||||
cmd = cmd .. ' | add-url ' .. quote_pipeline_arg(screenshot_url)
|
||||
end
|
||||
|
||||
local queue_target = is_named_store and ('store ' .. store) or 'folder'
|
||||
local success_text = is_named_store and ('Screenshot saved to store: ' .. store .. tag_suffix) or ('Screenshot saved to folder' .. tag_suffix)
|
||||
local failure_text = is_named_store and 'Screenshot upload failed' or 'Screenshot save failed'
|
||||
|
||||
_lua_log('screenshot-save: queueing repl pipeline cmd=' .. cmd)
|
||||
|
||||
return _queue_pipeline_in_repl(
|
||||
cmd,
|
||||
'Queued in REPL: screenshot -> ' .. store .. tag_suffix,
|
||||
'Queued in REPL: screenshot -> ' .. queue_target .. tag_suffix,
|
||||
'Screenshot queue failed',
|
||||
'screenshot-save',
|
||||
{
|
||||
kind = 'mpv-screenshot',
|
||||
mpv_notify = {
|
||||
success_text = 'Screenshot saved to store: ' .. store .. tag_suffix,
|
||||
failure_text = 'Screenshot upload failed',
|
||||
success_text = success_text,
|
||||
failure_text = failure_text,
|
||||
duration_ms = 3500,
|
||||
},
|
||||
}
|
||||
@@ -2049,6 +2092,14 @@ local function _open_store_picker_for_pending_screenshot()
|
||||
local selected = _get_selected_store()
|
||||
local items = {}
|
||||
|
||||
if _is_windows() then
|
||||
items[#items + 1] = {
|
||||
title = 'Pick folder…',
|
||||
hint = 'Save screenshot to a local folder',
|
||||
value = { 'script-message-to', mp.get_script_name(), 'medeia-image-screenshot-pick-path', '{}' },
|
||||
}
|
||||
end
|
||||
|
||||
if type(_cached_store_names) == 'table' and #_cached_store_names > 0 then
|
||||
for _, name in ipairs(_cached_store_names) do
|
||||
name = trim(tostring(name or ''))
|
||||
@@ -2061,7 +2112,7 @@ local function _open_store_picker_for_pending_screenshot()
|
||||
}
|
||||
end
|
||||
end
|
||||
else
|
||||
elseif #items == 0 then
|
||||
items[#items + 1] = {
|
||||
title = 'No stores found',
|
||||
hint = 'Configure stores in config.conf',
|
||||
@@ -2149,6 +2200,9 @@ local function _capture_screenshot()
|
||||
local function dispatch_screenshot_save()
|
||||
local store_count = (type(_cached_store_names) == 'table') and #_cached_store_names or 0
|
||||
local selected_store = _normalize_store_name(_get_selected_store())
|
||||
if not _is_cached_store_name(selected_store) then
|
||||
selected_store = ''
|
||||
end
|
||||
|
||||
if store_count > 1 then
|
||||
_pending_screenshot = { path = out_path }
|
||||
@@ -2200,6 +2254,24 @@ mp.register_script_message('medeia-image-screenshot-pick-store', function(json)
|
||||
_open_screenshot_tag_prompt(store, out_path)
|
||||
end)
|
||||
|
||||
mp.register_script_message('medeia-image-screenshot-pick-path', function()
|
||||
if type(_pending_screenshot) ~= 'table' or not _pending_screenshot.path then
|
||||
return
|
||||
end
|
||||
if not _is_windows() then
|
||||
mp.osd_message('Folder picker is Windows-only', 4)
|
||||
return
|
||||
end
|
||||
|
||||
local folder = _pick_folder_windows()
|
||||
if not folder or folder == '' then
|
||||
return
|
||||
end
|
||||
|
||||
local out_path = tostring(_pending_screenshot.path or '')
|
||||
_open_screenshot_tag_prompt(folder, out_path)
|
||||
end)
|
||||
|
||||
mp.register_script_message('medeia-image-screenshot-tags-search', function(query)
|
||||
_apply_screenshot_tag_query(query)
|
||||
end)
|
||||
@@ -2591,7 +2663,7 @@ local function _extract_store_hash(target)
|
||||
return nil
|
||||
end
|
||||
|
||||
local function _pick_folder_windows()
|
||||
_pick_folder_windows = function()
|
||||
-- Native folder picker via PowerShell + WinForms.
|
||||
local ps = [[Add-Type -AssemblyName System.Windows.Forms; $d = New-Object System.Windows.Forms.FolderBrowserDialog; $d.Description = 'Select download folder'; $d.ShowNewFolderButton = $true; if ($d.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $d.SelectedPath }]]
|
||||
local res = utils.subprocess({
|
||||
|
||||
Reference in New Issue
Block a user