update
This commit is contained in:
141
cmdnat/pipe.py
141
cmdnat/pipe.py
@@ -173,6 +173,97 @@ def _apply_log_filter(lines: Sequence[str], filter_text: Optional[str]) -> List[
|
|||||||
return filtered
|
return filtered
|
||||||
|
|
||||||
|
|
||||||
|
def _slice_mpv_log_to_latest_run(lines: Sequence[str]) -> List[str]:
|
||||||
|
startup_pattern = re.compile(r"\bmpv v\d", re.IGNORECASE)
|
||||||
|
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):
|
||||||
|
return collected[idx:]
|
||||||
|
return collected
|
||||||
|
|
||||||
|
|
||||||
|
def _get_mpv_property(prop_name: str) -> Optional[Any]:
|
||||||
|
try:
|
||||||
|
resp = _send_ipc_command(
|
||||||
|
{
|
||||||
|
"command": ["get_property", prop_name],
|
||||||
|
},
|
||||||
|
silent=True,
|
||||||
|
)
|
||||||
|
if resp and resp.get("error") == "success":
|
||||||
|
return resp.get("data")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _get_latest_mpv_run_marker(log_db_path: str) -> Optional[tuple[str, str]]:
|
||||||
|
try:
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
conn = sqlite3.connect(log_db_path, timeout=5.0)
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute(
|
||||||
|
(
|
||||||
|
"SELECT timestamp, message FROM logs "
|
||||||
|
"WHERE module = 'mpv' AND ("
|
||||||
|
"message LIKE '[helper] version=% started ipc=%' "
|
||||||
|
"OR message LIKE 'medeia lua loaded version=%'"
|
||||||
|
") "
|
||||||
|
"ORDER BY timestamp DESC LIMIT 1"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
row = cur.fetchone()
|
||||||
|
cur.close()
|
||||||
|
conn.close()
|
||||||
|
if row and row[0]:
|
||||||
|
return str(row[0]), str(row[1] or "")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _get_mpv_logs_for_latest_run(
|
||||||
|
log_db_path: str,
|
||||||
|
*,
|
||||||
|
log_filter_text: Optional[str],
|
||||||
|
limit: int = 200,
|
||||||
|
) -> tuple[Optional[str], Optional[str], List[tuple[Any, Any, Any, Any]]]:
|
||||||
|
marker = _get_latest_mpv_run_marker(log_db_path)
|
||||||
|
marker_ts = marker[0] if marker else None
|
||||||
|
marker_msg = marker[1] if marker else None
|
||||||
|
try:
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
conn = sqlite3.connect(log_db_path, timeout=5.0)
|
||||||
|
cur = conn.cursor()
|
||||||
|
query = "SELECT timestamp, level, module, message FROM logs WHERE module = 'mpv'"
|
||||||
|
params: List[str] = []
|
||||||
|
if marker_ts:
|
||||||
|
query += " AND timestamp >= ?"
|
||||||
|
params.append(marker_ts)
|
||||||
|
else:
|
||||||
|
cutoff = (datetime.utcnow() - timedelta(hours=6)).strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
query += " AND timestamp >= ?"
|
||||||
|
params.append(cutoff)
|
||||||
|
if log_filter_text:
|
||||||
|
query += " AND LOWER(message) LIKE ?"
|
||||||
|
params.append(f"%{log_filter_text.lower()}%")
|
||||||
|
query += " ORDER BY timestamp DESC LIMIT ?"
|
||||||
|
params.append(str(max(1, int(limit))))
|
||||||
|
cur.execute(query, tuple(params))
|
||||||
|
rows = cur.fetchall()
|
||||||
|
cur.close()
|
||||||
|
conn.close()
|
||||||
|
rows.reverse()
|
||||||
|
return marker_ts, marker_msg, rows
|
||||||
|
except Exception:
|
||||||
|
return marker_ts, marker_msg, []
|
||||||
|
|
||||||
|
|
||||||
def _try_enable_mpv_file_logging(mpv_log_path: str, *, attempts: int = 3) -> bool:
|
def _try_enable_mpv_file_logging(mpv_log_path: str, *, attempts: int = 3) -> bool:
|
||||||
"""Best-effort enable mpv log-file + verbose level on a running instance.
|
"""Best-effort enable mpv log-file + verbose level on a running instance.
|
||||||
|
|
||||||
@@ -2217,7 +2308,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
|||||||
|
|
||||||
tail_lines: List[str] = []
|
tail_lines: List[str] = []
|
||||||
for _ in range(8):
|
for _ in range(8):
|
||||||
tail_lines = _tail_text_file(mpv_log_path, max_lines=200)
|
tail_lines = _tail_text_file(mpv_log_path, max_lines=400, max_bytes=262144)
|
||||||
if tail_lines:
|
if tail_lines:
|
||||||
break
|
break
|
||||||
try:
|
try:
|
||||||
@@ -2227,9 +2318,17 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
|||||||
except Exception:
|
except Exception:
|
||||||
break
|
break
|
||||||
|
|
||||||
filtered_tail = _apply_log_filter(tail_lines, log_filter_text)
|
latest_run_tail = _slice_mpv_log_to_latest_run(tail_lines)
|
||||||
|
filtered_tail = _apply_log_filter(latest_run_tail, log_filter_text)
|
||||||
|
|
||||||
|
helper_heartbeat = _get_mpv_property("user-data/medeia-pipeline-ready")
|
||||||
|
helper_status = "not running"
|
||||||
|
if helper_heartbeat not in (None, "", "0", False):
|
||||||
|
helper_status = f"running ({helper_heartbeat})"
|
||||||
|
|
||||||
|
print(f"Pipeline helper: {helper_status}")
|
||||||
if filtered_tail:
|
if filtered_tail:
|
||||||
title = "MPV log (tail"
|
title = "MPV log (latest run tail"
|
||||||
if log_filter_text:
|
if log_filter_text:
|
||||||
title += f" filtered by '{log_filter_text}'"
|
title += f" filtered by '{log_filter_text}'"
|
||||||
title += "):"
|
title += "):"
|
||||||
@@ -2240,7 +2339,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
|||||||
if log_filter_text:
|
if log_filter_text:
|
||||||
print(f"MPV log (tail): <no entries match filter '{log_filter_text}'>")
|
print(f"MPV log (tail): <no entries match filter '{log_filter_text}'>")
|
||||||
else:
|
else:
|
||||||
print("MPV log (tail): <empty>")
|
print("MPV log (latest run tail): <empty>")
|
||||||
print(
|
print(
|
||||||
"Note: On some Windows builds, mpv cannot start writing to --log-file after launch."
|
"Note: On some Windows builds, mpv cannot start writing to --log-file after launch."
|
||||||
)
|
)
|
||||||
@@ -2252,27 +2351,21 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
|||||||
try:
|
try:
|
||||||
import sqlite3
|
import sqlite3
|
||||||
log_db_path = str((Path(__file__).resolve().parent.parent / "logs.db"))
|
log_db_path = str((Path(__file__).resolve().parent.parent / "logs.db"))
|
||||||
conn = sqlite3.connect(log_db_path, timeout=5.0)
|
marker_ts, marker_msg, mpv_logs = _get_mpv_logs_for_latest_run(
|
||||||
cur = conn.cursor()
|
log_db_path,
|
||||||
query = "SELECT timestamp, level, module, message FROM logs WHERE module = 'mpv'"
|
log_filter_text=log_filter_text,
|
||||||
params: List[str] = []
|
limit=250,
|
||||||
cutoff_24h = (datetime.utcnow() - timedelta(hours=24)).strftime("%Y-%m-%d %H:%M:%S")
|
)
|
||||||
query += " AND timestamp >= ?"
|
|
||||||
params.append(cutoff_24h)
|
|
||||||
if log_filter_text:
|
|
||||||
query += " AND LOWER(message) LIKE ?"
|
|
||||||
params.append(f"%{log_filter_text.lower()}%")
|
|
||||||
query += " ORDER BY timestamp DESC LIMIT 200"
|
|
||||||
cur.execute(query, tuple(params))
|
|
||||||
mpv_logs = cur.fetchall()
|
|
||||||
cur.close()
|
|
||||||
conn.close()
|
|
||||||
if log_filter_text:
|
if log_filter_text:
|
||||||
print(
|
print(
|
||||||
f"MPV logs from database (mpv module, last 24h, filtered by '{log_filter_text}', most recent first):"
|
f"MPV logs from database (latest run, filtered by '{log_filter_text}', chronological):"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print("MPV logs from database (mpv module, last 24h, most recent first):")
|
print("MPV logs from database (latest run, chronological):")
|
||||||
|
if marker_ts:
|
||||||
|
print(f"Latest run started: {marker_ts}")
|
||||||
|
if marker_msg:
|
||||||
|
print(f"Run marker: {marker_msg}")
|
||||||
if mpv_logs:
|
if mpv_logs:
|
||||||
for timestamp, level, _module, message in mpv_logs:
|
for timestamp, level, _module, message in mpv_logs:
|
||||||
ts = str(timestamp or "").strip()
|
ts = str(timestamp or "").strip()
|
||||||
@@ -2282,9 +2375,9 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
|||||||
print(f"[{level}] {message}")
|
print(f"[{level}] {message}")
|
||||||
else:
|
else:
|
||||||
if log_filter_text:
|
if log_filter_text:
|
||||||
print(f"(no mpv logs found matching '{log_filter_text}')")
|
print(f"(no latest-run mpv logs found matching '{log_filter_text}')")
|
||||||
else:
|
else:
|
||||||
print("(no mpv logs found)")
|
print("(no latest-run mpv logs found)")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
debug(f"Could not fetch database logs: {e}")
|
debug(f"Could not fetch database logs: {e}")
|
||||||
pass
|
pass
|
||||||
@@ -2482,7 +2575,7 @@ CMDLET = Cmdlet(
|
|||||||
CmdletArg(
|
CmdletArg(
|
||||||
name="log",
|
name="log",
|
||||||
type="flag",
|
type="flag",
|
||||||
description="Enable pipeable debug output, write an mpv log file, and optionally specify a filter string right after -log to search stored mpv logs from the last 24 hours",
|
description="Enable pipeable debug output, write an mpv log file, and optionally specify a filter string right after -log to search stored mpv logs from the latest observed run",
|
||||||
),
|
),
|
||||||
CmdletArg(
|
CmdletArg(
|
||||||
name="borderless",
|
name="borderless",
|
||||||
|
|||||||
Reference in New Issue
Block a user