Add system package install
This commit is contained in:
+39
-9
@@ -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 (
|
||||||
("2mic" in settings.satellite.event_service_command)
|
settings.satellite.event_service_command
|
||||||
or ("4mic" in settings.satellite.event_service_command)
|
and (
|
||||||
):
|
("2mic" 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,9 +162,10 @@ def apply_settings(settings: Settings) -> None:
|
|||||||
|
|
||||||
generate_services(settings)
|
generate_services(settings)
|
||||||
|
|
||||||
password = passwordbox("sudo password:")
|
if password is None:
|
||||||
if not password:
|
password = passwordbox("sudo password:")
|
||||||
return
|
if not password:
|
||||||
|
return
|
||||||
|
|
||||||
stop_services(password)
|
stop_services(password)
|
||||||
install_services(settings, password)
|
install_services(settings, password)
|
||||||
|
|||||||
@@ -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
|
||||||
+29
-7
@@ -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:
|
||||||
@@ -92,8 +102,7 @@ def install_wake_word(settings: Settings, wake_word_system: WakeWordSystem) -> N
|
|||||||
error("installing openWakeWord")
|
error("installing openWakeWord")
|
||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user