@danhachuel/thunderbolt 0.5.84 → 0.5.86
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/README.md +1 -1
- package/app/main.py +1 -0
- package/hermes_ui/media_downloader.py +28 -1
- package/package.json +1 -1
- package/requirements.txt +2 -1
- package/scripts/install.mjs +1 -1
package/README.md
CHANGED
|
@@ -141,7 +141,7 @@ A correcção da integração Nano Banana remove o campo de entrega `inline` rej
|
|
|
141
141
|
|
|
142
142
|
A página **AI Influencers > Tutorial Meta** apresenta o guia de configuração de uma conta Instagram profissional e das credenciais Meta para automações com n8n, distribuído localmente em `seed/references/guide-instagram.md` e com ligação para a [fonte original no GitHub](https://github.com/gyoridavid/ai_agents_az/blob/main/episode_8/guide-instagram.md). A página **Configurações > Notificações** mantém um histórico persistente de conclusões e falhas, reconcilia estados escritos por componentes locais e disponibiliza um checkbox independente para cada operação mapeada. A subaba **Geral** mantém esse centro local; a subaba **Telegram** permite configurar Bot Token, Chat ID e proxy opcional e envia as mesmas notificações pela Bot API oficial, sem polling ou mensagens recebidas. As notificações novas também aparecem automaticamente como pop-ups no canto inferior direito enquanto o utilizador está noutra página, sem precisar de abrir Notificações; cada aviso é mostrado uma vez por sessão e o histórico continua a controlar o estado de leitura. A página **Configurações > Logs**, colocada imediatamente abaixo de Notificações e acima de Configuração API, apresenta o histórico unificado de tarefas e notificações, com filtro livre por operação, filtros adicionais por operação e estado, e as colunas Operação, Estado, Data, Hora, Registo, Origem, Progresso e Detalhes. A tabela mantém uma barra vertical e, quando a soma das colunas excede a largura disponível, disponibiliza também uma barra de rolagem horizontal na parte inferior para consultar integralmente células longas, sobretudo em **Detalhes**.
|
|
143
143
|
|
|
144
|
-
A página **Edição > Download Mídia** utiliza a API Python do [yt-dlp](https://github.com/yt-dlp/yt-dlp) para descarregar vídeos e áudio de URLs públicas, com qualidade, contentor, formato de áudio, legendas, metadados, playlists, progresso e histórico local em `storage/downloads/` e `storage/state/media_downloads.json`. Conversão e combinação de streams podem exigir FFmpeg.
|
|
144
|
+
A página **Edição > Download Mídia** utiliza a API Python do [yt-dlp](https://github.com/yt-dlp/yt-dlp) para descarregar vídeos e áudio de URLs públicas, com qualidade, contentor, formato de áudio, legendas, metadados, playlists, progresso e histórico local em `storage/downloads/` e `storage/state/media_downloads.json`. O Thunderbolt instala o pacote Python **Deno** e resolve automaticamente o executável gerido por ele, passando-o ao yt-dlp como runtime `deno:<caminho>`. O pacote `yt-dlp[default]` inclui também os scripts EJS necessários para os desafios JavaScript do YouTube. Se existir um Deno instalado no `PATH`, ele é usado como fallback. Conversão e combinação de streams podem exigir FFmpeg.
|
|
145
145
|
|
|
146
146
|
## Catálogo comum do Backlog e da Automação
|
|
147
147
|
|
package/app/main.py
CHANGED
|
@@ -5461,6 +5461,7 @@ def render_automation():
|
|
|
5461
5461
|
blueprint_ids, blueprint_labels, current_blueprint, voice_options, current_voice = channel_default_options(channel)
|
|
5462
5462
|
automation_blueprint = current_blueprint
|
|
5463
5463
|
automation_voice = current_voice
|
|
5464
|
+
paired_thumbnail = thumbnail_blueprint_for_blueprint(automation_blueprint)
|
|
5464
5465
|
automation_format = str(channel.get("format") or "wide")
|
|
5465
5466
|
header_cols = st.columns([0.62, 2.15, 1.55, 1.25, 1.25, 1.45, 1.3], gap="small")
|
|
5466
5467
|
with header_cols[0]:
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import hashlib
|
|
4
4
|
import re
|
|
5
|
+
import shutil
|
|
5
6
|
import uuid
|
|
6
7
|
from datetime import datetime, timezone
|
|
7
8
|
from pathlib import Path
|
|
@@ -43,6 +44,22 @@ def _download_root() -> Path:
|
|
|
43
44
|
return storage.MEDIA_DOWNLOADS.resolve()
|
|
44
45
|
|
|
45
46
|
|
|
47
|
+
def _deno_runtime_path() -> str | None:
|
|
48
|
+
"""Resolve the project-managed Deno binary, with a PATH fallback."""
|
|
49
|
+
try:
|
|
50
|
+
import deno # type: ignore
|
|
51
|
+
|
|
52
|
+
finder = getattr(deno, "find_deno_bin", None)
|
|
53
|
+
if callable(finder):
|
|
54
|
+
candidate = Path(str(finder())).expanduser()
|
|
55
|
+
if candidate.is_file():
|
|
56
|
+
return str(candidate.resolve())
|
|
57
|
+
except (ImportError, OSError, RuntimeError, TypeError, ValueError):
|
|
58
|
+
pass
|
|
59
|
+
candidate = shutil.which("deno")
|
|
60
|
+
return str(Path(candidate).resolve()) if candidate else None
|
|
61
|
+
|
|
62
|
+
|
|
46
63
|
def _safe_download_path(value: str | Path) -> Path | None:
|
|
47
64
|
root = _download_root()
|
|
48
65
|
candidate = Path(value)
|
|
@@ -136,6 +153,10 @@ def build_download_options(
|
|
|
136
153
|
"overwrites": False,
|
|
137
154
|
"paths": {"home": str(root)},
|
|
138
155
|
}
|
|
156
|
+
deno_path = _deno_runtime_path()
|
|
157
|
+
if deno_path:
|
|
158
|
+
# Equivalent to the CLI argument --js-runtimes deno:<path>.
|
|
159
|
+
options["js_runtimes"] = {"deno": deno_path}
|
|
139
160
|
if progress_hook is not None:
|
|
140
161
|
options["progress_hooks"] = [progress_hook]
|
|
141
162
|
if normalized_mode == "audio":
|
|
@@ -183,7 +204,13 @@ def media_download_file(record: dict[str, Any], filename: str) -> Path | None:
|
|
|
183
204
|
|
|
184
205
|
|
|
185
206
|
def dependency_status() -> dict[str, Any]:
|
|
186
|
-
|
|
207
|
+
deno_path = _deno_runtime_path()
|
|
208
|
+
return {
|
|
209
|
+
"yt_dlp": yt_dlp is not None,
|
|
210
|
+
"deno": bool(deno_path),
|
|
211
|
+
"deno_path": deno_path or "",
|
|
212
|
+
"ffmpeg_note": "A conversão/combinação de streams pode exigir FFmpeg.",
|
|
213
|
+
}
|
|
187
214
|
|
|
188
215
|
|
|
189
216
|
def _files_from_info(info: Any, started_at: float) -> list[Path]:
|
package/package.json
CHANGED
package/requirements.txt
CHANGED
package/scripts/install.mjs
CHANGED
|
@@ -470,7 +470,7 @@ function writeSettings(moneyprinterPath) {
|
|
|
470
470
|
|
|
471
471
|
function installThunderboltDependencies(python) {
|
|
472
472
|
if (!existsSync(pythonBin)) run(python.command, [...python.args, "-m", "venv", venvPath]);
|
|
473
|
-
installRequirementIfNeeded(join(root, "requirements.txt"), "thunderbolt_requirements_sha256", ["streamlit", "requests", "pandas", "toml", "imageio_ffmpeg", "edge_tts", "google.auth", "google_auth_oauthlib", "googleapiclient", "yt_dlp", "youtube_transcript_api", "huggingface_hub"], "Thunderbolt");
|
|
473
|
+
installRequirementIfNeeded(join(root, "requirements.txt"), "thunderbolt_requirements_sha256", ["streamlit", "requests", "pandas", "toml", "imageio_ffmpeg", "edge_tts", "google.auth", "google_auth_oauthlib", "googleapiclient", "yt_dlp", "deno", "youtube_transcript_api", "huggingface_hub"], "Thunderbolt");
|
|
474
474
|
}
|
|
475
475
|
|
|
476
476
|
function installMoneyPrinterDependencies(moneyprinterPath) {
|