mirror of
https://forge.fsky.io/oneflux/omegafox.git
synced 2026-02-10 07:02:03 -08:00
pythonlib: Cleanup & bump to 0.4.6
- `camoufox test` will no longer highlight the cursor by default - Fixed launch_options blocking async - WebGL database cleanup & added ability to query all possible vendor/renderer pairs
This commit is contained in:
parent
31963aa83b
commit
4c52518dd2
7 changed files with 54 additions and 23 deletions
|
|
@ -114,7 +114,7 @@ def test(url: Optional[str] = None) -> None:
|
||||||
"""
|
"""
|
||||||
from .sync_api import Camoufox
|
from .sync_api import Camoufox
|
||||||
|
|
||||||
with Camoufox(headless=False, env=environ) as browser:
|
with Camoufox(headless=False, env=environ, config={'showcursor': False}) as browser:
|
||||||
page = browser.new_page()
|
page = browser.new_page()
|
||||||
if url:
|
if url:
|
||||||
page.goto(url)
|
page.goto(url)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import asyncio
|
||||||
|
from functools import partial
|
||||||
from typing import Any, Dict, Optional, Union, overload
|
from typing import Any, Dict, Optional, Union, overload
|
||||||
|
|
||||||
from playwright.async_api import (
|
from playwright.async_api import (
|
||||||
|
|
@ -82,13 +84,17 @@ async def AsyncNewBrowser(
|
||||||
else:
|
else:
|
||||||
virtual_display = None
|
virtual_display = None
|
||||||
|
|
||||||
opt = from_options or launch_options(headless=headless, debug=debug, **kwargs)
|
if not from_options:
|
||||||
|
from_options = await asyncio.get_event_loop().run_in_executor(
|
||||||
|
None,
|
||||||
|
partial(launch_options, headless=headless, debug=debug, **kwargs),
|
||||||
|
)
|
||||||
|
|
||||||
# Persistent context
|
# Persistent context
|
||||||
if persistent_context:
|
if persistent_context:
|
||||||
context = await playwright.firefox.launch_persistent_context(**opt)
|
context = await playwright.firefox.launch_persistent_context(**from_options)
|
||||||
return await async_attach_vd(context, virtual_display)
|
return await async_attach_vd(context, virtual_display)
|
||||||
|
|
||||||
# Browser
|
# Browser
|
||||||
browser = await playwright.firefox.launch(**opt)
|
browser = await playwright.firefox.launch(**from_options)
|
||||||
return await async_attach_vd(browser, virtual_display)
|
return await async_attach_vd(browser, virtual_display)
|
||||||
|
|
|
||||||
|
|
@ -55,16 +55,16 @@ LOCAL_DATA: Path = Path(os.path.abspath(__file__)).parent
|
||||||
|
|
||||||
# The supported architectures for each OS
|
# The supported architectures for each OS
|
||||||
OS_ARCH_MATRIX: Dict[str, List[str]] = {
|
OS_ARCH_MATRIX: Dict[str, List[str]] = {
|
||||||
'mac': ['x86_64', 'arm64'],
|
|
||||||
'win': ['x86_64', 'i686'],
|
'win': ['x86_64', 'i686'],
|
||||||
|
'mac': ['x86_64', 'arm64'],
|
||||||
'lin': ['x86_64', 'arm64', 'i686'],
|
'lin': ['x86_64', 'arm64', 'i686'],
|
||||||
}
|
}
|
||||||
|
|
||||||
# The relative path to the camoufox executable
|
# The relative path to the camoufox executable
|
||||||
LAUNCH_FILE = {
|
LAUNCH_FILE = {
|
||||||
'win': 'camoufox.exe',
|
'win': 'camoufox.exe',
|
||||||
'lin': 'camoufox-bin',
|
|
||||||
'mac': '../MacOS/camoufox',
|
'mac': '../MacOS/camoufox',
|
||||||
|
'lin': 'camoufox-bin',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,14 @@ def NewBrowser(
|
||||||
else:
|
else:
|
||||||
virtual_display = None
|
virtual_display = None
|
||||||
|
|
||||||
opt = from_options or launch_options(headless=headless, debug=debug, **kwargs)
|
if not from_options:
|
||||||
|
from_options = launch_options(headless=headless, debug=debug, **kwargs)
|
||||||
|
|
||||||
# Persistent context
|
# Persistent context
|
||||||
if persistent_context:
|
if persistent_context:
|
||||||
context = playwright.firefox.launch_persistent_context(**opt)
|
context = playwright.firefox.launch_persistent_context(**from_options)
|
||||||
return sync_attach_vd(context, virtual_display)
|
return sync_attach_vd(context, virtual_display)
|
||||||
|
|
||||||
# Browser
|
# Browser
|
||||||
browser = playwright.firefox.launch(**opt)
|
browser = playwright.firefox.launch(**from_options)
|
||||||
return sync_attach_vd(browser, virtual_display)
|
return sync_attach_vd(browser, virtual_display)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,15 @@
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Optional
|
from typing import Dict, List, Optional, Tuple
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import orjson
|
import orjson
|
||||||
|
|
||||||
|
from camoufox.pkgman import OS_ARCH_MATRIX
|
||||||
|
|
||||||
|
# Get database path relative to this file
|
||||||
|
DB_PATH = Path(__file__).parent / 'webgl_data.db'
|
||||||
|
|
||||||
|
|
||||||
def sample_webgl(
|
def sample_webgl(
|
||||||
os: str, vendor: Optional[str] = None, renderer: Optional[str] = None
|
os: str, vendor: Optional[str] = None, renderer: Optional[str] = None
|
||||||
|
|
@ -24,23 +29,19 @@ def sample_webgl(
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: If invalid OS provided or no data found for OS/vendor/renderer
|
ValueError: If invalid OS provided or no data found for OS/vendor/renderer
|
||||||
"""
|
"""
|
||||||
# Map OS to probability column
|
# Check that the OS is valid (avoid SQL injection)
|
||||||
os_map = {'win': 'windows', 'mac': 'macos', 'lin': 'linux'}
|
if os not in OS_ARCH_MATRIX:
|
||||||
if os not in os_map:
|
raise ValueError(f'Invalid OS: {os}. Must be one of: win, mac, lin')
|
||||||
raise ValueError(f'Invalid OS: {os}. Must be one of: {", ".join(os_map)}')
|
|
||||||
os = os_map[os]
|
|
||||||
|
|
||||||
# Get database path relative to this file
|
|
||||||
db_path = Path(__file__).parent / 'webgl_data.db'
|
|
||||||
|
|
||||||
# Connect to database
|
# Connect to database
|
||||||
conn = sqlite3.connect(db_path)
|
conn = sqlite3.connect(DB_PATH)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
if vendor and renderer:
|
if vendor and renderer:
|
||||||
# Get specific vendor/renderer pair and verify it exists for this OS
|
# Get specific vendor/renderer pair and verify it exists for this OS
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
f'SELECT vendor, renderer, data, {os} FROM webgl_fingerprints WHERE vendor = ? AND renderer = ?',
|
f'SELECT vendor, renderer, data, {os} FROM webgl_fingerprints ' # nosec
|
||||||
|
'WHERE vendor = ? AND renderer = ?',
|
||||||
(vendor, renderer),
|
(vendor, renderer),
|
||||||
)
|
)
|
||||||
result = cursor.fetchone()
|
result = cursor.fetchone()
|
||||||
|
|
@ -51,7 +52,7 @@ def sample_webgl(
|
||||||
if result[3] <= 0: # Check OS-specific probability
|
if result[3] <= 0: # Check OS-specific probability
|
||||||
# Get a list of possible (vendor, renderer) pairs for this OS
|
# Get a list of possible (vendor, renderer) pairs for this OS
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
f'SELECT DISTINCT vendor, renderer FROM webgl_fingerprints WHERE {os} > 0'
|
f'SELECT DISTINCT vendor, renderer FROM webgl_fingerprints WHERE {os} > 0' # nosec
|
||||||
)
|
)
|
||||||
possible_pairs = cursor.fetchall()
|
possible_pairs = cursor.fetchall()
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
|
|
@ -63,7 +64,9 @@ def sample_webgl(
|
||||||
return orjson.loads(result[2])
|
return orjson.loads(result[2])
|
||||||
|
|
||||||
# Get all vendor/renderer pairs and their probabilities for this OS
|
# Get all vendor/renderer pairs and their probabilities for this OS
|
||||||
cursor.execute(f'SELECT vendor, renderer, data, {os} FROM webgl_fingerprints WHERE {os} > 0')
|
cursor.execute(
|
||||||
|
f'SELECT vendor, renderer, data, {os} FROM webgl_fingerprints WHERE {os} > 0' # nosec
|
||||||
|
)
|
||||||
results = cursor.fetchall()
|
results = cursor.fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
@ -82,3 +85,24 @@ def sample_webgl(
|
||||||
|
|
||||||
# Parse the JSON data string
|
# Parse the JSON data string
|
||||||
return orjson.loads(data_strs[idx])
|
return orjson.loads(data_strs[idx])
|
||||||
|
|
||||||
|
|
||||||
|
def get_possible_pairs() -> Dict[str, List[Tuple[str, str]]]:
|
||||||
|
"""
|
||||||
|
Get all possible (vendor, renderer) pairs for all OS, where the probability is greater than 0.
|
||||||
|
"""
|
||||||
|
# Connect to database
|
||||||
|
conn = sqlite3.connect(DB_PATH)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Get all vendor/renderer pairs for each OS where probability > 0
|
||||||
|
result: Dict[str, List[Tuple[str, str]]] = {}
|
||||||
|
for os_type in OS_ARCH_MATRIX:
|
||||||
|
cursor.execute(
|
||||||
|
'SELECT DISTINCT vendor, renderer FROM webgl_fingerprints '
|
||||||
|
f'WHERE {os_type} > 0 ORDER BY {os_type} DESC', # nosec
|
||||||
|
)
|
||||||
|
result[os_type] = cursor.fetchall()
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
return result
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "camoufox"
|
name = "camoufox"
|
||||||
version = "0.4.6-beta"
|
version = "0.4.6"
|
||||||
description = "Wrapper around Playwright to help launch Camoufox"
|
description = "Wrapper around Playwright to help launch Camoufox"
|
||||||
authors = ["daijro <daijro.dev@gmail.com>"]
|
authors = ["daijro <daijro.dev@gmail.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue