@danhachuel/thunderbolt 0.6.35 → 0.6.37

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.
@@ -139,12 +139,48 @@ def _fetch_web_profile_user(username: str) -> dict[str, Any] | None:
139
139
  f'https://www.instagram.com/api/v1/users/web_profile_info/?username={username}',
140
140
  f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}',
141
141
  )
142
+ def profile_quality(user: Mapping[str, Any]) -> int:
143
+ return sum(bool(user.get(key)) for key in ('biography', 'edge_follow', 'edge_followed_by', 'edge_owner_to_timeline_media', 'username'))
144
+
145
+ def merge_profile(base: dict[str, Any] | None, candidate: Mapping[str, Any]) -> dict[str, Any]:
146
+ merged = dict(base or {})
147
+ for key, value in candidate.items():
148
+ if value not in (None, '', [], {}):
149
+ if isinstance(value, Mapping) and isinstance(merged.get(key), Mapping):
150
+ merged[key] = {**merged[key], **value}
151
+ else:
152
+ merged[key] = value
153
+ return merged
154
+
155
+ request_headers = [
156
+ headers,
157
+ {**headers, 'User-Agent': 'Instagram 390.0.0.0.50 Android', 'Accept': 'application/json, text/plain, */*'},
158
+ {**headers, 'Referer': f'https://www.instagram.com/{username}/', 'Origin': 'https://www.instagram.com', 'X-Requested-With': 'XMLHttpRequest'},
159
+ ]
160
+ best_user: dict[str, Any] | None = None
161
+ for request_header in request_headers:
162
+ for endpoint in endpoints:
163
+ try:
164
+ response = requests.get(endpoint, headers=request_header, timeout=15)
165
+ if response.status_code >= 400:
166
+ continue
167
+ payload = response.json()
168
+ except (requests.RequestException, ValueError, AttributeError, StopIteration):
169
+ if best_user:
170
+ return best_user
171
+ continue
172
+ user = ((payload.get('data') or {}).get('user') if isinstance(payload, dict) else None)
173
+ if isinstance(user, dict):
174
+ best_user = merge_profile(best_user, user)
175
+ if profile_quality(best_user) >= 4:
176
+ return best_user
177
+
142
178
  curl = shutil.which('curl')
143
179
  if curl:
144
180
  for endpoint in endpoints:
145
181
  try:
146
182
  completed = subprocess.run(
147
- [curl, '-L', '--max-time', '20', '-sS', '-A', headers['User-Agent'], '-H', f"x-ig-app-id: {headers['x-ig-app-id']}", '-H', 'Accept: application/json, text/plain, */*', endpoint],
183
+ [curl, '-L', '--max-time', '20', '-sS', '-A', headers['User-Agent'], '-H', f"x-ig-app-id: {headers['x-ig-app-id']}", '-H', 'Accept', 'application/json, text/plain, */*', endpoint],
148
184
  capture_output=True,
149
185
  text=True,
150
186
  encoding='utf-8',
@@ -155,21 +191,12 @@ def _fetch_web_profile_user(username: str) -> dict[str, Any] | None:
155
191
  payload = json.loads(completed.stdout) if completed.returncode == 0 and completed.stdout else None
156
192
  user = ((payload.get('data') or {}).get('user') if isinstance(payload, dict) else None)
157
193
  if isinstance(user, dict):
158
- return user
194
+ best_user = merge_profile(best_user, user)
195
+ if profile_quality(best_user) >= 4:
196
+ return best_user
159
197
  except (OSError, subprocess.SubprocessError, ValueError):
160
198
  continue
161
- for endpoint in endpoints:
162
- try:
163
- response = requests.get(endpoint, headers=headers, timeout=15)
164
- if response.status_code >= 400:
165
- continue
166
- payload = response.json()
167
- except (requests.RequestException, ValueError, AttributeError):
168
- continue
169
- user = ((payload.get('data') or {}).get('user') if isinstance(payload, dict) else None)
170
- if isinstance(user, dict):
171
- return user
172
- return None
199
+ return best_user
173
200
 
174
201
 
175
202
  def _country_from_bloks(value: Any) -> str:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.6.35",
3
+ "version": "0.6.37",
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",