From d3cd1479a657567b27f3048278cf8a05b6afd28f Mon Sep 17 00:00:00 2001 From: Christian Prado Date: Fri, 4 Sep 2026 07:22:20 -0700 Subject: [PATCH 1/2] fix: fetch mariocube with cloudscraper instead of Playwright (#33) --- cache/https___repo.mariocube.com_DSiWare_NDS_A_ | Bin 0 -> 18455 bytes db/tests/test_scrape_utils.py | 6 ++++-- db/utils/scrape_utils.py | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 cache/https___repo.mariocube.com_DSiWare_NDS_A_ diff --git a/cache/https___repo.mariocube.com_DSiWare_NDS_A_ b/cache/https___repo.mariocube.com_DSiWare_NDS_A_ new file mode 100644 index 0000000000000000000000000000000000000000..ea8130637c15f99af0e78b34bfac68dbbddf85d6 GIT binary patch literal 18455 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 P0qg9OWWXN6Yzg>(tnF`s literal 0 HcmV?d00001 diff --git a/db/tests/test_scrape_utils.py b/db/tests/test_scrape_utils.py index e3368b10..a0951a3e 100644 --- a/db/tests/test_scrape_utils.py +++ b/db/tests/test_scrape_utils.py @@ -3,6 +3,7 @@ from unittest.mock import MagicMock, patch +import utils.scrape_utils as scrape_utils from utils.scrape_utils import ( _needs_playwright, close_browser, @@ -88,8 +89,9 @@ def test_fetch_url_with_existing_session(tmp_cache_dir): def test_fetch_url_playwright_route(tmp_cache_dir): - url = f'https://{PLAYWRIGHT_REQUIRED_HOSTS[0]}/page' - with patch('utils.scrape_utils._fetch_with_playwright', return_value='pw') as mock_pw: + url = 'https://pw-only.example.com/page' + with patch.object(scrape_utils, 'PLAYWRIGHT_REQUIRED_HOSTS', ['pw-only.example.com']), \ + patch('utils.scrape_utils._fetch_with_playwright', return_value='pw') as mock_pw: result = fetch_url(url) assert result == 'pw' mock_pw.assert_called_once_with(url) diff --git a/db/utils/scrape_utils.py b/db/utils/scrape_utils.py index fa14dbc3..2eb4c601 100644 --- a/db/utils/scrape_utils.py +++ b/db/utils/scrape_utils.py @@ -20,8 +20,10 @@ 'Upgrade-Insecure-Requests': '1' } -# Sites that require Playwright (real browser) due to TLS fingerprinting -PLAYWRIGHT_REQUIRED_HOSTS = ['repo.mariocube.com'] +# Sites that require Playwright (real browser) due to TLS fingerprinting. +# repo.mariocube.com flipped: Cloudflare now challenges headless Chromium +# but passes cloudscraper, so it uses the default path again. +PLAYWRIGHT_REQUIRED_HOSTS = [] # Rate limiting settings MAX_RETRIES = 5 From b5878fa12140a2a0b84327c415c93669c22b1538 Mon Sep 17 00:00:00 2001 From: Christian Prado Date: Fri, 4 Sep 2026 07:22:58 -0700 Subject: [PATCH 2/2] chore: ignore local scrape cache --- .gitignore | 1 + cache/https___repo.mariocube.com_DSiWare_NDS_A_ | Bin 18455 -> 0 bytes 2 files changed, 1 insertion(+) delete mode 100644 cache/https___repo.mariocube.com_DSiWare_NDS_A_ diff --git a/.gitignore b/.gitignore index 815baf7a..d441bd1f 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release +cache/ diff --git a/cache/https___repo.mariocube.com_DSiWare_NDS_A_ b/cache/https___repo.mariocube.com_DSiWare_NDS_A_ deleted file mode 100644 index ea8130637c15f99af0e78b34bfac68dbbddf85d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18455 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 P0qg9OWWXN6Yzg>(tnF`s