@danhachuel/thunderbolt 0.4.67 → 0.4.69

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.
Files changed (2) hide show
  1. package/app/main.py +35 -17
  2. package/package.json +1 -1
package/app/main.py CHANGED
@@ -1855,8 +1855,20 @@ def format_metric_number(value: Any) -> str:
1855
1855
  return str(value)
1856
1856
 
1857
1857
 
1858
+ def classify_channel_platform(channel: Any) -> str:
1859
+ """Return the persisted platform, or unknown when it is not explicit."""
1860
+ if not isinstance(channel, dict):
1861
+ return "unknown"
1862
+ value = str(channel.get("platform") or "").strip().casefold().replace(" ", "")
1863
+ if value in {"youtube", "yt"}:
1864
+ return "youtube"
1865
+ if value in {"tiktok", "tik-tok", "tt"}:
1866
+ return "tiktok"
1867
+ return "unknown"
1868
+
1869
+
1858
1870
  def _tiktok_channel_records() -> list[dict[str, Any]]:
1859
- return [channel for channel in read_json("channels.json", []) if isinstance(channel, dict) and channel.get("platform") == "tiktok"]
1871
+ return [channel for channel in read_json("channels.json", []) if classify_channel_platform(channel) == "tiktok"]
1860
1872
 
1861
1873
 
1862
1874
  def _tiktok_avatar_url(value: dict[str, Any]) -> str:
@@ -2087,18 +2099,8 @@ def render_tiktok_channels():
2087
2099
  st.success("Canal TikTok cadastrado.")
2088
2100
  st.rerun()
2089
2101
  def is_youtube_channel_record(channel: Any) -> bool:
2090
- """Return whether a persisted channel is positively identified as YouTube."""
2091
- if not isinstance(channel, dict):
2092
- return False
2093
- platform = str(channel.get("platform") or "").strip().casefold().replace(" ", "")
2094
- if platform == "youtube":
2095
- return True
2096
- if platform:
2097
- return False
2098
- youtube_id = str(channel.get("youtube_id") or channel.get("youtube_channel_id") or "").strip()
2099
- youtube_url = str(channel.get("url") or channel.get("profile_url") or channel.get("source_url") or "").strip().casefold()
2100
- source = str(channel.get("metrics_source") or channel.get("import_source") or "").strip().casefold()
2101
- return bool(youtube_id or "youtube.com" in youtube_url or source.startswith("youtube"))
2102
+ """Return whether a persisted channel is explicitly identified as YouTube."""
2103
+ return classify_channel_platform(channel) == "youtube"
2102
2104
 
2103
2105
 
2104
2106
  def render_channels():
@@ -2563,7 +2565,7 @@ def render_channels():
2563
2565
  st.success(f"Canal {channel['name']} guardado manualmente.")
2564
2566
  st.rerun()
2565
2567
 
2566
- channels = read_json("channels.json", [])
2568
+ channels = [channel for channel in read_json("channels.json", []) if is_youtube_channel_record(channel)]
2567
2569
  if not channels:
2568
2570
  return
2569
2571
  for channel in channels:
@@ -2599,6 +2601,22 @@ def render_channels():
2599
2601
  if st.button("Apagar", key=f"delete_{channel_id}", use_container_width=True):
2600
2602
  st.session_state[delete_key] = True
2601
2603
  st.rerun()
2604
+ if st.session_state.get(delete_key):
2605
+ st.warning("Apagar este canal YouTube e os dados locais associados?")
2606
+ confirm_cols = st.columns(2)
2607
+ with confirm_cols[0]:
2608
+ if st.button("Confirmar apagar", type="primary", key=f"confirm_delete_{channel_id}"):
2609
+ removed = delete_channel(channel_id)
2610
+ st.session_state.pop(delete_key, None)
2611
+ if removed is None:
2612
+ st.error("O canal já não existe ou não pôde ser removido.")
2613
+ else:
2614
+ st.success(f"Canal {removed.get('name') or channel_id} apagado.")
2615
+ st.rerun()
2616
+ with confirm_cols[1]:
2617
+ if st.button("Cancelar", key=f"cancel_delete_{channel_id}"):
2618
+ st.session_state.pop(delete_key, None)
2619
+ st.rerun()
2602
2620
  if st.session_state.get(edit_key):
2603
2621
  render_channel_edit_form(channel, youtube_account_ids, youtube_account_labels, youtube_accounts_by_id)
2604
2622
  else:
@@ -2861,7 +2879,7 @@ def render_new_video(page_title: str = "Criação de Vídeos", prefix: str = "ne
2861
2879
  create_tab = tabs[0]
2862
2880
  draft_tab = tabs[1] if len(tabs) > 1 else None
2863
2881
  with create_tab:
2864
- all_channels = [c for c in read_json("channels.json", []) if isinstance(c, dict) and ((channel_platform == "tiktok" and c.get("platform") == "tiktok") or (channel_platform != "tiktok" and c.get("platform", "youtube") != "tiktok"))]
2882
+ all_channels = [c for c in read_json("channels.json", []) if classify_channel_platform(c) == channel_platform]
2865
2883
  active_channels = [c for c in all_channels if c.get("active", True)]
2866
2884
  if not all_channels:
2867
2885
  st.warning("Cadastre pelo menos um canal antes de criar vídeos.")
@@ -4804,7 +4822,7 @@ def render_automation():
4804
4822
  st.caption(f"Última verificação do worker: {last_tick}")
4805
4823
  if worker_status.get("last_error"):
4806
4824
  st.error(f"Último erro do worker: {worker_status['last_error']}")
4807
- channels = [channel for channel in read_json("channels.json", []) if isinstance(channel, dict) and channel.get("platform", "youtube") != "tiktok"]
4825
+ channels = [channel for channel in read_json("channels.json", []) if is_youtube_channel_record(channel)]
4808
4826
  if not channels:
4809
4827
  st.info("Nenhum canal cadastrado para configurar.")
4810
4828
  for channel in channels:
@@ -7900,7 +7918,7 @@ def render_update_youtube_videos():
7900
7918
  st.title("Update Youtube Vídeos")
7901
7919
  st.caption("Actualize título, descrição e thumbnail de vídeos publicados sem alterar o ficheiro de vídeo.")
7902
7920
  settings = read_json("settings.json", {})
7903
- channels = [channel for channel in read_json("channels.json", []) if isinstance(channel, dict) and channel.get("platform", "youtube") != "tiktok" and channel.get("active", True)]
7921
+ channels = [channel for channel in read_json("channels.json", []) if is_youtube_channel_record(channel) and channel.get("active", True)]
7904
7922
  if not channels:
7905
7923
  st.info("Cadastre pelo menos um canal YouTube activo antes de actualizar vídeos.")
7906
7924
  return
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.4.67",
3
+ "version": "0.4.69",
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",