Sync/dashboard, sanitize content, update config
Add local Claude permissions file; make background.js call syncToDashboard() after each run when config.syncToDashboard is enabled; improve content extraction in content.js by cloning link nodes, removing svg/style elements and stripping review-related text/counts before trimming; update config.py defaults to enable target and gamestop (remove bestbuy), set HEADLESS=True and STEALTH_HEADLESS=True to favor headless environments.
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(pip --version)",
|
||||||
|
"Bash(echo \"Exit: $?\")",
|
||||||
|
"Bash(\"/c/Users/hocke/AppData/Roaming/uv/python/cpython-3.14.3-windows-x86_64-none/python.exe\" --version)",
|
||||||
|
"Bash(\"/c/Users/hocke/AppData/Roaming/uv/python/cpython-3.14.3-windows-x86_64-none/python.exe\" -m pip --version)",
|
||||||
|
"Bash(uv --version)",
|
||||||
|
"Bash(PYTHON=\"/c/Users/hocke/AppData/Roaming/uv/python/cpython-3.14.3-windows-x86_64-none/python.exe\" \"$PYTHON\" -m pip list)",
|
||||||
|
"Bash(uv run:*)",
|
||||||
|
"Bash(uv pip:*)",
|
||||||
|
"Bash(uv venv:*)",
|
||||||
|
"Bash(/c/Users/hocke/Documents/GitHub/pokemon-stock-checker/.venv/Scripts/python.exe -c \"import flask; print\\(''flask ok''\\)\")",
|
||||||
|
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(''''Last sync:'''', d[''''last_sync'''']\\); print\\(''''Products:'''', len\\(d[''''products'''']\\)\\); print\\(''''Sample names:''''\\); [print\\('''' -'''', p[''''name''''][:80]\\) for p in d[''''products''''][:5]]\")",
|
||||||
|
"Bash(PYTHON=\"/c/Users/hocke/Documents/GitHub/pokemon-stock-checker/.venv/Scripts/python.exe\")",
|
||||||
|
"Bash(\"$PYTHON\" -c \":*)",
|
||||||
|
"Bash(1 grep:*)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -268,6 +268,11 @@ async function runStockCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await saveProducts();
|
await saveProducts();
|
||||||
|
|
||||||
|
// Sync to dashboard after every run
|
||||||
|
if (config.syncToDashboard) {
|
||||||
|
await syncToDashboard();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch and parse products from a URL using content script
|
// Fetch and parse products from a URL using content script
|
||||||
|
|||||||
@@ -60,7 +60,9 @@
|
|||||||
let isSoldOut = false;
|
let isSoldOut = false;
|
||||||
|
|
||||||
for (const link of links) {
|
for (const link of links) {
|
||||||
const text = link.textContent.trim();
|
const clone = link.cloneNode(true);
|
||||||
|
clone.querySelectorAll('svg, style').forEach(el => el.remove());
|
||||||
|
const text = clone.textContent.trim();
|
||||||
|
|
||||||
// Check if any link says "SOLD OUT"
|
// Check if any link says "SOLD OUT"
|
||||||
if (text.toUpperCase().includes("SOLD OUT")) {
|
if (text.toUpperCase().includes("SOLD OUT")) {
|
||||||
@@ -82,6 +84,8 @@
|
|||||||
bestName = bestName.replace(/\$[\d,.]+/g, "").trim();
|
bestName = bestName.replace(/\$[\d,.]+/g, "").trim();
|
||||||
// Remove "Add to Cart" etc
|
// Remove "Add to Cart" etc
|
||||||
bestName = bestName.replace(/Add to Cart/gi, "").trim();
|
bestName = bestName.replace(/Add to Cart/gi, "").trim();
|
||||||
|
// Remove review star CSS/SVG junk and plain review counts
|
||||||
|
bestName = bestName.replace(/\s*(review-|\d*\s*reviews?).*$/i, "").trim();
|
||||||
// Clean whitespace
|
// Clean whitespace
|
||||||
bestName = bestName.replace(/\s+/g, " ").trim();
|
bestName = bestName.replace(/\s+/g, " ").trim();
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ SORT_BY_NEWEST = True
|
|||||||
# Which sites to monitor
|
# Which sites to monitor
|
||||||
# Note: PokemonCenter has strong bot protection (Imperva) - may need manual workarounds
|
# Note: PokemonCenter has strong bot protection (Imperva) - may need manual workarounds
|
||||||
# Note: Walmart has aggressive bot protection (PerimeterX) - may need stealth mode
|
# Note: Walmart has aggressive bot protection (PerimeterX) - may need stealth mode
|
||||||
SITES_ENABLED = ["target", "bestbuy"] # Options: "pokemoncenter", "target", "gamestop", "bestbuy" (disabled - needs rework), "walmart"
|
SITES_ENABLED = ["target", "gamestop"] # Options: "pokemoncenter", "target", "gamestop", "bestbuy" (disabled - needs rework), "walmart"
|
||||||
|
|
||||||
# PokemonCenter URLs to monitor
|
# PokemonCenter URLs to monitor
|
||||||
POKEMON_CENTER_URLS = [
|
POKEMON_CENTER_URLS = [
|
||||||
@@ -74,7 +74,7 @@ KEYWORDS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Browser settings
|
# Browser settings
|
||||||
HEADLESS = False # Set to False to see the browser (useful for debugging)
|
HEADLESS = True # Set to False to see the browser (useful for debugging)
|
||||||
SLOW_MO = 0 # Milliseconds to slow down browser actions (for debugging)
|
SLOW_MO = 0 # Milliseconds to slow down browser actions (for debugging)
|
||||||
|
|
||||||
# Chrome profile for PokemonCenter (optional - helps bypass bot detection)
|
# Chrome profile for PokemonCenter (optional - helps bypass bot detection)
|
||||||
@@ -98,7 +98,7 @@ USE_REAL_CHROME = True
|
|||||||
USE_STEALTH_BROWSER = True
|
USE_STEALTH_BROWSER = True
|
||||||
|
|
||||||
# Stealth browser settings
|
# Stealth browser settings
|
||||||
STEALTH_HEADLESS = False # Keep False - headless is more detectable
|
STEALTH_HEADLESS = True # Set True for headless/no-display environments
|
||||||
STEALTH_SESSION_NAME = "pokemoncenter" # Name for cookie/session persistence
|
STEALTH_SESSION_NAME = "pokemoncenter" # Name for cookie/session persistence
|
||||||
|
|
||||||
# Human-like behavior settings
|
# Human-like behavior settings
|
||||||
|
|||||||
Reference in New Issue
Block a user