#!/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)