@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.
- package/integrations/instagram_public.py +41 -14
- package/package.json +1 -1
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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