From 1aa8ddfe38ba084ae92389c686cf668b53e01eed Mon Sep 17 00:00:00 2001 From: Dreagonmon <531486058@qq.com> Date: Sun, 2 Nov 2025 17:34:54 +0800 Subject: [PATCH] wip config --- .gitignore | 2 ++ README.md | 6 ++++ backup_box/__main__.py | 5 ++- backup_box/_env.py | 19 ++++++++++++ backup_box/app.py | 37 ++++++++++++++++++++++ backup_box/config.py | 69 ++++++++++++++++++++++++++++++++++++++++++ backup_box/tui.py | 1 + pyproject.toml | 9 +++++- 8 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 README.md create mode 100644 backup_box/_env.py create mode 100644 backup_box/app.py create mode 100644 backup_box/config.py create mode 100644 backup_box/tui.py diff --git a/.gitignore b/.gitignore index 2386ae5..928e007 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ +/venv/ *.egg* __pycache__ +/libs/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..5199d69 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Backup Box + + +## Config File +dir config: ./backup_box.toml +user config: C:\Users\\AppData\Local\backup_box\backup_box.toml \ No newline at end of file diff --git a/backup_box/__main__.py b/backup_box/__main__.py index 3abd9a1..0aaec1c 100644 --- a/backup_box/__main__.py +++ b/backup_box/__main__.py @@ -1,5 +1,4 @@ -def main(): - print("Hello World") +from . import app if __name__ == "__main__": - main() \ No newline at end of file + app.main() \ No newline at end of file diff --git a/backup_box/_env.py b/backup_box/_env.py new file mode 100644 index 0000000..4727147 --- /dev/null +++ b/backup_box/_env.py @@ -0,0 +1,19 @@ +from os import path as _pth +from os import environ as _env +PKG_NAME = "backup_box" +PKG_PATH = _pth.abspath(_pth.join(_pth.dirname(__file__), "..")) +PWD = _pth.abspath(".") + +def _get_app_config_dirs(): + path = _env.get("XDG_CONFIG_HOME", "") + if path: yield path + path = _env.get("LOCALAPPDATA", "") + if path: yield path + +def _get_sefault_user_config_dir(): + for dir in _get_app_config_dirs(): + path = _pth.abspath(_pth.join(dir, PKG_NAME)) + return path + return PWD + +DEFAULT_USER_CONFIG_DIR = _get_sefault_user_config_dir() diff --git a/backup_box/app.py b/backup_box/app.py new file mode 100644 index 0000000..28cbc61 --- /dev/null +++ b/backup_box/app.py @@ -0,0 +1,37 @@ +from . import _env, config +from argparse import ArgumentParser +from typing import TypedDict + + +def parse_args(): + p = ArgumentParser() + p.add_argument( + "-c", "--config", + dest="config", + help="Config .toml file path.", + required=False, + default="", + ) + p.set_defaults(action="gui") + # sub commands + sps = p.add_subparsers(title="Commands") + p_gui = sps.add_parser("gui") + p_gui.set_defaults(action="gui") + p_backup = sps.add_parser("backup") + p_backup.set_defaults(action="backup") + p_restore = sps.add_parser("restore") + p_restore.set_defaults(action="restore") + # parse args + args = p.parse_args() + # load config file + config.init_default_config() + if args["config"]: + config.apply_user_config(args["config"]) + print(args) + +def main(): + config.init_default_config() + config.reload_config() + print(config.get_config()) + print("Hello World") + parse_args() diff --git a/backup_box/config.py b/backup_box/config.py new file mode 100644 index 0000000..3e0cead --- /dev/null +++ b/backup_box/config.py @@ -0,0 +1,69 @@ +from . import _env +from os import path as _pth +from tomllib import load as toml_load +from tomli_w import dump as toml_dump +from typing import TypedDict + +EntryItem = TypedDict("EntryItem", { + "source": str, +}) + +ConfigDict = TypedDict("ConfigDict", { + "_config": list[str], + "entry": dict[str, EntryItem], +}) + +CONFIG_FILE_NAME = "backup_box.toml" + +def _new_config() -> ConfigDict: + return { + "entry": {}, + "_config": [], + } + +def _override_dict(target: ConfigDict, top_dict: dict): + for k, v in top_dict.items(): + if isinstance(v, dict) and isinstance(target.get(k, None), dict): + _override_dict(target[k], v) + else: + target[k] = v + +_cfg: ConfigDict = _new_config() + +def apply_user_config(dir_or_path: str): + if _pth.isdir(dir_or_path): + dir_or_path = _pth.abspath(_pth.join(dir_or_path, CONFIG_FILE_NAME)) + if dir_or_path in _cfg["_config"]: + return # skip if already added + try: + with open(dir_or_path, "rb") as f: + config = toml_load(f) + except: + config = {} + # ignore config file list + if "_config" in config: + del config["_config"] + # update config + _override_dict(_cfg, config) + # append config file list + _cfg["_config"].append(dir_or_path) + +def init_default_config(): + global _cfg + _cfg = _new_config() + apply_user_config(_env.DEFAULT_USER_CONFIG_DIR) + apply_user_config(_env.PWD) + +def reload_config(): + global _cfg + cfg_list = _cfg["_config"] + _cfg = _new_config() + for cfg in cfg_list: + apply_user_config(cfg) + +def get_config(): + return _cfg + +# find config yaml + + diff --git a/backup_box/tui.py b/backup_box/tui.py new file mode 100644 index 0000000..176adbb --- /dev/null +++ b/backup_box/tui.py @@ -0,0 +1 @@ +# tui \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index d64a910..ac987ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,14 @@ name = "backup_box" version = "0.0.1" license = "MIT" authors = [{ name="Dreagonmon" }] -dependencies = [] +dependencies = [ + "textual>=6.5.0", + "tomli-w >= 1.2.0", +] +requires-python = ">=3.11" + +[project.scripts] +bkb = "backup_box.app:main" [build-system] requires = [