This commit is contained in:
2026-03-25 00:56:58 -07:00
parent 96f327e4dc
commit c31402c8f1
5 changed files with 89 additions and 12 deletions

View File

@@ -396,6 +396,9 @@ M._reset_uosc_input_state = function(reason)
return false
end
pcall(mp.commandv, 'script-message-to', 'uosc', 'close-menu')
pcall(mp.commandv, 'script-message-to', 'uosc', 'sync-cursor')
M._disable_input_section('input_console', why .. '@immediate')
M._disable_input_section('input_forced_console', why .. '@immediate')
mp.add_timeout(0.05, function()
if ensure_uosc_loaded() then
pcall(mp.commandv, 'script-message-to', 'uosc', 'sync-cursor')
@@ -403,6 +406,13 @@ M._reset_uosc_input_state = function(reason)
M._disable_input_section('input_console', why .. '@sync')
M._disable_input_section('input_forced_console', why .. '@sync')
end)
mp.add_timeout(0.20, function()
if ensure_uosc_loaded() then
pcall(mp.commandv, 'script-message-to', 'uosc', 'sync-cursor')
end
M._disable_input_section('input_console', why .. '@sync2')
M._disable_input_section('input_forced_console', why .. '@sync2')
end)
return true
end
@@ -1332,9 +1342,10 @@ local function attempt_start_pipeline_helper_async(callback)
end
-- Wait for helper to become ready in background (non-blocking).
-- 12 s gives Python time to kill a stale lock holder (PS scan + taskkill)
-- and publish its first ready heartbeat before we give up.
local deadline = mp.get_time() + 12.0
-- The Python helper can spend up to 12s recovering a stale singleton lock
-- before it even starts connecting to mpv IPC, so the Lua-side wait must be
-- comfortably longer than that to avoid false startup failures.
local deadline = mp.get_time() + 45.0
local timer
timer = mp.add_periodic_timer(0.1, function()
if _is_pipeline_helper_ready() then
@@ -1345,7 +1356,7 @@ local function attempt_start_pipeline_helper_async(callback)
end
if mp.get_time() >= deadline then
timer:kill()
_lua_log('attempt_start_pipeline_helper_async: timeout waiting for ready')
_lua_log('attempt_start_pipeline_helper_async: timeout waiting for ready ' .. _helper_ready_diagnostics())
-- Reset debounce so the next attempt is not immediate; gives the
-- still-running Python helper time to die or acquire the lock.
_helper_start_debounce_ts = mp.get_time()
@@ -3795,12 +3806,11 @@ local function _sync_current_web_url_from_playback()
end
end
mp.add_hook('on_load', 50, function(hook)
mp.add_hook('on_load', 50, function()
local ok, err = pcall(M._apply_web_subtitle_load_defaults, 'on_load')
if not ok then
_lua_log('web-subtitles: on_load setup failed err=' .. tostring(err))
end
hook:continue()
end)
local _current_store_url_status = {

View File

@@ -1120,7 +1120,7 @@ def _run_op(op: str, data: Any) -> Dict[str, Any]:
def _append_helper_log(text: str) -> None:
"""Log to database instead of file. This provides unified logging with rest of system."""
"""Log helper diagnostics to file, database, and the mpv console emitter."""
payload = (text or "").rstrip()
if not payload:
return
@@ -1129,6 +1129,12 @@ def _append_helper_log(text: str) -> None:
if len(_HELPER_LOG_BACKLOG) > _HELPER_LOG_BACKLOG_LIMIT:
del _HELPER_LOG_BACKLOG[:-_HELPER_LOG_BACKLOG_LIMIT]
try:
with open(_helper_log_path(), "a", encoding="utf-8", errors="replace") as fh:
fh.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {payload}\n")
except Exception:
pass
try:
# Try database logging first (best practice: unified logging)
from SYS.database import log_to_db

View File

@@ -1113,6 +1113,13 @@ mp.register_script_message('close-menu', function(type)
if Menu:is_open(type) then Menu:close() end
end)
mp.register_script_message('sync-cursor', function()
cursor.last_events.primary_down = nil
cursor.last_events.primary_up = nil
cursor.last_events.secondary_down = nil
cursor.last_events.secondary_up = nil
cursor.last_events.primary_click = nil
cursor.last_events.secondary_click = nil
cursor.history:clear()
local mouse = mp.get_property_native('mouse-pos')
if type(mouse) == 'table' and mouse.hover and mouse.x and mouse.y then
cursor:move(mouse.x, mouse.y)

View File

@@ -2221,6 +2221,21 @@ class ItemDetailView(Table):
details_table.add_column("Key", style="cyan", justify="right", width=15)
details_table.add_column("Value", style="white")
def _render_tag_text(tag_value: Any) -> Text:
tag_text = Text()
tag_text.append("#", style="dim")
raw = str(tag_value or "")
namespace, sep, value = raw.partition(":")
if sep and namespace:
tag_text.append(namespace, style="#6ecbff")
tag_text.append(sep, style="#6ecbff")
if value:
tag_text.append(value, style="green")
else:
tag_text.append(raw, style="green")
return tag_text
# Canonical display order for metadata
order = ["Title", "Hash", "Store", "Path", "Ext", "Size", "Duration", "Url", "Relations"]
@@ -2268,7 +2283,7 @@ class ItemDetailView(Table):
if isinstance(tags, str):
tags = [t.strip() for t in tags.split(",") if t.strip()]
tags_sorted = sorted(map(str, tags))
tag_cols = Columns([f"[dim]#[/dim]{t}" for t in tags_sorted], equal=True, expand=True)
tag_cols = Columns([_render_tag_text(t) for t in tags_sorted], equal=True, expand=True)
details_table.add_row("", "") # Spacer
details_table.add_row("Tags:", tag_cols)
has_details = True

View File

@@ -256,18 +256,41 @@ def _focus_db_log_rows(
return _collapse_repeated_log_lines(rendered)
def _slice_mpv_log_to_latest_run(lines: Sequence[str]) -> List[str]:
startup_pattern = re.compile(r"\bmpv v\d", re.IGNORECASE)
def _slice_log_to_latest_marker(
lines: Sequence[str],
patterns: Sequence[re.Pattern[str]],
) -> List[str]:
collected = list(lines)
if not collected:
return []
for idx in range(len(collected) - 1, -1, -1):
text = str(collected[idx] or "")
if startup_pattern.search(text):
if any(pattern.search(text) for pattern in patterns):
return collected[idx:]
return collected
def _slice_mpv_log_to_latest_run(lines: Sequence[str]) -> List[str]:
return _slice_log_to_latest_marker(
lines,
[re.compile(r"\bmpv v\d", re.IGNORECASE)],
)
def _slice_lua_log_to_latest_run(lines: Sequence[str]) -> List[str]:
return _slice_log_to_latest_marker(
lines,
[re.compile(r"medeia[- ]lua loaded version=", re.IGNORECASE)],
)
def _slice_helper_log_to_latest_run(lines: Sequence[str]) -> List[str]:
return _slice_log_to_latest_marker(
lines,
[re.compile(r"\[helper\] version=.* started ipc=", re.IGNORECASE)],
)
def _get_mpv_property(prop_name: str) -> Optional[Any]:
try:
resp = _send_ipc_command(
@@ -2456,8 +2479,22 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
else:
print("MPV core log: <no focused entries>")
try:
lua_tail = _tail_text_file(str(_lua_log_file()), max_lines=400, max_bytes=262144)
except Exception:
lua_tail = []
lua_tail = _slice_lua_log_to_latest_run(lua_tail)
lua_tail = _collapse_repeated_log_lines(_apply_log_filter(lua_tail, log_filter_text))
if lua_tail:
title = "Medeia Lua log (latest run)"
if log_filter_text:
title += f" filtered by '{log_filter_text}'"
title += ":"
print(title)
for line in lua_tail:
print(line)
fallback_logs = [
("Medeia Lua log file tail", str(_lua_log_file())),
("Medeia helper log file tail", str(_helper_log_file())),
]
for title, path in fallback_logs:
@@ -2465,6 +2502,8 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
lines = _tail_text_file(path, max_lines=120)
except Exception:
lines = []
if path == str(_helper_log_file()):
lines = _slice_helper_log_to_latest_run(lines)
lines = _collapse_repeated_log_lines(_apply_log_filter(lines, log_filter_text))
if not lines:
continue