From 56d258846173a1d58579929ae81983f7c98047e8 Mon Sep 17 00:00:00 2001 From: Stefan Heyn Date: Wed, 4 Mar 2026 15:03:56 +0100 Subject: [PATCH] Add noVNC configure flow and helper start scripts --- Dockerfile.novnc | 21 +++++++++++++++ README.md | 46 +++++++++++++++++++++++++++++--- docker-compose.yml | 41 ++++++++++++++++++++++++++++ main.py | 18 +++++++++++-- scripts/start-novnc-configure.sh | 21 +++++++++++++++ startConfigure.sh | 22 +++++++++++++++ startDownload.sh | 25 +++++++++++++++++ 7 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 Dockerfile.novnc create mode 100644 scripts/start-novnc-configure.sh create mode 100755 startConfigure.sh create mode 100755 startDownload.sh diff --git a/Dockerfile.novnc b/Dockerfile.novnc new file mode 100644 index 0000000..51f02b5 --- /dev/null +++ b/Dockerfile.novnc @@ -0,0 +1,21 @@ +FROM mcr.microsoft.com/playwright/python:v1.52.0-jammy + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + xvfb \ + fluxbox \ + x11vnc \ + novnc \ + websockify \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements.txt /app/requirements.txt +RUN pip install --no-cache-dir -r /app/requirements.txt + +COPY main.py /app/main.py +COPY README.md /app/README.md +COPY scripts/start-novnc-configure.sh /app/scripts/start-novnc-configure.sh +RUN chmod +x /app/scripts/start-novnc-configure.sh + +ENTRYPOINT ["/app/scripts/start-novnc-configure.sh"] diff --git a/README.md b/README.md index 164522c..b519063 100644 --- a/README.md +++ b/README.md @@ -45,21 +45,59 @@ cd c:\projekte\amazon_invoice_downloader docker compose build ``` +Session direkt im Container erzeugen (Ubuntu mit Desktop/X11): + +```bash +sudo apt-get update && sudo apt-get install -y x11-xserver-utils +xhost +local:docker +docker compose --profile configure run --rm amazon-invoice-configure +xhost -local:docker +``` + +Im geöffneten Browser bei Amazon anmelden und danach im Terminal `Enter` drücken. +Die Session liegt anschließend in `./state/storage_state.json`. + +Session auf Ubuntu Server ohne GUI (noVNC): + +```bash +docker compose --profile configure-novnc up --build amazon-invoice-configure-novnc +``` + +Dann im Browser auf deinem PC oeffnen: + +```text +http://:6080/vnc.html +``` + +Im noVNC-Fenster bei Amazon einloggen. Die Session wird nach `LOGIN_WAIT_SECONDS` (Standard: 300s) automatisch gespeichert. +Anschließend kannst du den noVNC-Container beenden (`Ctrl+C` im Terminal). + +Alternative per Hilfsskript: + +```bash +chmod +x ./startConfigure.sh +./startConfigure.sh +``` + Rechnungen im Container herunterladen: ```powershell docker compose run --rm amazon-invoice-downloader download --from 2025-01-01 --to 2025-12-31 --headless true ``` +Alternative per Hilfsskript: + +```bash +chmod +x ./startDownload.sh +./startDownload.sh 2025-01-01 2025-12-31 +``` + Persistente Ordner: - `./state` -> `/root/.amazon_invoice_downloader` (config + session) - `./downloads` -> `/downloads` (Ausgabedateien) -Falls du bereits lokal konfiguriert hast, kopiere diese Dateien nach `./state`: - -- `config.json` -- `storage_state.json` +Falls noch nicht vorhanden, werden `config.json` und `storage_state.json` beim `configure`-Lauf in `./state` angelegt. Optionaler Zielordner im Container: diff --git a/docker-compose.yml b/docker-compose.yml index 446692e..dacf739 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,48 @@ working_dir: /app stdin_open: true tty: true + shm_size: "1gb" volumes: - ./downloads:/downloads - ./state:/root/.amazon_invoice_downloader command: ["-h"] + + amazon-invoice-configure: + build: + context: . + dockerfile: Dockerfile + image: amazon-invoice-downloader:latest + container_name: amazon-invoice-configure + working_dir: /app + stdin_open: true + tty: true + shm_size: "1gb" + profiles: ["configure"] + environment: + - DISPLAY=${DISPLAY} + volumes: + - /tmp/.X11-unix:/tmp/.X11-unix + - ./state:/root/.amazon_invoice_downloader + - ./downloads:/downloads + command: ["configure", "--marketplace", "de", "--download-dir", "/downloads"] + + amazon-invoice-configure-novnc: + build: + context: . + dockerfile: Dockerfile.novnc + image: amazon-invoice-downloader-novnc:latest + container_name: amazon-invoice-configure-novnc + stdin_open: true + tty: true + shm_size: "1gb" + profiles: ["configure-novnc"] + environment: + - MARKETPLACE=de + - DOWNLOAD_DIR=/downloads + - LOGIN_WAIT_SECONDS=300 + - NOVNC_PORT=6080 + ports: + - "6080:6080" + volumes: + - ./state:/root/.amazon_invoice_downloader + - ./downloads:/downloads diff --git a/main.py b/main.py index f786666..8246fbc 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,7 @@ import argparse import json import re +import time from dataclasses import dataclass from datetime import date, datetime from pathlib import Path @@ -278,8 +279,15 @@ def configure(args) -> None: page = context.new_page() page.goto(f"https://www.amazon.{args.marketplace}/your-orders/orders", wait_until="domcontentloaded") print("Bitte im Browser bei Amazon einloggen.") - print("Wenn Bestellungen sichtbar sind, Enter druecken.") - input() + if args.login_wait_seconds > 0: + print( + f"Warte {args.login_wait_seconds} Sekunden auf Login, " + "danach wird die Session automatisch gespeichert." + ) + time.sleep(args.login_wait_seconds) + else: + print("Wenn Bestellungen sichtbar sind, Enter druecken.") + input() context.storage_state(path=str(STORAGE_STATE_PATH)) browser.close() @@ -457,6 +465,12 @@ def build_parser() -> argparse.ArgumentParser: p_config.add_argument("--marketplace", default="de", help="z. B. de, com, co.uk") p_config.add_argument("--download-dir", default="~/Downloads/amazon_rechnungen") p_config.add_argument("--headless", action="store_true", help="Standard fuer Download-Lauf im Headless-Mode") + p_config.add_argument( + "--login-wait-seconds", + type=int, + default=0, + help="Optional: wartet X Sekunden vor Session-Speicherung (fuer noVNC/Serverbetrieb).", + ) p_config.set_defaults(func=configure) p_dl = sub.add_parser("download", help="Rechnungen nach Zeitraum herunterladen") diff --git a/scripts/start-novnc-configure.sh b/scripts/start-novnc-configure.sh new file mode 100644 index 0000000..ffec7ff --- /dev/null +++ b/scripts/start-novnc-configure.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +DISPLAY_NUM=${DISPLAY_NUM:-:99} +VNC_PORT=${VNC_PORT:-5900} +NOVNC_PORT=${NOVNC_PORT:-6080} +MARKETPLACE=${MARKETPLACE:-de} +DOWNLOAD_DIR=${DOWNLOAD_DIR:-/downloads} +LOGIN_WAIT_SECONDS=${LOGIN_WAIT_SECONDS:-300} + +Xvfb "$DISPLAY_NUM" -screen 0 1920x1080x24 & +fluxbox -display "$DISPLAY_NUM" & +x11vnc -display "$DISPLAY_NUM" -forever -shared -rfbport "$VNC_PORT" -nopw & +/usr/share/novnc/utils/novnc_proxy --vnc localhost:"$VNC_PORT" --listen "$NOVNC_PORT" & + +export DISPLAY="$DISPLAY_NUM" + +echo "noVNC bereit unter: http://:$NOVNC_PORT/vnc.html" +echo "Melde dich bei Amazon an. Session wird nach $LOGIN_WAIT_SECONDS Sekunden gespeichert." + +python /app/main.py configure --marketplace "$MARKETPLACE" --download-dir "$DOWNLOAD_DIR" --login-wait-seconds "$LOGIN_WAIT_SECONDS" diff --git a/startConfigure.sh b/startConfigure.sh new file mode 100755 index 0000000..69fde17 --- /dev/null +++ b/startConfigure.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +MARKETPLACE="${MARKETPLACE:-de}" +LOGIN_WAIT_SECONDS="${LOGIN_WAIT_SECONDS:-300}" +NOVNC_PORT="${NOVNC_PORT:-6080}" +DOWNLOAD_DIR="${DOWNLOAD_DIR:-/downloads}" + +mkdir -p state downloads + +export MARKETPLACE +export LOGIN_WAIT_SECONDS +export NOVNC_PORT +export DOWNLOAD_DIR + +echo "Starte noVNC-Configure auf Port ${NOVNC_PORT} ..." +echo "Oeffne im Browser: http://:${NOVNC_PORT}/vnc.html" + +docker compose --profile configure-novnc up --build amazon-invoice-configure-novnc diff --git a/startDownload.sh b/startDownload.sh new file mode 100755 index 0000000..d28a7c5 --- /dev/null +++ b/startDownload.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +if [[ $# -lt 2 ]]; then + echo "Usage: $0 [additional args]" + echo "Beispiel: $0 2025-01-01 2025-12-31 --debug --debug-json /downloads/debug-run.json" + exit 1 +fi + +DATE_FROM="$1" +DATE_TO="$2" +shift 2 + +mkdir -p state downloads + +docker compose run --rm amazon-invoice-downloader \ + download \ + --from "$DATE_FROM" \ + --to "$DATE_TO" \ + --output /downloads \ + --headless true \ + "$@"