fix: pass border parameter to display and handle special sources properly
BUG FIXES:
1. Border parameter not being passed to display.show()
- Display backends support border parameter but app.py wasn't passing it
- Now app.py passes params.border to display.show(border=params.border)
- Enables border-test preset to actually render borders
2. WebSocket and Multi displays didn't support border parameter
- Updated WebSocket Protocol to include border parameter
- Updated MultiDisplay.show() to accept and forward border parameter
- Updated test to expect border parameter in mock calls
3. app.py didn't properly handle special sources (empty, pipeline-inspect)
- Border-test preset with source='empty' was still fetching headlines
- Pipeline-inspect source was never using the introspection data source
- Now app.py detects special sources and uses appropriate data source stages:
* 'empty' source → EmptyDataSource stage
* 'pipeline-inspect' → PipelineIntrospectionSource stage
* Other sources → traditional items-based approach
- Uses SourceItemsToBufferStage for special sources instead of RenderStage
- Sets pipeline on introspection source after build to avoid circular dependency
TESTING:
- All 463 tests pass
- Linting passes
- Manual test: `uv run mainline.py --preset border-test` now correctly shows empty source
- border-test preset now properly initializes without fetching unnecessary content
The issue was that the enhanced app.py code from the original diff didn't make it into
the refactor commit. This fix restores that functionality.
This commit is contained in:
@@ -51,6 +51,7 @@ def run_pipeline_mode(preset_name: str = "demo"):
|
||||
from engine.fetch import fetch_all, fetch_poetry, load_cache
|
||||
from engine.pipeline.adapters import (
|
||||
RenderStage,
|
||||
SourceItemsToBufferStage,
|
||||
create_items_stage,
|
||||
create_stage_from_display,
|
||||
create_stage_from_effect,
|
||||
@@ -85,19 +86,29 @@ def run_pipeline_mode(preset_name: str = "demo"):
|
||||
)
|
||||
|
||||
print(" \033[38;5;245mFetching content...\033[0m")
|
||||
cached = load_cache()
|
||||
if cached:
|
||||
items = cached
|
||||
elif preset.source == "poetry":
|
||||
items, _, _ = fetch_poetry()
|
||||
|
||||
# Handle special sources that don't need traditional fetching
|
||||
introspection_source = None
|
||||
if preset.source == "pipeline-inspect":
|
||||
items = []
|
||||
print(" \033[38;5;245mUsing pipeline introspection source\033[0m")
|
||||
elif preset.source == "empty":
|
||||
items = []
|
||||
print(" \033[38;5;245mUsing empty source (no content)\033[0m")
|
||||
else:
|
||||
items, _, _ = fetch_all()
|
||||
cached = load_cache()
|
||||
if cached:
|
||||
items = cached
|
||||
elif preset.source == "poetry":
|
||||
items, _, _ = fetch_poetry()
|
||||
else:
|
||||
items, _, _ = fetch_all()
|
||||
|
||||
if not items:
|
||||
print(" \033[38;5;196mNo content available\033[0m")
|
||||
sys.exit(1)
|
||||
if not items:
|
||||
print(" \033[38;5;196mNo content available\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
print(f" \033[38;5;82mLoaded {len(items)} items\033[0m")
|
||||
print(f" \033[38;5;82mLoaded {len(items)} items\033[0m")
|
||||
|
||||
display = DisplayRegistry.create(preset.display)
|
||||
if not display:
|
||||
@@ -108,18 +119,45 @@ def run_pipeline_mode(preset_name: str = "demo"):
|
||||
|
||||
effect_registry = get_registry()
|
||||
|
||||
pipeline.add_stage("source", create_items_stage(items, preset.source))
|
||||
pipeline.add_stage(
|
||||
"render",
|
||||
RenderStage(
|
||||
items,
|
||||
width=80,
|
||||
height=24,
|
||||
camera_speed=params.camera_speed,
|
||||
camera_mode=preset.camera,
|
||||
firehose_enabled=params.firehose_enabled,
|
||||
),
|
||||
)
|
||||
# Create source stage based on preset source type
|
||||
if preset.source == "pipeline-inspect":
|
||||
from engine.data_sources.pipeline_introspection import (
|
||||
PipelineIntrospectionSource,
|
||||
)
|
||||
from engine.pipeline.adapters import DataSourceStage
|
||||
|
||||
introspection_source = PipelineIntrospectionSource(
|
||||
pipeline=None, # Will be set after pipeline.build()
|
||||
viewport_width=80,
|
||||
viewport_height=24,
|
||||
)
|
||||
pipeline.add_stage(
|
||||
"source", DataSourceStage(introspection_source, name="pipeline-inspect")
|
||||
)
|
||||
elif preset.source == "empty":
|
||||
from engine.data_sources.sources import EmptyDataSource
|
||||
from engine.pipeline.adapters import DataSourceStage
|
||||
|
||||
empty_source = EmptyDataSource(width=80, height=24)
|
||||
pipeline.add_stage("source", DataSourceStage(empty_source, name="empty"))
|
||||
else:
|
||||
pipeline.add_stage("source", create_items_stage(items, preset.source))
|
||||
|
||||
# Add appropriate render stage
|
||||
if preset.source in ("pipeline-inspect", "empty"):
|
||||
pipeline.add_stage("render", SourceItemsToBufferStage(name="items-to-buffer"))
|
||||
else:
|
||||
pipeline.add_stage(
|
||||
"render",
|
||||
RenderStage(
|
||||
items,
|
||||
width=80,
|
||||
height=24,
|
||||
camera_speed=params.camera_speed,
|
||||
camera_mode=preset.camera,
|
||||
firehose_enabled=params.firehose_enabled,
|
||||
),
|
||||
)
|
||||
|
||||
for effect_name in preset.effects:
|
||||
effect = effect_registry.get(effect_name)
|
||||
@@ -132,6 +170,10 @@ def run_pipeline_mode(preset_name: str = "demo"):
|
||||
|
||||
pipeline.build()
|
||||
|
||||
# For pipeline-inspect, set the pipeline after build to avoid circular dependency
|
||||
if introspection_source is not None:
|
||||
introspection_source.set_pipeline(pipeline)
|
||||
|
||||
if not pipeline.initialize():
|
||||
print(" \033[38;5;196mFailed to initialize pipeline\033[0m")
|
||||
sys.exit(1)
|
||||
@@ -162,7 +204,7 @@ def run_pipeline_mode(preset_name: str = "demo"):
|
||||
|
||||
result = pipeline.execute(items)
|
||||
if result.success:
|
||||
display.show(result.data)
|
||||
display.show(result.data, border=params.border)
|
||||
|
||||
if hasattr(display, "is_quit_requested") and display.is_quit_requested():
|
||||
if hasattr(display, "clear_quit_request"):
|
||||
|
||||
Reference in New Issue
Block a user