@danhachuel/thunderbolt 0.6.21 → 0.6.22
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.
|
@@ -12,7 +12,7 @@ from hermes_ui.domain import create_channel, update_channel
|
|
|
12
12
|
from hermes_ui.influencers import InfluencerBackendError, STANDALONE_CONTENT_INFLUENCER_ID, get_repository
|
|
13
13
|
from hermes_ui.storage import read_json, write_json
|
|
14
14
|
from hermes_ui.languages import LANGUAGE_CODES, language_code, language_label
|
|
15
|
-
from integrations.instagram_public import fetch_public_instagram_posts, fetch_public_instagram_profile
|
|
15
|
+
from integrations.instagram_public import fetch_public_instagram_posts, fetch_public_instagram_profile, normalize_instagram_bio
|
|
16
16
|
from integrations.meta_social import test_facebook_pages_api_card, test_instagram_api_card
|
|
17
17
|
|
|
18
18
|
|
|
@@ -298,7 +298,7 @@ def _render_instagram_card(profile: dict[str, Any], characters: list[dict[str, A
|
|
|
298
298
|
with header_cols[1]:
|
|
299
299
|
st.write(f"**{_clean(profile.get('name')) or 'Sem nome'}**")
|
|
300
300
|
st.caption(f"{_clean(profile.get('handle')) or _clean(profile.get('url')) or 'sem handler'}")
|
|
301
|
-
bio =
|
|
301
|
+
bio = normalize_instagram_bio(profile.get("bio"))
|
|
302
302
|
if bio:
|
|
303
303
|
st.caption(f"Bio: {bio}")
|
|
304
304
|
st.caption(f"{_clean(profile.get('country')) or 'País não definido'} · {_clean(profile.get('language')) or 'Idioma não definido'}")
|
|
@@ -18,6 +18,16 @@ class IntegrationResult:
|
|
|
18
18
|
data: dict[str, Any]
|
|
19
19
|
|
|
20
20
|
|
|
21
|
+
def normalize_instagram_bio(value: Any) -> str:
|
|
22
|
+
"""Keep the profile biography, never Instagram's metrics summary."""
|
|
23
|
+
bio = str(value or '').strip()
|
|
24
|
+
if not bio:
|
|
25
|
+
return ''
|
|
26
|
+
if re.search(r'\b(?:followers|following|seguidores|seguindo|posts|publicações)\b', bio, flags=re.IGNORECASE) and re.search(r'\d', bio):
|
|
27
|
+
return ''
|
|
28
|
+
return bio
|
|
29
|
+
|
|
30
|
+
|
|
21
31
|
def normalize_instagram_reference(source: str) -> dict[str, str]:
|
|
22
32
|
value = str(source or '').strip()
|
|
23
33
|
if not value:
|
|
@@ -114,7 +124,7 @@ def _profile_data_from_api(user: Mapping[str, Any], reference: Mapping[str, str]
|
|
|
114
124
|
'id': f"instagram_{reference['username']}",
|
|
115
125
|
**reference,
|
|
116
126
|
'name': str(user.get('full_name') or user.get('username') or reference['username']).strip(),
|
|
117
|
-
'bio':
|
|
127
|
+
'bio': normalize_instagram_bio(user.get('biography')),
|
|
118
128
|
'avatar_url': str(user.get('profile_pic_url_hd') or user.get('profile_pic_url') or '').strip(),
|
|
119
129
|
'subscriber_count': followers,
|
|
120
130
|
'following_count': following,
|
|
@@ -137,6 +147,9 @@ def fetch_public_instagram_profile(source: str) -> IntegrationResult:
|
|
|
137
147
|
return IntegrationResult(False, f'Não foi possível consultar o perfil público do Instagram: {exc}', reference)
|
|
138
148
|
if response.status_code >= 400:
|
|
139
149
|
return IntegrationResult(False, f'O Instagram devolveu HTTP {response.status_code}. Confirme o @handle ou use o cadastro manual.', reference | {'status_code': response.status_code})
|
|
150
|
+
api_user = _fetch_web_profile_user(reference['username'])
|
|
151
|
+
if api_user:
|
|
152
|
+
return IntegrationResult(True, 'Perfil Instagram encontrado publicamente.', _profile_data_from_api(api_user, reference))
|
|
140
153
|
title = _meta(response.text, 'og:title') or reference['username']
|
|
141
154
|
description = _meta(response.text, 'og:description')
|
|
142
155
|
avatar_url = _meta(response.text, 'og:image')
|
|
@@ -154,11 +167,7 @@ def fetch_public_instagram_profile(source: str) -> IntegrationResult:
|
|
|
154
167
|
followers = metric((r'([\d,.]+)\s*(?:mil\s+)?(?:followers|seguidores)',)) or _structured_metric(response.text, 'edge_followed_by', 'followers', 'follower_count') or _structured_metric_from_json(response.text, 'edge_followed_by', 'followers', 'follower_count', 'followerCount')
|
|
155
168
|
following = metric((r'([\d,.]+)\s*(?:mil\s+)?(?:following|seguindo)',)) or _structured_metric(response.text, 'edge_follow', 'follows', 'following', 'following_count', 'followingCount') or _structured_metric_from_json(response.text, 'edge_follow', 'follows', 'following', 'following_count', 'followingCount')
|
|
156
169
|
posts = metric((r'([\d,.]+)\s*(?:mil\s+)?(?:posts|publicações|publications)',)) or _structured_metric(response.text, 'edge_owner_to_timeline_media', 'posts', 'post_count')
|
|
157
|
-
|
|
158
|
-
api_user = _fetch_web_profile_user(reference['username'])
|
|
159
|
-
if api_user:
|
|
160
|
-
return IntegrationResult(True, 'Perfil Instagram encontrado publicamente.', _profile_data_from_api(api_user, reference))
|
|
161
|
-
data = {'id': f"instagram_{reference['username']}", **reference, 'name': title.split('(')[0].strip() or reference['username'], 'bio': description, 'avatar_url': avatar_url, 'subscriber_count': followers, 'following_count': following, 'post_count': posts, 'public_lookup': True, 'metrics_source': 'instagram_public_page', 'last_public_lookup_at': datetime.now(timezone.utc).isoformat()}
|
|
170
|
+
data = {'id': f"instagram_{reference['username']}", **reference, 'name': title.split('(')[0].strip() or reference['username'], 'bio': normalize_instagram_bio(description), 'avatar_url': avatar_url, 'subscriber_count': followers, 'following_count': following, 'post_count': posts, 'public_lookup': True, 'metrics_source': 'instagram_public_page', 'last_public_lookup_at': datetime.now(timezone.utc).isoformat()}
|
|
162
171
|
return IntegrationResult(True, 'Perfil Instagram encontrado publicamente.', data)
|
|
163
172
|
|
|
164
173
|
|
|
@@ -257,4 +266,4 @@ def fetch_public_instagram_posts(source: str, limit: int = 10) -> IntegrationRes
|
|
|
257
266
|
return IntegrationResult(bool(posts), 'Posts públicos encontrados.' if posts else 'Não foi possível encontrar posts públicos nesta página do Instagram.', reference | {'posts': posts[:max(1, int(limit))]})
|
|
258
267
|
|
|
259
268
|
|
|
260
|
-
__all__ = ['IntegrationResult', 'fetch_public_instagram_posts', 'fetch_public_instagram_profile', 'normalize_instagram_reference']
|
|
269
|
+
__all__ = ['IntegrationResult', 'fetch_public_instagram_posts', 'fetch_public_instagram_profile', 'normalize_instagram_bio', 'normalize_instagram_reference']
|
package/package.json
CHANGED