From b108ee28df9969b7e25d90a8ba85393b096c3eb3 Mon Sep 17 00:00:00 2001 From: cliouo <71540889+cliouo@users.noreply.github.com> Date: Mon, 16 Jun 2025 22:03:32 -0500 Subject: [PATCH] remove pycache --- .gitignore | 1 + AGENTS.md | 8 ++++++ data/cookie.json | 1 + docker-compose.yml | 25 +++++++++++++++++++ docker/Dockerfile.camoufox | 21 ++++++++++++++++ python/requirements.txt | 2 ++ python/runner.py | 47 ++++++++++++++++++++++++++++++++++++ scripts/bootstrap_login.sh | 5 ++++ scripts/docker-entrypoint.sh | 6 +++++ 9 files changed, 116 insertions(+) create mode 100644 AGENTS.md create mode 100644 data/cookie.json create mode 100644 docker-compose.yml create mode 100644 docker/Dockerfile.camoufox create mode 100644 python/requirements.txt create mode 100644 python/runner.py create mode 100755 scripts/bootstrap_login.sh create mode 100755 scripts/docker-entrypoint.sh diff --git a/.gitignore b/.gitignore index 7454e8a..68f6d46 100644 --- a/.gitignore +++ b/.gitignore @@ -85,3 +85,4 @@ profile.pprof # Windows 特定 Thumbs.db +python/__pycache__/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..d24d27d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,8 @@ +# Repo Guidelines + +- Run `go vet ./...` before committing Go code. +- After changes, run `go fmt ./...`. +- For Python code, run `python -m py_compile` on modified files. +- To build the Camoufox container and login, follow these steps: + 1. Run `scripts/bootstrap_login.sh` with `TARGET_URL` env set to login and generate `data/cookie.json`. + 2. Use `docker-compose up -d` to start the `camoufox` browser and Go server. diff --git a/data/cookie.json b/data/cookie.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/data/cookie.json @@ -0,0 +1 @@ +[] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..cfa8c68 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,25 @@ +version: "3.9" +services: + camoufox: + image: camoufox-runner + build: + context: . + dockerfile: docker/Dockerfile.camoufox + environment: + - TARGET_URL=${TARGET_URL} + - COOKIE_FILE=/data/cookie.json + - HTTP_PROXY=${HTTP_PROXY-} + - HEADLESS=true + volumes: + - ./data:/data + shm_size: "2gb" + + server: + build: . + depends_on: + - camoufox + environment: + - AUTH_TOKEN=${AUTH_TOKEN} + - PORT=5345 + ports: + - "5345:5345" diff --git a/docker/Dockerfile.camoufox b/docker/Dockerfile.camoufox new file mode 100644 index 0000000..4d61cc6 --- /dev/null +++ b/docker/Dockerfile.camoufox @@ -0,0 +1,21 @@ +FROM python:3.11-slim + +RUN apt-get update && apt-get install -y --no-install-recommends \ + xvfb libgtk-3-0 libdbus-glib-1-2 libasound2 \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app +COPY python/requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt && camoufox fetch + +COPY python/runner.py ./runner.py +COPY scripts/docker-entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENV COOKIE_FILE=/data/cookie.json +ENV TARGET_URL="" +ENV HTTP_PROXY="" +ENV HEADLESS=true + +VOLUME ["/data"] +ENTRYPOINT ["/entrypoint.sh"] diff --git a/python/requirements.txt b/python/requirements.txt new file mode 100644 index 0000000..9cfce0e --- /dev/null +++ b/python/requirements.txt @@ -0,0 +1,2 @@ +camoufox[geoip]>=0.9.3 +pyyaml>=6.0 diff --git a/python/runner.py b/python/runner.py new file mode 100644 index 0000000..25857ae --- /dev/null +++ b/python/runner.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +import argparse, json, os, signal, sys, time +from camoufox import launch + + +def parse(): + p = argparse.ArgumentParser() + p.add_argument("--url", required=True, help="page to keep in browser") + p.add_argument("--cookie", default="./data/cookie.json") + p.add_argument("--bootstrap", action="store_true", + help="open GUI, wait manual login, save cookie & exit") + p.add_argument("--proxy", help="http(s) proxy, e.g. http://user:pass@ip:port") + p.add_argument("--headless", action="store_true", default=False) + return p.parse_args() + + +def main(): + a = parse() + opts = { + "headless": a.headless, + "proxy": {"server": a.proxy} if a.proxy else None, + "virtual_display": not a.headless, + } + browser = launch(**opts) + ctx = browser.new_context() + + if os.path.exists(a.cookie): + with open(a.cookie) as f: + ctx.add_cookies(json.load(f)) + page = ctx.new_page() + page.goto(a.url) + + if a.bootstrap: + print(">> \u624b\u52a8\u5b8c\u6210 Google \u767b\u5f55\u540e\u6309 Ctrl-C \u7ed3\u675f") + try: + while True: + time.sleep(1) + finally: + with open(a.cookie, "w") as f: + json.dump(ctx.cookies(), f) + print(f">> cookie \u4fdd\u5b58\u5230 {a.cookie}") + else: + signal.pause() + + +if __name__ == "__main__": + main() diff --git a/scripts/bootstrap_login.sh b/scripts/bootstrap_login.sh new file mode 100755 index 0000000..ca1143d --- /dev/null +++ b/scripts/bootstrap_login.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -e +COOKIE=${COOKIE_FILE:-./data/cookie.json} +URL=${TARGET_URL:?need url} +python python/runner.py --url "$URL" --cookie "$COOKIE" --bootstrap diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh new file mode 100755 index 0000000..b29cc4e --- /dev/null +++ b/scripts/docker-entrypoint.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -e +ARGS=("--url" "$TARGET_URL" "--cookie" "$COOKIE_FILE") +[ -n "$HTTP_PROXY" ] && ARGS+=("--proxy" "$HTTP_PROXY") +[ "$HEADLESS" != "false" ] && ARGS+=("--headless") +exec python /app/runner.py "${ARGS[@]}"