@danhachuel/thunderbolt 0.3.31 → 0.3.32

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
@@ -41,7 +41,7 @@ from hermes_ui.llm_providers import LLM_CARDS_KEY, LLM_ACTIVE_CARD_KEY, LLM_PROV
41
41
  from hermes_ui.music import list_music_files, materialize_suno_audio, request_suno_generation, store_music_file
42
42
  from hermes_ui.media_downloader import AUDIO_FORMATS, VIDEO_CONTAINERS, VIDEO_QUALITY_OPTIONS, MediaDownloadError, build_download_options, clear_media_download_history, dependency_status, download_media, list_media_downloads, media_download_file
43
43
  from hermes_ui.notifications import clear_notifications, list_notifications, mark_all_notifications_read, mark_notification_read, notification_event_catalog, notification_preferences, record_notification, reconcile_persisted_notifications, save_notification_preferences, unread_notification_count
44
- from hermes_ui.languages import LANGUAGE_CODES, LANGUAGE_FLAG_DATA_URIS, language_code, language_label, ui_language_menu_label, ui_text, video_language_label, video_language_options
44
+ from hermes_ui.languages import LANGUAGE_CODES, VIDEO_LANGUAGE_CODES, LANGUAGE_FLAG_DATA_URIS, language_code, language_label, ui_language_menu_label, ui_text, video_language_label, video_language_options
45
45
  from hermes_ui.api_key_tests import test_apify_credentials, test_kaggle_credentials, test_material_source_credentials, test_nano_banana_credentials, test_postiz_credentials, test_tiktok_credentials, test_upload_post_credentials, test_voice_provider
46
46
  from hermes_ui.tutorials import tutorial_body, tutorial_caption, tutorial_title
47
47
 
@@ -147,8 +147,9 @@ VIDEO_LANGUAGE_OPTIONS = [
147
147
  ]
148
148
 
149
149
  # Mantemos esta lista histórica para preservar Blueprints, testes e tarefas antigas.
150
- # A UI acrescenta os dez códigos canónicos do MoneyPrinterTurbo com bandeiras.
151
- VIDEO_LANGUAGE_SELECTION_OPTIONS = ["music", *LANGUAGE_CODES, *[item for item in VIDEO_LANGUAGE_OPTIONS if item not in {"01 – Inglês", "06 – Alemão", "15 – Italiano", "29 – Turco", "31 – Russo", "36 – Português (Brasil)", "39 – Mandarim", "41 – Espanhol (LatAm)", "42 – Vietnamita", "44 – Indonésio"}]]
150
+ # A criação de vídeos usa exclusivamente os dez códigos canónicos do MoneyPrinterTurbo;
151
+ # os quatro idiomas adicionais pertencem apenas ao selector da UI.
152
+ VIDEO_LANGUAGE_SELECTION_OPTIONS = ["music", *VIDEO_LANGUAGE_CODES, *[item for item in VIDEO_LANGUAGE_OPTIONS if item not in {"01 – Inglês", "06 – Alemão", "15 – Italiano", "29 – Turco", "31 – Russo", "36 – Português (Brasil)", "39 – Mandarim", "41 – Espanhol (LatAm)", "42 – Vietnamita", "44 – Indonésio"}]]
152
153
 
153
154
  VIDEO_FORMAT_OPTIONS = ["wide", "shorts", "music"]
154
155
  VIDEO_CONCATENATION_OPTIONS = ["Random Concatenation (Recommended)", "Sequential Concatenation"]
@@ -9,20 +9,27 @@ from typing import Any
9
9
 
10
10
  # The persisted value is always the short MoneyPrinterTurbo-compatible code.
