@danhachuel/thunderbolt 0.3.98 → 0.3.99

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.
@@ -6,6 +6,7 @@ import base64
6
6
  import hashlib
7
7
  import io
8
8
  import json
9
+ import mimetypes
9
10
  from pathlib import Path
10
11
  from typing import Any, Mapping
11
12
 
@@ -294,24 +295,38 @@ def _render_content_history(repository: Any, influencer_id: str = "") -> None:
294
295
  if not records:
295
296
  return
296
297
  st.subheader("Conteúdos gerados")
297
- rows = []
298
298
  for item in records:
299
- rows.append({
300
- "Tipo": str(item.get("content_type") or "").capitalize(),
301
- "Estado": CONTENT_STATES.get(str(item.get("state") or ""), str(item.get("state") or "—")),
302
- "Provider": f"{item.get('provider') or '—'} · {item.get('model') or '—'}",
303
- "Plataforma": item.get("platform") or "",
304
- "Artefacto": item.get("artifact_path") or item.get("error") or "—",
305
- "Criado": item.get("created_at") or "—",
306
- })
307
- st.dataframe(rows, use_container_width=True, hide_index=True)
308
- latest = records[0]
309
- artifact = Path(str(latest.get("artifact_path") or ""))
310
- if artifact.is_file() and latest.get("state") == "completed":
311
- if latest.get("content_type") == "image":
312
- st.image(str(artifact), caption="Última imagem gerada", use_container_width=True)
313
- elif latest.get("content_type") == "video":
314
- st.video(str(artifact))
299
+ content_id = str(item.get("id") or "content")
300
+ content_type = str(item.get("content_type") or "").strip().lower()
301
+ artifact = Path(str(item.get("artifact_path") or ""))
302
+ state = str(item.get("state") or "")
303
+ type_label = "Imagem" if content_type == "image" else "Vídeo" if content_type == "video" else "Conteúdo"
304
+ with st.container(border=True):
305
+ preview_col, detail_col = st.columns([1.25, 2.75])
306
+ with preview_col:
307
+ if artifact.is_file() and content_type == "image":
308
+ st.image(str(artifact), caption=f"{type_label} gerada", use_container_width=True)
309
+ elif artifact.is_file() and content_type == "video":
310
+ st.video(str(artifact))
311
+ else:
312
+ st.caption("Artefacto indisponível")
313
+ with detail_col:
314
+ st.write(f"**{type_label} · {CONTENT_STATES.get(state, state or '—')}**")
315
+ st.caption(f"Provider: {item.get('provider') or '—'} · {item.get('model') or '—'}")
316
+ st.caption(f"Plataforma: {item.get('platform') or '—'} · Criado: {item.get('created_at') or '—'}")
317
+ if item.get("error"):
318
+ st.error(str(item.get("error") or "")[:700])
319
+ if artifact.is_file() and state == "completed" and content_type in {"image", "video"}:
320
+ fallback_mime = "image/png" if content_type == "image" else "video/mp4"
321
+ mime = mimetypes.guess_type(artifact.name)[0] or fallback_mime
322
+ st.download_button(
323
+ f"Descarregar {type_label.casefold()}",
324
+ data=artifact.read_bytes(),
325
+ file_name=artifact.name,
326
+ mime=mime,
327
+ key=f"influencer_content_download_{content_type}_{content_id}",
328
+ use_container_width=True,
329
+ )
315
330
 
316
331
 
317
332
  def _store_uploaded_file(uploaded: Any, folder: str) -> Path:
package/app/main.py CHANGED
@@ -3844,7 +3844,7 @@ def render_music_backlog() -> None:
3844
3844
  music_file = Path(music_path)
3845
3845
  st.success("Música pronta; pode continuar para o destino configurado.")
3846
3846
  st.download_button(
3847
- "Descarregar música pronta",
3847
+ "Descarregar música",
3848
3848
  data=music_file.read_bytes(),
3849
3849
  file_name=music_file.name,
3850
3850
  mime="audio/mpeg",
@@ -3921,6 +3921,14 @@ def render_thumbnails():
3921
3921
  image_path = record.get("image_path")
3922
3922
  if image_path and image_path.is_file():
3923
3923
  st.image(str(image_path), use_container_width=True)
3924
+ st.download_button(
3925
+ "Descarregar thumbnail",
3926
+ data=image_path.read_bytes(),
3927
+ file_name=image_path.name,
3928
+ mime="image/jpeg" if image_path.suffix.lower() in {".jpg", ".jpeg"} else "image/png",
3929
+ key=f"thumbnail_download_{task_id}_{record['variant_index']}",
3930
+ use_container_width=True,
3931
+ )
3924
3932
  else:
3925
3933
  st.markdown("### Sem imagem")
3926
3934
  st.caption("Imagem ainda não gerada")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.3.98",
3
+ "version": "0.3.99",
4
4
  "description": "Thunderbolt — interface local para operação de canais faceless e motor MoneyPrinterTurbo",
5
5
  "license": "MIT",
6
6
  "main": "scripts/cli.mjs",