From 2a34f855aa78c8cb1b06c79108706691521c2678 Mon Sep 17 00:00:00 2001 From: lwark Date: Thu, 25 Jul 2024 14:42:18 -0500 Subject: [PATCH] Increased flexibility and privacy. --- README.md | 15 ++- alembic_default.ini | 2 +- requirements.txt | Bin 5808 -> 5798 bytes .../frontend/widgets/submission_table.py | 2 +- src/submissions/tools.py | 99 +++++++++++++++--- submissions.spec | 73 +++++++++++++ 6 files changed, 172 insertions(+), 19 deletions(-) create mode 100644 submissions.spec diff --git a/README.md b/README.md index 3677b0d..c32d940 100644 --- a/README.md +++ b/README.md @@ -113,13 +113,26 @@ This is meant to import .xslx files created from the Design & Analysis Software ## SETUP: ## Download: +*Python v3.11 or greater must be installed on your system for this.* 1. Clone or download from github. 2. Enter the downloaded folder. +3. Open a terminal in the folder with the 'src' folder. +4. Create a new virtual environment: ```python -m venv venv``` +5. Activate the virtual environment: (Windows) ```venv\Scripts\activate.bat``` +6. Install dependencies: ```pip install -r requirements.txt``` ## Database: 1. Copy 'alembic_default.ini' to 'alembic.ini' in the same folder. 2. Open 'alembic.ini' and edit 'sqlalchemy.url' to the desired path of the database. 1. The path by default is sqlite based. Postgresql support is available. - 2. Postgres path \ No newline at end of file +3. Open a terminal in the folder with the 'src' folder. +4. Run database migration: ```alembic upgrade head``` + +## First Run: + +1. On first run, the application copies src/config.yml to C:\Users\{USERNAME}\Local\submissions\config +2. Initially, the 'directory_path' variable is set to the 'sqlalchemy.url' variable in alembic.ini +3. If this folder cannot be found, C:\Users\{USERNAME}\Documents\submissions will be used. + 1. If using Postgres, the 'database_path' and other variables will have to be updated manually. \ No newline at end of file diff --git a/alembic_default.ini b/alembic_default.ini index 8446f8e..54b313b 100644 --- a/alembic_default.ini +++ b/alembic_default.ini @@ -55,7 +55,7 @@ version_path_separator = os # Use os.pathsep. Default configuration used for ne # are written from script.py.mako # output_encoding = utf-8 -sqlalchemy.url = sqlite:///L:\Robotics Laboratory Support\Submissions\submissions.db +sqlalchemy.url = sqlite:///{{PUT DATABASE PATH HERE!!}} [post_write_hooks] # post_write_hooks defines scripts or Python functions that are run diff --git a/requirements.txt b/requirements.txt index bcdafd968c5d5ded5e4dc4abb889154ff353cdc6..c28e8be546d83d12024f35d5bd2f1fd8b70dcead 100644 GIT binary patch delta 78 zcmdm>yG(b(0(QX^hJ1!{hCBvaAT(ysV=&u1nZ1xnx|pGoAsHxDz>v;h1eP=cN?L;O Z=D(cw?3=v=gP1n&5?;l)xk*%y5di2T69WJM delta 92 zcmZ3cyFquu0`|@O*i)D`yKq^s^V%}lG8i%FF&KdG=4!!UCdp!kGKO@99EMDWB%q`% jgCS7L6o?HspA=rtC|tmh!jQ;N!jKA Path: + c = ConfigParser() + c.read(alembic_path) + path = c['alembic']['sqlalchemy.url'].replace("sqlite:///", "") + return Path(path).parent + + def save(self, settings_path:Path): + if not settings_path.exists(): + dicto = {} + for k,v in self.__dict__.items(): + if k in ['package', 'database_session']: + continue + match v: + case Path(): + print("Path") + if v.is_dir(): + print("dir") + v = v.absolute().__str__() + elif v.is_file(): + print("file") + v = v.parent.absolute().__str__() + case _: + pass + print(f"Key: {k}, Value: {v}") + dicto[k] = v + with open(settings_path, 'w') as f: + yaml.dump(dicto, f) + # return settings + def get_config(settings_path: Path | str | None = None) -> Settings: """ @@ -400,12 +460,17 @@ def get_config(settings_path: Path | str | None = None) -> Settings: if check_if_app(): settings_path = Path(sys._MEIPASS).joinpath("files", "config.yml") else: - settings_path = package_dir.joinpath('src', 'config.yml') + settings_path = project_path.joinpath('src', 'config.yml') with open(settings_path, "r") as dset: default_settings = yaml.load(dset, Loader=yaml.Loader) + # NOTE: Tell program we need to copy the config.yml to the user directory # NOTE: copy settings to config directory - return Settings(**copy_settings(settings_path=CONFIGDIR.joinpath("config.yml"), settings=default_settings)) + # settings = Settings(**copy_settings(settings_path=CONFIGDIR.joinpath("config.yml"), settings=default_settings)) + settings = Settings(**default_settings) + settings.save(settings_path=CONFIGDIR.joinpath("config.yml")) + print(f"Default settings: {pprint.pprint(settings.__dict__)}") + return settings else: # NOTE: check if user defined path is directory if settings_path.is_dir(): @@ -417,7 +482,9 @@ def get_config(settings_path: Path | str | None = None) -> Settings: logger.error("No config.yml file found. Writing to directory.") with open(settings_path, "r") as dset: default_settings = yaml.load(dset, Loader=yaml.Loader) - return Settings(**copy_settings(settings_path=settings_path, settings=default_settings)) + # return Settings(**copy_settings(settings_path=settings_path, settings=default_settings)) + settings = Settings(**default_settings) + settings.save(settings_path=settings_path) # logger.debug(f"Using {settings_path} for config file.") with open(settings_path, "r") as stream: settings = yaml.load(stream, Loader=yaml.Loader) diff --git a/submissions.spec b/submissions.spec new file mode 100644 index 0000000..033725a --- /dev/null +++ b/submissions.spec @@ -0,0 +1,73 @@ +# -*- mode: python ; coding: utf-8 -*- + +block_cipher = None + +#### custom for automation of documentation building #### +import sys, subprocess +from pathlib import Path +sys.path.append(Path(".").parent.joinpath('src').absolute().__str__()) +from submissions import __version__, __project__, bcolors, project_path + +doc_path = project_path.joinpath("docs").absolute() +build_path = project_path.joinpath(".venv", "Scripts", "sphinx-build").absolute().__str__() +print(bcolors.BOLD + "Running Sphinx subprocess to generate rst files..." + bcolors.ENDC) +api_path = project_path.joinpath(".venv", "Scripts", "sphinx-apidoc").absolute().__str__() +subprocess.run([api_path, "-o", doc_path.joinpath("source").__str__(), project_path.joinpath("src", "submissions").__str__(), "-f"]) +print(bcolors.BOLD + "Running Sphinx subprocess to generate html docs..." + bcolors.ENDC) +subprocess.run([build_path, doc_path.joinpath("source").__str__(), doc_path.joinpath("build").__str__(), "-a"]) +######################################################### + +a = Analysis( + ['src\\submissions\\__main__.py'], + pathex=[project_path.absolute().__str__()], + binaries=[], + datas=[ + ("src\\config.yml", "files"), + ("src\\submissions\\templates\\*", "files\\templates"), + ("src\\submissions\\templates\\css\\*", "files\\templates\\css"), + ("docs\\build", "files\\docs"), + ("src\\submissions\\resources\\*", "files\\resources"), + ("alembic.ini", "files"), + ], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=["*.xlsx"], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False, +) +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + +exe = EXE( + pyz, + a.scripts, + [], + exclude_binaries=True, + name=f"{__project__}_{__version__}", + debug=True, + bootloader_ignore_signals=False, + strip=False, + upx=True, + # Change these for non-beta versions + #console=False, + #disable_windowed_traceback=True, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) +coll = COLLECT( + exe, + a.binaries, + a.zipfiles, + a.datas, + strip=False, + upx=True, + upx_exclude=[], + name=f"{__project__}_{__version__}", +)