Conversation
There was a problem hiding this comment.
Pull request overview
Release bump to v26.3.10, alongside UI/session-handling tweaks for the Gradio interface and a Docker image refactor to a multi-stage build to reduce runtime image weight.
Changes:
- Bump default app version from 26.3.9 → 26.3.10 across compose files and
VERSION.txt. - Update Gradio UI styling/blocks editor behavior and adjust session save/restore + disconnect handling.
- Refactor
Dockerfileinto builder + runtime stages; adjust CUDA/PyTorch runtime env knobs and device detection heuristics.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
podman-compose.yml |
Bumps default APP_VERSION build-arg to 26.3.10. |
docker-compose.yml |
Bumps default APP_VERSION build-arg(s) to 26.3.10. |
VERSION.txt |
Updates application version to 26.3.10. |
Dockerfile |
Converts to multi-stage build and narrows runtime dependencies; copies artifacts from builder. |
lib/gradio.py |
UI CSS/layout adjustments, alternating accordion styling, session save filtering, reset + disconnect behavior tweaks. |
lib/core.py |
Adds DISCONNECTED status, session key filtering, reset refactor, and disconnect/unload handling. |
lib/conf.py |
Updates CUDA/PyTorch environment variables for allocation/loading behavior. |
lib/classes/tts_engines/common/utils.py |
Adjusts CUDA policy knobs and adds SDP attention backend toggles. |
lib/classes/device_installer.py |
Mostly string/quoting normalization; Jetson-specific env tuning. |
ebook2audiobook.command |
Updates docker program list and adds DOCKER_DEVICE_STR variable. |
ebook2audiobook.cmd |
Updates docker program list and adds DOCKER_DEVICE_STR variable. |
.dockerignore |
Stops ignoring ext/ so local path deps can be included in Docker builds. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ARG APP_VERSION=26.3.9 | ||
| ARG DEVICE_TAG=cu128 | ||
| ARG DOCKER_DEVICE_STR='{"name": "cu128", "os": "manylinux_2_28", "arch": "x86_64", "pyvenv": [3, 12], "tag": "cu128", "note": "default device"}' | ||
| ARG DOCKER_PROGRAMS_STR="curl ffmpeg mediainfo nodejs npm espeak-ng sox tesseract-ocr" | ||
| ARG ISO3_LANG=eng |
There was a problem hiding this comment.
Stage 2 of the multi-stage Dockerfile still defaults APP_VERSION to 26.3.9, while the builder stage and compose files default to 26.3.10. If the build arg isn’t provided, the resulting image label/version metadata will be incorrect; keep both stages in sync (or remove the default here and rely on the build arg).
| # Copy Python packages from builder | ||
| COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages | ||
| COPY --from=builder /usr/local/bin /usr/local/bin |
There was a problem hiding this comment.
The runtime stage copies Python artifacts from a hard-coded python3.12 path (/usr/local/lib/python3.12/site-packages). Since PYTHON_VERSION is an ARG, building with a different Python version would produce a broken image. Use the ${PYTHON_VERSION}/python${PYTHON_VERSION}-derived path (or query the site-packages path) so the Dockerfile stays version-agnostic.
| HOST_PROGRAMS=("cmake" "curl" "pkg-config" "xcb-util-cursor" "calibre" "ffmpeg" "mediainfo" "nodejs" "espeak-ng" "cargo" "rust" "sox" "tesseract") | ||
| DOCKER_PROGRAMS=("ffmpeg" "mediainfo" "nodejs" "espeak-ng" "sox" "tesseract-ocr") # tesseract-ocr-[lang] and calibre are hardcoded in Dockerfile | ||
| DOCKER_PROGRAMS=("curl ffmpeg" "mediainfo" "nodejs" "espeak-ng" "sox" "tesseract-ocr") # tesseract-ocr-[lang] and calibre are hardcoded in Dockerfile | ||
| DOCKER_MODE="" | ||
| DOCKER_IMG_NAME="athomasson2/$APP_NAME" | ||
| DOCKER_DEVICE_STR="" |
There was a problem hiding this comment.
DOCKER_PROGRAMS now contains an element with an embedded space ("curl ffmpeg"), which makes it a single array item rather than two programs. This is easy to mis-handle when expanding the array (and can lead to missing packages in build args / checks). Define each program as its own array element (e.g., separate curl and ffmpeg) and rely on ${DOCKER_PROGRAMS[*]} when a space-joined string is required.
| .accordion-block-even, | ||
| .accordion-block-even * { | ||
| background-color: var(-table-even-background-fill) !important; | ||
| } |
There was a problem hiding this comment.
CSS custom property reference on the even accordion rows is invalid: var(-table-even-background-fill) is missing the second leading dash, so the variable will never resolve and the rule will be ignored. Use the correct CSS variable name (consistent with the odd row rule) or provide a fallback value.
| for key, value in data.items(): | ||
| if key in session: | ||
| if isinstance(value, dict) and isinstance(session[key], dict): | ||
| restore_session_from_data(value, session[key]) | ||
| else: | ||
| if value is None and session[key] is not None: | ||
| continue | ||
| session[key] = value | ||
| if key not in save_session_keys_except: | ||
| if isinstance(value, dict) and isinstance(session[key], dict): | ||
| restore_session_from_data(value, session[key]) | ||
| else: | ||
| if value is None and session[key] is not None: | ||
| continue | ||
| session[key] = value |
There was a problem hiding this comment.
restore_session_from_data() now skips keys in save_session_keys_except unconditionally. That prevents reset_ebook_session() from clearing blocks_orig/blocks_edit (it calls restore_session_from_data() with those keys set to empty lists), so block data can persist across conversions and grow memory usage. Consider limiting the exclusion to localStorage restore only (e.g., pass an exclude_keys parameter), or explicitly reset blocks_orig/blocks_edit in reset_ebook_session() without going through the filtered restore helper.
| RUN if [ "${INSTALL_RUST}" = "1" ]; then \ | ||
| curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable; \ |
There was a problem hiding this comment.
The Docker build downloads and executes the Rust toolchain installer via curl https://sh.rustup.rs -sSf | sh -s -- ... without any checksum, signature, or version pinning. If an attacker compromises DNS, TLS, or the upstream host, they can inject arbitrary code into the build process and the resulting image. Use a pinned installer (e.g., via a specific versioned artifact) and verify its integrity (checksum or signature) before execution, instead of piping curl directly to sh.
| RUN set -eux; \ | ||
| wget -nv "${CALIBRE_INSTALLER_URL}" -O /tmp/calibre.sh; \ | ||
| bash /tmp/calibre.sh; \ |
There was a problem hiding this comment.
The Docker build downloads and executes the Calibre installer script from CALIBRE_INSTALLER_URL using wget and bash without any integrity verification. This remote script runs with full privileges in the build environment, so a compromise of the download endpoint or its delivery path would let an attacker inject malicious code into the built image. Fetch a specific, versioned installer artifact and verify it with a checksum or signature before execution, rather than executing the downloaded script directly.
No description provided.