@danhachuel/thunderbolt 0.6.76 → 0.6.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/main.py +7 -6
- package/hermes_ui/pipeline_worker.py +16 -2
- package/package.json +1 -1
package/app/main.py
CHANGED
|
@@ -4970,10 +4970,11 @@ def _task_artifact_path(task: dict[str, Any], *names: str) -> Path | None:
|
|
|
4970
4970
|
|
|
4971
4971
|
|
|
4972
4972
|
def _download_title(task: dict[str, Any]) -> str:
|
|
4973
|
-
"""Return
|
|
4974
|
-
raw_title = str(task.get("
|
|
4975
|
-
cleaned = re.sub(r'[<>:"
|
|
4976
|
-
cleaned =
|
|
4973
|
+
"""Return the original video name, safely normalised for downloaded files."""
|
|
4974
|
+
raw_title = str(task.get("topic") or task.get("title") or task.get("name") or "Vídeo").strip()
|
|
4975
|
+
cleaned = re.sub(r'[<>:"/\\|?*\x00-\x1f]+', "_", raw_title)
|
|
4976
|
+
cleaned = re.sub(r"\s+", "_", cleaned)
|
|
4977
|
+
cleaned = re.sub(r"_+", "_", cleaned).strip(" ._")
|
|
4977
4978
|
return cleaned or "Vídeo"
|
|
4978
4979
|
|
|
4979
4980
|
|
|
@@ -5713,7 +5714,7 @@ def _render_youtube_automation_cards():
|
|
|
5713
5714
|
st.download_button(
|
|
5714
5715
|
"Baixar Thumbnail",
|
|
5715
5716
|
data=thumbnail_path.read_bytes() if thumbnail_path else b"",
|
|
5716
|
-
file_name=_automation_download_name("
|
|
5717
|
+
file_name=_automation_download_name("Thumbnail", task, thumbnail_path, ".png"),
|
|
5717
5718
|
mime="image/png",
|
|
5718
5719
|
key=f"automation_download_thumbnail_{task['id']}",
|
|
5719
5720
|
use_container_width=True,
|
|
@@ -5761,7 +5762,7 @@ def _render_youtube_automation_cards():
|
|
|
5761
5762
|
st.download_button(
|
|
5762
5763
|
"Baixar Vídeo",
|
|
5763
5764
|
data=video_path.read_bytes() if video_path else b"",
|
|
5764
|
-
file_name=_automation_download_name("
|
|
5765
|
+
file_name=_automation_download_name("Vídeo", task, video_path, ".mp4"),
|
|
5765
5766
|
mime="video/mp4",
|
|
5766
5767
|
key=f"automation_download_video_{task['id']}",
|
|
5767
5768
|
use_container_width=True,
|
|
@@ -41,6 +41,7 @@ PIPELINE_LOG_FILENAME = "pipeline_worker.json"
|
|
|
41
41
|
VIDEO_TIMEOUT_SECONDS = 20 * 60
|
|
42
42
|
LONG_STOCK_VIDEO_TIMEOUT_SECONDS = 90 * 60
|
|
43
43
|
VIDEO_IDLE_TIMEOUT_SECONDS = 10 * 60
|
|
44
|
+
STOCK_VIDEO_IDLE_TIMEOUT_SECONDS = 30 * 60
|
|
44
45
|
STALE_TASK_SECONDS = VIDEO_TIMEOUT_SECONDS + 5 * 60
|
|
45
46
|
WORKER_HEARTBEAT_TIMEOUT_SECONDS = 15
|
|
46
47
|
CASCADE_STAGE_ORDER = ("topic", "script", "title", "keywords", "video", "thumbnail_prompt", "thumbnail", "upload")
|
|
@@ -726,6 +727,18 @@ def _video_timeout_seconds(task: dict[str, Any], settings: dict[str, Any] | None
|
|
|
726
727
|
return VIDEO_TIMEOUT_SECONDS
|
|
727
728
|
|
|
728
729
|
|
|
730
|
+
def _video_idle_timeout_seconds(task: dict[str, Any], settings: dict[str, Any] | None = None) -> int:
|
|
731
|
+
"""Allow slow stock downloads to stay quiet without treating them as hung."""
|
|
732
|
+
configured = VIDEO_IDLE_TIMEOUT_SECONDS
|
|
733
|
+
if configured <= 0:
|
|
734
|
+
return configured
|
|
735
|
+
effective_settings = settings if isinstance(settings, dict) else _settings()
|
|
736
|
+
route = _normalise_video_route(task, effective_settings)
|
|
737
|
+
if route in {"pexels", "pixabay"}:
|
|
738
|
+
return max(configured, STOCK_VIDEO_IDLE_TIMEOUT_SECONDS)
|
|
739
|
+
return configured
|
|
740
|
+
|
|
741
|
+
|
|
729
742
|
def _task_stale_timeout_seconds(task: dict[str, Any]) -> int:
|
|
730
743
|
"""Keep stale-task recovery aligned with the actual execution budget."""
|
|
731
744
|
if str(task.get("stage") or "").strip().casefold() == "video":
|
|
@@ -1032,6 +1045,7 @@ def _run_video_helper_once(
|
|
|
1032
1045
|
line_queue: queue.Queue[str | None] = queue.Queue()
|
|
1033
1046
|
started_at = time.monotonic()
|
|
1034
1047
|
timeout_seconds = _video_timeout_seconds(task, settings)
|
|
1048
|
+
idle_timeout_seconds = _video_idle_timeout_seconds(task, settings)
|
|
1035
1049
|
process: subprocess.Popen[str] | None = None
|
|
1036
1050
|
|
|
1037
1051
|
def _read_output() -> None:
|
|
@@ -1125,11 +1139,11 @@ def _run_video_helper_once(
|
|
|
1125
1139
|
failure_metadata=metadata,
|
|
1126
1140
|
fallback_eligible=True,
|
|
1127
1141
|
)
|
|
1128
|
-
if time.monotonic() - last_activity_at >=
|
|
1142
|
+
if time.monotonic() - last_activity_at >= idle_timeout_seconds:
|
|
1129
1143
|
_stop_process(process)
|
|
1130
1144
|
message = (
|
|
1131
1145
|
"A etapa Vídeo não apresentou actividade comprovada do motor durante "
|
|
1132
|
-
f"{
|
|
1146
|
+
f"{idle_timeout_seconds // 60} minutos e foi encerrada."
|
|
1133
1147
|
)
|
|
1134
1148
|
metadata = _failure_attribution(task, settings, "video", error=message)
|
|
1135
1149
|
raise PipelineError(
|
package/package.json
CHANGED