def on_start_sound(cmd: pcmd.Command, args: List[str], parameters: List[str], json: bool) -> None: """Callback for `start sound` - adds a sound effect""" for i, a in enumerate(parameters): if re.match(r'^[\d\.]*$', a): continue if not os.path.isfile(a): a = os.path.join(params.BPATH, 'res', 'sounds', a) if not os.path.isfile(a): if not json: utils.printerr(f'File "{a}" doesn\'t exist ... ') continue else: print( JSON.dumps({ 'error': f'File "{a}" doesn\'t exist ... "', })) return try: if i + 1 < len(args) and re.match(r'^[\d\.]+$', args[i + 1]): ch.add_sound(Sound(a, float(args[i + 1]))) continue ch.add_sound(Sound(a)) except Exception as e: if not json: utils.printerr(str(e)) else: print(JSON.dumps({ 'error': str(e), })) if json: print(JSON.dumps({}))
def on_show_audio(cmd: pcmd.Command, args: List[str], scale: float, char: str) -> None: """Callback for `show audio` - shows the detected input""" if not ch.is_alive(): utils.printerr('The audio channel isn\'t running at the moment ... ') return w, h = shutil.get_terminal_size() bw, bh = w // 4 * 3, h def disp_audio(screen: Screen) -> None: while True: screen.clear() b = ch.buff sw = len(b) // bw b = np.asarray( [np.average(b[i:i + sw]) for i in range(0, len(b), sw)]) for i, v in enumerate(b): screen.move((w - bw) // 2 + i, int(h // 2 - bh * v * scale)) screen.draw((w - bw) // 2 + i, h // 2, char=char, colour=1 if np.max(b) > .2 else 7) e = screen.get_key() if e in (ord('Q'), ord('q')): break screen.refresh() time.sleep(.01) Screen.wrapper(disp_audio)
def on_show_all_sounds(cmd: pcmd.Command, args: List[str], json: bool) -> None: """Callback for `show sounds all` - shows all available sounds""" spath = os.path.join(params.BPATH, 'res', 'sounds') if not os.path.isdir(spath): if not json: utils.printerr(f'Directory "{spath}" doesn\'t exist ... ') else: print( JSON.dumps( {'error': f'Directory "{spath}" doesn\'t exist ... '})) return sounds = [ s for s in os.listdir(spath) if os.path.isfile(os.path.join(spath, s)) and s.split('.')[-1] in params.ALLOWED_EXTS ] if not sounds: if not json: utils.printwrn('No sounds available ... ') else: print(JSON.dumps({'error': 'No sounds available ... '})) return if not json: print('Available sounds:\n - ', end='') print('\n - '.join(sounds)) return print(JSON.dumps({ 'sounds': sounds, }))
def on_show_all_filters(cmd: pcmd.Command, args: List[str], json: bool) -> None: """Callback for `show filters all` - shows all available voice-filters""" if not os.path.isdir(os.path.join(params.BPATH, 'lib', 'filters')): utils.printerr('Error: Directory "{}" doesn\'t exist ... '.format( os.path.join(params.BPATH, 'lib', 'filters'))) return fs = [ f[:-3] for f in os.listdir(os.path.join(params.BPATH, 'lib', 'filters')) if os.path.isfile(os.path.join(params.BPATH, 'lib', 'filters', f)) and f != 'filter.py' and f.endswith('.py') ] if not fs: if not json: utils.printwrn('No filters available ... ') else: print(JSON.dumps({ 'error': 'No filters available ... ', })) return if not json: print('Filters: \n - ', end='') print('\n - '.join(fs)) return print(JSON.dumps({ 'filters': fs, }))
def create_conf_prompt() -> None: """ Prompt the user to create a config file. """ with open(os.path.join(params.BPATH, 'lib', 'server', 'conf.json'), 'w') as f: while True: secret_len = input('Enter secret length [default 512 (bits)]: ') if not secret_len.strip(): secret_len = 512 else: try: secret_len = int(secret_len) if secret_len % 8 != 0: utils.printwrn( 'No. bits should be divisible by 8 ... ') continue except ValueError: utils.printerr('Enter a valid number!') continue break secret = secrets.token_bytes(secret_len // 8) f.write(json.dumps(dict(secret=base64.b64encode(secret).decode()))) with open(os.path.join(params.BPATH, 'lib', 'gui', '.tkn'), 'w') as o: root = User.load_root() o.write( jwt.encode({ 'uname': root.uname, }, secret, algorithm='HS256'))
def on_start_interpreter(cmd: pcmd.Command, args: List[str], fname: str) -> None: """Callback for `start interpreter` - interprets a .fig file""" try: interpreters.append(Interpreter(fname, ch, sh)) interpreters[-1].exec() except Exception as e: utils.printerr(str(e))
def create_prompt(cls) -> "User": """ Create a new user by prompting to the CLI. """ name = input('Enter new username: '******'Enter new password: '******'Confirm new password: '******'Passwords don\'t match!') return User(-1, name, User.hash(pwd))
def on_start(cmd: pcmd.Command, args: List[str]) -> None: """Callback for `start` - starts the channel""" global ch if ch.is_alive(): utils.printwrn('Already running ... ') return ch = Channel(ch.transf, ch.ist, ch.ost) try: ch.start() except IOError as e: utils.printerr(e)
def on_start_input(cmd: pcmd.Command, args: List[str], indi: int) -> None: """Callback for `start input` - adds an input device""" try: ch.add_ist( Device(pa, format=pyaudio.paFloat32, channels=1, rate=params.SMPRATE, input=True, input_device_index=indi)) except Exception as e: utils.printerr(str(e))
def on_start_sound(cmd: pcmd.Command, args: List[str], params: List[str]) -> None: """Callback for `start sound` - adds a sound effect""" for i, a in enumerate(params): if re.match(r'^[\d\.]*$', a): continue if not os.path.isfile(a): utils.printerr('File "{}" doesn\'t exist ... '.format(a)) try: if i + 1 < len(args) and re.match(r'^[\d\.]+$', args[i + 1]): ch.add_sound(Sound(a, float(args[i + 1]))) continue ch.add_sound(Sound(a)) except Exception as e: utils.printerr(str(e))
def start(): """Start the server hosting the static files""" global conf cpath = os.path.join(bpath, 'dist', 'config', 'conf.json') if not os.path.isfile(cpath): utils.printwrn( f'Config file ("{cpath}") missing ... trying to (re)compile GUI ... ' ) os.system(f'cd {bpath} && npm run build') if not os.path.isfile(cpath): utils.printerr(f'Config file "{cpath}" doesn\'t exist ... ') os._exit(1) with open(cpath, 'r') as f: conf = json.load(f) threading.Thread(target=_start).start()
def on_stop_sound(cmd: pcmd.Command, args: List[str], ind: str) -> None: """Callback for `stop sound` - removes a sound effect""" if ind.lower() in ('a', 'all'): ch.del_all_sounds() return try: ind = int(ind) except ValueError: utils.printerr('"{}" is not a valid index!'.format(ind)) return mxind = len(ch.get_sounds()) - 1 if ind > mxind: utils.printerr('Index {} is out of bounds (max: {})!'.format( ind, mxind)) return ch.del_sound(ind)
def on_stop_filter(cmd: pcmd.Command, args: List[str], ind: str) -> None: """Callback for `stop filter` - stops a running filter""" if ind.lower() in ('a', 'all'): ch.del_all_filters() return try: ind = int(ind) except ValueError: utils.printerr('"{}" is not a valid index!'.format(ind)) return filters = ch.get_filters() if ind >= len(filters): utils.printerr('Index {} is out of bounds (max: {})!'.format( ind, len(filters) - 1)) return ch.del_filter(ind)
def on_stop_interpreter(cmd: pcmd.Command, args: List[str], ind: str) -> None: """Callback for `stop interpreter` - stops a running interpreter""" global interpreters if ind.lower() in ('a', 'all'): for i in interpreters: i.kill() interpreters = [] return try: ind = int(ind) except ValueError: utils.printerr('"{}" is not a valid index!'.format(ind)) return if ind >= len(interpreters): utils.printerr('Index {} is out of bounds (max: {})!'.format( ind, len(interpreters) - 1)) return interpreters[ind].kill() del interpreters[ind]
def on_start_input(cmd: pcmd.Command, args: List[str], indi: int, json: bool) -> None: """Callback for `start input` - adds an input device""" try: ch.add_ist( Device(pa, format=pyaudio.paFloat32, channels=1, rate=params.SMPRATE, input=True, input_device_index=indi)) if json: print(JSON.dumps({})) except Exception as e: if not json: utils.printerr(str(e)) else: print(JSON.dumps({ 'error': str(e), }))
def show_key() -> None: """ Show the generated AES key in QR code format. """ if not key: utils.printerr('ERROR: Server is not running ... ') return print( f'Use this QR code to connect your devices: {base64.b64encode(key).decode()}\n' ) qr: qrcode.QRCode = qrcode.QRCode() qr.add_data(base64.b64encode(key)) qr.make() try: qr.print_ascii(invert=True) except: utils.printerr( 'Sorry, your terminal doesn\'t seem to support printing the qr code ... ' ) pass
def on_start(cmd: pcmd.Command, args: List[str], json: bool) -> None: """Callback for `start` - starts the channel""" global ch if ch.is_alive(): if not json: utils.printwrn('Already running ... ') else: print(JSON.dumps({ 'error': 'Already running ... ', })) return ch = Channel(ch.transf, ch.ist, ch.ost) server.ch = ch try: ch.start() if json: print(JSON.dumps({})) except IOError as e: if not json: utils.printerr(e) else: print(JSON.dumps({ 'error': str(e), }))
def on_start_filter(cmd: pcmd.Command, args: List[str], name: str, cargs: List[str]) -> None: """Callback for `start interpreter` - interprets a .fig file""" fs = [ f[:-3] for f in os.listdir(os.path.join(params.BPATH, 'lib', 'filters')) if os.path.isfile(os.path.join(params.BPATH, 'lib', 'filters', f)) and f != 'filter.py' and f.endswith('.py') ] if name not in fs: utils.printerr(f'Error: Unknown filter "{name}" ... ') return spec = importlib.util.spec_from_file_location( name, os.path.join(params.BPATH, 'lib', 'filters', f'{name}.py')) filt = importlib.util.module_from_spec(spec) spec.loader.exec_module(filt) try: ch.add_filter(filt.start(cargs)) except NameError as e: utils.printerr('Error: Invalid/incomplete filter definition ... ') utils.printerr(str(e)) except Exception as e: utils.printerr('Error: Filter init error ... ') utils.printerr(str(e))