From 3e1d88c08048a01d0af7f3a5c6a6032ba58aec1d Mon Sep 17 00:00:00 2001 From: D1j1t <69123673+D1j1t0@users.noreply.github.com> Date: Thu, 4 May 2023 22:24:53 +0100 Subject: [PATCH] Updated to version 2 Version 2.0 aims simply to be a more polished version 1.0 --- boot.py | 130 ++++++++++++--------- options.py | 4 +- prompt.py | 202 ++++++++++++++++++++++----------- scripts/themetool/themetool.py | 14 ++- theme.py | 8 +- themes/Aperture/theme.py | 10 +- themes/GeOS/theme.py | 8 +- themes/L3V14TH4N/theme.py | 8 +- themes/OmniShell/theme.py | 8 +- themes/Turtleshell/theme.py | 21 +++- themes/YoSH/theme.py | 20 ++++ 11 files changed, 295 insertions(+), 138 deletions(-) create mode 100644 themes/YoSH/theme.py diff --git a/boot.py b/boot.py index 97f4331..4a08f3a 100644 --- a/boot.py +++ b/boot.py @@ -1,55 +1,75 @@ -#this runs your .omnirc file -exec(open('.omnirc.py').read()) - -#This section imports the dependent libraries -import sys -import subprocess -import os -import theme -import options -from rich.console import Console -from rich.prompt import Prompt as prompt -import shutil -from importlib import reload -from pathlib import Path -import time - -#defines the login sequence -def login(): - f = open("password.txt", "r") - lgin = (f.read()) - usr = input("Please enter your Username: ") - usr = (usr + "\n") - pss = input("Now enter your Password: ") - usrpss = (usr + pss) - if lgin == usrpss: - print("Correct!") - else: - print("Incorrect, try again!") - login() - -#This section shows the splash logo -logo = theme.logo -if options.dologo == True: - Console().print(logo) - -#This section checks if the setup has already been completed -stpcmplt = (os.path.isfile("./password.txt")) - -#This section does the main setup -if stpcmplt == (bool(False)): - usrnm = input("Please assign a Username: ") - psswrd = input("Please assign a Password: ") - usrnm = (usrnm + "\n") - lgn = (usrnm + psswrd) - print("Writing Password...") - f = open("password.txt", "w") - f.write(lgn) - f.close() - print("Setup complete") - exec(open('prompt.py').read()) -else: - #calls the login sequence - if options.dologin == True: - login() - exec(open('prompt.py').read()) +#!/usr/bin/env python3 + +import os + +#Changes Current directory to the OmniShell +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +#Creates .omnirc.py if it doesn't exist +if os.path.isfile("./.omnirc.py") == False: + f = open(".omnirc.py", "w") + f.close() + +#This runs your .omnirc file +exec(open('.omnirc.py').read()) + +#This section imports the dependent libraries +import sys +import subprocess +import os +import options +from rich.console import Console +from rich.prompt import Prompt as prompt +import shutil +from importlib import reload +from pathlib import Path +import time +from prompt_toolkit import prompt +from prompt_toolkit import PromptSession +from prompt_toolkit.history import FileHistory +from prompt_toolkit.completion import NestedCompleter +from prompt_toolkit.auto_suggest import AutoSuggestFromHistory +from prompt_toolkit.validation import Validator +from prompt_toolkit.styles import Style +import theme + +#Defines the login sequence +def login(): + f = open("password.txt", "r") + lgin = (f.read()) + usr = input("Please enter your Username: ") + usr = (usr + "\n") + pss = input("Now enter your Password: ") + usrpss = (usr + pss) + if str(lgin) == str(usrpss): + print("Correct!") + else: + print("Incorrect, try again!") + login() + +#This section shows the splash logo +logo = theme.logo +if options.dologo == True: + Console().print(logo) + +#This section checks if the setup has already been completed +stpcmplt = (os.path.isfile("./password.txt")) + +#This section does the main setup +if stpcmplt == False and options.dologin == True: + usrnm = input("Please assign a Username: ") + psswrd = input("Please assign a Password: ") + usrnm = (usrnm + "\n") + lgn = (usrnm + psswrd) + print("Writing Password...") + f = open("password.txt", "w") + f.write(lgn) + f.close() + print("Setup complete") +else: + #Calls the login sequence + if options.dologin == True: + login() + +#Runs the prompt file +exec(open('prompt.py').read()) diff --git a/options.py b/options.py index fc24f38..153fa4d 100644 --- a/options.py +++ b/options.py @@ -1,5 +1,5 @@ #This file is made as an easy way for addons and other scripts to add user configurable variables/options -dologin = False #this feature is just a proof of concept at the moment and provides basically no extra security +dologin = False #This feature is just a proof of concept at the moment and provides basically no extra security dologo = True -unixmode = False \ No newline at end of file +unixmode = False diff --git a/prompt.py b/prompt.py index 40ad103..910d8c3 100644 --- a/prompt.py +++ b/prompt.py @@ -1,65 +1,139 @@ -#loads theme and asks for input -cmdno = Console().input(theme.prompt) -reload(theme) -prompt = (theme.prompt) - -#exits omnishell -if cmdno.lower() == ("exit"): - print("Bye, Bye") - -#show current directory -elif cmdno == ("cdir"): - dir_path = os.path.dirname(os.path.realpath(__file__)) - print(dir_path) - exec(open('prompt.py').read()) - -#does nothing, just prints new prompt -elif cmdno == (""): - exec(open('prompt.py').read()) - -#runs different files and scripts -else: - #checks which file types exist in ./scripts/ - filechkpy = (os.path.isfile("./scripts/" + cmdno + "/" + cmdno + ".py")) - filechkbat = (os.path.isfile("./scripts/" + cmdno + "/" + cmdno + ".bat")) - filechkexe = (os.path.isfile("./scripts/" + cmdno + "/" + cmdno + ".exe")) - filechklnk = (os.path.isfile("./scripts/" + cmdno + "/" + cmdno + ".lnk")) - - #prioritises python files - if filechkpy == (bool(True)): - cmd = (cmdno + ".py") - Console().print(prompt + "executing: " + cmd) - exec(open("./scripts/" + cmdno + "/" + cmd).read()) - exec(open('prompt.py').read()) - - #then .bat files - elif filechkbat == (bool(True)) and options.unixmode == (bool(False)): - cmd = (cmdno + ".bat") - dir_path = os.path.dirname(os.path.realpath(__file__)) - bat_path = os.path.join(dir_path, "scripts", cmdno, cmd) - Console().print(prompt + "executing: " + cmd) - subprocess.call([bat_path]) - exec(open('prompt.py').read()) - - #next .exe files - elif filechkexe == (bool(True)) and options.unixmode == (bool(False)): - cmd = (cmdno + ".exe") - dir_path = os.path.dirname(os.path.realpath(__file__)) - exe_path = os.path.join(dir_path, "scripts", cmdno, cmd) - Console().print(prompt + "executing: " + cmd) - subprocess.call(exe_path) - exec(open('prompt.py').read()) - - #last .lnk files (shortcuts) - elif filechklnk == (bool(True)) and options.unixmode == (bool(False)): - cmd = (cmdno + ".lnk") - dir_path = os.path.dirname(os.path.realpath(__file__)) - lnk_path = os.path.join(dir_path, "scripts", cmdno, cmd) - Console().print(prompt + "executing: " + cmd) - os.startfile(lnk_path) - exec(open('prompt.py').read()) - - #if no file exists, it will then try and run it as a shell command +#Define the prompt function +def main(cmdno, theme, os): + try: + #Loads theme + reload(theme) + prompt = (theme.prompt) + + #Exits omnishell + if cmdno.lower() == ("exit"): + print("Bye, Bye") + exit() + + #Show current directory + elif cmdno == ("cdir"): + dir_path = os.path.dirname(os.path.realpath(__file__)) + print(dir_path) + + #Does nothing, just prints new prompt + elif cmdno == (""): + #Don't worry this isn't meant to do anything + 0 == 0 + + #Runs different files and scripts + else: + #Checks which file types exist in ./scripts/ + filechkpy = (os.path.isfile("./scripts/" + cmdno + "/" + cmdno + ".py" )) + altchkpy = (os.path.isfile("./scripts/" + cmdno + "/main.py" )) + filechkbat = (os.path.isfile("./scripts/" + cmdno + "/" + cmdno + ".bat")) + filechkexe = (os.path.isfile("./scripts/" + cmdno + "/" + cmdno + ".exe")) + filechklnk = (os.path.isfile("./scripts/" + cmdno + "/" + cmdno + ".lnk")) + + #Gets the number of matching files + filematches = 0 + if filechkpy == True: + filematches = filematches + 1 + if altchkpy == True: + filematches = filematches + 1 + if filechkbat == True: + filematches = filematches + 1 + if filechkexe == True: + filematches = filematches + 1 + if filechklnk == True: + filematches = filematches + 1 + + #Sets file conflict mode + if filematches > 1: + print("Looks like there is a file conflict") + print(os.listdir("./scripts/" + cmdno + "/")) + conflict = input("choose a file: ") + else: + conflict = False + + #Runs python files + if filechkpy == (bool(True)) or altchkpy == (bool(True)) or conflict == (cmdno + ".py") or conflict == "main.py" : + cmd = (cmdno + ".py") + if altchkpy == (bool(True)) and conflict != (cmdno + ".py"): + cmd = ("main.py") + exec(open("./scripts/" + cmdno + "/" + cmd).read()) + + #Runs .bat files + elif filechkbat == (bool(True)) or conflict == (cmdno + ".bat") and options.unixmode == (bool(False)): + cmd = (cmdno + ".bat") + dir_path = os.path.dirname(os.path.realpath(__file__)) + bat_path = os.path.join(dir_path, "scripts", cmdno, cmd) + subprocess.call([bat_path]) + + #Runs .exe files + elif filechkexe == (bool(True)) or conflict == (cmdno + ".exe") and options.unixmode == (bool(False)): + cmd = (cmdno + ".exe") + dir_path = os.path.dirname(os.path.realpath(__file__)) + exe_path = os.path.join(dir_path, "scripts", cmdno, cmd) + subprocess.call(exe_path) + + #Runs .lnk files (shortcuts) + elif filechklnk == (bool(True)) or conflict == (cmdno + ".lnk") and options.unixmode == (bool(False)): + cmd = (cmdno + ".lnk") + dir_path = os.path.dirname(os.path.realpath(__file__)) + lnk_path = os.path.join(dir_path, "scripts", cmdno, cmd) + os.startfile(lnk_path) + + #If input begins with "p! " run as python code + if cmdno[0:3] == ("p! "): + exec(cmdno[3:]) + + #If input begins with "b! " run as bash + elif cmdno[0:3] == ("b! "): + os.system("/bin/bash -c " + cmdno[3:]) + + #If input begins with "z! " run as zsh + elif cmdno[0:3] == ("z! "): + os.system("/bin/zsh -c " + cmdno[3:]) + + #If input begins with "f! " run as fish + elif cmdno[0:3] == ("f! "): + os.system("/bin/fish -c " + cmdno[3:]) + + #If no file exists, it will then try and run it as a shell command + else: + os.system(cmdno) + + #If there is an error it prints it + except Exception as errmess: + print("Error", errmess) + +#Sets the autocomplete list to include: $PATH, native commands, and scripts +completionlist = [] +path = os.environ['PATH'] +path = path.split(':') +for i in range(len(path)): + completionlist = completionlist + os.listdir(path[i]) +completionlist = completionlist + os.listdir("./scripts/") + ['exit', 'cdir', 'p!', 'b!', 'z!', 'f!'] +#Turns the list into a dictionary so that the completetion only happens on the first word, to reduce lag +completiondict = {item: None for item in completionlist} +completer = NestedCompleter.from_nested_dict(completiondict) + +#Defines the rules for what counts as a valid command +def valcmd(text): + #Spaces are valid + if not text or text.isspace(): + return True + + #If the first word is on the completion list then it is valid else: - os.system(cmdno) - exec(open('prompt.py').read()) + text = text.split(maxsplit=1) + return text[0] in completionlist + +#Sets the error for if a command is not valid +cmdvalidator = Validator.from_callable( + valcmd, + error_message="Invalid Command", + move_cursor_to_end=True, +) + +#Sets the history file +session = PromptSession(history=FileHistory("./.omnihistory")) + +#The prompt +while True: + main(session.prompt(theme.prompt, style=theme.style, validator=cmdvalidator, validate_while_typing=True, completer=completer, auto_suggest=AutoSuggestFromHistory()), theme, os) diff --git a/scripts/themetool/themetool.py b/scripts/themetool/themetool.py index ba036b0..191c6ce 100644 --- a/scripts/themetool/themetool.py +++ b/scripts/themetool/themetool.py @@ -1,21 +1,21 @@ -#prints all installed themes and asks you to select one +#Prints all installed themes and asks you to select one print("\nPick a theme", os.listdir("./themes/")) selecttheme = input("Type the name of a theme: ") themechk = os.path.isdir("./themes/" + selecttheme + "/") themepath = ("./themes/" + selecttheme) -#if the theme you selected is valid it imports it +#If the theme you selected is valid it imports it if themechk == True: sys.path.insert(0, themepath) import theme sys.modules.pop('theme') import theme - #if the theme has an info variable it will print it + #If the theme has an info variable it will print it if hasattr(theme, 'info'): Console().print(theme.info) - #it then checks if the theme has a logo and prompt + #It then checks if the theme has a logo and prompt print("Features:") if hasattr(theme, 'logo'): print(u'\u2714' + " Custom Logo") @@ -26,7 +26,7 @@ else: print(u'\u2717' + " Custom Prompt") - #then it asks if you would like to install the theme and if yes then it will install it + #Then it asks if you would like to install the theme and if yes then it will install it switch = input("\nDo you want to switch to this theme? y/n: ") if switch.lower() == ("y"): if hasattr(theme, 'logo') and hasattr(theme, 'prompt'): @@ -34,11 +34,13 @@ oldtheme = os.path.join(path, 'theme.py') applytheme = os.path.join(path, 'themes', selecttheme, 'theme.py') shutil.copyfile(applytheme, oldtheme) + exit() else: print("\nError: Missing variables in theme file") else: sys.path.insert(0, "./") reload(theme) -#if theme doesn't exist it will exit + exit() +#If theme doesn't exist it will exit elif themechk == False: print("Theme does not exist") diff --git a/theme.py b/theme.py index 1c808c8..f7876a8 100644 --- a/theme.py +++ b/theme.py @@ -1,3 +1,5 @@ +from prompt_toolkit.styles import Style + info = """########### #Omnishell# ########### @@ -12,6 +14,10 @@ / /_/ / / / / /| // / ___/ / __ / /___/ /___/ /___ \____/_/ /_/_/ |_/___//____/_/ /_/_____/_____/_____/""" -prompt = """[yellow] +style = Style.from_dict({ + '': 'ansiyellow' +}) + +prompt = """ /OMNISHELL \_""" diff --git a/themes/Aperture/theme.py b/themes/Aperture/theme.py index d475ff5..bfb024b 100644 --- a/themes/Aperture/theme.py +++ b/themes/Aperture/theme.py @@ -1,3 +1,5 @@ +from prompt_toolkit.styles import Style + info = """########## #Aperture# ########## @@ -27,5 +29,9 @@ ,:+$+-,/H#MMMMMMM@- -, =++%%%%+/:-.""" -prompt = """[blue] -\\""" \ No newline at end of file +style = Style.from_dict({ + '': 'ansiblue' +}) + +prompt = """ +\\""" diff --git a/themes/GeOS/theme.py b/themes/GeOS/theme.py index e0677c4..5030f26 100644 --- a/themes/GeOS/theme.py +++ b/themes/GeOS/theme.py @@ -1,3 +1,5 @@ +from prompt_toolkit.styles import Style + info = """###### #GeOS# ###### @@ -18,4 +20,8 @@ \ \::/ \ \:\ \ \::/ \ \::/ \__\/ \__\/ \__\/ \__\/""" -prompt = """[yellow][GeOS}-{""" +style = Style.from_dict({ + '': 'ansiyellow' +}) + +prompt = """[GeOS}-{""" diff --git a/themes/L3V14TH4N/theme.py b/themes/L3V14TH4N/theme.py index 3f9bf9e..3d4ceac 100644 --- a/themes/L3V14TH4N/theme.py +++ b/themes/L3V14TH4N/theme.py @@ -1,3 +1,5 @@ +from prompt_toolkit.styles import Style + info = """########### #L3V14TH4N# ########### @@ -12,6 +14,10 @@ / / ! !___! __/\ V /! ! (_! ! !_! ! ! ! (_! ! ! ! ! /_/ !____/\___! \_/ !_!\__,_!\__!_! !_!\__,_!_! !_!""" -prompt = """[red] +style = Style.from_dict({ + '': 'ansired' +}) + +prompt = """ /L3V14TH4N \_""" diff --git a/themes/OmniShell/theme.py b/themes/OmniShell/theme.py index 1c808c8..f7876a8 100644 --- a/themes/OmniShell/theme.py +++ b/themes/OmniShell/theme.py @@ -1,3 +1,5 @@ +from prompt_toolkit.styles import Style + info = """########### #Omnishell# ########### @@ -12,6 +14,10 @@ / /_/ / / / / /| // / ___/ / __ / /___/ /___/ /___ \____/_/ /_/_/ |_/___//____/_/ /_/_____/_____/_____/""" -prompt = """[yellow] +style = Style.from_dict({ + '': 'ansiyellow' +}) + +prompt = """ /OMNISHELL \_""" diff --git a/themes/Turtleshell/theme.py b/themes/Turtleshell/theme.py index fc88b58..53584a7 100644 --- a/themes/Turtleshell/theme.py +++ b/themes/Turtleshell/theme.py @@ -1,23 +1,34 @@ +from prompt_toolkit.styles import Style from datetime import datetime now = datetime.now() usrname = ("put your username here") -logo = (u'\ue73c') +logo = ('') info = """[blink][red] ____[yellow]_ [green] [blue] _ [purple] _ [red] [yellow] _ [green] [blue] _[purple] _ |[red]_ _[yellow]| _[green] _ __[blue]| |_|[purple] | __[red]_ __[yellow]_| |_[green]_ _[blue]__| |[purple] | [red]| || [yellow]| | |[green] '__|[blue] __| [purple]|/ _ [red]\/ __[yellow]| '_ [green]\ / _[blue] \ | [purple]| |[red] || |[yellow]_| | [green]| | [blue]|_| |[purple] __/[red]\__ \ [yellow]| | [green]| __[blue]/ | |[purple] - |_[red]| \__[yellow],_|_|[green] \_[blue]_|_|\_[purple]__||[red]___/_[yellow]| |_|[green]\___|[blue]_|_| + |_[red]| \__[yellow],_|_|[green] \_[blue]_|_|\_[purple]__||[red]___/_[yellow]| |_|[green]\___|[blue]_|_| [/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/blink] - Showing off the [b]power[/b] of [yellow]Omni[/yellow]-[blue]Shell[/blue] - + Author: D1j1t""" -prompt = ('\n' + u'[green]\ue0b6' + u'\u2588[/green]' + "[black on green]" + logo + "[/black on green]" + u'[green]\u2588[/green]' + u'[green on yellow]\ue0b0[/green on yellow]' + u'[yellow]\u2588[/yellow]' + "[black on yellow]" + usrname + "[/black on yellow]" + u'[yellow]\u2588[/yellow]' + u'[yellow on blue]\ue0b0[/yellow on blue]' + u'[blue]\u2588' + '[black on blue]' + now.strftime('%H:%M:%S') + '[/black on blue]' + u'\u2588' + u'\ue0b0[/blue]' + " ") +style = Style.from_dict({ + 'front': 'ansigreen', + 'first': 'bg:ansigreen fg:ansiblack', + 'transition1': 'bg:ansiyellow fg:ansigreen', + 'second': 'bg:ansiyellow fg:ansiblack', + 'transition2': 'bg:ansiblue fg:ansiyellow', + 'third': 'bg:ansiblue fg:ansiblack', + 'end': 'ansiblue', +}) + +prompt = [('class:front', '\n'), ('class:first', ' ' + logo + ' '), ('class:transition1', ''), ('class:second', ' ' + usrname + ' '), ('class:transition2', ''), ('class:third', ' ' + now.strftime('%H:%M:%S') + ' '), ('class:end', ' ')] logo = """[blink][red] ____[yellow]_ [green] [blue] _ [purple] _ [red] [yellow] _ [green] [blue] _[purple] _ |[red]_ _[yellow]| _[green] _ __[blue]| |_|[purple] | __[red]_ __[yellow]_| |_[green]_ _[blue]__| |[purple] | [red]| || [yellow]| | |[green] '__|[blue] __| [purple]|/ _ [red]\/ __[yellow]| '_ [green]\ / _[blue] \ | [purple]| |[red] || |[yellow]_| | [green]| | [blue]|_| |[purple] __/[red]\__ \ [yellow]| | [green]| __[blue]/ | |[purple] - |_[red]| \__[yellow],_|_|[green] \_[blue]_|_|\_[purple]__||[red]___/_[yellow]| |_|[green]\___|[blue]_|_| + |_[red]| \__[yellow],_|_|[green] \_[blue]_|_|\_[purple]__||[red]___/_[yellow]| |_|[green]\___|[blue]_|_| [/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/purple][/red][/yellow][/green][/blue][/blink]""" diff --git a/themes/YoSH/theme.py b/themes/YoSH/theme.py new file mode 100644 index 0000000..446b61a --- /dev/null +++ b/themes/YoSH/theme.py @@ -0,0 +1,20 @@ +from prompt_toolkit.styles import Style + +logo=("""[red italic] + `'';; + ;; + ;;;;;;; + ;; + ;; + ;; + ;; + ,;''';;';, + ';,,;' '',, +[/red italic]""") + +style = Style.from_dict({ + 'main': 'bg:ansired fg:ansiblack', + 'end': 'bg:ansibrightred fg:ansired', +}) + +prompt=[('class:main', ' よ'), ('class:end', '▌')]