From 5d8ae314ac95304e661c651cc01c5ae0a491c75e Mon Sep 17 00:00:00 2001 From: Caleb Herpin Date: Tue, 27 Jul 2021 09:51:32 -0500 Subject: [PATCH] Removed gsetup --- Makefile | 3 +- gsetup | 5 - share/trick/pymods/trick/conftest.py | 3 +- share/trick/pymods/trick/makefile | 8 +- share/trick/pymods/trick/utils.py | 2 - trick_source/trick_gsetup/.gitignore | 12 - trick_source/trick_gsetup/README.md | 0 trick_source/trick_gsetup/help.txt | 117 -- trick_source/trick_gsetup/load.py | 59 - trick_source/trick_gsetup/main.py | 1200 ----------------- .../trick_gsetup/resources/trick_icon.gif | Bin 2693 -> 0 bytes .../trick_gsetup/resources/trick_small.gif | Bin 2393 -> 0 bytes trick_source/trick_gsetup/util.py | 6 - 13 files changed, 9 insertions(+), 1406 deletions(-) delete mode 100755 gsetup delete mode 100644 trick_source/trick_gsetup/.gitignore delete mode 100644 trick_source/trick_gsetup/README.md delete mode 100644 trick_source/trick_gsetup/help.txt delete mode 100644 trick_source/trick_gsetup/load.py delete mode 100755 trick_source/trick_gsetup/main.py delete mode 100644 trick_source/trick_gsetup/resources/trick_icon.gif delete mode 100644 trick_source/trick_gsetup/resources/trick_small.gif delete mode 100644 trick_source/trick_gsetup/util.py diff --git a/Makefile b/Makefile index bfce37b7..695e0a27 100644 --- a/Makefile +++ b/Makefile @@ -342,7 +342,7 @@ premade: # TESTING ################################################################################ # This target runs Trick's Unit-tests and simulation-tests. -test: unit_test sim_test pytest +test: unit_test sim_test @ echo "All tests completed sucessfully" .PHONY: $(UNIT_TEST_DIRS) @@ -364,6 +364,7 @@ sim_test: pytest: make -C share/trick/pymods/trick + #requirements: # @ $(MAKE) -C trick_test/requirements_docs install diff --git a/gsetup b/gsetup deleted file mode 100755 index 6995ff85..00000000 --- a/gsetup +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/python3 -import os -from trick_source.trick_gsetup.main import main - -main() diff --git a/share/trick/pymods/trick/conftest.py b/share/trick/pymods/trick/conftest.py index 6f00fbca..d18458fb 100644 --- a/share/trick/pymods/trick/conftest.py +++ b/share/trick/pymods/trick/conftest.py @@ -6,7 +6,7 @@ import subprocess import inspect sys.path.append(os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(inspect.getsourcefile(lambda:0))), '../..'))) -from trick.utils import is_web_server_started, params +from utils import is_web_server_started, params # store history of failures per test class name and per index in parametrize (if parametrize used) web_server_status = {} @@ -56,7 +56,6 @@ trick.exec_set_freeze_command(True)""") cmd = f'echo "cd {params.get_path_to_sim()} && ./S_main_Linux_9.3_x86_64.exe {os.path.join(params.get_input_folder(), params.get_test_input_file())} &" | /bin/bash' print("....................Running:", cmd) subprocess.run(cmd, shell=True) - os.system("/bin/bash") @pytest.fixture(scope="session", autouse=True) def close_sim(): diff --git a/share/trick/pymods/trick/makefile b/share/trick/pymods/trick/makefile index f4804917..ae108c41 100644 --- a/share/trick/pymods/trick/makefile +++ b/share/trick/pymods/trick/makefile @@ -1,8 +1,12 @@ -PYTHON = python3 +PYTHON = python test: venv - venv/bin/python -m pytest tests/civet_server/test_http.py tests/civet_server/test_ws.py tests/gsetup + venv/bin/python -m pytest tests/civet_server/test_http.py tests/civet_server/test_ws.py # tests/gsetup venv: $(PYTHON) -m pip install virtualenv $(PYTHON) -m virtualenv venv + venv/bin/python -m pip install -r requirements.txt + +clean: + rm -rf venv \ No newline at end of file diff --git a/share/trick/pymods/trick/utils.py b/share/trick/pymods/trick/utils.py index ea3aa778..9bbf0691 100644 --- a/share/trick/pymods/trick/utils.py +++ b/share/trick/pymods/trick/utils.py @@ -74,7 +74,5 @@ def is_web_server_started(): print(f"Checking for port output: {p.stdout}") sleep(.1) #We sleep to use less recourses if "LISTEN" in p.stdout.decode(): - print("Stdout is:", p.stdout) - os.system("/bin/bash") return True return False diff --git a/trick_source/trick_gsetup/.gitignore b/trick_source/trick_gsetup/.gitignore deleted file mode 100644 index fcc023cc..00000000 --- a/trick_source/trick_gsetup/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -*__pycache__* -.vscode/* -config.log -config.status -share/trick/makefiles/config_user.mk -*.json -!tests/config_for_test_app_with_file.json -build/* -main -main.spec -*practice* -*.cache diff --git a/trick_source/trick_gsetup/README.md b/trick_source/trick_gsetup/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/trick_source/trick_gsetup/help.txt b/trick_source/trick_gsetup/help.txt deleted file mode 100644 index 03992c95..00000000 --- a/trick_source/trick_gsetup/help.txt +++ /dev/null @@ -1,117 +0,0 @@ -`configure' configures Trick 17+ to adapt to many kinds of systems. - -Usage: ../git/trick/configure [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print `checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for `--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or `..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [/usr/local] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, `make install' will install all the files in -`/usr/local/bin', `/usr/local/lib' etc. You can specify -an installation prefix other than `/usr/local' using `--prefix', -for instance `--prefix=$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/trick] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] - -X features: - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-32bit Force Trick and sims to compile 32bit - --enable-offline Compile Trick in offline mode. Un-tar the - trick-offline directory in TRICK_HOME to use this - feature - --enable-mongoose Compile Trick with webserver capabilites. - --enable-java use java (default is yes) - --enable-er7utils use er7_utils (default is yes) - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-x use the X Window System - --with-python[=DIR] python root directory - --without-prepend-path do not prepend to path (this is default) - --with-prepend-path[=DIR] - specify a directory to prepend to PATH (default is - /usr/local/bin) - --with-swig[=DIR] path of directory containing the SWIG executable. - --with-llvm[=DIR] LLVM root directory - --with-zlib=DIR root directory path of zlib installation [defaults to - /usr/local or /usr if not found in /usr/local] - --without-zlib to disable zlib usage completely - --with-udunits[=DIR] UDUnits root directory - --with-hdf5[=DIR] HDF5 root directory - --with-dmtcp[=DIR] DMTCP root directory - --with-tpro[=DIR] TPRO root directory - --with-bc635[=DIR] BC635 root directory - --with-gsl[=DIR] GSL root directory - --with-gtest[=DIR] GTEST root directory - -Some influential environment variables: - XMKMF Path to xmkmf, Makefile generator for X Window System - CXX C++ compiler command - CXXFLAGS C++ compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CXXCPP C++ preprocessor - CC C compiler command - CFLAGS C compiler flags - JAVA_CC java compiler command - JAVA_CC_FLAGS - java compiler flags - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to the package provider. diff --git a/trick_source/trick_gsetup/load.py b/trick_source/trick_gsetup/load.py deleted file mode 100644 index 42aa254f..00000000 --- a/trick_source/trick_gsetup/load.py +++ /dev/null @@ -1,59 +0,0 @@ -from os import EX_CANTCREAT -import json -from pprint import pprint -import os - -def write_help(program): - os.system(f"{program} --help > help.txt") - -def load(): - with open("help.txt", "r") as f: - sections = {} - section = None - for line in f: - if line.endswith(":\n"): - section = line[:-1] - sections[section] = [] - elif section is not None and line != "\n": - try: - argIndex = line.index("--") #TODO: Add env var - helpIndex = line.index(" ", argIndex) - sections[section].append((line[argIndex:helpIndex], line[helpIndex:].strip())) - except: - print("Invalid line:", line) - myJson = { - "sections" : { - - } - } - for section in sections: - myJson["sections"][section] = { - "options" : {} - } - for t in sections[section]: - arg = t[0] - help = t[1] - try: - s = arg.split("=") - arg = s[0] - if "=" in arg: - continue - type = s[1] - if "DIR" in type: - type = "dir" - except: - type = "flag" - # print(arg, "=", type, ":", help) - if type in ("dir", "bool", "flag"): - if arg[-1] == "[": - arg = arg[:-1] - myJson["sections"][section]["options"][arg[2:]] = { - # "section": section, - "type": type, - "desc":help - } - else: - print("unuported type:", type) - - with open("config.json", "w") as f: - f.write(json.dumps(myJson, indent=4)) \ No newline at end of file diff --git a/trick_source/trick_gsetup/main.py b/trick_source/trick_gsetup/main.py deleted file mode 100755 index d9307d63..00000000 --- a/trick_source/trick_gsetup/main.py +++ /dev/null @@ -1,1200 +0,0 @@ -#!/usr/bin/python3 -# import PIL -from posixpath import curdir -import tkinter -# import ttkthemes - -import tkinter as tk -from tkinter import PhotoImage, StringVar, Tk, ttk -#from ttkthemes import ThemedTk -from tkinter import BooleanVar, Toplevel, Text, Menu, Canvas -from tkinter.constants import ANCHOR, NONE, SUNKEN -from tkinter.ttk import Frame, Button, Entry, Label, Checkbutton, LabelFrame, Radiobutton, Scrollbar -from tkinter import ttk -import json -from tkinter import filedialog -from tkinter.ttk import Notebook -import subprocess -from tkinter import messagebox -import logging -from tkinter.scrolledtext import ScrolledText -import traceback -import os -import argparse -import shutil -import time -import errno -import ntpath -import glob - -# from idlelib.ToolTip import * - - -#TODO: Write test case for this function -def QuoteForPOSIX(string): #Adapted from https://code.activestate.com/recipes/498202-quote-python-strings-for-safe-use-in-posix-shells/ - '''quote a string so it can be used as an argument in a posix shell - - According to: http://www.unix.org/single_unix_specification/ - 2.2.1 Escape Character (Backslash) - - A backslash that is not quoted shall preserve the literal value - of the following character, with the exception of a . - - 2.2.2 Single-Quotes - - Enclosing characters in single-quotes ( '' ) shall preserve - the literal value of each character within the single-quotes. - A single-quote cannot occur within single-quotes. - - ''' - - return "\\'".join("'" + p + "'" for p in string.split("'")) - -def get_configure_command(command, config_json, include_vars=False): - def get_with_catch(my_dict, key): - try: - return my_dict[key] - except KeyError as e: - raise RuntimeError(f"Required key {e} not found in the following json: {my_dict}") - - sep = " " - vars = "" - for section_name, section in get_with_catch(config_json, "sections").items(): - for option_name, option in get_with_catch(section, "options").items(): - if get_with_catch(option, "type") in ("bool", "flag"): - value = bool_to_string(string_to_bool(str(get_with_catch(option, "value")))) - elif get_with_catch(option, "type") in ("dir", "string"): - value = str(get_with_catch(option, "value")) - if value == "": - continue - elif get_with_catch(option, "type") == "envvar": - value = str(get_with_catch(option, "value")) - if value == "": - if option_name in os.environ: - del os.environ[option_name] - else: - os.environ[option_name] = value - if include_vars: - vars += f"{option_name} = {value}\n" - continue - elif get_with_catch(option, "type") in ("radio"): - value = str(get_with_catch(option, "value")) - else: - my_type = get_with_catch(option, "type") - raise RuntimeError(f"In function call get_configure_command: Option type '{my_type}' in {option} is not implemented yet.") - if value not in ("no"): #TODO: Check what possible values there are for false - #TODO: Should we add the no's to the comand - command += f"{sep}--{option_name}" - if option["type"] != "flag" and value not in ("EMPTY"): #TODO: Tell the developer this is a key word - value = QuoteForPOSIX(value) - command += f"={value}" - if include_vars: - command = vars + command - return command - -def string_to_bool(string): - if string.lower() in ("yes", "true"): - return True - else: - return False - -def bool_to_string(bool): - if bool: - return "yes" - else: - return "no" - -def run(program, *args, **kargs): - time = kargs.get("time", False) - new_args = [] - for key in kargs: - value = kargs[key] - new_args.append(f"--{key}={value}") - for value in args: - new_args.append(f"--{value}") - if time: - program = "time " + program - cmd = str(program + " " + " ".join(new_args)) - logging.info("Running: " + cmd) - process = subprocess.run(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True) - return process.stdout.decode() - -def textEvent(e): - logging.debug(f"state: {e.state}") - logging.debug(f"key: {e.keysym}") - if (e.state == 20 and e.keysym == "c"): #TODO: Add other exceptions like Ctrl+a - return - else: - return "break" - -def set_widget_geometry(widget, width=None, height=None): - """Set the geometry of a widget. Default to half of the screen size. If width or height is greater then the screen size will use default value for that demension""" - screen_width = widget.winfo_screenwidth() - screen_height = widget.winfo_screenheight() - if not (width and width <= screen_width): - if width: - logging.warning("Trying to set width larger than screen size. Defaulting to half of screen width") - width = screen_width/2 - if not (height and height <= screen_height): - if height: - logging.warning("Trying to set height larger than screen size. Defaulting to half of screen height") - height = screen_height/2 - widget.geometry(f"{int(width)}x{int(height)}") - -#Adapted from https://stackoverflow.com/questions/4770993/how-can-i-make-silent-exceptions-louder-in-tkinter -class Stderr(object): - def __init__(self, parent): - self.txt = Text(parent) - self.pack(self.txt, ) - def write(self, s): - self.txt.insert('insert', s) - def fileno(self): - return 2 - -class Data: - def __create_attribute_list(self): - try: - self._attrs_ - except: - dict.__setattr__(self, "_attrs_", []) #We use this list to perserve order - - def __init__(self, **kargs) -> None: - self.__create_attribute_list() - for key, value in kargs.items(): - self._attrs_.append(key) - if type(value) != dict: - setattr(self, key, value) - else: - setattr(self, key, Data(**value)) - - def _dict_(self): - d = {} - for attribute in self._attrs_: - # for attribute in dir(self): - if not attribute.startswith("_"): - var = getattr(self, attribute) - if type(var) == Data: - d[attribute] = var._dict_() - else: - d[attribute] = var - return d - - def __setattr__(self, name: str, value) -> None: - self.__create_attribute_list() - self._attrs_.append(name) - dict.__setattr__(self, name, value) - - -class Component: - def __init__(self, parent, name, source:Data, special_valid_params, special_required_params) -> None: - self.parent = parent - self.frame = Frame(parent) - self.name = name - self.source = source - - self.params = [x for x in dir(self.source) if not x.startswith("_")] - self.required_params = special_required_params - self.valid_params = special_valid_params - - for p in self.required_params: - if p not in self.params: - raise RuntimeError(f"Parameter {p} is required and not found in object '{source}.{name}'") - - for key in self.params: - if key not in self.valid_params: - raise RuntimeError(f"Parameter '{key}' in '{name}' is not a valid param. Valid params are {self.valid_params}.") - setattr(self, key, getattr(self.source, key)) - - for key in list(set(self.params).symmetric_difference(set(self.valid_params))): - setattr(self, key, "default") - self.params.append(key) - - def get_hidden(self): - try: - return string_to_bool(self.hidden) - except: - return False - - def pack(self, tk, **kargs): - if not self.get_hidden(): - tk.pack(kargs) - - def grid(self, tk, **kargs): - if not self.get_hidden(): - tk.grid(kargs) - - def get_frame(self): - return self.frame - -class Option(Component): - def __init__(self, parent, section, name, data, special_valid_params = [], special_required_params=[]) -> None: - self.source_attribute = "value" - required_params = ["type"] - valid_params = ["type", "value", "label", "desc", "hidden", "fill", "side", "expand"] - super().__init__(parent, name, getattr(getattr(getattr(getattr(data, "sections"), section), "options"), name), special_required_params=special_required_params + required_params, special_valid_params=special_valid_params + valid_params) - self.fill = "both" if self.fill == "default" else self.fill - self.side = "top" if self.side == "default" else self.side - self.expand = False if self.expand == "default" else self.expand - - @property - def value(self): - return getattr(self.source, self.source_attribute) - - @value.setter - def value(self, value): - setattr(self.source, self.source_attribute, value) - - def get_frame(self): - return self.frame - -class ToolTip(object): #Adapted from https://stackoverflow.com/questions/20399243/display-message-when-hovering-over-something-with-mouse-cursor-in-python - - def __init__(self, widget): - self.widget = widget - self.tipwindow = None - self.id = None - self.x = self.y = 0 - - def showtip(self, text): - "Display text in tooltip window" - self.text = text - if self.tipwindow or not self.text: - return - x, y, cx, cy = self.widget.bbox("insert") - x = x + self.widget.winfo_rootx() + 57 - y = y + cy + self.widget.winfo_rooty() +27 - self.tipwindow = tw = Toplevel(self.widget) - tw.wm_overrideredirect(1) - tw.wm_geometry("+%d+%d" % (x, y)) - label = Label(tw, text=self.text, justify="left", - background="#ffffe0", relief="solid", borderwidth=1, - font=("tahoma", "8", "normal")) - label.pack(ipadx=1) - - def hidetip(self): - tw = self.tipwindow - self.tipwindow = None - if tw: - tw.destroy() - -def CreateToolTip(widget, text): - toolTip = ToolTip(widget) - def enter(event): - toolTip.showtip(text) - def leave(event): - toolTip.hidetip() - widget.bind('', enter) - widget.bind('', leave) - - -class OptionDir(Option): - def __init__(self, parent, section, name, data): - super().__init__(parent, section, name, data, special_valid_params=["width"]) - # Setting defaults - self.width = 20 if self.width == "default" else self.width - self.label = self.name if self.label == "default" else self.label - self.value = "" if self.value == "default" else self.value - - #Building GUI - self.container = self.get_frame() - self.container = LabelFrame(self.get_frame(), text=f"{self.label} - {self.desc}") - self.pack(self.container, fill="both", expand=True) - # self.label_tk = Label(self.container, text=self.label) - # self.pack(self.label_tk, side="left") - self.directory_entry = Entry(self.container, width=self.width) - self.directory_entry.bind('', self.handler) - self.directory_entry.insert(0, self.value) - self.pack(self.directory_entry, side="left", fill="both", expand=True) - self.browse_button = Button(self.container, text="browse", command=self.browse_dir) - self.pack(self.browse_button, side="right") - CreateToolTip(self.browse_button, "Browse for a directory.") - # self.desc_label = Label(self.container, text = self.desc, font=("", 8)) #TODO: Make a hover-over pop up - # CreateToolTip(self.desc_label, self.desc) - # self.pack(self.desc_label, side="left") - - def handler(self, event): - logging.debug(f"Setting value to {self.directory_entry.get()}") - self.value = self.directory_entry.get() - - def browse_dir(self): - initDir=self.value - if initDir=="": - initDir=os.getcwd() - if not os.path.isdir(initDir): - messagebox.showerror("Error", f'Specified directory not found. Value was:{"(Empty)" if initDir=="" else initDir}') - initDir="" - dir = filedialog.askdirectory(initialdir=initDir) - if not dir in ("", ()): #askdirectory can return an empty tuple(Escape pressed) or an empty string(Cancel pressed) - self.directory_entry.delete(0, "end") - self.directory_entry.insert(0, dir) - self.handler(None) - -class OptionBool(Option): - def __init__(self, parent, section, name, data): - super().__init__(parent ,section, name, data) - #Setting defaults - self.value = "no" if self.value == "default" else self.value - self.label = self.name if self.label == "default" else self.label - - #Building GUI - self.bool = BooleanVar(value = self.value) - self.check_button = Checkbutton(self.get_frame(), text=self.label, command=self.handler, variable=self.bool) - self.pack(self.check_button, side="left") - self.desc_label = Label(self.get_frame(), text = f": {self.desc}") #TODO: Make a pop up - self.pack(self.desc_label, side="left") - # CreateToolTip(self.check_button, self.desc) - - def handler(self): - logging.debug(f"Setting value to {self.bool.get()}.") - self.value = "yes" if self.bool.get() else "no" - -class OptionString(OptionDir): - def __init__(self, parent, section, name, data): - super().__init__(parent, section, name, data) - - self.container["text"] = self.container["text"] - self.browse_button.pack_forget() - -class OptionEnvVar(OptionDir): - def __init__(self, parent, section, name, data): - super().__init__(parent, section, name, data) - - self.container["text"] = "ENV: " + self.container["text"] - self.browse_button.pack_forget() - - # self.value = "" if self.value == "default" else self.value - # self.label = self.name if self.label == "default" else self.label - - # self.tk_label = Label(self.get_frame(), text=self.label) - # self.pack(self.tk_label, side="left", pady=10) - - # self.directory_entry = Entry(self.get_frame()) - # self.directory_entry.bind('', self.handler) - # self.directory_entry.insert(0, self.value) - # self.pack(self.directory_entry, fill="both", expand=True, side="left") - - - # def handler(self, event): - # logging.debug(f"Setting value to {self.directory_entry.get()}") - # self.value = self.directory_entry.get() - -class OptionRadio(Option): - def __init__(self, parent, section, name: str, data: Data): - super().__init__(parent, section, name, data, special_valid_params=["options"], special_required_params=[]) - self.options = [] if self.options == "default" else self.options - self.value = "" if self.value == "default" else self.value - - self.box = LabelFrame(self.get_frame(), text=f"{self.name} - {self.desc}") - self.pack(self.box, side="left") - - self.variable = StringVar(value=self.value) - for key, obj in self.options._dict_().items(): - desc = obj.get("desc", "") - value = obj.get("value", key) - if len(desc) > 0: - desc = " - " + desc - self.pack(Radiobutton(self.box, text=f"{key}{desc}", variable = self.variable, value=value, command=lambda: self.handler()), anchor="w") - - def handler(self): - if self.variable.get() == self.value: - self.variable.set("") - logging.debug(f"Setting value to {self.variable.get()}") - self.value = self.variable.get() - - - -class Section(Component): - def __init__(self, parent, section, data:Data): #TODO: Figure out if I can pass in data instead of making it global - valid_params = ["options", "size"] #TODO: Use size or take it out of valid params - required_params = ["options"] - super().__init__(parent, section, getattr(getattr(data, "sections"), section), special_valid_params=valid_params, special_required_params=required_params) - - self.scrollable = self.get_scrollable_frame(self.get_frame()) - - self.components = {} - if type(parent) == Notebook: - parent.add(self.get_frame(), text=section) - - options = getattr(self.source, "options")._dict_() - for option in options: #TODO: Don't repeat this logic in get_configure_command - obj = getattr(getattr(self.source, "options"), option) - my_type = obj.type - if my_type == "dir": - self.components[option] = OptionDir(self.get_scrollable(), section, option, data) - elif my_type == "bool" or my_type == "flag": - self.components[option] = OptionBool(self.get_scrollable(), section, option, data) - elif my_type == "envvar": - self.components[option] = OptionEnvVar(self.get_scrollable(), section, option, data) - elif my_type == "radio": - self.components[option] = OptionRadio(self.get_scrollable(), section, option, data) - elif my_type == "string": - self.components[option] = OptionString(self.get_scrollable(), section, option, data) - else: - raise RuntimeError(f"Option type '{my_type}' in {option} is not implemented yet.") - - # self.components[option].get_frame().pack(fill="both", expand=1, side="top") - self.pack(self.components[option].get_frame(), fill = self.components[option].fill, expand = self.components[option].expand) - - def get_scrollable(self): - if self.scrollable: - return self.scrollable - else: - return self.get_frame() - - def get_frame(self): - return self.frame - - def get_required_height(self): - total = 0 - for component in self.components.values(): - total += component.get_frame().winfo_height() - return total - - def update_scrollbar(self): - if self.get_required_height() < self.main_frame.winfo_height(): - self.my_scrollbar.pack_forget() - self.scrollable = False - else: - self.my_scrollbar.pack(side="right", fill="y") - self.scrollable = True - - def get_scrollable_frame(self, parent): - self.main_frame = Frame(parent) - self.main_frame.pack(fill="both", expand=True) - - self.main_frame.bind("", lambda e: self.update_scrollbar()) - - self.my_canvas = Canvas(self.main_frame) - self.my_canvas.pack(side="left", fill="both", expand=True) - - self.my_scrollbar = ttk.Scrollbar(master=self.main_frame, orient="vertical", command=self.my_canvas.yview) - - self.my_canvas.configure(yscrollcommand=self.my_scrollbar.set) - - second_frame = Frame(self.my_canvas) - canvasFrame = self.my_canvas.create_window((0, 0), window=second_frame, anchor="nw") - - self.setIsInCanvas(False) - second_frame.bind("", lambda e: self.my_canvas.configure(scrollregion=self.my_canvas.bbox("all"))) - self.my_canvas.bind('', lambda e: self.my_canvas.itemconfig(canvasFrame, width=e.width)) - - self.my_canvas.bind('', lambda e: self.setIsInCanvas(True)) - self.my_canvas.bind('', lambda e: self.setIsInCanvas(False)) - - return second_frame - - def setIsInCanvas(self, bool): - self.isInCanvas = bool - - def _scroll(self, dir): - if self.scrollable: - if self.isInCanvas: - if self.get_frame().winfo_ismapped(): - speed = 1 - self.my_canvas.yview_scroll(dir * speed, "units") - - def scroll_up(self): - self._scroll(1) - - def scroll_down(self): - self._scroll(-1) - - -class App(Component): - def __init__(self, my_json_or_filename, program="/home/cherpin/git/trick/configure", resource_folder = f'{os.path.dirname(os.path.realpath(__file__))}/resources'): - if type(my_json_or_filename) == str: #Handle a file name - self.open(my_json_or_filename) - self.filename = my_json_or_filename - elif type(my_json_or_filename == dict): #Handle a dictionary object - self.filename = None - self.data = Data(**my_json_or_filename) - self.my_json = my_json_or_filename - else: - raise RuntimeError(f"Invalid parameter my_json_or_file: {my_json_or_filename}.") - - self._program = program - self.resource_folder = resource_folder - - self.root = tkinter.Tk() - # self.root = ThemedTk() #TODO: Figure out how to run this without pip install. - # self.root.get_themes() - # self.root.set_theme("plastik") - - set_widget_geometry(self.root) #TODO: Set geometry based on width of notebook - # self.root.geometry("+-1000+-1000") - - super().__init__(self.root, "app", self.data, special_required_params=["sections"], special_valid_params=["sections", "name", "landing"]) - - self.name = "app" if self.name == "default" else self.name - - self.root.title(self.name) - self.root.minsize(width=500, height=400) - # self.root.maxsize(width=800, height=800) - - self.root.report_callback_exception = self.report_callback_exception - - self.header = Frame(self.root) - self.header.pack(side = "top", fill="x") - self.footer = Frame(self.root) - self.footer.pack(side="bottom", fill="x") - self.options_title = "Options for script" - self.notebook_label_frame = LabelFrame(self.root, text=self.options_title) - self.notebook_label_frame.pack(expand=True, fill="both") - self.body = Frame(self.notebook_label_frame) - self.body.pack(expand=True, fill="both") - - def switch_tab(dir): - total_number_of_tabs = len(self.showing["sections"]) - if total_number_of_tabs > 0: - showing = list(self.showing["sections"]) - next_id = showing.index(self.notebook_name) + dir - if total_number_of_tabs - 1 < next_id: - next_id = list(self.sections).index(showing[0]) - elif next_id < 0: - next_id = list(self.sections).index(showing[total_number_of_tabs - 1]) - else: - next_id = list(self.sections).index(showing[next_id]) - self.notebook.select(next_id) - - navigation_frame = Frame(self.body) - navigation_frame.pack(anchor="e") - - tab_right_button = Button(navigation_frame, text="right", command=lambda: switch_tab(1)) #TODO: Make this a picture - tab_right_button.pack(side="right") - tab_left_button = Button(navigation_frame, text="left", command=lambda: switch_tab(-1)) #TODO: Make this a picture - tab_left_button.pack(side="right") - - - self.add_shortcuts() - self.build_menu(self.root) - self.build_search_bar(self.header) - self.build_current_script(self.footer) - - self.notebook_frame = Frame(self.body) - self.build_notebook(self.body) - self.build_current_command() #We can only run this after we build a notebook - - self._status = StringVar() - self.status_label = Label(self.footer, textvariable=self._status) - self.set_status() - self.status_label.pack(side="left") - - @property - def program(self): - return self._program - - @program.setter - def program(self, value): - self._program = value - self.update_status() - self.build_current_command() - - def set_status(self, msg=None): - if msg is None: - msg = f"Config file: {self.filename}" - self._status.set("Status - " + msg) - - def add_shortcuts(self): - self.root.bind(f"", lambda e: self.show_help()) - self.root.bind(f"", lambda e: self.execute()) - self.root.bind(f"", lambda e: self.focus_options()) - self.root.bind(f"", lambda e: self.focus_search()) - - def focus_options(self): - self.notebook_label_frame.focus_set() - - def focus_search(self): - self.search_entry.focus_set() - - def conf(self, e): - self.body.update() - height = self.body.winfo_height() - width = self.body.winfo_width() - self.notebook.configure(height=height, width=width) - - def build_notebook(self, parent): - self.notebook = ttk.Notebook(parent) - # self.body.bind("", self.conf) - self.notebook.pack(fill="both", expand=True) - self.sections = {} - sections = getattr(self.source, "sections")._dict_() - for section in sections: - obj = getattr(getattr(self.source, "sections"), section) - if len(getattr(obj, "options")._dict_()) > 0: #Note: not adding section if empty - self.sections[section] = Section(self.notebook, section, self.source) - CreateToolTip(self.sections[section].get_frame(), section) - - self.previous_section_length = 0 - - def call_func_on_obj(obj, func): - if obj: - getattr(obj, func)() - - self.get_frame().bind_all('', lambda e: call_func_on_obj(self.sections.get(self.notebook_name), "scroll_down")) - self.get_frame().bind_all('', lambda e: call_func_on_obj(self.sections.get(self.notebook_name), "scroll_up")) - self.call_search() - - - @property - def notebook_name(self): - if len(self.showing["sections"]) > 0: - return self.notebook.tab(self.notebook.select(), "text") - - def build_search_bar(self, parent): - #Search box - # SearchBox(self).get_frame().pack(anchor="e") - self.outer_search_box = LabelFrame(parent, text="Filter Options") - self.outer_search_box.pack(side="left", anchor="n", fill="x", expand=1) - - self.img = PhotoImage(file=f'{self.resource_folder}/trick_small.gif') - Label(self.outer_search_box, image=self.img).pack(side="right") - - self.search_box = Frame(self.outer_search_box) - self.search_box.rowconfigure(0, weight=1) - self.search_box.columnconfigure(0, weight=1) - - self.search_label = Label(self.search_box, text = "Search for options:", underline=0) - # self.search_label.grid(row=0, column=0, sticky="ew") - self.search_label.pack(expand=True, fill="x") - - self.search_entry = Entry(self.search_box) - self.search_entry.bind("", self.call_search) - CreateToolTip(self.search_entry, "Search for a specific option.") - # self.search_entry.grid(row=0, column=1, sticky="ew") - self.search_entry.pack(expand=True, fill="x") - - self.pack(self.search_box, side="top", anchor="e", expand=True, fill="x") - - self.only_checked = BooleanVar(False) - self.checked_toggle = Checkbutton(self.outer_search_box, variable=self.only_checked, text="Show only used options", command=self.call_search) - self.checked_toggle.pack(side="right", anchor="e", expand=True, fill="x") - - #End Search box - - def build_current_script(self, parent): - #Current Script - self.current_script = Frame(parent) - self.current_script.pack(side="top", anchor="n", fill="x", expand=True) - - self.label_frame = LabelFrame(self.current_script, text="Current Script with Options", underline=21) - self.label_frame.pack(side="top", expand=True, fill="x") - - # self.win = tk.Toplevel() - # self.win.title("General help for the configure script") - # self.win.geometry("800x500") - # output = run(self.program, "help") - # self.output = ScrolledText(self.win, state="normal", height=8, width=50) - # self.output.insert(1.0, output) - # self.output["state"] = "disabled" - # self.pack(self.output, fill="both", expand=True, anchor="w") - self.current_command = ScrolledText(self.label_frame, height=4, state="normal") - self.current_command.bind("", textEvent) - self.current_command.bind("", lambda e: self.setIsInCurrentCommand(True)) - self.current_command.bind("", lambda e: self.setIsInCurrentCommand(False)) - self.current_command.pack(side="top", anchor="w", fill="x", expand=True) - - self.setIsInCurrentCommand(False) - - self.root.bind("", self.build_current_command) - self.root.bind("", self.build_current_command) - - self.status_frame = Frame(self.label_frame) - self.status_frame.pack() - - status, color = self.get_status() - self.label_status = Label(self.status_frame, text=f"Status: {status}", foreground=color) - self.label_status.pack() - - self.button_frame = Frame(self.label_frame) - self.button_frame.pack() - - self.help_button = Button(self.button_frame, text=f"Help for script", command=self.show_help, underline=0) - self.help_button.pack(side="left", anchor="w", expand=True, fill="both", padx=10) - - - self.done_button = Button(self.button_frame, text="Execute command with options (will remember settings)", command=self.execute, underline=0) - CreateToolTip(self.done_button, "Execute command with options") - self.done_button.pack(side="right", anchor="e", expand=True, fill="both", padx=5) - - def setIsInCurrentCommand(self, value): - self.isInCurrentCommand = value - - def update_status(self): - self.label_status["text"], self.label_status["foreground"] = self.get_status() - - def get_status(self): - rvalue = "" - color = "black" - if os.access(self.program, os.X_OK): - rvalue += "Valid" - color = "green" - else: - rvalue += "Invalid" - color = "red" - return rvalue + " Executable File", color - - def show_help(self): #TODO: This code is being repeated where we a ScrolledText widget - self.win = tk.Toplevel() - self.win.title("General help for the configure script") - set_widget_geometry(self.win) - output = run(self.program, "help") - self.output = ScrolledText(self.win, state="normal", height=8, width=50) - self.output.bind("", textEvent) - self.output.insert(1.0, output) - self.pack(self.output, fill="both", expand=True, anchor="w") - - def build_current_command(self, e=None): - # self.current_command["state"] = "normal" - if not self.isInCurrentCommand: - text = get_configure_command(self.program, self.source._dict_(), include_vars=True) - self.current_command.delete(1.0, "end") - self.current_command.insert(1.0, text) - # self.current_command["state"] = "disabled" - # self.current_command["text"] = text - - def build_menu(self, parent): - menubar = Menu(parent) - filemenu = Menu(menubar, tearoff=0) - filemenu.add_command(label="Select command", command=self.select_command) - filemenu.add_command(label="Save options", command=self.save) - filemenu.add_separator() - filemenu.add_command(label="Exit", command=parent.destroy) #TODO: This may not work for non root parents - menubar.add_cascade(label="File", menu=filemenu, underline=0) - - parent.config(menu=menubar) - - def select_command(self): - initDir = os.path.abspath(os.path.dirname(self.program)) - file = filedialog.askopenfilename(initialdir=initDir) - if file not in ("", ()): - self.program = os.path.abspath(file) - - - def call_search(self, e=None): - current = self.search_entry.get() - self._search(current, self.sections) - msg = " (filtered)" - if current != "" or self.only_checked.get(): - self.notebook_label_frame["text"] = self.options_title + msg - else: - self.notebook_label_frame["text"] = self.options_title - - def _search(self, word, sections): - section_id = 0 - self.current_section_length = 0 - self.showing = { "sections" : {} } - for section in sections: - options = sections[section].components - count_hidden = 0 - self.showing["sections"][section] = {} - self.showing["sections"][section]["options"] = {} - for option in options: #TODO: Allow for double grouping - if (word != '' and not App.is_match(word, option, options[option].desc)) or (self.only_checked.get() and options[option].value in ("no", "")): - options[option].get_frame().pack_forget() - count_hidden += 1 - else: - options[option].get_frame().pack(fill = options[option].fill, ) - self.showing["sections"][section]["options"][option] = self.my_json["sections"][section]["options"][option] - if count_hidden == len(sections[section].components): - self.notebook.hide(section_id) - del self.showing["sections"][section] - else: - if self.previous_section_length == 0: - self.notebook.select(0) - self.notebook.add(sections[section].get_frame()) - self.current_section_length += 1 - section_id += 1 - self.previous_section_length = self.current_section_length - return self.showing - - @staticmethod - def is_match(search, *args): #Pass in args to see if search is a match with any of the arguments - rvalue = False - for a in args: - if search.lower() in a.lower(): - rvalue = True - return rvalue - - - def get_frame(self): - return self.root - - def execute(self, source=None, autoRun=False, parent=None, answer=None): - self.set_status("Running script") - if source == None: - cmd = get_configure_command(self.program, self.source._dict_()) - else: - cmd = get_configure_command(self.program, source._dict_()) - # RunCommand(self, cmd, autoRun=autoRun) - if not answer: - answer = messagebox.askyesno(title="Confirmation", message=f"Would you like to configure trick with your chosen options?") - - if answer: - output = run(cmd) - self.win = tk.Tk() - def quit(): - self.win.destroy() - self.root.destroy() - self.win.title("Script's output") - set_widget_geometry(self.win) - self.output = ScrolledText(self.win, state="normal", height=8, width=50) - self.output.bind("", textEvent) - self.output.insert(1.0, output) - self.output.pack(fill="both", expand=True, anchor="w") - self.finish_button = Button(self.win, text="Finished", command=quit) - self.finish_button.pack(anchor="e") - # self.root.destroy() #TODO: Check for a successfull output. - self.save() - # self.set_status() - self.win.mainloop() - # self.save() - else: - self.set_status() - - def save(self, filename=None): - if filename == None: - if self.filename == None: - raise RuntimeError(f"No file to save configuration to.") - else: - filename = self.filename - with open(filename, "w") as f: - f.write(json.dumps(self.source._dict_(), indent=4)) #TODO: What happens if there is an error on this line - try: - os.makedirs("archive") - except OSError as exception: - if exception.errno != errno.EEXIST: - raise - timestr = time.strftime("%Y%m%d-%H%M%S") - shutil.copyfile(filename, f"archive/{timestr}_{ntpath.basename(filename)}") - - - def open(self, filename): - with open(filename, "r") as f: - new_json = json.load(f) - self.data = Data(**new_json) - self.my_json = new_json - - #Adapted from https://stackoverflow.com/questions/4770993/how-can-i-make-silent-exceptions-louder-in-tkinter - def report_callback_exception(self, exc, val, tb): - #Handles tkinter exceptions - err_msg = { - "No file to save configuration to." : "You cannot save you current options because Gsetup was run without a configuration file." - } - err = err_msg.get(str(val), f'Unknown Error:{val}') - logging.error(traceback.format_exception(exc, val, tb)) - messagebox.showerror('Error Found', err) - - def is_saved(self): - # return DeepDiff(self.original_dict, self.data._dict_()) - return self.original_dict == self.data._dict_() - -class RunCommand: - def __init__(self, parent, command, autoRun = False) -> None: - self.win = tk.Toplevel() - # sys.stderr = Stderr(self.win) - self.parent = parent - self.command = command - self.win.title("Running command") - self.title = Text(self.win, height=3) - self.title.insert(1.0, f"Click run to run the folling command:\n{command}") - self.pack(self.title, anchor="w", expand=False, fill="x") - self.run_button = Button(self.win, text="run", command=self.run) - self.pack(self.run_button, anchor="w") - self.output = ScrolledText(self.win, state="disabled", height=8, width=50) - self.pack(self.output, fill="both", expand=True, anchor="w") - self.quit_button_and_save = Button(self.win, text="Quit and Save", command=self.quit_and_save) - self.pack(self.quit_button_and_save, anchor="w") - self.quit_button = Button(self.win, text="Quit", command=self.quit) - self.pack(self.quit_button, anchor="w") - - if autoRun: - self.run() - - self.win.bind("", lambda e: self.run()) - self.win.bind("", lambda e: self.quit()) - self.win.bind("", lambda e: self.quit()) - - def pack(self, tk, **kargs): - tk.pack(kargs) - - def grid(self, tk, **kargs): - tk.grid(kargs) - - def quit(self): - self.win.destroy() - - def quit_and_save(self): - self.parent.save() - self.win.destroy() - - def run(self): - stdout = run(self.command) - self.display(stdout) - - def display(self, msg): - self.output.configure(state="normal") - self.output.insert("end", msg) - self.output.configure(state="disabled") - self.output.yview("end") - -class SearchBox: - def __init__(self, parent:App) -> None: - self.parent = parent - - self.top = Frame(self.parent.get_frame()) - - self.search_box = LabelFrame(self.top, text="Filter Options") - self.search_box.rowconfigure(0, weight=1) - self.search_box.columnconfigure(0, weight=1) - - # self.done_button = Button(self.search_box, text="Continue", command=self.my_continue) - # CreateToolTip(self.done_button, "Continue to run and save screen.") - # self.done_button.grid(row=0,column=2, sticky="e") - - self.search_entry = Entry(self.search_box) - self.search_entry.bind("", self.parent.call_search) - CreateToolTip(self.search_entry, "Search for a specific option.") - self.search_entry.grid(row=0, column=1, sticky="e") - - self.search_label = Label(self.search_box, text = "Search for options:") - self.search_label.grid(row=0, column=0, sticky="e") - - self.search_box.pack(side="top", anchor="e", expand=False, fill="x") - - def get_frame(self): - return self.top - -class CurrentBox: - def __init__(self, parent:App) -> None: - self.parent = parent - - -class ChooseConfigure: - def __init__(self, parent=None) -> None: - if parent is None: - self.root = Tk() - else: - self.root = parent - - self.label = Label(text="Config file not found. Please click browse to find your config file or click continue to use the default.") - self.label.pack() - - self.dir = "" - self.browse_button = Button(self.root, text="Browse", command=self.browse) - self.browse_button.pack() - - self.continue_button = Button(self.root, text="Continue", command=self.continue_func) - self.continue_button.pack() - - self.file = { #This is the default configuration - "sections" : {}, - # "landing" : { "version" : 1.0} - } - - def continue_func(self): - self.root.destroy() - - def get_frame(self): - return self.root - - def browse(self): - initDir=os.getcwd() - if not os.path.isdir(initDir): - messagebox.showerror("Error", f'Specified directory not found. Value was:{"(Empty)" if initDir=="" else initDir}') - initDir="" - file = filedialog.askopenfilename(initialdir=initDir) #TODO: Fix this logic - if not dir in ("", ()): #askdirectory can return an empty tuple(Escape pressed) or an empty string(Cancel pressed) - self.file = file - self.root.destroy() - - def get_file(self): - return self.file - -def execute(parent, source, program, autoRun=False, answer=None): - cmd = get_configure_command(program, source._dict_()) - # RunCommand(self, cmd, autoRun=autoRun) - if not answer: - answer = messagebox.askyesno(title="Confirmation", message=f"Are you sure that you want to run the following command:\n{cmd}") - - if answer: - output_txt = run(cmd) - win = tk.Tk() - def quit(): - win.destroy() - if parent: - parent.destroy() - win.title("Script's output") - set_widget_geometry(win) - output = ScrolledText(win, state="normal", height=8, width=50) - output.bind("", textEvent) - output.insert(1.0, output_txt) - output.pack(fill="both", expand=True, anchor="w") - finish_button = Button(win, text="Finished", command=quit) - finish_button.pack(anchor="e") - # self.save() - win.mainloop() - -class LandingPage(Component): - def __init__(self, parent=None, config_file="./config.json", initial_dir=os.getcwd(), resource_folder = f'{os.path.dirname(os.path.realpath(__file__))}/resources') -> None: - if parent: - self.root = parent - else: - self.root = Tk() - - self.root.maxsize(width=531, height=292) #These numbers were found through trial and error - self.root.minsize(width=531, height=292) #These numbers were found through trial and error - set_widget_geometry(self.root, 531, 292) - - if type(config_file) is str: - with open(config_file, "r") as f: - app_json = json.load(f) - elif type(config_file) is dict: - app_json = config_file - else: - raise RuntimeError(f"Config_file is {type(config_file)}. It must be either a string or a dict.") - self.data = Data(**(app_json.get("landing", {}))) - - super().__init__(parent, app_json.get("name", "landing"), self.data, special_valid_params=["version", "desc"], special_required_params=[]) #Note: there should be no required params for Landing because landing itself is not required - - self.resource_folder = resource_folder - - #Set default values - self.version = "x.x" if self.version == "default" else self.version - self.desc = "This setup guide will allow you to easily see all the options that are available to configure Trick with." if self.desc == "default" else self.desc - - self.root.title(self.name) - - self.open_advanced = False - self.to_close = True - - self.header = Frame(self.root) - self.body = Frame(self.root) - self.footer = Frame(self.root) - - self.header.pack() - self.body.pack(expand=True, fill="both") - self.footer.pack() - - - self.release_label = Label(self.header, text=f"Release {self.version}") - self.release_label.pack(anchor="w") - - - self.title_frame = Frame(self.header) - self.desc_label = Label(self.title_frame, text="Welcome to Trick.", font='Helvetica 15 bold') - self.desc_label.pack(side="left") - self.img = PhotoImage(file=f'{self.resource_folder}/trick_icon.gif') - Label(self.title_frame, image=self.img).pack(side="left") - self.title_frame.pack() - - - self.desc_label2 = Label(self.header, wraplength=500, text=self.desc) - self.desc_label2.pack(pady=10) - - - self.label = Label(self.body, text="Location:") - self.label.pack(anchor="w", padx=50) - - self.folder_location = StringVar(value=initial_dir) - self.folder_entry = Entry(self.body, textvariable=self.folder_location) - self.folder_entry.pack(side="left", expand=True, fill="x", padx=50) - - self.change_button = Button(self.body, text="Change", command=self.change_dir) - CreateToolTip(self.change_button, "Click here to choose Trick's home directory. Configure will run from within this directory.") - self.change_button.pack(side="left", pady=10, padx=10) - - self.configure_fast_button = Button(self.footer, text="Configure with defaults", command=self.configure) - CreateToolTip(self.configure_fast_button, "Run configure with the default options.") - self.configure_fast_button.pack(side="left", padx=10, pady=10) - - self.configure_button = Button(self.footer, text="Configure with advanced options", command=self.configure_with_options) - CreateToolTip(self.configure_button, "Choose advanced options to configure trick with.") - self.configure_button.pack(side="left", padx=10, pady=10) - - self.close_button = Button(self.footer, text="Close", command=self.close) - self.close_button.pack(side="left", padx=10, pady=10) - - def change_dir(self): - dir = filedialog.askdirectory(initialdir=self.folder_location.get()) - if not dir in ("", ()): - self.folder_location.set(dir) - else: - logging.error("Invalid directory.") - - def set_program(self): - currdir = os.path.abspath(os.getcwd()) - try: - os.chdir(self.folder_location.get()) - except: - messagebox.showerror(title="Invalid directory", message=f"{self.folder_location.get()} is not a valid directory") - return False - arr = glob.glob("configure") - if len(arr) > 0: - self.program = os.path.abspath(arr[0]) - return True - else: - os.chdir(curdir) - messagebox.showerror(title="Wrong home directory", message=f"No configure file found in location: {self.folder_location.get()}. Please enter your trick home directory.") - return False - - def configure(self): - if self.set_program(): - self.open_advanced = False - self.to_close = False - self.close() - - def close(self): - self.root.destroy() - - def configure_with_options(self): - if self.set_program(): - self.open_advanced = True - self.to_close = False - self.close() - def get_frame(self): - return self.root - - -def main(): - logging.getLogger().setLevel(logging.DEBUG) - parser = argparse.ArgumentParser() - enable_load = False - - default = "(default: %(default)s)" - parser.add_argument("-s", "--script-file", default="./configure", help=f"script to add args to {default}") - parser.add_argument("-c", "--config", default=f"{os.path.dirname(os.path.realpath(__file__))}/sample_config.json", help=f"json file with gui options and settings {default}") - parser.add_argument("-b", "--build", action="store_true", default=False, help=f"guess the parameter choices from the scripts help output {default}") - args = parser.parse_args() - - resource_folder = f'{os.path.dirname(os.path.realpath(__file__))}/resources' - - if args.build: - if enable_load: - from load import load, write_help - write_help(args.script_file) - load() - else: - logging.warning(f"Build functionality is not enabled. Not loading {args.script_file}.") - - config_file = args.config - if not os.path.isfile(config_file): - c = ChooseConfigure() - c.get_frame().mainloop() - config_file = c.get_file() - if type(config_file) is str: - config_file = os.path.abspath(config_file) #Landing page will change cwd so we get abs path - if os.path.exists(args.script_file): - script_folder = os.path.dirname(os.path.abspath(args.script_file)) - else: - script_folder = os.getcwd() - l = LandingPage(parent=None, config_file=config_file, initial_dir=script_folder, resource_folder=resource_folder) - l.get_frame().mainloop() - if not l.to_close: - if l.open_advanced: - a = App(config_file, l.program, resource_folder=resource_folder) - a.get_frame().mainloop() - else: - execute(None, Data(sections=Data()), l.program, autoRun=True, answer=True) - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/trick_source/trick_gsetup/resources/trick_icon.gif b/trick_source/trick_gsetup/resources/trick_icon.gif deleted file mode 100644 index 60a2df285c05db14f27bc6cf97c3fb41bcde1ab2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2693 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 diff --git a/trick_source/trick_gsetup/resources/trick_small.gif b/trick_source/trick_gsetup/resources/trick_small.gif deleted file mode 100644 index 2cca2b4ba0a92aa4d427779c2ea1b5862c6d8038..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2393 zcmV-f38wZ(Nk%w1VO;}2C1pxpB z2?_%N00#;L2Lc5M1PulR2MGlO3JnDd4hakh5eo?o4-5EG;Q0Dl924Dk&^2D=jZ9GA=DEGcPVO zG%zwRH8C(UG%++bG&DFmI5s*qI5jspHaR;uJvlf#Jvu%-KRrG?K0rM>LOwr0K0HA~ zKtex6KtDr4L_1tf{B4 ztFf%At*@-LudcANuClPSue7$cv$wOgvbVIkwYRjowX?Olytulzxx2W&xwpE!xxKr; zzP!M^zPrA`y~Mx0zQe`A!@tJF$jZdS#mB_Q$;Qpc#>vab%FM~l%g@Qq(9F)u%+b`( z(azP+&ePG=(bLe^(a_M<*wxe5)78@1)6&(~)Y;eD*V)$9+T7jP*4o_J*xumW-`n8b z;^W=i-r?Qi;N;-q-{s)m-Q(rr=;i0>=I!U^ z=<4U{?CI(5@a*pE@$BmB@bmHW@b~fX_4oAm`u6?z_WSt#_WS<%`}q3&`TPC)|NHv+ z{{Q^{`~Uy{A^8LW3IP8AEC2ui09^nc000R70RIUbNU)&6g9sBUT*$DY!-o(fN}Nd1 zV7P41q(RFD5!R%SlQ>qScpn#x%O%*L&XZEZ*#_kIm1TSKytz&vB4t63mZquy8Rn-faw6F z0?&z3v?$V|SDF)QyJgMZy?M13jv8V^#nk~_Z2H zlh7zW*uV=u{j}%~GA1G!Jz!cfYVdDd8z~e~_R*eNg z3Np}O+#CPI(&GR{Q1g!=9|Taq0V+(A5I1&MumA*f&~pzz?p#xfH3@Z*0}DY8009j? zURAc7{VT+G5&kyhk9Ff7|Z0|l(ng$NP^FaQdr zCWMEG0Z@QOL2*DEfDNb=v`PsT2B5<$PI%b>1XLb`4G~`AcEt+|cq#2W!+3#j0T=Wk z={$RQSpWnx#35FY1@xhi7uOXaL3jgw1ID@tG!TbDhG1YL6s6qYUjZR#g3vCW8U?{s z6+)0lIm-}HaE%2JF^fI;Op`&4Nw9(s5*2>g01?n21WpkM%mqTg12F@{02N9=i$QQe z05utwlwe~EmL7yj{sv_i00Ip{S~bZ&o76~F%>hWDia+|?a|QxowB}DH7c@Xt;*1Q9 zf_+3RL(nc7)>r~L1#xr5vNawON(f^)n$5dVbC%-REPiswa7A{ycMWykUG^O z?FTVI%yqyAkkA7N1Z8V*h9#T8AqzdT@WC0{fscLU10RqWLL|DuB5fGsAdBddf0R&- zf4CwP|CmFCL{tWY*rH2D*+4b25x<|s06hcQ#y^xn1QD$(U~ULf1GHd{Xbj;1B`8$m z-VuvA#9#sbDey%-_CXJM!~qXOv`0Vc5sQONq5}A$fDBOZfjWc(3G#B;BMcGj-iN>jeM|0?7suxF@n(S%Djhz*hiv zFc6IeDGBoE#w6^akA3*V9`=~WA#_%N4hX{+T3A;DFp-ab@Pi)WU@5 z$1tFEfFSg$AWXQ`1NblyTOa{{))Eo~;_wYOK&t>^7zibx*cl0wf=}^C-X7y&4rBPh zT2TJ5!2_W6glymg7q(D_Gg3p4WSC(GIpBd8Cb5oxtO5!UMM54LN|1DTfeBDJ!WD2q zkZTws2{Rx;2uLskCuNH%t{3RJ{G7}^lXIllVhA2(pf2DC4=< LU5E-R5)c48E-wF9 diff --git a/trick_source/trick_gsetup/util.py b/trick_source/trick_gsetup/util.py deleted file mode 100644 index 740c05d9..00000000 --- a/trick_source/trick_gsetup/util.py +++ /dev/null @@ -1,6 +0,0 @@ -import subprocess - -def run(program): - print("Running:", program) - process = subprocess.run(program.split(" "), capture_output=True) - return process \ No newline at end of file