@danhachuel/thunderbolt 0.6.59 → 0.6.60

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.
@@ -214,9 +214,9 @@ def _extract_profile_user_from_html(document: str, username: str) -> dict[str, A
214
214
  return parsed
215
215
  return None
216
216
 
217
- followers = _metric_text_value(embedded_user.get('edge_followed_by')) or _metric_text_value(embedded_user.get('followers')) or metric((r'([\d.,]+)\s*(k|mil)?\s*(?:followers|seguidores)',)) or _structured_metric(document, 'edge_followed_by', 'followers', 'follower_count') or _structured_metric_from_json(document, 'edge_followed_by', 'followers', 'follower_count', 'followerCount')
218
- following = _metric_text_value(embedded_user.get('edge_follow')) or _metric_text_value(embedded_user.get('following')) or metric((r'([\d.,]+)\s*(k|mil)?\s*(?:following|seguindo)',)) or _structured_metric(document, 'edge_follow', 'follows', 'following', 'following_count', 'followingCount') or _structured_metric_from_json(document, 'edge_follow', 'follows', 'following', 'following_count', 'followingCount')
219
- post_count = _metric_text_value(embedded_user.get('edge_owner_to_timeline_media')) or _metric_text_value(embedded_user.get('posts')) or metric((r'([\d.,]+)\s*(k|mil)?\s*(?:posts|publicações|publications)',)) or _structured_metric(document, 'edge_owner_to_timeline_media', 'posts', 'post_count')
217
+ followers = _metric_text_value(embedded_user.get('edge_followed_by')) or _metric_text_value(embedded_user.get('followers')) or metric((r'([\d.,]+)\s*(k|mil)?\s*(?:followers|seguidores)', r'(?:followers|seguidores)\s*([\d.,]+)\s*(k|mil)?')) or _structured_metric(document, 'edge_followed_by', 'followers', 'follower_count') or _structured_metric_from_json(document, 'edge_followed_by', 'followers', 'follower_count', 'followerCount')
218
+ following = _metric_text_value(embedded_user.get('edge_follow')) or _metric_text_value(embedded_user.get('following')) or metric((r'([\d.,]+)\s*(k|mil)?\s*(?:following|seguindo)', r'(?:following|seguindo)\s*([\d.,]+)\s*(k|mil)?')) or _structured_metric(document, 'edge_follow', 'follows', 'following', 'following_count', 'followingCount') or _structured_metric_from_json(document, 'edge_follow', 'follows', 'following', 'following_count', 'followingCount')
219
+ post_count = _metric_text_value(embedded_user.get('edge_owner_to_timeline_media')) or _metric_text_value(embedded_user.get('posts')) or metric((r'([\d.,]+)\s*(k|mil)?\s*(?:posts|publicações|publications)', r'(?:posts|publicações|publications)\s*([\d.,]+)\s*(k|mil)?')) or _structured_metric(document, 'edge_owner_to_timeline_media', 'posts', 'post_count')
220
220
  country = _country_value(embedded_user.get('country') or embedded_user.get('country_code')) or extract_public_instagram_country(embedded_user)
221
221
  if not country:
222
222
  for payload in _embedded_json_documents(document):
@@ -227,7 +227,7 @@ def _extract_profile_user_from_html(document: str, username: str) -> dict[str, A
227
227
  user: dict[str, Any] = {
228
228
  'username': username,
229
229
  'full_name': title.split('(')[0].strip() or username,
230
- 'biography': description,
230
+ 'biography': biography,
231
231
  'edge_followed_by': {'count': followers} if followers is not None else {},
232
232
  'edge_follow': {'count': following} if following is not None else {},
233
233
  'edge_owner_to_timeline_media': {'count': post_count, 'edges': [{'node': post} for post in posts]},
@@ -261,6 +261,15 @@ def _fetch_web_profile_user(username: str) -> dict[str, Any] | None:
261
261
  merged[key] = value
262
262
  return merged
263
263
 
264
+ def profile_is_complete(user: Mapping[str, Any]) -> bool:
265
+ if profile_quality(user) < 4:
266
+ return False
267
+ if platform.system() != 'Windows':
268
+ return True
269
+ has_bio = bool(str(user.get('biography') or user.get('bio') or '').strip())
270
+ has_following = any(user.get(key) not in (None, '', {}, []) for key in ('edge_follow', 'follows', 'following', 'following_count', 'followingCount'))
271
+ return has_bio and has_following
272
+
264
273
  best_user: dict[str, Any] | None = None
265
274
  for endpoint in endpoints:
266
275
  try:
@@ -273,7 +282,7 @@ def _fetch_web_profile_user(username: str) -> dict[str, Any] | None:
273
282
  user = ((payload.get('data') or {}).get('user') if isinstance(payload, dict) else None)
274
283
  if isinstance(user, dict):
275
284
  best_user = merge_profile(best_user, user)
276
- if profile_quality(best_user) >= 4:
285
+ if profile_is_complete(best_user):
277
286
  return best_user
278
287
 
279
288
  curl = shutil.which('curl')
@@ -453,6 +462,8 @@ def fetch_public_instagram_profile(source: str) -> IntegrationResult:
453
462
  api_user = _fetch_web_profile_user(reference['username'])
454
463
  if api_user:
455
464
  return IntegrationResult(True, 'Perfil Instagram encontrado publicamente.', _profile_data_from_api(api_user, reference))
465
+ if platform.system() == 'Windows':
466
+ return IntegrationResult(False, 'Não foi possível encontrar o perfil público estruturado do Instagram.', reference)
456
467
  try:
457
468
  response = requests.get(reference['url'], headers={'User-Agent': 'Mozilla/5.0', 'Accept-Language': 'pt-BR,pt;q=0.9,en;q=0.8'}, timeout=12)
458
469
  except requests.RequestException as exc:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.6.59",
3
+ "version": "0.6.60",
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",