VoicePult/scripts/launcher.py
2026-10-03 11:07:47 +02:00

76 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""Installed VoicePult desktop launcher. No third-party dependencies."""
import argparse
import json
import os
from pathlib import Path
import subprocess
import sys
import time
import urllib.error
import urllib.request
ROOT = Path(__file__).resolve().parent
URL = 'http://127.0.0.1:8765'
def status():
try:
# Localhost should not pass through a user's HTTP proxy.
opener = urllib.request.build_opener(urllib.request.ProxyHandler({}))
with opener.open(URL + '/api/state', timeout=2) as response:
data = json.load(response)
if isinstance(data, dict) and data.get('virtual_mic') == 'VoicePult Mikrofon' and 'channels' in data:
return data
except (OSError, ValueError, urllib.error.URLError):
pass
return None
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--serve', action='store_true')
parser.add_argument('--background', action='store_true')
args = parser.parse_args()
meta = json.loads((ROOT / 'install.json').read_text())
config = Path(meta['config'])
command = [sys.executable, str(ROOT / 'server.py'), '--config', str(config)]
if meta.get('lan'):
command.append('--lan')
if args.serve:
os.execv(sys.executable, command)
if status() is None:
service_started = False
if meta['systemd']:
result = subprocess.run(['systemctl', '--user', 'start', 'voicepult.service'], capture_output=True)
service_started = result.returncode == 0
if not service_started:
log = Path(meta['log'])
log.parent.mkdir(parents=True, exist_ok=True)
with log.open('ab') as output:
subprocess.Popen(command, stdin=subprocess.DEVNULL, stdout=output,
stderr=output, start_new_session=True, cwd=ROOT)
for _ in range(40):
if status() is not None:
break
time.sleep(.25)
else:
log_hint = 'journalctl --user -u voicepult.service' if meta['systemd'] else meta['log']
raise RuntimeError('VoicePult startet nicht. Eventuell läuft bereits eine andere Instanz oder Port 8765 ist belegt. Protokoll: ' + log_hint)
if not args.background:
subprocess.run(['xdg-open', URL], check=True)
return 0
if __name__ == '__main__':
try:
sys.exit(main())
except (OSError, ValueError, RuntimeError, subprocess.CalledProcessError) as exc:
print('VoicePult: ' + str(exc), file=sys.stderr)
# Desktop launchers usually have no visible terminal.
try:
subprocess.run(['notify-send', 'VoicePult konnte nicht geöffnet werden', str(exc)], check=False)
except OSError:
pass
sys.exit(1)