From 71281848a3b0e95754f9c148a1ef5dafdc023aed Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Thu, 11 Oct 2018 00:23:30 +0200 Subject: test_task: pre-fill prompts with existing data Also some cleanups. --- kpov_judge/test_task.py | 88 +++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 50 deletions(-) diff --git a/kpov_judge/test_task.py b/kpov_judge/test_task.py index 63df973..cbc564c 100755 --- a/kpov_judge/test_task.py +++ b/kpov_judge/test_task.py @@ -20,35 +20,32 @@ locale.setlocale(locale.LC_ALL, ['C', 'utf8']) readline.set_completer_delims(readline.get_completer_delims().replace('/', '')) readline.parse_and_bind('tab: complete') -# SERVER_URL = "http://localhost/kpov_judge/" -#SERVER_URL = "http://kpov.fri.uni-lj.si/kpov_judge/" -#TASK_URL = SERVER_URL + '{task_id}/task.py' - TASK_URL = "file://" + os.getcwd() + '/tasks' PARAMS_FILE = os.path.expanduser("~/.kpov_params.yaml") DEFAULT_LANGUAGE = 'si' -"""get the parameters for a task either from the user -or from a file.""" -def get_params(params, meta, param_name_list=None, language=None): - if param_name_list is None: - param_name_list = list(meta.keys()) +# get the parameters for a task either from the user or from a file +def get_params(params, meta, language=None): + # prefill input() prompt with given text + def rlinput(prompt, prefill=''): + readline.set_startup_hook(lambda: readline.insert_text(prefill)) + try: + return input(prompt) + finally: + readline.set_startup_hook() + + param_name_list = list(meta.keys()) if language is None: language = params.get('language', DEFAULT_LANGUAGE) + for name in param_name_list: - if name not in meta: - pass m = meta.get(name, {}) + description = m.get('descriptions', {}).get(language, name) try: - description = m['descriptions'][language] - except KeyError: - description = name - init = params.get(name) or '' - try: - if name == 'password': + if m.get('masked', False): s = getpass.getpass('{}: '.format(description)) else: - s = input('{} [{}]: '.format(description, init)) + s = rlinput('{}: '.format(description), params.get(name, '')) if s and m.get('w', True): params[name] = s elif name not in params: @@ -57,22 +54,22 @@ def get_params(params, meta, param_name_list=None, language=None): print() return params -def add_meta_to_argparser(argparser, meta, defaults = {}): +def add_meta_to_argparser(argparser, meta, defaults={}): language = defaults.get('language', DEFAULT_LANGUAGE) for k, v in meta.items(): try: desc = v['descriptions'][language].encode("utf-8") except: desc = k - argparser.add_argument('--'+k, nargs='?', help=desc, type=str, default=defaults.get(k, None)) + argparser.add_argument('--'+k, nargs='?', type=str, help=desc, + default=defaults.get(k, None)) def http_auth(url, username, password): password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() password_mgr.add_password(None, url, username, password) handler = urllib.request.HTTPBasicAuthHandler(password_mgr) opener = urllib.request.build_opener(handler) - # Install the opener. Now all calls to urllib2.urlopen use our opener. - urllib.request.install_opener(opener) + urllib.request.install_opener(opener) # now all calls to urlopen use our opener def load_task(stream): # the stream should definitions for the functions task(…), @@ -89,7 +86,7 @@ def locate_task(params, argparser, quiet=False): } if 'task_url' not in params: params['task_url'] = TASK_URL - add_meta_to_argparser(argparser, meta = url_meta, defaults = params) + add_meta_to_argparser(argparser, meta=url_meta, defaults=params) args, unknown_args = argparser.parse_known_args() params['task_url'] = args.task_url if not quiet: @@ -98,12 +95,11 @@ def locate_task(params, argparser, quiet=False): fetch_params_meta = collections.OrderedDict({ 'username': {'descriptions': {'si': 'Uporabniško ime', 'en': 'Username'}}, }) - if params['task_url'] is not None and ( - params['task_url'].startswith('http')): - fetch_params_meta['password'] = {'descriptions': {'si': 'Geslo', 'en': 'Password'}, } + if params.get('task_url', '').startswith('http'): + fetch_params_meta['password'] = {'descriptions': {'si': 'Geslo', 'en': 'Password'}, 'masked': True} # and finally, the name of the task fetch_params_meta['task_name'] = {'descriptions': {'si': 'Ime naloge', 'en': 'Task name'}, } - add_meta_to_argparser(argparser, meta = fetch_params_meta, defaults = params) + add_meta_to_argparser(argparser, meta=fetch_params_meta, defaults=params) args, unknown_args = argparser.parse_known_args() # update params with the now known args for k, v in fetch_params_meta.items(): @@ -114,8 +110,7 @@ def locate_task(params, argparser, quiet=False): def load_params(filename): try: - with open(filename) as f: - return yaml.load(f) + return yaml.load(open(filename)) except: return {} @@ -150,29 +145,22 @@ if __name__ == '__main__': task_name = params['task_name'] if task_url.startswith('http'): http_auth(task_url, params['username'], params['password']) - print() print("Fetching {task_url}/{task_name}/task.py…".format(**params)) source = urllib.request.urlopen("{task_url}/{task_name}/task.py".format(**params)) task, task_check, task_params_meta, gen_params = load_task(source) except Exception as e: - import traceback - traceback.print_exc() + print(str(e)) print() for k, v in params.items(): - if k != 'password': + if k not in ('password', 'task_params'): print('{}: {}'.format(k, v)) - print() - if basic_args.help: - argparser.print_help() - else: - argparser.print_usage() with open(basic_args.params_file, 'w') as f: yaml.dump(params, f) exit(1) # get task parameters - params['task_params'] = params.get('task_params', dict()) - params['task_params'][params['task_name']] = params['task_params'].get(params['task_name'], dict()) + params['task_params'] = params.get('task_params', {}) + params['task_params'][params['task_name']] = params['task_params'].get(params['task_name'], {}) task_params = params['task_params'][params['task_name']] if basic_args.generate_params: #prejema lahko samo stringe in ne številk (potrebno je str(int) @@ -183,35 +171,35 @@ if __name__ == '__main__': response = urllib.request.urlopen('{task_url}/{task_name}/params.json'.format(**params)) web_task_params = json.load(io.TextIOWrapper(response)) task_params.update(web_task_params) - params_argparser = argparse.ArgumentParser(parents=[argparser], conflict_handler='resolve', add_help=True) - add_meta_to_argparser(params_argparser, task_params_meta, defaults=task_params) - args = vars(params_argparser.parse_args()) + + task_argparser = argparse.ArgumentParser(parents=[argparser], conflict_handler='resolve', add_help=True) + add_meta_to_argparser(task_argparser, task_params_meta, defaults=task_params) + args = vars(task_argparser.parse_args()) for k in task_params_meta: - if k in args and args[k] is not None: + if args.get(k): task_params[k] = args[k] if not basic_args.quiet: task_params = get_params(task_params, task_params_meta, language=params['language']) if basic_args.help: - print(params_argparser.format_help()) + print(task_argparser.format_help()) exit(0) - # run task.task() - public_params = dict() + public_params = {} for k in inspect.getargs(task.__code__)[0]: public_params[k] = task_params[k] params['task_params'][params['task_name']] = task_params # save parameters for the next run with open(basic_args.params_file, 'w') as f: - # print "dumping", params yaml.dump(params, f) try: print() - print('Running task… ', end='') + print('Running task… ') task_result = task(**public_params) - print('Checking task… ', end='') + print('Checking task… ') score, hints = task_check(task_result, task_params) print('Done!') + print() print('Score: {}'.format(score)) print('Hints:') for hint in hints: -- cgit v1.2.1