Add system package install

This commit is contained in:
Michael Hansen
2024-01-16 17:06:30 -06:00
parent 73604f9a71
commit 00d2625571
3 changed files with 142 additions and 16 deletions
+34 -4
View File
@@ -5,6 +5,12 @@ from typing import List, Optional
from .const import LOCAL_DIR, PROGRAM_DIR, SatelliteType, Settings from .const import LOCAL_DIR, PROGRAM_DIR, SatelliteType, Settings
from .drivers import install_drivers from .drivers import install_drivers
from .microphone import configure_microphone from .microphone import configure_microphone
from .packages import (
can_import,
install_packages,
install_packages_nogui,
packages_installed,
)
from .satellite import configure_satellite from .satellite import configure_satellite
from .services import generate_services, install_services, stop_services from .services import generate_services, install_services, stop_services
from .speakers import configure_speakers from .speakers import configure_speakers
@@ -22,6 +28,9 @@ def main() -> None:
settings = Settings.load() settings = Settings.load()
if not packages_installed("whiptail"):
install_packages_nogui("whiptail")
choice: Optional[str] = None choice: Optional[str] = None
while True: while True:
choice = main_menu(choice) choice = main_menu(choice)
@@ -85,6 +94,19 @@ def apply_settings(settings: Settings) -> None:
msgbox("Please set wake word system") msgbox("Please set wake word system")
return return
password: Optional[str] = None
if not packages_installed("python3-pip", "python3-venv"):
password = passwordbox("sudo password:")
if not password:
return
success = install_packages(
"Installing Python packages...", password, "python3-pip", "python3-venv"
)
if not success:
error("installing pip/venv for Python")
return
# Satellite venv # Satellite venv
venv_dir = PROGRAM_DIR / ".venv" venv_dir = PROGRAM_DIR / ".venv"
if not venv_dir.exists(): if not venv_dir.exists():
@@ -96,7 +118,9 @@ def apply_settings(settings: Settings) -> None:
return return
# silero (vad) # silero (vad)
if settings.satellite.type == SatelliteType.VAD: if (settings.satellite.type == SatelliteType.VAD) and (
not can_import("pysilero_vad")
):
result = run_with_gauge( result = run_with_gauge(
"Installing vad...", "Installing vad...",
[pip_install("-r", str(PROGRAM_DIR / "requirements_vad.txt"))], [pip_install("-r", str(PROGRAM_DIR / "requirements_vad.txt"))],
@@ -106,7 +130,9 @@ def apply_settings(settings: Settings) -> None:
return return
# webrtc (audio enhancements) # webrtc (audio enhancements)
if (settings.mic.noise_suppression > 0) or (settings.mic.auto_gain > 0): if ((settings.mic.noise_suppression > 0) or (settings.mic.auto_gain > 0)) and (
not can_import("webrtc_noise_gain")
):
result = run_with_gauge( result = run_with_gauge(
"Installing audio enhancements...", "Installing audio enhancements...",
[ [
@@ -119,10 +145,13 @@ def apply_settings(settings: Settings) -> None:
error("installing audio enhancements") error("installing audio enhancements")
return return
if settings.satellite.event_service_command and ( if (
settings.satellite.event_service_command
and (
("2mic" in settings.satellite.event_service_command) ("2mic" in settings.satellite.event_service_command)
or ("4mic" in settings.satellite.event_service_command) or ("4mic" in settings.satellite.event_service_command)
): )
) and (not can_import("gpiozero", "spidev")):
result = run_with_gauge( result = run_with_gauge(
"Installing event requirements...", "Installing event requirements...",
[pip_install("-r", str(PROGRAM_DIR / "requirements_respeaker.txt"))], [pip_install("-r", str(PROGRAM_DIR / "requirements_respeaker.txt"))],
@@ -133,6 +162,7 @@ def apply_settings(settings: Settings) -> None:
generate_services(settings) generate_services(settings)
if password is None:
password = passwordbox("sudo password:") password = passwordbox("sudo password:")
if not password: if not password:
return return
+74
View File
@@ -0,0 +1,74 @@
"""Install system packages."""
import subprocess
from .const import PROGRAM_DIR
from .whiptail import run_with_gauge
def packages_installed(*packages) -> bool:
for package in packages:
try:
subprocess.check_call(["dpkg", "--status", str(package)])
except Exception:
return False
return True
def install_packages_nogui(*packages, update: bool = True) -> bool:
assert packages, "No packages"
commands = []
if update:
commands.append(["sudo", "apt-get", "update"])
commands.append(
["sudo", "apt-get", "install", "--yes"] + [str(p) for p in packages]
)
for command in commands:
subprocess.check_call(
command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
)
def install_packages(
text: str, sudo_password: str, *packages, update: bool = True
) -> bool:
assert packages, "No packages"
commands = []
if update:
commands.append(["sudo", "-S", "apt-get", "update"])
commands.append(
["sudo", "-S", "apt-get", "install", "--yes"] + [str(p) for p in packages]
)
return run_with_gauge(text, commands, sudo_password=sudo_password)
def can_import(*names) -> bool:
assert names, "No names"
venv_dir = PROGRAM_DIR / ".venv"
if not venv_dir.exists():
return False
try:
import venv
except ImportError:
return False
context = venv.EnvBuilder().ensure_directories(PROGRAM_DIR / ".venv")
try:
subprocess.check_call(
[context.env_exe, "-c", "; ".join(f"import {name}" for name in names)],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
except Exception:
return False
return True
+28 -6
View File
@@ -6,7 +6,17 @@ from pathlib import Path
from typing import Dict, Optional from typing import Dict, Optional
from .const import LOCAL_DIR, SatelliteType, Settings, WakeWordSystem from .const import LOCAL_DIR, SatelliteType, Settings, WakeWordSystem
from .whiptail import error, inputbox, menu, msgbox, radiolist, run_with_gauge, yesno from .packages import install_packages, packages_installed
from .whiptail import (
error,
inputbox,
menu,
msgbox,
passwordbox,
radiolist,
run_with_gauge,
yesno,
)
def configure_wake_word(settings: Settings) -> None: def configure_wake_word(settings: Settings) -> None:
@@ -93,7 +103,6 @@ def install_wake_word(settings: Settings, wake_word_system: WakeWordSystem) -> N
return return
msgbox("openWakeWord installed successfully") msgbox("openWakeWord installed successfully")
settings.wake.system = wake_word_system settings.wake.system = wake_word_system
settings.save() settings.save()
return return
@@ -125,9 +134,9 @@ def install_wake_word(settings: Settings, wake_word_system: WakeWordSystem) -> N
pass pass
error("installing porcupine1") error("installing porcupine1")
else: return
msgbox("porcupine1 installed successfully")
msgbox("porcupine1 installed successfully")
settings.wake.system = wake_word_system settings.wake.system = wake_word_system
settings.save() settings.save()
return return
@@ -138,6 +147,19 @@ def install_wake_word(settings: Settings, wake_word_system: WakeWordSystem) -> N
if not yesno("Install snowboy?"): if not yesno("Install snowboy?"):
return return
snowboy_packages = ["python3-dev", "swig", "libatlas-base-dev"]
if not packages_installed(*snowboy_packages):
password = passwordbox("sudo password:")
if not password:
return
success = install_packages(
"Installing system packages...", password, *snowboy_packages
)
if not success:
error("installing " + ", ".join(snowboy_packages))
return
success = run_with_gauge( success = run_with_gauge(
"Installing snowboy", "Installing snowboy",
[ [
@@ -159,9 +181,9 @@ def install_wake_word(settings: Settings, wake_word_system: WakeWordSystem) -> N
pass pass
error("installing snowboy") error("installing snowboy")
else: return
msgbox("snowboy installed successfully")
msgbox("snowboy installed successfully")
settings.wake.system = wake_word_system settings.wake.system = wake_word_system
settings.save() settings.save()
return return