11
11
  LANGUAGE_CATALOG: tuple[dict[str, str], ...] = (
12
- {"code": "en", "name": "Inglês", "flag": "🇺🇸", "locale": "en-US"},
13
- {"code": "zh", "name": "Chinês Simplificado", "flag": "🇨🇳", "locale": "zh-CN"},
14
- {"code": "de", "name": "Alemão", "flag": "🇩🇪", "locale": "de-DE"},
15
- {"code": "vi", "name": "Vietnamita", "flag": "🇻🇳", "locale": "vi-VN"},
16
- {"code": "tr", "name": "Turco", "flag": "🇹🇷", "locale": "tr-TR"},
17
- {"code": "pt", "name": "Português", "flag": "🇧🇷", "locale": "pt-BR"},
18
- {"code": "ru", "name": "Russo", "flag": "🇷🇺", "locale": "ru-RU"},
19
- {"code": "es", "name": "Espanhol", "flag": "🇪🇸", "locale": "es-ES"},
20
- {"code": "id", "name": "Indonésio", "flag": "🇮🇩", "locale": "id-ID"},
21
- {"code": "it", "name": "Italiano", "flag": "🇮🇹", "locale": "it-IT"},
12
+ {"code": "en", "name": "Inglês", "ui_name": "English", "flag": "🇺🇸", "locale": "en-US"},
13
+ {"code": "zh", "name": "Chinês Simplificado", "ui_name": "Simplified Chinese", "flag": "🇨🇳", "locale": "zh-CN"},
14
+ {"code": "de", "name": "Alemão", "ui_name": "German", "flag": "🇩🇪", "locale": "de-DE"},
15
+ {"code": "vi", "name": "Vietnamita", "ui_name": "Vietnamese", "flag": "🇻🇳", "locale": "vi-VN"},
16
+ {"code": "tr", "name": "Turco", "ui_name": "Turkish", "flag": "🇹🇷", "locale": "tr-TR"},
17
+ {"code": "pt", "name": "Português", "ui_name": "Portuguese", "flag": "🇧🇷", "locale": "pt-BR"},
18
+ {"code": "ru", "name": "Russo", "ui_name": "Russian", "flag": "🇷🇺", "locale": "ru-RU"},
19
+ {"code": "es", "name": "Espanhol", "ui_name": "Spanish", "flag": "🇪🇸", "locale": "es-ES"},
20
+ {"code": "id", "name": "Indonésio", "ui_name": "Indonesian", "flag": "🇮🇩", "locale": "id-ID"},
21
+ {"code": "it", "name": "Italiano", "ui_name": "Italian", "flag": "🇮🇹", "locale": "it-IT"},
22
+ {"code": "pl", "name": "Polaco", "ui_name": "Polish", "flag": "🇵🇱", "locale": "pl-PL"},
23
+ {"code": "ga", "name": "Irlandês", "ui_name": "Irish", "flag": "🇮🇪", "locale": "ga-IE"},
24
+ {"code": "ar", "name": "Árabe", "ui_name": "Arabic", "flag": "🇸🇦", "locale": "ar-SA"},
25
+ {"code": "he", "name": "Hebraico", "ui_name": "Hebrew", "flag": "🇮🇱", "locale": "he-IL"},
22
26
  )
23
27
 
24
28
  LANGUAGE_BY_CODE = {item["code"]: item for item in LANGUAGE_CATALOG}
25
29
  LANGUAGE_CODES = tuple(item["code"] for item in LANGUAGE_CATALOG)
30
+ # Video creation keeps the original ten MoneyPrinterTurbo-compatible languages;
31
+ # the UI selector may contain additional interface languages independently.
32
+ VIDEO_LANGUAGE_CODES = ("en", "zh", "de", "vi", "tr", "pt", "ru", "es", "id", "it")
26
33
 
27
34
  # SVGs are embedded locally so flags render as images instead of relying on the
28
35
  # host operating system's emoji font (which may show regional-letter siglas).
@@ -37,6 +44,10 @@ LANGUAGE_FLAG_SVGS: dict[str, str] = {
37
44
  "es": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><path fill="#aa151b" d="M0 0h30v4H0zM0 16h30v4H0z"/><rect y="4" width="30" height="12" fill="#f1bf00"/><path fill="#ad1519" d="M7 7h2v6H7z"/></svg>',
38
45
  "id": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><path fill="#ce1126" d="M0 0h30v10H0z"/><path fill="#fff" d="M0 10h30v10H0z"/></svg>',
39
46
  "it": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><path fill="#009246" d="M0 0h10v20H0z"/><path fill="#f1f2f1" d="M10 0h10v20H10z"/><path fill="#ce2b37" d="M20 0h10v20H20z"/></svg>',
47
+ "pl": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><path fill="#fff" d="M0 0h30v10H0z"/><path fill="#dc143c" d="M0 10h30v10H0z"/></svg>',
48
+ "ga": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><path fill="#169b62" d="M0 0h10v20H0z"/><path fill="#fff" d="M10 0h10v20H10z"/><path fill="#ff883e" d="M20 0h10v20H20z"/></svg>',
49
+ "ar": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><rect width="30" height="20" fill="#006c35"/><path fill="#fff" d="M6 8.5h16v1H6zM9 11.5h12v1H9z"/><path fill="none" stroke="#fff" stroke-width=".7" d="M7 13.8h16"/></svg>',
50
+ "he": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 20"><rect width="30" height="20" fill="#fff"/><path fill="#0038b8" d="M0 2h30v3H0zM0 15h30v3H0z"/><path fill="none" stroke="#0038b8" stroke-width="1" d="m15 6 3.5 6h-7zM15 14 11.5 8h7z"/></svg>',
40
51
  }
