自分でちょっとずつ作っている cuekoma(python) は、年に数回しか使わない。 たぶん、そんな理由で、今年の秋のツーリング準備で使おうとしたら、使い方を忘れていた。 健忘症なのか痴呆症なのか。
コードを読んだりしてる時間が結構無駄。 なので、少しメニュー化することを真剣に考えようと思った次第。
が、今回は間に合うわけもないので、雛形だけ作ってみた。 省メモリ、省codeにしたいので、いわゆる、GUI のメニューでは無い。 しかも、ダイアログなんかも使わないシンプルなやつ。
やりたい事は、
- スクリプトを走らせると、
- 簡単な概要を表示して(configparserではない)、
- ジョブを選択して、
- 必要な設定ファイルを選択して、
- 実行する。
という、単純なもの。なにげに、 MS-DOS を思い起させるヤツだ。
使ったのは、 python-prompt-toolkit で、html のような設定で色付けとか、太字とかも可能。そして、logzero と使い分けることも。
現状は以下。
稚拙な source が下。
#!~/.pyenv/shims/python """Viking data file handling tool.""" from __future__ import unicode_literals import os import sys import logging from pathlib import Path import logzero from fuzzyfinder import fuzzyfinder from prompt_toolkit import HTML, prompt from prompt_toolkit import print_formatted_text as pprint from prompt_toolkit.history import FileHistory from prompt_toolkit.completion import Completer, Completion, WordCompleter from prompt_toolkit.auto_suggest import AutoSuggestFromHistory from prompt_toolkit.formatted_text import FormattedText # script run path os.chdir(Path("~/Documents/proj/gpxs").expanduser()) # the Python 3.6 or above, os.chdir() can deal with Path object directly. LOG_FORMAT = "%(color)s[%(module)s:%(lineno)3d]%(end_color)s %(message)s" FORMATTER = logzero.LogFormatter(fmt=LOG_FORMAT) logzero.setup_default_logger(formatter=FORMATTER) logzero.logfile("./_logs/pp-menu.log", maxBytes=3e5, backupCount=3) logzero.loglevel(logging.DEBUG) def get_keypars(key_par, in_buf, key_nam): """Parse key parameters of this application.""" if in_buf[0] != "#" and in_buf[0] != "\n": if in_buf[0] in ["["]: key_nam = in_buf.split("[")[1].split("]")[0] if key_nam not in key_par.values(): key_par[key_nam] = {"cate": key_nam} else: key_par[key_nam][in_buf.split("=")[0].strip()] = in_buf.split("=")[ 1 ].strip() return key_par, key_nam def read_ppmenu_ini(ini_f): """Read script setting ini file.""" with open(ini_f, "r") as in_file: key_par, key_nam = {}, "" for in_buf in in_file: key_par, key_nam = get_keypars(key_par, in_buf, key_nam) return key_par def show_app_para(app_parm): """Show script parameters and description.""" _str = "run dir : %s " % str(Path.cwd().relative_to(Path.home())) pprint(HTML(' - <skyblue>%s</skyblue> (application\'s ini file is hear)' % _str)) tour_path = Path(app_parm["app"]['top_dir']) _str = "data dir : %s " % str(tour_path.relative_to(Path.home())) pprint(HTML(' - <skyblue>%s</skyblue> (user\'s data(in/out) directory.)' % _str)) _str = "co_poi.vik : 個人的なPOIを収めている viking のデータファイル." pprint(HTML('\n - <skyblue>%s</skyblue>' % _str)) _str = "\n 簡単な説明を付け加えておく方が良いと、後悔している。\n" pprint(HTML(' <skyblue>%s</skyblue>' % _str)) class MyfileCompleter(Completer): """Set Completer.""" def __init__(self, globbed_path): self.globbed_path = globbed_path self.inifile_list = [f.name for f in self.globbed_path.glob("*.ini")] self.num_setfile = len(self.inifile_list) def get_completions(self, document, complete_event): """Set Completer.""" word_before_cursor = document.get_word_before_cursor(WORD=True) matches = fuzzyfinder(word_before_cursor, self.inifile_list) for m in matches: yield Completion(m, start_position=-len(word_before_cursor)) def select_ini_file(globbed_path): """Select tour ini file.""" _s_text = FormattedText([ ('#cccccc bold', "- Select ini file. "), ('#9999cc', '( %d ini files in dir.)\n' % MyfileCompleter(globbed_path).num_setfile), ('#7766cc', " (<tab>key show list)\n > "), ]) user_input = prompt( _s_text, history=FileHistory('pp-menu-ini-history.txt'), auto_suggest=AutoSuggestFromHistory(), completer=MyfileCompleter(globbed_path), ) _s_text = FormattedText([ ('#d15fee italic', ' >> INI file : '), ('#e066ff', user_input), ('#d15fee italic', '.\n'), ]) pprint(_s_text) return Path(globbed_path / user_input) def select_job_category(): """Select job.""" job_list = [ "10: co-poi.vik (change waypoint symbol to default)", "11: co-poi.vik (re-build from vildata. require co_poi_lay.set)", "12: co-poi.vik (copy to custom POI dir. require to_garmin_poi.set) ", "13: conv. to vildata, from all gpx data(check ...)", "14: conv. to vildata, from all json data(check ...)", "99: quit", ] job_index = [int(x.split(':')[0]) for x in job_list] _job_list_text = '\n ' + '\n '.join(job_list) + '' _s_text = FormattedText([ ('#cccccc bold', '- Select job : \n'), ('#7799dd', _job_list_text), ('#7766cc', "\n\n <tab>key select from list."), (' ', '\n\n > '), ]) job_completer = WordCompleter(job_list, ignore_case=True, ) user_input = prompt( _s_text, history=FileHistory("pp-menu-job-history.txt"), completer=job_completer ) _s_text = FormattedText([ ('#d15fee italic', ' >> JOB: '), ('#e066ff', user_input), ('#d15fee italic', '.\n'), ]) pprint(_s_text) job_number = user_input.split(':')[0] if int(job_number) not in job_index: # while でループへ。 logzero.logger.info("!! select wrong job !!") sys.exit() if int(job_number) == 99: pprint(HTML('\n<b> * ばいばい *</b>\n')) sys.exit() return job_number def main(): """Read config and set and select select job.""" pprint(HTML('\n<b><i>* menu test using python prompt toolkit .............</i></b>\n')) # スクリプトの共通パラメタの読み込み ppmenu_ini_file = Path.cwd() / "pp-menu.ini" app_parm = read_ppmenu_ini(ppmenu_ini_file) show_app_para(app_parm) # ジョブの選択 job_number = select_job_category() # 個別設定ファイルの選択 globbed_path = Path(app_parm['app']['top_dir']) tour_setfile = select_ini_file(globbed_path) logzero.logger.info(tour_setfile) logzero.logger.info(job_number) if __name__ == "__main__": main() sys.exit()
年末にかけて、ちょっとづつ進めようと思っている。 メニュー化で整理しようとすると、色々、`あれ` という事が噴出してるから。
0 件のコメント:
コメントを投稿