@danhachuel/thunderbolt 0.6.44 → 0.6.45

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.
@@ -24,7 +24,6 @@ except ImportError: # pragma: no cover - Streamlit is a runtime dependency
24
24
 
25
25
  LOGGER = logging.getLogger(__name__)
26
26
  _WINDOWS_PLAYWRIGHT_CHECKED = False
27
- _WINDOWS_COOKIE_WARNING_SHOWN = False
28
27
 
29
28
 
30
29
  ABOUT_ACCOUNT_URL = 'https://i.instagram.com/api/v1/bloks/apps/com.instagram.interactions.about_this_account/'
@@ -70,19 +69,11 @@ def _streamlit_message(level: str, message: str, key: str) -> None:
70
69
 
71
70
  def _ensure_windows_playwright() -> None:
72
71
  """Ensure Chromium exists on Windows before using the Playwright fallback."""
73
- global _WINDOWS_PLAYWRIGHT_CHECKED, _WINDOWS_COOKIE_WARNING_SHOWN
72
+ global _WINDOWS_PLAYWRIGHT_CHECKED
74
73
  if os.name != 'nt' or _WINDOWS_PLAYWRIGHT_CHECKED:
75
74
  return
76
75
  _WINDOWS_PLAYWRIGHT_CHECKED = True
77
76
  _load_dotenv_compat()
78
- cookie_names = ('INSTAGRAM_SESSIONID', 'IG_SESSIONID')
79
- if not any(os.getenv(name, '').strip() for name in cookie_names) and not _WINDOWS_COOKIE_WARNING_SHOWN:
80
- _WINDOWS_COOKIE_WARNING_SHOWN = True
81
- message = ('Windows: cookies Instagram não configurados. O país da conta pode ficar indisponível; '
82
- 'configure INSTAGRAM_SESSIONID (e, se necessário, INSTAGRAM_CSRFTOKEN, '
83
- 'INSTAGRAM_DS_USER_ID, INSTAGRAM_MID e INSTAGRAM_IG_DID) no ficheiro .env.')
84
- LOGGER.warning(message)
85
- _streamlit_message('warning', message, 'windows_cookie_warning')
86
77
  try:
87
78
  completed = subprocess.run(
88
79
  [sys.executable, '-m', 'playwright', 'install', 'chromium'],
@@ -224,6 +215,7 @@ def _structured_metric_from_json(document: str, *keys: str) -> int | None:
224
215
 
225
216
  def _fetch_web_profile_user(username: str) -> dict[str, Any] | None:
226
217
  _ensure_windows_playwright()
218
+ cookies = _instagram_cookies()
227
219
  headers = _instagram_headers()
228
220
  headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/131.0 Safari/537.36'
229
221
  # The www host is the current public web endpoint. The legacy i host is
@@ -273,7 +265,7 @@ def _fetch_web_profile_user(username: str) -> dict[str, Any] | None:
273
265
  for request_header in request_headers:
274
266
  for endpoint in endpoints:
275
267
  try:
276
- response = requests.get(endpoint, headers=request_header, timeout=15)
268
+ response = requests.get(endpoint, headers=request_header, cookies=cookies or None, timeout=15)
277
269
  LOGGER.debug('Instagram profile URL=%s status=%s content_type=%s', endpoint, response.status_code, response.headers.get('content-type', ''))
278
270
  if response.status_code >= 400:
279
271
  continue
@@ -330,6 +322,8 @@ def _fetch_web_profile_user(username: str) -> dict[str, Any] | None:
330
322
  user_agent=headers['User-Agent'],
331
323
  extra_http_headers={'x-ig-app-id': headers['x-ig-app-id'], 'Accept-Language': 'en-US,en;q=0.9'},
332
324
  )
325
+ if cookies:
326
+ page.context.add_cookies([{'name': name, 'value': value, 'domain': '.instagram.com', 'path': '/'} for name, value in cookies.items()])
333
327
  for endpoint in endpoints:
334
328
  try:
335
329
  response = page.goto(endpoint, wait_until='domcontentloaded', timeout=30000)
@@ -632,7 +626,7 @@ def fetch_public_instagram_posts(source: str, limit: int = 10) -> IntegrationRes
632
626
  if api_user.get('is_private'):
633
627
  return IntegrationResult(False, 'Esta conta é privada. O Instagram não disponibiliza posts sem uma sessão autenticada.', reference | {'posts': [], 'is_private': True})
634
628
  try:
635
- response = requests.get(reference['url'], headers={'User-Agent': 'Mozilla/5.0', 'Accept-Language': 'pt-BR,pt;q=0.9,en;q=0.8'}, timeout=15)
629
+ response = requests.get(reference['url'], headers={'User-Agent': 'Mozilla/5.0', 'Accept-Language': 'pt-BR,pt;q=0.9,en;q=0.8'}, cookies=_instagram_cookies() or None, timeout=15)
636
630
  except requests.RequestException as exc:
637
631
  LOGGER.warning('Falha HTTP nos posts Instagram URL=%s: %s', reference['url'], exc, exc_info=True)
638
632
  return IntegrationResult(False, f'Não foi possível consultar os posts públicos do Instagram: {exc}', reference)
@@ -662,6 +656,9 @@ def fetch_public_instagram_posts(source: str, limit: int = 10) -> IntegrationRes
662
656
  user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/131.0 Safari/537.36',
663
657
  extra_http_headers={'x-ig-app-id': '936619743392459', 'Accept-Language': 'en-US,en;q=0.9'},
664
658
  )
659
+ cookies = _instagram_cookies()
660
+ if cookies:
661
+ page.context.add_cookies([{'name': name, 'value': value, 'domain': '.instagram.com', 'path': '/'} for name, value in cookies.items()])
665
662
  page.goto(reference['url'], wait_until='domcontentloaded', timeout=30000)
666
663
  browser_document = page.content()
667
664
  for document in _embedded_json_documents(browser_document):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.6.44",
3
+ "version": "0.6.45",
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",