@danhachuel/thunderbolt 0.2.15 → 0.2.17
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/MANUAL-INSTALACAO.md +6 -4
- package/README.md +3 -3
- package/app/main.py +24 -6
- package/hermes_ui/storage.py +2 -0
- package/package.json +1 -1
package/MANUAL-INSTALACAO.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Este manual descreve a instalação local da UI Thunderbolt, baseada no MoneyPrinterTurbo, utilizando o pacote npm `@danhachuel/thunderbolt`. O fluxo recomendado instala automaticamente o ambiente Python, as dependências da aplicação, as dependências do MoneyPrinterTurbo, o Streamlit e o suporte FFmpeg através de `imageio-ffmpeg`.
|
|
4
4
|
|
|
5
|
-
> **Versão deste manual:** 0.2.
|
|
5
|
+
> **Versão deste manual:** 0.2.17
|
|
6
6
|
> **Pacote npm:** `@danhachuel/thunderbolt`
|
|
7
7
|
> **Porta padrão da UI:** `localhost:3030`
|
|
8
8
|
> **Repositório:** [github.com/DanHachuel/thunderbolt](https://github.com/DanHachuel/thunderbolt)
|
|
@@ -100,13 +100,13 @@ Execute:
|
|
|
100
100
|
Windows PowerShell ou MobaXterm:
|
|
101
101
|
|
|
102
102
|
```powershell
|
|
103
|
-
npx.cmd --yes @danhachuel/thunderbolt@0.2.
|
|
103
|
+
npx.cmd --yes @danhachuel/thunderbolt@0.2.17 install
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
Linux/macOS:
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
|
-
npx --yes @danhachuel/thunderbolt@0.2.
|
|
109
|
+
npx --yes @danhachuel/thunderbolt@0.2.17 install
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
A instalação normal é **segura para actualizações**: preserva `storage`, Blueprints, Brandings, configurações e artefactos do utilizador. Remove apenas `.venv`, o clone técnico do MoneyPrinterTurbo e dependências que serão recriadas. Uma pasta antiga sem dados do utilizador, como `C:\Users\<utilizador>\AppData\Local\hermes` da tentativa incompleta, pode ser removida; uma pasta antiga que contenha Blueprints, Brandings ou storage é preservada e apenas avisada no terminal. Feche processos Python, Node, Streamlit e MobaXterm que estejam a usar as pastas antes de executar.
|
|
@@ -345,7 +345,9 @@ Na primeira execução, abra **Configurações** e reveja:
|
|
|
345
345
|
|---|---|
|
|
346
346
|
| Porta Streamlit | Definir a porta local da UI |
|
|
347
347
|
| Pasta MoneyPrinterTurbo | Indicar o clone local que será sincronizado com `config.toml` |
|
|
348
|
-
| YouTube Data API
|
|
348
|
+
| YouTube Data API Key | Permitir importar nome, handle e métricas públicas de canais |
|
|
349
|
+
| YouTube OAuth Client ID | Identificar a aplicação OAuth 2.0 do Google para operações autenticadas |
|
|
350
|
+
| YouTube OAuth Client Secret | Secret do mesmo cliente OAuth 2.0; não é a Data API Key |
|
|
349
351
|
| TikTok Client ID/Secret | Credenciais da aplicação; Redirect URI, scopes e autorização ficam no TikTok for Developers Playground |
|
|
350
352
|
|
|
351
353
|
As chaves devem ser inseridas apenas na configuração local. Não as coloque no GitHub, no `package.json`, em blueprints ou em ficheiros de estado versionados.
|
package/README.md
CHANGED
|
@@ -103,9 +103,9 @@ thunderbolt
|
|
|
103
103
|
No Windows PowerShell, se `npx` for bloqueado por `npx.ps1`, use directamente `npx.cmd`:
|
|
104
104
|
|
|
105
105
|
```powershell
|
|
106
|
-
npx.cmd --yes @danhachuel/thunderbolt@0.2.
|
|
107
|
-
npx.cmd --yes @danhachuel/thunderbolt@0.2.
|
|
108
|
-
npx.cmd --yes @danhachuel/thunderbolt@0.2.
|
|
106
|
+
npx.cmd --yes @danhachuel/thunderbolt@0.2.17 install
|
|
107
|
+
npx.cmd --yes @danhachuel/thunderbolt@0.2.17 doctor
|
|
108
|
+
npx.cmd --yes @danhachuel/thunderbolt@0.2.17
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
Como alternativa, pode permitir scripts para o seu utilizador:
|
package/app/main.py
CHANGED
|
@@ -9,6 +9,10 @@ import streamlit as st
|
|
|
9
9
|
ROOT = Path(__file__).resolve().parents[1]
|
|
10
10
|
if str(ROOT) not in sys.path:
|
|
11
11
|
sys.path.insert(0, str(ROOT))
|
|
12
|
+
try:
|
|
13
|
+
APP_VERSION = json.loads((ROOT / "package.json").read_text(encoding="utf-8")).get("version", "")
|
|
14
|
+
except (OSError, json.JSONDecodeError):
|
|
15
|
+
APP_VERSION = ""
|
|
12
16
|
|
|
13
17
|
from hermes_ui.domain import STAGES, create_batch, create_channel, create_tasks_for_batch, pipeline_summary, transition_task, update_channel
|
|
14
18
|
from hermes_ui.storage import BLUEPRINTS, ensure_storage, list_blueprint_files, load_blueprint_file, now, read_json, write_json
|
|
@@ -26,9 +30,14 @@ st.markdown("""
|
|
|
26
30
|
:root { --accent:#35a7ff; --bg:#0b1118; --card:#121b26; }
|
|
27
31
|
[data-testid="stAppViewContainer"] { background: radial-gradient(circle at top right, #13283b 0, #0b1118 42%); }
|
|
28
32
|
[data-testid="stSidebar"] { background:#091018; border-right:1px solid #1d3448; }
|
|
29
|
-
[data-testid="stSidebar"]
|
|
30
|
-
[data-testid="stSidebar"]
|
|
31
|
-
[data-testid="stSidebar"]
|
|
33
|
+
[data-testid="stSidebar"] .block-container { padding-top:0.28rem; padding-bottom:0.45rem; }
|
|
34
|
+
[data-testid="stSidebar"] > div:first-child { padding-top:0.28rem; }
|
|
35
|
+
[data-testid="stSidebar"] .tb-brand { display:flex; align-items:baseline; gap:0.42rem; margin:0 0 0.68rem 0; white-space:nowrap; }
|
|
36
|
+
[data-testid="stSidebar"] .tb-brand-name { color:#f4f8fb; font-size:1.38rem; line-height:1.15; font-weight:750; letter-spacing:-0.02em; }
|
|
37
|
+
[data-testid="stSidebar"] .tb-brand-version { color:#8ba6bb; font-size:0.92rem; line-height:1; font-weight:500; }
|
|
38
|
+
[data-testid="stSidebar"] [data-testid="stButton"] { margin:0.025rem 0 !important; }
|
|
39
|
+
[data-testid="stSidebar"] [data-testid="stButton"] button { min-height:1.72rem; height:1.72rem; justify-content:flex-start; text-align:left; padding:0.10rem 0.52rem; border-radius:7px; border:1px solid transparent; font-size:0.86rem; font-weight:550; }
|
|
40
|
+
[data-testid="stSidebar"] [data-testid="stButton"] p { margin:0; line-height:1; }
|
|
32
41
|
[data-testid="stSidebar"] [data-testid="stBaseButton-secondary"] { background:transparent; color:#e7edf2; }
|
|
33
42
|
[data-testid="stSidebar"] [data-testid="stBaseButton-secondary"]:hover { background:#1c252e; border-color:#2d3944; color:#ffffff; }
|
|
34
43
|
[data-testid="stSidebar"] [data-testid="stBaseButton-primary"] { background:#292929; color:#ffffff; border-color:#3a3a3a; }
|
|
@@ -341,7 +350,15 @@ def render_settings():
|
|
|
341
350
|
st.subheader("Execução local")
|
|
342
351
|
port = st.number_input("Porta Streamlit", 1, 65535, int(settings.get("port", 3030)))
|
|
343
352
|
moneyprinter_path = st.text_input("Pasta do motor de vídeo", settings.get("moneyprinter_path", ""), key="settings_moneyprinter_path")
|
|
344
|
-
|
|
353
|
+
st.markdown("**YouTube — API pública e OAuth 2.0**")
|
|
354
|
+
st.caption("A Data API Key consulta canais e estatísticas públicas. O Client ID e o Client Secret são credenciais OAuth 2.0 separadas, usadas para autorizar operações na conta, como upload.")
|
|
355
|
+
youtube_cols = st.columns(3)
|
|
356
|
+
with youtube_cols[0]:
|
|
357
|
+
youtube_api_key = text_setting("YouTube Data API Key", "youtube_api_key", secret=True, help_text="Chave criada em Google Cloud > APIs e serviços > Credenciais > Chave de API.")
|
|
358
|
+
with youtube_cols[1]:
|
|
359
|
+
youtube_client_id = text_setting("YouTube OAuth Client ID", "youtube_client_id", help_text="Client ID do OAuth 2.0 criado no Google Cloud.")
|
|
360
|
+
with youtube_cols[2]:
|
|
361
|
+
youtube_client_secret = text_setting("YouTube OAuth Client Secret", "youtube_client_secret", secret=True, help_text="Client Secret do mesmo cliente OAuth 2.0.")
|
|
345
362
|
|
|
346
363
|
with st.expander("Serviço, materiais e rede"):
|
|
347
364
|
cols = st.columns(2)
|
|
@@ -439,6 +456,7 @@ def render_settings():
|
|
|
439
456
|
if st.form_submit_button("Guardar configurações do Thunderbolt", type="primary"):
|
|
440
457
|
settings.update({
|
|
441
458
|
"port": port, "moneyprinter_path": moneyprinter_path, "youtube_api_key": youtube_api_key,
|
|
459
|
+
"youtube_client_id": youtube_client_id, "youtube_client_secret": youtube_client_secret,
|
|
442
460
|
"log_level": log_level, "listen_host": listen_host, "listen_port": listen_port, "video_source": video_source,
|
|
443
461
|
"endpoint": endpoint, "proxy_http": proxy_http, "proxy_https": proxy_https, "match_materials_to_script": match_materials_to_script,
|
|
444
462
|
"llm_provider": llm_provider, "openai_api_key": openai_api_key, "openai_base_url": openai_base_url, "openai_model_name": openai_model_name,
|
|
@@ -609,8 +627,8 @@ def main():
|
|
|
609
627
|
]
|
|
610
628
|
current_page = st.session_state.get("page", "Dashboard")
|
|
611
629
|
with st.sidebar:
|
|
612
|
-
|
|
613
|
-
st.
|
|
630
|
+
version_markup = f'<span class="tb-brand-version">{APP_VERSION}</span>' if APP_VERSION else ""
|
|
631
|
+
st.markdown(f'<div class="tb-brand"><span class="tb-brand-name">Thunderbolt</span>{version_markup}</div>', unsafe_allow_html=True)
|
|
614
632
|
for target, icon, label in pages:
|
|
615
633
|
if st.button(label, key=f"nav_{target}", icon=icon, use_container_width=True, type="primary" if current_page == target else "secondary"):
|
|
616
634
|
st.session_state["page"] = target
|
package/hermes_ui/storage.py
CHANGED
package/package.json
CHANGED