41
52
  LANGUAGE_FLAG_DATA_URIS = {
42
53
  code: "data:image/svg+xml;base64," + base64.b64encode(svg.encode("utf-8")).decode("ascii")
@@ -56,6 +67,8 @@ LEGACY_LANGUAGE_CODES = {
56
67
  "deutsch": "de", "alemão": "de", "vietnamita": "vi", "turco": "tr", "português": "pt",
57
68
  "português (brasil)": "pt", "portuguese": "pt", "ru": "ru", "russo": "ru", "español": "es",
58
69
  "espanhol": "es", "indonésio": "id", "bahasa indonesia": "id", "italiano": "it",
70
+ "polish": "pl", "polaco": "pl", "polonês": "pl", "polones": "pl", "irish": "ga", "irlandês": "ga", "irlandes": "ga",
71
+ "arabic": "ar", "árabe": "ar", "arabe": "ar", "hebrew": "he", "hebraico": "he", "hebreu": "he",
59
72
  }
60
73
 
61
74
 
@@ -68,7 +81,7 @@ def language_code(value: Any, default: str = "pt") -> str:
68
81
  if lowered in LEGACY_LANGUAGE_CODES:
69
82
  return LEGACY_LANGUAGE_CODES[lowered]
70
83
  for item in LANGUAGE_CATALOG:
71
- if lowered in {item["name"].casefold(), item["locale"].casefold()}:
84
+ if lowered in {item["name"].casefold(), item.get("ui_name", "").casefold(), item["locale"].casefold()}:
72
85
  return item["code"]
73
86
  return default if default in LANGUAGE_BY_CODE else "pt"
74
87
 
@@ -81,12 +94,12 @@ def language_label(value: Any, *, include_code: bool = True) -> str:
81
94
  return f"{item['name']}{suffix} {item['flag']}"
82
95
 
83
96
 
84
- def ui_language_menu_label(value: Any, *, include_code: bool = True) -> str:
85
- """Return text-only UI label; the picker renders the flag as a real SVG icon."""
97
+ def ui_language_menu_label(value: Any, *, include_code: bool = False) -> str:
98
+ """Return the English UI label; the picker renders the flag as a real SVG icon."""
86
99
  code = language_code(value)
87
100
  item = LANGUAGE_BY_CODE[code]
88
101
  suffix = f" ({item['code']})" if include_code else ""
89
- return f"{item['name']}{suffix}"
102
+ return f"{item.get('ui_name', item['name'])}{suffix}"
90
103
 
91
104
 
92
105
  def language_option_labels(*, include_code: bool = True) -> list[str]:
@@ -140,7 +153,6 @@ UI_TRANSLATIONS: dict[str, dict[str, str]] = {
140
153
  },
141
154
  }
142
155
 
143
-
144
156
  # Labels for the independent LLM provider cards.
145
157
  _LLM_TRANSLATIONS: dict[str, dict[str, str]] = {
146
158
  "pt": {
@@ -1108,11 +1120,11 @@ def video_language_label(value: Any) -> str:
1108
1120
 
1109
1121
 
1110
1122
  def video_language_options() -> list[str]:
1111
- return ["music", *LANGUAGE_CODES]
1123
+ return ["music", *VIDEO_LANGUAGE_CODES]
1112
1124
 
1113
1125
 
1114
1126
  __all__ = [
1115
- "LANGUAGE_CATALOG", "LANGUAGE_BY_CODE", "LANGUAGE_CODES", "LANGUAGE_FLAG_DATA_URIS", "language_code", "language_flag",
1127
+ "LANGUAGE_CATALOG", "LANGUAGE_BY_CODE", "LANGUAGE_CODES", "VIDEO_LANGUAGE_CODES", "LANGUAGE_FLAG_DATA_URIS", "language_code", "language_flag",
1116
1128
  "language_label", "ui_language_menu_label", "language_locale", "language_option_codes", "language_option_labels",
1117
1129
  "ui_text", "video_language_label", "video_language_options",
1118
1130
  ]
@@ -1310,3 +1322,10 @@ _API_TEST_TRANSLATIONS: dict[str, dict[str, str]] = {
1310
1322
  }
1311
1323
  for _language_code, _api_test_values in _API_TEST_TRANSLATIONS.items():
1312
1324
  UI_TRANSLATIONS[_language_code].update(_api_test_values)
1325
+
1326
+
1327
+ # The four additional UI languages use the complete English UI catalogue as a
1328
+ # safe fallback until dedicated translations are added. Their selector labels,
1329
+ # flags and persisted language codes remain independent of video languages.
1330
+ for _ui_language_code in ("pl", "ga", "ar", "he"):
1331
+ UI_TRANSLATIONS[_ui_language_code] = dict(UI_TRANSLATIONS["en"])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.3.31",
3
+ "version": "0.3.32",
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",