CPythonist

Second 3.0: Source Code

source.py

__version__ = "3.0" """ Main function of Second 3.0. Called by second3.py or used as source file in second3.exe. """ def main(): try: import ctypes from os import system, mkdir, startfile, remove, chdir from os.path import isfile, isdir, basename, expanduser from sys import exit as exitSys from getpass import getuser from platform import system as platSys, release as platRel, version as platVer from pathlib import Path from shutil import copy2, copytree, rmtree, which as Shuwhich from datetime import datetime as dt, date as d system('') header = "\033[95m" blue = "\033[94m" cyan = "\033[96m" green = "\033[92m" yellow = "\033[93m" red = "\033[91m" reset = "\033[0m" bold = "\033[1m" underline = "\033[4m" cls = "\033[H\033[J" class helpContents: def cdHelp(): print(fr"""{bold}{green}CD:{reset} {green}CD command allows the user to change the current working directory of Second. File operations with relative paths take place from the current working directory. {bold}{cyan}Syntax:{reset} {cyan}CD ('/")('/"){reset} {yellow}Please note that when using the CD command, if you want to change to your root directory (i.e., drive, like C:\), please insert a backslash at the end (e.g., cd "C:{underline}\{reset}{yellow}") as without backslash it is interpreted as input to change the drive letter. {green}{underline}Examples:{reset} cd "myfolder" cd "E:\example\new" cd "custom\main" """) def copyHelp(): print(fr"""{bold}{green}COPY:{reset} {green}COPY command allows the user to copy a file or folder from a source location to destination location. This command can parse relative paths (from current working directory). {bold}{cyan}Syntax:{reset} {cyan}COPY ('/")('/") ('/")('/"){reset} {underline}Examples:{reset} copy "myfolder" "e:\Folder" copy "pictures\images.png" "desktop" """) def delHelp(): print(fr"""{bold}{green}DEL:{reset} {green}DEL command allows the user to remove a file/directory from a given location. This command can parse relative commands (from current working directory). {bold}{cyan}Syntax:{reset} {cyan}DEL ('/")('/"){reset} {underline}Examples:{reset} del "myfolder" del "documents\haha" del "desktop\new.exe" """) def mdirHelp(): print(fr"""{bold}{green}MDIR:{reset} {green}MDIR command allows the user to create a new directory. This command can parse relative commands (from current working directory). {bold}{cyan}Syntax:{reset} {cyan}MDIR ('/")('/"){reset} {underline}Examples:{reset} mdir "myfolder" mdir "desktop\new" """) def helpMenu(): print(f"""{bold}{underline}{green}Help:{reset} {green}\n {bold}{cyan}CD{reset} {green}Changes the current working direcory (CWD). {bold}{cyan}CLS{reset} {green}Clears the screen. {bold}{cyan}COPY{reset} {green}Copies file/directory to another directory {bold}{cyan}DATE{reset} {green}Displays today's date. {bold}{cyan}DEL{reset} {green}Delete a file/directory. {bold}{cyan}EXIT{reset} {green}Terminates Second. {bold}{cyan}MDIR{reset} {green}Creates a new directory. {bold}{cyan}PROMPT{reset} {green}Changes the prompt variable. {bold}{cyan}SECOND{reset} {green}Displays version compactibility and author. {bold}{cyan}START{reset} {green}Opens a file/directory. {bold}{cyan}TIME{reset} {green}Displays current time. {bold}{cyan}TITLE{reset} {green}Changes the title of the window.{reset} {green}(Note: all commands work in any case.) {reset}""") def secondPrint(): print(f"""{blue}Second by CPythonist, Infinite, Inc. {green}OS: {bold}Windows{reset} {green}Compatible versions: {bold}10/11{reset} {green}Administrative privileges required for some operations.{reset} """) def promptHelp(): print(fr"""{bold}{green}PROMPT:{reset} {green}PROMPT command allows the user to change the Second prompt string. {bold}{cyan}Syntax:{reset} {cyan}PROMPT ('/")('/") This command when given given without any other data, restores the original prompt of the Second. {underline}{green}Variables:{reset} {cyan}%U {green}Username of the user {cyan}%S {green}OS {cyan}%R {green}OS Release {cyan}%P {green}Current working directory (CWD) {cyan}%% {green}% symbol {underline}Examples:{reset} prompt "myPrompt" prompt ">>>" prompt "%U%P>" """) def startHelp(): print(fr"""{bold}{green}START:{reset} {green}START command allows the user to open a file/directory. This command when given given without any other data, restores the original title of the window. {bold}{cyan}Syntax:{reset} {cyan}START [('/")('/")]{reset} {underline}Examples:{reset} start "E:\new folder" start "second" """) def titleHelp(): print(fr"""{bold}{green}TITLE:{reset} {green}TITLE command allows the user to set the title of the console window in which Second is running. This command when given given without any other data, restores the original title of the window. {bold}{cyan}Syntax:{reset} {cyan}TITLE [('/")('/")]{reset} {underline}Examples:{reset} title "myTitle" title (-> Original title restored) """) ############################################################################# ############################################################################# """ Only one type of string is allowed in each of the individual commands. This function checks if the string passed to it has only one type of string. If it has two types, True and -1 is returned signifying improper quotes. If it has one type: 1 is returned if the quotes used is single quotes, or 2 is returned if the quotes used is double quotes If no quotes are present, 0 is returned. """ def detectNoOrMultipleQuotes(string): countSingle, countDouble = 0, 0 for i in string: if i == '\'': countSingle += 1 elif i == '\"': countDouble += 1 if (countSingle != 0 and countDouble != 0): return True, -1 elif (countSingle == 0 and countDouble == 0): return True, 0 else: if countSingle != 0: return False, 1 elif countDouble != 0: return False, 2 ############################################################################# ############################################################################# """ Change directory command. Changes the current working directory for file operations. Returns the parsed path and change status as a tuple -> (path, changed) """ def cd(remaining): if (temp:=detectNoOrMultipleQuotes(remaining))[0]: #temp is declared here! return ("Multiple types of quotes detected. Only one type of quote is allowed in \ each command." if temp[1] == -1 else "No quotes detected. Quotes must be used.\n"), False else: chdir(path) args = [] appendToArgs = args.append quotes = '\'' if temp[1] == 1 else '\"' remaining = [i for i in remaining.split(quotes) if not (i.isspace() or i == '')] pathPresent = False completed = False for i in remaining: if i.startswith('/'): if len(i) == 2: appendToArgs(i) else: return f"Invalid argument: '{i}'. CWD is unchanged.\n", False remaining = [i for i in remaining if i not in args] if len(args) == 1: if len(remaining) == 0: if args[0] in ("/h", "/?"): return 'cdHelp', None else: return f"Unknown argument: '{args[0]}'. CWD is unchanged.\n", False else: return "Invalid format of data given. Please check the format of the command. Type help for the help menu. CWD is unchanged.\n", False elif len(args) == 0: if len(remaining) == 1: if isdir(remaining[0]): pathTemp = str(Path(i).resolve()) chdir(pathTemp) print() return pathTemp, True else: return f"Directory not found: '{str(Path(remaining[0]).resolve())}'. CWD is unchanged.\n", False else: return f"Too many paths given. CWD is unchanged.\n", False else: return "No path was given. CWD is unchanged.\n", False ############################################################################# ############################################################################# """ Copies a file/directory to another directory, if destination directory and source file/directory exists, provided, permissions are available for read and write for source file/directory and destination folder. Returns copy message and copy status. """ def copy(remaining): if (temp:=detectNoOrMultipleQuotes(remaining))[0]: #temp is declared here! return ("Multiple types of quotes detected. Only one type of quote is allowed in \ each command.\n" if temp[1] == -1 else "No quotes detected. Quotes must be used.\n"), False else: try: args = [] appendToArgs = args.append quotes = '\'' if temp[1] == 1 else '\"' remaining = [i for i in remaining.split(quotes) if not (i.isspace() or i == '')] count = 0 source, dest = None, None sourceType = None for i in remaining: if i.startswith('/'): if len(i) == 2: appendToArgs(i) else: return f"Unknown argument: '{i}'. No file/directory was copied.\n", False elif isfile(i): if count == 0: source = i; sourceType = 'F' elif count == 1: return "Destination cannot be a file.\n" else: return "Two locations already given as input. No file was copied.\n", False count += 1 elif isdir(i): if count == 0: source = i; sourceType = 'D' elif count == 1: dest = i else: return "Two locations already given as input. No directory was copied.\n", False count += 1 else: return "File or directory not found. No file/directory was copied.\n", False for i in args: if i in ("/h", "/?"): return "copyHelp", None if (source != None) and (dest != None): source = str(Path(source).resolve()) dest = str(Path(dest).resolve()) if sourceType == 'F': try: copy2(source, dest) return "Copied successfully.\n", True except PermissionError: return f"Permissions not available for copying files from {source} to {dest}.\n", False elif sourceType == 'D': try: temp = basename(source) if not isdir(f"{dest}\\{temp}"): mkdir(f"{dest}\\{temp}") copytree(source, f"{dest}\\{temp}", dirs_exist_ok=True) return "Copied successfully.\n", True except PermissionError: return f"Required permissions not available to copy '{source}'. Process was terminated.\n", False else: if source == None: return "Source missing. No changed were made.\n", False elif dest == None: return "Destination missing. No changes were made.\n", False except: return "Unknown error while copying. Process terminated.\n", False ############################################################################# ############################################################################# """ Deletes a file/directory if it exists, provided permissions are available for deleting a file/directory in the parent directory. Returns delete message and delete status. """ def delete(remaining): if (temp:=detectNoOrMultipleQuotes(remaining))[0]: #temp is declared here! return ("Multiple types of quotes detected. Only one type of quote is allowed in \ each command." if temp[1] == -1 else "No quotes detected. Quotes must be used.\n"), False else: args = [] appendToArgs = args.append quotes = '\'' if temp[1] == 1 else '\"' remaining = [i for i in remaining.split(quotes) if not (i.isspace() or i == '')] for i in remaining: if i.startswith('/'): if len(i) == 2: appendToArgs(i) else: return f"Unknown argument: '{i}'. No file/folder was deleted.\n", False remaining = [i for i in remaining if i not in args] if len(args) == 1: if args[0] in ("/h", "/?"): return "delHelp", None else: return f"Unknown argument: '{args[0]}'.", False elif len(args) == 0: for i in remaining: if (temp1:=isfile(path + '\\' + i)) or (isfile(i)): actualPath = (path + '\\' + i) if temp1 else i try: remove(temp:=str(Path(actualPath).resolve())) return f"File '{str(Path(temp).resolve())}' deleted successfully.\n", True except PermissionError: return f"Permissions unavailable for deleting '{str(Path(actualPath).resolve())}'. Process was terminated.\n", False elif (temp1:=isdir(path + '\\' + i)) or (isdir(i)): actualPath = (path + '\\' + i) if temp1 else i try: rmtree(temp:=str(Path(actualPath).resolve())) return f"Directory '{temp}' successfully deleted.\n", True except PermissionError: return f"Permissions unavailable for deleting {str(Path(actualPath).resolve())}. Process was terminated.\n", False else: return f"File/Directory not found: '{i}'.\n", False else: return "Unknown arguments given. No directory was created.\n", False ############################################################################# ############################################################################# """ Creates a new directory if the parent directory exists, provided write permissions are available in the parent directory. Returns text message and status. """ def mdir(remaining): if (temp:=detectNoOrMultipleQuotes(remaining))[0]: #temp is declared here! return ("Multiple types of quotes detected. Only one type of quote is allowed in \ each command." if temp[1] == -1 else "No quotes detected. Quotes must be used.\n"), False else: args = [] appendToArgs = args.append quotes = '\'' if temp[1] == 1 else '\"' remaining = [i for i in remaining.split(quotes) if not (i.isspace() or i == '')] for i in remaining: if i.startswith('/'): if len(i) == 2: appendToArgs(i) else: return f"Invalid argument: '{i}'. No changes were made.\n", False remaining = [i for i in remaining if i not in args] if len(args) == 1: if args[0] in ("/h", "/?"): return "mdirHelp", None else: return f"Unknown argument: '{args[0]}'.\n", False elif len(args) == 0: for i in remaining: try: mkdir(path + '\\' + i) return "Directory successfully created.\n", True except OSError: return f"Illegal character used in a directory name: {i}", False except FileNotFoundError: return f"Second is unable to find the location: {i}", False else: return "Unknown arguments given. No directory was created.\n", False ############################################################################# ############################################################################# """ Changes the prompt of Second. When new prompt is specified, Second updates prompt variable to the new value. Returns prompt value or text message, and status. """ def promptChanger(remainingUnchanged): if (temp:=detectNoOrMultipleQuotes(remainingUnchanged))[0]: #temp is declared here! return ("Multiple types of quotes detected. Only one type of quote is allowed in \ each command." if temp[1] == -1 else "No quotes detected. Quotes must be used.\n"), False else: args = [] appendToArgs = args.append quotes = '\'' if temp[1] == 1 else '\"' remaining = [i for i in remainingUnchanged.split(quotes) if not (i.isspace() or i == '')] for i in remaining: if i.startswith('/'): if len(i) == 2: appendToArgs(i) else: return f"Unknown argument: '{i}'.\n", False remaining = [i for i in remaining if i not in args] if len(args) == 1: if args[0] in ("/h", "/?"): return "promptHelp", None else: return f"Unknown argument: '{args[0]}'.\n", False elif len(args) == 0: if len(remaining) == 1: return remaining[0], True elif len(remaining) == 0: return '', True else: return "Too many prompts given. Prompt is unchanged.\n", False else: return "Unknown arguments given. Prompt is unchanged.\n", False ############################################################################# ############################################################################# """ Starts a file/directory, or file in the PATH directories, if read permissions are available for opening the file/directory. Returns start message and start status. """ def start(remaining): if (temp:=detectNoOrMultipleQuotes(remaining))[0]: #temp is declared here! return ("Multiple types of quotes detected. Only one type of quote is allowed in \ each command." if temp[1] == -1 else "No quotes detected. Quotes must be used.\n"), False else: args = [] appendToArgs = args.append quotes = '\'' if temp[1] == 1 else '\"' remaining = [i for i in remaining.split(quotes) if not (i.isspace() or i == '')] for i in remaining: if i.startswith('/'): if len(i) == 2: appendToArgs(i) else: return f"Invalid argument: '{i}'.\n", False remaining = [i for i in remaining if i not in args] if len(args) == 1: if args[0] in ("/h", "/?"): return "startHelp", None else: return f"Unknown argument: '{i}'", False elif len(args) == 0: if len(remaining) == 1: temp1 = isfile(path + '\\' + remaining[0]) temp2 = isfile(remaining[0]) temp3 = isdir(path + '\\' + remaining[0]) if (temp1) or (temp2) or (temp3) or (isdir(remaining[0])): if temp1 or temp3: try: startfile(path + '\\' + remaining[0]) if temp1: return f"File '{str(Path(remaining[0]).resolve())}' opened successfully.\n", True return f"Directory {str(Path(remaining[0]).resolve())} opened successfully.\n", True except PermissionError: return f"Error while opening file '{i}': Access is denied.\n", False else: startfile(str(Path(remaining[0]).resolve())) if temp2: return f"File '{str(Path(remaining[0]).resolve())}' opened successfully.\n", True return f"Directory '{str(Path(remaining[0]).resolve())}' opened successfully.\n", True try: locate = Shuwhich(remaining[0]) if not (locate == None): startfile(locate) return f"File '{i}' successfully opened.\n", True return f"The file/directory was not found: '{remaining[0]}'.\n", False except PermissionError: return f"Permissions required for opening file '{remaining[0]}' was not available.\n", False else: return "More than one file/directory was given. Process was terminated.\n", False else: return f"Unknown arguments given. Process was terminated.\n", False ############################################################################# ############################################################################# """ Changes the title of Second window. Returns title message and change status. """ def title(remainingUnchanged): if (temp:=detectNoOrMultipleQuotes(remainingUnchanged))[0]: #temp is declared here! return ("Multiple types of quotes detected. Only one type of quote is allowed in \ each command." if temp[1] == -1 else "No quotes detected. Quotes must be used.\n"), False else: args = [] appendToArgs = args.append quotes = '\'' if temp[1] == 1 else '\"' remaining = [i for i in remainingUnchanged.split(quotes) if not (i.isspace() or i == '')] for i in remaining: if i.startswith('/'): if len(i) == 2: appendToArgs(i) else: return f"Invalid argument: {i}. Title is unchanged.\n", False remaining = [i for i in remaining if i not in args] if len(args) == 1: if args[0] in ("/h", "/?"): return "titleHelp", None else: return f"Unknown argument: {args[0]}. Title is unchanged.\n", False elif len(args) == 0: if len(remaining) == 1: try: ctypes.windll.kernel32.SetConsoleTitleW(remaining[0]) return "Title changed successfully.\n", True except: return f"Unable to change title to '{remaining[0]}'. Title is unchanged.\n", False elif len(remaining) == 0: return "Empty title is not allowed. Title is unchanged.\n", False else: return "Too many titles given. Title is unchanged.\n", False else: return "Unknown arguments given. No changes were made in the title.\n", False ############################################################################# ############################################################################# """ Function IO(path, prompt) manages the input/output of Second. Works: 1. Updates prompt variables. 2. Takes input. 3. Parses input string. 4. Checks if parsed command is valid. 5. Calls necessary functions/displays necessary information if command is valid. 6. Displays appropriate error messages if command is invalid. Returns path and prompt so that these can be passed to IO(path, prompt) again. """ def IO(path, prompt): promptTemp = prompt[:] if '%' in promptTemp: windowsVersion = platVer() windowsRelease = platRel() if int(windowsVersion.split('.')[0]) == 10: if int(windowsVersion.split('.')[2]) > 22000: windowsRelease = '11' else: windowsRelease = '10' promptTemp = promptTemp.replace("%P", path).replace("%U", getuser()).replace("%S", platSys()).replace("%R", windowsRelease) promptTemp = promptTemp.replace(r"%p", path).replace(r"%u", getuser()).replace(r"%s", platSys()).replace(r"%r", windowsRelease).replace(r"%%", '%') commandFull = input(promptTemp) commandFullUnchanged, commandFull = commandFull, commandFull.lower() command = commandFull remaining = '' remainingUnchanged = '' if commandFull in valid: command = commandFull else: for i in range(len(commandFull)): if commandFull[i] == ' ': command = commandFull[:i] remaining = commandFull[i+1:] remainingUnchanged = commandFullUnchanged[i+1:] break if command == valid[0]: if remaining == '' or remaining.isspace(): print(f"{red}Required data to change directory was not given. CWD is unchanged.\n{reset}") else: result = cd(remaining) if result[1] == True: path = result[0] elif result[1] == None: helpContents.cdHelp() else: print(red + result[0] + reset) elif command == valid[1]: system("cls") print() # if remaining == '' or remaining.isspace(): # system("cls") # print() # else: # print(f"{red}Unknown arguments given. No changes were made to console.\n{reset}") elif command == valid[2]: if remaining == '' or remaining.isspace(): print(f"{red}Required data for copying is not given. No file/folder was copied.\n{reset}") else: result = copy(remaining) if result[1]: print(green + result[0] + reset) elif result[1] == None: helpContents.copyHelp() else: print(red + result[0] + reset) elif command == valid[3]: if remaining == '' or remaining.isspace(): date = d.today().strftime(r"%d.%m.%Y (%d %B %Y)") print(f"{green}Date today: {date} (dd.mm.yyyy)\n{reset}") else: print(f"{red}Unknown arguments given.\n{reset}") elif command == valid[4]: if remaining == '' or remaining.isspace(): print(f"{red}Location for deletion is required. No changes were made.\n{reset}") else: result = delete(remaining) if result[1]: print(green + result[0] + reset) elif result[1] == None: helpContents.delHelp() else: print(red + result[0] + reset) elif command == valid[5]: print(f"{green}Program exited with code 0.{reset}") exitSys(0) elif command == valid[6]: if not (remaining == '' or remaining.isspace()): print(f"{red}Unknown arguments given.\n{green}\nHelp menu is still printed as \ no other argument/data is required by it in any case.\n{reset}") helpContents.helpMenu() elif command == valid[7]: if remaining == '' or remaining.isspace(): print(f"{red}Required data for making a directory was not given. No changes were made.\n{reset}") else: result = mdir(remaining) if result[1]: print(green + result[0] + reset) elif result[1] == None: helpContents.mdirHelp() else: print(red + result[0] + reset) elif command == valid[8]: if remaining == '' or remaining.isspace(): prompt = "%U@%S%R&&%P:~ $" print() else: result = promptChanger(remaining) if result[1]: prompt = result[0] print() elif result[1] == None: helpContents.promptHelp() else: print(red + result[0] + reset) elif command == valid[9]: if remaining == '' or remaining.isspace(): helpContents.secondPrint() else: print(f"{red}Unknown arguments given.\n{reset}") elif command == valid[10]: if remaining == '' or remaining.isspace(): print(f"{red}Required data for opening a file/directory was not given.\n{reset}") else: result = start(remaining) if result[1]: print(green + result[0] + reset) elif result[1] == None: helpContents.startHelp() else: print(red + result[0] + reset) elif command == valid[11]: if remaining == '' or remaining.isspace(): time = dt.now().strftime("%I:%M.%S [%f] %p (%d %B %Y)") print(f"{green}Time now: {time} (hh.mm.ss [microseconds] am/pm)\n{reset}") else: print(f"{red}Unknown arguments given.\n{reset}") elif command == valid[12]: if remaining == '' or remaining.isspace(): try: ctypes.windll.kernel32.SetConsoleTitleW("Second 3.0") print() except: print(f"{red}Unable to restore default title.\n{reset}") else: result = title(remainingUnchanged) if result[1]: print(green + result[0] + reset) elif result[1] == None: helpContents.titleHelp() else: print(red + result[0] + reset) else: if command == '': print() else: print(f"{red}Invalid command: '{bold}{command}{reset}{red}'.\n{reset}") return path, prompt ############################################################################# ctypes.windll.kernel32.SetConsoleTitleW("Second 3.0") print(f""" {cyan}Infinite Second 3.0{reset} Made by ... Developed in CPython 3.9.6, 3.10.0, 3.11.6, 3.12.0 Compiled in CPython 3.11.6 Thanks to stackoverflow.com for helping me out! Type 'help' without quotes for the help menu. """) valid = ("cd", "cls", "copy", "date", "del", "exit", "help", "mdir", "prompt", "second", "start", "time", "title") path = expanduser('~') prompt = "%U@%S%R&&%P:~ $" #prompt = f"{getuser()}@{platSys()}{platRel()}&&{path}:~ $" while True: try: path, prompt = IO(path, prompt) except KeyboardInterrupt: print() except EOFError: print(f"{green}Program exited with code 0.{reset}") exitSys(0) except Exception as excep: excepName = type(excep).__name__ print(f"Fatal error:\n{excepName}:{excep}") try: print(excepName, ': ', excep, sep='') from datetime import datetime as dt from pickle import dump with open("crashReports.dat", 'ab+') as f: f.seek(0) now = dt.now() dump(f"{now} =====> {excepName}: --> {str(excep)}", f) except FileNotFoundError: try: from datetime import datetime as dt from pickle import dump from os import makenod makenod("crashReports.dat") with open("crashReports.dat", 'ab+') as f: f.seek(0) now = dt.now() dump(f"Previous 'crashReports.dat' file not found. New file created on {now}.", f) dump(f"{now} =====> {excepName}: --> {str(excep)}", f) except: pass except: pass

second3.py

from source import main def run(): main() run()