|
| 1 | +import os |
| 2 | +import signal |
| 3 | +import subprocess |
1 | 4 | import sys
|
2 |
| -from subprocess import Popen, CREATE_NEW_CONSOLE |
| 5 | +import time |
3 | 6 |
|
| 7 | +# Some specific commands are needed for Windows vs macOS/Linux |
| 8 | +if sys.platform == "win32": |
| 9 | + from subprocess import CREATE_NEW_PROCESS_GROUP |
| 10 | + python_executable = "venv/Scripts/python" |
| 11 | +else: |
| 12 | + python_executable = "python" |
4 | 13 |
|
5 |
| -profiles = { |
6 |
| - "test": ['python -m omnibus', |
7 |
| - 'python sinks/plot/main.py', |
8 |
| - 'python sources/ni/main.py'], |
9 |
| - "texas": ['python sources/parsley/main.py $arg', |
10 |
| - 'python sources/ni/main.py', |
11 |
| - 'python -m omnibus'] |
12 |
| - # Add other profiles in here |
13 |
| - # If any commands require arguments to be passed in, write $arg in its place |
| 14 | +# Parse folders for sources and sinks |
| 15 | +modules = {"sources" : os.listdir('sources'), "sinks" : os.listdir('sinks')} |
14 | 16 |
|
15 |
| -} |
| 17 | +# Remove dot files |
| 18 | +for module in modules.keys(): |
| 19 | + for item in modules[module]: |
| 20 | + if item.startswith("."): |
| 21 | + modules[module].remove(item) |
16 | 22 |
|
| 23 | +for module in modules.keys(): |
| 24 | + print(f"{module.capitalize()}:") |
| 25 | + for i, item in enumerate(modules[module]): |
| 26 | + print(f"\t{i+1}. {item.capitalize()}") |
17 | 27 |
|
18 |
| -try: |
19 |
| - if sys.argv[1] == "_wrap": |
20 |
| - p = Popen(sys.argv[2]) |
21 |
| - if p.wait() != 0: |
22 |
| - input('Press enter to quit') |
| 28 | +# Construct CLI commands to start Omnibus |
| 29 | +source_selection = input(f"\nPlease enter your Source choice [1-{len(modules['sources'])}]: ") |
| 30 | +sink_selection = input(f"Please enter your Sink choice [1-{len(modules['sinks'])}]: ") |
| 31 | +omnibus = [python_executable, "-m", "omnibus"] |
| 32 | +source = [python_executable, f"sources/{modules['sources'][int(source_selection) - 1]}/main.py"] |
| 33 | +sink = [python_executable, f"sinks/{modules['sinks'][int(sink_selection) - 1]}/main.py"] |
| 34 | + |
| 35 | +commands = [omnibus, source, sink] |
| 36 | +processes = [] |
| 37 | +print("Launching... ", end="") |
23 | 38 |
|
| 39 | +# Execute commands as subprocesses |
| 40 | +for command in commands: |
| 41 | + if sys.platform == "win32": |
| 42 | + process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, |
| 43 | + creationflags=CREATE_NEW_PROCESS_GROUP) |
24 | 44 | else:
|
25 |
| - selection = sys.argv[1] |
26 |
| - processes = profiles[selection] |
27 |
| - args = sys.argv[2:] |
| 45 | + process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 46 | + |
| 47 | + time.sleep(0.5) |
| 48 | + processes.append(process) |
| 49 | + |
| 50 | +print("Done!") |
28 | 51 |
|
| 52 | +# Blank exception just for processes to throw |
| 53 | +class Finished(Exception): |
| 54 | + pass |
| 55 | + |
| 56 | +# If any file exits or the user presses control + c, |
| 57 | +# terminate all other files that are running |
| 58 | +try: |
| 59 | + while True: |
29 | 60 | for process in processes:
|
30 |
| - while '$arg' in process: |
31 |
| - process = process.replace('$arg', args[0], 1) |
32 |
| - args.pop(0) |
33 |
| - Popen(f'python launcher.py _wrap "{process}"', creationflags=CREATE_NEW_CONSOLE) |
34 |
| - |
35 |
| -except (KeyError, IndexError): |
36 |
| - print('Please enter a single valid profile selection (ex. python launcher.py texas)') |
37 |
| - print('Ensure that you have entered the correct amount of args required for each script in the right order') |
| 61 | + if process.poll() != None: |
| 62 | + raise Finished |
| 63 | +except (Finished, KeyboardInterrupt, Exception): |
| 64 | + for process in processes: |
| 65 | + if sys.platform == "win32": |
| 66 | + os.kill(process.pid, signal.CTRL_BREAK_EVENT) |
| 67 | + else: |
| 68 | + process.send_signal(signal.SIGINT) |
| 69 | + |
| 70 | + # Dump output and error (if exists) from every |
| 71 | + # process to the shell |
| 72 | + output, err = process.communicate() |
| 73 | + output, err = output.decode(), err.decode() |
| 74 | + print(f"\nOutput from {process.args}:") |
| 75 | + print(output) |
| 76 | + |
| 77 | + if err and "KeyboardInterrupt" not in err: |
| 78 | + print(f"\nError from {process.args}:") |
| 79 | + print(err) |
| 80 | +finally: |
| 81 | + for process in processes: |
| 82 | + if sys.platform == "win32": |
| 83 | + os.kill(process.pid, signal.CTRL_BREAK_EVENT) |
| 84 | + else: |
| 85 | + process.send_signal(signal.SIGINT) |
0 commit comments