@danhachuel/thunderbolt 0.6.28 → 0.6.29
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.
|
@@ -45,7 +45,7 @@ def _metric_input(value: Any) -> int | None:
|
|
|
45
45
|
def _render_instagram_bio(value: Any) -> None:
|
|
46
46
|
bio = normalize_instagram_bio(value)
|
|
47
47
|
if bio:
|
|
48
|
-
st.
|
|
48
|
+
st.text(bio)
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
def _language_index(value: Any) -> int:
|
|
@@ -99,7 +99,6 @@ def _render_instagram_posts(profile: Mapping[str, Any]) -> None:
|
|
|
99
99
|
profile_id = _clean(profile.get("id"))
|
|
100
100
|
state_key = _instagram_posts_key(profile_id)
|
|
101
101
|
posts = st.session_state.get(state_key, [])
|
|
102
|
-
source = _clean(profile.get("url")) or _clean(profile.get("handle"))
|
|
103
102
|
with st.expander("Últimos posts do Instagram", expanded=False):
|
|
104
103
|
action_cols = st.columns(3)
|
|
105
104
|
with action_cols[0]:
|
|
@@ -110,13 +109,14 @@ def _render_instagram_posts(profile: Mapping[str, Any]) -> None:
|
|
|
110
109
|
download_clicked = bool(posts) and st.download_button("Baixar todos", data=_instagram_posts_archive(posts), file_name=f"instagram-{profile_id}-posts.zip", mime="application/zip", key=f"download_instagram_posts_{profile_id}", use_container_width=True)
|
|
111
110
|
if load_clicked or refresh_clicked:
|
|
112
111
|
target = max(10, len(posts)) if refresh_clicked else 10
|
|
113
|
-
|
|
114
|
-
if
|
|
115
|
-
posts =
|
|
112
|
+
posts_ok, posts_message, loaded_posts = _load_instagram_posts(profile, limit=target)
|
|
113
|
+
if posts_ok:
|
|
114
|
+
posts = loaded_posts
|
|
116
115
|
st.session_state[state_key] = posts
|
|
117
116
|
st.success(f"{len(posts)} posts carregados.")
|
|
117
|
+
st.rerun()
|
|
118
118
|
else:
|
|
119
|
-
st.warning(
|
|
119
|
+
st.warning(posts_message)
|
|
120
120
|
posts = st.session_state.get(state_key, posts)
|
|
121
121
|
if not posts:
|
|
122
122
|
st.info("Clique em Carregar últimos 10 para consultar os posts públicos desta conta.")
|
|
@@ -133,11 +133,11 @@ def _render_instagram_posts(profile: Mapping[str, Any]) -> None:
|
|
|
133
133
|
if _clean(post.get("caption")):
|
|
134
134
|
st.caption(post["caption"])
|
|
135
135
|
if st.button("Mostrar + 10", key=f"more_instagram_posts_{profile_id}", use_container_width=True):
|
|
136
|
-
|
|
137
|
-
if
|
|
138
|
-
st.session_state[state_key] =
|
|
136
|
+
posts_ok, posts_message, loaded_posts = _load_instagram_posts(profile, limit=len(posts) + 10)
|
|
137
|
+
if posts_ok:
|
|
138
|
+
st.session_state[state_key] = loaded_posts
|
|
139
139
|
st.rerun()
|
|
140
|
-
st.warning(
|
|
140
|
+
st.warning(posts_message)
|
|
141
141
|
|
|
142
142
|
|
|
143
143
|
def _api_card_defaults(kind: str) -> tuple[str, list[str], Callable[[Mapping[str, Any]], dict[str, Any]]]:
|
|
@@ -291,6 +291,7 @@ def _characters(settings: Mapping[str, Any]) -> tuple[list[dict[str, Any]], Any
|
|
|
291
291
|
def _save_public_profile(data: Mapping[str, Any], *, country: str, language: str, character_id: str = "") -> dict[str, Any]:
|
|
292
292
|
name = _clean(data.get("name")) or _clean(data.get("username")) or "Conta Instagram"
|
|
293
293
|
url = _clean(data.get("url"))
|
|
294
|
+
selected_country = _clean(country) if _clean(country) in COUNTRY_OPTIONS else ""
|
|
294
295
|
metadata = {
|
|
295
296
|
**dict(data),
|
|
296
297
|
"platform": "instagram",
|
|
@@ -299,7 +300,7 @@ def _save_public_profile(data: Mapping[str, Any], *, country: str, language: str
|
|
|
299
300
|
"url": url,
|
|
300
301
|
"handle": _clean(data.get("handle")),
|
|
301
302
|
"bio": normalize_instagram_bio(data.get("bio")),
|
|
302
|
-
"country":
|
|
303
|
+
"country": selected_country,
|
|
303
304
|
"language": language.strip(),
|
|
304
305
|
"post_count": data.get("post_count"),
|
|
305
306
|
"subscriber_count": data.get("subscriber_count"),
|
|
@@ -319,6 +320,21 @@ def _merge_instagram_refresh(existing: Mapping[str, Any], refreshed: Mapping[str
|
|
|
319
320
|
return merged
|
|
320
321
|
|
|
321
322
|
|
|
323
|
+
def _refresh_instagram_profile(profile: Mapping[str, Any]) -> tuple[bool, str, dict[str, Any]]:
|
|
324
|
+
source = _clean(profile.get("url")) or _clean(profile.get("handle"))
|
|
325
|
+
result = fetch_public_instagram_profile(source)
|
|
326
|
+
if not result.ok:
|
|
327
|
+
return False, result.message, {}
|
|
328
|
+
return True, result.message, _merge_instagram_refresh(profile, result.data)
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def _load_instagram_posts(profile: Mapping[str, Any], limit: int = 10) -> tuple[bool, str, list[dict[str, Any]]]:
|
|
332
|
+
source = _clean(profile.get("url")) or _clean(profile.get("handle"))
|
|
333
|
+
result = fetch_public_instagram_posts(source, limit=limit)
|
|
334
|
+
posts = result.data.get("posts", []) if isinstance(result.data, dict) else []
|
|
335
|
+
return result.ok, result.message, posts
|
|
336
|
+
|
|
337
|
+
|
|
322
338
|
def _render_instagram_card(profile: dict[str, Any], characters: list[dict[str, Any]], settings: Mapping[str, Any]) -> None:
|
|
323
339
|
profile_id = _clean(profile.get("id"))
|
|
324
340
|
edit_key = f"edit_instagram_profile_{profile_id}"
|
|
@@ -344,13 +360,12 @@ def _render_instagram_card(profile: dict[str, Any], characters: list[dict[str, A
|
|
|
344
360
|
refresh_col, edit_col = st.columns(2)
|
|
345
361
|
with refresh_col:
|
|
346
362
|
if st.button("↻", help="Actualizar posts, seguidores e seguindo", key=f"refresh_instagram_{profile_id}"):
|
|
347
|
-
|
|
348
|
-
if
|
|
349
|
-
refreshed = _merge_instagram_refresh(profile, result.data)
|
|
363
|
+
refreshed_ok, refreshed_message, refreshed = _refresh_instagram_profile(profile)
|
|
364
|
+
if refreshed_ok:
|
|
350
365
|
update_channel(profile_id, {**refreshed, "platform": "instagram", "country": profile.get("country", ""), "language": profile.get("language", ""), "character_id": profile.get("character_id", "")})
|
|
351
366
|
st.success("Métricas Instagram actualizadas.")
|
|
352
367
|
st.rerun()
|
|
353
|
-
st.warning(
|
|
368
|
+
st.warning(refreshed_message)
|
|
354
369
|
with edit_col:
|
|
355
370
|
if st.button("Editar", key=f"edit_instagram_button_{profile_id}", use_container_width=True):
|
|
356
371
|
st.session_state[edit_key] = True
|
|
@@ -25,7 +25,13 @@ def normalize_instagram_bio(value: Any) -> str:
|
|
|
25
25
|
bio = str(value or '').strip()
|
|
26
26
|
if not bio:
|
|
27
27
|
return ''
|
|
28
|
-
|
|
28
|
+
metric_words = r'followers|following|seguidores|seguindo|posts|publicações|publications'
|
|
29
|
+
metric_hits = re.findall(
|
|
30
|
+
rf'(?:\d[\d.,]*\s*(?:{metric_words})\b|\b(?:{metric_words})\s*\d[\d.,]*)',
|
|
31
|
+
bio,
|
|
32
|
+
flags=re.IGNORECASE,
|
|
33
|
+
)
|
|
34
|
+
if len(metric_hits) >= 2:
|
|
29
35
|
return ''
|
|
30
36
|
return bio
|
|
31
37
|
|
package/package.json
CHANGED