mirror of
https://github.com/Comfy-Org/ComfyUI.git
synced 2026-08-24 18:10:27 +08:00
fix(jobs): prefer media over text for job preview_output (#14681)
This commit is contained in:
@@ -170,6 +170,19 @@ def is_previewable(media_type: str, item: dict) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def is_text_preview(media_type: str, item: dict) -> bool:
|
||||
"""
|
||||
Check if a previewable output item is textual rather than visual media.
|
||||
|
||||
Saved text files (SaveText's .txt/.md/.json) are real outputs but must not
|
||||
outrank visual media when picking the job preview.
|
||||
"""
|
||||
if media_type == 'text':
|
||||
return True
|
||||
filename = item.get('filename', '').lower()
|
||||
return any(filename.endswith(ext) for ext in TEXT_EXTENSIONS)
|
||||
|
||||
|
||||
def normalize_queue_item(item: tuple, status: str) -> dict:
|
||||
"""Convert queue item tuple to unified job dict.
|
||||
|
||||
@@ -259,8 +272,13 @@ def get_outputs_summary(outputs: dict) -> tuple[int, Optional[dict]]:
|
||||
Returns (outputs_count, preview_output).
|
||||
|
||||
Preview priority (matching frontend):
|
||||
1. type="output" with previewable media
|
||||
2. Any previewable media
|
||||
1. type="output" visual media (saved images/video/audio/3d)
|
||||
2. any other previewable visual media (e.g. temp/preview images)
|
||||
3. saved text file (e.g. SaveText's .txt/.md/.json)
|
||||
4. raw text (only when the job produced nothing else previewable)
|
||||
|
||||
Text is kept in its own slots so node/execution order can't let a text
|
||||
output mask a visual one (e.g. a text node that runs before an image).
|
||||
|
||||
Text content entries (strings under 'text') are preview-only metadata,
|
||||
matching the frontend's METADATA_KEYS: they can serve as the fallback
|
||||
@@ -269,6 +287,8 @@ def get_outputs_summary(outputs: dict) -> tuple[int, Optional[dict]]:
|
||||
count = 0
|
||||
preview_output = None
|
||||
fallback_preview = None
|
||||
text_file_fallback = None
|
||||
text_fallback = None
|
||||
|
||||
for node_id, node_outputs in outputs.items():
|
||||
if not isinstance(node_outputs, dict):
|
||||
@@ -296,8 +316,8 @@ def get_outputs_summary(outputs: dict) -> tuple[int, Optional[dict]]:
|
||||
'nodeId': node_id,
|
||||
'mediaType': media_type
|
||||
}
|
||||
if fallback_preview is None:
|
||||
fallback_preview = enriched
|
||||
if text_fallback is None:
|
||||
text_fallback = enriched
|
||||
continue
|
||||
# normalize_output_item returned a dict (e.g. 3D file)
|
||||
item = normalized
|
||||
@@ -314,12 +334,15 @@ def get_outputs_summary(outputs: dict) -> tuple[int, Optional[dict]]:
|
||||
}
|
||||
if 'mediaType' not in item:
|
||||
enriched['mediaType'] = media_type
|
||||
if item.get('type') == 'output':
|
||||
if is_text_preview(media_type, item):
|
||||
if text_file_fallback is None:
|
||||
text_file_fallback = enriched
|
||||
elif item.get('type') == 'output':
|
||||
preview_output = enriched
|
||||
elif fallback_preview is None:
|
||||
fallback_preview = enriched
|
||||
|
||||
return count, preview_output or fallback_preview
|
||||
return count, preview_output or fallback_preview or text_file_fallback or text_fallback
|
||||
|
||||
|
||||
def apply_sorting(jobs: list[dict], sort_by: str, sort_order: str) -> list[dict]:
|
||||
|
||||
Reference in New Issue
Block a user