@danhachuel/thunderbolt 0.4.51 → 0.4.53
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 +24 -67
- package/package.json +1 -1
package/app/main.py
CHANGED
|
@@ -1907,30 +1907,26 @@ def render_tiktok_channels():
|
|
|
1907
1907
|
current_prompt = str(channel.get("default_prompt_master") or channel.get("prompt_master") or "")
|
|
1908
1908
|
selected_prompt = st.selectbox("Prompt Master", prompt_ids, index=prompt_ids.index(current_prompt) if current_prompt in prompt_ids else 0, format_func=lambda item: prompt_labels.get(item, item), key=f"tiktok_import_card_prompt_{channel_id}")
|
|
1909
1909
|
with card_cols[5]:
|
|
1910
|
-
st.caption("Formato")
|
|
1911
|
-
st.write("Portrait 9:16")
|
|
1912
|
-
if st.button("Guardar", key=f"tiktok_import_card_save_{channel_id}", use_container_width=True, type="primary"):
|
|
1913
|
-
update_channel(channel_id, {"platform": "tiktok", "default_prompt_master": selected_prompt, "prompt_master": selected_prompt, "video_aspect_ratio": "Portrait 9:16", "style_wide": "portrait"})
|
|
1914
|
-
st.success("Prompt Master do canal guardado.")
|
|
1915
|
-
st.rerun()
|
|
1916
|
-
actions = st.columns([1.0, 1.0, 1.0, 1.0])
|
|
1917
|
-
with actions[0]:
|
|
1918
1910
|
active = st.toggle("Activo", value=bool(channel.get("active", True)), key=f"tiktok_import_card_active_{channel_id}")
|
|
1919
1911
|
if active != bool(channel.get("active", True)):
|
|
1920
1912
|
update_channel(channel_id, {"active": active})
|
|
1921
1913
|
st.rerun()
|
|
1922
|
-
with actions[1]:
|
|
1923
1914
|
if st.button("Editar", key=f"tiktok_import_card_edit_{channel_id}"):
|
|
1924
1915
|
st.session_state[f"tiktok_edit_{channel_id}"] = not st.session_state.get(f"tiktok_edit_{channel_id}", False)
|
|
1925
1916
|
st.rerun()
|
|
1926
|
-
with actions[2]:
|
|
1927
|
-
if st.button("Editar nicho", key=f"tiktok_import_card_niche_{channel_id}"):
|
|
1928
|
-
st.session_state[f"tiktok_niche_{channel_id}"] = not st.session_state.get(f"tiktok_niche_{channel_id}", False)
|
|
1929
|
-
st.rerun()
|
|
1930
|
-
with actions[3]:
|
|
1931
1917
|
if st.button("Apagar card", key=f"tiktok_import_card_delete_{channel_id}"):
|
|
1932
1918
|
st.session_state[f"tiktok_delete_{channel_id}"] = True
|
|
1933
1919
|
st.rerun()
|
|
1920
|
+
st.caption("Formato: Portrait 9:16")
|
|
1921
|
+
if st.button("Guardar", key=f"tiktok_import_card_save_{channel_id}", use_container_width=True, type="primary"):
|
|
1922
|
+
update_channel(channel_id, {"platform": "tiktok", "default_prompt_master": selected_prompt, "prompt_master": selected_prompt, "video_aspect_ratio": "Portrait 9:16", "style_wide": "portrait"})
|
|
1923
|
+
st.success("Prompt Master do canal guardado.")
|
|
1924
|
+
st.rerun()
|
|
1925
|
+
niche_action = st.columns([1.0, 4.0])
|
|
1926
|
+
with niche_action[0]:
|
|
1927
|
+
if st.button("Editar nicho", key=f"tiktok_import_card_niche_{channel_id}"):
|
|
1928
|
+
st.session_state[f"tiktok_niche_{channel_id}"] = not st.session_state.get(f"tiktok_niche_{channel_id}", False)
|
|
1929
|
+
st.rerun()
|
|
1934
1930
|
if st.session_state.get(f"tiktok_delete_{channel_id}"):
|
|
1935
1931
|
st.warning("Apagar este canal TikTok e os dados locais associados?")
|
|
1936
1932
|
confirm_cols = st.columns(2)
|
|
@@ -6813,7 +6809,7 @@ def render_settings():
|
|
|
6813
6809
|
key=f"settings_{key}",
|
|
6814
6810
|
)
|
|
6815
6811
|
|
|
6816
|
-
api_keys_tab, upload_api_keys_tab,
|
|
6812
|
+
api_keys_tab, upload_api_keys_tab, ai_influencers_tab, voice_test_tab = render_localized_tabs(["API Keys", "API Keys Upload", "AI Influencers", "Teste de Voz"])
|
|
6817
6813
|
|
|
6818
6814
|
with api_keys_tab:
|
|
6819
6815
|
with st.container(border=True):
|
|
@@ -7002,41 +6998,18 @@ def render_settings():
|
|
|
7002
6998
|
persist_callback=save_google_lyria,
|
|
7003
6999
|
)
|
|
7004
7000
|
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
)
|
|
7018
|
-
|
|
7019
|
-
with st.expander("Postiz", expanded=False):
|
|
7020
|
-
st.caption("O Thunderbolt é o cliente. A API key é enviada exclusivamente ao servidor Postiz configurado; não é colocada em URLs, logs ou repositório.")
|
|
7021
|
-
postiz_enabled = st.checkbox("Activar Postiz como fallback final", bool(settings.get("postiz_enabled", False)))
|
|
7022
|
-
postiz_mode = st.selectbox("Modo de ligação", ["api", "mcp"], index=0 if settings.get("postiz_mode", "api") != "mcp" else 1, help="API é o modo determinístico de upload. MCP fica disponível para uma ligação compatível com Streamable HTTP.")
|
|
7023
|
-
postiz_cols = st.columns(2)
|
|
7024
|
-
with postiz_cols[0]:
|
|
7025
|
-
postiz_api_key = text_setting("Postiz API key", "postiz_api_key", secret=True, help_text="API key criada nas definições do Postiz. A API HTTP usa o valor bruto no cabeçalho Authorization.")
|
|
7026
|
-
_render_credential_status(postiz_api_key)
|
|
7027
|
-
postiz_base_url = text_setting("Postiz Public API Base URL", "postiz_base_url", help_text="Cloud: https://api.postiz.com/public/v1 · Self-hosted: https://seu-servidor/api/public/v1")
|
|
7028
|
-
postiz_integration_id = text_setting("Postiz integração padrão", "postiz_integration_id", help_text="ID do canal/integração devolvido por GET /integrations.")
|
|
7029
|
-
with postiz_cols[1]:
|
|
7030
|
-
postiz_mcp_url = text_setting("Postiz MCP URL", "postiz_mcp_url", help_text="Cloud: https://api.postiz.com/mcp · o cliente acrescenta a API key conforme o modo escolhido.")
|
|
7031
|
-
postiz_auto_publish = st.checkbox("Permitir publicação imediata no Postiz", bool(settings.get("postiz_auto_publish", False)))
|
|
7032
|
-
st.caption("No Upload, a aba Postiz permite carregar as integrações e enviar vídeos manualmente. No fluxo recomendado, Postiz só é tentado depois da API Oficial e do Upload directo.")
|
|
7033
|
-
_render_api_test_control(
|
|
7034
|
-
settings,
|
|
7035
|
-
"postiz",
|
|
7036
|
-
lambda: test_postiz_credentials(postiz_api_key, postiz_base_url),
|
|
7037
|
-
widget_key="api_test_postiz",
|
|
7038
|
-
)
|
|
7039
|
-
|
|
7001
|
+
upload_post_enabled = bool(settings.get("upload_post_enabled", False))
|
|
7002
|
+
upload_post_api_key = str(settings.get("upload_post_api_key") or "")
|
|
7003
|
+
upload_post_username = str(settings.get("upload_post_username") or "")
|
|
7004
|
+
upload_post_platforms = str(settings.get("upload_post_platforms") or "youtube,tiktok")
|
|
7005
|
+
upload_post_auto_upload = bool(settings.get("upload_post_auto_upload", False))
|
|
7006
|
+
postiz_enabled = bool(settings.get("postiz_enabled", False))
|
|
7007
|
+
postiz_api_key = str(settings.get("postiz_api_key") or "")
|
|
7008
|
+
postiz_base_url = str(settings.get("postiz_base_url") or "https://api.postiz.com/public/v1")
|
|
7009
|
+
postiz_mcp_url = str(settings.get("postiz_mcp_url") or "https://api.postiz.com/mcp")
|
|
7010
|
+
postiz_mode = str(settings.get("postiz_mode") or "api")
|
|
7011
|
+
postiz_integration_id = str(settings.get("postiz_integration_id") or "")
|
|
7012
|
+
postiz_auto_publish = bool(settings.get("postiz_auto_publish", False))
|
|
7040
7013
|
save_all_settings = st.form_submit_button("Guardar configurações do Thunderbolt", type="primary")
|
|
7041
7014
|
if save_all_settings:
|
|
7042
7015
|
settings.update({
|
|
@@ -7071,13 +7044,7 @@ def render_settings():
|
|
|
7071
7044
|
st.subheader("API Keys Upload")
|
|
7072
7045
|
st.caption("Credenciais e integrações utilizadas pelos fluxos de publicação. Cada grupo fica separado para evitar misturar chaves de geração com chaves de upload.")
|
|
7073
7046
|
with st.expander("Contas Google", expanded=False):
|
|
7074
|
-
|
|
7075
|
-
if google_accounts:
|
|
7076
|
-
for account in google_accounts:
|
|
7077
|
-
st.markdown(f"**{account.get('label') or 'Conta Google'}** — {account.get('email') or 'sem e-mail'}")
|
|
7078
|
-
st.info("Para editar documentos de cookies, OAuth e canais associados, abra a subaba Contas Google.")
|
|
7079
|
-
else:
|
|
7080
|
-
st.info("Ainda não existem Contas Google configuradas.")
|
|
7047
|
+
render_google_accounts()
|
|
7081
7048
|
with st.expander("API Innertube", expanded=False):
|
|
7082
7049
|
st.caption("INNERTUBE_API_KEY global usada pelo Upload directo para todas as contas Google/YouTube.")
|
|
7083
7050
|
upload_innertube = st.text_input("INNERTUBE_API_KEY", value=str(settings.get("direct_innertube_api_key") or settings.get("INNERTUBE_API_KEY") or ""), type="password", key="upload_api_innertube_key")
|
|
@@ -7116,16 +7083,6 @@ def render_settings():
|
|
|
7116
7083
|
write_json("settings.json", settings)
|
|
7117
7084
|
st.success("Postiz guardado.")
|
|
7118
7085
|
st.rerun()
|
|
7119
|
-
with google_accounts_tab:
|
|
7120
|
-
render_google_accounts()
|
|
7121
|
-
|
|
7122
|
-
with tiktok_api_tab:
|
|
7123
|
-
st.subheader("API Tiktok")
|
|
7124
|
-
st.info("A configuração desta API foi reorganizada em Configuração API > API Keys Upload > API Tiktok.")
|
|
7125
|
-
|
|
7126
|
-
with bilibili_api_tab:
|
|
7127
|
-
st.subheader("API Bilibili")
|
|
7128
|
-
st.info("A configuração desta API foi reorganizada em Configuração API > API Keys Upload > API Bilibili.")
|
|
7129
7086
|
with ai_influencers_tab:
|
|
7130
7087
|
st.subheader("AI Influencers")
|
|
7131
7088
|
st.caption("Estado do backend usado por Personagens e Geração de Conteúdo IA. O selector e as credenciais são editados nesta aba, em Banco de Dados Influencers.")
|
package/package.json
CHANGED