Add Debian (.deb) installer (v1.1.0)
packaging/build-deb.sh builds an installable blitztext_<ver>_arm64.deb with a desktop entry, app icon, and launcher. Bundles a relocatable venv (all Python deps, no pip at install) and declares system deps (python3-gi, xdotool, libnotify-bin, recorder). Built on /usr/bin/python3 so the tray works out of the box. Installs via the Software app or `apt install ./…deb`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
689d948fa1
commit
6ef421c934
1
linux/.gitignore
vendored
1
linux/.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
.venv/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
dist/
|
||||
|
||||
@ -9,6 +9,22 @@ The version is defined in [`blitztext/__init__.py`](blitztext/__init__.py).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.1.0] - 2026-06-04
|
||||
|
||||
### Added
|
||||
- **Debian package** (`packaging/build-deb.sh`) producing an installable
|
||||
`blitztext_<ver>_arm64.deb` with a desktop entry, app icon, and a `blitztext`
|
||||
launcher. Installs via the Software app or `apt install ./…deb`. Bundles a
|
||||
relocatable venv with all Python deps (no pip/network at install) and declares
|
||||
system deps (python3-gi, xdotool, libnotify-bin, a recorder) so they pull in
|
||||
automatically. The bundled venv is built on the system `/usr/bin/python3`, so
|
||||
the tray works out of the box.
|
||||
|
||||
### Notes
|
||||
- `python3-gi` is already present on a standard Ubuntu GNOME install; the tray
|
||||
only seemed unavailable from source when the project venv was built from a
|
||||
non-system Python (e.g. conda/miniforge). The `.deb` avoids this entirely.
|
||||
|
||||
## [1.0.1] - 2026-06-03
|
||||
|
||||
### Changed
|
||||
@ -58,6 +74,7 @@ into that field.
|
||||
AppIndicator typelibs and GNOME `ubuntu-appindicators` extension are already
|
||||
present on the target host).
|
||||
|
||||
[Unreleased]: https://github.com/mARTin-B78/blitztext-app/compare/v1.0.1...HEAD
|
||||
[Unreleased]: https://github.com/mARTin-B78/blitztext-app/compare/v1.1.0...HEAD
|
||||
[1.1.0]: https://github.com/mARTin-B78/blitztext-app/compare/v1.0.1...v1.1.0
|
||||
[1.0.1]: https://github.com/mARTin-B78/blitztext-app/compare/v1.0.0...v1.0.1
|
||||
[1.0.0]: https://github.com/mARTin-B78/blitztext-app/releases/tag/v1.0.0
|
||||
|
||||
@ -37,6 +37,24 @@ transcribes, optionally rewrites, and types the result where your cursor is.
|
||||
|
||||
## Install
|
||||
|
||||
### Option A — Debian package (recommended on Ubuntu/Debian)
|
||||
|
||||
Build a `.deb` and install it with the Software app or apt:
|
||||
|
||||
```bash
|
||||
cd linux
|
||||
bash packaging/build-deb.sh # -> dist/blitztext_<ver>_arm64.deb
|
||||
sudo apt install ./dist/blitztext_*.deb # or double-click the .deb in Files
|
||||
```
|
||||
|
||||
This installs `blitztext` to `/opt/blitztext` (a self-contained bundle — no pip
|
||||
step), adds a **Blitztext** entry to your app grid, and pulls in the system deps
|
||||
(`python3-gi`, `xdotool`, `libnotify-bin`, a recorder). Launch it from the app
|
||||
grid, or run `blitztext` / `blitztext gui` from a terminal. Remove with
|
||||
`sudo apt remove blitztext`.
|
||||
|
||||
### Option B — run from source (venv)
|
||||
|
||||
```bash
|
||||
cd linux
|
||||
./install.sh
|
||||
@ -45,6 +63,11 @@ cd linux
|
||||
This creates `.venv`, installs `faster-whisper` + `pynput`, and writes the
|
||||
default config to `~/.config/blitztext/config.toml`.
|
||||
|
||||
> For the **tray** from source, the venv must be built on a Python that can see
|
||||
> the system `python3-gi` — `install.sh` uses `python3 -m venv
|
||||
> --system-site-packages`, so use the system `/usr/bin/python3` (a conda/miniforge
|
||||
> Python won't see the apt-installed `gi`). The `.deb` handles this for you.
|
||||
|
||||
## Run
|
||||
|
||||
Three front-ends, same engine (local Whisper + global hotkeys + xdotool typing):
|
||||
@ -62,17 +85,18 @@ export OPENAI_API_KEY=sk-...
|
||||
|
||||
The tray is the closest match to the macOS menu-bar app: a status icon with a
|
||||
menu listing every workflow (click to record), plus **Show panel**, **Settings…**,
|
||||
and **Quit**. It needs PyGObject once (the GTK/AppIndicator typelibs and the
|
||||
GNOME `ubuntu-appindicators` extension are already present here):
|
||||
and **Quit**. It needs PyGObject (`python3-gi`) and the GTK/AppIndicator
|
||||
typelibs — already present on a standard Ubuntu GNOME install (the `.deb`
|
||||
declares them as dependencies):
|
||||
|
||||
```bash
|
||||
sudo apt install python3-gi # one-time; no build, just the bindings
|
||||
sudo apt install python3-gi # usually already installed
|
||||
.venv/bin/python -m blitztext tray
|
||||
```
|
||||
|
||||
If PyGObject is missing, `tray` prints this hint and falls back to the window.
|
||||
(The venv is created with `--system-site-packages` so it can see the
|
||||
apt-installed `gi`.)
|
||||
If PyGObject isn't visible, `tray` prints this hint and falls back to the
|
||||
window. The venv is created with `--system-site-packages` so it can see the
|
||||
system `gi` — build it from `/usr/bin/python3`, not a conda/miniforge Python.
|
||||
|
||||
Either way, focus any text field and trigger a workflow — by tray menu, panel
|
||||
button, or hotkey (defaults):
|
||||
|
||||
@ -6,4 +6,4 @@ counterpart to the macOS Blitztext menu bar app: it runs natively on the host
|
||||
(not in a container) so it can type into any application via xdotool.
|
||||
"""
|
||||
|
||||
__version__ = "1.0.1"
|
||||
__version__ = "1.1.0"
|
||||
|
||||
11
linux/packaging/blitztext.desktop
Normal file
11
linux/packaging/blitztext.desktop
Normal file
@ -0,0 +1,11 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Blitztext
|
||||
GenericName=Voice Dictation
|
||||
Comment=Speak and have the text typed into any field
|
||||
Exec=blitztext tray
|
||||
Icon=blitztext
|
||||
Terminal=false
|
||||
Categories=Utility;AudioVideo;Accessibility;
|
||||
Keywords=dictation;speech;voice;transcription;whisper;stt;
|
||||
StartupNotify=false
|
||||
12
linux/packaging/blitztext.svg
Normal file
12
linux/packaging/blitztext.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="128" height="128" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0" stop-color="#2b8cff"/>
|
||||
<stop offset="1" stop-color="#0a5cf0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect x="8" y="8" width="112" height="112" rx="28" fill="url(#bg)"/>
|
||||
<path d="M70 26 L42 70 H60 L56 102 L86 56 H66 Z"
|
||||
fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 529 B |
104
linux/packaging/build-deb.sh
Executable file
104
linux/packaging/build-deb.sh
Executable file
@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build a self-contained .deb for Blitztext (Ubuntu/Debian, arm64).
|
||||
#
|
||||
# Bundles a relocatable venv with the Python deps (faster-whisper, pynput,
|
||||
# tomli-w) under /opt/blitztext so installation needs no pip/network. System
|
||||
# integration (python3-gi, xdotool, libnotify-bin, a recorder) is declared via
|
||||
# Depends so the Software app / apt pull them in.
|
||||
set -euo pipefail
|
||||
|
||||
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||
LINUX_DIR="$(dirname "$HERE")" # .../linux
|
||||
PKG="blitztext"
|
||||
ARCH="$(dpkg --print-architecture)"
|
||||
VER="$(sed -n 's/.*__version__ = "\(.*\)".*/\1/p' "$LINUX_DIR/blitztext/__init__.py")"
|
||||
PYBIN="${PYBIN:-/usr/bin/python3}"
|
||||
|
||||
BUILD="$(mktemp -d)"
|
||||
ROOT="$BUILD/${PKG}_${VER}_${ARCH}"
|
||||
OUT_DIR="${OUT_DIR:-$LINUX_DIR/dist}"
|
||||
trap 'rm -rf "$BUILD"' EXIT
|
||||
|
||||
echo "==> Building $PKG $VER ($ARCH) with $($PYBIN --version)"
|
||||
|
||||
# 1) Bundled, relocatable venv with all Python deps -------------------------
|
||||
APPDIR="$ROOT/opt/$PKG"
|
||||
VENV="$APPDIR/venv"
|
||||
mkdir -p "$APPDIR"
|
||||
"$PYBIN" -m venv --copies "$VENV"
|
||||
"$VENV/bin/pip" install --upgrade pip -q
|
||||
"$VENV/bin/pip" install -q -r "$LINUX_DIR/requirements.txt" tomli-w
|
||||
|
||||
# Drop the app package into the venv so `python -m blitztext` works.
|
||||
cp -r "$LINUX_DIR/blitztext" "$VENV/lib/python"*/site-packages/
|
||||
|
||||
# Let the venv also see the system PyGObject (apt python3-gi) for tray mode,
|
||||
# while still preferring its own bundled deps.
|
||||
PYVENV="$VENV/pyvenv.cfg"
|
||||
sed -i 's/^include-system-site-packages = false/include-system-site-packages = true/' "$PYVENV"
|
||||
grep -q "^include-system-site-packages = true" "$PYVENV" || echo "include-system-site-packages = true" >> "$PYVENV"
|
||||
|
||||
# Trim build cruft to shrink the package.
|
||||
find "$VENV" -type d -name "__pycache__" -prune -exec rm -rf {} + 2>/dev/null || true
|
||||
rm -rf "$VENV/lib/python"*/site-packages/pip "$VENV/lib/python"*/site-packages/pip-* \
|
||||
"$VENV"/bin/pip* "$VENV/lib/python"*/site-packages/setuptools* 2>/dev/null || true
|
||||
|
||||
cp "$LINUX_DIR/README.md" "$LINUX_DIR/CHANGELOG.md" "$APPDIR/"
|
||||
|
||||
# 2) Launcher, desktop entry, icon, docs ------------------------------------
|
||||
install -Dm755 /dev/stdin "$ROOT/usr/bin/$PKG" <<'EOF'
|
||||
#!/bin/sh
|
||||
exec /opt/blitztext/venv/bin/python -m blitztext "$@"
|
||||
EOF
|
||||
|
||||
install -Dm644 "$HERE/$PKG.desktop" "$ROOT/usr/share/applications/$PKG.desktop"
|
||||
install -Dm644 "$HERE/$PKG.svg" "$ROOT/usr/share/icons/hicolor/scalable/apps/$PKG.svg"
|
||||
install -Dm644 "$HERE/copyright" "$ROOT/usr/share/doc/$PKG/copyright"
|
||||
|
||||
# 3) DEBIAN control + maintainer scripts ------------------------------------
|
||||
SIZE_KB="$(du -sk "$ROOT" | cut -f1)"
|
||||
mkdir -p "$ROOT/DEBIAN"
|
||||
cat > "$ROOT/DEBIAN/control" <<EOF
|
||||
Package: $PKG
|
||||
Version: $VER
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Architecture: $ARCH
|
||||
Depends: python3 (>= 3.12), python3-gi, gir1.2-ayatanaappindicator3-0.1, xdotool, libnotify-bin, pipewire-bin | pulseaudio-utils | alsa-utils
|
||||
Maintainer: Martin Bierschenk <mail@martin-bierschenk.de>
|
||||
Installed-Size: $SIZE_KB
|
||||
Description: Blitztext - local voice dictation for Linux
|
||||
Focus any text field, press a hotkey, speak, and the transcribed text is
|
||||
typed into that field. Optional LLM rewrite turns rough speech into a nicer
|
||||
email, a calmer message, or adds emojis.
|
||||
.
|
||||
Transcription runs locally via faster-whisper; the optional rewrite uses any
|
||||
OpenAI-compatible endpoint (OpenAI or a local server). Runs in the system
|
||||
tray or as a small control-panel window. Requires an X11 session.
|
||||
EOF
|
||||
|
||||
cat > "$ROOT/DEBIAN/postinst" <<'EOF'
|
||||
#!/bin/sh
|
||||
set -e
|
||||
if [ "$1" = "configure" ]; then
|
||||
gtk-update-icon-cache -qf /usr/share/icons/hicolor 2>/dev/null || true
|
||||
update-desktop-database -q 2>/dev/null || true
|
||||
fi
|
||||
EOF
|
||||
chmod 755 "$ROOT/DEBIAN/postinst"
|
||||
|
||||
cat > "$ROOT/DEBIAN/postrm" <<'EOF'
|
||||
#!/bin/sh
|
||||
set -e
|
||||
# Remove runtime-generated files (e.g. *.pyc) left in the bundled venv.
|
||||
if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then
|
||||
rm -rf /opt/blitztext
|
||||
fi
|
||||
EOF
|
||||
chmod 755 "$ROOT/DEBIAN/postrm"
|
||||
|
||||
# 4) Build -------------------------------------------------------------------
|
||||
mkdir -p "$OUT_DIR"
|
||||
DEB="$OUT_DIR/${PKG}_${VER}_${ARCH}.deb"
|
||||
fakeroot dpkg-deb --build --root-owner-group "$ROOT" "$DEB" >/dev/null
|
||||
echo "==> Built: $DEB ($(du -h "$DEB" | cut -f1))"
|
||||
26
linux/packaging/copyright
Normal file
26
linux/packaging/copyright
Normal file
@ -0,0 +1,26 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: blitztext
|
||||
Source: https://github.com/mARTin-B78/blitztext-app
|
||||
|
||||
Files: *
|
||||
Copyright: 2026 Martin Bierschenk
|
||||
License: MIT
|
||||
|
||||
License: MIT
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
Loading…
Reference in New Issue
Block a user