From 428e47859cfd1893b259880a1fc070d829eb00a4 Mon Sep 17 00:00:00 2001 From: lwark Date: Fri, 26 Jul 2024 08:17:03 -0500 Subject: [PATCH] Increased flexibility and folder obscuring. --- CHANGELOG.md | 1 + src/config.yml | 6 +++ .../backend/db/models/submissions.py | 5 ++- src/submissions/frontend/widgets/functions.py | 16 +++++--- src/submissions/tools.py | 37 +++++++++++++------ 5 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 src/config.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f08b07..2ebe48a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 202407.04 - Added support for postgresql databases (auto backup not functional). +- Improved portability and folder obscuring. ## 202407.02 diff --git a/src/config.yml b/src/config.yml new file mode 100644 index 0000000..a94b251 --- /dev/null +++ b/src/config.yml @@ -0,0 +1,6 @@ +directory_path: null +database_path: null +database_schema: sqlite +database_user: null +database_password: null +database_name: null \ No newline at end of file diff --git a/src/submissions/backend/db/models/submissions.py b/src/submissions/backend/db/models/submissions.py index 9c01e4e..a1227b7 100644 --- a/src/submissions/backend/db/models/submissions.py +++ b/src/submissions/backend/db/models/submissions.py @@ -472,7 +472,10 @@ class BasicSubmission(BaseClass): except: logger.warning(f"Couldn't drop '{item}' column from submissionsheet df.") if chronologic: - df.sort_values(by="id", axis=0, inplace=True, ascending=False) + try: + df.sort_values(by="id", axis=0, inplace=True, ascending=False) + except KeyError: + logger.error("No column named 'id'") # NOTE: Human friendly column labels df.columns = [item.replace("_", " ").title() for item in df.columns] return df diff --git a/src/submissions/frontend/widgets/functions.py b/src/submissions/frontend/widgets/functions.py index bfdb1d5..b985bca 100644 --- a/src/submissions/frontend/widgets/functions.py +++ b/src/submissions/frontend/widgets/functions.py @@ -9,7 +9,7 @@ from PyQt6.QtWidgets import QMainWindow, QFileDialog logger = logging.getLogger(f"submissions.{__name__}") -def select_open_file(obj:QMainWindow, file_extension:str) -> Path: +def select_open_file(obj: QMainWindow, file_extension: str | None = None) -> Path: """ File dialog to select a file to read from @@ -19,19 +19,23 @@ def select_open_file(obj:QMainWindow, file_extension:str) -> Path: Returns: Path: Path of file to be opened - """ + """ try: home_dir = obj.last_dir.resolve().__str__() except FileNotFoundError: home_dir = Path.home().resolve().__str__() except AttributeError: home_dir = obj.app.last_dir.resolve().__str__() - fname = Path(QFileDialog.getOpenFileName(obj, 'Open file', home_dir, filter = f"{file_extension}(*.{file_extension})")[0]) + if file_extension is None: + fname = Path(QFileDialog.getExistingDirectory(obj, "Open Folder", home_dir)) + else: + fname = Path( + QFileDialog.getOpenFileName(obj, 'Open file', home_dir, filter=f"{file_extension}(*.{file_extension})")[0]) obj.last_dir = fname.parent return fname -def select_save_file(obj:QMainWindow, default_name:str, extension:str) -> Path: +def select_save_file(obj: QMainWindow, default_name: str, extension: str) -> Path: """ File dialog to select a file to write to @@ -42,13 +46,13 @@ def select_save_file(obj:QMainWindow, default_name:str, extension:str) -> Path: Returns: Path: Path of file to be opened - """ + """ try: home_dir = obj.last_dir.joinpath(default_name).resolve().__str__() except FileNotFoundError: home_dir = Path.home().joinpath(default_name).resolve().__str__() except AttributeError: home_dir = obj.app.last_dir.joinpath(default_name).resolve().__str__() - fname = Path(QFileDialog.getSaveFileName(obj, "Save File", home_dir, filter = f"{extension}(*.{extension})")[0]) + fname = Path(QFileDialog.getSaveFileName(obj, "Save File", home_dir, filter=f"{extension}(*.{extension})")[0]) obj.last_dir = fname.parent return fname diff --git a/src/submissions/tools.py b/src/submissions/tools.py index c83a3ae..8b577b5 100644 --- a/src/submissions/tools.py +++ b/src/submissions/tools.py @@ -25,6 +25,8 @@ from openpyxl.worksheet.worksheet import Worksheet from PyQt6.QtPrintSupport import QPrinter from __init__ import project_path from configparser import ConfigParser +from tkinter import Tk # from tkinter import Tk for Python 3.x +from tkinter.filedialog import askdirectory logger = logging.getLogger(f"submissions.{__name__}") @@ -261,14 +263,14 @@ class Settings(BaseSettings, extra="allow"): @classmethod def ensure_directory_exists(cls, value): if value is None: - print("No value for dir path") + # print("No value for dir path") if check_if_app(): alembic_path = Path(sys._MEIPASS).joinpath("files", "alembic.ini") else: alembic_path = project_path.joinpath("alembic.ini") - print(f"Getting alembic path: {alembic_path}") - value = cls.get_alembic_db_path(alembic_path=alembic_path) - print(f"Using {value}") + # print(f"Getting alembic path: {alembic_path}") + value = cls.get_alembic_db_path(alembic_path=alembic_path).parent + # print(f"Using {value}") if isinstance(value, str): value = Path(value) try: @@ -276,11 +278,12 @@ class Settings(BaseSettings, extra="allow"): except AttributeError: check = False if not check: - print(f"No directory found, using Documents/submissions") - value = Path.home().joinpath("Documents", "submissions") - value.mkdir() - # metadata.directory_path = value - print(f"Final return of directory_path: {value}") + # print(f"No directory found, using Documents/submissions") + # value = Path.home().joinpath("Documents", "submissions") + Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing + value = Path(askdirectory(title="Select directory for DB storage")) # show an "Open" dialog box and return the path to the selected file + value.mkdir(exist_ok=True) + # print(f"Final return of directory_path: {value}") return value @field_validator('database_path', mode="before") @@ -357,6 +360,18 @@ class Settings(BaseSettings, extra="allow"): if value is None: return package + @field_validator('database_name', mode='before') + @classmethod + def get_database_name(cls, value, values): + if value is None: + if check_if_app(): + alembic_path = Path(sys._MEIPASS).joinpath("files", "alembic.ini") + else: + alembic_path = project_path.joinpath("alembic.ini") + # print(f"Getting alembic path: {alembic_path}") + value = cls.get_alembic_db_path(alembic_path=alembic_path).stem + return value + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -389,13 +404,13 @@ class Settings(BaseSettings, extra="allow"): c = ConfigParser() c.read(alembic_path) path = c['alembic']['sqlalchemy.url'].replace("sqlite:///", "") - return Path(path).parent + return Path(path) 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']: + if k in ['package', 'database_session', 'submission_types']: continue match v: case Path():