fix: Clean console output and handle slow commands

1. Remove prompt lines (e.g., "MarWoj|*") from output
2. Remove echoed command from response
3. Strip leading/trailing whitespace
4. Longer timeout for slow commands: node_discover (15s),
   recv (60s), send/send_msg (15s)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-01-09 13:53:17 +01:00
parent 30163173b0
commit dd8b174e20
+77 -3
View File
@@ -3,6 +3,7 @@ mc-webui - Flask application entry point
"""
import logging
import re
import shlex
import requests
from flask import Flask, request as flask_request
@@ -12,6 +13,14 @@ from app.routes.views import views_bp
from app.routes.api import api_bp
from app.archiver.manager import schedule_daily_archiving
# Commands that require longer timeout (in seconds)
SLOW_COMMANDS = {
'node_discover': 15,
'recv': 60,
'send': 15,
'send_msg': 15,
}
# Configure logging
logging.basicConfig(
level=logging.DEBUG if config.FLASK_DEBUG else logging.INFO,
@@ -53,6 +62,65 @@ def create_app():
return app
# ============================================================
# Console output helpers
# ============================================================
def clean_console_output(output: str, command: str) -> str:
"""
Clean meshcli console output by removing:
- Prompt lines (e.g., "MarWoj|*" or "DeviceName|*[N]")
- Echoed command line
- Leading/trailing whitespace
"""
if not output:
return output
lines = output.split('\n')
cleaned_lines = []
# Pattern to match prompt: <name>|*[optional] or <name>|*
# Examples: "MarWoj|*", "MarWoj|*[3]", "Device Name|*"
prompt_pattern = re.compile(r'^.+\|\*(\[\d+\])?\s*$')
# Pattern to match prompt followed by command echo
# Example: "MarWoj|* contacts" or "MarWoj|*[3] get_radio"
prompt_cmd_pattern = re.compile(r'^.+\|\*(\[\d+\])?\s+\S+')
for line in lines:
stripped = line.rstrip()
# Skip empty lines at start
if not cleaned_lines and not stripped:
continue
# Skip lines that are just the prompt
if prompt_pattern.match(stripped):
continue
# Skip lines that are prompt + echoed command
if prompt_cmd_pattern.match(stripped):
# Check if this line is just echoing the command
# Extract the part after the prompt
match = re.match(r'^.+\|\*(\[\d+\])?\s+(.+)$', stripped)
if match:
echoed_part = match.group(2).strip()
if echoed_part == command.strip():
continue
cleaned_lines.append(line)
# Remove leading empty lines
while cleaned_lines and not cleaned_lines[0].strip():
cleaned_lines.pop(0)
# Remove trailing empty lines
while cleaned_lines and not cleaned_lines[-1].strip():
cleaned_lines.pop()
return '\n'.join(cleaned_lines)
# ============================================================
# WebSocket handlers for Console
# ============================================================
@@ -93,18 +161,24 @@ def handle_send_command(data):
except ValueError:
args = command.split()
# Determine timeout based on command
base_command = args[0] if args else ''
cmd_timeout = SLOW_COMMANDS.get(base_command, 10)
def execute_and_respond():
try:
response = requests.post(
config.MC_BRIDGE_URL,
json={'args': args, 'timeout': 30},
timeout=35
json={'args': args, 'timeout': cmd_timeout},
timeout=cmd_timeout + 5 # HTTP timeout slightly longer
)
if response.status_code == 200:
result = response.json()
if result.get('success'):
output = result.get('stdout', '').strip()
raw_output = result.get('stdout', '')
# Clean output: remove prompts and echoed commands
output = clean_console_output(raw_output, command)
if not output:
output = '(no output)'
socketio.emit('command_response', {