diff --git a/PyDAO_9000.egg-info/PKG-INFO b/PyDAO_9000.egg-info/PKG-INFO index c08c352..1e9913e 100644 --- a/PyDAO_9000.egg-info/PKG-INFO +++ b/PyDAO_9000.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: PyDAO-9000 -Version: 1.4.1 +Version: 1.4.3 Summary: 'All-In-One File' SQL Code Generator Author-email: Randall Nagy Project-URL: Homepage, https://github.com/soft9000/PyDAO @@ -103,10 +103,5 @@ Need some practice? Then try to ... ![KP3008](https://github.com/Python3-Training/PyQuest/blob/main/CardGame/QuestProjects/KP3008-C-R-U-D-Accounting.png) - -CONTACT INFORMATION ---- -If you have suggestions or opportunities - be they for additional projects, corrections, consulting and / or just about anything else - feel free to [drop me a message on Facebook](https://www.facebook.com/randall.nagy/) - ## zSupport? If you want to support the effort, I seek no donations. Instead, simply feel free to purchase one of [my educational](https://www.udemy.com/user/randallnagy2/) or [printed](https://www.amazon.com/Randall-Nagy/e/B08ZJLH1VN?ref=sr_ntt_srch_lnk_1&qid=1660050704&sr=8-1) productions? diff --git a/PyDAO_9000.egg-info/SOURCES.txt b/PyDAO_9000.egg-info/SOURCES.txt index 0229d6a..0fa241d 100644 --- a/PyDAO_9000.egg-info/SOURCES.txt +++ b/PyDAO_9000.egg-info/SOURCES.txt @@ -27,12 +27,13 @@ SqltDAO/DaoTest01/NasdaqDAO.py SqltDAO/DaoTest01/foo.py SqltDAO/DaoTest01/tc001_driver.py SqltDAO/DaoTest01/tc001_gen.py -SqltDAO/Gui/Data2Code.py -SqltDAO/Gui/DataAI.py -SqltDAO/Gui/DataFrameOne.py -SqltDAO/Gui/DataPreferences.py -SqltDAO/Gui/StandardEntry.py -SqltDAO/Gui/TableDef.py +SqltDAO/GenGUI/Data2Code.py +SqltDAO/GenGUI/DataAI.py +SqltDAO/GenGUI/DataFrameOne.py +SqltDAO/GenGUI/DataPreferences.py +SqltDAO/GenGUI/StandardEntry.py +SqltDAO/GenGUI/TableDef.py +SqltDAO/GenTUI/TuiMain.py SqltDAO/SchemaDef/DataDetective.py SqltDAO/SchemaDef/Factory.py SqltDAO/SchemaDef/OrderDef.py diff --git a/README.md b/README.md index e7a8f89..15beb5d 100644 --- a/README.md +++ b/README.md @@ -89,10 +89,5 @@ Need some practice? Then try to ... ![KP3008](https://github.com/Python3-Training/PyQuest/blob/main/CardGame/QuestProjects/KP3008-C-R-U-D-Accounting.png) - -CONTACT INFORMATION ---- -If you have suggestions or opportunities - be they for additional projects, corrections, consulting and / or just about anything else - feel free to [drop me a message on Facebook](https://www.facebook.com/randall.nagy/) - ## zSupport? If you want to support the effort, I seek no donations. Instead, simply feel free to purchase one of [my educational](https://www.udemy.com/user/randallnagy2/) or [printed](https://www.amazon.com/Randall-Nagy/e/B08ZJLH1VN?ref=sr_ntt_srch_lnk_1&qid=1660050704&sr=8-1) productions? diff --git a/SqltDAO/Gui/Data2Code.py b/SqltDAO/GenGUI/Data2Code.py similarity index 100% rename from SqltDAO/Gui/Data2Code.py rename to SqltDAO/GenGUI/Data2Code.py diff --git a/SqltDAO/Gui/DataAI.py b/SqltDAO/GenGUI/DataAI.py similarity index 100% rename from SqltDAO/Gui/DataAI.py rename to SqltDAO/GenGUI/DataAI.py diff --git a/SqltDAO/Gui/DataFrameOne.py b/SqltDAO/GenGUI/DataFrameOne.py similarity index 100% rename from SqltDAO/Gui/DataFrameOne.py rename to SqltDAO/GenGUI/DataFrameOne.py diff --git a/SqltDAO/Gui/DataPreferences.py b/SqltDAO/GenGUI/DataPreferences.py similarity index 100% rename from SqltDAO/Gui/DataPreferences.py rename to SqltDAO/GenGUI/DataPreferences.py diff --git a/SqltDAO/Gui/StandardEntry.py b/SqltDAO/GenGUI/StandardEntry.py similarity index 100% rename from SqltDAO/Gui/StandardEntry.py rename to SqltDAO/GenGUI/StandardEntry.py diff --git a/SqltDAO/Gui/TableDef.py b/SqltDAO/GenGUI/TableDef.py similarity index 100% rename from SqltDAO/Gui/TableDef.py rename to SqltDAO/GenGUI/TableDef.py diff --git a/SqltDAO/GenTUI/TuiMain.py b/SqltDAO/GenTUI/TuiMain.py new file mode 100644 index 0000000..7050d66 --- /dev/null +++ b/SqltDAO/GenTUI/TuiMain.py @@ -0,0 +1,234 @@ +#~ /usr/bin/env python3 +import os +import os.path + +def select_one(prompt, types): + 'Prompt & return Sqlite types for PyDAO, or False.' + for ss, value in enumerate(types): + print(f'{ss+1}.) {types[ss]}') + ans = input(prompt) + if not ans: + return False + which = int(ans) + if which >= 1 and which <= len(types): + return types[which-1] + return False + + +def get_bool(prompt): + 'Prompt & return True if input starts with "Y" or "y"' + ans = input(prompt) + if ans and ans[0] in 'Yy': + return True + return False + + +def get_int(prompt): + 'Prompt & return an integer, else False. Caveat zero based.' + ans = input(prompt) + if ans: + try: + return int(ans.strip()) + except: pass + return False + + +def project_overwrite(adict, afqn): + 'Always returns a three-tuple.' + with open(afqn, 'w') as fh: + payl = str(adict) + if fh.write(payl) == len(payl): + return True, adict, afqn + return False, adict, afqn + + +def mk_projectfn(project_name): + 'Check for BASE file name in the pwd. No-name Exception = "Done"' + if not project_name: + raise Exception("Done.") + return f'./{project_name}.dict' + + +def project_exists(fqproject_name): + 'Check for BASE file name in the pwd. No-name Exception = "Done"' + if not fqproject_name: + raise Exception("Done.") + return os.path.exists(fqproject_name) + + +def create(*args, **kwargs): + 'Create a GenTUI Project.' + if get_bool("Create a NEW GenTUI Project? y/N: "): + project = {}; key=None; value=None + project_name = mk_projectfn(input("Enter project name: ")) + if project_exists(project_name): + print("Error: File exists. Use Update?") + return False, None + print("Enter Tag. Tap Enter when done ...") + while True: + key = input("Field name: ") + if key: + value = select_one( + "Select field type: ", + ['INTEGER','REAL','TEXT'] + ) + if value: + project[key] = value + if not key or not value: + if not project: + return False, None + return project_overwrite(project, project_name) + return False, None + + +def is_safe(astr)->bool: + "Caveat 'tre basic ..." + if astr: + astr = astr.strip() + if astr: + return astr[0] == '{' + return False + + +def read(*args, **kwargs): + 'Read existing GenTUI Project.' + names = [] + for fname in os.listdir('./'): + if fname.endswith('.dict'): + names.append(fname) + if not names: + return False, None + zfile = select_one("Which project #? ", names) + if not zfile: + return False, None + fname = f'./{zfile}' + with open(fname) as fh: + astr = fh.read() + if is_safe(astr): + proj = eval(astr) + if proj and isinstance(proj, dict): + return True, proj, fname # 3 param true + return False, None + + +def update(*args, **kwargs): + 'Update a GenTUI Project.' + changed = False + sel = read(args, kwargs) + if sel and sel[0]: + while True: + show_project(sel[1]) + print("1.) Add Field") + print("2.) Change Field") + which = get_int("Which #? ([enter] if done): ") + if not which: + if changed: + if get_bool("Project definition changed - save? y/N: "): + if project_overwrite(sel[1], sel[2]): + print(f"Project {sel[2]} updated.") + return sel + else: + raise Exception(f"Error: Unable to save {sel[2]}!") + return sel + if which == 1: + key = input("New field name: ") + if key: + value = select_one( + "Select field type: ", + ['INTEGER','REAL','TEXT'] + ) + if value: + sel[1][key] = value + changed = True + continue + elif which == 2: # safe coding is no accident. + key = select_one("Select field: ", list(sel[1])) + if key: + if get_bool(f"Rename {key}? y/N: "): + nkey = input(f"New name for {key}: ") + if not nkey: + if get_bool(f"Delete {key}? "): + del sel[1][key] + print(f"Removed {key}.") + if project_overwrite(sel[1], sel[2]): + print(f"Project {sel[2]} updated.") + return sel + else: + raise Exception(f"Error: Unable to save {sel[2]}!") + else: + value = sel[1][key] + del sel[1][key] + sel[1][nkey] = value + print(f"Renamed {key} to {nkey}.") + key = nkey + changed = True + if get_bool(f"Change {key} type? y/N: "): + value = select_one( + "Select field type: ", + ['INTEGER','REAL','TEXT'] + ) + if value: + sel[1][key] = value + print(f"Changed {key} type to {value}") + changed = True + return False, None + + +def delete(*args, **kwargs): + 'Delete a GenTUI Project.' + sel = read(args, kwargs) + if sel and sel[0]: + if get_bool( + f"Delete Project {sel[2]}? \There's no undo, dude! y/N: "\ + ): + os.remove(sel[2]) + if not os.path.exists(sel[2]): + print(f"Deleted {sel[2]}") + return sel + else: + print(f"Error: Unable to remove {sel[2]}.") + return False, None + + +def my_quit(*args, **kwargs): + 'Quit GenTUI.' + print('Bye!') + quit() + + +def show_project(project): + if project: + max_ = len(max(project)) + print('*' * 10) + for col in project: + print(col.ljust(max_ + 1), end= '') + print(project[col]) + print('*' * 10,end='') + print() + + +def mainloop(*args, **kwargs): + options = { + 'c':create, + 'r':read, + 'u':update, + 'd':delete, + 'q':my_quit + } + project = None + while True: + try: + show_project(project) + for op in options: + print(f'{op}.) {options[op].__doc__}') + sel = input("Which: ") + if sel in options: + resp = options[sel](args, kwargs) + if resp[0]: + project = resp[1] + except Exception as ex: + print(f'Error: {ex}') + + +if __name__ == '__main__': + mainloop() diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dist/PyDAO_9000-1.4.1-py3-none-any.whl b/dist/PyDAO_9000-1.4.3-py3-none-any.whl similarity index 80% rename from dist/PyDAO_9000-1.4.1-py3-none-any.whl rename to dist/PyDAO_9000-1.4.3-py3-none-any.whl index 4e05085..01d84b6 100644 Binary files a/dist/PyDAO_9000-1.4.1-py3-none-any.whl and b/dist/PyDAO_9000-1.4.3-py3-none-any.whl differ diff --git a/dist/pydao_9000-1.4.1.tar.gz b/dist/pydao_9000-1.4.1.tar.gz deleted file mode 100644 index 30a2ba9..0000000 Binary files a/dist/pydao_9000-1.4.1.tar.gz and /dev/null differ diff --git a/dist/pydao_9000-1.4.3.tar.gz b/dist/pydao_9000-1.4.3.tar.gz new file mode 100644 index 0000000..b6bed16 Binary files /dev/null and b/dist/pydao_9000-1.4.3.tar.gz differ diff --git a/pyproject.toml b/pyproject.toml index 22bee07..275456b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "PyDAO-9000" -version = "1.4.1" +version = "1.4.3" authors = [ { name="Randall Nagy", email="r.a.nagy@gmail.com" }, ]