more fixes

This commit is contained in:
Ross
2026-07-11 16:54:35 +01:00
parent b703a23fd2
commit a10dd5bd7b
195 changed files with 3943 additions and 128 deletions
+63 -10
View File
@@ -113,6 +113,9 @@ async def run_capture(args):
else:
context = await browser_type.launch_persistent_context(user_data_dir=args.profile, headless=args.headless)
context_closed = asyncio.Event()
context.on('close', lambda ctx: context_closed.set())
page = await context.new_page()
async def attempt_autologin(page, username: str, password: str, post_login_selector: str, wait_after: float = 1.0):
@@ -469,6 +472,48 @@ async def run_capture(args):
# Start heartbeat
hb_task = asyncio.create_task(heartbeat())
# Start control server
async def open_in_playwright(target_url: str):
try:
pg = context.pages[0] if context.pages else await context.new_page()
await pg.goto(target_url)
print(f"{now_ts()}\tCONTROL\tOpened URL: {target_url}")
except Exception as e:
print(f"{now_ts()}\tCONTROL\tError opening URL: {e}")
async def handle_client(reader, writer):
try:
data = await reader.read(4096)
request_str = data.decode('utf-8', errors='ignore')
lines = request_str.split('\r\n')
if lines:
req_line = lines[0]
parts = req_line.split(' ')
if len(parts) >= 2:
method, path = parts[0], parts[1]
if path.startswith('/open'):
from urllib.parse import urlparse, parse_qs
query = urlparse(path).query
params = parse_qs(query)
target_url = params.get('url', [None])[0]
if target_url:
asyncio.create_task(open_in_playwright(target_url))
response = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n\r\n" + json.dumps({"status": "ok", "url": target_url})
writer.write(response.encode('utf-8'))
await writer.drain()
writer.close()
return
response = "HTTP/1.1 400 Bad Request\r\nContent-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n\r\n" + json.dumps({"status": "error"})
writer.write(response.encode('utf-8'))
await writer.drain()
except Exception:
pass
finally:
writer.close()
server = await asyncio.start_server(handle_client, '127.0.0.1', args.control_port)
print(f"Control server listening on http://127.0.0.1:{args.control_port}")
# Navigate after listeners attached
try:
await page.goto(args.url)
@@ -489,27 +534,31 @@ async def run_capture(args):
except Exception:
pass
# If interactive, let user log in; otherwise start capture immediately
if not args.no_prompt:
print('When you have logged in in the opened browser, press Enter here to continue and capture...')
try:
await asyncio.get_event_loop().run_in_executor(None, input)
except Exception:
pass
print(f'Starting async passive capture (types: {args.capture_types})')
try:
if args.continuous:
# keep running until KeyboardInterrupt
while True:
# keep running until KeyboardInterrupt or browser closes
while not context_closed.is_set():
await asyncio.sleep(1)
print("Browser context closed; exiting capture script.")
else:
await asyncio.sleep(5)
# wait 5s or until browser closes
for _ in range(5):
if context_closed.is_set():
break
await asyncio.sleep(1)
except KeyboardInterrupt:
print('Interrupted; closing...')
finally:
hb_task.cancel()
server.close()
try:
await server.wait_closed()
except Exception:
pass
try:
await context.close()
except Exception:
@@ -531,6 +580,7 @@ def parse_args():
parser.add_argument('--capture-types', default='xhr,fetch,document,other')
parser.add_argument('--dedupe-policy', default='delete', choices=['delete', 'move', 'keep', 'symlink'], help="What to do with older duplicate files: delete/move/keep/symlink")
parser.add_argument('--dry-run', action='store_true', help='If set, show dedupe actions without performing them')
parser.add_argument('--control-port', type=int, default=8089, help='Port for the async control server')
return parser.parse_args()
@@ -542,3 +592,6 @@ if __name__ == '__main__':
asyncio.run(run_capture(args))
except KeyboardInterrupt:
pass
finally:
import os
os._exit(0)