@danhachuel/thunderbolt 0.4.52 → 0.4.54
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 +60 -98
- package/package.json +1 -1
package/app/main.py
CHANGED
|
@@ -5899,7 +5899,7 @@ def render_bilibili_api_cards(settings: dict[str, Any]) -> None:
|
|
|
5899
5899
|
st.success("Novo card Bilibili criado.")
|
|
5900
5900
|
st.rerun()
|
|
5901
5901
|
|
|
5902
|
-
def render_google_accounts():
|
|
5902
|
+
def render_google_accounts(*, include_innertube: bool = True):
|
|
5903
5903
|
st.title("Contas Google")
|
|
5904
5904
|
st.caption("Gestão das contas Google/YouTube, documentos de credenciais, canais em lote e credenciais globais do YouTube.")
|
|
5905
5905
|
settings = read_json("settings.json", {})
|
|
@@ -6065,57 +6065,58 @@ def render_google_accounts():
|
|
|
6065
6065
|
if youtube_accounts_missing_document:
|
|
6066
6066
|
st.info("Contas que ainda precisam de dados no documento: " + ", ".join(youtube_accounts_missing_document))
|
|
6067
6067
|
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6068
|
+
if include_innertube:
|
|
6069
|
+
st.divider()
|
|
6070
|
+
st.markdown("### INNERTUBE_API_KEY")
|
|
6071
|
+
st.caption("Esta é uma chave API global do YouTube: aplica-se a todas as contas Google/YouTube e a todo o sistema. Não é associada a uma conta específica, não faz parte dos documentos de cookies/credenciais e não é editada no separador API Keys.")
|
|
6072
|
+
configured_global_innertube_api_key = str(settings.get("direct_innertube_api_key") or settings.get("INNERTUBE_API_KEY") or "").strip()
|
|
6073
|
+
current_innertube_api_key = configured_global_innertube_api_key
|
|
6074
|
+
if not current_innertube_api_key:
|
|
6075
|
+
# Migrate values created by older releases, which incorrectly stored
|
|
6076
|
+
# the key inside a selected Google account. The first legacy value is
|
|
6077
|
+
# retained as the single global value and all account copies are removed.
|
|
6078
|
+
for legacy_account in batch_accounts:
|
|
6079
|
+
current_innertube_api_key = str(legacy_account.get("innertube_api_key") or legacy_account.get("INNERTUBE_API_KEY") or "").strip()
|
|
6080
|
+
if current_innertube_api_key:
|
|
6081
|
+
break
|
|
6079
6082
|
if current_innertube_api_key:
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
+
settings["direct_innertube_api_key"] = current_innertube_api_key
|
|
6084
|
+
settings.pop("INNERTUBE_API_KEY", None)
|
|
6085
|
+
for legacy_account in batch_accounts:
|
|
6086
|
+
legacy_account.pop("innertube_api_key", None)
|
|
6087
|
+
legacy_account.pop("INNERTUBE_API_KEY", None)
|
|
6088
|
+
settings["youtube_batch_accounts"] = batch_accounts
|
|
6089
|
+
write_json("settings.json", settings)
|
|
6090
|
+
innertube_status_cols = st.columns([3.2, 1.2])
|
|
6091
|
+
with innertube_status_cols[0]:
|
|
6092
|
+
st.caption("Estado da chave global")
|
|
6093
|
+
with innertube_status_cols[1]:
|
|
6094
|
+
_render_credential_status(current_innertube_api_key)
|
|
6095
|
+
with st.form("innertube_api_key_form"):
|
|
6096
|
+
innertube_api_key_value = st.text_input(
|
|
6097
|
+
"INNERTUBE_API_KEY",
|
|
6098
|
+
value=current_innertube_api_key,
|
|
6099
|
+
type="password",
|
|
6100
|
+
key="global_innertube_api_key",
|
|
6101
|
+
help="Chave global usada pelo Upload directo para todas as contas Google/YouTube. Guarde-a na configuração global, separada dos documentos de cookies.",
|
|
6102
|
+
)
|
|
6103
|
+
_render_api_test_control(
|
|
6104
|
+
settings,
|
|
6105
|
+
"innertube",
|
|
6106
|
+
lambda: test_innertube_api_key(innertube_api_key_value),
|
|
6107
|
+
widget_key="api_test_innertube",
|
|
6108
|
+
)
|
|
6109
|
+
save_innertube_api_key = st.form_submit_button("Guardar INNERTUBE_API_KEY global", type="primary", use_container_width=True)
|
|
6110
|
+
if save_innertube_api_key:
|
|
6111
|
+
settings["direct_innertube_api_key"] = innertube_api_key_value.strip()
|
|
6083
6112
|
settings.pop("INNERTUBE_API_KEY", None)
|
|
6084
6113
|
for legacy_account in batch_accounts:
|
|
6085
6114
|
legacy_account.pop("innertube_api_key", None)
|
|
6086
6115
|
legacy_account.pop("INNERTUBE_API_KEY", None)
|
|
6087
6116
|
settings["youtube_batch_accounts"] = batch_accounts
|
|
6088
6117
|
write_json("settings.json", settings)
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
st.caption("Estado da chave global")
|
|
6092
|
-
with innertube_status_cols[1]:
|
|
6093
|
-
_render_credential_status(current_innertube_api_key)
|
|
6094
|
-
with st.form("innertube_api_key_form"):
|
|
6095
|
-
innertube_api_key_value = st.text_input(
|
|
6096
|
-
"INNERTUBE_API_KEY",
|
|
6097
|
-
value=current_innertube_api_key,
|
|
6098
|
-
type="password",
|
|
6099
|
-
key="global_innertube_api_key",
|
|
6100
|
-
help="Chave global usada pelo Upload directo para todas as contas Google/YouTube. Guarde-a na configuração global, separada dos documentos de cookies.",
|
|
6101
|
-
)
|
|
6102
|
-
_render_api_test_control(
|
|
6103
|
-
settings,
|
|
6104
|
-
"innertube",
|
|
6105
|
-
lambda: test_innertube_api_key(innertube_api_key_value),
|
|
6106
|
-
widget_key="api_test_innertube",
|
|
6107
|
-
)
|
|
6108
|
-
save_innertube_api_key = st.form_submit_button("Guardar INNERTUBE_API_KEY global", type="primary", use_container_width=True)
|
|
6109
|
-
if save_innertube_api_key:
|
|
6110
|
-
settings["direct_innertube_api_key"] = innertube_api_key_value.strip()
|
|
6111
|
-
settings.pop("INNERTUBE_API_KEY", None)
|
|
6112
|
-
for legacy_account in batch_accounts:
|
|
6113
|
-
legacy_account.pop("innertube_api_key", None)
|
|
6114
|
-
legacy_account.pop("INNERTUBE_API_KEY", None)
|
|
6115
|
-
settings["youtube_batch_accounts"] = batch_accounts
|
|
6116
|
-
write_json("settings.json", settings)
|
|
6117
|
-
st.success("INNERTUBE_API_KEY global guardada para todas as contas Google/YouTube e para todo o sistema.")
|
|
6118
|
-
st.rerun()
|
|
6118
|
+
st.success("INNERTUBE_API_KEY global guardada para todas as contas Google/YouTube e para todo o sistema.")
|
|
6119
|
+
st.rerun()
|
|
6119
6120
|
|
|
6120
6121
|
st.divider()
|
|
6121
6122
|
st.markdown("### Adicionar outra conta Gmail")
|
|
@@ -6809,7 +6810,7 @@ def render_settings():
|
|
|
6809
6810
|
key=f"settings_{key}",
|
|
6810
6811
|
)
|
|
6811
6812
|
|
|
6812
|
-
api_keys_tab, upload_api_keys_tab,
|
|
6813
|
+
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"])
|
|
6813
6814
|
|
|
6814
6815
|
with api_keys_tab:
|
|
6815
6816
|
with st.container(border=True):
|
|
@@ -6998,41 +6999,18 @@ def render_settings():
|
|
|
6998
6999
|
persist_callback=save_google_lyria,
|
|
6999
7000
|
)
|
|
7000
7001
|
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
)
|
|
7014
|
-
|
|
7015
|
-
with st.expander("Postiz", expanded=False):
|
|
7016
|
-
st.caption("O Thunderbolt é o cliente. A API key é enviada exclusivamente ao servidor Postiz configurado; não é colocada em URLs, logs ou repositório.")
|
|
7017
|
-
postiz_enabled = st.checkbox("Activar Postiz como fallback final", bool(settings.get("postiz_enabled", False)))
|
|
7018
|
-
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.")
|
|
7019
|
-
postiz_cols = st.columns(2)
|
|
7020
|
-
with postiz_cols[0]:
|
|
7021
|
-
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.")
|
|
7022
|
-
_render_credential_status(postiz_api_key)
|
|
7023
|
-
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")
|
|
7024
|
-
postiz_integration_id = text_setting("Postiz integração padrão", "postiz_integration_id", help_text="ID do canal/integração devolvido por GET /integrations.")
|
|
7025
|
-
with postiz_cols[1]:
|
|
7026
|
-
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.")
|
|
7027
|
-
postiz_auto_publish = st.checkbox("Permitir publicação imediata no Postiz", bool(settings.get("postiz_auto_publish", False)))
|
|
7028
|
-
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.")
|
|
7029
|
-
_render_api_test_control(
|
|
7030
|
-
settings,
|
|
7031
|
-
"postiz",
|
|
7032
|
-
lambda: test_postiz_credentials(postiz_api_key, postiz_base_url),
|
|
7033
|
-
widget_key="api_test_postiz",
|
|
7034
|
-
)
|
|
7035
|
-
|
|
7002
|
+
upload_post_enabled = bool(settings.get("upload_post_enabled", False))
|
|
7003
|
+
upload_post_api_key = str(settings.get("upload_post_api_key") or "")
|
|
7004
|
+
upload_post_username = str(settings.get("upload_post_username") or "")
|
|
7005
|
+
upload_post_platforms = str(settings.get("upload_post_platforms") or "youtube,tiktok")
|
|
7006
|
+
upload_post_auto_upload = bool(settings.get("upload_post_auto_upload", False))
|
|
7007
|
+
postiz_enabled = bool(settings.get("postiz_enabled", False))
|
|
7008
|
+
postiz_api_key = str(settings.get("postiz_api_key") or "")
|
|
7009
|
+
postiz_base_url = str(settings.get("postiz_base_url") or "https://api.postiz.com/public/v1")
|
|
7010
|
+
postiz_mcp_url = str(settings.get("postiz_mcp_url") or "https://api.postiz.com/mcp")
|
|
7011
|
+
postiz_mode = str(settings.get("postiz_mode") or "api")
|
|
7012
|
+
postiz_integration_id = str(settings.get("postiz_integration_id") or "")
|
|
7013
|
+
postiz_auto_publish = bool(settings.get("postiz_auto_publish", False))
|
|
7036
7014
|
save_all_settings = st.form_submit_button("Guardar configurações do Thunderbolt", type="primary")
|
|
7037
7015
|
if save_all_settings:
|
|
7038
7016
|
settings.update({
|
|
@@ -7067,13 +7045,7 @@ def render_settings():
|
|
|
7067
7045
|
st.subheader("API Keys Upload")
|
|
7068
7046
|
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.")
|
|
7069
7047
|
with st.expander("Contas Google", expanded=False):
|
|
7070
|
-
|
|
7071
|
-
if google_accounts:
|
|
7072
|
-
for account in google_accounts:
|
|
7073
|
-
st.markdown(f"**{account.get('label') or 'Conta Google'}** — {account.get('email') or 'sem e-mail'}")
|
|
7074
|
-
st.info("Para editar documentos de cookies, OAuth e canais associados, abra a subaba Contas Google.")
|
|
7075
|
-
else:
|
|
7076
|
-
st.info("Ainda não existem Contas Google configuradas.")
|
|
7048
|
+
render_google_accounts(include_innertube=False)
|
|
7077
7049
|
with st.expander("API Innertube", expanded=False):
|
|
7078
7050
|
st.caption("INNERTUBE_API_KEY global usada pelo Upload directo para todas as contas Google/YouTube.")
|
|
7079
7051
|
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")
|
|
@@ -7112,16 +7084,6 @@ def render_settings():
|
|
|
7112
7084
|
write_json("settings.json", settings)
|
|
7113
7085
|
st.success("Postiz guardado.")
|
|
7114
7086
|
st.rerun()
|
|
7115
|
-
with google_accounts_tab:
|
|
7116
|
-
render_google_accounts()
|
|
7117
|
-
|
|
7118
|
-
with tiktok_api_tab:
|
|
7119
|
-
st.subheader("API Tiktok")
|
|
7120
|
-
st.info("A configuração desta API foi reorganizada em Configuração API > API Keys Upload > API Tiktok.")
|
|
7121
|
-
|
|
7122
|
-
with bilibili_api_tab:
|
|
7123
|
-
st.subheader("API Bilibili")
|
|
7124
|
-
st.info("A configuração desta API foi reorganizada em Configuração API > API Keys Upload > API Bilibili.")
|
|
7125
7087
|
with ai_influencers_tab:
|
|
7126
7088
|
st.subheader("AI Influencers")
|
|
7127
7089
|
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