Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions eink/backend/background/scene_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,14 @@ async def update_scene_queue(scene, session):
):
needs_work = True

if not needs_work and record.filename:
# Check if file exists on disk
path = os.path.join(
get_storage_path("scene_display"), record.filename
)
if not os.path.exists(path):
needs_work = True

if needs_work:
to_queue.add((display_id, image_id))

Expand Down
7 changes: 7 additions & 0 deletions eink/backend/tests/integration/test_scene_queue.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os
import pytest
from sqlalchemy import select
from backend import models, database
from backend.utils.storage import get_storage_path


@pytest.mark.asyncio
Expand Down Expand Up @@ -171,6 +173,11 @@ async def test_scene_save_populates_queue(aiohttp_client, app):
session.add(sdi)
await session.commit()

# Create dummy file to pass the existence check in update_scene_queue
path = os.path.join(get_storage_path("scene_display"), "slice.png")
with open(path, "w") as f:
f.write("dummy")

# 6. Save scene again - should now have 0 in queue as it's up to date
resp = await client.put(f"/api/scene/{scene_id}", json=update_data)
assert resp.status == 200
Expand Down
103 changes: 103 additions & 0 deletions eink/backend/tests/unit/test_scene_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,3 +390,106 @@ async def test_scene_processor_rotation(db_setup, tmp_path):
assert config["height"] == 480
# Rotation should be 90 because landscape panel used as portrait
assert config["rotation"] == 90


@pytest.mark.asyncio
async def test_scene_processor_retriggers_if_file_missing(db_setup, tmp_path):
"""Test that scene_processor retriggers if the file is missing from disk."""

async with database.get_session() as session:
# Minimal setup for one display
dt = models.DisplayType(
id="dt1",
name="7.5",
width_mm=163,
height_mm=98,
panel_width_mm=163,
panel_height_mm=98,
width_px=800,
height_px=480,
colour_type="BW",
frame={},
mat={},
)
session.add(dt)
layout = models.Layout(
id="l1",
name="L",
canvas_width_mm=200,
canvas_height_mm=200,
items=[{"id": "d1", "display_type_id": "dt1", "x_mm": 0, "y_mm": 0}],
status="active",
)
session.add(layout)
img = models.Image(
id="i1",
name="I",
file_path="t.png",
width=100,
height=100,
file_type="png",
status="ACTIVE",
file_hash="h1",
)
session.add(img)
await session.commit()
await session.refresh(img)

scene = models.Scene(
id="s1",
name="S",
layout_id="l1",
status="active",
items=[
{
"id": "it1",
"type": "image",
"displays": ["d1"],
"images": [
{
"image_id": "i1",
"scaling_factor": 100,
"offset": {"x": 0, "y": 0},
}
],
}
],
)
session.add(scene)
await session.commit()
await session.refresh(scene)

# Create record with matching hashes but MISSING file on disk
record = models.SceneDisplayImage(
scene_id="s1",
display_id="d1",
image_id="i1",
image_hash=img.settings_hash,
scene_hash=scene.scene_hash,
file_hash="some-hash",
filename="slice_s1_i1_d1.png",
)
session.add(record)
await session.commit()

# Ensure the file does NOT exist on disk
# (It shouldn't anyway in this clean tmp_path test)
path = os.path.join(str(tmp_path), "slice_s1_i1_d1.png")
if os.path.exists(path):
os.remove(path)

# Mock get_storage_path to point to our tmp_path
with patch(
"backend.background.scene_processor.get_storage_path",
return_value=str(tmp_path),
):
await scene_handler._update_scene_queue(scene, session)
await session.commit()

# Verify that it was added to the queue
stmt = select(models.SceneQueue).where(models.SceneQueue.scene_id == "s1")
result = await session.execute(stmt)
queued = result.scalars().all()
assert len(queued) == 1
assert queued[0].display_id == "d1"
assert queued[0].image_id == "i1"
Loading