@danhachuel/thunderbolt 0.6.47 → 0.6.48

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 CHANGED
@@ -116,7 +116,7 @@ from hermes_ui.update_manager import check_version, restart_current_process, upd
116
116
 
117
117
  from hermes_ui.script_documents import list_script_documents, read_script_document, save_script_document, script_storage_path
118
118
  from hermes_ui.script_generation import generate_script_document
119
- from hermes_ui.video_length import channel_video_length, length_generation_settings, words_from_channel_time
119
+ from hermes_ui.video_length import DEFAULT_AVERAGE_VIDEO_TIME, channel_video_length, length_generation_settings, words_from_channel_time
120
120
  from hermes_ui.voice_preview import DEFAULT_SAMPLE, load_preview_file, synthesize_preview
121
121
  from hermes_ui.elevenlabs_voices import ElevenLabsVoicesError, cached_personal_voices, fetch_personal_voices, personal_voice_options
122
122
  from hermes_ui.thumbnail_generation import ThumbnailGenerationError, generate_thumbnail_image
@@ -2374,12 +2374,12 @@ def render_tiktok_channels():
2374
2374
  prompt_file = TIKTOK_PROMPT_MASTERS / str(channel.get("default_prompt_master") or channel.get("prompt_master") or "")
2375
2375
  prompt_content = load_prompt_master_file(prompt_file) if prompt_file.is_file() else ""
2376
2376
  calculated_time, calculated_source, calculated_words = _channel_average_video_time(channel, prompt_master=prompt_content)
2377
- average_video_time = st.text_input("Tempo Medio de Video (HH:MM)", value=str(channel.get("average_video_time") or calculated_time), key=f"tiktok_channel_average_video_time_{channel_id}", help=f"Referência: {calculated_words or 0} palavras · {calculated_source}. Use 00:00 para usar o Prompt Master.")
2377
+ average_video_time = st.text_input("Tempo Medio de Video (HH:MM)", value=str(channel.get("average_video_time") or DEFAULT_AVERAGE_VIDEO_TIME), key=f"tiktok_channel_average_video_time_{channel_id}", help=f"Referência: {calculated_words or 0} palavras · {calculated_source}.")
2378
2378
  if st.button("Guardar tempo", key=f"save_tiktok_channel_average_video_time_{channel_id}", use_container_width=True):
2379
2379
  if not valid_hhmm(average_video_time):
2380
2380
  st.error("Use o formato HH:MM, por exemplo 00:02.")
2381
2381
  else:
2382
- update_channel(channel_id, {"average_video_time": average_video_time.strip() or "00:00", "average_video_word_count": words_from_channel_time(average_video_time)})
2382
+ update_channel(channel_id, {"average_video_time": average_video_time.strip() or DEFAULT_AVERAGE_VIDEO_TIME, "average_video_word_count": words_from_channel_time(average_video_time)})
2383
2383
  st.success("Tempo médio do canal TikTok guardado.")
2384
2384
  st.rerun()
2385
2385
  with card_cols[6]:
@@ -3073,12 +3073,12 @@ def render_channels():
3073
3073
  st.metric("Visualizações", _format_channel_count(channel.get("view_count")))
3074
3074
  with header_cols[5]:
3075
3075
  calculated_time, calculated_source, calculated_words = _channel_average_video_time(channel)
3076
- average_video_time = st.text_input("Tempo Medio de Video (HH:MM)", value=str(channel.get("average_video_time") or calculated_time), key=f"youtube_channel_average_video_time_{channel_id}", help=f"Referência: {calculated_words or 0} palavras · {calculated_source}. Use 00:00 para usar o Blueprint.")
3076
+ average_video_time = st.text_input("Tempo Medio de Video (HH:MM)", value=str(channel.get("average_video_time") or DEFAULT_AVERAGE_VIDEO_TIME), key=f"youtube_channel_average_video_time_{channel_id}", help=f"Referência: {calculated_words or 0} palavras · {calculated_source}.")
3077
3077
  if st.button("Guardar tempo", key=f"save_youtube_channel_average_video_time_{channel_id}", use_container_width=True):
3078
3078
  if not valid_hhmm(average_video_time):
