diff --git a/main.py b/main.py index 25229ff..07a5d0d 100644 --- a/main.py +++ b/main.py @@ -3,12 +3,11 @@ from prompt_toolkit import prompt from prompt_toolkit.history import FileHistory from prompt_toolkit.auto_suggest import AutoSuggestFromHistory from prompt_toolkit.completion import WordCompleter, ThreadedCompleter +from inspect import getmembers, isfunction -CMDCompleter = ThreadedCompleter( - WordCompleter(['list', 'get', 'set', 'cat', 'rm', 'clear', - 'exit','write','diff','rename'], - ignore_case=True) - ) +cmds = [o[0] for o in getmembers(commands) if isfunction(o[1]) and not o[0].startswith("_")] + +CMDCompleter = ThreadedCompleter(WordCompleter(cmds, ignore_case=True)) def main(): file_path = prompt('Enter the mt.conf path: ', @@ -32,6 +31,9 @@ def main(): params = user_input.split(' ',1) if len(params) == 0: continue + elif params[0] == "help": + for x in cmds: + print("{}: {}".format(x,command_apis.helps[x])) else: try: getattr(commands, params[0])(param=params) diff --git a/module/command_apis.py b/module/command_apis.py index 72256a9..a6216dc 100644 --- a/module/command_apis.py +++ b/module/command_apis.py @@ -1,4 +1,7 @@ +from functools import wraps + def debug(func): + @wraps(func) def wrapped(*args,**kwargs): print("Args: " + str(args)) print("Kwargs: " + str(kwargs)) @@ -6,6 +9,7 @@ def debug(func): return wrapped def require_param(func): + @wraps(func) def wrapped(*args,**kwargs): if (len(kwargs["param"]) != 2): print("This command requires param in order to work.") @@ -14,6 +18,7 @@ def require_param(func): return wrapped def no_param(func): + @wraps(func) def wrapped(*args,**kwargs): if (len(kwargs["param"]) != 1): print("This command does not require any params.") @@ -30,7 +35,18 @@ class require_api_arg: def __init__(self,key): self.key = key def __call__(self,func): + @wraps(func) def wrapped(*args,**kwargs): kwargs[self.key] = (None if self.key not in api_args else api_args[self.key]) return func(*args,**kwargs) return wrapped + +helps = {} + +def help(helpstr="No helps avaliable"): + def help__tmp1(func): + helps[func.__name__] = helpstr + return func + return help__tmp1 + +helps["help"] = "Show this page" diff --git a/module/commands.py b/module/commands.py index 76589e9..7af3003 100644 --- a/module/commands.py +++ b/module/commands.py @@ -1,15 +1,18 @@ # ['list', 'get', 'set', 'cat', 'rm', 'clear', 'exit','write','diff','restore','rename'] -from prompt_toolkit import prompt -from prompt_toolkit.history import FileHistory -from prompt_toolkit.auto_suggest import AutoSuggestFromHistory -from prompt_toolkit.completion import WordCompleter -from . import mtconf, dict_diff +from prompt_toolkit import prompt as _prompt +from prompt_toolkit.history import FileHistory as _FileHistory +from prompt_toolkit.auto_suggest import AutoSuggestFromHistory as _AutoSuggestFromHistory +from prompt_toolkit.completion import WordCompleter as _WordCompleter +from . import mtconf as _mtconf +from . import dict_diff as _dict_diff from . import command_apis as api -import sys, os.path -diff_str = dict_diff.diff_str -diff_get = dict_diff.diff +import sys as _sys +import os.path as _path +_diff_str = _dict_diff.diff_str +_diff_get = _dict_diff.diff #@api.debug +@api.help("List all entries inside the mt.conf") @api.no_param @api.require_api_arg("conf") def list(conf,param): @@ -22,38 +25,46 @@ def list(conf,param): print("-- List of entries end, totally " + str(len(conf)) + " entries --") #@api.debug +@api.help("Get the value of an entry inside the mt.conf") @api.require_param @api.require_api_arg("conf") def get(conf,param): if param[1] in conf: + if param[1].startswith( '#' ): + print("WARNING: This entry is a commented entry. Use `rename {}` and type in `{}` to uncomment it.".format(param[1],param[1][1:])) print(conf[param[1]]) else: print("Entry \"{}\" does not exists.".format(param[1])) #@api.debug +@api.help("Change a entry's value or create one") @api.require_param @api.require_api_arg("conf") def set(conf,param): if param[1].__contains__(" "): print("Entry key cannot contain spaces!") else: + if param[1].startswith( '#' ): + print("WARNING: The editing entry is a commented entry. Use `rename {}` and type in `{}` to uncomment it.".format(param[1],param[1][1:])) if param[1] in conf: print("Current value of \"{}\": {}".format(param[1],str(conf[param[1]]))) else: print("Creating new entry \"{}\"".format(param[1])) - user_input = prompt('Enter the value: ', - history = FileHistory('value_history.txt'), - auto_suggest = AutoSuggestFromHistory(), + user_input = _prompt('Enter the value: ', + history = _FileHistory('value_history.txt'), + auto_suggest = _AutoSuggestFromHistory(), ) conf[param[1]] = user_input #@api.debug +@api.help("Print out the rendered mt.conf") @api.no_param @api.require_api_arg("conf") def cat(conf,param): - print(mtconf.render(conf)) + print(_mtconf.render(conf)) #@api.debug +@api.help("Delete an entry inside the mt.conf") @api.require_param @api.require_api_arg("conf") def rm(conf,param): @@ -68,6 +79,7 @@ def rm(conf,param): print("Entry does not exists!") #@api.debug +@api.help("Clear the mt.conf") @api.no_param @api.require_api_arg("conf") def clear(conf,param): @@ -79,61 +91,65 @@ def clear(conf,param): print("Cancled.") #@api.debug +@api.help("Leave mt.conf editor") @api.no_param @api.require_api_arg("orig_conf") @api.require_api_arg("file") @api.require_api_arg("conf") def exit(file,param,orig_conf,conf): - adds,dels = diff_get(orig_conf,conf) + adds,dels = _diff_get(orig_conf,conf) if len(adds) + len(dels) != 0: print("You have unsaved changes. Do you still want to continue?") - diff_str(orig_conf,conf) + _diff_str(orig_conf,conf) if input("(Yes/No) ").lower() != "yes": print("Cancled.") return file.close() print("Bye") - sys.exit() + _sys.exit() #@api.debug +@api.help("Write changes to the mt.conf file") @api.require_api_arg("orig_conf") @api.require_api_arg("file") @api.require_api_arg("conf") def write(conf,file,param,orig_conf): if not(len(param) == 2) or (param[1].lower() != "nobackup"): print("Creating backup file...") - file_dir,file_name = os.path.split(file.name) - back_dir = os.path.join(file_dir,"~" + file_name) + file_dir,file_name = _path.split(file.name) + back_dir = _path.join(file_dir,"~" + file_name) backup_file = open(back_dir,"w") - backup_file.write(mtconf.render(orig_conf)) + backup_file.write(_mtconf.render(orig_conf)) backup_file.close() print("Backup file at {}".format(back_dir)) print("Writing data into file...") - file.write(mtconf.render(conf)) + file.write(_mtconf.render(conf)) api.set_api_arg("orig_conf",conf.copy()) print("Done") #@api.debug +@api.help("Show the difference between the staged changes and the saved file") @api.no_param @api.require_api_arg("orig_conf") @api.require_api_arg("conf") def diff(param,orig_conf,conf): - adds,dels = diff_get(orig_conf,conf) + adds,dels = _diff_get(orig_conf,conf) if len(adds) + len(dels) != 0: - diff_str(orig_conf,conf) + _diff_str(orig_conf,conf) else: print("No changes.") #@api.debug +@api.help("Rename an entry") @api.require_param @api.require_api_arg("conf") def rename(conf,param): if param[1] not in conf: print("Rename failed: source not exists!") else: - user_input = prompt('Enter the new name: ', - history = FileHistory('name_history.txt'), - auto_suggest = AutoSuggestFromHistory(), + user_input = _prompt('Enter the new name: ', + history = _FileHistory('name_history.txt'), + auto_suggest = _AutoSuggestFromHistory(), ) if user_input.__contains__(" "): print("Entry key cannot contain spaces!") diff --git a/module/mtconf.py b/module/mtconf.py index 62d8723..2bb93ac 100644 --- a/module/mtconf.py +++ b/module/mtconf.py @@ -1,6 +1,6 @@ import re -re_rule = re.compile(r"^([#\w]+) *= *(.+)$",flags=(re.M)) +re_rule = re.compile(r"^(#?\w+) *= *(.+)$",flags=(re.M)) def fromfile(f): return read(f.read())