~geb/numen

77931c997ede7b20fa751b107fb36dff0d86c49f — John Gebbie 9 months ago e2b7897
install: separate building and installing

Also installs to /usr/lib not /lib, removes ./install-vosk-musl.sh
and $NUMEN_MANPAGE_DIR, and bumps dotool.
9 files changed, 124 insertions(+), 158 deletions(-)

M .gitignore
M README.md
A build.sh
A get-dotool.sh
R install-model.sh => get-model.sh
R install-vosk.sh => get-vosk.sh
D install-dotool.sh
D install-numen.sh
D install-vosk-musl.sh
M .gitignore => .gitignore +0 -2
@@ 1,3 1,1 @@
/model
/numen
/tmp/

M README.md => README.md +4 -3
@@ 23,16 23,17 @@ and potentially other platforms.
A binary of the [speech recognition library](https://alphacephei.com/vosk)
and an English model (about 40MB) can be installed with:

    sudo ./install-vosk.sh && sudo ./install-model.sh
    ./get-vosk.sh && sudo ./get-vosk.sh install
    ./get-model.sh && sudo ./get-model.sh install

The [dotool](https://sr.ht/~geb/dotool) command which simulates the input,
can be installed with:

    sudo ./install-dotool.sh
    ./get-dotool.sh && sudo ./get-dotool.sh install

Finally, Numen itself can be installed with:

    sudo ./install-numen.sh
    ./build.sh && sudo ./build.sh install

## Permission and Keyboard Layouts


A build.sh => build.sh +42 -0
@@ 0,0 1,42 @@
#!/bin/sh
# ./build.sh ['install']
: "${NUMEN_VERSION=$(git describe --long --abbrev=12 --tags --dirty 2>/dev/null || echo 0.7)}"
: "${NUMEN_DESTDIR=}"
: "${NUMEN_BINDIR=usr/local/bin}"
: "${NUMEN_DEFAULT_PHRASES_DIR=/etc/numen/phrases}"
: "${NUMEN_SCRIPTS_DIR=/etc/numen/scripts}"
: "${NUMEN_DEFAULT_MODEL_PACKAGE=vosk-model-small-en-us}"
: "${NUMEN_DEFAULT_MODEL_PATHS=/usr/local/share/vosk-models/small-en-us /usr/share/vosk-models/small-en-us}"

if [ "$*" != '' ] && [ "$*" != install ]; then
	echo bad usage
	exit 1
fi

if ! [ "$NUMEN_SKIP_CHECKS" ]; then
	ok=1
	! command -v arecord >/dev/null && echo 'you need alsa-utils' && unset ok
	! command -v dotool >/dev/null && echo 'you need dotool' && unset ok
	! command -v gcc >/dev/null && echo 'you need gcc' && unset ok
	! command -v go >/dev/null && echo 'you need go (aka golang)' && unset ok
	! command -v scdoc >/dev/null && echo 'you need scdoc' && unset ok
	[ "$ok" ] || exit
fi

if ! [ "$1" ]; then
	go build -ldflags "-X 'main.Version=$NUMEN_VERSION'
		-X 'main.DefaultModelPackage=$NUMEN_DEFAULT_MODEL_PACKAGE'
		-X 'main.DefaultModelPaths=$NUMEN_DEFAULT_MODEL_PATHS'
		-X 'main.DefaultPhrasesDir=$NUMEN_DEFAULT_PHRASES_DIR'" || exit
	echo Built successfully.
else
	install -Dm755 numen numenc -t "$NUMEN_DESTDIR/$NUMEN_BINDIR" || exit
	install -Dm755 scripts/* -t "$NUMEN_DESTDIR/$NUMEN_SCRIPTS_DIR" || exit
	install -Dm644 phrases/* -t "$NUMEN_DESTDIR/$NUMEN_DEFAULT_PHRASES_DIR" || exit
	sed -i "s:/etc/numen/scripts:$NUMEN_SCRIPTS_DIR:g" \
		"$NUMEN_DESTDIR/$NUMEN_SCRIPTS_DIR"/* \
		"$NUMEN_DESTDIR/$NUMEN_DEFAULT_PHRASES_DIR"/* || exit
	mkdir -p "$NUMEN_DESTDIR/usr/share/man/man1" || exit
	scdoc < doc/numen.1.scd > "$NUMEN_DESTDIR/usr/share/man/man1/numen.1" || exit
	echo Installed Successfully.
fi

A get-dotool.sh => get-dotool.sh +35 -0
@@ 0,0 1,35 @@
#!/bin/sh
# ./get-dotool.sh ['install']
version=7688cc321c18420ac44abdb5d0acaba09af1675b
distfile="https://git.sr.ht/~geb/dotool/archive/$version.tar.gz"
checksum=6b331da5d52fc6f3c987fe7c85b6984c484eb43640eb940097143ff6523d11c9

if [ "$*" != '' ] && [ "$*" != install ]; then
	echo bad usage
	exit 1
fi

ok=1
! command -v go >/dev/null && echo 'you need go (aka golang)' && unset ok
! command -v tar >/dev/null && echo 'you need tar' && unset ok
! command -v scdoc >/dev/null && echo 'you need scdoc' && unset ok
! command -v wget >/dev/null && echo 'you need wget' && unset ok
! test -d /usr/include/xkbcommon && echo 'you need libxkbcommon-dev' && unset ok
[ "$ok" ] || exit

export DOTOOL_VERSION="$version"

mkdir -p tmp && cd tmp
if ! [ "$1" ]; then
	wget --no-verbose -O dotool.tar.gz "$distfile" || exit
	if [ "$(sha256sum dotool.tar.gz | cut -d' ' -f1)" != "$checksum" ]; then
		echo dotool.tar.gz did not match checksum
		exit 1
	fi
	tar xf dotool.tar.gz || exit
	cd "dotool-$version" || exit
	./build.sh || exit
else
	cd "dotool-$version" || exit
	./build.sh install || exit
fi

R install-model.sh => get-model.sh +19 -17
@@ 1,28 1,30 @@
#!/bin/sh
# This installs a Vosk speech recognition model.
# ./get-model.sh ['install']
f=vosk-model-small-en-us-0.15
name=small-en-us
checksum=30f26242c4eb449f948e42cb302dd7a686cb29a3423a8367f99ff41780942498

if [ "$*" != '' ] && [ "$*" != install ]; then
	echo bad usage
	exit 1
fi

ok=1
! command -v unzip >/dev/null && echo 'you need unzip' && unset ok
! command -v wget >/dev/null && echo 'you need wget' && unset ok
[ "$ok" ] || exit

# not necessary but lets you run ./numen in this directory
ln -sf "/usr/local/share/vosk-models/$model_name" model

rm -rf tmp && mkdir -p tmp && cd tmp || exit

wget "https://alphacephei.com/kaldi/models/$f.zip" || exit
if [ "$(sha256sum "$f.zip" | cut -d' ' -f1)" != "$checksum" ]; then
	printf %s\\n "$f.zip did not match the checksum"
	exit 1
mkdir -p tmp && cd tmp
if ! [ "$1" ]; then
	wget --no-verbose -O "$f.zip" "https://alphacephei.com/kaldi/models/$f.zip" || exit
	if [ "$(sha256sum "$f.zip" | cut -d' ' -f1)" != "$checksum" ]; then
		printf %s\\n "$f.zip did not match the checksum"
		exit 1
	fi
	echo Downloaded successfully.
else
	unzip -qo "$f.zip" || exit
	mkdir -p /usr/local/share/vosk-models || exit
	mv -T "$f" "/usr/local/share/vosk-models/$name" || exit
	echo Installed successfully.
fi

unzip -q "$f.zip" || exit
mkdir -p /usr/local/share/vosk-models || exit
rm -rf "/usr/local/share/vosk-models/$name" || exit
mv "$f" "/usr/local/share/vosk-models/$name" || exit

echo 'Installed successfully.'

R install-vosk.sh => get-vosk.sh +24 -19
@@ 1,19 1,19 @@
#!/bin/sh
# This installs the Vosk speech recognition library.
# See ./install-vosk-musl.sh for musl-based distros like Alpine Linux.
# ./get-vosk.sh ['install']
version=0.3.45

ok=1
! command -v unzip >/dev/null && echo 'you need unzip' && unset ok
! command -v wget >/dev/null && echo 'you need wget' && unset ok
[ "$ok" ] || exit
if [ "$*" != '' ] && [ "$*" != install ]; then
	echo bad usage
	exit 1
fi

a="$(uname -m)"
case "$a" in
*86) a=x86;;
aarch64|armv7l|riscv64|x86_64) ;;
*) echo "There isn't a binary for your architecture: $a"; exit 1;;
*) echo "there's no binary for your architecture: $a"; exit 1;;
esac
f="vosk-linux-$a-$version"

case "$a" in
aarch64) checksum=45e95d37755deb07568e79497d7feba8c03aee5a9e071df29961aa023fd94541;;


@@ 23,17 23,22 @@ x86) checksum=b539efc22780948bd98e2ecb9c1b92ca08b3c552a18744f7202ab78405b8e1f9;;
x86_64) checksum=bbdc8ed85c43979f6443142889770ea95cbfbc56cffb5c5dcd73afa875c5fbb2;;
esac

rm -rf tmp && mkdir -p tmp && cd tmp || exit
ok=1
! command -v unzip >/dev/null && echo 'you need unzip' && unset ok
! command -v wget >/dev/null && echo 'you need wget' && unset ok
[ "$ok" ] || exit

f="vosk-linux-$a-$version"
wget "https://github.com/alphacep/vosk-api/releases/download/v$version/$f.zip" || exit
if [ "$(sha256sum "$f.zip" | cut -d' ' -f1)" != "$checksum" ]; then
	printf %s\\n "$f.zip did not match the checksum"
	exit 1
mkdir -p tmp && cd tmp
if ! [ "$1" ]; then
	wget --no-verbose -O "$f.zip" "https://github.com/alphacep/vosk-api/releases/download/v$version/$f.zip" || exit
	if [ "$(sha256sum "$f.zip" | cut -d' ' -f1)" != "$checksum" ]; then
		printf %s\\n "$f.zip did not match the checksum"
		exit 1
	fi
	echo Downloaded successfully.
else
	unzip -qo "$f.zip" || exit
	install -Dm755 "$f/libvosk.so" -t /usr/lib || exit
	install -Dm644 "$f/vosk_api.h" -t /usr/include || exit
	echo Installed successfully.
fi

unzip -q "$f" || exit
mkdir -p /lib && cp "$f/libvosk.so" /lib || exit
mkdir -p /usr/include && cp "$f/vosk_api.h" /usr/include || exit

echo 'Installed successfully.'

D install-dotool.sh => install-dotool.sh +0 -25
@@ 1,25 0,0 @@
#!/bin/sh
version=7b38f27d30581b2ba2a75c079502fdc118e4bf57
distfile="https://git.sr.ht/~geb/dotool/archive/$version.tar.gz"
checksum=6a9156bdf8bb6405615733e14cf22f6f5e91c4006799b5e9770d09e08633bda0

ok=1
! command -v go > /dev/null && echo 'you need go (sometimes packaged as golang)' && unset ok
! command -v tar > /dev/null && echo 'you need tar' && unset ok
! command -v wget > /dev/null && echo 'you need wget' && unset ok
! test -d /usr/include/xkbcommon && echo 'you need libxkbcommon-dev' && unset ok
[ "$ok" ] || exit

rm -rf tmp && mkdir -p tmp && cd tmp || exit

wget --no-verbose -O dotool.tar.gz "$distfile" || exit
if [ "$(sha256sum dotool.tar.gz | cut -d' ' -f1)" != "$checksum" ]; then
	echo 'dotool.tar.gz did not match checksum'
	exit 1
fi

tar xf dotool.tar.gz || exit
cd "dotool-$version" || exit
DOTOOL_VERSION="$version" ./install.sh || exit

echo 'Installed successfully.'

D install-numen.sh => install-numen.sh +0 -57
@@ 1,57 0,0 @@
#!/bin/sh
# install-numen.sh [DESTDIR] [BINDIR]
: "${NUMEN_VERSION=$(git describe --long --abbrev=12 --tags --dirty 2>/dev/null || echo 0.7)}"
: "${NUMEN_DEFAULT_MODEL_PACKAGE=vosk-model-small-en-us}"
: "${NUMEN_DEFAULT_MODEL_PATHS=/usr/local/share/vosk-models/small-en-us /usr/share/vosk-models/small-en-us}"
: "${NUMEN_DEFAULT_PHRASES_DIR=/etc/numen/phrases}"
: "${NUMEN_MANPAGE_DIR=/usr/share/man/man1}"
: "${NUMEN_SCRIPTS_DIR=/etc/numen/scripts}"

if ! [ "$NUMEN_SKIP_CHECKS" ]; then
	ok=1
	! command -v arecord >/dev/null && echo 'you need the alsa-utils package' && unset ok
	! command -v dotool >/dev/null && echo 'you need dotool' && unset ok
	! command -v gcc >/dev/null && echo 'you need gcc' && unset ok
	! command -v go >/dev/null && echo 'you need go (aka golang)' && unset ok
	! command -v scdoc >/dev/null && echo 'you need scdoc' && unset ok
	[ "$ok" ] || exit

	if ! dotool --version >/dev/null 2>&1; then
		echo 'You need a newer version of dotool (version 1.1 or later),'
		echo 'use your package manager or run: sudo ./install-dotool.sh'
		exit 1
	fi
fi

if ! [ "$NUMEN_SKIP_BINARY" ]; then
	go build -buildvcs=false -ldflags "-X 'main.Version=$NUMEN_VERSION'
		-X 'main.DefaultModelPackage=$NUMEN_DEFAULT_MODEL_PACKAGE'
		-X 'main.DefaultModelPaths=$NUMEN_DEFAULT_MODEL_PATHS'
		-X 'main.DefaultPhrasesDir=$NUMEN_DEFAULT_PHRASES_DIR'" || exit
	echo 'Built successfully.'
fi

if [ "$NUMEN_SKIP_INSTALL" ]; then
	exit
fi

mkdir -p "$1/${2:-usr/local/bin}" || exit
if ! [ "$NUMEN_SKIP_BINARY" ]; then
	cp numen "$1/${2:-usr/local/bin}" || exit
fi
cp numenc "$1/${2:-usr/local/bin}" || exit

# Install the scripts used in the default phrases
rm -rf "$1/$NUMEN_SCRIPTS_DIR" && mkdir -p "$1/$NUMEN_SCRIPTS_DIR" || exit
cp scripts/* "$1/$NUMEN_SCRIPTS_DIR" || exit
sed -i "s:/etc/numen/scripts:$NUMEN_SCRIPTS_DIR:g" "$1/$NUMEN_SCRIPTS_DIR"/* || exit

# Install the default phrases
rm -rf "$1/$NUMEN_DEFAULT_PHRASES_DIR" && mkdir -p "$1/$NUMEN_DEFAULT_PHRASES_DIR" || exit
cp -r phrases/* "$1/$NUMEN_DEFAULT_PHRASES_DIR" || exit
sed -i "s:/etc/numen/scripts:$NUMEN_SCRIPTS_DIR:g" "$1/$NUMEN_DEFAULT_PHRASES_DIR"/* || exit

# Install the manpage
mkdir -p "$1/$NUMEN_MANPAGE_DIR" && scdoc < doc/numen.1.scd > "$1/$NUMEN_MANPAGE_DIR/numen.1" || exit

echo 'Installed successfully.'

D install-vosk-musl.sh => install-vosk-musl.sh +0 -35
@@ 1,35 0,0 @@
#!/bin/sh
# This installs the Vosk speech recognition library for musl-based distros
# like Alpine Linux.
version=0.3.45

ok=1
! command -v unzip >/dev/null && echo 'you need unzip' && unset ok
! command -v wget >/dev/null && echo 'you need wget' && unset ok
[ "$ok" ] || exit

a="$(uname -m)"
case "$a" in
aarch64|x86_64) ;;
*) echo "There isn't a binary for your architecture: $a"; exit 1;;
esac

case "$a" in
aarch64) checksum=78a5273c523f74a56d897a202aaa1b8a7dd948c62038bd243960c14f8cc991a5;;
x86_64) checksum=f48b9f8f99d8241c394414472e1893c8bf2df749ac6e322cfc729fd6f71f178a;;
esac

rm -rf tmp && mkdir -p tmp && cd tmp || exit

f="$a"
wget "https://github.com/JohnGebbie/build-vosk/releases/download/$version/$f.zip" || exit
if [ "$(sha256sum "$f.zip" | cut -d' ' -f1)" != "$checksum" ]; then
	printf %s\\n "$f.zip did not match the checksum"
	exit 1
fi

unzip -q "$f" || exit
mkdir -p /lib && cp "$f/libvosk.so" /lib || exit
mkdir -p /usr/include && cp "$f/vosk_api.h" /usr/include || exit

echo 'Installed successfully.'