tabbed frametype filtering
This commit is contained in:
275
setup_textual_debugging.py
Normal file
275
setup_textual_debugging.py
Normal file
@@ -0,0 +1,275 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Setup script to integrate Textual debugging tools with StreamLens
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
def setup_debugging_integration():
|
||||
"""Add debugging capabilities to StreamLens app"""
|
||||
|
||||
app_path = Path("analyzer/tui/textual/app_v2.py")
|
||||
|
||||
if not app_path.exists():
|
||||
print("❌ StreamLens app file not found")
|
||||
return False
|
||||
|
||||
# Read current app file
|
||||
with open(app_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Check if debugging is already integrated
|
||||
if "TextualStateMonitor" in content:
|
||||
print("✅ Debugging already integrated")
|
||||
return True
|
||||
|
||||
# Add debugging imports
|
||||
import_addition = '''
|
||||
# Debugging imports
|
||||
try:
|
||||
from textual_state_visualizer import TextualStateMonitor, TextualStateWebServer
|
||||
from textual_inspector import inspect_textual_app, print_widget_tree
|
||||
DEBUGGING_AVAILABLE = True
|
||||
except ImportError:
|
||||
DEBUGGING_AVAILABLE = False
|
||||
'''
|
||||
|
||||
# Find the right place to add imports (after existing imports)
|
||||
lines = content.split('\n')
|
||||
import_index = 0
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
if line.startswith('if TYPE_CHECKING:'):
|
||||
import_index = i
|
||||
break
|
||||
else:
|
||||
# Find last import line
|
||||
for i, line in enumerate(lines):
|
||||
if line.startswith('from ') or line.startswith('import '):
|
||||
import_index = i + 1
|
||||
|
||||
# Insert debugging imports
|
||||
lines.insert(import_index, import_addition)
|
||||
|
||||
# Add debugging methods to the app class
|
||||
debugging_methods = '''
|
||||
|
||||
# Debugging methods
|
||||
def start_debugging(self, web_interface: bool = True, port: int = 8080):
|
||||
"""Start debugging tools"""
|
||||
if not DEBUGGING_AVAILABLE:
|
||||
print("❌ Debugging tools not available. Run: pip install watchdog")
|
||||
return
|
||||
|
||||
self._debug_monitor = TextualStateMonitor(self)
|
||||
self._debug_monitor.start_monitoring()
|
||||
|
||||
if web_interface:
|
||||
self._debug_server = TextualStateWebServer(self._debug_monitor, port)
|
||||
self._debug_server.start()
|
||||
|
||||
print(f"🔍 Debug monitoring started!")
|
||||
if web_interface:
|
||||
print(f"🌐 Web interface: http://localhost:{port}")
|
||||
|
||||
def stop_debugging(self):
|
||||
"""Stop debugging tools"""
|
||||
if hasattr(self, '_debug_monitor') and self._debug_monitor:
|
||||
self._debug_monitor.stop_monitoring()
|
||||
if hasattr(self, '_debug_server') and self._debug_server:
|
||||
self._debug_server.stop()
|
||||
|
||||
def debug_widget_tree(self):
|
||||
"""Print current widget tree to console"""
|
||||
if not DEBUGGING_AVAILABLE:
|
||||
print("❌ Debugging tools not available")
|
||||
return
|
||||
|
||||
data = inspect_textual_app(self)
|
||||
print("🔍 TEXTUAL APP INSPECTION")
|
||||
print("=" * 50)
|
||||
print_widget_tree(data.get('current_screen', {}))
|
||||
|
||||
def debug_focused_widget(self):
|
||||
"""Print info about currently focused widget"""
|
||||
focused = self.focused
|
||||
if focused:
|
||||
print(f"🎯 Focused widget: {focused.__class__.__name__}")
|
||||
if hasattr(focused, 'id'):
|
||||
print(f" ID: {focused.id}")
|
||||
if hasattr(focused, 'classes'):
|
||||
print(f" Classes: {list(focused.classes)}")
|
||||
if hasattr(focused, 'label'):
|
||||
print(f" Label: {focused.label}")
|
||||
else:
|
||||
print("🎯 No widget has focus")
|
||||
|
||||
# Debugging key bindings
|
||||
def action_debug_tree(self):
|
||||
"""Debug action: Print widget tree"""
|
||||
self.debug_widget_tree()
|
||||
|
||||
def action_debug_focus(self):
|
||||
"""Debug action: Print focused widget"""
|
||||
self.debug_focused_widget()
|
||||
|
||||
def action_start_web_debug(self):
|
||||
"""Debug action: Start web debugging interface"""
|
||||
self.start_debugging()
|
||||
'''
|
||||
|
||||
# Find the class definition and add methods
|
||||
class_found = False
|
||||
for i, line in enumerate(lines):
|
||||
if line.strip().startswith('class StreamLensAppV2'):
|
||||
class_found = True
|
||||
# Find the end of the class to add methods
|
||||
indent_level = len(line) - len(line.lstrip())
|
||||
|
||||
# Find a good place to insert methods (before the last method or at the end)
|
||||
insert_index = len(lines)
|
||||
for j in range(i + 1, len(lines)):
|
||||
if lines[j].strip() and not lines[j].startswith(' ' * (indent_level + 1)):
|
||||
insert_index = j
|
||||
break
|
||||
|
||||
# Insert debugging methods
|
||||
method_lines = debugging_methods.split('\n')
|
||||
for k, method_line in enumerate(method_lines):
|
||||
lines.insert(insert_index + k, method_line)
|
||||
break
|
||||
|
||||
if not class_found:
|
||||
print("❌ StreamLensAppV2 class not found")
|
||||
return False
|
||||
|
||||
# Add debugging key bindings to BINDINGS
|
||||
for i, line in enumerate(lines):
|
||||
if 'BINDINGS = [' in line:
|
||||
# Find the end of BINDINGS
|
||||
bracket_count = 0
|
||||
for j in range(i, len(lines)):
|
||||
bracket_count += lines[j].count('[') - lines[j].count(']')
|
||||
if bracket_count == 0:
|
||||
# Insert debugging bindings before the closing bracket
|
||||
debug_bindings = [
|
||||
' Binding("ctrl+d,t", "debug_tree", "Debug: Widget Tree", show=False),',
|
||||
' Binding("ctrl+d,f", "debug_focus", "Debug: Focused Widget", show=False),',
|
||||
' Binding("ctrl+d,w", "start_web_debug", "Debug: Web Interface", show=False),'
|
||||
]
|
||||
for k, binding in enumerate(debug_bindings):
|
||||
lines.insert(j + k, binding)
|
||||
break
|
||||
break
|
||||
|
||||
# Write the modified content
|
||||
new_content = '\n'.join(lines)
|
||||
|
||||
# Create backup
|
||||
backup_path = app_path.with_suffix('.py.backup')
|
||||
with open(backup_path, 'w') as f:
|
||||
f.write(content)
|
||||
print(f"📁 Backup created: {backup_path}")
|
||||
|
||||
# Write modified file
|
||||
with open(app_path, 'w') as f:
|
||||
f.write(new_content)
|
||||
|
||||
print("✅ Debugging integration added to StreamLens app")
|
||||
print("\nNew debugging features:")
|
||||
print(" 🔧 self.start_debugging() - Start debug monitoring with web interface")
|
||||
print(" 🔍 self.debug_widget_tree() - Print widget tree to console")
|
||||
print(" 🎯 self.debug_focused_widget() - Print focused widget info")
|
||||
print(" ⌨️ Ctrl+D,T - Debug widget tree")
|
||||
print(" ⌨️ Ctrl+D,F - Debug focused widget")
|
||||
print(" ⌨️ Ctrl+D,W - Start web debug interface")
|
||||
|
||||
return True
|
||||
|
||||
def install_dependencies():
|
||||
"""Install required dependencies"""
|
||||
import subprocess
|
||||
|
||||
print("📦 Installing debugging dependencies...")
|
||||
|
||||
try:
|
||||
subprocess.check_call([sys.executable, "-m", "pip", "install", "watchdog"])
|
||||
print("✅ Dependencies installed")
|
||||
return True
|
||||
except subprocess.CalledProcessError:
|
||||
print("❌ Failed to install dependencies")
|
||||
print("Please run: pip install watchdog")
|
||||
return False
|
||||
|
||||
def create_development_script():
|
||||
"""Create a development script for easy debugging"""
|
||||
|
||||
dev_script = '''#!/usr/bin/env python3
|
||||
"""
|
||||
StreamLens Development Script with Debugging
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add analyzer to path
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
from analyzer.tui.textual.app_v2 import StreamLensAppV2
|
||||
|
||||
def main():
|
||||
"""Run StreamLens with debugging enabled"""
|
||||
print("🚀 Starting StreamLens in debug mode...")
|
||||
|
||||
app = StreamLensAppV2()
|
||||
|
||||
# Start debugging automatically
|
||||
app.start_debugging(web_interface=True, port=8080)
|
||||
|
||||
# Run the app
|
||||
app.run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
'''
|
||||
|
||||
with open("debug_streamlens.py", 'w') as f:
|
||||
f.write(dev_script)
|
||||
|
||||
print("✅ Created debug_streamlens.py - Run with: python debug_streamlens.py")
|
||||
|
||||
def main():
|
||||
print("🔧 StreamLens Textual Debugging Setup")
|
||||
print("=" * 50)
|
||||
|
||||
# Install dependencies
|
||||
if not install_dependencies():
|
||||
return
|
||||
|
||||
# Setup debugging integration
|
||||
if not setup_debugging_integration():
|
||||
return
|
||||
|
||||
# Create development script
|
||||
create_development_script()
|
||||
|
||||
print("\n🎉 Setup complete! Here's how to use the debugging tools:")
|
||||
print("\n1. **Development Mode**: python debug_streamlens.py")
|
||||
print(" - Starts app with web debugging interface automatically")
|
||||
print(" - Opens browser to http://localhost:8080")
|
||||
print("\n2. **Live Reload**: python textual_dev_server.py debug_streamlens.py")
|
||||
print(" - Restarts app when you modify Python files")
|
||||
print("\n3. **Manual Debugging**: In your app, call:")
|
||||
print(" - app.debug_widget_tree() - Print widget hierarchy")
|
||||
print(" - app.debug_focused_widget() - Check what has focus")
|
||||
print(" - app.start_debugging() - Start web interface")
|
||||
print("\n4. **Keyboard Shortcuts** (while app is running):")
|
||||
print(" - Ctrl+D,T - Print widget tree")
|
||||
print(" - Ctrl+D,F - Print focused widget")
|
||||
print(" - Ctrl+D,W - Start web debug interface")
|
||||
print("\n5. **Testing**: python textual_test_framework.py")
|
||||
print(" - Run automated tests on your Textual components")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user