multi1/launcher.py
2024-09-16 18:18:10 +02:00

123 lines
4.4 KiB
Python

import blessed
import subprocess
import os
import sys
import time
from contextlib import contextmanager
term = blessed.Terminal()
MENU_ITEMS = [
("Ollama", "ol1.py", "Launch Ollama-based chat application"),
("Perplexity", "p1.py", "Launch Perplexity-based chat application"),
("Groq", "g1.py", "Launch Groq-based chat application"),
("Edit .env", "edit_env", "Edit environment variables"),
("Exit", None, "Exit the launcher")
]
@contextmanager
def fullscreen():
with term.fullscreen(), term.cbreak(), term.hidden_cursor():
yield
def draw_3d_box(y, x, height, width, color):
shadow_color = term.color_rgb(50, 50, 50)
# Draw shadow
print(term.move(y+1, x+2) + shadow_color + '' * (width-1) + term.normal)
for i in range(height-1):
print(term.move(y+2+i, x+width) + shadow_color + '' + term.normal)
# Draw main box
print(term.move(y, x) + color + '' + '' * (width - 2) + '' + term.normal)
for i in range(height - 2):
print(term.move(y + i + 1, x) + color + '' + ' ' * (width - 2) + '' + term.normal)
print(term.move(y + height - 1, x) + color + '' + '' * (width - 2) + '' + term.normal)
def draw_menu(current_option):
menu_width = 50
menu_height = len(MENU_ITEMS) * 3 + 5
start_y = (term.height - menu_height) // 2
start_x = (term.width - menu_width) // 2
main_color = term.cornflower_blue
draw_3d_box(start_y, start_x, menu_height, menu_width, main_color)
title = '🚀 Launcher Menu 🚀'
print(term.move(start_y + 1, start_x + (menu_width - len(title)) // 2) + term.bold + term.yellow(title))
for i, (option, _, _) in enumerate(MENU_ITEMS):
y = start_y + i * 3 + 4
if i == current_option:
item_color = term.black_on_yellow
draw_3d_box(y-1, start_x+3, 3, menu_width-6, item_color)
print(term.move(y, start_x + 5) + item_color + term.bold(f" {option:<{menu_width - 10}} ") + term.normal)
else:
item_color = term.white_on_blue
draw_3d_box(y-1, start_x+3, 3, menu_width-6, item_color)
print(term.move(y, start_x + 5) + item_color + term.bold(f" {option:<{menu_width - 10}} ") + term.normal)
description = MENU_ITEMS[current_option][2]
print(term.move(start_y + menu_height, start_x) + term.center(term.italic(description), menu_width))
def run_script(script):
with fullscreen():
print(term.clear + term.move_y(term.height // 2) + term.bold_green(term.center(f"Running {script}...")))
time.sleep(1)
process = subprocess.Popen(["streamlit", "run", script], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
with term.cbreak():
print(term.clear)
try:
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
if term.inkey(timeout=0.1) == 'q':
process.terminate()
print(term.bold_red("\nScript terminated. Press any key to return to the launcher..."))
term.inkey()
return
except KeyboardInterrupt:
process.terminate()
print(term.bold_red("\nScript terminated. Press any key to return to the launcher..."))
term.inkey()
return
print(term.bold_green("\nScript finished. Press any key to return to the launcher..."))
term.inkey()
def edit_env():
os.system('clear')
os.system("nano .env")
def main_menu():
current_option = 0
while True:
with fullscreen():
print(term.clear)
draw_menu(current_option)
key = term.inkey()
if key.name == 'KEY_UP' and current_option > 0:
current_option -= 1
elif key.name == 'KEY_DOWN' and current_option < len(MENU_ITEMS) - 1:
current_option += 1
elif key.name == 'KEY_ENTER':
selected_option = MENU_ITEMS[current_option][1]
if selected_option is None:
return
elif selected_option == "edit_env":
edit_env()
else:
run_script(selected_option)
elif key == 'q':
return
if __name__ == "__main__":
main_menu()