3079
3079
  st.error("Use o formato HH:MM, por exemplo 00:02.")
3080
3080
  else:
3081
- update_channel(channel_id, {"average_video_time": average_video_time.strip() or "00:00", "average_video_word_count": words_from_channel_time(average_video_time)})
3081
+ update_channel(channel_id, {"average_video_time": average_video_time.strip() or DEFAULT_AVERAGE_VIDEO_TIME, "average_video_word_count": words_from_channel_time(average_video_time)})
3082
3082
  st.success("Tempo médio do canal YouTube guardado.")
3083
3083
  st.rerun()
3084
3084
  with header_cols[6]:
@@ -5447,7 +5447,7 @@ def render_tiktok_automation():
5447
5447
  for channel in channels:
5448
5448
  channel_id = str(channel["id"])
5449
5449
  with st.container(border=True):
5450
- header_cols = st.columns([0.55, 2.15, 1.25, 1.35, 1.55, 1.2])
5450
+ header_cols = st.columns([0.55, 2.35, 1.25, 0.82, 0.92, 1.2])
5451
5451
  with header_cols[0]:
5452
5452
  profile_image = _tiktok_avatar_url(channel)
5453
5453
  if profile_image:
@@ -5465,7 +5465,7 @@ def render_tiktok_automation():
5465
5465
  prompt_file = TIKTOK_PROMPT_MASTERS / str(channel.get("default_prompt_master") or channel.get("prompt_master") or "")
5466
5466
  prompt_content = load_prompt_master_file(prompt_file) if prompt_file.is_file() else ""
5467
5467
  calculated_time, calculated_source, calculated_words = _channel_average_video_time(channel, prompt_master=prompt_content)
5468
- average_video_time = st.text_input("Tempo Medio de Video (HH:MM)", value=str(channel.get("average_video_time") or calculated_time), key=f"tiktok_average_video_time_{channel_id}", help=f"Referência média: {calculated_words or 0} palavras · fonte: {calculated_source}. Use 00:00 para voltar ao Prompt Master.")
5468
+ average_video_time = st.text_input("Tempo Medio de Video (HH:MM)", value=str(channel.get("average_video_time") or DEFAULT_AVERAGE_VIDEO_TIME), key=f"tiktok_average_video_time_{channel_id}", help=f"Referência média: {calculated_words or 0} palavras · fonte: {calculated_source}.")
5469
5469
  default_cols = st.columns([1.0, 1.0, 1.35, 1.45, 1.55, 1.0], gap="small")
5470
5470
  with default_cols[0]:
5471
5471
  st.markdown("**Idioma do roteiro**")
@@ -5492,7 +5492,7 @@ def render_tiktok_automation():
5492
5492
  st.error("O Tempo Medio de Video deve estar no formato HH:MM, por exemplo 00:02.")
5493
5493
  else:
5494
5494
  avatar_url = _tiktok_avatar_url(channel)
5495
- update_channel(channel_id, {"automation_on": bool(enabled), "automation_time": schedule_time.strip(), "average_video_time": average_video_time.strip() or "00:00", "average_video_word_count": words_from_channel_time(average_video_time), "default_prompt_master": prompt, "prompt_master": prompt, "platform": "tiktok", "format": automation_format, "video_aspect_ratio": "Portrait 9:16", "style_wide": "portrait", "avatar_url": avatar_url, "thumbnail_url": avatar_url})
5495
+ update_channel(channel_id, {"automation_on": bool(enabled), "automation_time": schedule_time.strip(), "average_video_time": average_video_time.strip() or DEFAULT_AVERAGE_VIDEO_TIME, "average_video_word_count": words_from_channel_time(average_video_time), "default_prompt_master": prompt, "prompt_master": prompt, "platform": "tiktok", "format": automation_format, "video_aspect_ratio": "Portrait 9:16", "style_wide": "portrait", "avatar_url": avatar_url, "thumbnail_url": avatar_url})
5496
5496
  st.success("Automação TikTok guardada.")
5497
5497
  st.rerun()
5498
5498
  _render_tiktok_automation_cards()
@@ -5626,7 +5626,7 @@ def render_automation():
5626
5626
  automation_voice = current_voice
5627
5627
  paired_thumbnail = thumbnail_blueprint_for_blueprint(automation_blueprint)
5628
5628
  automation_format = str(channel.get("format") or "wide")
5629
- header_cols = st.columns([0.58, 1.95, 1.4, 1.15, 1.15, 1.25, 1.25, 1.45], gap="small")
5629
+ header_cols = st.columns([0.58, 2.15, 1.4, 1.15, 1.15, 1.25, 0.82, 0.92], gap="small")
5630
5630
  with header_cols[0]:
5631
5631
  if channel.get("thumbnail_url"):
5632
5632
  st.image(channel["thumbnail_url"], width=48)
@@ -5653,7 +5653,7 @@ def render_automation():
5653
5653
  schedule_time = st.text_input("Horário (HH:MM)", value=channel.get("automation_time", "00:00"), key=f"automation_time_{channel_id}")
5654
5654
  with header_cols[7]:
5655
5655
  calculated_time, calculated_source, calculated_words = _channel_average_video_time(channel)
5656
- average_video_time = st.text_input("Tempo Medio de Video (HH:MM)", value=str(channel.get("average_video_time") or calculated_time), key=f"average_video_time_{channel_id}", help=f"Referência média: {calculated_words or 0} palavras · fonte: {calculated_source}. Use 00:00 para voltar ao Blueprint.")
5656
+ average_video_time = st.text_input("Tempo Medio de Video (HH:MM)", value=str(channel.get("average_video_time") or DEFAULT_AVERAGE_VIDEO_TIME), key=f"average_video_time_{channel_id}", help=f"Referência média: {calculated_words or 0} palavras · fonte: {calculated_source}.")
5657
5657
 
5658
5658
  control_cols = st.columns([1.8, 1.8, 1.35, 1.2], gap="small")
5659
5659
  with control_cols[0]:
@@ -5685,7 +5685,7 @@ def render_automation():
5685
5685
  update_channel(channel_id, {
5686
5686
  "automation_on": bool(enabled),
5687
5687
  "automation_time": schedule_time.strip(),
5688
- "average_video_time": average_video_time.strip() or "00:00",
5688
+ "average_video_time": average_video_time.strip() or DEFAULT_AVERAGE_VIDEO_TIME,
5689
5689
  "average_video_word_count": words_from_channel_time(average_video_time),
5690
5690
  "format": automation_format,
5691
5691
  })
@@ -6,6 +6,7 @@ from pathlib import Path
6
6
  from typing import Any
7
7
 
8
8
  WORDS_PER_MINUTE = 150
9
+ DEFAULT_AVERAGE_VIDEO_TIME = "00:12"
9
10
  AVERAGE_VIDEO_TIME_KEY = "average_video_time"
10
11
  AVERAGE_VIDEO_WORD_COUNT_KEY = "average_video_word_count"
11
12
 
@@ -100,7 +101,8 @@ def channel_video_length(channel: dict[str, Any], blueprint: Any = None, prompt_
100
101
  words = explicit_word_count(blueprint, prompt_master)
101
102
  if words:
102
103
  return words, hhmm_from_minutes(round(words / WORDS_PER_MINUTE)), "Blueprint/Prompt Master"
103
- return 0, "00:00", "sem referência"
104
+ default_minutes = minutes_from_hhmm(DEFAULT_AVERAGE_VIDEO_TIME)
105
+ return default_minutes * WORDS_PER_MINUTE, DEFAULT_AVERAGE_VIDEO_TIME, "padrão do canal"
104
106
 
105
107
 
106
108
  def words_from_channel_time(value: Any) -> int:
@@ -121,6 +123,7 @@ def length_generation_settings(channel: dict[str, Any], blueprint: Any = None, p
121
123
  __all__ = [
122
124
  "AVERAGE_VIDEO_TIME_KEY",
123
125
  "AVERAGE_VIDEO_WORD_COUNT_KEY",
126
+ "DEFAULT_AVERAGE_VIDEO_TIME",
124
127
  "WORDS_PER_MINUTE",
125
128
  "channel_video_length",
126
129
  "explicit_word_count",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.6.47",
3
+ "version": "0.6.48",
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",